summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2025-12-01 18:36:04 +0100
committerAlbrecht Schlosser <albrechts.fltk@online.de>2025-12-01 23:06:37 +0100
commit5a6a7eb009cde5c0613418a11b0fb637f0cd9468 (patch)
tree87c694ec64091c02af916a7b959f16127c8c52e2
parent2e169770396fed12b3b9200b3354322924b36537 (diff)
Add background (`bg`) attribute to table of boxtypes
This is a first step to fix some background (re-)drawing issues in widgets. A new bit in the array of boxtypes can be used to determine if a particular boxtype uses a solid background (e.g. all FL_*_BOX types) or if the parent widget is responsible for drawing it (FL_NO_BOX and all FL_*_FRAME) types, and maybe more ... The old struct member `set` in the struct of boxtypes has been renamed to `flags` and is now used as a bit field. Except these changes, this first commit fixes the focus box drawing of specific boxtypes, as seen in unittest_schemes.cxx in the Fl_Check_Button with label "Check", and very likely more.
-rw-r--r--FL/Fl.H2
-rw-r--r--src/Fl_Button.cxx40
-rw-r--r--src/fl_boxtype.cxx217
3 files changed, 150 insertions, 109 deletions
diff --git a/FL/Fl.H b/FL/Fl.H
index fbaad5df1..85f5c1fd2 100644
--- a/FL/Fl.H
+++ b/FL/Fl.H
@@ -689,6 +689,8 @@ FL_EXPORT extern int box_dy(Fl_Boxtype);
FL_EXPORT extern int box_dw(Fl_Boxtype);
FL_EXPORT extern int box_dh(Fl_Boxtype);
+FL_EXPORT extern bool box_bg(Fl_Boxtype);
+
FL_EXPORT extern int draw_box_active();
FL_EXPORT extern Fl_Color box_color(Fl_Color);
FL_EXPORT extern void set_box_color(Fl_Color);
diff --git a/src/Fl_Button.cxx b/src/Fl_Button.cxx
index e586e5ffa..3df97875b 100644
--- a/src/Fl_Button.cxx
+++ b/src/Fl_Button.cxx
@@ -1,7 +1,7 @@
//
// Button widget for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2014 by Bill Spitzak and others.
+// Copyright 1998-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -150,28 +150,34 @@ int Fl_Button::handle(int event) {
if (when() & FL_WHEN_RELEASE) do_callback(FL_REASON_RELEASED);
return 1;
case FL_SHORTCUT:
- if (!(shortcut() ?
- Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
- if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
+ if (!(shortcut() ? Fl::test_shortcut(shortcut()) : test_shortcut()))
+ return 0;
+ if (Fl::visible_focus() && handle(FL_FOCUS))
+ Fl::focus(this);
goto triggered_by_keyboard;
- case FL_FOCUS :
- case FL_UNFOCUS :
+ case FL_FOCUS:
+ case FL_UNFOCUS:
if (Fl::visible_focus()) {
- if (box() == FL_NO_BOX) {
- // Widgets with the FL_NO_BOX boxtype need a parent to
- // redraw, since it is responsible for redrawing the
- // background...
- int X = x() > 0 ? x() - 1 : 0;
- int Y = y() > 0 ? y() - 1 : 0;
- if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
+ if (!Fl::box_bg(box())) {
+ // Widgets with boxtypes that don't draw the background need a parent
+ // to redraw, since it is responsible for drawing the background...
+ if (window()) {
+ int X = x() > 0 ? x() - 1 : 0;
+ int Y = y() > 0 ? y() - 1 : 0;
+ window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2);
+ }
} else {
- if (box() && (fl_box(box())==box())) redraw();
- else redraw_label();
+ if (box() && (fl_box(box()) == box())) // ? FIXME ?
+ redraw();
+ else
+ redraw_label();
}
return 1;
- } else return 0;
+ } else {
+ return 0;
+ }
/* NOTREACHED */
- case FL_KEYBOARD :
+ case FL_KEYBOARD:
if (Fl::focus() == this && Fl::event_key() == ' ' &&
!(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
triggered_by_keyboard: // from FL_SHORTCUT
diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx
index 1569e58bd..cdd396eaf 100644
--- a/src/fl_boxtype.cxx
+++ b/src/fl_boxtype.cxx
@@ -1,7 +1,7 @@
//
// Box drawing code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2022 by Bill Spitzak and others.
+// Copyright 1998-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -324,91 +324,107 @@ void fl_border_frame(int x, int y, int w, int h, Fl_Color c) {
fl_rect(x, y, w, h);
}
-////////////////////////////////////////////////////////////////
+// /////////////////////////////////////////////////////////////////////
+// Up to FLTK 1.4 the 6th element of the following struct was named 'set'
+// and could only be 0 or 1: whether the boxtype was "set" or not.
+// Since FLTK 1.5 the 6th element of the struct is named 'flags' and
+// is used as a set of bit flags:
+// - bit 0 (1): 1 = set, 0 = not (yet) set (fully initialized)
+// - bit 1 (2): 0 = boxtype has a solid background, 1 = no (frame type)
+// - bit 3 ++ : undefined, must be 0, reserved for future extensions.
+// The bit values were chosen so the default is suitable for backwards
+// compatibility, i.e. if users defining their own schemes don't set the
+// corresponding bits.
+// To do: define an enum for bit values ?
+// To do: check if "diamond" and "oval" boxes need bit 1 == 1 like frames.
+// See also Fl::box_bg() which returns true if bit 1 == zero.
+// /////////////////////////////////////////////////////////////////////
static struct {
Fl_Box_Draw_F *f;
uchar dx, dy, dw, dh;
- int set;
+ int flags;
Fl_Box_Draw_Focus_F *ff;
+ bool set() { return flags & 1; }
+ bool bg() { return !(flags & 2); }
} fl_box_table[FL_MAX_BOXTYPE+1] = {
- // must match list in Enumerations.H!!!
- {fl_no_box, 0,0,0,0,1},
- {fl_flat_box, 0,0,0,0,1}, // FL_FLAT_BOX
- {fl_up_box, D1,D1,D2,D2,1},
- {fl_down_box, D1,D1,D2,D2,1},
- {fl_up_frame, D1,D1,D2,D2,1},
- {fl_down_frame, D1,D1,D2,D2,1},
- {fl_thin_up_box, 1,1,2,2,1},
- {fl_thin_down_box, 1,1,2,2,1},
- {fl_thin_up_frame, 1,1,2,2,1},
- {fl_thin_down_frame, 1,1,2,2,1},
- {fl_engraved_box, 2,2,4,4,1},
- {fl_embossed_box, 2,2,4,4,1},
- {fl_engraved_frame, 2,2,4,4,1},
- {fl_embossed_frame, 2,2,4,4,1},
- {fl_border_box, 1,1,2,2,1},
- {fl_border_box, 1,1,5,5,0}, // _FL_SHADOW_BOX
- {fl_border_frame, 1,1,2,2,1},
- {fl_border_frame, 1,1,5,5,0}, // _FL_SHADOW_FRAME
- {fl_border_box, 1,1,2,2,0}, // _FL_ROUNDED_BOX
- {fl_border_box, 1,1,2,2,0}, // _FL_RSHADOW_BOX
- {fl_border_frame, 1,1,2,2,0}, // _FL_ROUNDED_FRAME
- {fl_flat_box, 0,0,0,0,0}, // _FL_RFLAT_BOX
- {fl_up_box, 3,3,6,6,0}, // _FL_ROUND_UP_BOX
- {fl_down_box, 3,3,6,6,0}, // _FL_ROUND_DOWN_BOX
- {fl_up_box, 0,0,0,0,0}, // _FL_DIAMOND_UP_BOX
- {fl_down_box, 0,0,0,0,0}, // _FL_DIAMOND_DOWN_BOX
- {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_BOX
- {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_SHADOW_BOX
- {fl_border_frame, 1,1,2,2,0}, // _FL_OVAL_FRAME
- {fl_flat_box, 0,0,0,0,0}, // _FL_OVAL_FLAT_BOX
- {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_DOWN_BOX
- {fl_up_frame, 2,2,4,4,0}, // _FL_PLASTIC_UP_FRAME
- {fl_down_frame, 2,2,4,4,0}, // _FL_PLASTIC_DOWN_FRAME
- {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_DOWN_BOX
- {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_DOWN_BOX
- {fl_up_box, 2,2,4,4,0}, // _FL_GTK_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_GTK_DOWN_BOX
- {fl_up_frame, 2,2,4,4,0}, // _FL_GTK_UP_FRAME
- {fl_down_frame, 2,2,4,4,0}, // _FL_GTK_DOWN_FRAME
- {fl_up_frame, 1,1,2,2,0}, // _FL_GTK_THIN_UP_FRAME
- {fl_down_frame, 1,1,2,2,0}, // _FL_GTK_THIN_DOWN_FRAME
- {fl_up_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_UP_BOX
- {fl_down_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_DOWN_BOX
- {fl_up_box, 2,2,4,4,0}, // _FL_GTK_ROUND_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_GTK_ROUND_DOWN_BOX
- {fl_up_box, 2,2,4,4,0}, // _FL_GLEAM_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_DOWN_BOX
- {fl_up_frame, 2,2,4,4,0}, // _FL_GLEAM_UP_FRAME
- {fl_down_frame, 2,2,4,4,0}, // _FL_GLEAM_DOWN_FRAME
- {fl_up_box, 2,2,4,4,0}, // _FL_GLEAM_THIN_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_THIN_DOWN_BOX
- {fl_up_box, 2,2,4,4,0}, // _FL_GLEAM_ROUND_UP_BOX
- {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_ROUND_DOWN_BOX
- {fl_up_box, 2,2,4,4,0}, // _FL_OXY_UP_BOX,
- {fl_down_box, 2,2,4,4,0}, // _FL_OXY_DOWN_BOX,
- {fl_up_frame, 2,2,4,4,0}, // _FL_OXY_UP_FRAME,
- {fl_down_frame, 2,2,4,4,0}, // _FL_OXY_DOWN_FRAME,
- {fl_thin_up_box, 1,1,2,2,0}, // _FL_OXY_THIN_UP_BOX,
- {fl_thin_down_box, 1,1,2,2,0}, // _FL_OXY_THIN_DOWN_BOX,
- {fl_thin_up_frame, 1,1,2,2,0}, // _FL_OXY_THIN_UP_FRAME,
- {fl_thin_down_frame, 1,1,2,2,0}, // _FL_OXY_THIN_DOWN_FRAME,
- {fl_up_box, 2,2,4,4,0}, // _FL_OXY_ROUND_UP_BOX,
- {fl_down_box, 2,2,4,4,0}, // _FL_OXY_ROUND_DOWN_BOX,
- {fl_up_box, 2,2,4,4,0}, // _FL_OXY_BUTTON_UP_BOX,
- {fl_down_box, 2,2,4,4,0}, // _FL_OXY_BUTTON_DOWN_BOX,
- {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+0
- {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+1
- {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+2
- {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+3
- {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+4
- {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+5
- {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+6
- {fl_down_box, 3,3,6,6,0} // FL_FREE_BOX+7
+ // must match list in Enumerations.H !!!
+ {fl_no_box, 0,0,0,0,3}, // FL_NO_BOX
+ {fl_flat_box, 0,0,0,0,1}, // FL_FLAT_BOX
+ {fl_up_box, D1,D1,D2,D2,1}, // FL_UP_BOX
+ {fl_down_box, D1,D1,D2,D2,1}, // FL_DOWN_BOX
+ {fl_up_frame, D1,D1,D2,D2,3}, // FL_UP_FRAME
+ {fl_down_frame, D1,D1,D2,D2,3}, // FL_DOWN_FRAME
+ {fl_thin_up_box, 1,1,2,2,1}, // FL_THIN_UP_BOX
+ {fl_thin_down_box, 1,1,2,2,1}, // FL_THIN_DOWN_BOX,
+ {fl_thin_up_frame, 1,1,2,2,3}, // FL_THIN_UP_FRAME,
+ {fl_thin_down_frame, 1,1,2,2,3}, // FL_THIN_DOWN_FRAME,
+ {fl_engraved_box, 2,2,4,4,1}, // FL_ENGRAVED_BOX,
+ {fl_embossed_box, 2,2,4,4,1}, // FL_EMBOSSED_BOX,
+ {fl_engraved_frame, 2,2,4,4,3}, // FL_ENGRAVED_FRAME
+ {fl_embossed_frame, 2,2,4,4,3}, // FL_EMBOSSED_FRAME
+ {fl_border_box, 1,1,2,2,1}, // FL_BORDER_BOX
+ {fl_border_box, 1,1,5,5,0}, // _FL_SHADOW_BOX
+ {fl_border_frame, 1,1,2,2,3}, // FL_BORDER_FRAME,
+ {fl_border_frame, 1,1,5,5,2}, // _FL_SHADOW_FRAME
+ {fl_border_box, 1,1,2,2,0}, // _FL_ROUNDED_BOX
+ {fl_border_box, 1,1,2,2,0}, // _FL_RSHADOW_BOX
+ {fl_border_frame, 1,1,2,2,2}, // _FL_ROUNDED_FRAME
+ {fl_flat_box, 0,0,0,0,0}, // _FL_RFLAT_BOX
+ {fl_up_box, 3,3,6,6,0}, // _FL_ROUND_UP_BOX
+ {fl_down_box, 3,3,6,6,0}, // _FL_ROUND_DOWN_BOX
+ {fl_up_box, 0,0,0,0,0}, // _FL_DIAMOND_UP_BOX
+ {fl_down_box, 0,0,0,0,0}, // _FL_DIAMOND_DOWN_BOX
+ {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_BOX
+ {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_SHADOW_BOX
+ {fl_border_frame, 1,1,2,2,2}, // _FL_OVAL_FRAME
+ {fl_flat_box, 0,0,0,0,0}, // _FL_OVAL_FLAT_BOX
+ {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_DOWN_BOX
+ {fl_up_frame, 2,2,4,4,2}, // _FL_PLASTIC_UP_FRAME
+ {fl_down_frame, 2,2,4,4,2}, // _FL_PLASTIC_DOWN_FRAME
+ {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_DOWN_BOX
+ {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_DOWN_BOX
+ {fl_up_box, 2,2,4,4,0}, // _FL_GTK_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_GTK_DOWN_BOX
+ {fl_up_frame, 2,2,4,4,2}, // _FL_GTK_UP_FRAME
+ {fl_down_frame, 2,2,4,4,2}, // _FL_GTK_DOWN_FRAME
+ {fl_up_frame, 1,1,2,2,2}, // _FL_GTK_THIN_UP_FRAME
+ {fl_down_frame, 1,1,2,2,2}, // _FL_GTK_THIN_DOWN_FRAME
+ {fl_up_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_UP_BOX
+ {fl_down_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_DOWN_BOX
+ {fl_up_box, 2,2,4,4,0}, // _FL_GTK_ROUND_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_GTK_ROUND_DOWN_BOX
+ {fl_up_box, 2,2,4,4,0}, // _FL_GLEAM_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_DOWN_BOX
+ {fl_up_frame, 2,2,4,4,2}, // _FL_GLEAM_UP_FRAME
+ {fl_down_frame, 2,2,4,4,2}, // _FL_GLEAM_DOWN_FRAME
+ {fl_up_box, 2,2,4,4,0}, // _FL_GLEAM_THIN_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_THIN_DOWN_BOX
+ {fl_up_box, 2,2,4,4,0}, // _FL_GLEAM_ROUND_UP_BOX
+ {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_ROUND_DOWN_BOX
+ {fl_up_box, 2,2,4,4,0}, // _FL_OXY_UP_BOX,
+ {fl_down_box, 2,2,4,4,0}, // _FL_OXY_DOWN_BOX,
+ {fl_up_frame, 2,2,4,4,2}, // _FL_OXY_UP_FRAME,
+ {fl_down_frame, 2,2,4,4,2}, // _FL_OXY_DOWN_FRAME,
+ {fl_thin_up_box, 1,1,2,2,0}, // _FL_OXY_THIN_UP_BOX,
+ {fl_thin_down_box, 1,1,2,2,0}, // _FL_OXY_THIN_DOWN_BOX,
+ {fl_thin_up_frame, 1,1,2,2,2}, // _FL_OXY_THIN_UP_FRAME,
+ {fl_thin_down_frame, 1,1,2,2,2}, // _FL_OXY_THIN_DOWN_FRAME,
+ {fl_up_box, 2,2,4,4,0}, // _FL_OXY_ROUND_UP_BOX,
+ {fl_down_box, 2,2,4,4,0}, // _FL_OXY_ROUND_DOWN_BOX,
+ {fl_up_box, 2,2,4,4,0}, // _FL_OXY_BUTTON_UP_BOX,
+ {fl_down_box, 2,2,4,4,0}, // _FL_OXY_BUTTON_DOWN_BOX,
+ {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+0
+ {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+1
+ {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+2
+ {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+3
+ {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+4
+ {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+5
+ {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+6
+ {fl_down_box, 3,3,6,6,0} // FL_FREE_BOX+7
};
/**
@@ -455,16 +471,33 @@ int Fl::box_dw(Fl_Boxtype t) {return fl_box_table[t].dw;}
int Fl::box_dh(Fl_Boxtype t) {return fl_box_table[t].dh;}
/**
+ Returns whether the given boxtype draws its background.
+
+ FL_NO_BOX and all FL_*_FRAME boxtypes need their parent to draw the
+ background rather than just calling redraw. This is used internally
+ for some widgets to ensure that the background is fully drawn when,
+ for instance, only the focus box is changed.
+
+ \param[in] bt Boxtype
+ \return true if the box draws a solid background,\n
+ false if it is at least partially transparent.
+ \since 1.5.0
+*/
+extern bool Fl::box_bg(Fl_Boxtype bt) {
+ return fl_box_table[bt].bg();
+}
+
+/**
Sets the drawing function for a given box type.
\param[in] t box type
\param[in] f box drawing function
\param[in] ff optional box focus rectangle drawing function
*/
void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f, Fl_Box_Draw_Focus_F* ff) {
- if (!fl_box_table[t].set) {
- fl_box_table[t].f = f;
- fl_box_table[t].ff = ff;
- fl_box_table[t].set = 1;
+ if (!fl_box_table[t].set()) {
+ fl_box_table[t].f = f;
+ fl_box_table[t].ff = ff;
+ fl_box_table[t].flags |= 1;
}
}
@@ -487,13 +520,13 @@ Fl_Box_Draw_F *Fl::get_boxtype(Fl_Boxtype t) {
void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f,
uchar dx, uchar dy, uchar dw, uchar dh,
Fl_Box_Draw_Focus_F* ff) {
- fl_box_table[t].f = f;
- fl_box_table[t].set = 1;
- fl_box_table[t].dx = dx;
- fl_box_table[t].dy = dy;
- fl_box_table[t].dw = dw;
- fl_box_table[t].dh = dh;
- fl_box_table[t].ff = ff;
+ fl_box_table[t].f = f;
+ fl_box_table[t].flags |= 1;
+ fl_box_table[t].dx = dx;
+ fl_box_table[t].dy = dy;
+ fl_box_table[t].dw = dw;
+ fl_box_table[t].dh = dh;
+ fl_box_table[t].ff = ff;
}
/** Copies the from boxtype. */
@@ -546,7 +579,7 @@ void fl_draw_box_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, F
fl_color(savecolor);
}
-/** Draws the widget box according its box style */
+/** Draws the widget box according to its box style */
void Fl_Widget::draw_box() const {
if (box_) draw_box((Fl_Boxtype)box_, x_, y_, w_, h_, color_);
draw_backdrop();