|
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) ![]() |
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