From 5e8adebac2899d60fffc53d4692bc4972abcf795 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 3 Sep 2023 00:09:32 +0200 Subject: Adds compact buttons feature to create keypads. See test/buttons for an example. --- src/Fl.cxx | 4 ++-- src/Fl_Button.cxx | 56 +++++++++++++++++++++++++++++++++++++++++++++++++----- src/fl_boxtype.cxx | 4 ++-- 3 files changed, 55 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Fl.cxx b/src/Fl.cxx index c08eb4930..e204a1cd5 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1143,12 +1143,12 @@ void fl_throw_focus(Fl_Widget *o) { // the inactive widget and all inactive parent groups. // // This is used to send FL_SHORTCUT events to the Fl::belowmouse() widget -// in case the target widget itself is inactive_r(). In this case the event +// in case the target widget itself is !active_r(). In this case the event // is sent to the first active_r() parent. // // This prevents sending events to inactive widgets that might get the // input focus otherwise. The search is fast and light and avoids calling -// inactive_r() multiple times. +// !active_r() multiple times. // See STR #3216. // // Returns: first active_r() widget "above" the widget wi or NULL if diff --git a/src/Fl_Button.cxx b/src/Fl_Button.cxx index dec92d483..b15b33fbf 100644 --- a/src/Fl_Button.cxx +++ b/src/Fl_Button.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -67,7 +68,29 @@ void Fl_Button::setonly() { // set this radio button on, turn others off void Fl_Button::draw() { if (type() == FL_HIDDEN_BUTTON) return; Fl_Color col = value() ? selection_color() : color(); - draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col); + Fl_Boxtype bt = value() ? (down_box()?down_box():fl_down(box())) : box(); + if (compact_ && parent()) { + Fl_Widget *p = parent(); + int px, py, pw = p->w(), ph = p->h(); + if (p->as_window()) { px = 0; py = 0; } else { px = p->x(); py = p->y(); } + fl_push_clip(x(), y(), w(), h()); + draw_box(bt, px, py, pw, ph, col); + fl_pop_clip(); + const int hh = 5, ww = 5; + Fl_Color divider_color = fl_gray_ramp(FL_NUM_GRAY/3); + if (!active_r()) + divider_color = fl_inactive(divider_color); + if (x()+w() != px+pw) { + fl_color(divider_color); + fl_yxline(x()+w()-1, y()+hh, y()+h()-1-hh); + } + if (y()+h() != py+ph) { + fl_color(divider_color); + fl_xyline(x()+ww, y()+h()-1, x()+w()-1-ww); + } + } else { + draw_box(bt, col); + } draw_backdrop(); if (labeltype() == FL_NORMAL_LABEL && value()) { Fl_Color c = labelcolor(); @@ -215,11 +238,14 @@ void Fl_Button::key_release_timeout(void *d) \param[in] L widget label, default is no label */ Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *L) -: Fl_Widget(X,Y,W,H,L) { +: Fl_Widget(X,Y,W,H,L), + shortcut_(0), + value_(0), + oldval(0), + down_box_(FL_NO_BOX), + compact_(0) +{ box(FL_UP_BOX); - down_box(FL_NO_BOX); - value_ = oldval = 0; - shortcut_ = 0; set_flag(SHORTCUT_LABEL); } @@ -249,3 +275,23 @@ Fl_Toggle_Button::Fl_Toggle_Button(int X,int Y,int W,int H,const char *L) { type(FL_TOGGLE_BUTTON); } + +/** + Decide if buttons should be rendered in compact mode. + + \image html compact_buttons_gtk.png "compact button keypad using GTK+ Scheme" + \image latex compact_buttons_gtk.png "compact button keypad using GTK+ Scheme" width=4cm + + \image html compact_buttons_gleam.png "compact buttons in Gleam" + \image latex compact_buttons_gleam.png "compact buttons in Gleam" width=4cm + + In compact mode, the button's surrounding border is altered to visually signal + that multiple buttons are functionally linked together. To ensure the correct + rendering of buttons in compact mode, all buttons must be part of the same + group, positioned close to each other, and aligned with the edges of the + group. Any button outlines not in contact with the parent group's outline + will be displayed as separators. + + \param[in] v switch compact mode on (1) or off (0) + */ +void Fl_Button::compact(uchar v) { compact_ = v; } diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx index 96d016fe1..4f446c8ec 100644 --- a/src/fl_boxtype.cxx +++ b/src/fl_boxtype.cxx @@ -64,7 +64,7 @@ const uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-' Gets the drawing color to be used for the background of a box. This method is only useful inside box drawing code. It returns the - color to be used, either fl_inactive(c) if the widget is inactive_r() + color to be used, either fl_inactive(c) if the widget is !active_r() or \p c otherwise. */ Fl_Color Fl::box_color(Fl_Color c) { @@ -84,7 +84,7 @@ Fl_Color Fl::box_color(Fl_Color c) { This method is only useful inside box drawing code. Whenever a box is drawn with one of the standard box drawing methods, a static variable is set depending on the widget's current state - if the widget is - inactive_r() then the internal variable is false (0), otherwise it + !active_r() then the internal variable is false (0), otherwise it is true (1). This is faster than calling Fl_Widget::active_r() because the state is cached. -- cgit v1.2.3