From 281ec24c8f4b7daf7cc4e7c30b640cbe0b33d037 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Fri, 26 Apr 2024 12:42:11 +0200 Subject: [PATCH] Box types can now defined and draw their own focus frame, STR 2145, #659 --- FL/Enumerations.H | 3 +- FL/Fl.H | 7 +++- FL/fl_draw.H | 1 + src/Fl_Tree_Item.cxx | 23 +---------- src/Fl_Widget.cxx | 20 +-------- src/Fl_get_system_colors.cxx | 5 ++- src/fl_boxtype.cxx | 78 ++++++++++++++++++++++++++++++------ src/fl_diamond_box.cxx | 22 ++++++++-- src/fl_gleam.cxx | 2 +- src/fl_gtk.cxx | 8 ++-- src/fl_oval_box.cxx | 23 ++++++++--- src/fl_oxy.cxx | 7 ++-- src/fl_plastic.cxx | 8 ++-- src/fl_round_box.cxx | 17 ++++++-- src/fl_rounded_box.cxx | 23 ++++++++--- src/fl_shadow_box.cxx | 2 +- 16 files changed, 163 insertions(+), 86 deletions(-) diff --git a/FL/Enumerations.H b/FL/Enumerations.H index 6da998576..3d5bc7f89 100644 --- a/FL/Enumerations.H +++ b/FL/Enumerations.H @@ -694,7 +694,8 @@ enum Fl_Boxtype { // boxtypes (if you change these you must also change fl_boxty _FL_OXY_ROUND_DOWN_BOX, ///< oxy version of FL_ROUND_DOWN_BOX, use FL_OXY_ROUND_DOWN_BOX _FL_OXY_BUTTON_UP_BOX, ///< FL_OXY_BUTTON_UP_BOX (new boxtype ?), use FL_OXY_BUTTON_UP_BOX _FL_OXY_BUTTON_DOWN_BOX, ///< FL_OXY_BUTTON_DOWN_BOX (new boxtype ?), use FL_OXY_BUTTON_DOWN_BOX - FL_FREE_BOXTYPE ///< the first free box type for creation of new box types + FL_FREE_BOXTYPE, ///< the first free box type for creation of new box types + FL_MAX_BOXTYPE = 255 ///< highest legal index for a box type }; #ifndef FL_DOXYGEN diff --git a/FL/Fl.H b/FL/Fl.H index e35ebe2ad..fef27fa93 100644 --- a/FL/Fl.H +++ b/FL/Fl.H @@ -88,6 +88,9 @@ typedef void (Fl_Label_Measure_F)(const Fl_Label *label, int &width, int &height /** Signature of some box drawing functions passed as parameters */ typedef void (Fl_Box_Draw_F)(int x, int y, int w, int h, Fl_Color color); +/** Signature of box focus frame drawing functions */ +typedef void (Fl_Box_Draw_Focus_F)(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg); + /** Signature of timeout callback functions passed as parameters. Please see Fl::add_timeout() for details. */ @@ -1215,7 +1218,9 @@ public: // boxtypes: static Fl_Box_Draw_F *get_boxtype(Fl_Boxtype); - static void set_boxtype(Fl_Boxtype, Fl_Box_Draw_F*,uchar,uchar,uchar,uchar); + static void set_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, + uchar, uchar, uchar, uchar, + Fl_Box_Draw_Focus_F* =NULL); static void set_boxtype(Fl_Boxtype, Fl_Boxtype from); static int box_dx(Fl_Boxtype); static int box_dy(Fl_Boxtype); diff --git a/FL/fl_draw.H b/FL/fl_draw.H index 7cf3f6838..14137c5d7 100644 --- a/FL/fl_draw.H +++ b/FL/fl_draw.H @@ -976,6 +976,7 @@ FL_EXPORT void fl_draw(const char *str, int x, int y, int w, int h, Fl_Align ali FL_EXPORT void fl_frame(const char *s, int x, int y, int w, int h); FL_EXPORT void fl_frame2(const char *s, int x, int y, int w, int h); FL_EXPORT void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color); +FL_EXPORT void fl_draw_box_focus(Fl_Boxtype, int x, int y, int w, int h, Fl_Color, Fl_Color); // basic GUI objects (check marks, arrows, more to come ...): diff --git a/src/Fl_Tree_Item.cxx b/src/Fl_Tree_Item.cxx index c7b9d81e6..544170a32 100644 --- a/src/Fl_Tree_Item.cxx +++ b/src/Fl_Tree_Item.cxx @@ -800,27 +800,6 @@ Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs, int yonly) static_cast(*this).find_clicked(prefs, yonly))); } -static void draw_item_focus(Fl_Boxtype B, Fl_Color fg, Fl_Color bg, int X, int Y, int W, int H) { - // Pasted from Fl_Widget::draw_focus(); we don't have access to this method - if (!Fl::visible_focus()) return; - switch (B) { - case FL_DOWN_BOX: - case FL_DOWN_FRAME: - case FL_THIN_DOWN_BOX: - case FL_THIN_DOWN_FRAME: - X ++; - Y ++; - default: - break; - } - X += Fl::box_dx(B); - Y += Fl::box_dy(B); - W -= Fl::box_dw(B)+1; - H -= Fl::box_dh(B)+1; - fl_color(fl_contrast(fg, bg)); - fl_focus_rect(X, Y, W, H); -} - /// Return the item's 'visible' height. Takes into account the item's: /// - visibility (if !is_visible(), returns 0) /// - labelfont() height: if label() != NULL @@ -1137,7 +1116,7 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Tree_Item *itemfocus, Fl::visible_focus() && Fl::focus() == tree() && prefs.selectmode() != FL_TREE_SELECT_NONE ) { - draw_item_focus(FL_NO_BOX,fg,bg,label_x()+1,label_y()+1,label_w()-1,label_h()-1); + fl_draw_box_focus(FL_NO_BOX, label_x()+1, label_y()+1, label_w()-1, label_h()-1, fg, bg); } } // end drawthis } // end clipped diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx index c5b59f5db..bf2ff03d0 100644 --- a/src/Fl_Widget.cxx +++ b/src/Fl_Widget.cxx @@ -213,25 +213,7 @@ Fl_Widget::~Fl_Widget() { void Fl_Widget::draw_focus(Fl_Boxtype bt, int X, int Y, int W, int H, Fl_Color bg) const { if (!Fl::visible_focus()) return; if (!visible_focus()) return; - switch (bt) { - case FL_DOWN_BOX: - case FL_DOWN_FRAME: - case FL_THIN_DOWN_BOX: - case FL_THIN_DOWN_FRAME: - X ++; - Y ++; - default: - break; - } - X += Fl::box_dx(bt); - Y += Fl::box_dy(bt); - W -= Fl::box_dw(bt)+1; - H -= Fl::box_dh(bt)+1; - - Fl_Color savecolor = fl_color(); - fl_color(fl_contrast(FL_BLACK, bg)); - fl_focus_rect(X, Y, W, H); - fl_color(savecolor); + fl_draw_box_focus(bt, X, Y, W, H, FL_BLACK, bg); } void Fl_Widget::activate() { diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx index ecc08a5e0..24bf8e441 100644 --- a/src/Fl_get_system_colors.cxx +++ b/src/Fl_get_system_colors.cxx @@ -144,6 +144,7 @@ extern void fl_thin_up_box(int, int, int, int, Fl_Color); extern void fl_thin_down_box(int, int, int, int, Fl_Color); extern void fl_round_up_box(int, int, int, int, Fl_Color); extern void fl_round_down_box(int, int, int, int, Fl_Color); +extern void fl_round_focus(Fl_Boxtype, int, int, int, int, Fl_Color, Fl_Color); extern void fl_up_frame(int, int, int, int, Fl_Color); extern void fl_down_frame(int, int, int, int, Fl_Color); @@ -359,8 +360,8 @@ int Fl::reload_scheme() { set_boxtype(FL_DOWN_BOX, fl_down_box, D1, D1, D2, D2); set_boxtype(FL_THIN_UP_BOX, fl_thin_up_box, 1, 1, 2, 2); set_boxtype(FL_THIN_DOWN_BOX, fl_thin_down_box, 1, 1, 2, 2); - set_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box, 3, 3, 6, 6); - set_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box, 3, 3, 6, 6); + set_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box, 3, 3, 6, 6, fl_round_focus); + set_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box, 3, 3, 6, 6, fl_round_focus); // Use standard size scrollbars... Fl::scrollbar_size(16); diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx index 708635fbb..ea8571b93 100644 --- a/src/fl_boxtype.cxx +++ b/src/fl_boxtype.cxx @@ -288,8 +288,9 @@ static struct { Fl_Box_Draw_F *f; uchar dx, dy, dw, dh; int set; -} fl_box_table[256] = { -// must match list in Enumerations.H!!! + Fl_Box_Draw_Focus_F *ff; +} 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}, @@ -412,13 +413,15 @@ 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;} /** - Sets the drawing function for a given box type. - \param[in] t box type - \param[in] f box drawing function -*/ -void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) { + 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; } } @@ -427,16 +430,30 @@ void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) { Fl_Box_Draw_F *Fl::get_boxtype(Fl_Boxtype t) { return fl_box_table[t].f; } -/** Sets the function to call to draw a specific boxtype. */ + +/** + Sets the function to call to draw a specific box type. + + \param[in] t index of the box type between 0 (FL_NO_BOX) and up to and + including FL_MAX_BOXTYPE + \param[in] f callback function that draws the box + \param[in] dx, dy top left frame width, distance in pixels to box contents + \param[in] dw, dh left plus right frame width, top plus bottom frame width + \param[in] ff optional callback that draws the box focus, defaults + to a rectangle, inset by dx, dy, dw, dh + */ void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f, - uchar a, uchar b, uchar c, uchar d) { + 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 = a; - fl_box_table[t].dy = b; - fl_box_table[t].dw = c; - fl_box_table[t].dh = d; + 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. */ void Fl::set_boxtype(Fl_Boxtype to, Fl_Boxtype from) { fl_box_table[to] = fl_box_table[from]; @@ -452,6 +469,41 @@ void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) { if (t && fl_box_table[t].f) fl_box_table[t].f(x,y,w,h,c); } +/** + Draws the focus rectangle inside a box using given type, position, size and color. + Boxes can set their own focus drawing callback. The focus frame does not + need to be a rectangle at all, but should fit inside the shape of the box. + \param[in] bt box type + \param[in] x, y, w, h position and size + \param[in] fg, bg foreground and background color + */ +void fl_draw_box_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg) { + if (!Fl::visible_focus()) return; + if ((bt >= 0) && (bt <= FL_MAX_BOXTYPE) && (fl_box_table[bt].ff)) { + fl_box_table[bt].ff(bt, x, y, w, h, fg, bg); + return; + } + switch (bt) { + case FL_DOWN_BOX: + case FL_DOWN_FRAME: + case FL_THIN_DOWN_BOX: + case FL_THIN_DOWN_FRAME: + x++; + y++; + default: + break; + } + x += Fl::box_dx(bt); + y += Fl::box_dy(bt); + w -= Fl::box_dw(bt)+1; + h -= Fl::box_dh(bt)+1; + + Fl_Color savecolor = fl_color(); + fl_color(fl_contrast(fg, bg)); + fl_focus_rect(x, y, w, h); + fl_color(savecolor); +} + /** Draws the widget box according its box style */ void Fl_Widget::draw_box() const { if (box_) draw_box((Fl_Boxtype)box_, x_, y_, w_, h_, color_); diff --git a/src/fl_diamond_box.cxx b/src/fl_diamond_box.cxx index e5f7749ec..414e5dea3 100644 --- a/src/fl_diamond_box.cxx +++ b/src/fl_diamond_box.cxx @@ -59,9 +59,25 @@ static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) { fl_color(g[(int)'A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3); } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +void fl_diamond_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg) { + w &= -2; + h &= -2; + x += Fl::box_dx(bt)+4; + y += Fl::box_dy(bt)+4; + w -= Fl::box_dw(bt)+8; + h -= Fl::box_dh(bt)+8; + int x1 = x+w/2; + int y1 = y+h/2; + Fl_Color savecolor = fl_color(); + fl_color(fl_contrast(fg, bg)); + fl_line_style(FL_DOT); + fl_loop(x,y1, x1,y, x+w,y1, x1,y+h); + fl_line_style(FL_SOLID); + fl_color(savecolor); +} +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_DIAMOND_BOX() { - fl_internal_boxtype(_FL_DIAMOND_DOWN_BOX, fl_diamond_down_box); - fl_internal_boxtype(_FL_DIAMOND_UP_BOX,fl_diamond_up_box); + fl_internal_boxtype(_FL_DIAMOND_DOWN_BOX, fl_diamond_down_box, fl_diamond_focus); + fl_internal_boxtype(_FL_DIAMOND_UP_BOX, fl_diamond_up_box, fl_diamond_focus); return _FL_DIAMOND_UP_BOX; } diff --git a/src/fl_gleam.cxx b/src/fl_gleam.cxx index c75472dc5..d7f80adc6 100644 --- a/src/fl_gleam.cxx +++ b/src/fl_gleam.cxx @@ -164,7 +164,7 @@ static void thin_down_box(int x, int y, int w, int h, Fl_Color c) { frame_rect_down(x, y, w, h, c, fl_color_average(c, FL_BLACK, .45f), .35f, 0.85f); } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_GLEAM_UP_BOX() { fl_internal_boxtype(_FL_GLEAM_UP_BOX, up_box); diff --git a/src/fl_gtk.cxx b/src/fl_gtk.cxx index 5319f6e90..495ca189e 100644 --- a/src/fl_gtk.cxx +++ b/src/fl_gtk.cxx @@ -24,7 +24,7 @@ #include #include -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); static void gtk_color(Fl_Color c) { @@ -283,6 +283,8 @@ static void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) { #endif +extern void fl_rounded_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg); + Fl_Boxtype fl_define_FL_GTK_UP_BOX() { fl_internal_boxtype(_FL_GTK_UP_BOX, gtk_up_box); fl_internal_boxtype(_FL_GTK_DOWN_BOX, gtk_down_box); @@ -292,8 +294,8 @@ Fl_Boxtype fl_define_FL_GTK_UP_BOX() { fl_internal_boxtype(_FL_GTK_THIN_DOWN_BOX, gtk_thin_down_box); fl_internal_boxtype(_FL_GTK_THIN_UP_FRAME, gtk_thin_up_frame); fl_internal_boxtype(_FL_GTK_THIN_DOWN_FRAME, gtk_thin_down_frame); - fl_internal_boxtype(_FL_GTK_ROUND_UP_BOX, gtk_round_up_box); - fl_internal_boxtype(_FL_GTK_ROUND_DOWN_BOX, gtk_round_down_box); + fl_internal_boxtype(_FL_GTK_ROUND_UP_BOX, gtk_round_up_box, fl_rounded_focus); + fl_internal_boxtype(_FL_GTK_ROUND_DOWN_BOX, gtk_round_down_box, fl_rounded_focus); return _FL_GTK_UP_BOX; } diff --git a/src/fl_oval_box.cxx b/src/fl_oval_box.cxx index 9a0e1968a..3d8d27fd3 100644 --- a/src/fl_oval_box.cxx +++ b/src/fl_oval_box.cxx @@ -45,11 +45,24 @@ static void fl_oval_shadow_box(int x, int y, int w, int h, Fl_Color c) { fl_oval_box(x,y,w,h,c); } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +void fl_oval_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg) { + x += Fl::box_dx(bt)+1; + y += Fl::box_dy(bt)+1; + w -= Fl::box_dw(bt)+2; + h -= Fl::box_dh(bt)+2; + Fl_Color savecolor = fl_color(); + fl_color(fl_contrast(fg, bg)); + fl_line_style(FL_DOT); + fl_arc(x, y, w, h, 0, 360); + fl_line_style(FL_SOLID); + fl_color(savecolor); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_OVAL_BOX() { - fl_internal_boxtype(_FL_OSHADOW_BOX,fl_oval_shadow_box); - fl_internal_boxtype(_FL_OVAL_FRAME,fl_oval_frame); - fl_internal_boxtype(_FL_OFLAT_BOX,fl_oval_flat_box); - fl_internal_boxtype(_FL_OVAL_BOX,fl_oval_box); + fl_internal_boxtype(_FL_OSHADOW_BOX, fl_oval_shadow_box, fl_oval_focus); + fl_internal_boxtype(_FL_OVAL_FRAME, fl_oval_frame, fl_oval_focus); + fl_internal_boxtype(_FL_OFLAT_BOX, fl_oval_flat_box, fl_oval_focus); + fl_internal_boxtype(_FL_OVAL_BOX, fl_oval_box, fl_oval_focus); return _FL_OVAL_BOX; } diff --git a/src/fl_oxy.cxx b/src/fl_oxy.cxx index 59909fdf9..763f5012f 100644 --- a/src/fl_oxy.cxx +++ b/src/fl_oxy.cxx @@ -504,7 +504,8 @@ void round_down_box(int x, int y, int w, int h, Fl_Color col) { } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F *); +extern void fl_rounded_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg); +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_OXY_UP_BOX() { @@ -516,8 +517,8 @@ Fl_Boxtype fl_define_FL_OXY_UP_BOX() { fl_internal_boxtype(_FL_OXY_THIN_DOWN_BOX, thin_down_box); fl_internal_boxtype(_FL_OXY_THIN_UP_FRAME, thin_up_frame); fl_internal_boxtype(_FL_OXY_THIN_DOWN_FRAME, thin_down_frame); - fl_internal_boxtype(_FL_OXY_ROUND_UP_BOX, round_up_box); - fl_internal_boxtype(_FL_OXY_ROUND_DOWN_BOX, round_down_box); + fl_internal_boxtype(_FL_OXY_ROUND_UP_BOX, round_up_box, fl_rounded_focus); + fl_internal_boxtype(_FL_OXY_ROUND_DOWN_BOX, round_down_box, fl_rounded_focus); fl_internal_boxtype(_FL_OXY_BUTTON_UP_BOX, button_up_box); fl_internal_boxtype(_FL_OXY_BUTTON_DOWN_BOX, button_down_box); diff --git a/src/fl_plastic.cxx b/src/fl_plastic.cxx index eda2337f5..bc897833c 100644 --- a/src/fl_plastic.cxx +++ b/src/fl_plastic.cxx @@ -348,8 +348,8 @@ static void down_round(int x, int y, int w, int h, Fl_Color c) { } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); - +extern void fl_rounded_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg); +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX() { fl_internal_boxtype(_FL_PLASTIC_UP_BOX, up_box); @@ -358,8 +358,8 @@ Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX() { fl_internal_boxtype(_FL_PLASTIC_DOWN_FRAME, down_frame); fl_internal_boxtype(_FL_PLASTIC_THIN_UP_BOX, thin_up_box); fl_internal_boxtype(_FL_PLASTIC_THIN_DOWN_BOX, down_box); - fl_internal_boxtype(_FL_PLASTIC_ROUND_UP_BOX, up_round); - fl_internal_boxtype(_FL_PLASTIC_ROUND_DOWN_BOX, down_round); + fl_internal_boxtype(_FL_PLASTIC_ROUND_UP_BOX, up_round, fl_rounded_focus); + fl_internal_boxtype(_FL_PLASTIC_ROUND_DOWN_BOX, down_round, fl_rounded_focus); return _FL_PLASTIC_UP_BOX; } diff --git a/src/fl_round_box.cxx b/src/fl_round_box.cxx index 54c8ebb07..88cbcfc25 100644 --- a/src/fl_round_box.cxx +++ b/src/fl_round_box.cxx @@ -108,9 +108,20 @@ void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) { draw(CLOSED, x, y, w, h, 0, (Fl_Color)g[(int)'A']); } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +void fl_round_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg) { + x += Fl::box_dx(bt); + y += Fl::box_dy(bt); + w -= Fl::box_dw(bt); + h -= Fl::box_dh(bt); + Fl_Color savecolor = fl_color(); + fl_line_style(FL_DOT); + draw(CLOSED, x, y, w, h, 0, fl_contrast(fg, bg)); + fl_line_style(FL_SOLID); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_ROUND_UP_BOX() { - fl_internal_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box); - fl_internal_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box); + fl_internal_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box, fl_round_focus); + fl_internal_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box, fl_round_focus); return _FL_ROUND_UP_BOX; } diff --git a/src/fl_rounded_box.cxx b/src/fl_rounded_box.cxx index f1b351144..9b64f5265 100644 --- a/src/fl_rounded_box.cxx +++ b/src/fl_rounded_box.cxx @@ -62,20 +62,33 @@ static void fl_rshadow_box(int x, int y, int w, int h, Fl_Color c) { fl_rounded_box(x, y, w, h, c); } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +void fl_rounded_focus(Fl_Boxtype bt, int x, int y, int w, int h, Fl_Color fg, Fl_Color bg) { + x += Fl::box_dx(bt); + y += Fl::box_dy(bt); + w -= Fl::box_dw(bt)+1; + h -= Fl::box_dh(bt)+1; + Fl_Color savecolor = fl_color(); + fl_color(fl_contrast(fg, bg)); + fl_line_style(FL_DOT); + rbox(0, x+1, y+1, w-1, h-1); + fl_line_style(FL_SOLID); + fl_color(savecolor); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_ROUNDED_BOX() { - fl_internal_boxtype(_FL_ROUNDED_FRAME, fl_rounded_frame); - fl_internal_boxtype(_FL_ROUNDED_BOX, fl_rounded_box); + fl_internal_boxtype(_FL_ROUNDED_FRAME, fl_rounded_frame, fl_rounded_focus); + fl_internal_boxtype(_FL_ROUNDED_BOX, fl_rounded_box, fl_rounded_focus); return _FL_ROUNDED_BOX; } Fl_Boxtype fl_define_FL_RFLAT_BOX() { - fl_internal_boxtype(_FL_RFLAT_BOX, fl_rflat_box); + fl_internal_boxtype(_FL_RFLAT_BOX, fl_rflat_box, fl_rounded_focus); return _FL_RFLAT_BOX; } Fl_Boxtype fl_define_FL_RSHADOW_BOX() { - fl_internal_boxtype(_FL_RSHADOW_BOX, fl_rshadow_box); + fl_internal_boxtype(_FL_RSHADOW_BOX, fl_rshadow_box, fl_rounded_focus); return _FL_RSHADOW_BOX; } diff --git a/src/fl_shadow_box.cxx b/src/fl_shadow_box.cxx index d89d09b68..57b0cf048 100644 --- a/src/fl_shadow_box.cxx +++ b/src/fl_shadow_box.cxx @@ -36,7 +36,7 @@ static void fl_shadow_box(int x, int y, int w, int h, Fl_Color c) { fl_shadow_frame(x,y,w,h,FL_GRAY0); } -extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*, Fl_Box_Draw_Focus_F* =NULL); Fl_Boxtype fl_define_FL_SHADOW_BOX() { fl_internal_boxtype(_FL_SHADOW_FRAME, fl_shadow_frame); fl_internal_boxtype(_FL_SHADOW_BOX, fl_shadow_box);