MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Thirdparty/FLTKVW/Flv_Style.cxx
Go to the documentation of this file.
00001 //      ======================================================================
00002 //      File:    Flv_Style.cxx - Flv_Style implementation
00003 //      Program: Flv_Style - FLTK Virtual List/Table Styles Widget
00004 //      Version: 0.1.0
00005 //      Started: 11/21/99
00006 //
00007 //      Copyright (C) 1999 Laurence Charlton
00008 //
00009 //      Description:
00010 //      The styles classes are basically defined to make life easier while
00011 //      working with styles for the virtual classes.
00012 //      ======================================================================
00013 
00014 #include <FL/Fl_Widget.H>
00015 #include "Flv_Style.H"
00016 #include <stdio.h>
00017 #ifdef WIN32
00018 #include <memory.h>
00019 #include <string.h>
00020 #else
00021 #include <memory.h>
00022 #endif
00023 
00024 #define ADDSIZE 10
00025 
00026 //      Flv_Style bits
00027 #define STYLE_DEFINE_FONT                                               0x0001
00028 #define STYLE_DEFINE_FONT_SIZE                  0x0002
00029 #define STYLE_DEFINE_FOREGROUND                 0x0004
00030 #define STYLE_DEFINE_BACKGROUND                 0x0008
00031 #define STYLE_DEFINE_ALIGN                                      0x0010
00032 #define STYLE_DEFINE_FRAME                                      0x0020
00033 #define STYLE_DEFINE_RESIZABLE                  0x0040
00034 #define STYLE_DEFINE_HEIGHT                                     0x0080
00035 #define STYLE_DEFINE_WIDTH                                      0x0100
00036 #define STYLE_DEFINE_LOCKED                                     0x0200
00037 #define STYLE_DEFINE_BORDER                                     0x0400
00038 #define STYLE_DEFINE_BORDER_COLOR               0x0800
00039 #define STYLE_DEFINE_BORDER_SPACING     0x1000
00040 #define STYLE_DEFINE_X_MARGIN                           0x2000
00041 #define STYLE_DEFINE_Y_MARGIN                           0x4000
00042 #define STYLE_DEFINE_EDITOR                                     0x8000
00043 
00044 #define CLEAR(n) vdefined &= ~(n)
00045 #define DEFINED(n) ((vdefined & (n))!= 0)
00046 #define DEFINED2(v,n) ((v.vdefined & (n))!= 0)
00047 
00048 Flv_Style::Flv_Style()
00049 {
00050         vdefined = 0;
00051         vvalue = 0;
00052         //      I'm not worried about initializing the rest of the private
00053         //      variables since they are undefined.
00054 }
00055 
00056 Flv_Style::Flv_Style( int value )
00057 {
00058         vdefined = 0;
00059         vvalue = value;
00060         //      I'm not worried about initializing the rest of the private
00061         //      variables since they are undefined.
00062 }
00063 
00064 //      ==================================================================
00065 //      Set drawing alignment
00066 const Fl_Align &Flv_Style::align(const Fl_Align &n)
00067 {
00068         valign = n;
00069         vdefined |= STYLE_DEFINE_ALIGN;
00070         return valign;
00071 }
00072 
00073 //      Undefine drawing alignment
00074 void Flv_Style::clear_align(void)
00075 {
00076         CLEAR(STYLE_DEFINE_ALIGN);
00077 }
00078 
00079 //      Is drawing alignment defined?
00080 bool Flv_Style::align_defined(void) const
00081 {
00082         return DEFINED(STYLE_DEFINE_ALIGN);
00083 }
00084 
00085 //      ==================================================================
00086 //      Set background color
00087 Fl_Color Flv_Style::background(Fl_Color n)
00088 {
00089         vbackground = n;
00090         vdefined |= STYLE_DEFINE_BACKGROUND;
00091         return vbackground;
00092 }
00093 
00094 //      Undefine background color
00095 void Flv_Style::clear_background(void)
00096 {
00097         CLEAR(STYLE_DEFINE_BACKGROUND);
00098 }
00099 
00100 //      Is background defined?
00101 bool Flv_Style::background_defined(void) const
00102 {
00103         return DEFINED(STYLE_DEFINE_BACKGROUND);
00104 }
00105 
00106 
00107 //      ==================================================================
00108 //      Set border
00109 int Flv_Style::border(int n)
00110 {
00111         vborder = (unsigned char)n;
00112         vdefined |= STYLE_DEFINE_BORDER;
00113         return vborder;
00114 }
00115 
00116 //      Undefine border
00117 void Flv_Style::clear_border(void)
00118 {
00119         CLEAR(STYLE_DEFINE_BORDER);
00120 }
00121 
00122 //      Is border defined?
00123 bool Flv_Style::border_defined(void) const
00124 {
00125         return DEFINED(STYLE_DEFINE_BORDER);
00126 }
00127 
00128 //      ==================================================================
00129 //      Set border_color
00130 Fl_Color Flv_Style::border_color(Fl_Color n)
00131 {
00132         vborder_color = n;
00133         vdefined |= STYLE_DEFINE_BORDER_COLOR;
00134         return vborder_color;
00135 }
00136 
00137 //      Undefine border_color
00138 void Flv_Style::clear_border_color(void)
00139 {
00140         CLEAR(STYLE_DEFINE_BORDER_COLOR);
00141 }
00142 
00143 //      Is border_color defined?
00144 bool Flv_Style::border_color_defined(void) const
00145 {
00146         return DEFINED(STYLE_DEFINE_BORDER_COLOR);
00147 }
00148 
00149 
00150 //      ==================================================================
00151 //      Set border_spacing
00152 int Flv_Style::border_spacing(int n)
00153 {
00154         vborder_spacing = (unsigned char)n;
00155         vdefined |= STYLE_DEFINE_BORDER_SPACING;
00156         return vborder_spacing;
00157 }
00158 
00159 //      Undefine border_spacing
00160 void Flv_Style::clear_border_spacing(void)
00161 {
00162         CLEAR(STYLE_DEFINE_BORDER_SPACING);
00163 }
00164 
00165 //      Is border_spacing defined?
00166 bool Flv_Style::border_spacing_defined(void) const
00167 {
00168         return DEFINED(STYLE_DEFINE_BORDER_SPACING);
00169 }
00170 
00171 //      ==================================================================
00172 //      Set content editor
00173 Fl_Widget *Flv_Style::editor(Fl_Widget *v)
00174 {
00175         veditor = v;
00176         if (Fl::focus()!=v && veditor)
00177                 veditor->hide();
00178         vdefined |= STYLE_DEFINE_EDITOR;
00179         return veditor;
00180 }
00181 
00182 //      Undefine border_spacing
00183 void Flv_Style::clear_editor(void)
00184 {
00185         CLEAR(STYLE_DEFINE_EDITOR);
00186 }
00187 
00188 //      Is border_spacing defined?
00189 bool Flv_Style::editor_defined(void) const
00190 {
00191         return DEFINED(STYLE_DEFINE_EDITOR);
00192 }
00193 
00194 //      ==================================================================
00195 //      Set current font
00196 const Fl_Font &Flv_Style::font(const Fl_Font &n)
00197 {
00198         vfont = n;
00199         vdefined |= STYLE_DEFINE_FONT;
00200         return vfont;
00201 }
00202 
00203 //      Undefine font
00204 void Flv_Style::clear_font(void)
00205 {
00206         CLEAR(STYLE_DEFINE_FONT);
00207 }
00208 
00209 //      Is font defined
00210 bool Flv_Style::font_defined(void) const
00211 {
00212         return DEFINED(STYLE_DEFINE_FONT);
00213 }
00214 
00215 //      ==================================================================
00216 //      Set font size
00217 int Flv_Style::font_size(int n)
00218 {
00219         if (n < 1)                                              //      Clip at 1 as the smallest font size
00220                 n = 1;
00221         vfont_size = n;
00222         vdefined |= STYLE_DEFINE_FONT_SIZE;
00223         return vfont_size;
00224 }
00225 
00226 //      Undefine font size
00227 void Flv_Style::clear_font_size(void)
00228 {
00229         CLEAR(STYLE_DEFINE_FONT_SIZE);
00230 }
00231 
00232 //      Is font size defined?
00233 bool Flv_Style::font_size_defined(void) const
00234 {
00235         return DEFINED(STYLE_DEFINE_FONT_SIZE);
00236 }
00237 
00238 //      ==================================================================
00239 //      Set foreground color
00240 Fl_Color Flv_Style::foreground(Fl_Color n)
00241 {
00242         vforeground = n;
00243         vdefined |= STYLE_DEFINE_FOREGROUND;
00244         return vforeground;
00245 }
00246 
00247 //      Undefine foreground color
00248 void Flv_Style::clear_foreground(void)
00249 {
00250         CLEAR(STYLE_DEFINE_FOREGROUND);
00251 }
00252 
00253 //      Is foreground defined?
00254 bool Flv_Style::foreground_defined(void) const
00255 {
00256         return DEFINED(STYLE_DEFINE_FOREGROUND);
00257 }
00258 
00259 //      ==================================================================
00260 //      Set frame type
00261 const Fl_Boxtype &Flv_Style::frame(const Fl_Boxtype &n)
00262 {
00263         vframe = n;
00264         vdefined |= STYLE_DEFINE_FRAME;
00265         return vframe;
00266 }
00267 
00268 //      Undefine frame type
00269 void Flv_Style::clear_frame(void)
00270 {
00271         CLEAR(STYLE_DEFINE_FRAME);
00272 }
00273 
00274 //      Is frame type defined?
00275 bool Flv_Style::frame_defined(void) const
00276 {
00277         return DEFINED(STYLE_DEFINE_FRAME);
00278 }
00279 
00280 //      ==================================================================
00281 //      Set height
00282 int Flv_Style::height(int n )
00283 {
00284         if (n < 0)
00285                 n = 0;
00286         vdefined |= STYLE_DEFINE_HEIGHT;
00287         return (vheight = n);
00288 }
00289 
00290 //      Undefine row height
00291 void Flv_Style::clear_height(void)
00292 {
00293         CLEAR(STYLE_DEFINE_HEIGHT);
00294 }
00295 
00296 //      Is row height defined?
00297 bool Flv_Style::height_defined(void) const
00298 {
00299         return DEFINED(STYLE_DEFINE_HEIGHT);
00300 }
00301 
00302 //      ==================================================================
00303 //      Set locked
00304 bool Flv_Style::locked(bool n)
00305 {
00306         vdefined |= STYLE_DEFINE_LOCKED;
00307         return (vlocked = n);
00308 }
00309 
00310 //      Undefine locked
00311 void Flv_Style::clear_locked(void)
00312 {
00313         CLEAR(STYLE_DEFINE_LOCKED);
00314 }
00315 
00316 //      Is locked defined?
00317 bool Flv_Style::locked_defined(void) const
00318 {
00319         return DEFINED(STYLE_DEFINE_LOCKED);
00320 }
00321 
00322 //      ==================================================================
00323 //      Set resizable
00324 bool Flv_Style::resizable(bool n)
00325 {
00326         vresizable = n;
00327         vdefined |= STYLE_DEFINE_RESIZABLE;
00328         return vresizable;
00329 }
00330 
00331 //      Undefine resizable
00332 void Flv_Style::clear_resizable(void)
00333 {
00334         CLEAR(STYLE_DEFINE_RESIZABLE);
00335 }
00336 
00337 //      Is resizable defined?
00338 bool Flv_Style::resizable_defined(void) const
00339 {
00340         return DEFINED(STYLE_DEFINE_RESIZABLE);
00341 }
00342 
00343 //      ==================================================================
00344 //      Set column width
00345 int Flv_Style::width(int n)
00346 {
00347         if (n < 0)
00348                 n = 0;
00349         vdefined |= STYLE_DEFINE_WIDTH;
00350         return (vwidth = n);
00351 }
00352 
00353 //      Undefine column width
00354 void Flv_Style::clear_width(void)
00355 {
00356         CLEAR(STYLE_DEFINE_WIDTH);
00357 }
00358 
00359 //      Is column width defined?
00360 bool Flv_Style::width_defined(void) const
00361 {
00362         return DEFINED(STYLE_DEFINE_WIDTH);
00363 }
00364 
00365 //      ==================================================================
00366 //      Set x margin
00367 int Flv_Style::x_margin(int x)
00368 {
00369         if (x<0)
00370         x=0;
00371         if (x!=vx_margin)
00372   {
00373         vdefined |= STYLE_DEFINE_X_MARGIN;
00374     vx_margin = (unsigned char)x;
00375   }
00376   return vx_margin;
00377 }
00378 
00379 //      Undefine x margin
00380 void Flv_Style::clear_x_margin(void)
00381 {
00382         CLEAR(STYLE_DEFINE_X_MARGIN);
00383 }
00384 
00385 //      Is x margin defined
00386 bool Flv_Style::x_margin_defined(void) const
00387 {
00388         return DEFINED(STYLE_DEFINE_X_MARGIN);
00389 }
00390 
00391 //      ==================================================================
00392 //      Set y margin
00393 int Flv_Style::y_margin(int y)
00394 {
00395         if (y<0)
00396         y=0;
00397         if (y!=vy_margin)
00398   {
00399         vdefined |= STYLE_DEFINE_Y_MARGIN;
00400     vy_margin = (unsigned char)y;
00401   }
00402   return vy_margin;
00403 }
00404 
00405 //      Undefine y margin
00406 void Flv_Style::clear_y_margin(void)
00407 {
00408         CLEAR(STYLE_DEFINE_Y_MARGIN);
00409 }
00410 
00411 //      Is y margin defined
00412 bool Flv_Style::y_margin_defined(void) const
00413 {
00414         return DEFINED(STYLE_DEFINE_Y_MARGIN);
00415 }
00416 
00417 //      ==================================================================
00418 //      Cumulative assignment operator
00419 //      This will only assign portions that are defined.
00420 const Flv_Style &Flv_Style::operator=(const Flv_Style &n)
00421 {
00422         if (n.align_defined())
00423                 align(n.valign);
00424         if (n.background_defined())
00425                 background(n.vbackground);
00426   if (n.border_defined())
00427         border(n.vborder);
00428         if (n.border_color_defined())
00429                 border_color(n.vborder_color);
00430         if (n.border_spacing_defined())
00431                 border_spacing(n.vborder_spacing);
00432         if (n.editor_defined())
00433                 editor(n.veditor);
00434         if (n.font_defined())
00435                 font(n.vfont);
00436         if (n.font_size_defined())
00437                 font_size(n.vfont_size);
00438         if (n.foreground_defined())
00439                 foreground(n.vforeground);
00440         if (n.frame_defined())
00441                 frame(n.vframe);
00442         if (n.height_defined())
00443                 height(n.vheight);
00444         if (n.locked_defined())
00445                 locked(n.vlocked);
00446         if (n.resizable_defined())
00447                 resizable(n.vresizable);
00448         if (n.width_defined())
00449                 width(n.vwidth);
00450   if (n.x_margin_defined())
00451         x_margin(n.vx_margin);
00452         if (n.y_margin_defined())
00453                 y_margin(n.vy_margin);
00454 
00455 
00456         //      I'm not copying value because it seems meaningless in every context
00457         //      I can think of.
00458 
00459         //      I'm not copying cell_style either for the same reason.  It just seems like
00460         //      a REALLY bad idea.
00461                 return *this;
00462 }
00463 
00464 //      **********************************************************************
00465 //      Routines for Flv_Style_List
00466 //
00467 //      Implemented as a dynamic sparse array
00468 //      **********************************************************************
00469 Flv_Style_List::Flv_Style_List()
00470 {
00471         list = NULL;
00472         vcount = vallocated = vcurrent = 0;
00473 }
00474 
00475 void Flv_Style_List::compact(void)
00476 {
00477         int n, t;
00478 
00479   //    Release memory for any dead items
00480         for (t=0;       t<vcount;       t++ )
00481   {
00482         list[t]->cell_style.compact();                  //      Compact cells!
00483     if (list[t]->cell_style.count()==0 && list[t]->all_clear())
00484     {
00485                         delete list[t];
00486       list[t] = NULL;
00487     }
00488   }
00489   //    Compact list now
00490         for (t=n=0;     t<vcount;       t++ )
00491   {
00492         if (list[t])
00493         list[n++] = list[t];
00494     else if (vcurrent<=t && vcurrent>0)
00495         vcurrent--;
00496   }
00497 
00498   //    Make list easy to view, wasted CPU cycles
00499   for (t=n;     t<vcount;       t++ )
00500         list[t] = NULL;
00501 
00502   vcount = n;   //      Update count
00503 
00504   if (!vcount && list)
00505   {
00506                 delete []list;
00507     list = NULL;
00508     vcount = vcurrent = vallocated = 0;
00509   }
00510 }
00511 //      Undefine all styles in list
00512 void Flv_Style_List::clear(void)
00513 {
00514         int t;
00515 
00516   for (t=0;     t<vcount;       t++ )                                                                   //      Make all entries clear
00517         list[t]->clear_all();
00518   compact();                                                                                                                            //      Remove dead space thats left
00519 }
00520 
00521 //      Free memory for all (including cell
00522 void Flv_Style_List::release(void)
00523 {
00524         int t;
00525         for (t = 0; t < vcount; t++ )
00526         {
00527                 list[t]->cell_style.release();
00528                 delete list[t];
00529         }
00530         if (list)
00531                 delete []list;
00532         list = NULL;
00533         vcurrent = vcount = vallocated = 0;
00534 }
00535 
00536 Flv_Style *Flv_Style_List::current(void)                        //      Current node
00537 {
00538         if (!list)
00539                 return NULL;
00540         return list[vcurrent];
00541 }
00542 
00543 //      Find closest match
00544 //      It will find the first value >= n
00545 Flv_Style *Flv_Style_List::find( int n )
00546 {
00547         int t, l, h;
00548 
00549         if (!list || vcount == 0)       //      If list is empty, there will be no matches
00550                 return NULL;
00551 
00552         //      How a about a nice binary search?  It will be slower for sequential
00553         //      processing and a small number of styles, but worlds faster as the
00554         //      number of styles increases.  Use skip_to for sequential processing
00555         //      and find for random access.
00556         l = 0;
00557         h = vcount-1;
00558         while (l+1 < h)
00559         {
00560                 vcurrent = (l+h) / 2;
00561                 t = list[vcurrent]->value();
00562                 if (t == n)
00563                         return list[vcurrent];
00564                 else if (t < n)
00565                         l = vcurrent;
00566                 else
00567                         h = vcurrent;
00568         }
00569 
00570         //      This needs cleaning, I fairly certain there's way too much logic here
00571         //      While this will work, I think we only need to check one of the values
00572         //      but I've been wrong before... :)
00573         vcurrent = l;
00574         t = list[vcurrent]->value();
00575         if (t == n)
00576                 return list[vcurrent];
00577         if (t < n && vcurrent < vcount-1)
00578         {
00579                 vcurrent=h;
00580                 t = list[vcurrent]->value();
00581                 if (t == n)
00582                         return list[vcurrent];
00583         }
00584         return NULL;
00585 }
00586 
00587 Flv_Style *Flv_Style_List::first(void)                                                                                  //      Get first style
00588 {
00589         if (!list)
00590                 return NULL;
00591         vcurrent = 0;
00592         return list[vcurrent];
00593 }
00594 
00595 bool Flv_Style_List::insert( Flv_Style *n )             //      Add style (if doesn't exist)
00596 {
00597         int t;
00598         //      Make sure there is room for a new item
00599         if (vcount == vallocated)
00600         {
00601                 Flv_Style **a = new Flv_Style *[vallocated+ADDSIZE];
00602                 if (!a)
00603                         return false;
00604     //  Wasted CPU cycles, but list is pretty
00605     memset( a, 0, sizeof(Flv_Style *)*(vallocated+ADDSIZE) );
00606                 if (vcount)
00607                         memcpy( a, list, sizeof(Flv_Style *)*vcount );
00608                 vallocated += ADDSIZE;
00609     if (list)
00610                         delete []list;
00611                 list = a;
00612         }
00613 
00614   if (vcount)
00615   {
00616                 find(n->value());                                                                       //      Point to insert candidate
00617         if (n->value()==list[vcurrent]->value())        //      No duplicates
00618                 return false;
00619           if (n->value()>list[vcurrent]->value())               //      Insert at end of list
00620                 vcurrent++;
00621   }
00622 
00623 
00624         //      Make room for insert if not appending
00625   for (t=vcount;        t>vcurrent;     t-- )
00626         list[t] = list[t-1];
00627 
00628         list[vcurrent] = n;
00629         vcount++;
00630         return true;
00631 }
00632 
00633 Flv_Style *Flv_Style_List::next(void)                                                                                   //      Next style
00634 {
00635         if (!list || vcurrent >= vcount-1)
00636                 return NULL;
00637 
00638         vcurrent++;
00639         return list[vcurrent];
00640 }
00641 
00642 Flv_Style *Flv_Style_List::prior(void)
00643 {
00644 
00645         if (!vcurrent || !list)
00646                 return 0;
00647         vcurrent--;
00648         return list[vcurrent];
00649 }
00650 
00651 bool Flv_Style_List::clear_current(void)
00652 {
00653         if (!list)
00654                 return false;
00655 
00656         if (list[vcurrent]->cell_style.count() == 0)
00657                 return release_current();
00658         list[vcurrent]->clear_all();
00659         return true;
00660 }
00661 
00662 bool Flv_Style_List::release_current(void)                                                                              //      Remove current style
00663 {
00664         if (!list)
00665                 return false;
00666 
00667         delete list[vcurrent];
00668         if (vcurrent < vcount-1)
00669         {
00670                 memmove(list+vcurrent, list+vcurrent+1, sizeof(Flv_Style *)*(vcount-vcurrent) );
00671                 vcount--;
00672                 list[vcount] = NULL;
00673         }
00674         if (vcurrent == vcount)
00675                 vcurrent--;
00676 
00677         return true;
00678 }
00679 
00680 //      From n skip up to value v
00681 Flv_Style *Flv_Style_List::skip_to( int v )
00682 {
00683         int c;
00684 
00685         if (!list || !vcount)
00686                 return NULL;
00687 
00688         //      In case we're backing up or starting over
00689         //      We're checking vcurrent-1 so if the last search found
00690         //      an entry > the desired value, and this search isn't quite
00691         //      to the last found value, we don't want to start over, just
00692         //      stay where we are.
00693         //      Style 1, 2, 3, 7 & 10 defined
00694         //      search for 4 (current points to 7) returns false
00695         //      search for 5 (stay at seven since 3 is < value, return false)
00696         //              If we started at 0 we'd end up here anyway... :)
00697         //      search for 7 (stay at seven, we'll find it quick, return true)
00698         if (vcurrent)
00699         {
00700         if (list[vcurrent-1]->value() >= v)
00701                         vcurrent = 0;
00702   }
00703 
00704         for (; vcurrent < vcount; vcurrent++ )
00705         {
00706                 c = list[vcurrent]->value();
00707                 if (c == v)
00708                         return list[vcurrent];
00709                 else if (c > v)
00710                         return NULL;
00711         }
00712         vcurrent--;
00713         return NULL;
00714 }
00715 
00716 //      Note: this could be a little wierd since it's actually returning
00717 //      the style with value 'value' instead of list index 'value'
00718 //      Plus: it's going to define the style if it doesn't already exist!
00719 //
00720 //      If you don't want extraneous styles getting inserted, be sure to
00721 //      use the find operator first.  (I.e. If your reading a style value
00722 //      and the style didn't previously exist, all the style information
00723 //      will be undefined!
00724 Flv_Style &Flv_Style_List::operator[](int value)
00725 {
00726         Flv_Style *p;
00727 
00728         if (find(value))                                                        //      If it exists
00729                 return *(list[vcurrent]);               //              return it
00730 
00731         p = new Flv_Style;
00732         p->value(value);
00733         insert(p);
00734         return *p;
00735 }
00736 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines