/fltk/src/Fl_Group.cxx
C++ | 828 lines | 545 code | 78 blank | 205 comment | 218 complexity | e023b90158e09a0759dd87a59364de5e MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-3.0, 0BSD
- //
- // "$Id: Fl_Group.cxx 7469 2010-04-07 23:17:33Z matt $"
- //
- // Group widget for the Fast Light Tool Kit (FLTK).
- //
- // Copyright 1998-2009 by Bill Spitzak and others.
- //
- // This library is free software; you can redistribute it and/or
- // modify it under the terms of the GNU Library General Public
- // License as published by the Free Software Foundation; either
- // version 2 of the License, or (at your option) any later version.
- //
- // This library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- // Library General Public License for more details.
- //
- // You should have received a copy of the GNU Library General Public
- // License along with this library; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- // USA.
- //
- // Please report all bugs and problems on the following page:
- //
- // http://www.fltk.org/str.php
- //
-
- // The Fl_Group is the only defined container type in FLTK.
-
- // Fl_Window itself is a subclass of this, and most of the event
- // handling is designed so windows themselves work correctly.
-
- #include <stdio.h>
- #include <FL/Fl.H>
- #include <FL/Fl_Group.H>
- #include <FL/Fl_Window.H>
- #include <FL/fl_draw.H>
- #include <stdlib.h>
-
- Fl_Group* Fl_Group::current_;
-
- // Hack: A single child is stored in the pointer to the array, while
- // multiple children are stored in an allocated array:
-
- /**
- Returns a pointer to the array of children. <I>This pointer is only
- valid until the next time a child is added or removed.</I>
- */
- Fl_Widget*const* Fl_Group::array() const {
- return children_ <= 1 ? (Fl_Widget**)(&array_) : array_;
- }
-
- /**
- Searches the child array for the widget and returns the index. Returns children()
- if the widget is NULL or not found.
- */
- int Fl_Group::find(const Fl_Widget* o) const {
- Fl_Widget*const* a = array();
- int i; for (i=0; i < children_; i++) if (*a++ == o) break;
- return i;
- }
-
- // Metrowerks CodeWarrior and others can't export the static
- // class member: current_, so these methods can't be inlined...
-
- /**
- Sets the current group so you can build the widget
- tree by just constructing the widgets.
-
- begin() is automatically called by the constructor for Fl_Group (and thus for
- Fl_Window as well). begin() <I>is exactly the same as</I> current(this).
- <I>Don't forget to end() the group or window!</I>
- */
- void Fl_Group::begin() {current_ = this;}
-
- /**
- <I>Exactly the same as</I> current(this->parent()). Any new widgets
- added to the widget tree will be added to the parent of the group.
- */
- void Fl_Group::end() {current_ = parent();}
-
- /**
- Returns the currently active group.
-
- The Fl_Widget constructor automatically does current()->add(widget) if this
- is not null. To prevent new widgets from being added to a group, call
- Fl_Group::current(0).
- */
- Fl_Group *Fl_Group::current() {return current_;}
-
- /**
- See static Fl_Group *Fl_Group::current()
- */
- void Fl_Group::current(Fl_Group *g) {current_ = g;}
-
- extern Fl_Widget* fl_oldfocus; // set by Fl::focus
-
- // For back-compatibility, we must adjust all events sent to child
- // windows so they are relative to that window.
-
- static int send(Fl_Widget* o, int event) {
- if (o->type() < FL_WINDOW) return o->handle(event);
- switch ( event )
- {
- case FL_DND_ENTER: /* FALLTHROUGH */
- case FL_DND_DRAG:
- // figure out correct type of event:
- event = (o->contains(Fl::belowmouse())) ? FL_DND_DRAG : FL_DND_ENTER;
- }
- int save_x = Fl::e_x; Fl::e_x -= o->x();
- int save_y = Fl::e_y; Fl::e_y -= o->y();
- int ret = o->handle(event);
- Fl::e_y = save_y;
- Fl::e_x = save_x;
- switch ( event )
- {
- case FL_ENTER: /* FALLTHROUGH */
- case FL_DND_ENTER:
- // Successful completion of FL_ENTER means the widget is now the
- // belowmouse widget, but only call Fl::belowmouse if the child
- // widget did not do so:
- if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o);
- break;
- }
- return ret;
- }
-
- // translate the current keystroke into up/down/left/right for navigation:
- #define ctrl(x) (x^0x40)
- static int navkey() {
- switch (Fl::event_key()) {
- case 0: // not an FL_KEYBOARD/FL_SHORTCUT event
- break;
- case FL_Tab:
- if (!Fl::event_state(FL_SHIFT)) return FL_Right;
- case 0xfe20: // XK_ISO_Left_Tab
- return FL_Left;
- case FL_Right:
- return FL_Right;
- case FL_Left:
- return FL_Left;
- case FL_Up:
- return FL_Up;
- case FL_Down:
- return FL_Down;
- }
- return 0;
- }
-
- int Fl_Group::handle(int event) {
- if(user_handler_) {
- int result = (*user_handler_)(this, event);
- if (result) return result;
- }
- Fl_Widget*const* a = array();
- int i;
- Fl_Widget* o;
-
- switch (event) {
-
- case FL_FOCUS:
- switch (navkey()) {
- default:
- if (savedfocus_ && savedfocus_->take_focus()) return 1;
- case FL_Right:
- case FL_Down:
- for (i = children(); i--;) if ((*a++)->take_focus()) return 1;
- break;
- case FL_Left:
- case FL_Up:
- for (i = children(); i--;) if (a[i]->take_focus()) return 1;
- break;
- }
- return 0;
-
- case FL_UNFOCUS:
- savedfocus_ = fl_oldfocus;
- return 0;
-
- case FL_KEYBOARD:
- return navigation(navkey());
-
- case FL_SHORTCUT:
- for (i = children(); i--;) {
- o = a[i];
- if (o->takesevents() && Fl::event_inside(o) && send(o,FL_SHORTCUT))
- return 1;
- }
- for (i = children(); i--;) {
- o = a[i];
- if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_SHORTCUT))
- return 1;
- }
- if ((Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter))
- //return navigation(FL_Down);
- return navigation(FL_Right);
- return 0;
-
- case FL_ENTER:
- case FL_MOVE:
- for (i = children(); i--;) {
- o = a[i];
- if (o->visible() && Fl::event_inside(o)) {
- if (o->contains(Fl::belowmouse())) {
- return send(o,FL_MOVE);
- } else {
- Fl::belowmouse(o);
- if (send(o,FL_ENTER)) return 1;
- }
- }
- }
- Fl::belowmouse(this);
- return 1;
-
- case FL_DND_ENTER:
- case FL_DND_DRAG:
- for (i = children(); i--;) {
- o = a[i];
- if (o->takesevents() && Fl::event_inside(o)) {
- if (o->contains(Fl::belowmouse())) {
- return send(o,FL_DND_DRAG);
- } else if (send(o,FL_DND_ENTER)) {
- if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o);
- return 1;
- }
- }
- }
- Fl::belowmouse(this);
- return 0;
-
- case FL_PUSH:
- for (i = children(); i--;) {
- o = a[i];
- if (o->takesevents() && Fl::event_inside(o)) {
- Fl_Widget_Tracker wp(o);
- if (send(o,FL_PUSH)) {
- if (Fl::pushed() && wp.exists() && !o->contains(Fl::pushed())) Fl::pushed(o);
- return 1;
- }
- }
- }
- return 0;
-
- case FL_RELEASE:
- case FL_DRAG:
- o = Fl::pushed();
- if (o == this) return 0;
- else if (o) send(o,event);
- else {
- for (i = children(); i--;) {
- o = a[i];
- if (o->takesevents() && Fl::event_inside(o)) {
- if (send(o,event)) return 1;
- }
- }
- }
- return 0;
-
- case FL_MOUSEWHEEL:
- for (i = children(); i--;) {
- o = a[i];
- if (o->takesevents() && Fl::event_inside(o) && send(o,FL_MOUSEWHEEL))
- return 1;
- }
- for (i = children(); i--;) {
- o = a[i];
- if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_MOUSEWHEEL))
- return 1;
- }
- return 0;
-
- case FL_DEACTIVATE:
- case FL_ACTIVATE:
- for (i = children(); i--;) {
- o = *a++;
- if (o->active()) o->handle(event);
- }
- return 1;
-
- case FL_SHOW:
- case FL_HIDE:
- for (i = children(); i--;) {
- o = *a++;
- if (event == FL_HIDE && o == Fl::focus()) {
- // Give up input focus...
- int old_event = Fl::e_number;
- o->handle(Fl::e_number = FL_UNFOCUS);
- Fl::e_number = old_event;
- Fl::focus(0);
- }
- if (o->visible()) o->handle(event);
- }
- return 1;
-
- default:
- // For all other events, try to give to each child, starting at focus:
- for (i = 0; i < children(); i ++)
- if (Fl::focus_ == a[i]) break;
-
- if (i >= children()) i = 0;
-
- if (children()) {
- for (int j = i;;) {
- if (a[j]->takesevents()) if (send(a[j], event)) return 1;
- j++;
- if (j >= children()) j = 0;
- if (j == i) break;
- }
- }
-
- return 0;
- }
- }
-
- //void Fl_Group::focus(Fl_Widget *o) {Fl::focus(o); o->handle(FL_FOCUS);}
-
- #if 0
- const char *nameof(Fl_Widget *o) {
- if (!o) return "NULL";
- if (!o->label()) return "<no label>";
- return o->label();
- }
- #endif
-
- // try to move the focus in response to a keystroke:
- int Fl_Group::navigation(int key) {
- if (children() <= 1) return 0;
- int i;
- for (i = 0; ; i++) {
- if (i >= children_) return 0;
- if (array_[i]->contains(Fl::focus())) break;
- }
- Fl_Widget *previous = array_[i];
-
- for (;;) {
- switch (key) {
- case FL_Right:
- case FL_Down:
- i++;
- if (i >= children_) {
- if (parent()) return 0;
- i = 0;
- }
- break;
- case FL_Left:
- case FL_Up:
- if (i) i--;
- else {
- if (parent()) return 0;
- i = children_-1;
- }
- break;
- default:
- return 0;
- }
- Fl_Widget* o = array_[i];
- if (o == previous) return 0;
- switch (key) {
- case FL_Down:
- case FL_Up:
- // for up/down, the widgets have to overlap horizontally:
- if (o->x() >= previous->x()+previous->w() ||
- o->x()+o->w() <= previous->x()) continue;
- }
- if (o->take_focus()) return 1;
- }
- }
-
- ////////////////////////////////////////////////////////////////
-
- Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l)
- : Fl_Widget(X,Y,W,H,l) {
- align(FL_ALIGN_TOP);
- set_flag(GROUP_TYPE);
- children_ = 0;
- array_ = 0;
- savedfocus_ = 0;
- resizable_ = this;
- sizes_ = 0; // this is allocated when first resize() is done
- // Subclasses may want to construct child objects as part of their
- // constructor, so make sure they are add()'d to this object.
- // But you must end() the object!
- user_handler_ = NULL;
- begin();
- }
-
- /**
- Deletes all child widgets from memory recursively.
-
- This method differs from the remove() method in that it
- affects all child widgets and deletes them from memory.
- */
- void Fl_Group::clear() {
- savedfocus_ = 0;
- resizable_ = this;
- init_sizes();
- // okay, now it is safe to destroy the children:
- while (children_) {
- Fl_Widget* o = child(0); // *first* child widget
- if (o->parent() == this) { // should always be true
- remove(o); // remove child widget first
- delete o; // then delete it
- } else { // this should never happen !
- #ifdef DEBUG_CLEAR
- printf ("Fl_Group::clear() widget:%p, parent: %p != this (%p)\n",
- o, o->parent(), this); fflush(stdout);
- #endif // DEBUG_CLEAR
- remove(o); // remove it
- }
- }
- }
-
- /**
- The destructor <I>also deletes all the children</I>. This allows a
- whole tree to be deleted at once, without having to keep a pointer to
- all the children in the user code.
-
- It is allowed that the Fl_Group and all of its children are automatic
- (local) variables, but you must declare the Fl_Group \e first, so that
- it is destroyed last.
-
- If you add static or automatic (local) variables to an Fl_Group, then it
- is your responsibility to remove (or delete) all such static or automatic
- child widgets \e \b before destroying the group - otherwise the child
- widgets' destructors would be called twice!
- */
- Fl_Group::~Fl_Group() {
- clear();
- }
-
- /**
- The widget is removed from its current group (if any) and then
- inserted into this group. It is put at index n - or at the end,
- if n >= children(). This can also be used to rearrange
- the widgets inside a group.
- */
- void Fl_Group::insert(Fl_Widget &o, int index) {
- if (o.parent()) {
- Fl_Group* g = o.parent();
- int n = g->find(o);
- if (g == this) {
- if (index > n) index--;
- if (index == n) return;
- }
- g->remove(o);
- }
- o.parent_ = this;
- if (children_ == 0) { // use array pointer to point at single child
- array_ = (Fl_Widget**)&o;
- } else if (children_ == 1) { // go from 1 to 2 children
- Fl_Widget* t = (Fl_Widget*)array_;
- array_ = (Fl_Widget**)malloc(2*sizeof(Fl_Widget*));
- if (index) {array_[0] = t; array_[1] = &o;}
- else {array_[0] = &o; array_[1] = t;}
- } else {
- if (!(children_ & (children_-1))) // double number of children
- array_ = (Fl_Widget**)realloc((void*)array_,
- 2*children_*sizeof(Fl_Widget*));
- int j; for (j = children_; j > index; j--) array_[j] = array_[j-1];
- array_[j] = &o;
- }
- children_++;
- init_sizes();
- }
-
- /**
- The widget is removed from its current group (if any) and then added
- to the end of this group.
- */
- void Fl_Group::add(Fl_Widget &o) {insert(o, children_);}
-
- /**
- Removes a widget from the group but does not delete it.
-
- This method does nothing if the widget is not a child of the group.
-
- This method differs from the clear() method in that it only affects
- a single widget and does not delete it from memory.
- */
- void Fl_Group::remove(Fl_Widget &o) {
- if (!children_) return;
- int i = find(o);
- if (i >= children_) return;
- if (&o == savedfocus_) savedfocus_ = 0;
- if (o.parent_ == this) { // this should always be true
- o.parent_ = 0;
- }
- #ifdef DEBUG_REMOVE
- else { // this should never happen !
- printf ("Fl_Group::remove(): widget %p, parent_ (%p) != this (%p)\n",
- &o, o.parent_, this);
- }
- #endif // DEBUG_REMOVE
-
- // remove the widget from the group
-
- children_--;
- if (children_ == 1) { // go from 2 to 1 child
- Fl_Widget *t = array_[!i];
- free((void*)array_);
- array_ = (Fl_Widget**)t;
- } else if (children_ > 1) { // delete from array
- for (; i < children_; i++) array_[i] = array_[i+1];
- }
- init_sizes();
- }
-
- ////////////////////////////////////////////////////////////////
-
- // Rather lame kludge here, I need to detect windows and ignore the
- // changes to X,Y, since all children are relative to X,Y. That
- // is why I check type():
-
- // sizes array stores the initial positions of widgets as
- // left,right,top,bottom quads. The first quad is the group, the
- // second is the resizable (clipped to the group), and the
- // rest are the children. This is a convenient order for the
- // algorithm. If you change this be sure to fix Fl_Tile which
- // also uses this array!
-
- /**
- Resets the internal array of widget sizes and positions.
-
- The Fl_Group widget keeps track of the original widget sizes and
- positions when resizing occurs so that if you resize a window back to its
- original size the widgets will be in the correct places. If you rearrange
- the widgets in your group, call this method to register the new arrangement
- with the Fl_Group that contains them.
-
- If you add or remove widgets, this will be done automatically.
-
- \note The internal array of widget sizes and positions will be allocated and
- filled when the next resize() occurs.
-
- \sa sizes()
- */
- void Fl_Group::init_sizes() {
- delete[] sizes_; sizes_ = 0;
- }
-
- /**
- Returns the internal array of widget sizes and positions.
-
- If the sizes() array does not exist, it will be allocated and filled
- with the current widget sizes and positions.
-
- \note You should never need to use this method directly, unless you have
- special needs to rearrange the children of a Fl_Group. Fl_Tile uses
- this to rearrange its widget positions.
-
- \sa init_sizes()
-
- \todo Should the internal representation of the sizes() array be documented?
- */
-
- st_widget_sizes* Fl_Group::sizes() {
- if (!sizes_) {
- //int* p = sizes_ = new int[4*(children_+2)];
- st_widget_sizes* p = sizes_ = new st_widget_sizes[(children_+2)];
- // first thing in sizes array is the group's size:
- if (type() < FL_WINDOW) {p->x = x(); p->y = y();} else {p->x = p->y = 0;}
- p->w = p->x+w(); p->h = p->y+h();
- p->labelsize = labelsize();
- p->textsize = textsize();
- // next is the resizable's size:
- ++p;
- p->x = sizes_->x; // init to the group's size
- p->w = sizes_->w;
- p->y = sizes_->y;
- p->h = sizes_->h;
- p->labelsize = sizes_->labelsize;
- p->textsize = sizes_->textsize;
-
- Fl_Widget* r = resizable();
- if (r && r != this) { // then clip the resizable to it
- int t;
- t = r->x(); if (t > sizes_->x) p->x = t;
- t +=r->w(); if (t < sizes_->w) p->w = t;
- t = r->y(); if (t > sizes_->y) p->y = t;
- t +=r->h(); if (t < sizes_->h) p->h = t;
- p->labelsize = r->labelsize();
- p->textsize = r->textsize();
- }
- // next is all the children's sizes:
- ++p;
- Fl_Widget*const* a = array();
- for (int i=children_; i--;) {
- Fl_Widget* o = *a++;
- p->x = o->x();
- p->w = o->x()+o->w();
- p->y = o->y();
- p->h = o->y()+o->h();
- p->labelsize = o->labelsize();
- p->textsize = o->textsize();
- ++p;
- }
- }
- return sizes_;
- }
-
- /**
- Resizes the Fl_Group widget and all of its children.
-
- The Fl_Group widget first resizes itself, and then it moves and resizes
- all its children according to the rules documented for
- Fl_Group::resizable(Fl_Widget*)
-
- \sa Fl_Group::resizable(Fl_Widget*)
- \sa Fl_Group::resizable()
- \sa Fl_Widget::resize(int,int,int,int)
- */
- void Fl_Group::resize(int X, int Y, int W, int H) {
-
- int dx = X-x();
- int dy = Y-y();
- int dw = W-w();
- int dh = H-h();
-
- st_widget_sizes *p = sizes(); // save initial sizes and positions
-
- Fl_Widget::resize(X,Y,W,H); // make new xywh values visible for children
-
- if (!resizable() || dw==0 && dh==0 ) {
-
- if (type() < FL_WINDOW) {
- Fl_Widget*const* a = array();
- for (int i=children_; i--;) {
- Fl_Widget* o = *a++;
- o->resize(o->x()+dx, o->y()+dy, o->w(), o->h());
- }
- }
-
- } else if (children_) {
-
- // get changes in size/position from the initial size:
- dx = X - p->x;
- dw = W - (p->w - p->x);
- dy = Y - p->y;
- dh = H - (p->h - p->y);
- if (type() >= FL_WINDOW) dx = dy = 0;
- ++p;
-
- // get initial size of resizable():
- int IX = p->x;
- int IR = p->w;
- int IY = p->y;
- int IB = p->h;
- ++p;
-
- Fl_Widget*const* a = array();
- for (int i=children_; i--;) {
- Fl_Widget* o = *a++;
- #if 1
- int XX = p->x;
- if (XX >= IR) XX += dw;
- else if (XX > IX) XX = IX+((XX-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
- int R = p->w;
- if (R >= IR) R += dw;
- else if (R > IX) R = IX+((R-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
-
- int YY = p->y;
- if (YY >= IB) YY += dh;
- else if (YY > IY) YY = IY+((YY-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
- int B = p->h;
- if (B >= IB) B += dh;
- else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
- #else // much simpler code from Francois Ostiguy:
- int XX = p->x;
- if (XX >= IR) XX += dw;
- else if (XX > IX) XX += dw * (XX-IX)/(IR-IX);
- int R = p->w;
- if (R >= IR) R += dw;
- else if (R > IX) R = R + dw * (R-IX)/(IR-IX);
-
- int YY = p->y;
- if (YY >= IB) YY += dh;
- else if (YY > IY) YY = YY + dh*(YY-IY)/(IB-IY);
- int B = p->h;
- if (B >= IB) B += dh;
- else if (B > IY) B = B + dh*(B-IY)/(IB-IY);
- #endif
- o->resize(XX+dx, YY+dy, R-XX, B-YY);
- ++p;
- }
- }
- }
-
- /**
- Draws all children of the group.
-
- This is useful, if you derived a widget from Fl_Group and want to draw a special
- border or background. You can call draw_children() from the derived draw() method
- after drawing the box, border, or background.
- */
- void Fl_Group::draw_children() {
- Fl_Widget*const* a = array();
-
- if (clip_children()) {
- fl_push_clip(x() + Fl::box_dx(box()),
- y() + Fl::box_dy(box()),
- w() - Fl::box_dw(box()),
- h() - Fl::box_dh(box()));
- }
-
- if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing:
- for (int i=children_; i--;) {
- Fl_Widget& o = **a++;
- draw_child(o);
- draw_outside_label(o);
- }
- } else { // only redraw the children that need it:
- for (int i=children_; i--;) update_child(**a++);
- }
-
- if (clip_children()) fl_pop_clip();
- }
-
- void Fl_Group::draw() {
- if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing:
- draw_box();
- draw_label();
- }
- draw_children();
- }
-
- /**
- Draws a child only if it needs it.
-
- This draws a child widget, if it is not clipped \em and if any damage() bits
- are set. The damage bits are cleared after drawing.
-
- \sa Fl_Group::draw_child(Fl_Widget& widget) const
- */
- void Fl_Group::update_child(Fl_Widget& widget) const {
- if (widget.damage() && widget.visible() && widget.type() < FL_WINDOW &&
- fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) {
- widget.draw();
- widget.clear_damage();
- }
- }
-
- /**
- Forces a child to redraw.
-
- This draws a child widget, if it is not clipped.
- The damage bits are cleared after drawing.
- */
- void Fl_Group::draw_child(Fl_Widget& widget) const {
- if (widget.visible() && widget.type() < FL_WINDOW &&
- fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) {
- widget.clear_damage(FL_DAMAGE_ALL);
- widget.draw();
- widget.clear_damage();
- }
- }
-
- extern char fl_draw_shortcut;
-
- /** Parents normally call this to draw outside labels of child widgets. */
- void Fl_Group::draw_outside_label(const Fl_Widget& widget) const {
- if (!widget.visible()) return;
- // skip any labels that are inside the widget:
- if (!(widget.align()&15) || (widget.align() & FL_ALIGN_INSIDE)) return;
- // invent a box that is outside the widget:
- int a = widget.align();
- int X = widget.x();
- int Y = widget.y();
- int W = widget.w();
- int H = widget.h();
- if ( (a & 0x0f) == FL_ALIGN_LEFT_TOP ) {
- a = (a &~0x0f ) | FL_ALIGN_TOP_RIGHT;
- X = x();
- W = widget.x()-X-3;
- } else if ( (a & 0x0f) == FL_ALIGN_LEFT_BOTTOM ) {
- a = (a &~0x0f ) | FL_ALIGN_BOTTOM_RIGHT;
- X = x();
- W = widget.x()-X-3;
- } else if ( (a & 0x0f) == FL_ALIGN_RIGHT_TOP ) {
- a = (a &~0x0f ) | FL_ALIGN_TOP_LEFT;
- X = X+W+3;
- W = x()+this->w()-X;
- } else if ( (a & 0x0f) == FL_ALIGN_RIGHT_BOTTOM ) {
- a = (a &~0x0f ) | FL_ALIGN_BOTTOM_LEFT;
- X = X+W+3;
- W = x()+this->w()-X;
- } else if (a & FL_ALIGN_TOP) {
- a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
- Y = y();
- H = widget.y()-Y;
- } else if (a & FL_ALIGN_BOTTOM) {
- a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
- Y = Y+H;
- H = y()+h()-Y;
- } else if (a & FL_ALIGN_LEFT) {
- a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
- X = x();
- W = widget.x()-X-3;
- } else if (a & FL_ALIGN_RIGHT) {
- a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
- X = X+W+3;
- W = x()+this->w()-X;
- }
- widget.draw_label(X,Y,W,H,(Fl_Align)a);
- }
-
- void Fl_Group::resizefont(float font_scale){
- st_widget_sizes *p = sizes();
-
- //element at 0 is self = this window
- for(int i=1, iMax=children(); i < iMax; i++)
- {
- Fl_Widget *wdg = child(i);
- if(wdg->inherits_from("Fl_Group"))
- ((Fl_Group*)wdg)->resizefont(font_scale);
- else
- {
- st_widget_sizes *tmp = p+i;
- wdg->labelsize( tmp->labelsize * font_scale);
- if (tmp->textsize)
- wdg->textsize( tmp->textsize * font_scale);
- }
- }
- }
-
- //
- // End of "$Id: Fl_Group.cxx 7469 2010-04-07 23:17:33Z matt $".
- //