diff --git a/FL/Fl_Device.H b/FL/Fl_Device.H index 597ffa7e2..082d65775 100644 --- a/FL/Fl_Device.H +++ b/FL/Fl_Device.H @@ -160,6 +160,7 @@ public: // --- implementation is in src/fl_rect.cxx which includes src/drivers/xxx/Fl_xxx_Graphics_Driver_rect.cxx virtual void point(int x, int y) = 0; virtual void rect(int x, int y, int w, int h) = 0; + virtual void focus_rect(int x, int y, int w, int h); virtual void rectf(int x, int y, int w, int h) = 0; virtual void line(int x, int y, int x1, int y1) = 0; virtual void line(int x, int y, int x1, int y1, int x2, int y2) = 0; diff --git a/FL/fl_draw.H b/FL/fl_draw.H index 71dc2224d..690534982 100644 --- a/FL/fl_draw.H +++ b/FL/fl_draw.H @@ -200,6 +200,10 @@ enum { */ inline void fl_rect(int x, int y, int w, int h) { fl_graphics_driver->rect(x,y,w,h); } +/** + Draw a dotted rectangle, used to indicate keyboard focus on a widget. + */ +inline void fl_focus_rect(int x, int y, int w, int h) { fl_graphics_driver->focus_rect(x, y, w, h); } /** Draws with passed color a 1-pixel border \e inside the given bounding box */ inline void fl_rect(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rect(x,y,w,h);} /** Colors with current color a rectangle that exactly fills the given bounding box */ diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index 689ee4654..c4b7c8585 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -20,6 +20,7 @@ #include "config_lib.h" #include #include +#include #ifdef FL_CFG_GFX_QUARTZ #include "drivers/Quartz/Fl_Quartz_Graphics_Driver.h" @@ -87,6 +88,13 @@ void Fl_Graphics_Driver::text_extents(const char*t, int n, int& dx, int& dy, int dy = descent(); } +void Fl_Graphics_Driver::focus_rect(int x, int y, int w, int h) +{ + line_style(FL_DOT); + rect(x, y, w, h); + line_style(FL_SOLID); +} + /** A constructor that sets the graphics driver used by the display */ Fl_Display_Device::Fl_Display_Device(Fl_Graphics_Driver *graphics_driver) : Fl_Surface_Device(graphics_driver) { this->set_current(); diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx index c8db04ab8..717f8efb9 100644 --- a/src/Fl_Widget.cxx +++ b/src/Fl_Widget.cxx @@ -206,37 +206,13 @@ Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const { default: break; } - - fl_color(fl_contrast(FL_BLACK, color())); - -#if defined(USE_X11) || defined(__APPLE_QUARTZ__) - fl_line_style(FL_DOT); - fl_rect(X + Fl::box_dx(B), Y + Fl::box_dy(B), - W - Fl::box_dw(B) - 1, H - Fl::box_dh(B) - 1); - fl_line_style(FL_SOLID); -#elif defined(WIN32) - // Windows 95/98/ME do not implement the dotted line style, so draw - // every other pixel around the focus area... - // - // Also, QuickDraw (MacOS) does not support line styles specifically, - // and the hack we use in fl_line_style() will not draw horizontal lines - // on odd-numbered rows... - int i, xx, yy; - X += Fl::box_dx(B); Y += Fl::box_dy(B); - W -= Fl::box_dw(B) + 2; - H -= Fl::box_dh(B) + 2; + W -= Fl::box_dw(B)+1; + H -= Fl::box_dh(B)+1; - for (xx = 0, i = 1; xx < W; xx ++, i ++) if (i & 1) fl_point(X + xx, Y); - for (yy = 0; yy < H; yy ++, i ++) if (i & 1) fl_point(X + W, Y + yy); - for (xx = W; xx > 0; xx --, i ++) if (i & 1) fl_point(X + xx, Y + H); - for (yy = H; yy > 0; yy --, i ++) if (i & 1) fl_point(X, Y + yy); -#elif defined(FL_PORTING) -# pragma message "handle focus drawing" -#else -# error unsupported platform -#endif // WIN32 + fl_color(fl_contrast(FL_BLACK, color())); + fl_focus_rect(X, Y, W, H); } diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver.h b/src/drivers/GDI/Fl_GDI_Graphics_Driver.h index 1e8ff72d7..06e040f1a 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.h +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver.h @@ -69,6 +69,7 @@ protected: // --- implementation is in src/fl_rect.cxx which includes src/cfg_gfx/gdi_rect.cxx void point(int x, int y); void rect(int x, int y, int w, int h); + void focus_rect(int x, int y, int w, int h); void rectf(int x, int y, int w, int h); void line(int x, int y, int x1, int y1); void line(int x, int y, int x1, int y1, int x2, int y2); diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx index 553d7c043..796896cdd 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx @@ -48,6 +48,17 @@ void Fl_GDI_Graphics_Driver::rect(int x, int y, int w, int h) { LineTo(fl_gc, x, y); } +void Fl_GDI_Graphics_Driver::focus_rect(int x, int y, int w, int h) { + // Windows 95/98/ME do not implement the dotted line style, so draw + // every other pixel around the focus area... + w--; h--; + int i=1, xx, yy; + for (xx = 0; xx < w; xx++, i++) if (i & 1) point(x + xx, y); + for (yy = 0; yy < h; yy++, i++) if (i & 1) point(x + w, y + yy); + for (xx = w; xx > 0; xx--, i++) if (i & 1) point(x + xx, y + h); + for (yy = h; yy > 0; yy--, i++) if (i & 1) point(x, y + yy); +} + void Fl_GDI_Graphics_Driver::rectf(int x, int y, int w, int h) { if (w<=0 || h<=0) return; RECT rect;