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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
// Fl_Widget.C
// fltk (Fast Light Tool Kit) version 0.99
// Copyright (C) 1998 Bill Spitzak
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Group.H>
////////////////////////////////////////////////////////////////
// for compatability with Forms, all widgets without callbacks are
// inserted into a "queue" when they are activated, and the forms
// compatability interaction functions (fl_do_events, etc) will
// read one widget at a time from this queue and return it:
const int QUEUE_SIZE = 20;
static Fl_Widget *obj_queue[QUEUE_SIZE];
static int obj_head, obj_tail;
void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) {
#if 0
// This is necessary for strict forms compatability but is confusing.
// Use the parent's callback if this widget does not have one.
for (Fl_Widget *p = o->parent(); p; p = p->parent())
if (p->callback() != default_callback) {
p->do_callback(o,v);
return;
}
#endif
obj_queue[obj_head++] = o;
if (obj_head >= QUEUE_SIZE) obj_head = 0;
if (obj_head == obj_tail) {
obj_tail++;
if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
}
}
Fl_Widget *Fl::readqueue() {
if (obj_tail==obj_head) return 0;
Fl_Widget *o = obj_queue[obj_tail++];
if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
return o;
}
////////////////////////////////////////////////////////////////
int Fl_Widget::handle(int) {return 0;}
Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {
x_ = X; y_ = Y; w_ = W; h_ = H;
label_.value = L;
label_.type = FL_NORMAL_LABEL;
label_.font = FL_HELVETICA;
label_.size = FL_NORMAL_SIZE;
label_.color = FL_BLACK;
callback_ = default_callback;
user_data_ = 0;
type_ = 0;
flags_ = 0;
damage_ = 0;
box_ = FL_NO_BOX;
color_ = FL_GRAY;
color2_ = FL_GRAY;
align_ = FL_ALIGN_CENTER;
when_ = FL_WHEN_RELEASE;
parent_ = 0;
if (Fl_Group::current()) Fl_Group::current()->add(this);
}
void Fl_Widget::resize(int X, int Y, int W, int H) {
x_ = X; y_ = Y; w_ = W; h_ = H;
}
// this is useful for parent widgets to call to resize children:
int Fl_Widget::damage_resize(int X, int Y, int W, int H) {
if (x() == X && y() == Y && w() == W && h() == H) return 0;
resize(X, Y, W, H);
redraw();
return 1;
}
int Fl_Widget::take_focus() {
if (!takesevents()) return 0;
if (!handle(FL_FOCUS)) return 0; // see if it wants it
if (contains(Fl::focus())) return 1; // it called Fl::focus for us
Fl::focus(this);
return 1;
}
extern void fl_throw_focus(Fl_Widget*); // in Fl_x.C
// Destruction does not remove from any parent group! And groups when
// destroyed destroy all their children. This is convienent and fast.
// However, it is only legal to destroy a "root" such as an Fl_Window,
// and automatic destructors may be called.
Fl_Widget::~Fl_Widget() {
parent_ = 0; // kludge to prevent ~Fl_Group from destroying again
fl_throw_focus(this);
}
// redraw this, plus redraw opaque object if there is an outside label
static void redraw_label(Fl_Widget* w) {
w->redraw();
if (w->label() && (w->align()&15) && !(w->align() & FL_ALIGN_INSIDE)) {
for (Fl_Widget *p = w->parent(); p; p = p->parent())
if (p->box() || !p->parent()) {p->redraw(); break;}
}
}
void Fl_Widget::activate() {
if (active()) return;
clear_flag(INACTIVE);
handle(FL_ACTIVATE);
if (inside(Fl::focus())) Fl::focus()->take_focus();
redraw_label(this);
}
void Fl_Widget::deactivate() {
if (!active()) return;
set_flag(INACTIVE);
handle(FL_DEACTIVATE);
fl_throw_focus(this);
redraw_label(this);
}
int Fl_Widget::active_r() const {
for (const Fl_Widget* o = this; o; o = o->parent())
if (!o->active()) return 0;
return 1;
}
void Fl_Widget::show() {
if (visible()) return;
clear_flag(INVISIBLE);
handle(FL_SHOW);
if (inside(Fl::focus())) Fl::focus()->take_focus();
redraw_label(this);
}
void Fl_Widget::hide() {
if (!visible()) return;
set_flag(INVISIBLE);
handle(FL_HIDE);
fl_throw_focus(this);
for (Fl_Widget *p = parent(); p; p = p->parent())
if (p->box() || !p->parent()) {p->redraw(); break;}
}
int Fl_Widget::visible_r() const {
for (const Fl_Widget* o = this; o; o = o->parent())
if (!o->visible()) return 0;
return 1;
}
// return true if widget is inside (or equal to) this:
// Returns false for null widgets.
int Fl_Widget::contains(const Fl_Widget *o) const {
for (; o; o = o->parent_) if (o == this) return 1;
return 0;
}
|