diff --git a/FL/fl_draw.H b/FL/fl_draw.H
index 4095aab34..2ad8d81af 100644
--- a/FL/fl_draw.H
+++ b/FL/fl_draw.H
@@ -982,6 +982,10 @@ FL_EXPORT void fl_draw_arrow(Fl_Rect bb, Fl_Arrow_Type t, Fl_Orientation o, Fl_C
// Draw a potentially small, filled circle
FL_EXPORT void fl_draw_circle(int x, int y, int d, Fl_Color color);
+// Draw the full "radio button" of a radio menu entry or radio button
+// This requires scheme specific handling (particularly gtk+ scheme)
+FL_EXPORT void fl_draw_radio(int x, int y, int d, Fl_Color color);
+
// images:
/**
diff --git a/src/Fl_Light_Button.cxx b/src/Fl_Light_Button.cxx
index 9658be15a..98ef910e6 100644
--- a/src/Fl_Light_Button.cxx
+++ b/src/Fl_Light_Button.cxx
@@ -32,6 +32,16 @@ void Fl_Light_Button::draw() {
Fl_Color col = value() ? (active_r() ? selection_color() :
fl_inactive(selection_color())) : color();
+ // determine the color of the check mark or radio button (circle)
+
+ Fl_Color check_color = selection_color(); // default = selection color
+ if (Fl::is_scheme("gtk+"))
+ check_color = FL_SELECTION_COLOR; // exception for gtk+
+ if (!active_r())
+ check_color = fl_inactive(check_color);
+ // select a color with enough contrast
+ check_color = fl_contrast(check_color, FL_BACKGROUND2_COLOR);
+
int W = labelsize(); // check mark box size
if (W > 25) W = 25; // limit box size
int bx = Fl::box_dx(box()); // box frame width
@@ -42,8 +52,11 @@ void Fl_Light_Button::draw() {
int cy = y() + dy; // check mark box y-position
int cw = 0; // check mark box width and height
- if (down_box()) {
- // draw other down_box() styles:
+ // FIXME: the *box type* of the widget determines the drawing style:
+ // (a) down_box() == 0: Fl_Light_Button style
+ // (b) down_box() != 0: other button styles
+
+ if (down_box()) { // draw "other" button styles (b):
switch (down_box()) {
case FL_DOWN_BOX :
case FL_UP_BOX :
@@ -53,14 +66,11 @@ void Fl_Light_Button::draw() {
draw_box(down_box(), cx, cy, W, W, FL_BACKGROUND2_COLOR);
if (value()) {
// Check mark...
- if (Fl::is_scheme("gtk+")) {
- col = FL_SELECTION_COLOR;
- }
// Calculate box position and size
cx += Fl::box_dx(down_box());
cy += Fl::box_dy(down_box());
cw = W - Fl::box_dw(down_box());
- fl_draw_check(Fl_Rect(cx, cy, cw, cw), col);
+ fl_draw_check(Fl_Rect(cx, cy, cw, cw), check_color);
}
break;
case _FL_ROUND_DOWN_BOX :
@@ -68,27 +78,16 @@ void Fl_Light_Button::draw() {
// Radio button...
draw_box(down_box(), x()+dx, y()+dy, W, W, FL_BACKGROUND2_COLOR);
if (value()) {
+
+ // Draw round check mark of radio button
+
int tW = (W - Fl::box_dw(down_box())) / 2 + 1;
if ((W - tW) & 1) tW++; // Make sure difference is even to center
int tdx = dx + (W - tW) / 2;
int tdy = dy + (W - tW) / 2;
+ fl_draw_radio(x() + tdx - 1, y() + tdy - 1, tW + 2, check_color);
- if (Fl::is_scheme("gtk+")) {
- fl_color(FL_SELECTION_COLOR);
- tW --;
- fl_pie(x() + tdx - 1, y() + tdy - 1, tW + 3, tW + 3, 0.0, 360.0);
- fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.2f));
- } else {
- fl_color(col);
- }
-
- fl_draw_circle(x() + tdx, y() + tdy, tW, fl_color());
-
- if (Fl::is_scheme("gtk+")) {
- fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.5));
- fl_arc(x() + tdx, y() + tdy, tW + 1, tW + 1, 60.0, 180.0);
- }
- }
+ } // Radio button: if (value())
break;
default :
draw_box(down_box(), x()+dx, y()+dy, W, W, col);
@@ -96,7 +95,7 @@ void Fl_Light_Button::draw() {
}
lx = dx + W + 2;
} else {
- // if down_box() is zero, draw light button style:
+ // if down_box() is zero, draw light button style (a):
int hh = h()-2*dy - 2;
int ww = W/2+1;
int xx = dx;
diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx
index 271bcd50b..3a3e70708 100644
--- a/src/Fl_Menu.cxx
+++ b/src/Fl_Menu.cxx
@@ -290,7 +290,7 @@ void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m,
if (selected) {
Fl_Color r = m ? m->selection_color() : FL_SELECTION_COLOR;
Fl_Boxtype b = m && m->down_box() ? m->down_box() : FL_FLAT_BOX;
- if (fl_contrast(r,color)!=r) { // back compatibility boxtypes
+ if (fl_contrast(r, color) != r) { // back compatibility boxtypes
if (selected == 2) { // menu title
r = color;
b = m ? m->box() : FL_UP_BOX;
@@ -314,45 +314,26 @@ void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m,
int d = (h - FL_NORMAL_SIZE + 1) / 2;
int W = h - 2 * d;
+ Fl_Color check_color = labelcolor_;
+ if (Fl::is_scheme("gtk+"))
+ check_color = FL_SELECTION_COLOR;
+ check_color = fl_contrast(check_color, FL_BACKGROUND2_COLOR);
+
if (flags & FL_MENU_RADIO) {
+
fl_draw_box(FL_ROUND_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR);
if (value()) {
int tW = (W - Fl::box_dw(FL_ROUND_DOWN_BOX)) / 2 + 1;
if ((W - tW) & 1) tW++; // Make sure difference is even to center
int td = (W - tW) / 2;
- if (Fl::is_scheme("gtk+")) {
- fl_color(FL_SELECTION_COLOR);
- tW --;
- fl_pie(x + td + 1, y + d + td - 1, tW + 3, tW + 3, 0.0, 360.0);
- fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.2f));
- } else {
- fl_color(labelcolor_);
- }
+ fl_draw_radio(x + td + 1, y + d + td - 1, tW + 2, check_color);
+ } // FL_MENU_RADIO && value()
- fl_draw_circle(x + td + 2, y + d + td, tW, fl_color());
+ } else { // FL_MENU_TOGGLE && ! FL_MENU_RADIO
- if (Fl::is_scheme("gtk+")) {
- fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.5));
- fl_arc(x + td + 2, y + d + td, tW + 1, tW + 1, 60.0, 180.0);
- }
- }
- } else {
fl_draw_box(FL_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR);
if (value()) {
- if (Fl::is_scheme("gtk+")) {
- fl_color(FL_SELECTION_COLOR);
- } else {
- fl_color(labelcolor_);
- }
- int tx = x + 5;
- int tw = W - 6;
- int d1 = tw/3;
- int d2 = tw-d1;
- int ty = y + d + (W+d2)/2-d1-2;
- for (int n = 0; n < 3; n++, ty++) {
- fl_line(tx, ty, tx+d1, ty+d1);
- fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1);
- }
+ fl_draw_check(Fl_Rect(x+3, y+d+1, W-2, W-2), check_color);
}
}
x += W + 3;
diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx
index bfd1c67fd..b0598245f 100644
--- a/src/fl_draw.cxx
+++ b/src/fl_draw.cxx
@@ -594,25 +594,76 @@ void fl_draw_check(Fl_Rect bb, Fl_Color col) {
/**
Draw a potentially small, filled circle using a given color.
- This function draws using \p color a filled circle bounded by rectangle (x, y, d, d).
+ This function draws a filled circle bounded by rectangle
+ (x, y, d, d) using color \p color
- This function is the same as fl_pie(x, y, d, d, 0, 360) except with some systems
- that don't draw small circles well. In that situation, the circle diameter \p d is converted
- from FLTK units to pixels and this function approximates a filled circle by drawing several
- filled rectangles if the converted diameter is ≤ 6 pixels.
+ This function is the same as fl_pie(x, y, d, d, 0, 360) except
+ with some systems that don't draw small circles well. In that situation,
+ the circle diameter \p d is converted from FLTK units to pixels and this
+ function approximates a filled circle by drawing several filled
+ rectangles if the converted diameter is ≤ 6 pixels.
- \param[in] x,y coordinates of top left of the bounding box
- \param[in] d diameter == width and height of the bounding box in FLTK units
- \param[in] color drawing color
+ The current drawing color fl_color() is preserved across the call.
+
+ \param[in] x,y coordinates of top left of the bounding box
+ \param[in] d diameter == width and height of the bounding box in FLTK units
+ \param[in] color the color used to draw the circle
\since 1.4.0
*/
void fl_draw_circle(int x, int y, int d, Fl_Color color) {
#define DEBUG_DRAW_CIRCLE (0) // bit 1 = draw bounding box (green)
-#if (DEBUG_DRAW_CIRCLE & 1)
+#if (DEBUG_DRAW_CIRCLE & 0)
Fl_Color current = fl_color();
- fl_rectf(x0, y0, d, d, FL_GREEN);
+ fl_rectf(x, y, d, d, FL_GREEN);
fl_color(current);
#endif
fl_graphics_driver->draw_circle(x, y, d, color);
}
+
+/**
+ Draw a round check mark (circle) of a radio button.
+
+ This draws only the round "radio button mark", it does not draw the
+ (also typically round) box of the radio button.
+
+ Call this only if the radio button is \c ON.
+
+ This method draws a scheme specific "circle" with a particular light effect
+ if the scheme is gtk+. For all other schemes this function draws a simple,
+ small circle.
+
+ The \c color must be chosen by the caller so it has enough contrast with
+ the background.
+
+ The bounding box of the circle is the rectangle (x, y, d, d).
+
+ The current drawing color fl_color() is preserved across the call.
+
+ \param[in] x,y coordinates of top left of the bounding box
+ \param[in] d diameter == width and height of the bounding box in FLTK units
+ \param[in] color the base color used to draw the circle
+
+ \since 1.4.0
+*/
+void fl_draw_radio(int x, int y, int d, Fl_Color color) {
+
+ Fl_Color current = fl_color();
+
+#if (0) // DEBUG: draw bounding box
+ fl_color(fl_lighter(FL_RED));
+ fl_rectf(x, y, d, d);
+#endif
+
+ if (Fl::is_scheme("gtk+")) {
+ fl_color(color);
+ fl_pie(x, y, d, d, 0.0, 360.0);
+ Fl_Color icol = fl_color_average(FL_WHITE, color, 0.2f);
+ fl_draw_circle(x + 2, y + 2, d - 4, icol);
+ fl_color(fl_color_average(FL_WHITE, color, 0.5));
+ fl_arc(x + 1, y + 1, d - 1, d - 1, 60.0, 180.0);
+ } else {
+ fl_draw_circle(x + 1, y + 1, d - 2, color);
+ }
+ fl_color(current);
+}