From b1ba37c5ba1df543baa87d328805af34da4bd2b1 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Thu, 24 Nov 2022 19:00:00 +0100 Subject: Add "Oxy" scheme (STR 2675, STR 3477) This commit is similar to the patch given in STR 3477, oxy_v5.diff: https://www.fltk.org/strfiles/3477/oxy_v5.diff ... with modifications, and updated to current FLTK code. --- src/CMakeLists.txt | 1 + src/Fl_Choice.cxx | 11 +- src/Fl_Input_Choice.cxx | 7 +- src/Fl_Menu.cxx | 21 +- src/Fl_Menu_Button.cxx | 28 +-- src/Fl_Scrollbar.cxx | 4 +- src/Fl_Tree_Prefs.cxx | 2 + src/Fl_get_system_colors.cxx | 26 +- src/Makefile | 1 + src/fl_boxtype.cxx | 12 + src/fl_draw.cxx | 2 + src/fl_draw_arrow.cxx | 14 +- src/fl_oxy.cxx | 557 +++++++++++++++++++++++++++++++++++++++++++ src/fl_oxy.h | 40 ++++ src/makedepend | 16 ++ 15 files changed, 697 insertions(+), 45 deletions(-) create mode 100644 src/fl_oxy.cxx create mode 100644 src/fl_oxy.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 21d2089a5..471361451 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -149,6 +149,7 @@ set (CPPFILES fl_open_uri.cxx fl_oval_box.cxx fl_overlay.cxx + fl_oxy.cxx fl_plastic.cxx fl_read_image.cxx fl_rect.cxx diff --git a/src/Fl_Choice.cxx b/src/Fl_Choice.cxx index c23010c07..8646368d3 100644 --- a/src/Fl_Choice.cxx +++ b/src/Fl_Choice.cxx @@ -65,15 +65,16 @@ void Fl_Choice::draw() { // Arrow box or horizontal divider line, depending on the current scheme - // Scheme: Box or divider line + // Scheme: Box or divider line // ---------------------------------------- - // Default (None): Arrow box (FL_UP_BOX) - // gtk+, gleam: Divider line - // else: Nothing (!) + // Default (None): Arrow box (FL_UP_BOX) + // gtk+, gleam, oxy: Divider line + // else: Nothing (!) if (Fl::scheme()) { if (Fl::is_scheme("gtk+") || - Fl::is_scheme("gleam")) { + Fl::is_scheme("gleam") || + Fl::is_scheme("oxy")) { // draw the divider int x1 = x() + w() - 20 - dx; int y1 = y() + h() / 2; diff --git a/src/Fl_Input_Choice.cxx b/src/Fl_Input_Choice.cxx index 4cf8712e6..ae38cd1c6 100644 --- a/src/Fl_Input_Choice.cxx +++ b/src/Fl_Input_Choice.cxx @@ -5,7 +5,7 @@ // | input area || \/ | // |______________||____| // -// Copyright 1998-2017 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // Copyright 2004 by Greg Ercolano. // // This library is free software. Distribution and use rights are outlined in @@ -137,8 +137,9 @@ Fl_Input_Choice::InputMenuButton::InputMenuButton(int x,int y,int w,int h,const void Fl_Input_Choice::InputMenuButton::draw() { draw_box(); fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); - int xc = x()+w()/2, yc=y()+h()/2; - fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3); + Fl_Rect ab(this); + ab.inset(1); + fl_draw_arrow(ab, FL_ARROW_CHOICE, FL_ORIENT_NONE, fl_color()); if (Fl::focus() == this) draw_focus(); } diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx index 6e6d26da9..77b48499e 100644 --- a/src/Fl_Menu.cxx +++ b/src/Fl_Menu.cxx @@ -476,10 +476,6 @@ void menuwindow::autoscroll(int n) { void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) { if (!m) return; // this happens if -1 is selected item and redrawn - // FIXME: size and coordinate calculation (sz, x1, y1) should be simplified when - // the "old code" below is entirely removed (left as is for comparison). - // AlbrechtS Nov. 23, 2022 - int BW = Fl::box_dx(box()); int xx = BW; int W = w(); @@ -497,19 +493,14 @@ void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) { // the shortcuts and arrows assume fl_color() was left set by draw(): if (m->submenu()) { - int sz = (hh-7)&-2; - int y1 = yy+(hh-sz)/2; - int x1 = xx+ww-sz-3; - -#if (0) // old code, independent of active scheme (left for comparison) - - fl_polygon(x1+2, y1, x1+2, y1+sz, x1+sz/2+2, y1+sz/2); -#else // right arrow whose style dependends on the active scheme + // calculate the bounding box of the submenu pointer (arrow) + int sz = (hh-2) & -2; + int x1 = xx + ww - sz - 2; + int y1 = yy + (hh-sz)/2 + 1; - fl_draw_arrow(Fl_Rect(x1-1, y1-1, sz+2, sz+2), FL_ARROW_SINGLE, FL_ORIENT_RIGHT, fl_color()); - -#endif + // draw an arrow whose style dependends on the active scheme + fl_draw_arrow(Fl_Rect(x1, y1, sz, sz), FL_ARROW_SINGLE, FL_ORIENT_RIGHT, fl_color()); } else if (m->shortcut_) { Fl_Font f = m->labelsize_ || m->labelfont_ ? (Fl_Font)m->labelfont_ : diff --git a/src/Fl_Menu_Button.cxx b/src/Fl_Menu_Button.cxx index f57b52b4e..b9dfb666e 100644 --- a/src/Fl_Menu_Button.cxx +++ b/src/Fl_Menu_Button.cxx @@ -26,31 +26,23 @@ static Fl_Menu_Button *pressed_menu_button_ = 0; void Fl_Menu_Button::draw() { if (!box() || type()) return; - // FIXME: size and coordinate calculation (H, X, Y) should be simplified when - // the "old code" below is entirely removed (left as is for comparison). - // AlbrechtS Nov. 23, 2022 + // calculate position and size of virtual "arrow box" (choice button) - int H = (labelsize()-3)&-2; - int X = x()+w()-H-Fl::box_dx(box())-Fl::box_dw(box())-1; - int Y = y()+(h()-H)/2; + int ah = h() - Fl::box_dh(box()); + int aw = ah > 20 ? 20 : ah; // limit width: don't waste space for button + int ax = x() + w() - Fl::box_dx(box()) - aw; + int ay = y() + (h() - ah) / 2; + + // the remaining space is used to draw the label draw_box(pressed_menu_button_ == this ? fl_down(box()) : box(), color()); - draw_label(x()+Fl::box_dx(box()), y(), X-x()+2, h()); + draw_label(x() + Fl::box_dx(box()), y(), w() - Fl::box_dw(box()) - aw, h()); if (Fl::focus() == this) draw_focus(); -#if (0) // old code: outline of an engraved down-arrow for all schemes - - fl_color(active_r() ? FL_DARK3 : fl_inactive(FL_DARK3)); - fl_line(X+H/2, Y+H, X, Y, X+H, Y); - fl_color(active_r() ? FL_LIGHT3 : fl_inactive(FL_LIGHT3)); - fl_line(X+H, Y, X+H/2, Y+H); - -#else // new code: filled down-arrow whose style dependends on the current scheme + // draw the arrow (choice button) Fl_Color arrow_color = active_r() ? FL_DARK3 : fl_inactive(FL_DARK3); - fl_draw_arrow(Fl_Rect(X-1, Y-1, H+4, H+4), FL_ARROW_SINGLE, FL_ORIENT_DOWN, arrow_color); - -#endif + fl_draw_arrow(Fl_Rect(ax, ay, aw, ah), FL_ARROW_SINGLE, FL_ORIENT_DOWN, arrow_color); } diff --git a/src/Fl_Scrollbar.cxx b/src/Fl_Scrollbar.cxx index d8d42ce80..688e760b2 100644 --- a/src/Fl_Scrollbar.cxx +++ b/src/Fl_Scrollbar.cxx @@ -203,9 +203,9 @@ void Fl_Scrollbar::draw() { int H = h() - Fl::box_dh(box()); Fl_Rect ab; // arrow box - int inset = 3; + int inset = 2; if (W < 8 || H < 8) - inset = 2; + inset = 1; if (horizontal()) { if (W < 3*H) { diff --git a/src/Fl_Tree_Prefs.cxx b/src/Fl_Tree_Prefs.cxx index d8f68a8ba..fa45a3e33 100644 --- a/src/Fl_Tree_Prefs.cxx +++ b/src/Fl_Tree_Prefs.cxx @@ -176,6 +176,8 @@ Fl_Tree_Prefs::Fl_Tree_Prefs() { _selectbox = _FL_GTK_THIN_UP_BOX; } else if (Fl::is_scheme("plastic")) { _selectbox = _FL_PLASTIC_THIN_UP_BOX; + } else if (Fl::is_scheme("oxy")) { + _selectbox = _FL_OXY_THIN_UP_BOX; } } diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx index 4ce086481..6e7d37214 100644 --- a/src/Fl_get_system_colors.cxx +++ b/src/Fl_get_system_colors.cxx @@ -1,7 +1,7 @@ // // System color support for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2018 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -149,6 +149,8 @@ static Fl_Pixmap tile(tile_xpm); - "gleam" - This scheme is inspired by the Clearlooks Glossy scheme. (Colin Jones and Edmanuel Torres). + - "oxy" - Subset of Dmitrij K's oxy scheme (STR 2675, 3477) + Uppercase scheme names are equivalent, but the stored scheme name will always be lowercase and Fl::scheme() will return this lowercase name. @@ -167,6 +169,7 @@ int Fl::scheme(const char *s) { else if (!fl_ascii_strcasecmp(s, "gtk+")) s = fl_strdup("gtk+"); else if (!fl_ascii_strcasecmp(s, "plastic")) s = fl_strdup("plastic"); else if (!fl_ascii_strcasecmp(s, "gleam")) s = fl_strdup("gleam"); + else if (!fl_ascii_strcasecmp(s, "oxy")) s = fl_strdup("oxy"); else s = 0; } if (scheme_) free((void*)scheme_); @@ -273,6 +276,27 @@ int Fl::reload_scheme() { set_boxtype(_FL_ROUND_UP_BOX, FL_GLEAM_ROUND_UP_BOX); set_boxtype(_FL_ROUND_DOWN_BOX, FL_GLEAM_ROUND_DOWN_BOX); + // Use slightly thinner scrollbars... + Fl::scrollbar_size(15); + } else if (scheme_ && !fl_ascii_strcasecmp(scheme_, "oxy")) { + // Oxy scheme + if (scheme_bg_) { + delete scheme_bg_; + scheme_bg_ = (Fl_Image *)0; + } + + set_boxtype(FL_UP_FRAME, FL_OXY_UP_FRAME); + set_boxtype(FL_DOWN_FRAME, FL_OXY_DOWN_FRAME); + set_boxtype(FL_THIN_UP_FRAME, FL_OXY_THIN_UP_FRAME); + set_boxtype(FL_THIN_DOWN_FRAME, FL_OXY_THIN_DOWN_FRAME); + + set_boxtype(FL_UP_BOX, FL_OXY_UP_BOX); + set_boxtype(FL_DOWN_BOX, FL_OXY_DOWN_BOX); + set_boxtype(FL_THIN_UP_BOX, FL_OXY_THIN_UP_BOX); + set_boxtype(FL_THIN_DOWN_BOX, FL_OXY_THIN_DOWN_BOX); + set_boxtype(_FL_ROUND_UP_BOX, FL_OXY_ROUND_UP_BOX); + set_boxtype(_FL_ROUND_DOWN_BOX, FL_OXY_ROUND_DOWN_BOX); + // Use slightly thinner scrollbars... Fl::scrollbar_size(15); } else { diff --git a/src/Makefile b/src/Makefile index 388f69b23..a2b9ed0bb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -152,6 +152,7 @@ CPPFILES = \ fl_open_uri.cxx \ fl_oval_box.cxx \ fl_overlay.cxx \ + fl_oxy.cxx \ fl_plastic.cxx \ fl_read_image.cxx \ fl_rect.cxx \ diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx index cb9226ebe..08d80cb45 100644 --- a/src/fl_boxtype.cxx +++ b/src/fl_boxtype.cxx @@ -344,6 +344,18 @@ static struct { {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_THIN_DOWN_BOX {fl_up_box, 2,2,4,4,0}, // _FL_GLEAM_ROUND_UP_BOX {fl_down_box, 2,2,4,4,0}, // _FL_GLEAM_ROUND_DOWN_BOX + {fl_up_box, 2,2,4,4,0}, // _FL_OXY_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_OXY_DOWN_BOX, + {fl_up_frame, 2,2,4,4,0}, // _FL_OXY_UP_FRAME, + {fl_down_frame, 2,2,4,4,0}, // _FL_OXY_DOWN_FRAME, + {fl_thin_up_box, 1,1,2,2,0}, // _FL_OXY_THIN_UP_BOX, + {fl_thin_down_box, 1,1,2,2,0}, // _FL_OXY_THIN_DOWN_BOX, + {fl_thin_up_frame, 1,1,2,2,0}, // _FL_OXY_THIN_UP_FRAME, + {fl_thin_down_frame, 1,1,2,2,0}, // _FL_OXY_THIN_DOWN_FRAME, + {fl_up_box, 4,4,8,8,0}, // _FL_OXY_ROUND_UP_BOX, + {fl_down_box, 4,4,8,8,0}, // _FL_OXY_ROUND_DOWN_BOX, + {fl_up_box, 2,2,4,4,0}, // _FL_OXY_BUTTON_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_OXY_BUTTON_DOWN_BOX, {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+0 {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+1 {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+2 diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx index 2ed733d5a..7b36d4c75 100644 --- a/src/fl_draw.cxx +++ b/src/fl_draw.cxx @@ -28,6 +28,8 @@ #include // fl_open_display() #include "flstring.h" +#include "fl_oxy.h" + #include #include #include diff --git a/src/fl_draw_arrow.cxx b/src/fl_draw_arrow.cxx index 0bee12226..16ee4361d 100644 --- a/src/fl_draw_arrow.cxx +++ b/src/fl_draw_arrow.cxx @@ -22,6 +22,11 @@ #include #include #include +#include "fl_oxy.h" + +// Debug mode: if you design a widget or want to check its layout, +// then enable one or both flags of DEBUG_ARROW (below) so you can +// see where the arrows (i.e. their bounding boxes) are positioned #ifndef DEBUG_ARROW #define DEBUG_ARROW (0) // 0 = off, 1 = green background, 2 = red frame, 3 = both @@ -224,7 +229,14 @@ void fl_draw_arrow(Fl_Rect r, Fl_Arrow_Type t, Fl_Orientation o, Fl_Color col) { debug_arrow(r); - // implementation of all arrow types + // special case: arrows for the "oxy" scheme + + if (Fl::is_scheme("oxy")) { + oxy_arrow(r, t, o, col); + return; + } + + // implementation of all arrow types for other schemes switch(t) { case FL_ARROW_SINGLE: diff --git a/src/fl_oxy.cxx b/src/fl_oxy.cxx new file mode 100644 index 000000000..7f24260dc --- /dev/null +++ b/src/fl_oxy.cxx @@ -0,0 +1,557 @@ +// +// "Oxy" Scheme drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 2011 by Dmitrij K. e-mail: kdiman at live dot ru +// Copyright 2012-2022 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please report all bugs and problems on the following page: +// +// https://www.fltk.org/str.php +// + +#include +#include +#include +#include "fl_oxy.h" + +// Status of this scheme (to-do list): +// +// This scheme works but is still work in progress: +// +// Some of the internal (static) and global functions in this file need fixes: +// (1) parameter 'bool active' should not be necessary, the caller has to set up the colors +// (2) parameter 'Fl_Color hcol' is currently not set up by the caller in fl_draw_arrow() +// (3) oxy_arrow(bb, t, o, col) (4 parameters) duplicates 'col' for 'col' and 'hcol' +// when calling oxy_arrow(bb, t, o, true, col, col) (6 parameters) +// (4) drawing arrows with adjacent lines does not scale well (ctrl/+/-), +// we should draw polygons instead, see fl_draw_check() for an example. + +#define GROFF 0.45f // gradients offset + +static void arrow_begin(bool active, Fl_Color col, Fl_Color hcol, float av) { + Fl_Color col1 = fl_color_average(col, hcol, av); + fl_color(active ? col1 : fl_inactive(col1)); + fl_begin_line(); +} + +static void arrow_end() { + fl_end_line(); +} + +static void single_arrow(Fl_Rect bb, Fl_Orientation o, + bool active, Fl_Color col, Fl_Color hcol) { + + int x1 = bb.x(); + int y1 = bb.y(); + int w1 = bb.w(); + int h1 = bb.h(); + + int dx = w1 / 3; + if (h1 < w1) dx = h1 / 3; + if (dx > 4) dx = 4; + else if (dx < 2) dx = 2; + + // this is for "single" arrows (Fl_Arrow_Type FL_ARROW_SINGLE) only ! + + float angle = int(o) * 45.0; + + int tx = x1 + (w1 + 1)/2; + int ty = y1 + (h1 + 1)/2; + + fl_push_matrix(); + fl_translate(tx, ty); + fl_rotate(angle); + + int x0 = -(dx+1)/2; + + arrow_begin(active, col, hcol, 0.38); + fl_vertex(x0, -dx); + fl_vertex(x0 + dx, 0); + fl_vertex(x0, dx); + arrow_end(); + + arrow_begin(active, col, hcol, 0.58); + fl_vertex(x0, -dx + 1); + fl_vertex(x0 + dx - 1, 0); + fl_vertex(x0, dx - 1); + arrow_end(); + + arrow_begin(active, col, hcol, 0.78); + fl_vertex(x0 + 1, -dx); + fl_vertex(x0 + dx + 1, 0); + fl_vertex(x0 + 1, dx); + arrow_end(); + + fl_pop_matrix(); +} + +/** + Draw an "arrow" GUI element for the 'oxy' scheme. + + \param[in] bb bounding box + \param[in] t arrow type + \param[in] o orientation + \param[in] active widget is active (true) or inactive (false) + \param[in] col arrow color + \param[in] hcol "highlight" color + +*/ + +void oxy_arrow(Fl_Rect bb, Fl_Arrow_Type t, Fl_Orientation o, + bool active, Fl_Color col, Fl_Color hcol) { + + switch(t) { + + case FL_ARROW_DOUBLE: + + switch (int(o)) { + case FL_ORIENT_DOWN: + case FL_ORIENT_UP: + bb.y(bb.y() - 2); // shift upwards + bb.h(bb.h() - 4); // reduce size + single_arrow(bb, o, active, col, hcol); + bb.y(bb.y() + 4); // shift down + single_arrow(bb, o, active, col, hcol); + break; + default: + bb.x(bb.x() - 2); // shift left + bb.w(bb.w() - 4); // reduce size + single_arrow(bb, o, active, col, hcol); + bb.x(bb.x() + 4); // shift right + single_arrow(bb, o, active, col, hcol); + break; + } + break; + + case FL_ARROW_CHOICE: + + bb.y(bb.y() - 2); // shift upwards + bb.h(bb.h() - 4); // reduce size + single_arrow(bb, FL_ORIENT_DOWN, active, col, hcol); + bb.y(bb.y() + 4); // shift down + single_arrow(bb, FL_ORIENT_DOWN, active, col, hcol); + break; + + default: + + single_arrow(bb, o, active, col, hcol); + break; + + } + +} + + +/** + Draw an "arrow" GUI element for the 'oxy' scheme (simplified). + + \param[in] bb bounding box + \param[in] t arrow type + \param[in] o orientation + \param[in] col arrow color +*/ + +void oxy_arrow(Fl_Rect bb, Fl_Arrow_Type t, Fl_Orientation o, Fl_Color col) { + + oxy_arrow(bb, t, o, true, col, col); + +} + + +// draw gradient from South to North +static void _oxy_up_box_(int x, int y, int w, int h, Fl_Color bg) { + float groff = GROFF; + if (groff < 0.0) { + groff = 0.0f; + } + float gradoffset = groff; + float stepoffset = (1.0 / (float)h); + int xw = x + w - 1; + // from bottom to top + for (int _y = y; _y < y + h; _y++) { + fl_color(fl_color_average(bg, FL_WHITE, (gradoffset < 1.0) ? gradoffset : 1.0)); + fl_xyline(x, _y, xw); + gradoffset += stepoffset; + } +} + + +// draw gradient from North to South +static void _oxy_down_box_(int x, int y, int w, int h, Fl_Color bg) { + float groff = GROFF; + if (groff < 0.0) { + groff = 0.0f; + } + float gradoffset = groff; + float stepoffset = (1.0 / (float)h); + int xw = x + w - 1; + // from top to bottom + for (int _y = y + h - 1; _y >= y; _y--) { + fl_color(fl_color_average(bg, FL_WHITE, (gradoffset < 1.0) ? gradoffset : 1.0)); + fl_xyline(x, _y, xw); + gradoffset += stepoffset; + } +} + +// draw gradient for button up box +static void _oxy_button_up_box_(int x, int y, int w, int h, Fl_Color bg) { + int half_h = h / 2; + float gradoffset = 0.15f; + float stepoffset = (1.0 / (float)half_h); + Fl_Color col = fl_color_average(bg, FL_WHITE, 0.5); + int xw = x + w - 1; + for (int _y = y; _y <= y + half_h; _y++) { + fl_color(fl_color_average(col, FL_WHITE, (gradoffset < 1.0) ? gradoffset : 1.0)); + fl_xyline(x, _y, xw); + gradoffset += stepoffset; + } + gradoffset = 0.0f; + col = bg; + for (int _y = y + h - 1; _y >= y + half_h - 1; _y--) { + fl_color(fl_color_average(col, FL_WHITE, (gradoffset < 1.0) ? gradoffset : 1.0)); + fl_xyline(x, _y, xw); + gradoffset += stepoffset; + } +} + + +// draw gradient for button down box +static void _oxy_button_down_box_(int x, int y, int w, int h, Fl_Color bg) { + bg = fl_color_average(bg, FL_BLACK, 0.88); + int half_h = h / 2, xw = x + w - 1; + float gradoffset = 0.15f, stepoffset = (1.0 / (float)half_h); + Fl_Color col = fl_color_average(bg, FL_WHITE, 0.5); + for (int _y = y; _y <= y + half_h; _y++) { + fl_color(fl_color_average(col, FL_WHITE, (gradoffset < 1.0) ? gradoffset : 1.0)); + fl_xyline(x, _y, xw); + gradoffset += stepoffset; + } + gradoffset = 0.0f; + col = bg; + for (int _y = y + h - 1; _y >= y + half_h - 1; _y--) { + fl_color(fl_color_average(col, FL_WHITE, (gradoffset < 1.0) ? gradoffset : 1.0)); + fl_xyline(x, _y, xw); + gradoffset += stepoffset; + } +} + + +// draw rounded box +static void _oxy_rounded_box_(int x, int y, int w, int h, Fl_Color bg) { + fl_color(bg); + if (w > h) { + fl_pie(x, y, h, h, 90.0, 270.0); // right half of circle + fl_rectf(x + h / 2, y, w - h, h); // rectangle between left and right half-circle + fl_pie(x + w - h, y, h, h, 0.0, 90.0); // top-left quarter of circle + fl_pie(x + w - h, y, h, h, 270.0, 360.0); // bottom-left quarter of circle + } else { + fl_pie(x, y, w, w, 0.0, 180.0); // top half of circle + fl_rectf(x, y + w / 2, w, h - w); // rectangle between top and bottom half-circle + fl_pie(x, y + h - w, w, w, 180.0, 360.0); // bottom half of circle + } +} + + +static Fl_Color oxy_color(Fl_Color col) { + if (Fl::draw_box_active()) { + return col; + } else { + return fl_inactive(col); + } +} + + +static void oxy_draw(int x, int y, int w, int h, Fl_Color col, int typebox, bool is_shadow) { + + if (w < 1 || h < 1) + return; + int X, Y, W, H, X1, Y1; + + // draw bg + if (typebox != _FL_OXY_UP_FRAME && typebox != _FL_OXY_DOWN_FRAME) { + + X = x + 1; + Y = y + 1; + W = w - 2; + H = h - 2; + + switch (typebox) { + case _FL_OXY_UP_BOX: { + _oxy_up_box_(X, Y, W, H, oxy_color(col)); + break; + } + case _FL_OXY_DOWN_BOX: { + _oxy_down_box_(X, Y, W, H, oxy_color(col)); + break; + } + case _FL_OXY_BUTTON_UP_BOX: { + _oxy_button_up_box_(X, Y, W, H, oxy_color(col)); + break; + } + case _FL_OXY_BUTTON_DOWN_BOX: { + _oxy_button_down_box_(X, Y, W, H, oxy_color(col)); + break; + } + case _FL_OXY_ROUND_UP_BOX: + case _FL_OXY_ROUND_DOWN_BOX: + _oxy_rounded_box_(x, y, w, h, oxy_color(fl_color_average(col, FL_WHITE, 0.82))); + break; + default: { break; } + } + } + + Fl_Color leftline = col, topline = col, rightline = col, bottomline = col; + + if (typebox == _FL_OXY_ROUND_UP_BOX || typebox == _FL_OXY_ROUND_DOWN_BOX) { + leftline = fl_color_average(col, FL_WHITE, 0.88); + leftline = topline = rightline = bottomline = fl_color_average(leftline, FL_BLACK, 0.97); + } + + else if (typebox == _FL_OXY_UP_BOX || typebox == _FL_OXY_UP_FRAME) { + topline = fl_color_average(col, FL_BLACK, 0.95); + leftline = fl_color_average(col, FL_BLACK, 0.85); + rightline = leftline; + bottomline = fl_color_average(col, FL_BLACK, 0.88); + } + + else if (typebox == _FL_OXY_DOWN_BOX || typebox == _FL_OXY_DOWN_FRAME) { + topline = fl_color_average(col, FL_BLACK, 0.88); + leftline = fl_color_average(col, FL_BLACK, 0.85); + rightline = leftline; + bottomline = fl_color_average(col, FL_BLACK, 0.95); + } + + else if (typebox == _FL_OXY_BUTTON_UP_BOX || typebox == _FL_OXY_BUTTON_DOWN_BOX) { + topline = leftline = rightline = bottomline = fl_color_average(col, FL_BLACK, 0.85); + } + + // draw border + if (typebox != _FL_OXY_ROUND_UP_BOX && typebox != _FL_OXY_ROUND_DOWN_BOX) { + // bottom side + fl_color(oxy_color(bottomline)); + fl_line(x + 1, y + h - 1, x + w - 2, y + h - 1); + // right side + fl_color(oxy_color(rightline)); + fl_line(x + w - 1, y + 1, x + w - 1, y + h - 2); + // top side + fl_color(oxy_color(topline)); + fl_line(x + 1, y, x + w - 2, y); + // left side + fl_color(oxy_color(leftline)); + fl_line(x, y + 1, x, y + h - 2); + } + + // draw shadow + if (is_shadow) { + + if (typebox == _FL_OXY_ROUND_UP_BOX) { + topline = fl_color_average(col, FL_WHITE, 0.35); + bottomline = fl_color_average(col, FL_BLACK, 0.94); + } + + else if (typebox == _FL_OXY_ROUND_DOWN_BOX) { + topline = fl_color_average(col, FL_BLACK, 0.94); + bottomline = fl_color_average(col, FL_WHITE, 0.35); + } + + else if (typebox == _FL_OXY_UP_BOX || typebox == _FL_OXY_UP_FRAME) { + topline = fl_color_average(col, FL_WHITE, 0.35); + leftline = fl_color_average(col, FL_WHITE, 0.4); + rightline = leftline; + bottomline = fl_color_average(col, FL_BLACK, 0.8); + } + + else if (typebox == _FL_OXY_DOWN_BOX || typebox == _FL_OXY_DOWN_FRAME) { + topline = fl_color_average(col, FL_BLACK, 0.8); + leftline = fl_color_average(col, FL_BLACK, 0.94); + rightline = leftline; + bottomline = fl_color_average(col, FL_WHITE, 0.35); + } + + int xw1 = x + w - 1; + int xw2 = x + w - 2; + int xw3 = x + w - 3; + int yh2 = y + h - 2; + int yh1 = y + h - 1; + + if (typebox == _FL_OXY_UP_BOX || typebox == _FL_OXY_UP_FRAME) { + fl_color(oxy_color(topline)); + X = x + 1; + Y = y + 1; + X1 = xw2; + Y1 = y + 1; + fl_line(X, Y, X1, Y1); // top line + + fl_color(oxy_color(leftline)); + X = x + 1; + Y = yh2; + X1 = x + 1; + Y1 = y + 2; + fl_line(X, Y, X1, Y1); // left line + + fl_color(oxy_color(rightline)); + X = xw2; + Y = y + 2; + X1 = xw2; + Y1 = yh2; + fl_line(X, Y, X1, Y1); // right line + + fl_color(oxy_color(bottomline)); + X = xw2; + Y = yh2; + X1 = x + 1; + Y1 = yh2; + fl_line(X, Y, X1, Y1); // bottom line + } + + else if (typebox == _FL_OXY_DOWN_BOX || typebox == _FL_OXY_DOWN_FRAME) { + fl_color(oxy_color(topline)); + X = x + 1; + Y = y + 1; + X1 = xw2; + Y1 = y + 1; + fl_line(X, Y, X1, Y1); // top line + + fl_color(oxy_color(leftline)); + X = x + 1; + Y = yh2; + X1 = x + 1; + Y1 = y + 2; + fl_line(X, Y, X1, Y1); // left line + + fl_color(oxy_color(rightline)); + X = xw2; + Y = y + 2; + X1 = xw2; + Y1 = yh2; + fl_line(X, Y, X1, Y1); // right line + + fl_color(oxy_color(bottomline)); + X = xw3; + Y = yh2; + X1 = x + 2; + Y1 = yh2; + fl_line(X, Y, X1, Y1); // bottom line + } + + else if (typebox == _FL_OXY_ROUND_UP_BOX || typebox == _FL_OXY_ROUND_DOWN_BOX) { + + int Radius, smooth; + int r_offset2; // quarter of smooth and half of smooth + + if (w > h) { + smooth = w; + } else { + smooth = h; + } + + // correcting `smooth' + if (smooth > 0 && (smooth * 3 > w || smooth * 3 > h)) { + if (h < w) { + smooth = h / 3; + } else { + smooth = w / 3; + } + } + + r_offset2 = smooth / 2; + + Radius = smooth * 3; + if (Radius == 3) { + Radius = 4; + } + + fl_color(oxy_color(topline)); + fl_line(x + 1, yh1 - smooth - r_offset2, x + 1, y + r_offset2 + smooth); // left side + fl_arc(x + 1, y + 1, Radius, Radius, 90.0, 180.0); // left-top corner + if (typebox == _FL_OXY_ROUND_DOWN_BOX) { + fl_arc(x + 1, y + 1, Radius + 1, Radius + 1, 90.0, 180.0); + } // left-top corner (DOWN_BOX) + fl_line(x + smooth + r_offset2, y + 1, xw1 - smooth - r_offset2, y + 1); // top side + fl_arc(xw1 - Radius, y + 1, Radius, Radius, 00.0, 90.0); // right-top corner + if (typebox == _FL_OXY_ROUND_DOWN_BOX) { + fl_arc(xw1 - Radius, y + 1, Radius + 1, Radius + 1, 00.0, 90.0); + } // right-top corner (DOWN_BOX) + fl_line(xw2, y + smooth + r_offset2, xw2, yh1 - smooth - r_offset2); // right side + fl_arc(x + 1, yh1 - Radius, Radius, Radius, 180.0, 200.0); // left-bottom corner + fl_arc(xw1 - Radius, yh1 - Radius, Radius, Radius, 340.0, 360.0); // right-bottom + fl_color(oxy_color(bottomline)); + fl_arc(x + 1, yh1 - Radius, Radius, Radius, 200.0, 270.0); // left-bottom corner + if (typebox == _FL_OXY_ROUND_UP_BOX) { + fl_arc(x + 1, yh1 - Radius, Radius + 1, Radius + 1, 200.0, 270.0); + } // left-bottom corner (UP_BOX) + fl_line(xw1 - smooth - r_offset2, yh2, x + smooth + r_offset2, yh2); // bottom side + fl_arc(xw1 - Radius, yh1 - Radius, Radius, Radius, 270.0, 340.0); // right-bottom corner + if (typebox == _FL_OXY_ROUND_UP_BOX) { + fl_arc(xw1 - Radius, yh1 - Radius, Radius + 1, Radius + 1, 270.0, 340.0); + } // right-bottom corner + } + + } // end `if (is_shadow)' + +} // end `static void oxy_draw(...)' + + +void button_up_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_BUTTON_UP_BOX, true); +} +void button_down_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_BUTTON_DOWN_BOX, true); +} +void up_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_UP_BOX, true); +} +void down_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_DOWN_BOX, true); +} +void thin_up_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_UP_BOX, false); +} +void thin_down_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_DOWN_BOX, false); +} +void up_frame(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_UP_FRAME, true); +} +void down_frame(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_DOWN_FRAME, true); +} +void thin_up_frame(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_UP_FRAME, false); +} +void thin_down_frame(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_DOWN_FRAME, false); +} +void round_up_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_ROUND_UP_BOX, true); +} +void round_down_box(int x, int y, int w, int h, Fl_Color col) { + oxy_draw(x, y, w, h, col, _FL_OXY_ROUND_DOWN_BOX, true); +} + + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F *); + +Fl_Boxtype fl_define_FL_OXY_UP_BOX() { + + fl_internal_boxtype(_FL_OXY_UP_BOX, up_box); + fl_internal_boxtype(_FL_OXY_DOWN_BOX, down_box); + fl_internal_boxtype(_FL_OXY_UP_FRAME, up_frame); + fl_internal_boxtype(_FL_OXY_DOWN_FRAME, down_frame); + fl_internal_boxtype(_FL_OXY_THIN_UP_BOX, thin_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_BUTTON_UP_BOX, button_up_box); + fl_internal_boxtype(_FL_OXY_BUTTON_DOWN_BOX, button_down_box); + + return _FL_OXY_UP_BOX; +} diff --git a/src/fl_oxy.h b/src/fl_oxy.h new file mode 100644 index 000000000..94a33f7b4 --- /dev/null +++ b/src/fl_oxy.h @@ -0,0 +1,40 @@ +// +// "Oxy" Scheme drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 2011 by Dmitrij K. e-mail: kdiman at live dot ru +// Copyright 2012-2022 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please report all bugs and problems on the following page: +// +// https://www.fltk.org/str.php +// + +#ifndef fl_oxy_h +#define fl_oxy_h + +#include + +// draw an arrow GUI element for the 'oxy' scheme +// bb bounding box +// t arrow type +// o orientation +// ac widget is active (true) or inactive (false) +// c arrow color +// hc "highlight" color + +extern FL_EXPORT void oxy_arrow(Fl_Rect bb, + Fl_Arrow_Type t, Fl_Orientation o, + bool ac, + Fl_Color c, Fl_Color hc = FL_BLACK); + +extern FL_EXPORT void oxy_arrow(Fl_Rect bb, + Fl_Arrow_Type t, Fl_Orientation o, + Fl_Color col); + +#endif // fl_oxy_h diff --git a/src/makedepend b/src/makedepend index cbfef9ce0..27151b7f3 100644 --- a/src/makedepend +++ b/src/makedepend @@ -1589,6 +1589,7 @@ fl_draw.o: ../FL/platform.H fl_draw.o: ../FL/platform_types.h fl_draw.o: ../FL/x11.H fl_draw.o: flstring.h +fl_draw.o: fl_oxy.h fl_draw_arrow.o: ../FL/Enumerations.H fl_draw_arrow.o: ../FL/Fl.H fl_draw_arrow.o: ../FL/Fl_Cairo.H @@ -1599,6 +1600,7 @@ fl_draw_arrow.o: ../FL/Fl_Export.H fl_draw_arrow.o: ../FL/fl_types.h fl_draw_arrow.o: ../FL/fl_utf8.h fl_draw_arrow.o: ../FL/platform_types.h +fl_draw_arrow.o: fl_oxy.h fl_draw_pixmap.o: ../config.h fl_draw_pixmap.o: ../FL/Enumerations.H fl_draw_pixmap.o: ../FL/filename.H @@ -2536,6 +2538,7 @@ Fl_Menu_Button.o: ../FL/Fl_Image.H Fl_Menu_Button.o: ../FL/Fl_Menu_.H Fl_Menu_Button.o: ../FL/Fl_Menu_Button.H Fl_Menu_Button.o: ../FL/Fl_Menu_Item.H +Fl_Menu_Button.o: ../FL/Fl_Rect.H Fl_Menu_Button.o: ../FL/fl_types.h Fl_Menu_Button.o: ../FL/fl_utf8.h Fl_Menu_Button.o: ../FL/Fl_Widget.H @@ -2909,6 +2912,19 @@ Fl_own_colormap.o: ../FL/Fl_Valuator.H Fl_own_colormap.o: ../FL/Fl_Widget.H Fl_own_colormap.o: ../FL/platform_types.h Fl_own_colormap.o: Fl_Screen_Driver.H +fl_oxy.o: ../FL/Enumerations.H +fl_oxy.o: ../FL/Fl.H +fl_oxy.o: ../FL/Fl_Cairo.H +fl_oxy.o: ../FL/fl_casts.H +fl_oxy.o: ../FL/fl_config.h +fl_oxy.o: ../FL/fl_draw.H +fl_oxy.o: ../FL/Fl_Export.H +fl_oxy.o: ../FL/Fl_Rect.H +fl_oxy.o: ../FL/fl_types.h +fl_oxy.o: ../FL/fl_utf8.h +fl_oxy.o: ../FL/Fl_Widget.H +fl_oxy.o: ../FL/platform_types.h +fl_oxy.o: fl_oxy.h Fl_Pack.o: ../FL/Enumerations.H Fl_Pack.o: ../FL/Fl.H Fl_Pack.o: ../FL/Fl_Cairo.H -- cgit v1.2.3