mirror of
https://github.com/fltk/fltk.git
synced 2026-05-28 11:25:22 +08:00
Optimize "arrow" drawing and centering
- center (sub)menu arrow as good as possible - adjust arrow sizes in Fl_Counter widget - refactor "oxy" arrow drawing and centering in widgets
This commit is contained in:
+1
-1
@@ -62,7 +62,7 @@ void Fl_Counter::arrow_widths(int &w1, int &w2) {
|
|||||||
w2 = w() * 17/100;
|
w2 = w() * 17/100;
|
||||||
}
|
}
|
||||||
// limit arrow box sizes to reserve more space for the text box
|
// limit arrow box sizes to reserve more space for the text box
|
||||||
if (w1 > 18) w1 = 18;
|
if (w1 > 13) w1 = 13;
|
||||||
if (w2 > 24) w2 = 24;
|
if (w2 > 24) w2 = 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -526,10 +526,10 @@ void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) {
|
|||||||
if (m->submenu()) {
|
if (m->submenu()) {
|
||||||
|
|
||||||
// calculate the bounding box of the submenu pointer (arrow)
|
// calculate the bounding box of the submenu pointer (arrow)
|
||||||
int sz = (hh-2) & -2;
|
int sz = ((hh-2) & (-2)) + 1 ; // must be odd for better centering
|
||||||
if (sz > 12) sz = 12; // limit arrow size => max(d) = (sz-2)/2 = 5
|
if (sz > 13) sz = 13; // limit arrow size
|
||||||
int x1 = xx + ww - sz - 2;
|
int x1 = xx + ww - sz - 2; // left border
|
||||||
int y1 = yy + (hh-sz)/2 + 1;
|
int y1 = yy + (hh-sz)/2 + 1; // top border
|
||||||
|
|
||||||
// draw an arrow whose style depends on the active scheme
|
// draw an arrow whose style depends on the active scheme
|
||||||
fl_draw_arrow(Fl_Rect(x1, y1, sz, sz), FL_ARROW_SINGLE, FL_ORIENT_RIGHT, fl_color());
|
fl_draw_arrow(Fl_Rect(x1, y1, sz, sz), FL_ARROW_SINGLE, FL_ORIENT_RIGHT, fl_color());
|
||||||
|
|||||||
+50
-44
@@ -2,7 +2,7 @@
|
|||||||
// "Oxy" Scheme drawing routines for the Fast Light Tool Kit (FLTK).
|
// "Oxy" Scheme drawing routines for the Fast Light Tool Kit (FLTK).
|
||||||
//
|
//
|
||||||
// Copyright 2011 by Dmitrij K. aka "kdiman"
|
// Copyright 2011 by Dmitrij K. aka "kdiman"
|
||||||
// Copyright 2012-2022 by Bill Spitzak and others.
|
// Copyright 2012-2024 by Bill Spitzak and others.
|
||||||
//
|
//
|
||||||
// This library is free software. Distribution and use rights are outlined in
|
// 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
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
@@ -20,66 +20,74 @@
|
|||||||
#include <FL/Fl_Rect.H>
|
#include <FL/Fl_Rect.H>
|
||||||
#include "fl_oxy.h"
|
#include "fl_oxy.h"
|
||||||
|
|
||||||
// Status of this scheme (to-do list):
|
// Note:
|
||||||
//
|
//
|
||||||
// This scheme works but is not yet perfect:
|
// Drawing on the X11 platform w/o Cairo can be asymmetric for some "arrows"
|
||||||
//
|
|
||||||
// (1) Drawing on the X11 platform (w/o Cairo) can be asymmetric for some "arrows"
|
|
||||||
// (2) Arrows are not always centered perfectly
|
|
||||||
|
|
||||||
#define GROFF 0.45f // gradients offset
|
#define GROFF 0.45f // gradients offset
|
||||||
|
|
||||||
// Draw a single arrow
|
#ifndef DEBUG_OXY_ARROW
|
||||||
static void single_arrow(Fl_Rect bb, Fl_Orientation o, Fl_Color col) {
|
#define DEBUG_OXY_ARROW 0 // 0 = off, 1 = cross at center position of arrows
|
||||||
|
#endif
|
||||||
|
|
||||||
fl_color(col);
|
// Draw a single arrow
|
||||||
fl_line_style(FL_SOLID, 1);
|
|
||||||
fl_push_matrix();
|
static void single_arrow(Fl_Rect bb, Fl_Orientation o, Fl_Color col) {
|
||||||
|
|
||||||
int x1 = bb.x();
|
int x1 = bb.x();
|
||||||
int y1 = bb.y();
|
int y1 = bb.y();
|
||||||
int w1 = bb.w();
|
int w1 = bb.w();
|
||||||
int h1 = bb.h();
|
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;
|
|
||||||
|
|
||||||
float angle = int(o) * 45.0f;
|
float angle = int(o) * 45.0f;
|
||||||
|
|
||||||
int tx = x1 + (w1 + 1)/2;
|
// calculate arrow size
|
||||||
int ty = y1 + (h1 + 1)/2;
|
int dx = (w1 - 3) / 2;
|
||||||
|
if (h1 < w1) dx = (h1 - 3) / 2;
|
||||||
|
if (dx > 4) dx = 4;
|
||||||
|
else if (dx < 2) dx = 2;
|
||||||
|
// dx = (dx + 1) & (-2); // should be even ? not required
|
||||||
|
|
||||||
const int lw = 2; // arrow line width: n means n+1 pixels
|
int tx = x1 + w1/2;
|
||||||
|
int ty = y1 + h1/2;
|
||||||
|
|
||||||
// define translation adjustments for easier maintenance
|
const int lw = 2; // arrow line width: n+1 pixels (must be even)
|
||||||
|
const int dw = 1; // half the line width
|
||||||
|
|
||||||
static int tr_x = 0;
|
fl_color(col);
|
||||||
static int tr_y = -1;
|
fl_line_style(FL_SOLID, 1);
|
||||||
|
fl_push_matrix();
|
||||||
|
|
||||||
if (o == FL_ORIENT_LEFT)
|
fl_translate(tx, ty); // move to center
|
||||||
tr_x = 2;
|
fl_rotate(angle); // rotate by given angle
|
||||||
|
|
||||||
if (o & 2) // up or down arrow
|
// DEBUG: Draw a two-colored cross at the center of the arrow box
|
||||||
fl_translate(tx, ty - (lw+1)/2 + tr_y);
|
// This can be used to debug or adjust array alignment (centering)
|
||||||
else // left or right arrow
|
|
||||||
fl_translate(tx - lw/2 + tr_x, ty);
|
|
||||||
|
|
||||||
fl_rotate(angle);
|
#if (DEBUG_OXY_ARROW) // draw a cross at the center
|
||||||
|
int ll; // line length
|
||||||
|
fl_color(FL_BLUE); // "horizontal" line
|
||||||
|
ll = (o&2) ? h1/2 - 1 : w1/2 - 1; // line length
|
||||||
|
fl_begin_line();
|
||||||
|
fl_vertex(-ll, 0); fl_vertex(ll, 0);
|
||||||
|
fl_end_line();
|
||||||
|
fl_color(0x22882200); // "vertical" line
|
||||||
|
ll = (o&2) ? w1/2 - 1 : h1/2 - 1; // line length
|
||||||
|
fl_begin_line();
|
||||||
|
fl_vertex(0, -ll); fl_vertex(0, ll);
|
||||||
|
fl_end_line();
|
||||||
|
fl_color(col); // back to original color
|
||||||
|
#endif
|
||||||
|
|
||||||
int x0 = (-dx)/2;
|
// Draw the "arrow", similar to '>' at the center of the box
|
||||||
|
|
||||||
fl_begin_complex_polygon();
|
fl_begin_complex_polygon();
|
||||||
|
fl_vertex(-dx + dw, -dx);
|
||||||
fl_vertex(x0, -dx);
|
fl_vertex( 0 + dw, 0);
|
||||||
fl_vertex(x0 + dx, 0);
|
fl_vertex(-dx + dw, dx);
|
||||||
fl_vertex(x0, dx);
|
fl_vertex(-dx + dw + lw, dx);
|
||||||
|
fl_vertex( 0 + dw + lw, 0);
|
||||||
fl_vertex(x0 + lw, dx);
|
fl_vertex(-dx + dw + lw, -dx);
|
||||||
fl_vertex(x0 + lw + dx, 0);
|
|
||||||
fl_vertex(x0 + lw, -dx);
|
|
||||||
|
|
||||||
fl_end_complex_polygon();
|
fl_end_complex_polygon();
|
||||||
|
|
||||||
fl_pop_matrix();
|
fl_pop_matrix();
|
||||||
@@ -105,14 +113,12 @@ void oxy_arrow(Fl_Rect bb, Fl_Arrow_Type t, Fl_Orientation o, Fl_Color col) {
|
|||||||
switch (int(o)) {
|
switch (int(o)) {
|
||||||
case FL_ORIENT_DOWN:
|
case FL_ORIENT_DOWN:
|
||||||
case FL_ORIENT_UP:
|
case FL_ORIENT_UP:
|
||||||
bb.y(bb.y() - 2); // shift upwards
|
|
||||||
bb.h(bb.h() - 4); // reduce size
|
bb.h(bb.h() - 4); // reduce size
|
||||||
single_arrow(bb, o, col);
|
single_arrow(bb, o, col);
|
||||||
bb.y(bb.y() + 4); // shift down
|
bb.y(bb.y() + 4); // shift down
|
||||||
single_arrow(bb, o, col);
|
single_arrow(bb, o, col);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bb.x(bb.x() - 1); // shift left
|
|
||||||
bb.w(bb.w() - 4); // reduce size
|
bb.w(bb.w() - 4); // reduce size
|
||||||
single_arrow(bb, o, col);
|
single_arrow(bb, o, col);
|
||||||
bb.x(bb.x() + 4); // shift right
|
bb.x(bb.x() + 4); // shift right
|
||||||
@@ -123,10 +129,10 @@ void oxy_arrow(Fl_Rect bb, Fl_Arrow_Type t, Fl_Orientation o, Fl_Color col) {
|
|||||||
|
|
||||||
case FL_ARROW_CHOICE:
|
case FL_ARROW_CHOICE:
|
||||||
|
|
||||||
// bb.y(bb.y() - 0); // don't shift upwards (was: -2)
|
bb.y(bb.y() - 1); // shift upwards
|
||||||
bb.h(bb.h() - 4); // reduce size
|
bb.h(bb.h() - 4); // reduce height
|
||||||
single_arrow(bb, FL_ORIENT_UP, col);
|
single_arrow(bb, FL_ORIENT_UP, col);
|
||||||
bb.y(bb.y() + 4); // shift down
|
bb.y(bb.y() + 6); // shift down
|
||||||
single_arrow(bb, FL_ORIENT_DOWN, col);
|
single_arrow(bb, FL_ORIENT_DOWN, col);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user