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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
|
//
// Menu type header file for the Fast Light Tool Kit (FLTK).
//
// Type for creating all subclasses of Fl_Widget
// This should have the widget pointer in it, but it is still in the
// Fl_Type base class.
//
// 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
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#ifndef _FLUID_FL_MENU_TYPE_H
#define _FLUID_FL_MENU_TYPE_H
#include "Fl_Button_Type.h"
#include "Fd_Snap_Action.h"
#include <FL/Fl_Choice.H>
#include <FL/Fl_Menu_.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Input_Choice.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Menu_Bar.H>
extern Fl_Menu_Item dummymenu[];
extern Fl_Menu_Item button_type_menu[];
extern Fl_Menu_Item menu_item_type_menu[];
/**
\brief Manage all types on menu items.
Deriving Fl_Menu_Item_Type from Fl_Button_Type is intentional. For the purpose
of editing, a Menu Item is implemented with `o` pointing to an Fl_Button for
holding all properties.
*/
class Fl_Menu_Item_Type : public Fl_Button_Type
{
typedef Fl_Button_Type super;
public:
Fl_Menu_Item* subtypes() FL_OVERRIDE {return menu_item_type_menu;}
const char* type_name() FL_OVERRIDE {return "MenuItem";}
const char* alt_type_name() FL_OVERRIDE {return "fltk::Item";}
Fl_Type* make(Strategy strategy) FL_OVERRIDE;
int is_button() const FL_OVERRIDE {return 1;} // this gets shortcut to work
Fl_Widget* widget(int,int,int,int) FL_OVERRIDE {return 0;}
Fl_Widget_Type* _make() FL_OVERRIDE {return 0;}
virtual const char* menu_name(Fd_Code_Writer& f, int& i);
int flags();
void write_static(Fd_Code_Writer& f) FL_OVERRIDE;
void write_item(Fd_Code_Writer& f);
void write_code1(Fd_Code_Writer& f) FL_OVERRIDE;
void write_code2(Fd_Code_Writer& f) FL_OVERRIDE;
int is_true_widget() const FL_OVERRIDE { return 0; }
ID id() const FL_OVERRIDE { return ID_Menu_Item; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Item) ? true : super::is_a(inID); }
};
/**
\brief Manage Radio style Menu Items.
*/
class Fl_Radio_Menu_Item_Type : public Fl_Menu_Item_Type
{
typedef Fl_Menu_Item_Type super;
public:
const char* type_name() FL_OVERRIDE {return "RadioMenuItem";}
Fl_Type* make(Strategy strategy) FL_OVERRIDE;
ID id() const FL_OVERRIDE { return ID_Radio_Menu_Item; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Radio_Menu_Item) ? true : super::is_a(inID); }
};
/**
\brief Manage Checkbox style Menu Items.
*/
class Fl_Checkbox_Menu_Item_Type : public Fl_Menu_Item_Type
{
typedef Fl_Menu_Item_Type super;
public:
const char* type_name() FL_OVERRIDE {return "CheckMenuItem";}
Fl_Type* make(Strategy strategy) FL_OVERRIDE;
ID id() const FL_OVERRIDE { return ID_Checkbox_Menu_Item; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Checkbox_Menu_Item) ? true : super::is_a(inID); }
};
/**
\brief Manage Submenu style Menu Items.
Submenu Items are simply buttons just like all other menu items, but they
can also hold a pointer to a list of submenus, or have a flag set that
allows submenus to follow in the current array. As buttons, they can
be clicked by the user, and they will call their callback, if one is set.
*/
class Fl_Submenu_Type : public Fl_Menu_Item_Type
{
typedef Fl_Menu_Item_Type super;
public:
Fl_Menu_Item* subtypes() FL_OVERRIDE {return 0;}
const char* type_name() FL_OVERRIDE {return "Submenu";}
const char* alt_type_name() FL_OVERRIDE {return "fltk::ItemGroup";}
int is_parent() const FL_OVERRIDE {return 1;}
int is_button() const FL_OVERRIDE {return 0;} // disable shortcut
Fl_Type* make(Strategy strategy) FL_OVERRIDE;
// changes to submenu must propagate up so build_menu is called
// on the parent Fl_Menu_Type:
void add_child(Fl_Type*a, Fl_Type*b) FL_OVERRIDE {parent->add_child(a,b);}
void move_child(Fl_Type*a, Fl_Type*b) FL_OVERRIDE {parent->move_child(a,b);}
void remove_child(Fl_Type*a) FL_OVERRIDE {parent->remove_child(a);}
ID id() const FL_OVERRIDE { return ID_Submenu; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Submenu) ? true : super::is_a(inID); }
};
// -----------------------------------------------------------------------------
/**
\brief Base class for all widgets that can have a pulldown menu attached.
Widgets with this type can be derived from Fl_Menu_ or from
Fl_Group (Fl_Input_Choice).
*/
class Fl_Menu_Manager_Type : public Fl_Widget_Type
{
typedef Fl_Widget_Type super;
public:
void ideal_size(int &w, int &h) FL_OVERRIDE {
h = layout->textsize_not_null() + 8;
w = layout->textsize_not_null() * 6 + 8;
Fd_Snap_Action::better_size(w, h);
}
int is_parent() const FL_OVERRIDE {return 1;}
int menusize;
virtual void build_menu() = 0;
Fl_Menu_Manager_Type() : Fl_Widget_Type() {menusize = 0;}
void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE { build_menu(); }
void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE { build_menu(); }
void remove_child(Fl_Type*) FL_OVERRIDE { build_menu();}
Fl_Type* click_test(int x, int y) FL_OVERRIDE = 0;
void write_code2(Fd_Code_Writer& f) FL_OVERRIDE;
void copy_properties() FL_OVERRIDE = 0;
ID id() const FL_OVERRIDE { return ID_Menu_Manager_; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Manager_) ? true : super::is_a(inID); }
};
/**
\brief Manage the composite widget Input Choice.
\note Input Choice is a composite window, so `o` will be pointing to a widget
derived from Fl_Group. All menu related methods from Fl_Menu_Trait_Type must
be virtual and must be reimplemented here (click_test, build_menu, textstuff).
*/
class Fl_Input_Choice_Type : public Fl_Menu_Manager_Type
{
typedef Fl_Menu_Manager_Type super;
int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
Fl_Input_Choice *myo = (Fl_Input_Choice*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
switch (w) {
case 4:
case 0: f = (Fl_Font)myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
case 1: myo->textfont(f); break;
case 2: myo->textsize(s); break;
case 3: myo->textcolor(c); break;
}
return 1;
}
public:
~Fl_Input_Choice_Type() {
if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Input_Choice*)o)->menu());
}
const char *type_name() FL_OVERRIDE {return "Fl_Input_Choice";}
const char *alt_type_name() FL_OVERRIDE {return "fltk::ComboBox";}
Fl_Type* click_test(int,int) FL_OVERRIDE;
Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
Fl_Input_Choice *myo = new Fl_Input_Choice(X,Y,W,H,"input choice:");
myo->menu(dummymenu);
myo->value("input");
return myo;
}
Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Input_Choice_Type();}
void build_menu() FL_OVERRIDE;
ID id() const FL_OVERRIDE { return ID_Input_Choice; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Input_Choice) ? true : super::is_a(inID); }
void copy_properties() FL_OVERRIDE;
};
/**
\brief Base class to handle widgets that are derived from Fl_Menu_.
*/
class Fl_Menu_Base_Type : public Fl_Menu_Manager_Type
{
typedef Fl_Menu_Manager_Type super;
int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
Fl_Menu_ *myo = (Fl_Menu_*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
case 1: myo->textfont(f); break;
case 2: myo->textsize(s); break;
case 3: myo->textcolor(c); break;
}
return 1;
}
public:
int is_parent() const FL_OVERRIDE {return 1;}
void build_menu() FL_OVERRIDE;
~Fl_Menu_Base_Type() {
if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Menu_*)o)->menu());
}
Fl_Type* click_test(int x, int y) FL_OVERRIDE;
void copy_properties() FL_OVERRIDE;
ID id() const FL_OVERRIDE { return ID_Menu_; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_) ? true : super::is_a(inID); }
};
extern Fl_Menu_Item button_type_menu[];
/**
\brief Make Menu Button widgets.
*/
class Fl_Menu_Button_Type : public Fl_Menu_Base_Type
{
typedef Fl_Menu_Base_Type super;
Fl_Menu_Item *subtypes() FL_OVERRIDE {return button_type_menu;}
public:
const char *type_name() FL_OVERRIDE {return "Fl_Menu_Button";}
const char *alt_type_name() FL_OVERRIDE {return "fltk::MenuButton";}
Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
return new Fl_Menu_Button(X,Y,W,H,"menu");}
Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Menu_Button_Type();}
ID id() const FL_OVERRIDE { return ID_Menu_Button; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Button) ? true : super::is_a(inID); }
};
/**
\brief Manage Choice type menu widgets.
*/
class Fl_Choice_Type : public Fl_Menu_Base_Type
{
typedef Fl_Menu_Base_Type super;
public:
const char *type_name() FL_OVERRIDE {return "Fl_Choice";}
const char *alt_type_name() FL_OVERRIDE {return "fltk::Choice";}
Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
Fl_Choice *myo = new Fl_Choice(X,Y,W,H,"choice:");
myo->menu(dummymenu);
return myo;
}
Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Choice_Type();}
ID id() const FL_OVERRIDE { return ID_Choice; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Choice) ? true : super::is_a(inID); }
};
/**
\brief Manage Menubar widgets.
*/
class Fl_Menu_Bar_Type : public Fl_Menu_Base_Type
{
typedef Fl_Menu_Base_Type super;
public:
const char *type_name() FL_OVERRIDE {return "Fl_Menu_Bar";}
const char *alt_type_name() FL_OVERRIDE {return "fltk::MenuBar";}
Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {return new Fl_Menu_Bar(X,Y,W,H);}
Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Menu_Bar_Type();}
ID id() const FL_OVERRIDE { return ID_Menu_Bar; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Bar) ? true : super::is_a(inID); }
};
#endif // _FLUID_FL_MENU_TYPE_H
|