Fix Fl_Pack to support more box types.

Old code supported only frame styles, this code
can now handle box types with a background.
This commit is contained in:
Matthias Melcher
2025-12-29 16:21:17 +01:00
parent 2fb67053a1
commit 83fab8cb0f
3 changed files with 41 additions and 10 deletions

View File

@@ -21,6 +21,7 @@
#define Fl_Pack_H
#include <FL/Fl_Group.H>
#include <FL/Fl_Rect.H>
/**
This widget was designed to add the functionality of compressing and
@@ -39,6 +40,12 @@
resizable() widget is the last widget in the group it is extended to take
the full available width or height, respectively, of the Fl_Pack group.
\note Fl_Pack is optimized to use a frame-only (`..._FRAME`) box type.
Box types with background graphics (`..._BOX`) generally work, but can be
slower witch a large number of children. Not all box types work well
with FL_Pack. Avoid irregular graphics like FL_DIAMOND_BOX and background
images.
\note You can nest Fl_Pack widgets or put them inside Fl_Scroll widgets
or inside other group widgets but their behavior can sometimes be
<i>"surprising"</i>. This is partly due to the fact that Fl_Pack widgets
@@ -61,6 +68,7 @@ public:
};
protected:
void draw_filler_(const Fl_Rect& rect);
void draw() override;
public:

View File

@@ -49,6 +49,22 @@ Fl_Pack::Fl_Pack(int X, int Y, int W, int H, const char *L)
// type(VERTICAL); // already set like this
}
/** Draw a rectangular area as a background filler.
If the box type has a background (is not a frame), this will clip to the
rectangular area and draw the box. Otherwise, it will draw a rectangle
in widget color.
\param[in] rect fill this rectangle inside the widget bounds
*/
void Fl_Pack::draw_filler_(const Fl_Rect& rect) {
if (Fl::box_bg(box())) {
fl_push_clip(rect.x(), rect.y(), rect.w(), rect.h());
draw_box();
fl_pop_clip();
} else {
fl_rectf(rect.x(), rect.y(), rect.w(), rect.h(), color());
}
}
void Fl_Pack::draw() {
int tx = x()+Fl::box_dx(box());
int ty = y()+Fl::box_dy(box());
@@ -102,11 +118,10 @@ void Fl_Pack::draw() {
}
if (spacing_ && current_position>maximum_position && box() &&
(X != o->x() || Y != o->y() || d&FL_DAMAGE_ALL)) {
fl_color(color());
if (horizontal())
fl_rectf(maximum_position, ty, spacing_, th);
draw_filler_( { maximum_position, ty, spacing_, th } );
else
fl_rectf(tx, maximum_position, tw, spacing_);
draw_filler_( { tx, maximum_position, tw, spacing_ } );
}
if (X != o->x() || Y != o->y() || W != o->w() || H != o->h()) {
o->resize(X,Y,W,H);
@@ -132,14 +147,12 @@ void Fl_Pack::draw() {
if (horizontal()) {
if (maximum_position < tx+tw && box()) {
fl_color(color());
fl_rectf(maximum_position, ty, tx+tw-maximum_position, th);
draw_filler_( { maximum_position, ty, tx+tw-maximum_position, th } );
}
tw = maximum_position-tx;
} else {
if (maximum_position < ty+th && box()) {
fl_color(color());
fl_rectf(tx, maximum_position, tw, ty+th-maximum_position);
draw_filler_( { tx, maximum_position, tw, ty+th-maximum_position } );
}
th = maximum_position-ty;
}
@@ -153,7 +166,13 @@ void Fl_Pack::draw() {
d = FL_DAMAGE_ALL;
}
if (d&FL_DAMAGE_ALL) {
if (Fl::box_bg(box())) {
// Make sure that we only draw the frame part, because the children
// and fillers are already rendered at this point.
draw_box(fl_frame(box()), x(), y(), w(), h(), color());
} else {
draw_box();
}
draw_label();
}
}

View File

@@ -186,9 +186,11 @@ Fl_Input::paste_menu_text = gettext("Paste");} {}
MenuItem {} {
label sandals
callback {[](Fl_Widget*, void*)
/* If this code generates an error, you are using an older version of Fluid */
/* Support for lambda callbacks was added dec 12 2025 */
{
puts("The shoe is the sign!");
}} selected
}}
xywh {0 0 100 20}
}
MenuItem {} {
@@ -223,6 +225,8 @@ Fl_Input::paste_menu_text = gettext("Paste");} {}
Fl_Check_Button wShave {
label shave
callback {[](Fl_Widget* w, void*)->void {
/* If this code generates an error, you are using an older version of Fluid */
/* Support for lambda callbacks was added dec 12 2025 */
auto* btn = static_cast<Fl_Check_Button*>(w);
if (btn->value()) {
puts("Shave.");
@@ -230,7 +234,7 @@ Fl_Input::paste_menu_text = gettext("Paste");} {}
puts("Don't shave.");
}
}}
comment {// Testing lambdas for callbacks}
comment {// Testing lambdas for callbacks} selected
xywh {25 212 105 24} down_box DOWN_BOX
}
Fl_Check_Button wBrush {