summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fl_gleam.cxx136
1 files changed, 93 insertions, 43 deletions
diff --git a/src/fl_gleam.cxx b/src/fl_gleam.cxx
index 087f4baf4..010b50a8a 100644
--- a/src/fl_gleam.cxx
+++ b/src/fl_gleam.cxx
@@ -1,9 +1,9 @@
//
// "$Id$"
//
-// "Gleam" drawing routines for the Fast Light Tool Kit (FLTK).
+// "Gleam" scheme box drawing routines for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2018 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
@@ -22,97 +22,148 @@
//
// Modified 2012-2013 by Edmanuel Torres
// This is a new version of the fl_gleam. The gradients are on the top
-// an the bottom, the text area looks like in the classic FLTK way.
+// and the bottom, the text area looks like in the classic FLTK way.
//
#include <FL/Fl.H>
#include <FL/fl_draw.H>
+/*
+ Implementation notes:
+
+ All box types have 2 pixel wide borders, there is no distinction
+ of "thin" box types, hence Fl::box_dx() = Fl::box_dy() = 2,
+ Fl::box_dw() = Fl::box_dh() = 4 for all box types.
+
+ All coordinates of function calls (x, y, w, h) describe the full
+ box size with borders, i.e. the original box coordinates.
+ The interior (background) of the box is drawn with reduced size.
+ This is adjusted only in function shade_rect_top_bottom().
+
+ Note: There is one pixel "leaking" out of the box border at each
+ corner which is currently not drawn in a full box redraw.
+*/
+
+// Standard box drawing code
static void gleam_color(Fl_Color c) {
Fl::set_box_color(c);
}
+/* Draw the shaded background of the box.
+
+ This is called before the box frame (border) is drawn.
+ The interior of the box (shaded background) should be inset by two
+ pixels, hence width and height should be reduced by 4 (border size).
+ Since not all pixels of the border are drawn (border lines are shorter
+ by one or two pixels on each side) setting other offsets (+1, -2 instead
+ of +2, -4) would leak the box background color instead of the parent
+ widget's background color.
+ Note: the original implementation was maybe equivalent to using +1 and -2
+ for offset and width, respectively instead of +2 and -4. It is not clear
+ whether this was intended or by accident.
+*/
+
static void shade_rect_top_bottom(int x, int y, int w, int h, Fl_Color fg1, Fl_Color fg2, float th) {
- // Draws the shiny using maximum limits
- int h_top = ((h/2) < (20) ? (h/2) : (20)); // min(h/2,20);
- int h_bottom = ((h/6) < (15) ? (h/6) : (15)); // min(h/6,15);
- int h_flat = h-(h_top+h_bottom);
- int j = 0;
- float step_size_top = h_top>1?(0.999f/(float)(h_top)):1;
- float step_size_bottom = h_bottom>1?(0.999f/(float)(h_bottom)):1;
- // This loop generates the gradient at the top of the widget
- for (float k = 1; k >= 0; k -= step_size_top){
+ // calculate background size w/o borders
+ x += 2; y += 2; w -= 4; h -= 4;
+ // draw the shiny background using maximum limits
+ int h_top = ((h/2) < (20) ? (h/2) : (20)); // min(h/2, 20);
+ int h_bottom = ((h/6) < (15) ? (h/6) : (15)); // min(h/6, 15);
+ int h_flat = h - h_top - h_bottom;
+ float step_size_top = h_top > 1 ? (0.999f/float(h_top)) : 1;
+ float step_size_bottom = h_bottom > 1 ? (0.999f/float(h_bottom)) : 1;
+ // draw the gradient at the top of the widget
+ float k = 1;
+ for (int i = 0; i < h_top; i++, k -= step_size_top) {
gleam_color(fl_color_average(fl_color_average(fg1, fg2, th), fg1, k));
- fl_xyline(x, y+j, x+w);
- j++;
+ fl_xyline(x, y+i, x+w-1);
}
+
+ // draw a "flat" rectangle in the middle area of the box
gleam_color(fg1);
- fl_rectf(x, y+h_top, w+1, h_flat);
- // This loop generates the gradient at the bottom of the widget
- for (float k = 1; k >= 0; k -= step_size_bottom){
- gleam_color(fl_color_average(fg1,fl_color_average(fg1, fg2, th), k));
- fl_xyline(x, y+j+h_flat-1, x+w);
- j++;
+ fl_rectf(x, y + h_top, w, h_flat);
+
+ // draw the gradient at the bottom of the widget
+ k = 1;
+ for (int i = 0; i < h_bottom; i++, k -= step_size_bottom) {
+ gleam_color(fl_color_average(fg1, fl_color_average(fg1, fg2, th), k));
+ fl_xyline(x, y+h_top+h_flat+i, x+w-1);
}
}
+// See shade_rect_top_bottom()
static void shade_rect_top_bottom_up(int x, int y, int w, int h, Fl_Color bc, float th) {
- shade_rect_top_bottom(x,y,w,h,bc,FL_WHITE,th);
+ shade_rect_top_bottom(x, y, w, h, bc, FL_WHITE, th);
}
+// See shade_rect_top_bottom()
static void shade_rect_top_bottom_down(int x, int y, int w, int h, Fl_Color bc, float th) {
- shade_rect_top_bottom(x,y,w,h,bc,FL_BLACK,th);
+ shade_rect_top_bottom(x, y, w, h, bc, FL_BLACK, th);
}
+// Draw box borders. Color arguments:
+// - fg1: outer border line (left, right, top, bottom)
+// - fg2: inner border line (left, right)
+// - lc : inner border line (top, bottom)
+
static void frame_rect(int x, int y, int w, int h, Fl_Color fg1, Fl_Color fg2, Fl_Color lc) {
+ // outer border line:
gleam_color(fg1);
- fl_yxline(x, y+h-1, y+1); //Go from bottom to top left side
- fl_yxline(x+w, y+h-1, y+1); //Go from bottom to top right side
- fl_xyline(x+1, y, x+w-1); //Go across the top
- fl_xyline(x+1, y+h, x+w-1); //Go across the bottom
+ fl_xyline(x+1, y, x+w-2); // top
+ fl_yxline(x+w-1, y+1, y+h-2); // right
+ fl_xyline(x+1, y+h-1, x+w-2); // bottom
+ fl_yxline(x, y+1, y+h-2); // left
+
+ // inner border line (left, right):
gleam_color(fg2);
- fl_yxline(x+1, y+h-2, y+2); //Go from bottom to top left side
- fl_yxline(x+w-1, y+h-2, y+2); //Go from bottom to top right side
+ fl_yxline(x+1, y+2, y+h-3); // left
+ fl_yxline(x+w-2, y+2, y+h-3); // right
+
+ // inner border line (top, bottom):
gleam_color(lc);
- fl_xyline(x+2, y+1, x+w-3); //Go across the top
- fl_xyline(x+2, y+h-1, x+w-3); //Go across the bottom
+ fl_xyline(x+2, y+1, x+w-3); // top
+ fl_xyline(x+2, y+h-2, x+w-3); // bottom
}
+// Draw box borders with different colors (up/down effect).
+
static void frame_rect_up(int x, int y, int w, int h, Fl_Color bc, Fl_Color lc, float th1, float th2) {
- frame_rect(x,y,w,h,fl_color_average(fl_darker(bc), FL_BLACK, th1),fl_color_average(bc, FL_WHITE, th2),lc);
+ frame_rect(x, y, w, h, fl_color_average(fl_darker(bc), FL_BLACK, th1), fl_color_average(bc, FL_WHITE, th2), lc);
}
static void frame_rect_down(int x, int y, int w, int h, Fl_Color bc, Fl_Color lc, float th1, float th2) {
- frame_rect(x,y,w,h,fl_color_average(bc, FL_WHITE, th1),fl_color_average(FL_BLACK, bc, th2),lc);
+ frame_rect(x,y,w,h,fl_color_average(bc, FL_WHITE, th1), fl_color_average(FL_BLACK, bc, th2), lc);
}
+// Draw the different box types. These are the actual box drawing functions.
+
static void up_frame(int x, int y, int w, int h, Fl_Color c) {
- frame_rect_up(x, y, w-1, h-1, c, fl_color_average(c, FL_WHITE, .25f), .55f, .05f);
+ frame_rect_up(x, y, w, h, c, fl_color_average(c, FL_WHITE, .25f), .55f, .05f);
}
static void up_box(int x, int y, int w, int h, Fl_Color c) {
- shade_rect_top_bottom_up(x+2, y+1, w-5, h-3, c, .15f);
- frame_rect_up(x, y, w-1, h-1, c, fl_color_average(c, FL_WHITE, .05f), .15f, .05f);
+ shade_rect_top_bottom_up(x, y, w, h, c, .15f);
+ frame_rect_up(x, y, w, h, c, fl_color_average(c, FL_WHITE, .05f), .15f, .05f);
}
static void thin_up_box(int x, int y, int w, int h, Fl_Color c) {
- shade_rect_top_bottom_up(x+2, y+1, w-5, h-3, c, .25f);
- frame_rect_up(x, y, w-1, h-1, c, fl_color_average(c, FL_WHITE, .45f), .25f, .15f);
+ shade_rect_top_bottom_up(x, y, w, h, c, .25f);
+ frame_rect_up(x, y, w, h, c, fl_color_average(c, FL_WHITE, .45f), .25f, .15f);
}
static void down_frame(int x, int y, int w, int h, Fl_Color c) {
- frame_rect_down(x, y, w-1, h-1, fl_darker(c), fl_darker(c), .25f, .95f);
+ frame_rect_down(x, y, w, h, fl_darker(c), fl_darker(c), .25f, .95f);
}
static void down_box(int x, int y, int w, int h, Fl_Color c) {
- shade_rect_top_bottom_down(x+1, y+1, w-3, h-3, c, .65f);
- frame_rect_down(x, y, w-1, h-1, c, fl_color_average(c, FL_BLACK, .05f), .05f, .95f);
+ shade_rect_top_bottom_down(x, y, w, h, c, .65f);
+ frame_rect_down(x, y, w, h, c, fl_color_average(c, FL_BLACK, .05f), .05f, .95f);
}
static void thin_down_box(int x, int y, int w, int h, Fl_Color c) {
- shade_rect_top_bottom_down(x+1, y+1, w-3, h-3, c, .85f);
- frame_rect_down(x, y, w-1, h-1, c, fl_color_average(c, FL_BLACK, .45f), .35f, 0.85f);
+ shade_rect_top_bottom_down(x, y, w, h, c, .85f);
+ frame_rect_down(x, y, w, h, c, fl_color_average(c, FL_BLACK, .45f), .35f, 0.85f);
}
extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
@@ -133,4 +184,3 @@ Fl_Boxtype fl_define_FL_GLEAM_UP_BOX() {
//
// End of "$Id$".
//
-