source: rtems-graphics-toolkit/fltk-1.1.10/fluid/align_widget.cxx @ 513eea1

Last change on this file since 513eea1 was 513eea1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/09/10 at 22:43:24

2010-01-08 Joel Sherrill <joel.sherrill@…>

fltk 1.1.10. imported

  • ORIGIN: Updated.
  • Property mode set to 100644
File size: 14.2 KB
Line 
1//
2// "$Id$"
3//
4// Alignment code for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 1998-2005 by Bill Spitzak and others.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25//     http://www.fltk.org/str.php
26//
27
28#include <FL/Fl.H>
29#include <FL/Fl_Window.H>
30#include "Fl_Widget_Type.h"
31#include "undo.h"
32
33/**
34 * the first behaviour always uses the first selected widget as a reference
35 * the second behaviour uses the largest widget (most extreme positions) as
36 * a reference.
37 */
38#define BREAK_ON_FIRST break
39//#define BREAK_ON_FIRST
40
41void align_widget_cb(Fl_Widget*, long how)
42{
43  const int max = 32768, min = -32768;
44  int left, right, top, bot, wdt, hgt, n;
45  Fl_Type *o;
46  int changed = 0;
47  switch ( how )
48  {
49  //---- align
50  case 10: // align left
51    left = max;
52    for (o = Fl_Type::first; o; o = o->next)
53      if (o->selected && o->is_widget())
54      {
55        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
56        if (w->x()<left)
57          left = w->x();
58        BREAK_ON_FIRST;
59      }
60    if (left!=max)
61      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
62        if (o->selected && o->is_widget())
63        {
64          if (!changed) {
65            changed = 1;
66            set_modflag(1);
67            undo_checkpoint();
68          }
69
70          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
71          if (o->next && o->next->level > o->level && !o->next->selected &&
72              !o->is_menu_button()) {
73            // When resizing a group, make sure we also move the children...
74            ((igroup *)w)->full_resize(left, w->y(), w->w(), w->h());
75          } else {
76            // Otherwise, just do the widget...
77            w->resize(left, w->y(), w->w(), w->h());
78          }
79          w->redraw();
80          if (w->window()) w->window()->redraw();
81        }
82    break;
83  case 11: // align h.center
84    left = max; right = min;
85    for (o = Fl_Type::first; o; o = o->next)
86      if (o->selected && o->is_widget())
87      {
88        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
89        if (w->x()<left)
90          left = w->x();
91        if (w->x()+w->w()>right)
92          right = w->x()+w->w();
93        BREAK_ON_FIRST;
94      }
95    if (left!=max)
96    {
97      int center2 = left+right;
98      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
99        if (o->selected && o->is_widget())
100        {
101          if (!changed) {
102            changed = 1;
103            set_modflag(1);
104            undo_checkpoint();
105          }
106
107          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
108          if (o->next && o->next->level > o->level && !o->next->selected &&
109              !o->is_menu_button()) {
110            // When resizing a group, make sure we also move the children...
111            ((igroup *)w)->full_resize((center2-w->w())/2, w->y(), w->w(), w->h());
112          } else {
113            // Otherwise, just do the widget...
114            w->resize((center2-w->w())/2, w->y(), w->w(), w->h());
115          }
116          w->redraw();
117          if (w->window()) w->window()->redraw();
118        }
119    }
120    break;
121  case 12: // align right
122    right = min;
123    for (o = Fl_Type::first; o; o = o->next)
124      if (o->selected && o->is_widget())
125      {
126        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
127        if (w->x()+w->w()>right)
128          right = w->x()+w->w();
129        BREAK_ON_FIRST;
130      }
131    if (right!=min)
132      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
133        if (o->selected && o->is_widget())
134        {
135          if (!changed) {
136            changed = 1;
137            set_modflag(1);
138            undo_checkpoint();
139          }
140
141          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
142          if (o->next && o->next->level > o->level && !o->next->selected &&
143              !o->is_menu_button()) {
144            // When resizing a group, make sure we also move the children...
145            ((igroup *)w)->full_resize(right-w->w(), w->y(), w->w(), w->h());
146          } else {
147            // Otherwise, just do the widget...
148            w->resize(right-w->w(), w->y(), w->w(), w->h());
149          }
150          w->redraw();
151          if (w->window()) w->window()->redraw();
152        }
153    break;
154  case 13: // align top
155    top = max;
156    for (o = Fl_Type::first; o; o = o->next)
157      if (o->selected && o->is_widget())
158      {
159        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
160        if (w->y()<top)
161          top = w->y();
162        BREAK_ON_FIRST;
163      }
164    if (top!=max)
165      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
166        if (o->selected && o->is_widget())
167        {
168          if (!changed) {
169            changed = 1;
170            set_modflag(1);
171            undo_checkpoint();
172          }
173
174          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
175          if (o->next && o->next->level > o->level && !o->next->selected &&
176              !o->is_menu_button()) {
177            // When resizing a group, make sure we also move the children...
178            ((igroup *)w)->full_resize(w->x(), top, w->w(), w->h());
179          } else {
180            // Otherwise, just do the widget...
181            w->resize(w->x(), top, w->w(), w->h());
182          }
183          w->redraw();
184          if (w->window()) w->window()->redraw();
185        }
186    break;
187  case 14: // align v.center
188    top = max; bot = min;
189    for (o = Fl_Type::first; o; o = o->next)
190      if (o->selected && o->is_widget())
191      {
192        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
193        if (w->y()<top)
194          top = w->y();
195        if (w->y()+w->h()>bot)
196          bot = w->y()+w->h();
197        BREAK_ON_FIRST;
198      }
199    if (top!=max)
200    {
201      int center2 = top+bot;
202      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
203        if (o->selected && o->is_widget())
204        {
205          if (!changed) {
206            changed = 1;
207            set_modflag(1);
208            undo_checkpoint();
209          }
210
211          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
212          if (o->next && o->next->level > o->level && !o->next->selected &&
213              !o->is_menu_button()) {
214            // When resizing a group, make sure we also move the children...
215            ((igroup *)w)->full_resize(w->x(), (center2-w->h())/2, w->w(), w->h());
216          } else {
217            // Otherwise, just do the widget...
218            w->resize(w->x(), (center2-w->h())/2, w->w(), w->h());
219          }
220          w->redraw();
221          if (w->window()) w->window()->redraw();
222        }
223    }
224    break;
225  case 15: // align bottom
226    bot = min;
227    for (o = Fl_Type::first; o; o = o->next)
228      if (o->selected && o->is_widget())
229      {
230        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
231        if (w->y()+w->h()>bot)
232          bot = w->y()+w->h();
233        BREAK_ON_FIRST;
234      }
235    if (bot!=min)
236      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
237        if (o->selected && o->is_widget())
238        {
239          if (!changed) {
240            changed = 1;
241            set_modflag(1);
242            undo_checkpoint();
243          }
244
245          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
246          if (o->next && o->next->level > o->level && !o->next->selected &&
247              !o->is_menu_button()) {
248            // When resizing a group, make sure we also move the children...
249            ((igroup *)w)->full_resize( w->x(), bot-w->h(), w->w(), w->h());
250          } else {
251            // Otherwise, just do the widget...
252            w->resize( w->x(), bot-w->h(), w->w(), w->h());
253          }
254          w->redraw();
255          if (w->window()) w->window()->redraw();
256        }
257    break;
258  //---- space evently
259  case 20: // space evenly across
260    left = max; right = min; wdt = 0, n = 0;
261    for (o = Fl_Type::first; o; o = o->next)
262      if (o->selected && o->is_widget())
263      {
264        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
265        if (w->x()<left)
266          left = w->x();
267        if (w->x()+w->w()>right)
268          right = w->x()+w->w();
269        wdt += w->w();
270        n++;
271      }
272    wdt = (right-left)-wdt;
273    n--;
274    if (n>0)
275    {
276      int cnt = 0, wsum = 0;
277      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
278        if (o->selected && o->is_widget())
279        {
280          if (!changed) {
281            changed = 1;
282            set_modflag(1);
283            undo_checkpoint();
284          }
285
286          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
287          if (o->next && o->next->level > o->level && !o->next->selected &&
288              !o->is_menu_button()) {
289            // When resizing a group, make sure we also move the children...
290            ((igroup *)w)->full_resize(left+wsum+wdt*cnt/n, w->y(), w->w(), w->h());
291          } else {
292            // Otherwise, just do the widget...
293            w->resize(left+wsum+wdt*cnt/n, w->y(), w->w(), w->h());
294          }
295          w->redraw();
296          if (w->window()) w->window()->redraw();
297          cnt++;
298          wsum += w->w();
299        }
300    }
301    break;
302  case 21: // space evenly down
303    top = max; bot = min; hgt = 0, n = 0;
304    for (o = Fl_Type::first; o; o = o->next)
305      if (o->selected && o->is_widget())
306      {
307        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
308        if (w->y()<top)
309          top = w->y();
310        if (w->y()+w->h()>bot)
311          bot = w->y()+w->h();
312        hgt += w->h();
313        n++;
314      }
315    hgt = (bot-top)-hgt;
316    n--;
317    if (n>0)
318    {
319      int cnt = 0, hsum = 0;
320      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
321        if (o->selected && o->is_widget())
322        {
323          if (!changed) {
324            changed = 1;
325            set_modflag(1);
326            undo_checkpoint();
327          }
328
329          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
330          if (o->next && o->next->level > o->level && !o->next->selected &&
331              !o->is_menu_button()) {
332            // When resizing a group, make sure we also move the children...
333            ((igroup *)w)->full_resize(w->x(), top+hsum+hgt*cnt/n, w->w(), w->h());
334          } else {
335            // Otherwise, just do the widget...
336            w->resize(w->x(), top+hsum+hgt*cnt/n, w->w(), w->h());
337          }
338          w->redraw();
339          if (w->window()) w->window()->redraw();
340          cnt++;
341          hsum += w->h();
342        }
343    }
344    break;
345  //---- make same size
346  case 30: // same width
347    wdt = min;
348    for (o = Fl_Type::first; o; o = o->next)
349      if (o->selected && o->is_widget())
350      {
351        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
352        if (w->w()>wdt)
353          wdt = w->w();
354        BREAK_ON_FIRST;
355      }
356    if (wdt!=min)
357      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
358        if (o->selected && o->is_widget())
359        {
360          if (!changed) {
361            changed = 1;
362            set_modflag(1);
363            undo_checkpoint();
364          }
365
366          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
367          if (o->next && o->next->level > o->level && !o->next->selected &&
368              !o->is_menu_button()) {
369            // When resizing a group, make sure we also move the children...
370            ((igroup *)w)->full_resize(w->x(), w->y(), wdt, w->h());
371          } else {
372            // Otherwise, just do the widget...
373            w->resize(w->x(), w->y(), wdt, w->h());
374          }
375          w->redraw();
376          if (w->window()) w->window()->redraw();
377        }
378    break;
379  case 31: // same height
380    hgt = min;
381    for (o = Fl_Type::first; o; o = o->next)
382      if (o->selected && o->is_widget())
383      {
384        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
385        if (w->h()>hgt)
386          hgt = w->h();
387        BREAK_ON_FIRST;
388      }
389    if (hgt!=min)
390      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
391        if (o->selected && o->is_widget())
392        {
393          if (!changed) {
394            changed = 1;
395            set_modflag(1);
396            undo_checkpoint();
397          }
398
399          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
400          if (o->next && o->next->level > o->level && !o->next->selected &&
401              !o->is_menu_button()) {
402            // When resizing a group, make sure we also move the children...
403            ((igroup *)w)->full_resize( w->x(), w->y(), w->w(), hgt);
404          } else {
405            // Otherwise, just do the widget...
406            w->resize( w->x(), w->y(), w->w(), hgt);
407          }
408          w->redraw();
409          if (w->window()) w->window()->redraw();
410        }
411    break;
412  case 32: // same size
413    hgt = min; wdt = min;
414    for (o = Fl_Type::first; o; o = o->next)
415      if (o->selected && o->is_widget())
416      {
417        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
418        if (w->w()>wdt)
419          wdt = w->w();
420        if (w->h()>hgt)
421          hgt = w->h();
422        BREAK_ON_FIRST;
423      }
424    if (hgt!=min)
425      for (Fl_Type *o = Fl_Type::first; o; o = o->next)
426        if (o->selected && o->is_widget())
427        {
428          if (!changed) {
429            changed = 1;
430            set_modflag(1);
431            undo_checkpoint();
432          }
433
434          Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
435          if (o->next && o->next->level > o->level && !o->next->selected &&
436              !o->is_menu_button()) {
437            // When resizing a group, make sure we also move the children...
438            ((igroup *)w)->full_resize( w->x(), w->y(), wdt, hgt);
439          } else {
440            // Otherwise, just do the widget...
441            w->resize( w->x(), w->y(), wdt, hgt);
442          }
443          w->redraw();
444          if (w->window()) w->window()->redraw();
445        }
446    break;
447  //---- center in group
448  case 40: // center hor
449    for (o = Fl_Type::first; o; o = o->next)
450      if (o->selected && o->is_widget() && o->parent)
451      {
452        if (!changed) {
453          changed = 1;
454          set_modflag(1);
455          undo_checkpoint();
456        }
457
458        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
459        Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
460        int center2;
461
462        if (w->window() == p) center2 = p->w();
463        else center2 = 2*p->x()+p->w();
464
465        if (o->next && o->next->level > o->level && !o->next->selected &&
466            !o->is_menu_button() && !o->is_menu_button()) {
467          // When resizing a group, make sure we also move the children...
468          ((igroup *)w)->full_resize((center2-w->w())/2, w->y(), w->w(), w->h());
469        } else {
470          // Otherwise, just do the widget...
471          w->resize((center2-w->w())/2, w->y(), w->w(), w->h());
472        }
473        w->redraw();
474        if (w->window()) w->window()->redraw();
475      }
476    break;
477  case 41: // center vert
478    for (o = Fl_Type::first; o; o = o->next)
479      if (o->selected && o->is_widget() && o->parent)
480      {
481        if (!changed) {
482          changed = 1;
483          set_modflag(1);
484          undo_checkpoint();
485        }
486
487        Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
488        Fl_Widget *p = ((Fl_Widget_Type *)o->parent)->o;
489        int center2;
490
491        if (w->window() == p) center2 = p->h();
492        else center2 = 2*p->y()+p->h();
493
494        if (o->next && o->next->level > o->level && !o->next->selected &&
495            !o->is_menu_button()) {
496          // When resizing a group, make sure we also move the children...
497          ((igroup *)w)->full_resize(w->x(), (center2-w->h())/2, w->w(), w->h());
498        } else {
499          // Otherwise, just do the widget...
500          w->resize(w->x(), (center2-w->h())/2, w->w(), w->h());
501        }
502        set_modflag(1);
503        w->redraw();
504        if (w->window()) w->window()->redraw();
505      }
506    break;
507  }
508}
509
510
511// Set sizes of selected widgets...
512void widget_size_cb(Fl_Widget *, long size) {
513  // Update any selected widgets...
514  int changed = 0;
515  for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
516    if (o->selected && o->is_widget()) {
517      if (!changed) {
518        changed = 1;
519        set_modflag(1);
520        undo_checkpoint();
521      }
522
523      Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
524      w->labelsize((uchar)size);
525      Fl_Font f;
526      int s = (int)size;
527      Fl_Color c;
528      ((Fl_Widget_Type *)o)->textstuff(2, f, s, c);
529
530      w->redraw();
531      // since this may be a major change, the whole window should be redrawn
532      if (w->window()) w->window()->redraw();
533    }
534  }
535}
536
537
538//
539// End of "$Id$".
540//
541
Note: See TracBrowser for help on using the repository browser.