1 /********************************************************************************
2 * *
3 * Data Target Test *
4 * *
5 *********************************************************************************
6 * Copyright (C) 1997,2006 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * $Id: datatarget.cpp,v 1.49 2006/02/10 03:53:48 fox Exp $ *
9 ********************************************************************************/
10 #include "fx.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <sys/stat.h>
14 #include <signal.h>
15 #ifndef WIN32
16 #include <unistd.h>
17 #endif
18
19 /*******************************************************************************/
20
21
22 // Mini application object
23 class DataTargetWindow : public FXMainWindow {
24 FXDECLARE(DataTargetWindow)
25 protected:
26 FXMenuBar* menubar;
27 FXMenuPane* filemenu;
28 FXMenuPane* optionmenu;
29 FXPopup* popup;
30 FXMatrix* matrix;
31 FXint some_int;
32 FXdouble some_double;
33 FXint some_option;
34 FXString some_string;
35 FXColor some_color;
36 FXint some_progress;
37 FXDataTarget int_target;
38 FXDataTarget double_target;
39 FXDataTarget string_target;
40 FXDataTarget option_target;
41 FXDataTarget color_target;
42 FXDataTarget progress_target;
43 FXProgressDialog *progressdialog;
44 public:
45 long onCmdTimer(FXObject*,FXSelector,void*);
46 long onCmdQuit(FXObject*,FXSelector,void*);
47 long onCmdProgress(FXObject*,FXSelector,void*);
48 public:
DataTargetWindow()49 DataTargetWindow(){}
50 public:
51 enum {
52 ID_TIMER=FXMainWindow::ID_LAST,
53 ID_PROGRESS,
54 ID_QUIT
55 };
56 public:
57 DataTargetWindow(FXApp *a);
58 void create();
59 virtual ~DataTargetWindow();
60 };
61
62
63
64 /*******************************************************************************/
65
66 // Map
67 FXDEFMAP(DataTargetWindow) DataTargetWindowMap[]={
68 FXMAPFUNC(SEL_CLOSE, 0, DataTargetWindow::onCmdQuit),
69 FXMAPFUNC(SEL_SIGNAL, DataTargetWindow::ID_QUIT, DataTargetWindow::onCmdQuit),
70 FXMAPFUNC(SEL_TIMEOUT,DataTargetWindow::ID_TIMER, DataTargetWindow::onCmdTimer),
71 FXMAPFUNC(SEL_COMMAND,DataTargetWindow::ID_PROGRESS, DataTargetWindow::onCmdProgress),
72 };
73
74
75 // Object implementation
FXIMPLEMENT(DataTargetWindow,FXMainWindow,DataTargetWindowMap,ARRAYNUMBER (DataTargetWindowMap))76 FXIMPLEMENT(DataTargetWindow,FXMainWindow,DataTargetWindowMap,ARRAYNUMBER(DataTargetWindowMap))
77
78
79
80 // Make some windows
81 DataTargetWindow::DataTargetWindow(FXApp* a):FXMainWindow(a,"Data Target Test",NULL,NULL,DECOR_ALL,20,20,700,460){
82
83 // Initialize some simple variables
84 some_int = 10;
85 some_double = 3.1415927;
86 some_string = "FOX";
87 some_color = FXRGB(255,0,0);
88 some_option = 0;
89 some_progress = 0;
90
91
92 // Connect INTEGER target
93 int_target.connect(some_int);
94
95 // Connect DOUBLE target
96 double_target.connect(some_double);
97
98 // Connect STRING target
99 string_target.connect(some_string);
100
101 // Connect COLOR target
102 color_target.connect(some_color);
103
104 // Connect option target
105 option_target.connect(some_option);
106
107 // Connect progress target
108 progress_target.connect(some_progress);
109
110 // Create progress dialog
111 progressdialog=new FXProgressDialog(this,"Progress","We zijn druk, we zijn druk\nWe zijn ongelooflijk druk.",PROGRESSDIALOG_CANCEL|DECOR_BORDER|DECOR_RESIZE|DECOR_TITLE);
112 progressdialog->setTarget(&int_target);
113 progressdialog->setSelector(FXDataTarget::ID_VALUE);
114
115 // Menubar
116 menubar=new FXMenuBar(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
117
118 // File menu
119 filemenu=new FXMenuPane(this);
120 new FXMenuCommand(filemenu,"Progress dialog...",NULL,this,ID_PROGRESS);
121 new FXMenuCommand(filemenu,"&Quit\tCtl-Q",NULL,getApp(),FXApp::ID_QUIT);
122 new FXMenuTitle(menubar,"&File",NULL,filemenu);
123
124 // Option menu
125 optionmenu=new FXMenuPane(this);
126
127 // The menu radios change the "some_option" variable via the option_target
128 new FXMenuRadio(optionmenu,"Option 1",&option_target,FXDataTarget::ID_OPTION+0);
129 new FXMenuRadio(optionmenu,"Option 2",&option_target,FXDataTarget::ID_OPTION+1);
130 new FXMenuRadio(optionmenu,"Option 3",&option_target,FXDataTarget::ID_OPTION+2);
131 new FXMenuRadio(optionmenu,"Option 4",&option_target,FXDataTarget::ID_OPTION+3);
132
133 new FXMenuTitle(menubar,"&Option",NULL,optionmenu);
134
135
136 // Lone progress bar at the bottom, which reflects the value of variable "some_progress"
137 new FXProgressBar(this,&progress_target,FXDataTarget::ID_VALUE,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK);
138
139 new FXHorizontalSeparator(this,LAYOUT_SIDE_TOP|SEPARATOR_GROOVE|LAYOUT_FILL_X);
140
141 FXHorizontalFrame *horframe=new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
142
143 new FXLabel(horframe,
144 "FXDataTarget can be used to connect a Widget to an application variable without any of the\n"
145 "tradional \"glue\" programming code.\n\n"
146 "The widgets below are connected (via FXDataTarget) to an integer, real, string, option, and\n"
147 "color variable, respectively.\n\n"
148 "Changing one of them will cause all widgets connected to the same FXDataTarget to \n"
149 "update so as to reflect the value of the application variable.\n\n"
150 "The progress bar below shows a time-varying variable, demonstrating that widgets\n"
151 "can be updated via FXDataTarget's regardless how the variables are changed.\n\n"
152 "Note that the \"Option\" pulldown menu is also connected to the option variable!",
153 NULL,LAYOUT_LEFT|JUSTIFY_LEFT);
154
155 new FXProgressBar(horframe,&int_target,FXDataTarget::ID_VALUE,PROGRESSBAR_PERCENTAGE|PROGRESSBAR_DIAL|LAYOUT_RIGHT|LAYOUT_FILL_Y|LAYOUT_FILL_X);
156
157 new FXHorizontalSeparator(this,LAYOUT_SIDE_TOP|SEPARATOR_GROOVE|LAYOUT_FILL_X);
158 new FXSlider(this,&int_target,FXDataTarget::ID_VALUE,SLIDER_VERTICAL|SLIDER_INSIDE_BAR|LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH,0,0,20,0);
159
160 // Arange nicely
161 matrix=new FXMatrix(this,9,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
162
163 // First row
164 new FXLabel(matrix,"&Integer",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
165
166 // The value of variable "some_int" may be changed by any of these widgets below
167 new FXTextField(matrix,10,&int_target,FXDataTarget::ID_VALUE,TEXTFIELD_INTEGER|JUSTIFY_RIGHT|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
168 new FXTextField(matrix,10,&int_target,FXDataTarget::ID_VALUE,TEXTFIELD_INTEGER|JUSTIFY_RIGHT|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
169 new FXSlider(matrix,&int_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH,0,0,100);
170 new FXDial(matrix,&int_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH|DIAL_HORIZONTAL|DIAL_HAS_NOTCH,0,0,100);
171 new FXKnob(matrix,&int_target,FXDataTarget::ID_VALUE,KNOB_TICKS|LAYOUT_CENTER_Y|LAYOUT_CENTER_X);
172 new FXSpinner(matrix,5,&int_target,FXDataTarget::ID_VALUE,SPIN_CYCLIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW);
173 new FXProgressBar(matrix,&int_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|PROGRESSBAR_PERCENTAGE|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
174 FX7Segment *seven=new FX7Segment(matrix,FXString::null,SEVENSEGMENT_SHADOW|JUSTIFY_RIGHT|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW|LAYOUT_FILL_X);
175 seven->setTarget(&int_target);
176 seven->setSelector(FXDataTarget::ID_VALUE);
177
178
179 // Second row
180 new FXLabel(matrix,"&Real",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
181
182 // The value of variable "some_double" may be changed by the widgets below
183 new FXTextField(matrix,10,&double_target,FXDataTarget::ID_VALUE,TEXTFIELD_REAL|JUSTIFY_RIGHT|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
184 new FXTextField(matrix,10,&double_target,FXDataTarget::ID_VALUE,TEXTFIELD_REAL|JUSTIFY_RIGHT|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
185 FXRealSlider *rslider=new FXRealSlider(matrix,&double_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH,0,0,100);
186 rslider->setRange(0.0,10.0);
187 new FXDial(matrix,&double_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH|DIAL_HORIZONTAL|DIAL_HAS_NOTCH,0,0,100);
188
189 FXRealSpinner *rspinner=new FXRealSpinner(matrix,8,&double_target,FXDataTarget::ID_VALUE,REALSPIN_CYCLIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW);
190 rspinner->setRange(-10.0,10.0);
191 rspinner->setIncrement(0.01);
192 rspinner->setGranularity(0.01);
193 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
194 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
195 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
196
197 // Third row
198 new FXLabel(matrix,"&String",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
199
200 // The string variable "some_string" can be changed by these text fields
201 new FXTextField(matrix,10,&string_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
202 new FXTextField(matrix,10,&string_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
203 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
204 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
205 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
206 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
207 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
208 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
209
210 // Fourth row
211 new FXLabel(matrix,"&Option",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
212
213 // The variable "some_option" is changed by the following widgets
214 new FXTextField(matrix,10,&option_target,FXDataTarget::ID_VALUE,TEXTFIELD_INTEGER|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
215 new FXRadioButton(matrix,"Option &1",&option_target,FXDataTarget::ID_OPTION+0,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
216 new FXRadioButton(matrix,"Option &2",&option_target,FXDataTarget::ID_OPTION+1,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
217 new FXRadioButton(matrix,"Option &3",&option_target,FXDataTarget::ID_OPTION+2,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
218 new FXRadioButton(matrix,"Option &4",&option_target,FXDataTarget::ID_OPTION+3,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
219
220 // Even option menus can be hooked up
221 popup=new FXPopup(this);
222 new FXOption(popup,"First",NULL,&option_target,FXDataTarget::ID_OPTION+0,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
223 new FXOption(popup,"Second",NULL,&option_target,FXDataTarget::ID_OPTION+1,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
224 new FXOption(popup,"Third",NULL,&option_target,FXDataTarget::ID_OPTION+2,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
225 new FXOption(popup,"Fourth",NULL,&option_target,FXDataTarget::ID_OPTION+3,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
226 FXOptionMenu *options=new FXOptionMenu(matrix,popup,LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
227 options->setTarget(&option_target);
228 options->setSelector(FXDataTarget::ID_VALUE);
229
230 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
231 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
232
233 // Fifth
234 new FXLabel(matrix,"&Color",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
235
236 // Two colorwells connect to the variable "some_color"
237 new FXColorWell(matrix,0,&color_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW,0,0,0,0, 0,0,0,0);
238 new FXColorWell(matrix,0,&color_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW,0,0,0,0, 0,0,0,0);
239 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
240 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
241 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
242 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
243 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
244
245 // Install an accelerator
246 getAccelTable()->addAccel(parseAccel("Ctl-Q"),getApp(),FXSEL(SEL_COMMAND,FXApp::ID_QUIT));
247
248 }
249
250
251 // Clean up
~DataTargetWindow()252 DataTargetWindow::~DataTargetWindow(){
253 getApp()->removeTimeout(this,ID_TIMER);
254 delete progressdialog;
255 delete filemenu;
256 delete optionmenu;
257 delete popup;
258 }
259
260
261 // Timer
onCmdTimer(FXObject *,FXSelector,void *)262 long DataTargetWindow::onCmdTimer(FXObject*,FXSelector,void*){
263
264 // Increment modulo 100
265 some_progress=(some_progress+1)%100;
266
267 // Reset timer for next time
268 getApp()->addTimeout(this,ID_TIMER,80);
269 return 1;
270 }
271
272
273 // Quit
onCmdQuit(FXObject *,FXSelector,void *)274 long DataTargetWindow::onCmdQuit(FXObject*,FXSelector,void*){
275 getApp()->exit(0);
276 return 1;
277 }
278
279
280 // Show progress
onCmdProgress(FXObject *,FXSelector,void *)281 long DataTargetWindow::onCmdProgress(FXObject*,FXSelector,void*){
282 progressdialog->show(PLACEMENT_OWNER);
283 return 1;
284 }
285
286
287 // Start
create()288 void DataTargetWindow::create(){
289
290 // Create windows
291 FXMainWindow::create();
292
293 // Kick off the timer
294 getApp()->addTimeout(this,ID_TIMER,80);
295
296 // Show
297 show(PLACEMENT_SCREEN);
298 }
299
300
301 /*******************************************************************************/
302
303
304 // Start the whole thing
main(int argc,char * argv[])305 int main(int argc,char *argv[]){
306
307 // Make application
308 FXApp application("DataTarget","FoxTest");
309
310 // Open display
311 application.init(argc,argv);
312
313 // Main window
314 DataTargetWindow* window=new DataTargetWindow(&application);
315
316 // Handle interrupt to save stuff nicely
317 application.addSignal(SIGINT,window,DataTargetWindow::ID_QUIT);
318
319 // Create app
320 application.create();
321
322 // Run
323 return application.run();
324 }
325