fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

align_widget.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: align_widget.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // Alignment code for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library 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 GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 #include <FL/Fl.H>
00029 #include <FL/Fl_Window.H>
00030 #include "Fl_Widget_Type.h"
00031 #include "undo.h"
00032 
00038 #define BREAK_ON_FIRST break
00039 //#define BREAK_ON_FIRST
00040 
00041 void align_widget_cb(Fl_Widget*, long how) 
00042 {
00043   const int max = 32768, min = -32768;
00044   int left, right, top, bot, wdt, hgt, n;
00045   Fl_Type *o;
00046   int changed = 0;
00047   switch ( how )
00048   {
00049   //---- align
00050   case 10: // align left
00051     left = max;
00052     for (o = Fl_Type::first; o; o = o->next)
00053       if (o->selected && o->is_widget())
00054       {
00055         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00056         if (w->x()<left)
00057           left = w->x();
00058         BREAK_ON_FIRST;
00059       }
00060     if (left!=max)
00061       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00062         if (o->selected && o->is_widget())
00063         {
00064           if (!changed) {
00065             changed = 1;
00066             set_modflag(1);
00067             undo_checkpoint();
00068           }
00069 
00070           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00071           if (o->next && o->next->level > o->level && !o->next->selected &&
00072               !o->is_menu_button()) {
00073             // When resizing a group, make sure we also move the children...
00074             ((igroup *)w)->full_resize(left, w->y(), w->w(), w->h());
00075           } else {
00076             // Otherwise, just do the widget...
00077             w->resize(left, w->y(), w->w(), w->h());
00078           }
00079           w->redraw();
00080           if (w->window()) w->window()->redraw();
00081         }
00082     break;
00083   case 11: // align h.center
00084     left = max; right = min;
00085     for (o = Fl_Type::first; o; o = o->next)
00086       if (o->selected && o->is_widget())
00087       {
00088         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00089         if (w->x()<left)
00090           left = w->x();
00091         if (w->x()+w->w()>right)
00092           right = w->x()+w->w();
00093         BREAK_ON_FIRST;
00094       }
00095     if (left!=max)
00096     {
00097       int center2 = left+right;
00098       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00099         if (o->selected && o->is_widget())
00100         {
00101           if (!changed) {
00102             changed = 1;
00103             set_modflag(1);
00104             undo_checkpoint();
00105           }
00106 
00107           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00108           if (o->next && o->next->level > o->level && !o->next->selected &&
00109               !o->is_menu_button()) {
00110             // When resizing a group, make sure we also move the children...
00111             ((igroup *)w)->full_resize((center2-w->w())/2, w->y(), w->w(), w->h());
00112           } else {
00113             // Otherwise, just do the widget...
00114             w->resize((center2-w->w())/2, w->y(), w->w(), w->h());
00115           }
00116           w->redraw();
00117           if (w->window()) w->window()->redraw();
00118         }
00119     }
00120     break;
00121   case 12: // align right
00122     right = min;
00123     for (o = Fl_Type::first; o; o = o->next)
00124       if (o->selected && o->is_widget())
00125       {
00126         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00127         if (w->x()+w->w()>right)
00128           right = w->x()+w->w();
00129         BREAK_ON_FIRST;
00130       }
00131     if (right!=min)
00132       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00133         if (o->selected && o->is_widget())
00134         {
00135           if (!changed) {
00136             changed = 1;
00137             set_modflag(1);
00138             undo_checkpoint();
00139           }
00140 
00141           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00142           if (o->next && o->next->level > o->level && !o->next->selected &&
00143               !o->is_menu_button()) {
00144             // When resizing a group, make sure we also move the children...
00145             ((igroup *)w)->full_resize(right-w->w(), w->y(), w->w(), w->h());
00146           } else {
00147             // Otherwise, just do the widget...
00148             w->resize(right-w->w(), w->y(), w->w(), w->h());
00149           }
00150           w->redraw();
00151           if (w->window()) w->window()->redraw();
00152         }
00153     break;
00154   case 13: // align top
00155     top = max;
00156     for (o = Fl_Type::first; o; o = o->next)
00157       if (o->selected && o->is_widget())
00158       {
00159         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00160         if (w->y()<top)
00161           top = w->y();
00162         BREAK_ON_FIRST;
00163       }
00164     if (top!=max)
00165       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00166         if (o->selected && o->is_widget())
00167         {
00168           if (!changed) {
00169             changed = 1;
00170             set_modflag(1);
00171             undo_checkpoint();
00172           }
00173 
00174           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00175           if (o->next && o->next->level > o->level && !o->next->selected &&
00176               !o->is_menu_button()) {
00177             // When resizing a group, make sure we also move the children...
00178             ((igroup *)w)->full_resize(w->x(), top, w->w(), w->h());
00179           } else {
00180             // Otherwise, just do the widget...
00181             w->resize(w->x(), top, w->w(), w->h());
00182           }
00183           w->redraw();
00184           if (w->window()) w->window()->redraw();
00185         }
00186     break;
00187   case 14: // align v.center
00188     top = max; bot = min;
00189     for (o = Fl_Type::first; o; o = o->next)
00190       if (o->selected && o->is_widget())
00191       {
00192         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00193         if (w->y()<top)
00194           top = w->y();
00195         if (w->y()+w->h()>bot)
00196           bot = w->y()+w->h();
00197         BREAK_ON_FIRST;
00198       }
00199     if (top!=max)
00200     {
00201       int center2 = top+bot;
00202       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00203         if (o->selected && o->is_widget())
00204         {
00205           if (!changed) {
00206             changed = 1;
00207             set_modflag(1);
00208             undo_checkpoint();
00209           }
00210 
00211           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00212           if (o->next && o->next->level > o->level && !o->next->selected &&
00213               !o->is_menu_button()) {
00214             // When resizing a group, make sure we also move the children...
00215             ((igroup *)w)->full_resize(w->x(), (center2-w->h())/2, w->w(), w->h());
00216           } else {
00217             // Otherwise, just do the widget...
00218             w->resize(w->x(), (center2-w->h())/2, w->w(), w->h());
00219           }
00220           w->redraw();
00221           if (w->window()) w->window()->redraw();
00222         }
00223     }
00224     break;
00225   case 15: // align bottom
00226     bot = min;
00227     for (o = Fl_Type::first; o; o = o->next)
00228       if (o->selected && o->is_widget())
00229       {
00230         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00231         if (w->y()+w->h()>bot)
00232           bot = w->y()+w->h();
00233         BREAK_ON_FIRST;
00234       }
00235     if (bot!=min)
00236       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00237         if (o->selected && o->is_widget())
00238         {
00239           if (!changed) {
00240             changed = 1;
00241             set_modflag(1);
00242             undo_checkpoint();
00243           }
00244 
00245           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00246           if (o->next && o->next->level > o->level && !o->next->selected &&
00247               !o->is_menu_button()) {
00248             // When resizing a group, make sure we also move the children...
00249             ((igroup *)w)->full_resize( w->x(), bot-w->h(), w->w(), w->h());
00250           } else {
00251             // Otherwise, just do the widget...
00252             w->resize( w->x(), bot-w->h(), w->w(), w->h());
00253           }
00254           w->redraw();
00255           if (w->window()) w->window()->redraw();
00256         }
00257     break;
00258   //---- space evently
00259   case 20: // space evenly across
00260     left = max; right = min; wdt = 0, n = 0;
00261     for (o = Fl_Type::first; o; o = o->next)
00262       if (o->selected && o->is_widget())
00263       {
00264         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00265         if (w->x()<left)
00266           left = w->x();
00267         if (w->x()+w->w()>right)
00268           right = w->x()+w->w();
00269         wdt += w->w();
00270         n++;
00271       }
00272     wdt = (right-left)-wdt;
00273     n--;
00274     if (n>0)
00275     {
00276       int cnt = 0, wsum = 0;
00277       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00278         if (o->selected && o->is_widget())
00279         {
00280           if (!changed) {
00281             changed = 1;
00282             set_modflag(1);
00283             undo_checkpoint();
00284           }
00285 
00286           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00287           if (o->next && o->next->level > o->level && !o->next->selected &&
00288               !o->is_menu_button()) {
00289             // When resizing a group, make sure we also move the children...
00290             ((igroup *)w)->full_resize(left+wsum+wdt*cnt/n, w->y(), w->w(), w->h());
00291           } else {
00292             // Otherwise, just do the widget...
00293             w->resize(left+wsum+wdt*cnt/n, w->y(), w->w(), w->h());
00294           }
00295           w->redraw();
00296           if (w->window()) w->window()->redraw();
00297           cnt++;
00298           wsum += w->w();
00299         }
00300     }
00301     break;
00302   case 21: // space evenly down
00303     top = max; bot = min; hgt = 0, n = 0;
00304     for (o = Fl_Type::first; o; o = o->next)
00305       if (o->selected && o->is_widget())
00306       {
00307         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00308         if (w->y()<top)
00309           top = w->y();
00310         if (w->y()+w->h()>bot)
00311           bot = w->y()+w->h();
00312         hgt += w->h();
00313         n++;
00314       }
00315     hgt = (bot-top)-hgt;
00316     n--;
00317     if (n>0)
00318     {
00319       int cnt = 0, hsum = 0;
00320       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00321         if (o->selected && o->is_widget())
00322         {
00323           if (!changed) {
00324             changed = 1;
00325             set_modflag(1);
00326             undo_checkpoint();
00327           }
00328 
00329           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00330           if (o->next && o->next->level > o->level && !o->next->selected &&
00331               !o->is_menu_button()) {
00332             // When resizing a group, make sure we also move the children...
00333             ((igroup *)w)->full_resize(w->x(), top+hsum+hgt*cnt/n, w->w(), w->h());
00334           } else {
00335             // Otherwise, just do the widget...
00336             w->resize(w->x(), top+hsum+hgt*cnt/n, w->w(), w->h());
00337           }
00338           w->redraw();
00339           if (w->window()) w->window()->redraw();
00340           cnt++;
00341           hsum += w->h();
00342         }
00343     }
00344     break;
00345   //---- make same size
00346   case 30: // same width
00347     wdt = min;
00348     for (o = Fl_Type::first; o; o = o->next)
00349       if (o->selected && o->is_widget())
00350       {
00351         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00352         if (w->w()>wdt)
00353           wdt = w->w();
00354         BREAK_ON_FIRST;
00355       }
00356     if (wdt!=min)
00357       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00358         if (o->selected && o->is_widget())
00359         {
00360           if (!changed) {
00361             changed = 1;
00362             set_modflag(1);
00363             undo_checkpoint();
00364           }
00365 
00366           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00367           if (o->next && o->next->level > o->level && !o->next->selected &&
00368               !o->is_menu_button()) {
00369             // When resizing a group, make sure we also move the children...
00370             ((igroup *)w)->full_resize(w->x(), w->y(), wdt, w->h());
00371           } else {
00372             // Otherwise, just do the widget...
00373             w->resize(w->x(), w->y(), wdt, w->h());
00374           }
00375           w->redraw();
00376           if (w->window()) w->window()->redraw();
00377         }
00378     break;
00379   case 31: // same height
00380     hgt = min;
00381     for (o = Fl_Type::first; o; o = o->next)
00382       if (o->selected && o->is_widget())
00383       {
00384         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00385         if (w->h()>hgt)
00386           hgt = w->h();
00387         BREAK_ON_FIRST;
00388       }
00389     if (hgt!=min)
00390       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00391         if (o->selected && o->is_widget())
00392         {
00393           if (!changed) {
00394             changed = 1;
00395             set_modflag(1);
00396             undo_checkpoint();
00397           }
00398 
00399           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00400           if (o->next && o->next->level > o->level && !o->next->selected &&
00401               !o->is_menu_button()) {
00402             // When resizing a group, make sure we also move the children...
00403             ((igroup *)w)->full_resize( w->x(), w->y(), w->w(), hgt);
00404           } else {
00405             // Otherwise, just do the widget...
00406             w->resize( w->x(), w->y(), w->w(), hgt);
00407           }
00408           w->redraw();
00409           if (w->window()) w->window()->redraw();
00410         }
00411     break;
00412   case 32: // same size
00413     hgt = min; wdt = min;
00414     for (o = Fl_Type::first; o; o = o->next)
00415       if (o->selected && o->is_widget())
00416       {
00417         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00418         if (w->w()>wdt)
00419           wdt = w->w();
00420         if (w->h()>hgt)
00421           hgt = w->h();
00422         BREAK_ON_FIRST;
00423       }
00424     if (hgt!=min)
00425       for (Fl_Type *o = Fl_Type::first; o; o = o->next)
00426         if (o->selected && o->is_widget())
00427         {
00428           if (!changed) {
00429             changed = 1;
00430             set_modflag(1);
00431             undo_checkpoint();
00432           }
00433 
00434           Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00435           if (o->next && o->next->level > o->level && !o->next->selected &&
00436               !o->is_menu_button()) {
00437             // When resizing a group, make sure we also move the children...
00438             ((igroup *)w)->full_resize( w->x(), w->y(), wdt, hgt);
00439           } else {
00440             // Otherwise, just do the widget...
00441             w->resize( w->x(), w->y(), wdt, hgt);
00442           }
00443           w->redraw();
00444           if (w->window()) w->window()->redraw();
00445         }
00446     break;
00447   //---- center in group
00448   case 40: // center hor
00449     for (o = Fl_Type::first; o; o = o->next)
00450       if (o->selected && o->is_widget() && o->parent)
00451       {
00452         if (!changed) {
00453           changed = 1;
00454           set_modflag(1);
00455           undo_checkpoint();
00456         }
00457 
00458         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00459         Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
00460         int center2;
00461 
00462         if (w->window() == p) center2 = p->w();
00463         else center2 = 2*p->x()+p->w();
00464 
00465         if (o->next && o->next->level > o->level && !o->next->selected &&
00466             !o->is_menu_button() && !o->is_menu_button()) {
00467           // When resizing a group, make sure we also move the children...
00468           ((igroup *)w)->full_resize((center2-w->w())/2, w->y(), w->w(), w->h());
00469         } else {
00470           // Otherwise, just do the widget...
00471           w->resize((center2-w->w())/2, w->y(), w->w(), w->h());
00472         }
00473         w->redraw();
00474         if (w->window()) w->window()->redraw();
00475       }
00476     break;
00477   case 41: // center vert
00478     for (o = Fl_Type::first; o; o = o->next)
00479       if (o->selected && o->is_widget() && o->parent)
00480       {
00481         if (!changed) {
00482           changed = 1;
00483           set_modflag(1);
00484           undo_checkpoint();
00485         }
00486 
00487         Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00488         Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
00489         int center2;
00490 
00491         if (w->window() == p) center2 = p->h();
00492         else center2 = 2*p->y()+p->h();
00493 
00494         if (o->next && o->next->level > o->level && !o->next->selected &&
00495             !o->is_menu_button()) {
00496           // When resizing a group, make sure we also move the children...
00497           ((igroup *)w)->full_resize(w->x(), (center2-w->h())/2, w->w(), w->h());
00498         } else {
00499           // Otherwise, just do the widget...
00500           w->resize(w->x(), (center2-w->h())/2, w->w(), w->h());
00501         }
00502         set_modflag(1);
00503         w->redraw();
00504         if (w->window()) w->window()->redraw();
00505       }
00506     break;
00507   }
00508 }
00509 
00510 
00511 // Set sizes of selected widgets...
00512 void widget_size_cb(Fl_Widget *, long size) {
00513   // Update any selected widgets...
00514   int changed = 0;
00515   for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
00516     if (o->selected && o->is_widget()) {
00517       if (!changed) {
00518         changed = 1;
00519         set_modflag(1);
00520         undo_checkpoint();
00521       }
00522 
00523       Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
00524       w->labelsize((Fl_Font)size);
00525       Fl_Font f;
00526       int s = (int)size;
00527       Fl_Color c;
00528       ((Fl_Widget_Type *)o)->textstuff(2, f, s, c);
00529 
00530       w->redraw();
00531       // since this may be a major change, the whole window should be redrawn
00532       if (w->window()) w->window()->redraw();
00533     }
00534   }
00535 }
00536 
00537 
00538 //
00539 // End of "$Id: align_widget.cxx 7903 2010-11-28 21:06:39Z matt $".
00540 //
00541