summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2023-10-16 10:53:18 +0200
committerAlbrecht Schlosser <albrechts.fltk@online.de>2023-10-16 13:33:40 +0200
commit6ba7b49baf11e526d1ed19aef491db2cd120e55e (patch)
tree1a13b19b4496ccc4d7552e7fc80a8f9234808e31
parentda5331b59210769b4e15f24a0b5237a7ec5bfc4d (diff)
Improve subclassing cababilities of Fl_Tile (STR 2791)
- remove static variables and functions - make move_intersection() virtual - add (protected) cursor access methods These changes were inspired by STR 2791 where the user proposing an enhancement was not able to subclass Fl_Tile properly. This commit fixes the mentioned issues and enables subclassing without copying internal code.
-rw-r--r--FL/Fl_Tile.H20
-rw-r--r--src/Fl_Tile.cxx66
-rw-r--r--test/tile.cxx17
3 files changed, 67 insertions, 36 deletions
diff --git a/FL/Fl_Tile.H b/FL/Fl_Tile.H
index af104a4eb..a7de02fea 100644
--- a/FL/Fl_Tile.H
+++ b/FL/Fl_Tile.H
@@ -1,7 +1,7 @@
//
// Tile header file for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2016 by Bill Spitzak and others.
+// Copyright 1998-2023 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
@@ -29,10 +29,24 @@ public:
int handle(int event) FL_OVERRIDE;
Fl_Tile(int X, int Y, int W, int H, const char *L=0);
void resize(int X, int Y, int W, int H) FL_OVERRIDE;
- void move_intersection(int oldx, int oldy, int newx, int newy);
+ virtual void move_intersection(int oldx, int oldy, int newx, int newy);
FL_DEPRECATED("in 1.4.0 - use move_intersection(p) instead",
- void position(int oldx, int oldy, int newx, int newy)) { return move_intersection(oldx, oldy, newx, newy); }
+ void position(int oldx, int oldy, int newx, int newy)) { move_intersection(oldx, oldy, newx, newy); }
void position(int x, int y) { Fl_Group::position(x, y); }
+
+protected:
+ int cursor_; ///< current cursor index (0..3)
+ Fl_Cursor *cursors_; ///< points at the array of 4 cursors (may be overridden)
+
+ /** Returns the cursor for cursor index n.
+ \see Fl_Tile::set_cursor(int)
+ */
+
+ Fl_Cursor cursor(int n) {
+ return cursors_[n];
+ }
+
+ void set_cursor(int n); // set one of n (0..3) cursors
};
#endif
diff --git a/src/Fl_Tile.cxx b/src/Fl_Tile.cxx
index a5de6039d..5c238e487 100644
--- a/src/Fl_Tile.cxx
+++ b/src/Fl_Tile.cxx
@@ -87,6 +87,13 @@
#include <FL/Fl_Rect.H>
#include <stdlib.h>
+static Fl_Cursor Fl_Tile_cursors[4] = {
+ FL_CURSOR_DEFAULT, // 0 normal
+ FL_CURSOR_WE, // 1 drag horizontally
+ FL_CURSOR_NS, // 2 drag vertically
+ FL_CURSOR_MOVE // 3 move intersection
+};
+
/**
Drags the intersection at (\p oldx,\p oldy) to (\p newx,\p newy).
This redraws all the necessary children.
@@ -173,30 +180,33 @@ void Fl_Tile::resize(int X,int Y,int W,int H) {
}
}
-static void set_cursor(Fl_Tile*t, Fl_Cursor c) {
- static Fl_Cursor cursor;
- if (cursor == c || !t->window()) return;
- cursor = c;
-#ifdef __sgi
- t->window()->cursor(c,FL_RED,FL_WHITE);
-#else
- t->window()->cursor(c);
-#endif
+/**
+ Set one of four cursors used for dragging etc..
+
+ Fl_Tile uses an array of four cursors that are set depending on user actions:
+ - 0: normal cursor
+ - 1: horizontal dragging
+ - 2: vertical dragging
+ - 3: dragging an intersection
+
+ This method sets the window cursor for the given index \p n.
+*/
+void Fl_Tile::set_cursor(int n) {
+ if (n < 0 || n > 3) n = 0; // check array index
+ cursor_ = n; // always store the index
+ if (cursor_ == n || !window())
+ return;
+ window()->cursor(cursor(n));
}
-static Fl_Cursor cursors[4] = {
- FL_CURSOR_DEFAULT,
- FL_CURSOR_WE,
- FL_CURSOR_NS,
- FL_CURSOR_MOVE};
+#define DRAGH 1
+#define DRAGV 2
+#define GRABAREA 4
int Fl_Tile::handle(int event) {
static int sdrag;
static int sdx, sdy;
static int sx, sy;
-#define DRAGH 1
-#define DRAGV 2
-#define GRABAREA 4
int mx = Fl::event_x();
int my = Fl::event_y();
@@ -239,13 +249,13 @@ int Fl_Tile::handle(int event) {
sdrag = 0; sx = sy = 0;
if (mindx <= GRABAREA) {sdrag = DRAGH; sx = oldx;}
if (mindy <= GRABAREA) {sdrag |= DRAGV; sy = oldy;}
- set_cursor(this, cursors[sdrag]);
+ set_cursor(sdrag);
if (sdrag) return 1;
return Fl_Group::handle(event);
}
case FL_LEAVE:
- set_cursor(this, FL_CURSOR_DEFAULT);
+ set_cursor(0); // set default cursor
break;
case FL_DRAG:
@@ -264,10 +274,13 @@ int Fl_Tile::handle(int event) {
int newy;
if (sdrag&DRAGV) {
newy = Fl::event_y()-sdy;
- if (newy < r->y()) newy = r->y();
- else if (newy > r->y()+r->h()) newy = r->y()+r->h();
- } else
+ if (newy < r->y())
+ newy = r->y();
+ else if (newy > r->y()+r->h())
+ newy = r->y()+r->h();
+ } else {
newy = sy;
+ }
move_intersection(sx, sy, newx, newy);
if (event == FL_DRAG) {
set_changed();
@@ -275,9 +288,10 @@ int Fl_Tile::handle(int event) {
} else {
do_callback(FL_REASON_CHANGED);
}
- return 1;}
+ return 1;
+ } // case FL_RELEASE
- }
+ } // switch()
return Fl_Group::handle(event);
}
@@ -297,6 +311,8 @@ int Fl_Tile::handle(int event) {
*/
Fl_Tile::Fl_Tile(int X,int Y,int W,int H,const char*L)
-: Fl_Group(X,Y,W,H,L)
+: Fl_Group(X,Y,W,H,L),
+ cursor_(0),
+ cursors_(Fl_Tile_cursors)
{
}
diff --git a/test/tile.cxx b/test/tile.cxx
index 2b6485ef2..e8b1d6318 100644
--- a/test/tile.cxx
+++ b/test/tile.cxx
@@ -1,7 +1,7 @@
//
// Fl_Tile test program for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2016 by Bill Spitzak and others.
+// Copyright 1998-2023 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
@@ -19,18 +19,19 @@
#include <FL/Fl_Tile.H>
#include <FL/Fl_Box.H>
-//#define TEST_INACTIVE
+// #define TEST_INACTIVE
int main(int argc, char** argv) {
- Fl_Double_Window window(300,300);
+ Fl_Double_Window window(300, 300);
window.box(FL_NO_BOX);
window.resizable(window);
- int dx = 20, dy = dx; // border width of resizable() - see below
- Fl_Tile tile(0,0,300,300);
+ Fl_Tile tile(0, 0, 300, 300);
// create the symmetrical resize box with dx and dy pixels distance, resp.
// from the borders of the Fl_Tile widget before all other children
+
+ int dx = 20, dy = dx; // border width of resizable()
Fl_Box r(tile.x()+dx,tile.y()+dy,tile.w()-2*dx,tile.h()-2*dy);
tile.resizable(r);
@@ -62,9 +63,9 @@ int main(int argc, char** argv) {
box2b.color(13);
box2b.labelsize(36);
box2b.align(FL_ALIGN_CLIP);
- //tile2.end();
+ // tile2.end();
- //Fl_Tile tile3(150,150,150,150);
+ // Fl_Tile tile3(150,150,150,150);
Fl_Box box3a(150,150,150,70,"3a");
box3a.box(FL_DOWN_BOX);
box3a.color(12);
@@ -76,7 +77,7 @@ int main(int argc, char** argv) {
box3b.color(13);
box3b.labelsize(36);
box3b.align(FL_ALIGN_CLIP);
- //tile3.end();
+ // tile3.end();
tile.end();
window.end();