|
commit ab58971bcf9cedee6ecd131ca032087ff7d1623c
Author: Albrecht Schlosser <albrechts.fltk@online.de>
AuthorDate: Fri Jan 14 17:17:09 2022 +0100
Commit: Albrecht Schlosser <albrechts.fltk@online.de>
CommitDate: Fri Jan 14 17:17:09 2022 +0100
Improve focus box drawing and documentation
Add new method
Fl_Widget::draw_focus(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color bg)
... with background color for correct contrast testing (in Fl_Tabs)
Draw the focus box of the "tabs" of Fl_Tabs widgets with the correct
boxtype and background color.
Make 'unsigned int visible_focus()' const so it can be used in 'const'
methods.
Do not draw the focus box if the per-widget focus box option is off.
FL/Fl_Widget.H | 27 +++++++++++++++++++++++----
FL/fl_draw.H | 7 ++++++-
src/Fl_Tabs.cxx | 4 ++--
src/Fl_Widget.cxx | 46 +++++++++++++++++++++++++++++++++++++---------
4 files changed, 68 insertions(+), 16 deletions(-)
diff --git FL/Fl_Widget.H FL/Fl_Widget.H
index 0745b90..1c90848 100644
--- FL/Fl_Widget.H
+++ FL/Fl_Widget.H
@@ -169,9 +169,28 @@ protected:
void draw_box(Fl_Boxtype t, Fl_Color c) const;
void draw_box(Fl_Boxtype t, int x,int y,int w,int h, Fl_Color c) const;
void draw_backdrop() const;
- /** draws a focus rectangle around the widget */
- void draw_focus() {draw_focus(box(),x(),y(),w(),h());}
- void draw_focus(Fl_Boxtype t, int x,int y,int w,int h) const;
+
+ /** Draws a focus rectangle around the widget.
+ This method uses the widget's boxtype and coordinates and its
+ background color color().
+ \see Fl_Widget::draw_focus(Fl_Boxtype, int, int, int, int, Fl_Color) const
+ */
+ void draw_focus() const {
+ draw_focus(box(), x(), y(), w(), h(), color());
+ }
+
+ /** Draws a focus rectangle around the widget.
+ This method uses the given boxtype and coordinates and the widget's
+ background color color().
+ \see Fl_Widget::draw_focus(Fl_Boxtype, int, int, int, int, Fl_Color) const
+ */
+ void draw_focus(Fl_Boxtype t, int X, int Y, int W, int H) const {
+ draw_focus(t, X, Y, W, H, color());
+
+ }
+ // See documentation in Fl_Widget.cxx
+ void draw_focus(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color bg) const;
+
void draw_label() const;
void draw_label(int, int, int, int) const;
@@ -845,7 +864,7 @@ public:
\retval 0 if this widget has no visible focus.
\see visible_focus(int), set_visible_focus(), clear_visible_focus()
*/
- unsigned int visible_focus() { return flags_ & VISIBLE_FOCUS; }
+ unsigned int visible_focus() const { return flags_ & VISIBLE_FOCUS; }
/** The default callback for all widgets that don't set a callback.
diff --git FL/fl_draw.H FL/fl_draw.H
index 8db59b4..66125d3 100644
--- FL/fl_draw.H
+++ FL/fl_draw.H
@@ -299,7 +299,12 @@ inline void fl_rect(Fl_Rect r) {
fl_rect(r.x(), r.y(), r.w(), r.h());
}
-/** Draw a dotted rectangle, used to indicate keyboard focus on a widget. */
+/** Draw a dotted rectangle, used to indicate keyboard focus on a widget.
+
+ This method draws the rectangle in the current color and independent of
+ the Fl::visible_focus() option. You may need to set the current color
+ with fl_color() before you call this.
+*/
inline void fl_focus_rect(int x, int y, int w, int h) {
fl_graphics_driver->focus_rect(x, y, w, h);
}
diff --git src/Fl_Tabs.cxx src/Fl_Tabs.cxx
index 4c83b64..9b62645 100644
--- src/Fl_Tabs.cxx
+++ src/Fl_Tabs.cxx
@@ -417,7 +417,7 @@ void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) {
o->draw_label(x1, y() + yofs, W, H - yofs, tab_align());
if (Fl::focus() == this && o->visible())
- draw_focus(box(), x1, y(), W, H);
+ draw_focus(bt, x1, y(), W, H, bc);
fl_pop_clip();
} else {
@@ -435,7 +435,7 @@ void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) {
o->draw_label(x1, y() + h() - H, W, H - yofs, tab_align());
if (Fl::focus() == this && o->visible())
- draw_focus(box(), x1, y() + h() - H, W, H);
+ draw_focus(bt, x1, y() + h() - H, W, H, bc);
fl_pop_clip();
}
diff --git src/Fl_Widget.cxx src/Fl_Widget.cxx
index 8b4de1a..16bf7bc 100644
--- src/Fl_Widget.cxx
+++ src/Fl_Widget.cxx
@@ -182,11 +182,38 @@ Fl_Widget::~Fl_Widget() {
if (callback_ == default_callback) cleanup_readqueue(this);
}
-/** Draws a focus box for the widget at the given position and size. */
+/**
+ Draws a focus box for the widget at the given position and size.
+
+ This method does nothing if
+ - the global option Fl::visible_focus() or
+ - the per-widget option visible_focus()
+ is false (off).
+
+ This means that Fl_Widget::draw_focus() or one of the more specialized
+ methods can be called without checking these visible focus options.
+
+ \note This method must only be called if the widget has the focus.
+ This is not tested internally.
+
+ The boxtype \p bt is used to calculate the inset so the focus box is drawn
+ inside the box borders.
-void Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const {
+ The default focus box drawing color is black. The background color \p bg
+ is used to determine a better visible color if necessary by using
+ fl_contrast() with the given background color.
+
+ \param[in] bt Boxtype that needs to be considered (frame width)
+ \param[in] X,Y,W,H Bounding box
+ \param[in] bg Background color
+
+ \see Fl_Widget::draw_focus()
+ \see Fl_Widget::draw_focus(Fl_Boxtype, int, int, int, int) const
+*/
+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;
- switch (B) {
+ if (!visible_focus()) return;
+ switch (bt) {
case FL_DOWN_BOX:
case FL_DOWN_FRAME:
case FL_THIN_DOWN_BOX:
@@ -196,16 +223,17 @@ void Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const {
default:
break;
}
- X += Fl::box_dx(B);
- Y += Fl::box_dy(B);
- W -= Fl::box_dw(B)+1;
- H -= Fl::box_dh(B)+1;
+ X += Fl::box_dx(bt);
+ Y += Fl::box_dy(bt);
+ W -= Fl::box_dw(bt)+1;
+ H -= Fl::box_dh(bt)+1;
- fl_color(fl_contrast(FL_BLACK, color()));
+ Fl_Color savecolor = fl_color();
+ fl_color(fl_contrast(FL_BLACK, bg));
fl_focus_rect(X, Y, W, H);
+ fl_color(savecolor);
}
-
void Fl_Widget::activate() {
if (!active()) {
clear_flag(INACTIVE);
[ Direct Link to Message ] | |