-
Notifications
You must be signed in to change notification settings - Fork 1
/
resizebar.h
143 lines (137 loc) · 5.67 KB
/
resizebar.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#pragma once
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>
namespace fltklayout {
// based on erco horizontal resizer bar widget
// http://seriss.com/people/erco/fltk/#ResizerBar
class VerticalResizerBar : public Fl_Box {
int last_y;
int min_h; // min height for widget above us
void HandleDrag(int diff) {
Fl_Scroll *grp=(Fl_Scroll*)parent();
int top=y();
int bot=y()+h();
// First pass: find widget directly above us with common edge
// Possibly clamp 'diff' if widget would get too small..
//
for (int t=0; t<grp->children(); t++) {
Fl_Widget *w=grp->child(t);
if (diff<0 && w->y()+w->h() == top) { // found widget directly above?
if (w->h()+diff < min_h) diff=w->h()-min_h; // clamp
break; // done with first pass
} else if (diff>0 && w->y() == bot) { // found widget directly below?
if (w->h()-diff < min_h) diff=w->h()-min_h; // clamp
break; // done with first pass
}
}
// Second pass: find widgets below us, move based on clamped diff
for (int t=0; t<grp->children(); t++) {
Fl_Widget *w=grp->child(t);
if (w->y()+w->h() == top) // found widget directly above?
w->resize(w->x(), w->y(), w->w(), w->h()+diff); // change height
else if (w->y() == bot) // found widget below us?
w->resize(w->x(), w->y()+diff, w->w(), w->h()-diff); // change height
}
// Change our position last
resize(x(),y()+diff,w(),h());
grp->init_sizes();
grp->redraw();
}
public:
VerticalResizerBar(int X,int Y,int W,int H,const char *l) : Fl_Box(X,Y,W,H,"///////") {
last_y=0;
min_h=5;
// align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
// labelfont(FL_COURIER);
// labelsize(H);
visible_focus(0);
box(FL_FLAT_BOX);
}
void SetMinHeight(int val) { min_h=val; }
int GetMinHeight() const { return min_h; }
int handle(int e) {
int ret=0;
int this_y=Fl::event_y_root();
switch (e) {
case FL_FOCUS: ret=1; break;
case FL_ENTER: ret=1; fl_cursor(FL_CURSOR_NS); break;
case FL_LEAVE: ret=1; fl_cursor(FL_CURSOR_DEFAULT); break;
case FL_PUSH: ret=1; last_y=this_y; break;
case FL_DRAG:
HandleDrag(this_y-last_y);
last_y=this_y;
ret=1;
break;
default: break;
}
return(Fl_Box::handle(e) | ret);
}
};
class HorizontalResizerBar : public Fl_Box {
int orig_w;
int last_x;
int min_w; // min height for widget above us
void HandleDrag(int diff) {
Fl_Scroll *grp=(Fl_Scroll*)parent();
int left=x();
int right=x()+w();
// First pass: find widget directly above us with common edge
// Possibly clamp 'diff' if widget would get too small..
//
for (int t=0; t<grp->children(); t++) {
Fl_Widget *w=grp->child(t);
if (diff<0 && w->x()+w->w()==left) { // found widget directly to left?
if (w->w()+diff<min_w) diff=w->w()-min_w; // clamp
break; // done with first pass
} else if (diff>0 && w->x()==right) { // found widget directly to right?
if (w->w()-diff<min_w) diff=w->w()-min_w; // clamp
break; // done with first pass
}
}
// Second pass: find widgets to right of us, move based on clamped diff
for (int t=0; t<grp->children(); t++) {
Fl_Widget *w=grp->child(t);
if (w->x()+w->w() == left) // found widget directly to left?
w->resize(w->x(), w->y(), w->w()+diff, w->h()); // change width
else if (w->x() == right) // found widget below us?
w->resize(w->x()+diff, w->y(), w->w()-diff, w->h()); // change width
}
// Change our position last
resize(x()+diff,y(),w(),h());
grp->init_sizes();
grp->redraw();
}
public:
HorizontalResizerBar(int X,int Y,int W,int H,const char *l) : Fl_Box(X,Y,W,H,"///////") {
last_x=0;
min_w=5;
// align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
// labelfont(FL_COURIER);
// labelsize(H);
visible_focus(0);
box(FL_FLAT_BOX);
}
void SetMinWidth(int val) { min_w=val; }
int GetMinWidth() const { return min_w; }
int handle(int e) {
int ret=0;
int this_x=Fl::event_x_root();
switch (e) {
case FL_FOCUS: ret=1; break;
case FL_ENTER: ret=1; fl_cursor(FL_CURSOR_WE); break;
case FL_LEAVE: ret=1; fl_cursor(FL_CURSOR_DEFAULT); break;
case FL_PUSH: ret=1; last_x=this_x; break;
case FL_DRAG:
HandleDrag(this_x-last_x);
last_x=this_x;
ret=1;
break;
default: break;
}
return(Fl_Box::handle(e) | ret);
}
};
} // namespace fltklayout