diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2025-12-01 18:36:04 +0100 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2025-12-01 23:06:37 +0100 |
| commit | 5a6a7eb009cde5c0613418a11b0fb637f0cd9468 (patch) | |
| tree | 87c694ec64091c02af916a7b959f16127c8c52e2 | |
| parent | 2e169770396fed12b3b9200b3354322924b36537 (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.H | 2 | ||||
| -rw-r--r-- | src/Fl_Button.cxx | 40 | ||||
| -rw-r--r-- | src/fl_boxtype.cxx | 217 |
3 files changed, 150 insertions, 109 deletions
@@ -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(); |
