Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

Fui.cpp

Go to the documentation of this file.
00001 /*
00002  * Fui.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00028 #include "../Include/Ui.h"
00029 #include "../Include/Fui.h"
00030 #include "../Include/Utility.h"
00031 #include "../Include/Globals.h"
00032 
00033 using namespace std;
00034 
00035 
00036 // Forward declaration of local helper functions
00037 static CFuiComponent *CreateFuiComponent (EFuiComponentTypes type);
00038 // static CFuiComponent *CreateFuiComponent (const char* name);
00039 static bool           ValidFuiComponentType (Tag tag);
00040 
00041 
00042 static SFont* FuiFont (Tag fontTag)
00043 {
00044   SFont* rc = NULL;
00045 
00046   switch (fontTag) {
00047   case 'deff':
00048     // Default 10-point font
00049     rc = &globals->fonts.ftasci10;
00050     break;
00051 
00052   case 'tath':
00053     // Thin 24-point font
00054     rc = &globals->fonts.ftthin24;
00055     break;
00056 
00057   case 'butn':
00058     // Button uses default 10-point font
00059     rc = &globals->fonts.ftasci10;
00060     break;
00061 
00062   case 'micr':
00063     // Micro 5-point font
00064     rc = &globals->fonts.ftmicro5;
00065     break;
00066 
00067   default:
00068     WARNINGLOG ("Unsupported FUI font 0x%08X", fontTag);
00069     rc = &globals->fonts.ftasci10;
00070   }
00071 
00072   return rc;
00073 }
00074 
00075 
00076 //
00077 // CFuiComponent
00078 //
00079 CFuiComponent::CFuiComponent (int x, int y, int w, int h, Tag window)
00080 {
00081   this->x = x;
00082   this->y = y;
00083   this->w = w;
00084   this->h = h;
00085   this->parentWindowId = window;
00086 
00087   type = (EFuiComponentTypes)0;
00088   id = 0;
00089   bind = 0;
00090   strcpy (widgetName, "");
00091   widgetTag = 0;
00092   strcpy (text, "");
00093   xParent = yParent = 0;
00094   enable = 1;
00095   show = 1;
00096   fontTag = 0;
00097   font = NULL;
00098   surface = NULL;
00099 
00100   // If width/height values were supplied to the constructor, create the drawing surface
00101 //  if ((w != 0) && (h != 0)) {
00102 //    MakeSurface ();
00103 //  }
00104 }
00105 
00106 CFuiComponent::~CFuiComponent (void)
00107 {
00108   // Temporarily commented out surface deletion since it was causing a crash
00109   //   (double free of the drawBuffer I think) when a window was closed.
00110   //   This causes a memory leak and must be fixed soon!
00112 /*
00113   if (surface != NULL) {
00114     FreeSurface (surface);
00115     surface = NULL;
00116   }  
00117 */
00118 }
00119 
00120 int CFuiComponent::Read (SStream *stream, Tag tag)
00121 {
00122   int rc = TAG_IGNORED;
00123 
00124   switch (tag) {
00125   case 'ID  ':
00126   case 'id  ':
00127     ReadTag (&id, stream);
00128     rc = TAG_READ;
00129     break;
00130   case 'bind':
00131     {
00132       int i;
00133       ReadInt (&i, stream);
00134       bind = (EFuiBinding) i;
00135     }
00136     rc = TAG_READ;
00137     break;
00138   case 'widg':
00139     ReadString (widgetName, 64, stream);
00140     ReadTag (&widgetTag, stream);
00141     rc = TAG_READ;
00142     break;
00143   case 'text':
00144     ReadString (text, 256, stream);
00145     rc = TAG_READ;
00146     break;
00147   case 'loc ':
00148     ReadInt (&x, stream);
00149     ReadInt (&y, stream);
00150     rc = TAG_READ;
00151     break;
00152   case 'size':
00153     ReadInt (&w, stream);
00154     ReadInt (&h, stream);
00155     rc = TAG_READ;
00156     break;
00157   case 'enab':
00158     ReadInt (&enable, stream);
00159     rc = TAG_READ;
00160     break;
00161   case 'show':
00162     ReadInt (&show, stream);
00163     rc = TAG_READ;
00164     break;
00165   case 'font':
00166     ReadTag (&fontTag, stream);
00167     rc = TAG_READ;
00168     break;
00169   }
00170 
00171   if (rc == TAG_IGNORED) {
00172     char s[8];
00173     globals->logWarning->Write ("%s : Unknown tag %s", widgetName, TagString (s, tag));
00174   }
00175 
00176   return rc;
00177 }
00178 
00179 void CFuiComponent::ReadFinished (void)
00180 {
00181   font = FuiFont (fontTag);
00182   MakeSurface ();
00183 }
00184 
00185 void CFuiComponent::SetParentWindowId (Tag parentWindowId)
00186 {
00187   this->parentWindowId = parentWindowId;
00188 }
00189 
00190 
00191 //
00192 // Create drawing surface for the component.  This may be called either from
00193 //   ReadFinished() following the parsing of all tags from a .win file,
00194 //   or in the constructor that takes the component size/location.
00195 //
00196 void CFuiComponent::MakeSurface (void)
00197 {
00198   surface = CreateSurface (w, h);
00199   surface->xScreen = xParent + x;
00200   surface->yScreen = yParent + y;
00201   EraseSurface (surface);
00202 }
00203 
00204 void CFuiComponent::SetText (const char *text)
00205 {
00206   memset (this->text, 0, 256);
00207   if (text != NULL) {
00208     strncpy (this->text, text, 255);
00209   }
00210 }
00211 
00212 void CFuiComponent::SetPosition (int x, int y)
00213 {
00214   // Validate new position before applying
00215   if ((x >= 0) && (x < (globals->screenWidth - this->w)) &&
00216       (y >= 0) && (y < (globals->screenHeight - this->h)))
00217   {
00218     this->x = x;
00219     this->y = y;
00220 
00221     if (surface != NULL) {
00222       surface->xScreen = xParent + x;
00223       surface->yScreen = yParent + y;
00224     }
00225   }
00226 }
00227 
00228 void CFuiComponent::SetParentPosition (int xParent, int yParent)
00229 {
00230   this->xParent = xParent;
00231   this->yParent = yParent;
00232 
00233   if (surface != NULL) {
00234     surface->xScreen = xParent + x;
00235     surface->yScreen = yParent + y;
00236   }
00237 }
00238 
00239 void CFuiComponent::SetSize (int w, int h)
00240 {
00241   if ((w != this->w) || (h != this->h)) {
00242     this->w = w;
00243     this->h = h;
00244 
00245     // Replace surface if required
00246     if (surface != NULL) {
00247       FreeSurface (surface);
00248       surface = CreateSurface (w, h);
00249       surface->xScreen = xParent + x;
00250       surface->yScreen = yParent + y;
00251     }
00252   }
00253 }
00254 
00255 void CFuiComponent::SetPositionSize (int x, int y, int w, int h)
00256 {
00257   SetPosition (x, y);
00258   SetSize (w, h);
00259 }
00260 
00261 void CFuiComponent::Draw (void)
00262 {
00263   // Only draw if surface has been created and the component is visible
00264   if ((surface != NULL) && show) {
00265     glDrawBuffer (GL_BACK);
00266     // Starting raster position is bottom-left corner of the surface,
00267     //   with (0,0) at top-left of the screen
00268     glRasterPos2i (surface->xScreen, surface->yScreen + surface->ySize);
00269     glDrawPixels (surface->xSize, surface->ySize,
00270       GL_RGBA,
00271       GL_UNSIGNED_BYTE,
00272       surface->drawBuffer);
00273   }
00274 }
00275 
00276 bool CFuiComponent::MouseHit (int mx, int my)
00277 {
00278   // Calculate component starting screen locations
00279   int cx = xParent + x;
00280   int cy = yParent + y;
00281   return (mx >= cx) && (mx < (cx + w)) && (my >= cy) && (my < (cy + h));
00282 }
00283 
00284 bool CFuiComponent::MouseMove (int x, int y)
00285 {
00286   bool rc = false;
00287   return rc;
00288 }
00289 
00290 bool CFuiComponent::MouseClick (int x, int y, EMouseButton button)
00291 {
00292   bool rc = false;
00293   return rc;
00294 }
00295 
00296 bool CFuiComponent::MouseStopClick (int x, int y, EMouseButton button)
00297 {
00298   bool rc = false;
00299   return rc;
00300 }
00301 
00302 //
00303 // CFuiWindowTitle
00304 //
00305 CFuiWindowTitle::CFuiWindowTitle (int x, int y, int w, int h, Tag window)
00306 : CFuiComponent (x, y, w, h, window)
00307 {
00308   widgetTag = 'defa';
00309   strcpy (widgetName, "WindowTitle");
00310 
00311   bmBack = NULL;
00312   bmAltBack = NULL;
00313   bmLeft = NULL;
00314   bmRight = NULL;
00315   colText = MakeRGB (255, 255, 255);
00316   font = FuiFont ('deff');
00317 
00318   back = left = right = NULL;
00319 
00320   Fill ();
00321 }
00322 
00323 void CFuiWindowTitle::Fill (void)
00324 {
00325   // Get FUI theme for this component
00326   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
00327   if (tw == NULL) {
00328     char s[8];
00329     TagToString (s, widgetTag);
00330     gtfo ("CFuiWindowTitle : Cannot get theme widget %s", s);
00331   }
00332 
00333   // Get window backdrop bitmap from the theme.  If no bitmap exists, a blank
00334   //   canvas component is used as the backdrop.
00335   bmBack = tw->GetBitmap ("BACK");
00336   back = new CFuiPicture;
00337   back->SetBitmap (bmBack);
00338   back->SetPositionSize (0, 0, w, h);
00339   childVector.push_back (back);
00340 
00342 
00343   // Get optional left frame bitmap
00344   bmLeft = tw->GetBitmap ("LEFT");
00345   int bmwLeft = 0, bmhLeft = 0;
00346   if (bmLeft != NULL) {
00347     GetBitmapSize (bmLeft, &bmwLeft, &bmhLeft);
00348     left = new CFuiPicture;
00349     left->SetBitmap (bmLeft);
00350     left->SetPositionSize (0, 0, bmwLeft, h);
00351     childVector.push_back (left);
00352   }
00353 
00354   // Get optional right frame bitmap
00355   bmRight = tw->GetBitmap ("RIGHT");
00356   int bmwRight = 0, bmhRight = 0;
00357   if (bmRight != NULL) {
00358     GetBitmapSize (bmRight, &bmwRight, &bmhRight);
00359     right = new CFuiPicture;
00360     right->SetBitmap (bmRight);
00361     right->SetPositionSize (w-bmwRight, 0, bmwRight, h);
00362     childVector.push_back (right);
00363   }
00364 
00365   // Get text colour
00366   colText = tw->GetColour ("TEXT");
00367 }
00368 
00369 void CFuiWindowTitle::SetParentPosition (int xParent, int yParent)
00370 {
00371   CFuiComponent::SetParentPosition (xParent, yParent);
00372 
00373   // Update all children
00374   vector<CFuiComponent*>::iterator i;
00375   for (i=childVector.begin(); i!=childVector.end(); i++) {
00376     (*i)->SetParentPosition(xParent + x, yParent + y);
00377   }
00378 }
00379 
00380 void CFuiWindowTitle::Draw (void)
00381 {
00382   // Draw each component
00383   vector<CFuiComponent*>::iterator i;
00384   for (i=childVector.begin(); i!=childVector.end(); i++) {
00385     (*i)->Draw();
00386   }
00387 
00388   // Draw text
00389   int th = TextHeight (font, text);
00390   DrawTextC (surface, font, w/2, (h-th)/2, colText, text);
00391 //  int th = TextHeight (&globals->fonts.ftasci10, text);
00392 //  DrawTextC (surface, &globals->fonts.ftasci10, w/2, (h-th)/2, colText, text);
00393 
00394   CFuiComponent::Draw ();
00395 }
00396 
00397 
00398 //
00399 // CFuiCloseButton
00400 //
00401 CFuiCloseButton::CFuiCloseButton (int x, int y, int w, int h, Tag window)
00402 : CFuiComponent (x, y, w, h, window)
00403 {
00404   type = COMPONENT_CLOSE_BUTTON;
00405   widgetTag = 'defa';
00406   strcpy (widgetName, "WindowCloseButton");
00407 
00408   bmBack = NULL;
00409   back = NULL;
00410   state = false;
00411 
00412   Fill ();
00413 }
00414 
00415 void CFuiCloseButton::Fill (void)
00416 {
00417   // Get FUI theme for this component
00418   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
00419   if (tw == NULL) {
00420     char s[8];
00421     TagToString (s, widgetTag);
00422     gtfo ("%s : Cannot get theme widget %s", widgetName, s);
00423   }
00424 
00425   bmBack = tw->GetBitmap ("BACK");
00426   if (bmBack != NULL) {
00427     int bmwBack = 0, bmhBack = 0;
00428     GetBitmapSize (bmBack, &bmwBack, &bmhBack);
00429     back = new CFuiPicture (0, 0, bmwBack, bmhBack);
00430     back->SetBitmap (bmBack);
00431     back->SetFrame (0);
00432   }
00433   SetParentPosition (x, y);
00434 }
00435 
00436 void CFuiCloseButton::SetParentPosition (int xParent, int yParent)
00437 {
00438   CFuiComponent::SetParentPosition (xParent, yParent);
00439 
00440   // Update all children
00441   if (back != NULL) {
00442     back->SetParentPosition (xParent + x, yParent + y);
00443   }
00444 }
00445 
00446 void CFuiCloseButton::Draw (void)
00447 {
00448   // Draw the backdrop bitmap
00449   if (back != NULL) {
00450     back->Draw ();
00451   }
00452 }
00453 
00454 bool CFuiCloseButton::MouseMove (int x, int y)
00455 {
00456   bool rc = false;
00457   if ((state == true) && !MouseHit (x, y)) {
00458     state = false;
00459     back->SetFrame (0);
00460     rc = true;
00461   }
00462   return rc;
00463 }
00464 
00465 bool CFuiCloseButton::MouseClick (int x, int y, EMouseButton button)
00466 {
00467   bool rc = false;
00468   if (MouseHit (x, y)) {
00469     state = true;
00470     back->SetFrame (1);
00471     rc = true;
00472   }
00473   return rc;
00474 }
00475 
00476 bool CFuiCloseButton::MouseStopClick (int x, int y, EMouseButton button)
00477 {
00478   bool rc = false;
00479   if (state == true) {
00480     state = false;
00481     back->SetFrame (0);
00482     rc = true;
00483   }
00484   return rc;
00485 }
00486 
00487 //
00488 // CFuiMinimizeButton
00489 //
00490 CFuiMinimizeButton::CFuiMinimizeButton (int x, int y, int w, int h, Tag window)
00491 : CFuiComponent (x, y, w, h, window)
00492 {
00493   type = COMPONENT_MINIMIZE_BUTTON;
00494   widgetTag = 'defa';
00495   strcpy (widgetName, "WindowMinimizeButton");
00496 
00497   bmBack = NULL;
00498   back = NULL;
00499   state = false;
00500 
00501   Fill ();
00502 }
00503 
00504 void CFuiMinimizeButton::Fill (void)
00505 {
00506   // Get FUI theme for this component
00507   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
00508   if (tw == NULL) {
00509     char s[8];
00510     TagToString (s, widgetTag);
00511     gtfo ("%s : Cannot get theme widget %s", widgetName, s);
00512   }
00513 
00514   bmBack = tw->GetBitmap ("BACK");
00515   if (bmBack != NULL) {
00516     int bmwBack = 0, bmhBack = 0;
00517     GetBitmapSize (bmBack, &bmwBack, &bmhBack);
00518     back = new CFuiPicture (0, 0, bmwBack, bmhBack);
00519     back->SetBitmap (bmBack);
00520   }
00521   SetParentPosition (x, y);
00522 }
00523 
00524 void CFuiMinimizeButton::SetParentPosition (int xParent, int yParent)
00525 {
00526   CFuiComponent::SetParentPosition (xParent, yParent);
00527 
00528   // Update all children
00529   if (back != NULL) {
00530     back->SetParentPosition (xParent + x, yParent + y);
00531   }
00532 }
00533 
00534 void CFuiMinimizeButton::Draw (void)
00535 {
00536   // Draw the backdrop bitmap
00537   if (back != NULL) {
00538     back->Draw ();
00539   }
00540 }
00541 
00542 bool CFuiMinimizeButton::MouseMove (int x, int y)
00543 {
00544   bool rc = false;
00545   if ((state == true) && !MouseHit (x, y)) {
00546     state = false;
00547     back->SetFrame (0);
00548     rc = true;
00549   }
00550   return rc;
00551 }
00552 
00553 bool CFuiMinimizeButton::MouseClick (int x, int y, EMouseButton button)
00554 {
00555   bool rc = false;
00556   if (MouseHit (x, y)) {
00557     state = true;
00558     back->SetFrame (1);
00559     rc = true;
00560   }
00561   return rc;
00562 }
00563 
00564 bool CFuiMinimizeButton::MouseStopClick (int x, int y, EMouseButton button)
00565 {
00566   bool rc = false;
00567   if (state == true) {
00568     state = false;
00569     back->SetFrame (0);
00570     rc = true;
00571   }
00572   return rc;
00573 }
00574 
00575 
00576 //
00577 // CFuiZoomButton
00578 //
00579 CFuiZoomButton::CFuiZoomButton (int x, int y, int w, int h, Tag window)
00580 : CFuiComponent (x, y, w, h, window)
00581 {
00582   type = COMPONENT_ZOOM_BUTTON;
00583   widgetTag = 'defa';
00584   strcpy (widgetName, "WindowZoomButton");
00585 
00586   bmBack = NULL;
00587   back = NULL;
00588   state = false;
00589 
00590   Fill ();
00591 }
00592 
00593 void CFuiZoomButton::Fill (void)
00594 {
00595   // Get FUI theme for this component
00597   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
00598   if (tw == NULL) {
00599     char s[8];
00600     TagToString (s, widgetTag);
00601     gtfo ("%s : Cannot get theme widget %s", widgetName, s);
00602   }
00603 
00604   bmBack = tw->GetBitmap ("BACK");
00605   if (bmBack != NULL) {
00606     int bmwBack = 0, bmhBack = 0;
00607     GetBitmapSize (bmBack, &bmwBack, &bmhBack);
00608     back = new CFuiPicture (0, 0, bmwBack, bmhBack);
00609     back->SetBitmap (bmBack);
00610   }
00611   SetParentPosition (x, y);
00612 }
00613 
00614 void CFuiZoomButton::SetParentPosition (int xParent, int yParent)
00615 {
00616   CFuiComponent::SetParentPosition (xParent, yParent);
00617 
00618   // Update all children
00619   if (back != NULL) {
00620     back->SetParentPosition (xParent + x, yParent + y);
00621   }
00622 }
00623 
00624 void CFuiZoomButton::Draw (void)
00625 {
00626   // Draw the backdrop bitmap
00627   if (back != NULL) {
00628     back->Draw ();
00629   }
00630 }
00631 
00632 bool CFuiZoomButton::MouseMove (int x, int y)
00633 {
00634   bool rc = false;
00635   if ((state == true) && !MouseHit (x, y)) {
00636     state = false;
00637     back->SetFrame (0);
00638     rc = true;
00639   }
00640   return rc;
00641 }
00642 
00643 bool CFuiZoomButton::MouseClick (int x, int y, EMouseButton button)
00644 {
00645   bool rc = false;
00646   if (MouseHit (x, y)) {
00647     state = true;
00648     back->SetFrame (1);
00649     rc = true;
00650   }
00651   return rc;
00652 }
00653 
00654 bool CFuiZoomButton::MouseStopClick (int x, int y, EMouseButton button)
00655 {
00656   bool rc = false;
00657   if (state == true) {
00658     state = false;
00659     back->SetFrame (0);
00660     rc = true;
00661   }
00662   return rc;
00663 }
00664 
00665 
00666 //
00667 // CFuiWindow
00668 //
00669 CFuiWindow::CFuiWindow (const char* winFilename, Tag windowId, FuiEventNoticeCb handler)
00670 : CFuiComponent()
00671 {
00672   this->state = FUI_WINDOW_INIT;
00673   this->windowId = windowId;
00674   type = COMPONENT_WINDOW;
00675   strcpy (this->winFilename, winFilename);
00676   this->handler = handler;
00677 
00678   mini = zoom = close = 0;
00679 
00680   surface = NULL;
00681   bmBack = NULL;
00682   bmTop = NULL;
00683   bmBottom = NULL;
00684   bmLeft = NULL;
00685   bmRight = NULL;
00686   bmTopLeft = NULL;
00687   bmTopRight = NULL;
00688   bmBottomLeft = NULL;
00689   bmBottomRight = NULL;
00690 
00691   windowTitle = NULL;
00692   btnClose = NULL;
00693   btnMini = NULL;
00694   btnZoom = NULL;
00695 
00696   // Open stream
00697   SStream stream;
00698   strcpy (stream.filename, winFilename);
00699   strcpy (stream.mode, "r");
00700   if (OpenStream (&globals->pfs, &stream)) {
00701     ReadFrom (this, &stream);
00702     CloseStream (&stream);
00703   }
00704 }
00705 
00706 CFuiWindow::~CFuiWindow (void)
00707 {
00708   // Free drawing surface
00709   if (surface != NULL) {
00710     FreeSurface (surface);
00711     surface = NULL;
00712   }
00713 
00714   // Delete decoration components
00715   list<CFuiComponent*>::iterator i;
00716   for (i=decorationList.begin(); i!=decorationList.end(); i++) {
00717     CFuiComponent *c = *i;
00718     delete c;
00719   }
00720 
00721   // Delete child components
00722   for (i=childList.begin(); i!=childList.end(); i++) delete (*i);
00723 }
00724 
00725 int CFuiWindow::Read (SStream *stream, Tag tag)
00726 {
00727   int rc = TAG_IGNORED;
00728 
00729   switch (tag) {
00730   case 'wsiz':
00731     ReadInt (&xWsiz, stream);
00732     ReadInt (&yWsiz, stream);
00733     rc = TAG_READ;
00734     break;
00735   case 'ipos':
00736     ReadInt (&x1, stream);
00737     ReadInt (&y1, stream);
00738     ReadInt (&x2, stream);
00739     ReadInt (&y2, stream);
00740     rc = TAG_READ;
00741     break;
00742   case 'titl':
00743     ReadInt (&title, stream);
00744     rc = TAG_READ;
00745     break;
00746   case 'clos':
00747     ReadInt (&close, stream);
00748     rc = TAG_READ;
00749     break;
00750   case 'mini':
00751     ReadInt (&mini, stream);
00752     rc = TAG_READ;
00753     break;
00754   case 'zoom':
00755     ReadInt (&zoom, stream);
00756     rc = TAG_READ;
00757     break;
00758   case 'rsiz':
00759     ReadInt (&resize, stream);
00760     rc = TAG_READ;
00761     break;
00762   case 'move':
00763     ReadInt (&move, stream);
00764     rc = TAG_READ;
00765     break;
00766   case 'bord':
00767     ReadInt (&border, stream);
00768     rc = TAG_READ;
00769     break;
00770   case 'bsiz':
00771     ReadInt (&borderSize, stream);
00772     rc = TAG_READ;
00773     break;
00774   case 'layr':
00775     {
00776       int i;
00777       ReadInt (&i, stream);
00778       layer = (EFuiLayer) i;
00779     }
00780     rc = TAG_READ;
00781     break;
00782   case 'trns':
00783     ReadInt (&trns, stream);
00784     rc = TAG_READ;
00785     break;
00786   case 'save':
00787     ReadInt (&save, stream);
00788     rc = TAG_READ;
00789     break;
00790   }
00791 
00792   // Add subcomponent if applicable
00793   if (rc == TAG_IGNORED) {
00794     if (ValidFuiComponentType (tag)) {
00795       CFuiComponent *c = CreateFuiComponent ((EFuiComponentTypes)tag);
00796       if (c != NULL) {
00797         ReadFrom (c, stream);
00798         c->SetParentWindowId (this->windowId);
00799         c->SetParentPosition (x, y);
00800         childList.push_back (c);
00801         rc = TAG_READ;
00802       } else {
00803         char s[8];
00804         globals->logWarning->Write ("CFuiWindow : Skipping unsupported widget %s",
00805           TagString (s, tag));
00806         SkipObject (stream);
00807       }
00808       rc = TAG_READ;
00809     }
00810   }
00811 
00812   // Send tag to parent class for processing.
00813   if (rc == TAG_IGNORED) {
00814     rc = CFuiComponent::Read (stream, tag);
00815   }
00816 
00817   return rc;
00818 }
00819 
00820 void CFuiWindow::ReadFinished (void)
00821 {
00822   // Get FUI theme for this component
00823   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
00824   if (tw == NULL) {
00825     char s[8];
00826     TagToString (s, widgetTag);
00827     gtfo ("CFuiWindow : Invalid theme identifier %s in window file %s", s, winFilename);
00828   }
00829 
00830   // Set overall window location and size
00831   w = xWsiz;
00832   h = yWsiz;
00833 
00834   // Locals for bitmap width/height
00835   int bmw, bmh;
00836 
00837   // Get window backdrop bitmap from the theme.  If no bitmap exists, a blank
00838   //   canvas component is used as the backdrop.
00839   bmBack = tw->GetBitmap ("BACK");
00840   if (bmBack != NULL) {
00841     CFuiPicture *back = new CFuiPicture (0, 0, w, h);
00842     back->SetBitmap (bmBack);
00843     back->SetParentPosition (x, y);
00844     decorationList.push_back (back);
00845   }
00846 
00847   // Get optional top frame bitmap
00848   bmTop = tw->GetBitmap ("TOP");
00849   if (bmTop != NULL) {
00850     GetBitmapSize (bmTop, &bmw, &bmh);
00851     CFuiPicture *top = new CFuiPicture (0, 0, w, bmh);
00852     top->SetBitmap (bmTop);
00853     top->SetParentPosition (x, y);
00854     decorationList.push_back (top);
00855   }
00856 
00857   // Get optional bottom frame bitmap
00858   bmBottom = tw->GetBitmap ("BOTTOM");
00859   if (bmBottom != NULL) {
00860     GetBitmapSize (bmBottom, &bmw, &bmh);
00861     CFuiPicture *bottom = new CFuiPicture (0, h-bmh, w, bmh);
00862     bottom->SetBitmap (bmBottom);
00863     bottom->SetParentPosition (x, y);
00864     decorationList.push_back (bottom);
00865   }
00866 
00867   // Get optional left frame bitmap
00868   bmLeft = tw->GetBitmap ("LEFT");
00869   if (bmLeft != NULL) {
00870     GetBitmapSize (bmLeft, &bmw, &bmh);
00871     CFuiPicture *left = new CFuiPicture (0, 0, bmw, h);
00872     left->SetBitmap (bmLeft);
00873     left->SetParentPosition (x, y);
00874     decorationList.push_back (left);
00875   }
00876 
00877   // Get optional right frame bitmap
00878   bmRight = tw->GetBitmap ("RIGHT");
00879   if (bmRight != NULL) {
00880     GetBitmapSize (bmRight, &bmw, &bmh);
00881     CFuiPicture *right = new CFuiPicture (w-bmw, 0, bmw, h);
00882     right->SetBitmap (bmRight);
00883     right->SetParentPosition (x, y);
00884     decorationList.push_back (right);
00885   }
00886 
00887   // Get optional top-left corner bitmap
00888   bmTopLeft = tw->GetBitmap ("TOPLEFT");
00889   if (bmTopLeft != NULL) {
00890     GetBitmapSize (bmTopLeft, &bmw, &bmh);
00891     CFuiPicture *topleft = new CFuiPicture (0, 0, bmw, bmh);
00892     topleft->SetBitmap (bmTopLeft);
00893     topleft->SetParentPosition (x, y);
00894     decorationList.push_back (topleft);
00895   }
00896 
00897   // Get optional top-right corner bitmap
00898   bmTopRight = tw->GetBitmap ("TOPRIGHT");
00899   if (bmTopRight != NULL) {
00900     GetBitmapSize (bmTopRight, &bmw, &bmh);
00901     CFuiPicture *topright = new CFuiPicture (w-bmw, 0, bmw, bmh);
00902     topright->SetBitmap (bmTopRight);
00903     topright->SetParentPosition (x, y);
00904     decorationList.push_back (topright);
00905   }
00906 
00907   // Get optional bottom-left corner bitmap
00908   bmBottomLeft = tw->GetBitmap ("BOTLEFT");
00909   if (bmBottomLeft != NULL) {
00910     GetBitmapSize (bmBottomLeft, &bmw, &bmh);
00911     CFuiPicture *botleft = new CFuiPicture (0, h-bmh, bmw, bmh);
00912     botleft->SetBitmap (bmBottomLeft);
00913     botleft->SetParentPosition (x, y);
00914     decorationList.push_back (botleft);
00915   }
00916 
00917   // Get optional bottom-right corner bitmap
00918   bmBottomRight = tw->GetBitmap ("BOTRIGHT");
00919   if (bmBottomRight != NULL) {
00920     GetBitmapSize (bmBottomRight, &bmw, &bmh);
00921     CFuiPicture *botright = new CFuiPicture (w-bmw, h-bmh, bmw, bmh);
00922     botright->SetBitmap (bmBottomRight);
00923     botright->SetParentPosition (x, y);
00924     decorationList.push_back (botright);
00925   }
00926 
00927   if (title) {
00928     // Create title bar
00929     // @todo Use theme to determine window title type
00930     // @todo Get height of backdrop bitmap instead of hard-coded height
00931     windowTitle = new CFuiWindowTitle (0, -20, w, 20);
00932     windowTitle->SetText (text);
00933     windowTitle->SetParentPosition (x, y);
00934     decorationList.push_back (windowTitle);
00935   }
00936 
00937   // Maintain running count of right-hand edge to align title bar buttons
00938   int wMax = w - 20;
00939 
00940   // Add optional window decoration components
00941   if (close) {
00944     btnClose = new CFuiCloseButton (wMax, -16, 20, 20);
00945     btnClose->SetParentPosition (x, y);
00946     decorationList.push_back (btnClose);
00947     wMax -= 20;
00948   }
00949   if (zoom) {
00952     btnZoom = new CFuiZoomButton (wMax, -16, 20, 20);
00953     btnZoom->SetParentPosition (x, y);
00954     decorationList.push_back (btnZoom);
00955     wMax -= 20;
00956   }
00957   if (mini) {
00960     btnMini = new CFuiMinimizeButton (wMax, -16, 20, 20);
00961     btnMini->SetParentPosition (x, y);
00962     decorationList.push_back (btnMini);
00963   }
00964 
00965   // Set window state to open
00966   state = FUI_WINDOW_OPEN;
00967 }
00968 
00969 EFuiWindowState CFuiWindow::GetState (void)
00970 {
00971   return state;
00972 }
00973 
00974 void CFuiWindow::Close (void)
00975 {
00976   state = FUI_WINDOW_CLOSED;
00977 }
00978 
00979 void CFuiWindow::Draw (SSurface *surface)
00980 {
00981   // Draw window decoration components
00982   list<CFuiComponent*>::iterator i;
00983   for (i=decorationList.begin(); i!=decorationList.end(); i++) {
00984     (*i)->Draw();
00985   }
00986 
00987   // Draw child components
00988   for (i=childList.begin(); i!=childList.end(); i++) {
00989     (*i)->Draw();
00990   }
00991 }
00992 
00993 void CFuiWindow::Draw (void)
00994 {
00995   Draw (surface);
00996 }
00997 
00998 //
00999 // Set the position of the window relative to the top-left corner of the screen
01000 //
01001 void CFuiWindow::SetPosition (int sx, int sy)
01002 {
01003   CFuiComponent::SetPosition (sx, sy);
01004 
01005   // Update parent position of window decorations
01006   list<CFuiComponent*>::iterator i;
01007   for (i=decorationList.begin(); i!=decorationList.end(); i++) {
01008     (*i)->SetParentPosition (x, y);
01009   }
01010 
01011   // Update parent position of child widgets
01012   for (i=childList.begin(); i!=childList.end(); i++) {
01013     (*i)->SetParentPosition(x, y);
01014   }
01015 }
01016 
01023 bool CFuiWindow::MouseMove (int mx, int my)
01024 {
01025   bool rc = false;
01026 
01027   if (state == FUI_WINDOW_MOVE) {
01028     int dx = mx - lastX;
01029     int dy = my - lastY;
01030 
01031     int nx = x + dx;
01032     int ny = y + dy;
01033 
01034     SetPosition (nx, ny);
01035 
01036     lastX = mx;
01037     lastY = my;
01038 
01039     rc = true;
01040   }
01041 
01042   // If mouse click has not been handled yet, send to child widgets
01043   list<CFuiComponent*>::iterator i;
01044   for (i=childList.begin(); i!=childList.end() && !rc; i++) {
01045     rc = (*i)->MouseMove (mx, my);
01046   }
01047 
01048   return rc;
01049 }
01050 
01051 bool CFuiWindow::MouseClick (int mx, int my, EMouseButton button)
01052 {
01053   bool rc = false;
01054 
01055   // Check for hits on standard window decorations
01056   if (!rc && btnClose) {
01057     rc = btnClose->MouseClick (mx, my, button);
01058   }
01059   if (!rc && btnZoom) {
01060     rc = btnZoom->MouseClick (mx, my, button);
01061   }
01062   if (!rc && btnMini) {
01063     rc = btnMini->MouseClick (mx, my, button);
01064   }
01065 
01066   if (!rc && (windowTitle && windowTitle->MouseHit (mx, my))) {
01067     // Clicked on window title frame
01068     if (button == MOUSE_BUTTON_LEFT) {
01069       state = FUI_WINDOW_MOVE;
01070       lastX = mx;
01071       lastY = my;
01072       rc = true;
01073     }
01074   }
01075 
01076   // If mouse click has not been handled yet, send to child widgets
01077   list<CFuiComponent*>::iterator i;
01078   for (i=childList.begin(); i!=childList.end() && !rc; i++) {
01079     rc = (*i)->MouseClick (mx, my, button);
01080   }
01081 
01082   return rc;
01083 }
01084 
01085 bool CFuiWindow::MouseStopClick (int mx, int my, EMouseButton button)
01086 {
01087   bool rc = false;
01088 
01089   if ((state == FUI_WINDOW_MOVE) && (button == MOUSE_BUTTON_LEFT)) {
01090     state = FUI_WINDOW_OPEN;
01091     rc = true;
01092   }
01093 
01094   if (!rc && btnClose) {
01095     rc = btnClose->MouseStopClick (mx, my, button);
01096     if (rc) {
01097       Close ();
01098     }
01099   }
01100   if (!rc && btnZoom) {
01101     rc = btnZoom->MouseStopClick (mx, my, button);
01102   }
01103   if (!rc && btnMini) {
01104     rc = btnMini->MouseStopClick (mx, my, button);
01105   }
01106 
01107   // If mouse click has not been handled yet, send to child widgets
01108   list<CFuiComponent*>::iterator i;
01109   for (i=childList.begin(); i!=childList.end() && !rc; i++) {
01110     rc = (*i)->MouseStopClick (mx, my, button);
01111   }
01112 
01113   return rc;
01114 }
01115 
01116 void CFuiWindow::SetTitle (const char* title)
01117 {
01118   if (windowTitle != NULL) {
01119     windowTitle->SetText (title);
01120   }
01121 }
01122 
01123 CFuiComponent *CFuiWindow::GetComponent (Tag component)
01124 {
01125   CFuiComponent *rc = NULL;
01126 
01127   list<CFuiComponent*>::iterator i;
01128   for (i=childList.begin(); i!=childList.end(); i++) {
01129     if ((*i)->GetId() == component) {
01130       rc = (*i);
01131     }
01132   }
01133 
01134   return rc;
01135 }
01136 
01137 void CFuiWindow::GenerateEventNotice (Tag componentId,
01138                                       EFuiEvents event,
01139                                       EFuiEvents subevent)
01140 {
01141   if (handler != NULL) {
01142     handler (windowId, componentId, event, subevent);
01143   }
01144 }
01145 
01146 
01147 //
01148 // CFuiButton
01149 //
01150 CFuiButton::CFuiButton (int x, int y, int w, int h, Tag window)
01151 : CFuiComponent (x, y, w, h, window)
01152 {
01153   type = COMPONENT_BUTTON;
01154   widgetTag = 'defa';
01155   strcpy (widgetName, "Button");
01156 
01157   bmLeft = NULL;
01158   bmBack = NULL;
01159   bmRight = NULL;
01160 
01161   left = NULL;
01162   back = NULL;
01163   right = NULL;
01164 
01165   ok = 0;
01166   canc = 0;
01167   rrpt = 0;
01168   rate = 0.0f;
01169   strcpy (psiz, "");
01170   xLsiz = yLsiz = 0;
01171   xBsiz = yBsiz = 0;
01172 }
01173 
01174 int CFuiButton::Read (SStream *stream, Tag tag)
01175 {
01176   int rc = TAG_IGNORED;
01177 
01178   switch (tag) {
01179   case 'ok  ':
01180     ReadInt (&ok, stream);
01181     if (ok != 0) id = 'okok';
01182     rc = TAG_READ;
01183     break;
01184   case 'canc':
01185     ReadInt (&canc, stream);
01186     if (canc != 0) id = 'canc';
01187     rc = TAG_READ;
01188     break;
01189   case 'rrpt':
01190     ReadInt (&rrpt, stream);
01191     rc = TAG_READ;
01192     break;
01193   case 'rate':
01194     ReadFloat (&rate, stream);
01195     rc = TAG_READ;
01196     break;
01197   case 'psiz':
01198     ReadString (psiz, 64, stream);
01199     rc = TAG_READ;
01200   case 'lsiz':
01201     ReadInt (&xLsiz, stream);
01202     ReadInt (&yLsiz, stream);
01203     rc = TAG_READ;
01204     break;
01205   case 'bsiz':
01206     ReadInt (&xBsiz, stream);
01207     ReadInt (&yBsiz, stream);
01208     rc = TAG_READ;
01209     break;
01210   }
01211 
01212   // Send tag to parent class for processing
01213   if (rc == TAG_IGNORED) {
01214     rc = CFuiComponent::Read (stream, tag);
01215   }
01216 
01217   return rc;
01218 }
01219 
01220 void CFuiButton::ReadFinished (void)
01221 {
01222   CFuiComponent::ReadFinished ();
01223 
01224   // Get FUI theme for this component
01225   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
01226   if (tw == NULL) {
01227     char s[8];
01228     TagToString (s, widgetTag);
01229     gtfo ("Cannot get theme widget %s", s);
01230   }
01231 
01232   int bmwLeft = 0, bmhLeft = 0;
01233   int bmwBack = 0, bmhBack = 0;
01234   int bmwRight = 0, bmhRight = 0;
01235 
01236   // Left button edge bitmap
01237   bmLeft = tw->GetBitmap ("LEFT");
01238   if (bmLeft != NULL) {
01239     GetBitmapSize (bmLeft, &bmwLeft, &bmhLeft);
01240     left = new CFuiPicture (0, 0, bmwLeft, bmhLeft);
01241     left->SetBitmap (bmLeft);
01242   }
01243 
01244   // Right button edge bitmap
01245   bmRight = tw->GetBitmap ("RIGHT");
01246   if (bmRight != NULL) {
01247     GetBitmapSize (bmRight, &bmwRight, &bmhRight);
01248     right = new CFuiPicture (xBsiz - bmwRight - 1, 0, bmwRight, bmhRight);
01249     right->SetBitmap (bmRight);
01250   }
01251 
01252   // Back button bitmap is tiled across actual button size
01253   int wBack = xBsiz - bmwLeft - bmwRight;
01254   int hBack = yBsiz;
01255   bmBack = tw->GetBitmap ("BACK");
01256   if (bmBack != NULL) {
01257     GetBitmapSize (bmBack, &bmwBack, &bmhBack);
01258     back = new CFuiPicture (bmwLeft, 0, wBack, hBack);
01259     back->SetBitmap (bmBack);
01260   }
01261 
01262   // Get theme components
01263   colText = tw->GetColour ("TEXT");
01264 
01265   SetParentPosition (x, y);
01266 
01267   state = false;
01268 }
01269 
01270 void CFuiButton::SetParentPosition (int xParent, int yParent)
01271 {
01272   CFuiComponent::SetParentPosition (xParent, yParent);
01273 
01274   // Update all children
01275   if (left != NULL) {
01276     left->SetParentPosition (xParent + x, yParent + y);
01277   }
01278   if (back != NULL) {
01279     back->SetParentPosition (xParent + x, yParent + y);
01280   }
01281   if (left != NULL) {
01282     right->SetParentPosition (xParent + x, yParent + y);
01283   }
01284 }
01285 
01286 void CFuiButton::Draw (void)
01287 {
01288   // Draw button components
01289   if (left != NULL) left->Draw ();
01290   if (back != NULL) back->Draw ();
01291   if (right != NULL) right->Draw ();
01292 
01293   // Draw label
01294   int th = TextHeight (font, text);
01295   if (surface != NULL) {
01296     DrawTextC (surface, font, xBsiz/2, (yBsiz-th)/2, colText, text);
01297   }
01298 
01299   CFuiComponent::Draw ();
01300 }
01301 
01302 bool CFuiButton::MouseMove (int x, int y)
01303 {
01304   bool rc = false;
01305   
01306   // If button is currently pressed and mouse is moved outside of button
01307   //   hit area, then set state to unpressed but don't send BUTTONPRESS event
01308   if ((state == true) && !MouseHit (x, y)) {
01309     state = false;
01310     if (left) left->SetFrame (0);
01311     if (back) back->SetFrame (0);
01312     if (right) right->SetFrame (0);
01313   }
01314   return rc;
01315 }
01316 
01317 bool CFuiButton::MouseClick (int x, int y, EMouseButton button)
01318 {
01319   bool rc = false;
01320 
01321   // If mouse clicked inside button area, set state to pressed.  The BUTTONPRESS
01322   //   event is only sent when the button is clicked and released
01323   if (MouseHit (x, y)) {
01324     state = true;
01325     if (left) left->SetFrame (1);
01326     if (back) back->SetFrame (1);
01327     if (right) right->SetFrame (1);
01328     rc = true;
01329   }
01330 
01331   return rc;
01332 }
01333 
01334 bool CFuiButton::MouseStopClick (int x, int y, EMouseButton button)
01335 {
01336   bool rc = false;
01337 
01338   // If mouse is released inside button area and it was in the pressed state,
01339   //   then set it to unpressed and send the BUTTONPRESS event
01340   if (state == true) {
01341     state = false;
01342     globals->fuimgr->GenerateEventNotice (parentWindowId, id,
01343                                           EVENT_BUTTONPRESSED, EVENT_NOSUBEVENT);
01344     if (left) left->SetFrame (0);
01345     if (back) back->SetFrame (0);
01346     if (right) right->SetFrame (0);
01347     rc = true;
01348   }
01349 
01350   return rc;
01351 }
01352 
01353 
01354 //
01355 // CFuiPopupMenu
01356 //
01357 CFuiPopupMenu::CFuiPopupMenu (int x, int y, int w, int h, Tag window)
01358 : CFuiButton (x, y, w, h, window)
01359 {
01360   type = COMPONENT_POPUPMENU;
01361 
01362   just1 = just2 = just3 = 0;
01363 
01364   bmBack = NULL;
01365   bmLeft = NULL;
01366   bmRight = NULL;
01367 
01368   colText = MakeRGB (255, 255, 255);
01369   colSelection = MakeRGB (0, 0, 0);
01370 
01371   popupActive = false;
01372   selection = 0;
01373   xText  = yText = 0;
01374 }
01375 
01376 int CFuiPopupMenu::Read (SStream *stream, Tag tag)
01377 {
01378   int rc = TAG_IGNORED;
01379 
01380   switch (tag) {
01381   case 'just':
01382     {
01383       int i;
01384       ReadInt (&i, stream);
01385       just1 = (EFuiJustify) i;
01386       ReadInt (&i, stream);
01387       just2 = (EFuiJustify) i;
01388       ReadInt (&i, stream);
01389       just3 = (EFuiJustify) i;
01390     }
01391     rc = TAG_READ;
01392     break;
01393   }
01394 
01395   // Send tag to parent class for processing
01396   if (rc == TAG_IGNORED) {
01397     rc = CFuiButton::Read (stream, tag);
01398   }
01399 
01400   return rc;
01401 }
01402 
01403 void CFuiPopupMenu::ReadFinished (void)
01404 {
01405   CFuiComponent::ReadFinished ();
01406 
01407   // Get FUI theme for this component
01408   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
01409   if (tw == NULL) {
01410     char s[8];
01411     TagToString (s, widgetTag);
01412     globals->logWarning->Write ("CFuiPopupMenu : Cannot get theme widget %s", s);
01413   } else {
01414     // Locals for bitmap width/height
01415     int bmw = 0;
01416     int bmh = 0;
01417 
01418     // Width of left and right bitmaps determines size of center (back) bitmap
01419     int wLeft = 0;
01420     int wRight = 0;
01421 
01422     // Get optional left frame bitmap
01423     bmLeft = tw->GetBitmap ("LEFT");
01424     if (bmLeft != NULL) {
01425       GetBitmapSize (bmLeft, &bmw, &bmh);
01426       xText = bmw;
01427       wLeft = bmw;
01428       CFuiPicture *left = new CFuiPicture (0, 0, bmw, bmh);
01429       left->SetBitmap (bmLeft);
01430       left->SetParentPosition (x, y);
01431       decorationList.push_back (left);
01432     }
01433 
01434     // Get optional right frame bitmap
01435     bmRight = tw->GetBitmap ("RIGHT");
01436     if (bmRight != NULL) {
01437       GetBitmapSize (bmRight, &bmw, &bmh);
01438       wRight = bmw;
01439       CFuiPicture *right = new CFuiPicture (w-wRight, 0, bmw, bmh);
01440       right->SetBitmap (bmRight);
01441       right->SetParentPosition (x, y);
01442       decorationList.push_back (right);
01443     }
01444 
01445     // Get optional backdrop frame bitmap
01446     bmBack = tw->GetBitmap ("BACK");
01447     if (bmBack != NULL) {
01448       GetBitmapSize (bmBack, &bmw, &bmh);
01449       CFuiPicture *back = new CFuiPicture (wLeft, 0, w-wLeft-wRight, bmh);
01450       back->SetBitmap (bmBack);
01451       back->SetParentPosition (x, y);
01452       decorationList.push_back (back);
01453     }
01454 
01455     // Get text colour
01456     colText = tw->GetColour ("TEXT");
01457     colSelection = tw->GetColour ("SELECTION");
01458   }
01459 }
01460 
01461 void CFuiPopupMenu::SetParentPosition (int xParent, int yParent)
01462 {
01463   CFuiComponent::SetParentPosition (xParent, yParent);
01464 
01465   // Update all decorations
01466   list<CFuiComponent*>::iterator i;
01467   for (i=decorationList.begin(); i!=decorationList.end(); i++) {
01468     (*i)->SetParentPosition (xParent + x, yParent + y);
01469   }
01470 }
01471 
01472 void CFuiPopupMenu::Draw (void)
01473 {
01474   if (surface != NULL) {
01475     // Draw decoration components
01476     list<CFuiComponent*>::iterator i;
01477     for (i=decorationList.begin(); i!=decorationList.end(); i++) {
01478       CFuiComponent *component = *i;
01479       if (component->IsType (COMPONENT_PICTURE)) {
01480         CFuiPicture *picture = (CFuiPicture *)component;
01481         picture->Draw ();
01482       }
01483     }
01484 
01485     // If active, draw all choices on popup surface
01486     if (popupActive) {
01488     } else {
01489       // Popup is not active; just display current selection
01490       char s[256];
01491       GetItemSelection (s);
01492       DrawText (surface, font, xText, yText, colText, s);
01493     }
01494   }
01495 
01496   CFuiComponent::Draw ();
01497 }
01498 
01499 void CFuiPopupMenu::ClearItems (void)
01500 {
01501   items.clear();
01502 }
01503 
01504 void CFuiPopupMenu::AddItem (Tag item, const char *label)
01505 {
01506   items[item] = label;
01507 }
01508 
01509 void CFuiPopupMenu::AddSeparator (void)
01510 {
01511   // @todo Implement popup menu separator, may require item storage in multimap
01512 }
01513 
01514 void CFuiPopupMenu::RemoveItem (Tag item)
01515 {
01516   items.erase(item);
01517 }
01518 
01519 void CFuiPopupMenu::SelectItem (Tag item)
01520 {
01521   selection = item;
01522 }
01523 
01524 Tag CFuiPopupMenu::GetItemSelection (char *outText)
01525 {
01526   Tag rc = 0;
01527   strcpy (outText, "");
01528 
01529   map<Tag, string>::iterator i = items.find(selection);
01530   if (i != items.end()) {
01531     rc = selection;
01532     strcpy (outText, i->second.c_str());
01533   }
01534 
01535   return rc;
01536 }
01537 
01538 
01539 //
01540 // CFuiCheckbox
01541 //
01542 CFuiCheckbox::CFuiCheckbox (int x, int y, int w, int h, Tag window)
01543 : CFuiComponent (x, y, w, h, window)
01544 {
01545   type = COMPONENT_CHECKBOX;
01546   widgetTag = 'defa';
01547   strcpy (widgetName, "CheckBox");
01548 
01549   bmBack = NULL;
01550   state = 0;
01551   pressed = false;
01552 }
01553 
01554 int CFuiCheckbox::Read (SStream *stream, Tag tag)
01555 {
01556   int rc = TAG_IGNORED;
01557 
01558   switch (tag) {
01559   case 'stat':
01560     ReadInt (&state, stream);
01561     rc = TAG_READ;
01562     break;
01563   }
01564 
01565   // Send tag to parent class for processing
01566   if (rc == TAG_IGNORED) {
01567     rc = CFuiComponent::Read (stream, tag);
01568   }
01569 
01570   return rc;
01571 }
01572 
01573 void CFuiCheckbox::ReadFinished (void)
01574 {
01575   CFuiComponent::ReadFinished ();
01576 
01577   // Get FUI theme for this component
01578   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
01579   if (tw == NULL) {
01580     char s[8];
01581     TagToString (s, widgetTag);
01582     gtfo ("Cannot get theme widget %s", s);
01583   }
01584 
01585   // Get backdrop bitmap, this is a 2-frame bitmap for the on/off radio button state
01586   bmBack = tw->GetBitmap ("BACK");
01587 }
01588 
01589 void CFuiCheckbox::Draw (void)
01590 {
01591   // Draw checkbox
01592   if (surface) {
01593     int dx = 0;
01594     int dy = 0;
01595 
01596     // Draw bitmap
01597     if (bmBack) {
01598       int frame = state;
01599       if (pressed) frame += 3;
01600       DrawBitmap (surface, bmBack, 0, 0, frame);
01601       GetBitmapSize (bmBack, &dx, &dy);
01602     }
01603 
01604     // Draw label
01605     unsigned int black = MakeRGB (0, 0, 0);
01606     int m = TextWidth (font, "m");
01607     DrawText (surface, font, dx+m, 0, black, text);
01608   }
01609 
01610   CFuiComponent::Draw ();
01611 }
01612 
01613 int CFuiCheckbox::GetState (void)
01614 {
01615   return state;
01616 }
01617 
01618 void CFuiCheckbox::SetState (int state)
01619 {
01620   this->state = state;
01621 }
01622 
01623 bool CFuiCheckbox::MouseClick (int x, int y, EMouseButton button)
01624 {
01625   bool rc = false;
01626   if (MouseHit (x, y)) {
01627     pressed = true;
01628     rc = true;
01629   }
01630   return rc;
01631 }
01632 
01633 bool CFuiCheckbox::MouseStopClick (int x, int y, EMouseButton button)
01634 {
01635   bool rc = false;
01636 
01637   // Only set the checkbox state if the widget was in the pressed state
01638   if (MouseHit (x, y) && pressed) {
01639     // Toggle state
01640     if (state == 0) {
01641       // Check
01642       SetState (1);
01643       globals->fuimgr->GenerateEventNotice (parentWindowId, id,
01644                                             EVENT_CHECKED, EVENT_NOSUBEVENT);
01645     } else {
01646       // Uncheck
01647       SetState (0);
01648       globals->fuimgr->GenerateEventNotice (parentWindowId, id,
01649                                             EVENT_UNCHECKED, EVENT_NOSUBEVENT);
01650     }
01651     pressed = false;
01652     rc = true;
01653   }
01654 
01655   return rc;
01656 }
01657 
01658 
01659 //
01660 // CFuiRadioButton
01661 //
01662 CFuiRadioButton::CFuiRadioButton (int x, int y, int w, int h, Tag window)
01663 : CFuiComponent (x, y, w, h, window)
01664 {
01665   type = COMPONENT_RADIOBUTTON;
01666   widgetTag = 'defa';
01667   strcpy (widgetName, "RadioButton");
01668 
01669   bmBack = NULL;
01670   state = 0;
01671   pressed = false;
01672 }
01673 
01674 int CFuiRadioButton::Read (SStream *stream, Tag tag)
01675 {
01676   int rc = TAG_IGNORED;
01677 
01678   switch (tag) {
01679   case 'stat':
01680     ReadInt (&state, stream);
01681     SetState (state);
01682     rc = TAG_READ;
01683     break;
01684   }
01685 
01686   // Send tag to parent class for processing
01687   if (rc == TAG_IGNORED) {
01688     rc = CFuiComponent::Read (stream, tag);
01689   }
01690 
01691   return rc;
01692 }
01693 
01694 void CFuiRadioButton::ReadFinished (void)
01695 {
01696   CFuiComponent::ReadFinished ();
01697 
01698   // Get FUI theme for this component
01699   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
01700   if (tw == NULL) {
01701     char s[8];
01702     TagToString (s, widgetTag);
01703     gtfo ("Cannot get theme widget %s", s);
01704   }
01705 
01706   // Get backdrop bitmap, this is a 2-frame bitmap for the on/off radio button state
01707   bmBack = tw->GetBitmap ("BACK");
01708 }
01709 
01710 void CFuiRadioButton::Draw (void)
01711 {
01712   // Draw radio button
01713   if (surface) {
01714     int dx = 0;
01715     int dy = 0;
01716 
01717     // Draw bitmap
01718     // Radio button bitmaps are 9-frame PBGs with the following frame layout:
01719     //   0 - Unchecked normal
01720     //   1 - Checked normal
01721     //   2 - N/A normal
01722     //   3 - Unchecked depressed
01723     //   4 - Checked depressed
01724     //   5 - N/A depressed
01725     //   6 - Unchecked grayed-out
01726     //   7 - Checked grayed-out
01727     //   8 - N/A grayed-out
01728 
01729     if (bmBack) {
01730       int frame = 0;
01731       // @todo Check for grayed out
01732       frame = state;
01733       if (pressed) frame += 3;
01734       DrawBitmap (surface, bmBack, 0, 0, frame);
01735       GetBitmapSize (bmBack, &dx, &dy);
01736     }
01737 
01738     // Draw label separated by m-width from bitmap
01739     unsigned int black = MakeRGB (0, 0, 0);
01740     int m = TextWidth (font, "m");
01741     DrawText (surface, font, dx+m, 0, black, text);
01742   }
01743 
01744   CFuiComponent::Draw ();
01745 }
01746 
01747 int CFuiRadioButton::GetState (void)
01748 {
01749   return state;
01750 }
01751 
01752 void CFuiRadioButton::SetState (int state)
01753 {
01754   this->state = state;
01755 }
01756 
01757 //
01758 // Clicking does not change the state; the owner application must 
01759 //   change state in response to EVENT_CHECKED
01760 //
01761 bool CFuiRadioButton::MouseClick (int x, int y, EMouseButton button)
01762 {
01763   bool rc = false;
01764   if (MouseHit (x, y)) {
01765     pressed = true;
01766     rc = true;
01767   }
01768   return rc;
01769 }
01770 
01771 bool CFuiRadioButton::MouseStopClick (int x, int y, EMouseButton button)
01772 {
01773   bool rc = false;
01774 
01775   // Always reset pressed flag, it will only be set if mouse was clicked inside
01776   //   the radio button
01777   pressed = false;
01778 
01779   // If mouse clicked inside button area, send EVENT_CHECKED.  The state
01780   //   of linked radio buttons must be set by the controlling application.
01781   //   event is only sent when the button is clicked and released
01782   if (MouseHit (x, y)) {
01783     SetState (1);
01784     globals->fuimgr->GenerateEventNotice (parentWindowId, id,
01785                                           EVENT_CHECKED, EVENT_NOSUBEVENT);
01786     rc = true;
01787   }
01788 
01789   return rc;
01790 }
01791 
01792 
01793 
01794 //
01795 // CFuiLabel
01796 //
01797 CFuiLabel::CFuiLabel (int x, int y, int w, int h, Tag window)
01798 : CFuiComponent (x, y, w, h, window)
01799 {
01800   type = COMPONENT_LABEL;
01801   widgetTag = 'defa';
01802   strcpy (widgetName, "Label");
01803 
01804   just = wrap = 0;
01805 
01806   colText = MakeRGB (255, 255, 255);
01807   colShadow = MakeRGB (0, 0, 0);
01808   useShadow = false;
01809 }
01810 
01811 int CFuiLabel::Read (SStream *stream, Tag tag)
01812 {
01813   int rc = TAG_IGNORED;
01814 
01815   switch (tag) {
01816   case 'just':
01817     ReadInt (&just, stream);
01818     rc = TAG_READ;
01819     break;
01820   case 'wrap':
01821     ReadInt (&wrap, stream);
01822     rc = TAG_READ;
01823     break;
01824   }
01825 
01826   // Send tag to parent class for processing
01827   if (rc == TAG_IGNORED) {
01828     rc = CFuiComponent::Read (stream, tag);
01829   }
01830 
01831   return rc;
01832 }
01833 
01834 void CFuiLabel::ReadFinished (void)
01835 {
01836   CFuiComponent::ReadFinished ();
01837 
01838   // Get FUI theme for this component
01839   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
01840   if (tw == NULL) {
01841     char s[8];
01842     TagToString (s, widgetTag);
01843     globals->logWarning->Write ("CFuiLabel : Cannot get theme widget %s", s);
01844   }
01845 
01846   // Get theme components
01847   colText = tw->GetColour ("TEXT");
01848   colShadow = tw->GetColour ("SHADOW");
01849   useShadow = tw->GetFlag ("USESHADOW");
01850 }
01851 
01852 void CFuiLabel::Draw (void)
01853 {
01854   if (surface != NULL) {
01855     EraseSurface (surface);
01856 
01857     // Calculate y-offset
01858     int y = 0;
01859     if (just & JUSTIFY_V_TOP) {
01860       y = 0;
01861     } else if (just & JUSTIFY_V_CENTER) {
01862       y = (surface->ySize - MaxCharHeight(font)) / 2;
01863     } else if (just & JUSTIFY_V_BOTTOM) {
01864       y = surface->ySize - MaxCharHeight(font);
01865     }
01866 
01867     // Draw justified text
01868     if (just & JUSTIFY_H_LEFT) {
01869       DrawText (surface, font, 0, y, colText, text);
01870     } else if (just & JUSTIFY_H_CENTER) {
01871       DrawTextC (surface, font, w/2, y, colText, text);
01872     } else if (just & JUSTIFY_H_RIGHT) {
01873       int tw = TextWidth (font, text);
01874       DrawTextR (surface, font, w-tw, y, colText, text);
01875     } else {
01876       globals->logWarning->Write ("CFuiLabel : No horizontal justification (%d)", just);
01877     }
01878   }
01879 
01880   CFuiComponent::Draw ();
01881 }
01882 
01883 void CFuiLabel::SetColour (unsigned int colour)
01884 {
01885   colText = colour;
01886 }
01887 
01888 //
01889 // CFuiTextField
01890 //
01891 CFuiTextField::CFuiTextField (int x, int y, int w, int h, Tag window)
01892 : CFuiComponent (x, y, w, h, window)
01893 {
01894   type = COMPONENT_TEXTFIELD;
01895   widgetTag = 'defa';
01896   strcpy (widgetName, "TextField");
01897 
01898   bmBack = NULL;
01899   bmTop = NULL;
01900   bmBottom = NULL;
01901   bmLeft = NULL;
01902   bmRight = NULL;
01903   bmTopLeft = NULL;
01904   bmTopRight = NULL;
01905   bmBottomLeft = NULL;
01906   bmBottomRight = NULL;
01907 
01908   colText = MakeRGB (0, 0, 0);
01909   colHighlight = MakeRGB (128, 0, 128);
01910   colTextHighlight = MakeRGB (255, 255, 255);
01911   colLine = MakeRGB (0, 0, 0);
01912   colFill = MakeRGB (0, 0, 0);
01913   colFillDisabled = MakeRGB (128, 0, 128);
01914   colCaret = MakeRGB (0, 0, 0);
01915 
01916   pass = false;
01917   nChars = 0;
01918   data = NULL;
01919   numb = 0;
01920   ignore_background = false;
01921 }
01922 
01923 CFuiTextField::~CFuiTextField (void)
01924 {
01925   if (data != NULL) delete[] data;
01926 }
01927   
01928 int CFuiTextField::Read (SStream *stream, Tag tag)
01929 {
01930   int rc = TAG_IGNORED;
01931 
01932   switch (tag) {
01933   case 'pass':
01934     ReadInt (&pass, stream);
01935     rc = TAG_READ;
01936     break;
01937 
01938   case 'chrs':
01939     ReadInt (&nChars, stream);
01940     SetMaxChars (nChars);
01941     rc = TAG_READ;
01942     break;
01943 
01944   case 'numb':
01945     ReadInt (&numb, stream);
01946     rc = TAG_READ;
01947     break;
01948   }
01949 
01950   // Send tag to parent class for processing.
01951   if (rc == TAG_IGNORED) {
01952     rc = CFuiComponent::Read (stream, tag);
01953   }
01954 
01955   return rc;
01956 }
01957 
01958 void CFuiTextField::ReadFinished (void)
01959 {
01960   CFuiComponent::ReadFinished ();
01961 
01962   // Get FUI theme for this component
01963   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
01964   if (tw == NULL) {
01965     char s[8];
01966     TagToString (s, widgetTag);
01967     globals->logWarning->Write ("CFuiLabel : Cannot get theme widget %s", s);
01968   } else {
01969     // Locals for bitmap width/height
01970     int bmw = 0;
01971     int bmh = 0;
01972 
01973     // Get optional top-left corner bitmap
01974     bmTopLeft = tw->GetBitmap ("TOPLEFT");
01975     if (bmTopLeft != NULL) {
01976       GetBitmapSize (bmTopLeft, &bmw, &bmh);
01977       CFuiPicture *topleft = new CFuiPicture (0, 0, bmw, bmh);
01978       topleft->SetBitmap (bmTopLeft);
01979       topleft->SetParentPosition (x, y);
01980       decorationList.push_back (topleft);
01981     }
01982 
01983     // Get optional top frame bitmap
01984     bmTop = tw->GetBitmap ("TOP");
01985     if (bmTop != NULL) {
01986       GetBitmapSize (bmTop, &bmw, &bmh);
01987       CFuiPicture *top = new CFuiPicture (0, 0, w, bmh);
01988       top->SetBitmap (bmTop);
01989       top->SetParentPosition (x, y);
01990       decorationList.push_back (top);
01991     }
01992 
01993     // Get optional bottom frame bitmap
01994     bmBottom = tw->GetBitmap ("BOTTOM");
01995     if (bmBottom != NULL) {
01996       GetBitmapSize (bmBottom, &bmw, &bmh);
01997       CFuiPicture *bottom = new CFuiPicture (0, h-bmh, w, bmh);
01998       bottom->SetBitmap (bmBottom);
01999       bottom->SetParentPosition (x, y);
02000       decorationList.push_back (bottom);
02001     }
02002 
02003     // Get optional left frame bitmap
02004     bmLeft = tw->GetBitmap ("LEFT");
02005     if (bmLeft != NULL) {
02006       GetBitmapSize (bmLeft, &bmw, &bmh);
02007       CFuiPicture *left = new CFuiPicture (0, 0, bmw, h);
02008       left->SetBitmap (bmLeft);
02009       left->SetParentPosition (x, y);
02010       decorationList.push_back (left);
02011     }
02012 
02013     // Get optional right frame bitmap
02014     bmRight = tw->GetBitmap ("RIGHT");
02015     if (bmRight != NULL) {
02016       GetBitmapSize (bmRight, &bmw, &bmh);
02017       CFuiPicture *right = new CFuiPicture (w-bmw, 0, bmw, h);
02018       right->SetBitmap (bmRight);
02019       right->SetParentPosition (x, y);
02020       decorationList.push_back (right);
02021     }
02022 
02023     // Get optional top-right corner bitmap
02024     bmTopRight = tw->GetBitmap ("TOPRIGHT");
02025     if (bmTopRight != NULL) {
02026       GetBitmapSize (bmTopRight, &bmw, &bmh);
02027       CFuiPicture *topright = new CFuiPicture (w-bmw, 0, bmw, bmh);
02028       topright->SetBitmap (bmTopRight);
02029       topright->SetParentPosition (x, y);
02030       decorationList.push_back (topright);
02031     }
02032 
02033     // Get optional bottom-left corner bitmap
02034     bmBottomLeft = tw->GetBitmap ("BOTLEFT");
02035     if (bmBottomLeft != NULL) {
02036       GetBitmapSize (bmBottomLeft, &bmw, &bmh);
02037       CFuiPicture *botleft = new CFuiPicture (0, h-bmh, bmw, bmh);
02038       botleft->SetBitmap (bmBottomLeft);
02039       botleft->SetParentPosition (x, y);
02040       decorationList.push_back (botleft);
02041     }
02042 
02043     // Get optional bottom-right corner bitmap
02044     bmBottomRight = tw->GetBitmap ("BOTRIGHT");
02045     if (bmBottomRight != NULL) {
02046       GetBitmapSize (bmBottomRight, &bmw, &bmh);
02047       CFuiPicture *botright = new CFuiPicture (w-bmw, h-bmh, bmw, bmh);
02048       botright->SetBitmap (bmBottomRight);
02049       botright->SetParentPosition (x, y);
02050       decorationList.push_back (botright);
02051     }
02052 
02053     // Get window backdrop bitmap from the theme.  This is not added to the decoration
02054     //   list since the ignore_backdrop flag will determine if it is drawn or not.
02055     bmBack = tw->GetBitmap ("BACK");
02056 
02057     // Get text colours
02058     colText = tw->GetColour ("TEXT");
02059     colHighlight = tw->GetColour ("HILITE");
02060     colTextHighlight = tw->GetColour ("TEXTHILITE");
02061     colLine = tw->GetColour ("LINE");
02062     colFill = tw->GetColour ("FILL");
02063     colFillDisabled = tw->GetColour ("FILLDISABLED");
02064     colCaret = tw->GetColour ("CARET");
02065     ignore_background = tw->GetFlag ("IGNORE_BITMAP_BACKGROUND");
02066   }
02067 }
02068 
02069 void CFuiTextField::SetParentPosition (int xParent, int yParent)
02070 {
02071   CFuiComponent::SetParentPosition (xParent, yParent);
02072 
02073   // Update all decorations
02074   list<CFuiComponent*>::iterator i;
02075   for (i=decorationList.begin(); i!=decorationList.end(); i++) {
02076     (*i)->SetParentPosition (xParent + x, yParent + y);
02077   }
02078 }
02079 
02080 void CFuiTextField::Draw (void)
02081 {
02082   if (surface != NULL) {
02083     // Fill surface with fill colour
02084     // @todo Check for enable/disable state
02085     EraseSurfaceRGB (surface, colFill);
02086 
02087     // Draw background bitmap if not transparent
02088     if ((bmBack != NULL) && !ignore_background) {
02089       DrawBitmap (surface, bmBack, 0, 0, 0);
02090     }
02091 
02092     // Draw decoration components
02093     list<CFuiComponent*>::iterator i;
02094     for (i=decorationList.begin(); i!=decorationList.end(); i++) {
02095       (*i)->Draw();
02096     }
02097 
02098     if (data != NULL) {
02099       DrawText (surface, font, 0, 0, colText, data);
02100     }
02101     
02102     // @todo If this text field is active, draw caret
02103   }
02104 
02105   CFuiComponent::Draw ();
02106 }
02107 
02108 void CFuiTextField::SetMaxChars (int maxChars)
02109 {
02110   // If new buffer size is the same as old buffer size, do nothing
02111   if (nChars == maxChars) return;
02112   
02113   // Allocate new char buffer
02114   char *newData = new char[maxChars+1];
02115   memset (newData, 0, maxChars+1);
02116   nChars = maxChars;
02117   
02118   // If a buffer already existed, copy contents to new buffer before deleting
02119   if (data != NULL) {
02120     strncpy (newData, data, nChars);
02121     delete data;
02122     data = newData;
02123   }
02124 }
02125 
02126 int CFuiTextField::GetMaxChars (void)
02127 {
02128   return nChars;
02129 }
02130 
02131 void CFuiTextField::UsePassword (int passwordFlag)
02132 {
02133   this->pass = passwordFlag;
02134 }
02135 
02136 int CFuiTextField::IsPassword (void)
02137 {
02138   return pass;
02139 }
02140 
02141 int CFuiTextField::GetLength (void)
02142 {
02143   // Return actual number of used characters in data buffer
02144   return strlen (data);
02145 }
02146 
02147 void CFuiTextField::SetText (char *text)
02148 {
02149   if (data != NULL) {
02150     strncpy (data, text, nChars);
02151   } else {
02152     // No data buffer exists, create it
02153     nChars = strlen(text) + 1;
02154     data = new char[nChars];
02155     strcpy (data, text);
02156   }  
02157 }
02158 
02159 char* CFuiTextField::GetText(void)
02160 {
02161   return data;
02162 }
02163 
02164 void CFuiTextField::SetSelection(int firstChar, int lastChar)
02165 {
02166 }
02167 
02168 void CFuiTextField::GetSelection(int *firstChar, int *lastChar)
02169 {
02170 }
02171 
02172 //
02173 // CFuiLine
02174 //
02175 CFuiLine::CFuiLine (int x, int y, int w, int h, Tag window)
02176 : CFuiComponent (x, y, w, h, window)
02177 {
02178   type = COMPONENT_LINE;
02179   widgetTag = 'defa';
02180   strcpy (widgetName, "Line");
02181 
02182   direction = FUI_LINE_HORIZONTAL;
02183   thickness = 1;
02184 }
02185 
02186 int CFuiLine::Read (SStream *stream, Tag tag)
02187 {
02188   int rc = TAG_IGNORED;
02189 
02190   switch (tag) {
02191   case 'dirc':
02192     ReadInt (&direction, stream);
02193     rc = TAG_READ;
02194     break;
02195 
02196   case 'thck':
02197     ReadInt (&thickness, stream);
02198     rc = TAG_READ;
02199     break;
02200   }
02201 
02202   // Send tag to parent class for processing
02203   if (rc == TAG_IGNORED) {
02204     rc = CFuiComponent::Read (stream, tag);
02205   }
02206 
02207   return rc;
02208 }
02209 
02210 void CFuiLine::ReadFinished (void)
02211 {
02212   CFuiComponent::ReadFinished ();
02213 
02214   // Get FUI theme for this component
02215   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
02216   if (tw == NULL) {
02217     char s[8];
02218     TagToString (s, widgetTag);
02219     globals->logWarning->Write ("CFuiLabel : Cannot get theme widget %s", s);
02220   } else {
02221     // Get theme components
02222     colLine = tw->GetColour ("LINE");
02223   }
02224 }
02225 
02226 void CFuiLine::Draw (void)
02227 {
02228   if (surface != NULL) {
02229     DrawLine (surface, x, y, x+w, y+h, colLine);
02230   }
02231 
02232   CFuiComponent::Draw ();
02233 }
02234 
02235 
02236 //
02237 // CFuiBox
02238 //
02239 CFuiBox::CFuiBox (int x, int y, int w, int h, Tag window)
02240 : CFuiComponent (x, y, w, h, window)
02241 {
02242   type = COMPONENT_BOX;
02243   widgetTag = 'defa';
02244   strcpy (widgetName, "Box");
02245 
02246   thickness = 0;
02247   colLine = MakeRGB (0, 0, 0);
02248   colFill = MakeRGB (0, 0, 0);
02249 }
02250 
02251 int CFuiBox::Read (SStream *stream, Tag tag)
02252 {
02253   int rc = TAG_IGNORED;
02254 
02255   switch (tag) {
02256   case 'thck':
02257     ReadInt (&thickness, stream);
02258     rc = TAG_READ;
02259     break;
02260   }
02261 
02262   // Send tag to parent class for processing
02263   if (rc == TAG_IGNORED) {
02264     rc = CFuiComponent::Read (stream, tag);
02265   }
02266 
02267   return rc;
02268 }
02269 
02270 void CFuiBox::ReadFinished (void)
02271 {
02272   CFuiComponent::ReadFinished ();
02273 
02274   // Get FUI theme for this component
02275   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
02276   if (tw == NULL) {
02277     char s[8];
02278     TagToString (s, widgetTag);
02279     globals->logWarning->Write ("CFuiLabel : Cannot get theme widget %s", s);
02280   } else {
02281     // Get theme components
02282     colLine = tw->GetColour ("LINE");
02283     colFill = tw->GetColour ("FILL");
02284   }
02285 }
02286 
02287 void CFuiBox::Draw (void)
02288 {
02289   if (surface != NULL) {
02290   }
02291 
02292   CFuiComponent::Draw ();
02293 }
02294 
02295 
02296 //
02297 // CFuiPicture
02298 //
02299 CFuiPicture::CFuiPicture (int x, int y, int w, int h, Tag window)
02300 : CFuiComponent (x, y, w, h, window)
02301 {
02302   type = COMPONENT_PICTURE;
02303   widgetTag = 'defa';
02304   strcpy (widgetName, "Picture");
02305   bm = NULL;
02306   destroyBitmap = false;
02307 
02308   // Initialize frame index, ensuring that first call to Draw() will force
02309   //   the bitmap to be drawn on the component surface
02310   lastFrame = -1;
02311   frame = 0;
02312 }
02313 
02314 CFuiPicture::~CFuiPicture (void)
02315 {
02316   if (destroyBitmap) {
02317     // Bitmap was instantiated by this widget instance, so it must be
02318     //   freed and deleted
02319     FreeBitmap (bm);
02320     delete bm;
02321   }
02322 }
02323 
02324 int CFuiPicture::Read (SStream *stream, Tag tag)
02325 {
02326   int rc = TAG_IGNORED;
02327 
02328   switch (tag) {
02329   case 'back':
02330     destroyBitmap = true;
02331     bm = new SBitmap;
02332     ReadString (bm->bitmapName, 64, stream);
02333     LoadBitmap (bm);
02334     rc = TAG_READ;
02335     break;
02336   }
02337 
02338   // Send tag to parent class for processing
02339   if (rc == TAG_IGNORED) {
02340     rc = CFuiComponent::Read (stream, tag);
02341   }
02342 
02343   return rc;
02344 }
02345 
02346 void CFuiPicture::ReadFinished (void)
02347 {
02348   CFuiComponent::ReadFinished();
02349 
02350   if (bm == NULL) {
02351     // No bitmap is currently defined.  Load default from theme
02352     CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
02353     if (tw == NULL) {
02354       char s[8];
02355       TagToString (s, widgetTag);
02356       globals->logWarning->Write ("CFuiLabel : Cannot get theme widget %s", s);
02357     } else {
02358       // Get theme components
02359       bm = tw->GetBitmap ("BACK");
02360       if (bm == NULL) {
02361         bm = tw->GetBitmap ("ALTBACK");
02362       }
02363     }
02364   }
02365 
02366   // Finally, if a bitmap was available from any source, assign it to the widget
02367   if (bm != NULL) {
02368     SetBitmap (bm);
02369   }
02370 }
02371 
02372 void CFuiPicture::SetBitmap (SBitmap *bm)
02373 {
02374   if (bm != NULL) {
02375     this->bm = bm;
02376 
02377     // If no width/height has been specified, use the bitmap width/height
02378     if ((this->w == 0) && (this->h == 0)) {
02379       GetBitmapSize (bm, &this->w, &this->h);
02380     }
02381     MakeSurface ();
02382   }
02383 }
02384 
02385 void CFuiPicture::DrawTiledBitmap (SBitmap *bitmap)
02386 {
02387   if (frame != lastFrame) {
02388     // Frame number has changed, redraw bitmap tiled across surface
02389     int bx, by;
02390     GetBitmapSize (bitmap, &bx, &by);
02391     for (int iy=0; iy<(int)surface->ySize; iy+=by) {
02392       for (int ix=0; ix<(int)surface->xSize; ix+=bx) {
02393         DrawBitmap (surface, bitmap, ix, iy, frame);
02394       }
02395     }
02396     lastFrame = frame;
02397   }
02398 }
02399 
02400 void CFuiPicture::Draw (void)
02401 {
02402   if (surface != NULL) {
02403     if (bm != NULL) {
02404       DrawTiledBitmap (bm);
02405     }
02406   }
02407 
02408   CFuiComponent::Draw ();
02409 }
02410 
02411 void CFuiPicture::DrawNoTiling (void)
02412 {
02413   if ((surface != NULL) && (frame != lastFrame)) {
02414     // Redraw bitmap at top-left corner of surface
02415     if (bm != NULL) {
02416       DrawBitmap (surface, bm, 0, 0, frame);
02417     }
02418     lastFrame = frame;
02419   }
02420 
02421   CFuiComponent::Draw ();
02422 }
02423 
02424 void CFuiPicture::SetFrame (int i)
02425 {
02426   frame = i;
02427 }
02428 
02429 
02430 //
02431 // CFuiMenuBar
02432 //
02433 
02434 //
02435 // CFuiScrollBar
02436 //
02437 
02438 //
02439 // CFuiSlider
02440 //
02441 CFuiSlider::CFuiSlider (int x, int y, int w, int h, Tag window)
02442 : CFuiComponent (x, y, w, h, window)
02443 {
02444   type = COMPONENT_SLIDER;
02445   widgetTag = 'defa';
02446   strcpy (widgetName, "Slider");
02447 
02448   bmBack = NULL;
02449   bmAltBack = NULL;
02450   bmHThumb = NULL;
02451   bmVThumb = NULL;
02452   bmHLTick = NULL;
02453   bmHSTick = NULL;
02454   bmVLTick = NULL;
02455   bmVSTick = NULL;
02456 
02457   back = NULL;
02458 
02459   minv = 0.0f;
02460   maxv = 100.0f;
02461   curv = 0.0f;
02462   majt = 20.0f;
02463   dmjt = true;
02464   mint = 10.0f;
02465   dmnt = true;
02466   snap = true;
02467   link = 0;
02468 
02469   vertical = false;
02470 }
02471 
02472 int CFuiSlider::Read (SStream *stream, Tag tag)
02473 {
02474   int rc = TAG_IGNORED;
02475 
02476   switch (tag) {
02477   case 'maxv':
02478     ReadFloat (&maxv, stream);
02479     rc = TAG_READ;
02480     break;
02481   case 'minv':
02482     ReadFloat (&minv, stream);
02483     rc = TAG_READ;
02484     break;
02485   case 'curv':
02486     ReadFloat (&curv, stream);
02487     rc = TAG_READ;
02488     break;
02489   case 'majt':
02490     ReadFloat (&majt, stream);
02491     rc = TAG_READ;
02492     break;
02493   case 'dmjt':
02494     {
02495       int i;
02496       ReadInt (&i, stream);
02497       dmjt = (i != 0);
02498     }
02499     rc = TAG_READ;
02500     break;
02501   case 'mint':
02502     ReadFloat (&mint, stream);
02503     rc = TAG_READ;
02504     break;
02505   case 'dmnt':
02506     {
02507       int i;
02508       ReadInt (&i, stream);
02509       dmnt = (i != 0);
02510     }
02511     rc = TAG_READ;
02512     break;
02513   case 'snap':
02514     {
02515       int i;
02516       ReadInt (&i, stream);
02517       snap = (i != 0);
02518     }
02519     rc = TAG_READ;
02520     break;
02521   case 'link':
02522     ReadTag (&link, stream);
02523     rc = TAG_READ;
02524     break;
02525   }
02526   
02527   // Send tag to parent class for processing.
02528   if (rc == TAG_IGNORED) {
02529     rc = CFuiComponent::Read (stream, tag);
02530   }
02531 
02532   return rc;
02533 }
02534 
02535 void CFuiSlider::ReadFinished (void)
02536 {
02537   CFuiComponent::ReadFinished ();
02538 
02539   // Get FUI theme for this component
02540   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
02541   if (tw == NULL) {
02542     char s[8];
02543     TagToString (s, widgetTag);
02544     globals->logWarning->Write ("CFuiLabel : Cannot get theme widget %s", s);
02545   } else {
02546     // Get backdrop bitmap
02547     bmBack = tw->GetBitmap ("BACK");
02548     if (bmBack != NULL) {
02549       int bmw, bmh;
02550       GetBitmapSize (bmBack, &bmw, &bmh);
02551       back = new CFuiPicture (0, 0, w, bmh);
02552       back->SetBitmap (bmBack);
02553       back->SetParentPosition (x, y);
02554     }
02555 
02556     // Get alternate backdrop bitmap
02557     bmAltBack = tw->GetBitmap ("ALTBACK");
02558 
02559     // Get horizontal thumb bitmap
02560     bmHThumb = tw->GetBitmap ("HTHUMB");
02561 
02562     // Get vertical thumb bitmap
02563     bmVThumb = tw->GetBitmap ("VTHUMB");
02564 
02565     // Get horizontal major tick bitmap
02566     bmHLTick = tw->GetBitmap ("HLTICK");
02567 
02568     // Get horizontal minor tick bitmap
02569     bmHSTick = tw->GetBitmap ("HSTICK");
02570 
02571     // Get vertical major tick bitmap
02572     bmVLTick = tw->GetBitmap ("VLTICK");
02573 
02574     // Get vertical minor tick bitmap
02575     bmVSTick = tw->GetBitmap ("VSTICK");
02576   }
02577 }
02578 
02579 void CFuiSlider::SetParentPosition (int xParent, int yParent)
02580 {
02581   CFuiComponent::SetParentPosition (xParent, yParent);
02582 
02583   // Update position of slider backdrop
02584   back->SetParentPosition (xParent + x, yParent + y);
02585 }
02586 
02587 void CFuiSlider::Draw (void)
02588 {
02589   if (surface != NULL) {
02590     // Draw backdrop bitmap if it exists.  The bitmap width or height will be 
02591     //   used to offset the drawing of any tick marks.
02592     if (back != NULL) {
02593       back->Draw ();
02594     }
02595 
02596     // Select horizontal or vertical bitmap sets
02597     if (vertical) {
02598       // Get thumb bitmap size in order to offset any tick marks
02599       int bmw = 0;
02600       int bmh = 0;
02601       if (bmVThumb) {
02602         GetBitmapSize (bmVThumb, &bmw, &bmh);
02603       }
02604 
02605       // Draw minor ticks
02606       if (dmnt && bmVSTick && (mint > 0)) {
02607         for (float f=minv; f<=maxv; f+=mint) {
02608           int yTick = (int)((float)h * ((f - minv) / (maxv - minv)));
02609           DrawBitmap (surface, bmVSTick, bmw, yTick, 0);
02610         }
02611       }
02612 
02613       // Draw major ticks
02614       if (dmjt && bmVLTick && (majt > 0)) {
02615         for (float f=0; f<=maxv; f+=majt) {
02616           int yTick = (int)((float)h * ((f - minv) / (maxv - minv)));
02617           DrawBitmap (surface, bmVSTick, bmw, yTick, 0);
02618         }
02619       }
02620 
02621       // Draw indicator
02622       if (bmVThumb) {
02623         DrawBitmap (surface, bmVThumb, 0, 0, 0);
02624       }
02625 
02626     } else {
02627       // Get thumb bitmap size in order to offset any tick marks
02628       int bmw = 0;
02629       int bmh = 0;
02630       if (bmHThumb) {
02631         GetBitmapSize (bmHThumb, &bmw, &bmh);
02632       }
02633 
02634       // Draw minor ticks
02635       if (dmnt && bmHSTick && (mint > 0)) {
02636         for (float f=minv; f<=maxv; f+=mint) {
02637           int xTick = (int)((float)w * ((f - minv) / (maxv - minv)));
02638           DrawBitmap (surface, bmHSTick, xTick, bmh, 0);
02639         }
02640       }
02641 
02642       // Draw major ticks
02643       if (dmjt && bmHLTick && (majt > 0)) {
02644         for (float f=minv; f<=maxv; f+=majt) {
02645           int xTick = (int)((float)w * ((f - minv) / (maxv - minv)));
02646           DrawBitmap (surface, bmHSTick, xTick, bmh, 0);
02647         }
02648       }
02649 
02650       // Draw indicator
02651       if (bmHThumb) {
02652         DrawBitmap (surface, bmHThumb, 0, 0, 0);
02653       }
02654     }
02655   }
02656 
02657   CFuiComponent::Draw ();
02658 }
02659 
02660 void CFuiSlider::SetMajorTickSpacing (float spacing)
02661 {
02662   majt = spacing;
02663 }
02664 
02665 void CFuiSlider::SetMinorTickSpacing (float spacing)
02666 {
02667   mint = spacing;
02668 }
02669 
02670 void CFuiSlider::SetSnapToTicks (int snapFlag)
02671 {
02672   snap = snapFlag;
02673 }
02674 
02675 void CFuiSlider::SetDrawMajorTicks (int drawFlag)
02676 {
02677   dmjt = drawFlag;
02678 }
02679 
02680 void CFuiSlider::SetDrawMinorTicks (int drawFlag)
02681 {
02682   dmnt = drawFlag;
02683 }
02684 
02685 float CFuiSlider::GetMajorTickSpacing (void)
02686 {
02687   return majt;
02688 }
02689 
02690 float CFuiSlider::GetMinorTickSpacing (void)
02691 {
02692   return mint;
02693 }
02694 
02695 int CFuiSlider::GetSnapToTicks (void)
02696 {
02697   return snap;
02698 }
02699 
02700 int CFuiSlider::GetDrawMajorTicks (void)
02701 {
02702   return dmjt;
02703 }
02704 
02705 int CFuiSlider::GetDrawMinorTicks (void)
02706 {
02707   return dmnt;
02708 }
02709 
02710 
02711 //
02712 // CFuiGauge
02713 //
02714 
02715 
02716 
02717 //
02718 // CFuiGroupBox
02719 //
02720 CFuiGroupBox::CFuiGroupBox (int x, int y, int w, int h, Tag window)
02721 : CFuiComponent (x, y, w, h, window)
02722 {
02723   type = COMPONENT_GROUPBOX;
02724   widgetTag = 'defa';
02725   strcpy (widgetName, "GroupBox");
02726 
02727   bmBack = NULL;
02728   bmTop = NULL;
02729   bmBottom = NULL;
02730   bmLeft = NULL;
02731   bmRight = NULL;
02732   bmTopLeft = NULL;
02733   bmTopRight = NULL;
02734   bmBottomLeft = NULL;
02735   bmBottomRight = NULL;
02736 
02737   transparent = true;
02738   colText = MakeRGB (0, 0, 0);
02739   xText = 0;
02740 }
02741 
02742 // @todo CFuiGroupBox destructor
02743 
02744 int CFuiGroupBox::Read (SStream *stream, Tag tag)
02745 {
02746   int rc = TAG_IGNORED;
02747 
02748   // Add subcomponent if applicable
02749   if (ValidFuiComponentType (tag)) {
02750     CFuiComponent *c = CreateFuiComponent ((EFuiComponentTypes)tag);
02751     if (c != NULL) {
02752       ReadFrom (c, stream);
02753       c->SetParentPosition (x, y);
02754       childList.push_back (c);
02755       rc = TAG_READ;
02756     } else {
02757       char s[8];
02758       globals->logWarning->Write ("CFuiGroupBox : Skipping unsupported widget %s",
02759         TagString (s, tag));
02760       SkipObject (stream);
02761     }
02762     rc = TAG_READ;
02763   }
02764 
02765   // Send tag to parent class for processing.
02766   if (rc == TAG_IGNORED) {
02767     rc = CFuiComponent::Read (stream, tag);
02768   }
02769 
02770   return rc;
02771 }
02772 
02773 void CFuiGroupBox::ReadFinished (void)
02774 {
02775   CFuiComponent::ReadFinished ();
02776 
02777   // Get FUI theme for this component
02778   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
02779   if (tw == NULL) {
02780     char s[8];
02781     TagToString (s, widgetTag);
02782     globals->logWarning->Write ("CFuiLabel : Cannot get theme widget %s", s);
02783   } else {
02784     // Locals for bitmap width/height
02785     int bmw = 0;
02786     int bmh = 0;
02787 
02788     // Get optional top-left corner bitmap
02789     bmTopLeft = tw->GetBitmap ("TOPLEFT");
02790     if (bmTopLeft != NULL) {
02791       GetBitmapSize (bmTopLeft, &bmw, &bmh);
02792       CFuiPicture *topleft = new CFuiPicture (0, 0, bmw, bmh);
02793       topleft->SetBitmap (bmTopLeft);
02794       topleft->SetParentPosition (x, y);
02795       decorationList.push_back (topleft);
02796     }
02797 
02798     // Set x offset for text label to width of top-left bitmap
02799     xText = bmw;
02800 
02801     // Get optional top frame bitmap
02802     bmTop = tw->GetBitmap ("TOP");
02803     if (bmTop != NULL) {
02804       GetBitmapSize (bmTop, &bmw, &bmh);
02805       CFuiPicture *top = new CFuiPicture (0, 0, w, bmh);
02806       top->SetBitmap (bmTop);
02807       top->SetParentPosition (x, y);
02808       decorationList.push_back (top);
02809     }
02810 
02811     // Get optional bottom frame bitmap
02812     bmBottom = tw->GetBitmap ("BOTTOM");
02813     if (bmBottom != NULL) {
02814       GetBitmapSize (bmBottom, &bmw, &bmh);
02815       CFuiPicture *bottom = new CFuiPicture (0, h-bmh, w, bmh);
02816       bottom->SetBitmap (bmBottom);
02817       bottom->SetParentPosition (x, y);
02818       decorationList.push_back (bottom);
02819     }
02820 
02821     // Get optional left frame bitmap
02822     bmLeft = tw->GetBitmap ("LEFT");
02823     if (bmLeft != NULL) {
02824       GetBitmapSize (bmLeft, &bmw, &bmh);
02825       CFuiPicture *left = new CFuiPicture (0, 0, bmw, h);
02826       left->SetBitmap (bmLeft);
02827       left->SetParentPosition (x, y);
02828       decorationList.push_back (left);
02829     }
02830 
02831     // Get optional right frame bitmap
02832     bmRight = tw->GetBitmap ("RIGHT");
02833     if (bmRight != NULL) {
02834       GetBitmapSize (bmRight, &bmw, &bmh);
02835       CFuiPicture *right = new CFuiPicture (w-bmw, 0, bmw, h);
02836       right->SetBitmap (bmRight);
02837       right->SetParentPosition (x, y);
02838       decorationList.push_back (right);
02839     }
02840 
02841     // Get optional top-right corner bitmap
02842     bmTopRight = tw->GetBitmap ("TOPRIGHT");
02843     if (bmTopRight != NULL) {
02844       GetBitmapSize (bmTopRight, &bmw, &bmh);
02845       CFuiPicture *topright = new CFuiPicture (w-bmw, 0, bmw, bmh);
02846       topright->SetBitmap (bmTopRight);
02847       topright->SetParentPosition (x, y);
02848       decorationList.push_back (topright);
02849     }
02850 
02851     // Get optional bottom-left corner bitmap
02852     bmBottomLeft = tw->GetBitmap ("BOTLEFT");
02853     if (bmBottomLeft != NULL) {
02854       GetBitmapSize (bmBottomLeft, &bmw, &bmh);
02855       CFuiPicture *botleft = new CFuiPicture (0, h-bmh, bmw, bmh);
02856       botleft->SetBitmap (bmBottomLeft);
02857       botleft->SetParentPosition (x, y);
02858       decorationList.push_back (botleft);
02859     }
02860 
02861     // Get optional bottom-right corner bitmap
02862     bmBottomRight = tw->GetBitmap ("BOTRIGHT");
02863     if (bmBottomRight != NULL) {
02864       GetBitmapSize (bmBottomRight, &bmw, &bmh);
02865       CFuiPicture *botright = new CFuiPicture (w-bmw, h-bmh, bmw, bmh);
02866       botright->SetBitmap (bmBottomRight);
02867       botright->SetParentPosition (x, y);
02868       decorationList.push_back (botright);
02869     }
02870 
02871     // Get window backdrop bitmap from the theme.  This is not added to the decoration
02872     //   list since the transparent flag will determine if it is drawn or not.
02873     bmBack = tw->GetBitmap ("BACK");
02874 
02875     // Get text colour
02876     colText = tw->GetColour ("TEXT");
02877   }
02878 }
02879 
02880 void CFuiGroupBox::SetParentPosition (int xParent, int yParent)
02881 {
02882   CFuiComponent::SetParentPosition (xParent, yParent);
02883 
02884   // Update all decorations
02885   list<CFuiComponent*>::iterator i;
02886   for (i=decorationList.begin(); i!=decorationList.end(); i++) {
02887     (*i)->SetParentPosition (xParent + x, yParent + y);
02888   }
02889 
02890   // Update all children
02891   for (i=childList.begin(); i!=childList.end(); i++) {
02892     (*i)->SetParentPosition(xParent + x, yParent + y);
02893   }
02894 }
02895 
02896 void CFuiGroupBox::Draw (void)
02897 {
02898   if (surface != NULL) {
02899     // Draw background bitmap if groupbox is not transparent
02900     if ((bmBack != NULL) && !transparent) {
02901       DrawBitmap (surface, bmBack, 0, 0, 0);
02902     }
02903 
02904     // Draw groupbox decoration components
02905     list<CFuiComponent*>::iterator i;
02906     for (i=decorationList.begin(); i!=decorationList.end(); i++) {
02907       (*i)->Draw();
02908     }
02909 
02910     DrawText (surface, font, xText, 0, colText, text);
02911 
02912     // Draw child components
02913     for (i=childList.begin(); i!=childList.end(); i++) {
02914       (*i)->Draw();
02915     }
02916   }
02917 
02918   CFuiComponent::Draw ();
02919 }
02920 
02921 bool CFuiGroupBox::MouseMove (int mx, int my)
02922 {
02923   bool rc = false;
02924 
02925   // Send directly to child widgets
02926   list<CFuiComponent*>::iterator i;
02927   for (i=childList.begin(); i!=childList.end() && !rc; i++) {
02928     rc = (*i)->MouseMove (mx, my);
02929   }
02930 
02931   return rc;
02932 }
02933 
02934 bool CFuiGroupBox::MouseClick (int mx, int my, EMouseButton button)
02935 {
02936   bool rc = false;
02937 
02938   // Send directly to child widgets
02939   list<CFuiComponent*>::iterator i;
02940   for (i=childList.begin(); i!=childList.end() && !rc; i++) {
02941     rc = (*i)->MouseClick (mx, my, button);
02942   }
02943 
02944   return rc;
02945 }
02946 
02947 bool CFuiGroupBox::MouseStopClick (int mx, int my, EMouseButton button)
02948 {
02949   bool rc = false;
02950 
02951   // Send directly to child widgets
02952   list<CFuiComponent*>::iterator i;
02953   for (i=childList.begin(); i!=childList.end() && !rc; i++) {
02954     rc = (*i)->MouseStopClick (mx, my, button);
02955   }
02956 
02957   return rc;
02958 }
02959 
02960 
02961 
02962 //
02963 // CFuiGauge
02964 //
02965 
02966 
02967 //
02968 // CFuiListRow
02969 //
02970 
02971 CFuiListRow::CFuiListRow (void)
02972 {
02973   height = 0;
02974 }
02975 
02976 void CFuiListRow::SetHeight (unsigned int height)
02977 {
02978   this->height = height;
02979 }
02980 
02981 unsigned int CFuiListRow::GetHeight (void)
02982 {
02983   return height;
02984 }
02985 
02986 void CFuiListRow::SetText (const char *text)
02987 {
02988   this->text = text;
02989 }
02990 
02991 const char* CFuiListRow::GetText (void)
02992 {
02993   return text.c_str();
02994 }
02995 
02996 
02997 //
02998 // CFuiListColumn
02999 //
03000 CFuiListColumn::CFuiListColumn (void)
03001 {
03002   width = minWidth = 0;
03003 }
03004 
03005 void CFuiListColumn::SetWidth (unsigned int width)
03006 {
03007   this->width = width;
03008 }
03009 
03010 unsigned int CFuiListColumn::GetWidth (void)
03011 {
03012   return width;
03013 }
03014 
03015 void CFuiListColumn::SetTitle (const char *title)
03016 {
03017   this->title = title;
03018 }
03019 
03020 void CFuiListColumn::AddRow (CFuiListRow row)
03021 {
03022   // @todo Adjust minimum width
03023 
03024   // Add row to list
03025   rows.push_back (row);
03026 }
03027 
03028 void CFuiListColumn::DeleteRow (unsigned int row)
03029 {
03030   vector<CFuiListRow>::iterator i = rows.begin();
03031   for (unsigned int ir=0; (ir <= row) && (i != rows.end()); ir++, i++);
03032   if (i != rows.end()) {
03033     rows.erase (i);
03034   }
03035 }
03036 
03037 void CFuiListColumn::DeleteAllRows (void)
03038 {
03039   rows.clear();
03040 }
03041 
03042 CFuiListRow& CFuiListColumn::GetRow (unsigned int i)
03043 {
03044   return rows[i];
03045 }
03046 
03047 unsigned int CFuiListColumn::GetRowCount (void)
03048 {
03049   return rows.size();
03050 }
03051 
03052 
03053 //
03054 // CFuiList
03055 //
03056 CFuiList::CFuiList (int x, int y, int w, int h, Tag window)
03057 : CFuiComponent (x, y, w, h, window)
03058 {
03059   type = COMPONENT_LIST;
03060   widgetTag = 'defa';
03061   strcpy (widgetName, "List");
03062 
03063   utit = usrr = 0;
03064   multiselect = 0;
03065   vscroll = 0;
03066   hscroll = 0;
03067   dwidth = dheight = 0;
03068   autowidth = 0;
03069 
03070   bmTop = NULL;
03071   bmBottom = NULL;
03072   bmLeft = NULL;
03073   bmRight = NULL;
03074   bmTopLeft = NULL;
03075   bmTopRight = NULL;
03076   bmBottomLeft = NULL;
03077   bmBottomRight = NULL;
03078   bmHighlight = NULL;
03079   bmBack = NULL;
03080 
03081   colText = MakeRGB (0, 0, 0);
03082   colTextHighlight = MakeRGB (0, 0, 0);
03083   colHighlight = MakeRGB (255, 255, 0);
03084 
03085   scrollRow = scrollCol = 0;
03086   nRows = 0;
03087 }
03088 
03089 int CFuiList::Read (SStream *stream, Tag tag)
03090 {
03091   int rc = TAG_IGNORED;
03092 
03093   switch (tag) {
03094   case 'utit':
03095     ReadInt (&utit, stream);
03096     rc = TAG_READ;
03097     break;
03098   case 'usrr':
03099     ReadInt (&usrr, stream);
03100     rc = TAG_READ;
03101     break;
03102   case 'msel':
03103     ReadInt (&multiselect, stream);
03104     rc = TAG_READ;
03105     break;
03106   case 'vscr':
03107     ReadInt (&vscroll, stream);
03108     rc = TAG_READ;
03109     break;
03110   case 'hscr':
03111     ReadInt (&hscroll, stream);
03112     rc = TAG_READ;
03113     break;
03114   case 'dwid':
03115     ReadInt (&dwidth, stream);
03116     rc = TAG_READ;
03117     break;
03118   case 'dhgt':
03119     ReadInt (&dheight, stream);
03120     rc = TAG_READ;
03121     break;
03122   case 'autw':
03123     ReadInt (&autowidth, stream);
03124     rc = TAG_READ;
03125     break;
03126   }
03127 
03128   // Send tag to parent class for processing
03129   if (rc == TAG_IGNORED) {
03130     rc = CFuiComponent::Read (stream, tag);
03131   }
03132 
03133   return rc;
03134 }
03135 
03136 void CFuiList::ReadFinished (void)
03137 {
03138   CFuiComponent::ReadFinished ();
03139 
03140   // Get FUI theme for this component
03141   CFuiThemeWidget *tw = globals->fuimgr->GetThemeWidget (widgetTag, widgetName);
03142   if (tw == NULL) {
03143     char s[8];
03144     TagToString (s, widgetTag);
03145     globals->logWarning->Write ("CFuiList : Cannot get theme widget %s", s);
03146   } else {
03147     // Locals for bitmap width/height
03148     int bmw = 0;
03149     int bmh = 0;
03150 
03151     // Get optional top frame bitmap
03152     bmTop = tw->GetBitmap ("TOP");
03153     if (bmTop != NULL) {
03154       GetBitmapSize (bmTop, &bmw, &bmh);
03155       CFuiPicture *top = new CFuiPicture (0, 0, w, bmh);
03156       top->SetBitmap (bmTop);
03157       top->SetParentPosition (x, y);
03158       decorationList.push_back (top);
03159     }
03160 
03161     // Get optional bottom frame bitmap
03162     bmBottom = tw->GetBitmap ("BOTTOM");
03163     if (bmBottom != NULL) {
03164       GetBitmapSize (bmBottom, &bmw, &bmh);
03165       CFuiPicture *bottom = new CFuiPicture (0, h-bmh, w, bmh);
03166       bottom->SetBitmap (bmBottom);
03167       bottom->SetParentPosition (x, y);
03168       decorationList.push_back (bottom);
03169     }
03170 
03171     // Get optional left frame bitmap
03172     bmLeft = tw->GetBitmap ("LEFT");
03173     if (bmLeft != NULL) {
03174       GetBitmapSize (bmLeft, &bmw, &bmh);
03175       CFuiPicture *left = new CFuiPicture (0, 0, bmw, h);
03176       left->SetBitmap (bmLeft);
03177       left->SetParentPosition (x, y);
03178       decorationList.push_back (left);
03179     }
03180 
03181     // Get optional right frame bitmap
03182     bmRight = tw->GetBitmap ("RIGHT");
03183     if (bmRight != NULL) {
03184       GetBitmapSize (bmRight, &bmw, &bmh);
03185       CFuiPicture *right = new CFuiPicture (w-bmw, 0, bmw, h);
03186       right->SetBitmap (bmRight);
03187       right->SetParentPosition (x, y);
03188       decorationList.push_back (right);
03189     }
03190 
03191     // Get optional top-left corner bitmap
03192     bmTopLeft = tw->GetBitmap ("TOPLEFT");
03193     if (bmTopLeft != NULL) {
03194       GetBitmapSize (bmTopLeft, &bmw, &bmh);
03195       CFuiPicture *topleft = new CFuiPicture (0, 0, bmw, bmh);
03196       topleft->SetBitmap (bmTopLeft);
03197       topleft->SetParentPosition (x, y);
03198       decorationList.push_back (topleft);
03199     }
03200 
03201     // Get optional top-right corner bitmap
03202     bmTopRight = tw->GetBitmap ("TOPRIGHT");
03203     if (bmTopRight != NULL) {
03204       GetBitmapSize (bmTopRight, &bmw, &bmh);
03205       CFuiPicture *topright = new CFuiPicture (w-bmw, 0, bmw, bmh);
03206       topright->SetBitmap (bmTopRight);
03207       topright->SetParentPosition (x, y);
03208       decorationList.push_back (topright);
03209     }
03210 
03211     // Get optional bottom-left corner bitmap
03212     bmBottomLeft = tw->GetBitmap ("BOTLEFT");
03213     if (bmBottomLeft != NULL) {
03214       GetBitmapSize (bmBottomLeft, &bmw, &bmh);
03215       CFuiPicture *botleft = new CFuiPicture (0, h-bmh, bmw, bmh);
03216       botleft->SetBitmap (bmBottomLeft);
03217       botleft->SetParentPosition (x, y);
03218       decorationList.push_back (botleft);
03219     }
03220 
03221     // Get optional bottom-right corner bitmap
03222     bmBottomRight = tw->GetBitmap ("BOTRIGHT");
03223     if (bmBottomRight != NULL) {
03224       GetBitmapSize (bmBottomRight, &bmw, &bmh);
03225       CFuiPicture *botright = new CFuiPicture (w-bmw, h-bmh, bmw, bmh);
03226       botright->SetBitmap (bmBottomRight);
03227       botright->SetParentPosition (x, y);
03228       decorationList.push_back (botright);
03229     }
03230 
03231     // Get optional highlight bitmap
03232     bmHighlight = tw->GetBitmap ("HIGHLIGHT");
03233     if (bmHighlight != NULL) {
03234       GetBitmapSize (bmHighlight, &bmw, &bmh);
03235       CFuiPicture *highlight = new CFuiPicture (0, 0, bmw, bmh);
03236       highlight->SetBitmap (bmBottomRight);
03237       highlight->SetParentPosition (x, y);
03238       decorationList.push_back (highlight);
03239     }
03240 
03241     // Get window backdrop bitmap from the theme.  This is not added to the decoration
03242     //   list since the transparent flag will determine if it is drawn or not.
03243     bmBack = tw->GetBitmap ("BACK");
03244 
03245     // Get text colour
03246     colText = tw->GetColour ("TEXT");
03247     colTextHighlight = tw->GetColour ("TEXTHILITE");
03248     colHighlight = tw->GetColour ("HILITE");
03249 
03250     // Get optional DONT_DRAW_BACKGROUND flag
03251     noBackground = tw->GetFlag ("DONT_DRAW_BACKGROUND");
03252   }
03253 }
03254 
03255 void CFuiList::SetParentPosition (int xParent, int yParent)
03256 {
03257   CFuiComponent::SetParentPosition (xParent, yParent);
03258 
03259   // Update all decorations
03260   list<CFuiComponent*>::iterator i;
03261   for (i=decorationList.begin(); i!=decorationList.end(); i++) {
03262     (*i)->SetParentPosition (xParent + x, yParent + y);
03263   }
03264 }
03265 
03266 void CFuiList::Draw (void)
03267 {
03268   if (surface != NULL) {
03269     // Draw background bitmap
03270     if ((bmBack != NULL) && !noBackground) {
03271       DrawBitmap (surface, bmBack, 0, 0, 0);
03272     }
03273 
03274     // Draw decoration components
03275     list<CFuiComponent*>::iterator i;
03276     for (i=decorationList.begin(); i!=decorationList.end(); i++) {
03277       (*i)->Draw();
03278     }
03279 
03280     // @todo Process data to determine layout to accomodate for different row heights
03281 
03282     // Display data
03283     vector<CFuiListColumn>::iterator c;
03284     int x = 0;
03285     int iStartRow = scrollRow;
03286     for (c=cols.begin(); c!=cols.end(); c++) {
03287       int y = 0;
03288       for (unsigned int i=iStartRow; i<c->GetRowCount(); i++) {
03289         CFuiListRow &row = c->GetRow (i);
03290         DrawText (surface, font, x, y, colText, row.GetText());
03291         y += row.GetHeight();
03292         
03293         // Stop displaying rows when bottom edge of surface has been reached
03294         if (y >= h) break;
03295       }
03296       x += c->GetWidth();
03297 
03298       // Stop displaying columns when right edge of surface has been reached
03299       if (x >= w) break;
03300     }
03301   }
03302 
03303   CFuiComponent::Draw ();
03304 }
03305 
03306 void CFuiList::ScrollToRow (unsigned int row)
03307 {
03308   if (row <= GetRowCount()) scrollRow = row;
03309 }
03310 
03311 void CFuiList::ScrollToColumn (unsigned int column)
03312 {
03313   if (column <= GetColumnCount()) scrollCol = column;
03314 }
03315 
03316 unsigned int CFuiList::GetRowCount (void)
03317 {
03318   return nRows;;
03319 }
03320 
03321 unsigned int CFuiList::GetColumnCount (void)
03322 {
03323   return cols.size();
03324 }
03325 
03326 void CFuiList::AddColumn (unsigned int width, char *title)
03327 {
03328   CFuiListColumn c;
03329   c.SetWidth (width);
03330   c.SetTitle (title);
03331   cols.push_back (c);
03332 }
03333 
03334 void CFuiList::DeleteColumn (unsigned int column)
03335 {
03336   // Adjust scroll column if necessary
03337   if ((scrollCol == column) && (scrollCol != 0)) scrollCol--;
03338 
03339   // Erase the column from the list
03340   vector<CFuiListColumn>::iterator i = cols.begin();
03341   for (unsigned int ic=0; (i != cols.end()) && (ic < column); ic++, i++);
03342   if (i != cols.end()) {
03343     cols.erase (i);
03344   }
03345 }
03346 
03347 void CFuiList::DeleteAllColumns (void)
03348 {
03349   cols.erase (cols.begin(), cols.end());
03350   scrollCol = 0;
03351 }
03352 
03353 void CFuiList::SetColumnWidth (unsigned int column, unsigned int width)
03354 {
03355   if (column <= GetColumnCount()) {
03356     cols[column].SetWidth (width);
03357   }
03358 }
03359 
03360 void CFuiList::AddRow (unsigned int height)
03361 {
03362   // Add row to all columns
03363   vector<CFuiListColumn>::iterator i;
03364   for (i=cols.begin(); i!=cols.end(); i++) {
03365     CFuiListRow r;
03366     r.SetHeight (height);
03367     i->AddRow (r);
03368     nRows++;
03369   }
03370 }
03371 
03372 void CFuiList::DeleteRow (unsigned int row)
03373 {
03374   // Delete row from all columns
03375   vector<CFuiListColumn>::iterator i;
03376   for (i=cols.begin(); i!=cols.end(); i++) {
03377     i->DeleteRow (row);
03378   }
03379 }
03380 
03381 void CFuiList::DeleteAllRows (void)
03382 {
03383   // Delete all rows from all columns
03384   vector<CFuiListColumn>::iterator i;
03385   for (i=cols.begin(); i!=cols.end(); i++) {
03386     i->DeleteAllRows ();
03387   }
03388 }
03389 
03390 unsigned int CFuiList::CountSelectedRows (void)
03391 {
03392   int rc = 0;
03393 
03394   // @todo Count selected rows
03395   
03396   return rc;
03397 }
03398 
03399 unsigned int CFuiList::GetSelectedRow (unsigned int index)
03400 {
03401   int rc = 0;
03402 
03403   // @todo Get selected row
03404 
03405   return rc;
03406 }
03407 
03408 void CFuiList::SelectRow (unsigned int row)
03409 {
03410   // @todo Select row
03411 }
03412 
03413 void CFuiList::ClearSelection (void)
03414 {
03415   // @todo Clear selection
03416 }
03417 
03418 void CFuiList::SetCellText (unsigned int row, unsigned int column, char *text)
03419 {
03420   if (column <= GetColumnCount()) {
03421     CFuiListColumn& c = cols[column];
03422     if (row <= c.GetRowCount()) {
03423       CFuiListRow& r = c.GetRow (row);
03424       r.SetText (text);
03425     }
03426   }
03427 }
03428 
03429 void CFuiList::SetCellIcon (unsigned int row, unsigned int column, char *filename)
03430 {
03431   // @todo Set cell icon
03432 }
03433 
03434 void CFuiList::ClearCellText (unsigned int row, unsigned int column)
03435 {
03436   SetCellText (row, column, "");
03437 }
03438 
03439 void CFuiList::ClearCellIcon (unsigned int row, unsigned int column)
03440 {
03441   // @todo Clear cell icon
03442 }
03443 
03444 void CFuiList::GetCellText (unsigned int row, unsigned int column, char *outtext)
03445 {
03446   if (column <= GetColumnCount()) {
03447     CFuiListColumn& c = cols[column];
03448     if (row <= c.GetRowCount()) {
03449       CFuiListRow& r = c.GetRow (row);
03450       strcpy (outtext, r.GetText());
03451     }
03452   }
03453 }
03454 
03455 
03456 //
03457 // CFuiTextPopup
03458 //
03459 void CFuiTextPopup::SetText (const char* text = NULL)
03460 {
03461   // Call parent class method
03462   CFuiComponent::SetText (text);
03463 
03464   // Delete previous SSurface if it was created
03465   if (surface != NULL) {
03466     FreeSurface (surface);
03467     surface = NULL;
03468   }
03469 
03470   if (text != NULL) {
03471     // Use default font
03472     SFont *font = &globals->fonts.ftasci10;
03473 
03474     // Define colours
03475     unsigned int black = MakeRGB (0, 0, 0);
03476     unsigned int darkgrey = MakeRGB (100, 100, 100);
03477     unsigned int mediumgrey = MakeRGB (164, 164, 164);
03478     unsigned int lightgrey = MakeRGB (212, 212, 212);
03479     unsigned int white = MakeRGB (255, 255, 255);
03480 
03481     // Create surface
03482     int xSpace = 12;
03483     int ySpace = 4;
03484     w = TextWidth (font, this->text) + (2 * xSpace);
03485     h = TextHeight (font, this->text) + (2 * ySpace);
03486     surface = CreateSurface (w, h);
03487     surface->xScreen = x;
03488     surface->yScreen = y;
03489     EraseSurfaceRGB (surface, mediumgrey);
03490 
03491     // Draw borders
03492     DrawRect (surface, 2, 2, w-1, h-1, lightgrey);
03493     DrawRect (surface, 1, 1, w-2, h-2, darkgrey);
03494 
03495     // Draw shadowed text
03496     DrawText (surface, font, xSpace+1, ySpace+1, black, this->text);
03497     DrawText (surface, font, xSpace, ySpace, white, this->text);
03498   }
03499 }
03500 
03501 
03502 //
03503 // CFuiGraphTrace
03504 //
03505 CFuiGraphTrace::CFuiGraphTrace (Tag id, int type)
03506 {
03507   this->id = id;
03508   this->type = type;
03509   colour = MakeRGB (255, 255, 255);
03510   minX = minY = 0.0f;
03511   maxX = maxY = 100.0f;
03512 }
03513 
03514 void CFuiGraphTrace::AddPoint (float x, float y)
03515 {
03516   SFuiGraphTracePoint p;
03517   p.x = x;
03518   p.y = y;
03519   points.push_back (p);
03520 }
03521 
03522 void CFuiGraphTrace::ClearPoints (void)
03523 {
03524   points.erase (points.begin(), points.end());
03525 }
03526 
03527 void CFuiGraphTrace::SetRange (float minX, float minY, float maxX, float maxY)
03528 {
03529   this->minX = minX;
03530   this->minY = minY;
03531   this->maxX = maxX;
03532   this->maxY = maxY;
03533 }
03534 
03535 void CFuiGraphTrace::SetColour (unsigned int colour)
03536 {
03537   this->colour = colour;
03538 }
03539 
03540 void CFuiGraphTrace::Draw (SSurface *surface)
03541 {
03542   static int prevX = 0;
03543   static int prevY = 0;
03544 
03545   vector<SFuiGraphTracePoint>::iterator i;
03546   for (i=points.begin(); i!=points.end(); i++) {
03547     float x = i->x;
03548     float y = i->y;
03549 
03550     float dx = (x - minX) / (maxX - minX);
03551     float dy = (maxY - y) / (maxY - minY);
03552     if (dx < 0) dx = 0;
03553     if (dx > 1.0f) dx = 1.0f;
03554     if (dy < 0) dy = 0;
03555     if (dy > 1.0f) dy = 1.0f;
03556 
03557     int px = (int)((float)surface->xSize * dx);
03558     int py = (int)((float)surface->ySize * dy);
03559 
03560     if (i == points.begin()) {
03561       // Initialize previous x and y offets for line trace
03562       prevX = px;
03563       prevY = py;
03564     }
03565 
03566     switch (type) {
03567     case FUI_GRAPH_TRACE_POINT:
03568       DrawDot (surface, px, py, colour);
03569       break;
03570 
03571     case FUI_GRAPH_TRACE_LINE:
03572       DrawLine (surface, prevX, prevY, px, py, colour);
03573       prevX = px;
03574       prevY = py;
03575       break;
03576     }
03577   }
03578 }
03579 
03580 
03581 //
03582 // CFuiGraph
03583 //
03584 CFuiGraph::CFuiGraph (void)
03585 {
03586   type = COMPONENT_GRAPH;
03587   widgetTag = 'defa';
03588   strcpy (widgetName, "Graph");
03589 
03590   useGrid = false;
03591   minX = minY = 0;
03592   maxX = maxY = 100.0f;
03593   stepX = stepY = 10.0f;
03594 
03595   // Initialize background and grid colours
03596   bgColour = MakeRGB (1, 1, 1);
03597   gridColour = MakeRGB (64, 64, 64);
03598 }
03599 
03600 int CFuiGraph::Read (SStream *stream, Tag tag)
03601 {
03602   int rc = TAG_IGNORED;
03603   switch (tag) {
03604   case 'grid':
03605     {
03606       int i = 0;
03607       ReadInt (&i, stream);
03608       useGrid = (i != 0);
03609     }
03610     rc = TAG_READ;
03611     break;
03612   case 'grdr':
03613     ReadFloat (&minX, stream);
03614     ReadFloat (&minY, stream);
03615     ReadFloat (&maxX, stream);
03616     ReadFloat (&maxY, stream);
03617     ReadFloat (&stepX, stream);
03618     ReadFloat (&stepY, stream);
03619     rc = TAG_READ;
03620     break;
03621   }
03622 
03623   // Send tag to parent class for processing
03624   if (rc == TAG_IGNORED) {
03625     rc = CFuiComponent::Read (stream, tag);
03626   }
03627 
03628   return rc;
03629 }
03630 
03631 void CFuiGraph::Draw (void)
03632 {
03633   if (surface != NULL) {
03634 
03635     // Fill surface with background colour
03636     EraseSurfaceRGB (surface, bgColour);
03637 
03638     // Draw grid if necessary
03639     if (useGrid) {
03640       // Horizontal grid lines
03641       float y = stepY;
03642       while (y <= surface->ySize) {
03643         float dy = (maxY - y) / (maxY - minY);
03644         if (dy < 0) dy = 0;
03645         if (dy > 1.0f) dy = 1.0f;
03646         int py = (int)((float)surface->ySize * dy);
03647         DrawLine (surface, 0, py, surface->xSize, py, gridColour);
03648         y += stepY;
03649       }
03650 
03651       // Vertical grid lines
03652       float x = stepX;
03653       while (x <= surface->xSize) {
03654         float dx = (x - minX) / (maxX - minX);
03655         if (dx < 0) dx = 0;
03656         if (dx > 1.0f) dx = 1.0f;
03657         int px = (int)((float)surface->xSize * dx);
03658         DrawLine (surface, px, 0, px, surface->ySize, gridColour);
03659         x += stepX;
03660       }
03661     }
03662 
03663     // Notify application to update trace data
03664     globals->fuimgr->GenerateEventNotice (parentWindowId, id,
03665                                           EVENT_UPDATE, EVENT_NOSUBEVENT);
03666 
03667     // Draw traces
03668     map<Tag,CFuiGraphTrace*>::iterator i;
03669     for (i=traces.begin(); i!=traces.end(); i++) {
03670       CFuiGraphTrace *t = i->second;
03671       t->Draw (surface);
03672     }
03673   }
03674 
03675   CFuiComponent::Draw ();
03676 }
03677 
03678 void CFuiGraph::AddTrace (Tag traceID, int traceType)
03679 {
03680   map<Tag,CFuiGraphTrace*>::iterator i = traces.find(traceID);
03681   if (i == traces.end()) {
03682     traces[traceID] = new CFuiGraphTrace (traceID, traceType);
03683   } else {
03684     WARNINGLOG ("CFuiGraph::AddTrace : Duplicate trace");
03685   }
03686 }
03687 
03688 void CFuiGraph::RemoveTrace (Tag traceID)
03689 {
03690   map<Tag,CFuiGraphTrace*>::iterator i = traces.find(traceID);
03691   if (i != traces.end()) {
03692     traces.erase (i);
03693   } else {
03694     WARNINGLOG ("CFuiGraph::RemoveTrace : Non-existent trace");
03695   }
03696 }
03697 
03698 void CFuiGraph::RemoveAllTraces (void)
03699 {
03700   traces.erase (traces.begin(), traces.end());
03701 }
03702 
03703 void CFuiGraph::AddTracePoint(Tag traceID, float x, float y)
03704 {
03705   map<Tag,CFuiGraphTrace*>::iterator i = traces.find(traceID);
03706   if (i != traces.end()) {
03707     CFuiGraphTrace* t = i->second;
03708     t->AddPoint (x, y);
03709   } else {
03710     WARNINGLOG ("CFuiGraph::AddTracePoint : Non-existent trace");
03711   }
03712 }
03713 
03714 void CFuiGraph::ClearTracePoints (Tag traceID)
03715 {
03716   map<Tag,CFuiGraphTrace*>::iterator i = traces.find(traceID);
03717   if (i != traces.end()) {
03718     CFuiGraphTrace* t = i->second;
03719     t->ClearPoints ();
03720   } else {
03721     WARNINGLOG ("CFuiGraph::ClearTracePoints : Non-existent trace");
03722   }
03723 }
03724 
03725 void CFuiGraph::SetTraceRange (Tag traceID, float minX, float minY, float maxX, float maxY)
03726 {
03727   map<Tag,CFuiGraphTrace*>::iterator i = traces.find(traceID);
03728   if (i != traces.end()) {
03729     CFuiGraphTrace* t = i->second;
03730     t->SetRange (minX, minY, maxX, maxY);
03731   } else {
03732     WARNINGLOG ("CFuiGraph::SetTraceRange : Non-existent trace");
03733   }
03734 }
03735 
03736 void CFuiGraph::SetTraceColour (Tag traceID, unsigned int colour)
03737 {
03738   map<Tag,CFuiGraphTrace*>::iterator i = traces.find(traceID);
03739   if (i != traces.end()) {
03740     CFuiGraphTrace* t = i->second;
03741     t->SetColour (colour);
03742   } else {
03743     WARNINGLOG ("CFuiGraph::SetTraceColour : Non-existent trace");
03744   }
03745 }
03746 
03747 void CFuiGraph::SetUseGrid (int useGrid)
03748 {
03749   this->useGrid = (useGrid != 0);
03750 }
03751 
03752 void CFuiGraph::SetGridRange (float minX, float minY, float maxX, float maxY)
03753 {
03754   this->minX = minX;
03755   this->minY = minY;
03756   this->maxX = maxX;
03757   this->maxY = maxY;
03758 }
03759 
03760 void CFuiGraph::SetGridSpacing (float stepX, float stepY)
03761 {
03762   this->stepX = stepX;
03763   this->stepY = stepY;
03764 }
03765 
03766 void CFuiGraph::SetGridColour (unsigned int colour)
03767 {
03768   this->gridColour = colour;
03769 }
03770 
03771 void CFuiGraph::SetGridBackColour (unsigned int colour)
03772 {
03773   this->bgColour = colour;
03774 }
03775 
03776 void CFuiGraph::GetGridRange(float *minX, float *minY, float *maxX, float *maxY)
03777 {
03778   *minX = this->minX;
03779   *minY = this->minY;
03780   *maxX = this->maxX;
03781   *maxY = this->maxY;
03782 }
03783 
03784 void CFuiGraph::GetGridSpacing(float *stepX, float *stepY)
03785 {
03786   *stepX = this->stepX;
03787   *stepY = this->stepY;
03788 }
03789 
03790 
03791 //
03792 // Local helper functions
03793 //
03794 
03795 //
03796 // Validate a tag value suspected to be a FUI component type
03797 //
03798 static bool ValidFuiComponentType (Tag tag)
03799 {
03800   bool rc = false;
03801 
03802   switch (tag) {
03803   case COMPONENT_WINDOW:
03804   case COMPONENT_BUTTON:
03805   case COMPONENT_DOUBLE_BUTTON:
03806   case COMPONENT_DEFAULT_BUTTON:
03807   case COMPONENT_POPUPMENU:
03808   case COMPONENT_MENUBAR:
03809   case COMPONENT_WINDOW_MENUBAR:
03810   case COMPONENT_MENU:
03811   case COMPONENT_CHECKBOX:
03812   case COMPONENT_RADIOBUTTON:
03813   case COMPONENT_LABEL:
03814   case COMPONENT_LINE:
03815   case COMPONENT_BOX:
03816   case COMPONENT_PICTURE:
03817   case COMPONENT_SCROLLBAR:
03818   case COMPONENT_SLIDER:
03819   case COMPONENT_GROUPBOX:
03820   case COMPONENT_GAUGE:
03821   case COMPONENT_LIST:
03822   case COMPONENT_SCROLLAREA:
03823   case COMPONENT_TEXTFIELD:
03824   case COMPONENT_TEXTAREA:
03825   case COMPONENT_PROGRESS:
03826   case COMPONENT_MAP:
03827   case COMPONENT_TABPAGE:
03828   case COMPONENT_TABBUTTON:
03829   case COMPONENT_TABCONTROL:
03830   case COMPONENT_GRAPH:
03831   case COMPONENT_DLLVIEW:
03832   case COMPONENT_DISCLOSURE:
03833   case COMPONENT_CANVAS:
03834   case COMPONENT_RUNWAY_CANVAS:
03835   case COMPONENT_MARQUEE:
03836   case COMPONENT_HORIZ_MARQUEE:
03837   case COMPONENT_WINDOW_NORESIZE:
03838   case COMPONENT_TITLE:
03839   case COMPONENT_PALETTE_WINDOW:
03840   case COMPONENT_PALETTE_WINDOW_TITLE:
03841   case COMPONENT_CLOSE_BUTTON:
03842   case COMPONENT_MINIMIZE_BUTTON:
03843   case COMPONENT_ZOOM_BUTTON:
03844     rc = true;
03845   }
03846 
03847   return rc;
03848 }
03849 
03850 //
03851 // Helper function instantiates a FUI component given its component type
03852 //
03853 static CFuiComponent *CreateFuiComponent (EFuiComponentTypes type)
03854 {
03855   switch (type) {
03856   case COMPONENT_TITLE:
03857     return new CFuiWindowTitle;
03858     break;
03859 
03860   case COMPONENT_CLOSE_BUTTON:
03861     return new CFuiCloseButton;
03862     break;
03863 
03864   case COMPONENT_MINIMIZE_BUTTON:
03865     return new CFuiMinimizeButton;
03866     break;
03867 
03868   case COMPONENT_ZOOM_BUTTON:
03869     return new CFuiZoomButton;
03870     break;
03871 
03872   case COMPONENT_BUTTON:
03873     return new CFuiButton;
03874     break;
03875 
03876   case COMPONENT_LABEL:
03877     return new CFuiLabel;
03878     break;
03879 
03880   case COMPONENT_TEXTFIELD:
03881     return new CFuiTextField;
03882     break;
03883 
03884   case COMPONENT_PICTURE:
03885     return new CFuiPicture;
03886     break;
03887 
03888   case COMPONENT_CHECKBOX:
03889     return new CFuiCheckbox;
03890     break;
03891 
03892   case COMPONENT_RADIOBUTTON:
03893     return new CFuiRadioButton;
03894     break;
03895 
03896   case COMPONENT_LINE:
03897     return new CFuiLine;
03898     break;
03899 
03900   case COMPONENT_BOX:
03901     return new CFuiBox;
03902     break;
03903 
03904   case COMPONENT_GROUPBOX:
03905     return new CFuiGroupBox;
03906     break;
03907 
03908   case COMPONENT_SLIDER:
03909     return new CFuiSlider;
03910     break;
03911 
03912   case COMPONENT_LIST:
03913     return new CFuiList;
03914     break;
03915 
03916   case COMPONENT_POPUPMENU:
03917     return new CFuiPopupMenu;
03918     break;
03919 
03920   case COMPONENT_GRAPH:
03921     return new CFuiGraph;
03922     break;
03923 
03924   case COMPONENT_SCROLLBAR:
03925 //    return new CFuiScrollbar;
03926     break;
03927 
03928   case COMPONENT_DOUBLE_BUTTON:
03929 //    return new CFuiDoubleButton;
03930     break;
03931 
03932   case COMPONENT_DEFAULT_BUTTON:
03933 //    return new CFuiDefaultButton;
03934     break;
03935 
03936   case COMPONENT_MENUBAR:
03937 //    return new CFuiMenuBar;
03938     break;
03939 
03940   case COMPONENT_WINDOW_MENUBAR:
03941 //    return new CFuiWindowMenuBar;
03942     break;
03943 
03944   case COMPONENT_MENU:
03945 //    return new CFuiMenu;
03946     break;
03947 
03948   case COMPONENT_GAUGE:
03949 //    return new CFuiGauge;
03950     break;
03951 
03952   case COMPONENT_SCROLLAREA:
03953 //    return new CFuiScrollArea;
03954     break;
03955 
03956   case COMPONENT_TEXTAREA:
03957 //    return new CFuiTextArea;
03958     break;
03959 
03960   case COMPONENT_PROGRESS:
03961 //    return new CFuiProgress;
03962     break;
03963 
03964   case COMPONENT_MAP:
03965 //    return new CFuiMap;
03966     break;
03967 
03968   case COMPONENT_TABPAGE:
03969 //    return new CFuiTabPage;
03970     break;
03971 
03972   case COMPONENT_TABBUTTON:
03973 //    return new CFuiTabButton;
03974     break;
03975 
03976   case COMPONENT_TABCONTROL:
03977 //    return new CFuiTabControl;
03978     break;
03979 
03980   case COMPONENT_DLLVIEW:
03981 //    return new CFuiDLLView;
03982     break;
03983 
03984   case COMPONENT_DISCLOSURE:
03985 //    return new CFuiDisclosure;
03986     break;
03987 
03988   case COMPONENT_CANVAS:
03989 //    return new CFuiCanvas;
03990     break;
03991 
03992   case COMPONENT_RUNWAY_CANVAS:
03993 //    return new CFuiRunwayCanvas;
03994     break;
03995 
03996   case COMPONENT_MARQUEE:
03997 //    return new CFuiMarquee;
03998     break;
03999 
04000   case COMPONENT_HORIZ_MARQUEE:
04001 //    return new CFuiHorizMarquee;
04002     break;
04003 
04004   case COMPONENT_WINDOW_NORESIZE:
04005 //    return new CFuiWindowNoResize;
04006     break;
04007 
04008   case COMPONENT_PALETTE_WINDOW:
04009 //    return new CFuiPaletteWindow;
04010     break;
04011 
04012   case COMPONENT_PALETTE_WINDOW_TITLE:
04013 //    return new CFuiPaletteWindowTitle;
04014     break;
04015 
04016   default:
04017     // No action required
04018     ;
04019   }
04020 
04021   return NULL;
04022 }
04023 
04024 /* Function is currently unused, leave commented unless necessary
04025 
04026 //
04027 // Helper function instantiates a FUI component given its name
04028 //
04029 static CFuiComponent *CreateFuiComponent (const char* name)
04030 {
04031   CFuiComponent *rc = NULL;
04032 
04033   Tag type = CFuiManager::GetComponentType (name);
04034   if (type != 0) {
04035     rc = CreateFuiComponent ((EFuiComponentTypes)type);
04036   }
04037   
04038   return rc;
04039 }
04040 
04041 */
SourceForge.net Logo Documentation generated by doxygen