2
// "$Id: Fl_Group.cxx 7469 2010-04-07 23:17:33Z matt $"
2
// "$Id: Fl_Group.cxx 8184 2011-01-04 18:28:01Z matt $"
4
4
// Group widget for the Fast Light Tool Kit (FLTK).
6
// Copyright 1998-2009 by Bill Spitzak and others.
6
// Copyright 1998-2010 by Bill Spitzak and others.
8
8
// This library is free software; you can redistribute it and/or
9
9
// modify it under the terms of the GNU Library General Public
388
388
resizable_ = this;
391
// we must change the Fl::pushed() widget, if it is one of
392
// the group's children. Otherwise fl_fix_focus() would send
393
// lots of events to children that are about to be deleted
396
Fl_Widget *pushed = Fl::pushed(); // save pushed() widget
397
if (contains(pushed)) pushed = this; // set it to be the group, if it's a child
398
Fl::pushed(this); // for fl_fix_focus etc.
390
400
// okay, now it is safe to destroy the children:
392
Fl_Widget* o = child(0); // *first* child widget
393
if (o->parent() == this) { // should always be true
394
remove(o); // remove child widget first
395
delete o; // then delete it
396
} else { // this should never happen !
398
printf ("Fl_Group::clear() widget:%p, parent: %p != this (%p)\n",
399
o, o->parent(), this); fflush(stdout);
400
#endif // DEBUG_CLEAR
401
remove(o); // remove it
402
#define REVERSE_CHILDREN
403
#ifdef REVERSE_CHILDREN
404
// Reverse the order of the children. Doing this and deleting
405
// always the last child is much faster than the other way around.
408
Fl_Widget **a = (Fl_Widget**)array();
409
for (int i=0,j=children_-1; i<children_/2; i++,j--) {
415
#endif // REVERSE_CHILDREN
417
while (children_) { // delete all children
418
int idx = children_-1; // last child's index
419
Fl_Widget* w = child(idx); // last child widget
420
if (w->parent()==this) { // should always be true
421
if (children_>2) { // optimized removal
422
w->parent_ = 0; // reset child's parent
423
children_--; // update counter
424
} else { // slow removal
427
delete w; // delete the child
428
} else { // should never happen
429
remove(idx); // remove it anyway
433
if (pushed != this) Fl::pushed(pushed); // reset pushed() widget
463
494
void Fl_Group::add(Fl_Widget &o) {insert(o, children_);}
466
Removes a widget from the group but does not delete it.
497
Removes the widget at \p index from the group but does not delete it.
468
This method does nothing if the widget is not a child of the group.
499
This method does nothing if \p index is out of bounds.
470
501
This method differs from the clear() method in that it only affects
471
502
a single widget and does not delete it from memory.
473
void Fl_Group::remove(Fl_Widget &o) {
474
if (!children_) return;
476
if (i >= children_) return;
506
void Fl_Group::remove(int index) {
507
if (index < 0 || index >= children_) return;
508
Fl_Widget &o = *child(index);
477
509
if (&o == savedfocus_) savedfocus_ = 0;
478
510
if (o.parent_ == this) { // this should always be true
482
else { // this should never happen !
483
printf ("Fl_Group::remove(): widget %p, parent_ (%p) != this (%p)\n",
484
&o, o.parent_, this);
486
#endif // DEBUG_REMOVE
488
514
// remove the widget from the group
491
517
if (children_ == 1) { // go from 2 to 1 child
492
Fl_Widget *t = array_[!i];
518
Fl_Widget *t = array_[!index];
493
519
free((void*)array_);
494
520
array_ = (Fl_Widget**)t;
495
521
} else if (children_ > 1) { // delete from array
496
for (; i < children_; i++) array_[i] = array_[i+1];
522
for (; index < children_; index++) array_[index] = array_[index+1];
528
Removes a widget from the group but does not delete it.
530
This method does nothing if the widget is not a child of the group.
532
This method differs from the clear() method in that it only affects
533
a single widget and does not delete it from memory.
535
\note If you have the child's index anyway, use remove(int index)
536
instead, because this doesn't need a child lookup in the group's
537
table of children. This can be much faster, if there are lots of
540
void Fl_Group::remove(Fl_Widget &o) {
541
if (!children_) return;
543
if (i < children_) remove(i);
501
546
////////////////////////////////////////////////////////////////
503
548
// Rather lame kludge here, I need to detect windows and ignore the
601
646
Fl_Widget::resize(X,Y,W,H); // make new xywh values visible for children
603
if (!resizable() || dw==0 && dh==0 ) {
648
if (!resizable() || (dw==0 && dh==0) ) {
605
650
if (type() < FL_WINDOW) {
606
651
Fl_Widget*const* a = array();
740
785
// skip any labels that are inside the widget:
741
786
if (!(widget.align()&15) || (widget.align() & FL_ALIGN_INSIDE)) return;
742
787
// invent a box that is outside the widget:
743
int a = widget.align();
788
Fl_Align a = widget.align();
744
789
int X = widget.x();
745
790
int Y = widget.y();
746
791
int W = widget.w();
747
792
int H = widget.h();
794
if (const_cast<Fl_Group*>(this)->as_window()) {
748
799
if ( (a & 0x0f) == FL_ALIGN_LEFT_TOP ) {
749
800
a = (a &~0x0f ) | FL_ALIGN_TOP_RIGHT;
751
802
W = widget.x()-X-3;
752
803
} else if ( (a & 0x0f) == FL_ALIGN_LEFT_BOTTOM ) {
753
804
a = (a &~0x0f ) | FL_ALIGN_BOTTOM_RIGHT;
755
806
W = widget.x()-X-3;
756
807
} else if ( (a & 0x0f) == FL_ALIGN_RIGHT_TOP ) {
757
808
a = (a &~0x0f ) | FL_ALIGN_TOP_LEFT;
760
811
} else if ( (a & 0x0f) == FL_ALIGN_RIGHT_BOTTOM ) {
761
812
a = (a &~0x0f ) | FL_ALIGN_BOTTOM_LEFT;
764
815
} else if (a & FL_ALIGN_TOP) {
765
816
a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
767
818
H = widget.y()-Y;
768
819
} else if (a & FL_ALIGN_BOTTOM) {
769
820
a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
772
823
} else if (a & FL_ALIGN_LEFT) {
773
824
a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
775
826
W = widget.x()-X-3;
776
827
} else if (a & FL_ALIGN_RIGHT) {
777
828
a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
781
832
widget.draw_label(X,Y,W,H,(Fl_Align)a);
785
// End of "$Id: Fl_Group.cxx 7469 2010-04-07 23:17:33Z matt $".
836
// End of "$Id: Fl_Group.cxx 8184 2011-01-04 18:28:01Z matt $".