1 /********************************************************************************
2 * *
3 * Data Target Test *
4 * *
5 *********************************************************************************
6 * Copyright (C) 1997 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * $Id: datatarget.cpp,v 1.44 2004/10/01 07:09:31 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,8,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 FXSpinner(matrix,5,&int_target,FXDataTarget::ID_VALUE,SPIN_CYCLIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW);
172 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);
173 FX7Segment *seven=new FX7Segment(matrix,FXString::null,SEVENSEGMENT_SHADOW|JUSTIFY_RIGHT|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW|LAYOUT_FILL_X);
174 seven->setTarget(&int_target);
175 seven->setSelector(FXDataTarget::ID_VALUE);
176
177
178 // Second row
179 new FXLabel(matrix,"&Real",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
180
181 // The value of variable "some_double" may be changed by the widgets below
182 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);
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 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);
185 rslider->setRange(0.0,10.0);
186 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);
187
188 FXRealSpinner *rspinner=new FXRealSpinner(matrix,5,&double_target,FXDataTarget::ID_VALUE,FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW);
189 rspinner->setRange(0.0,10.0);
190 rspinner->setIncrement(0.01);
191 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
192 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
193
194 // Third row
195 new FXLabel(matrix,"&String",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
196
197 // The string variable "some_string" can be changed by these text fields
198 new FXTextField(matrix,10,&string_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
199 new FXTextField(matrix,10,&string_target,FXDataTarget::ID_VALUE,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
200 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
201 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
202 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
203 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
204 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
205
206 // Fourth row
207 new FXLabel(matrix,"&Option",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
208
209 // The variable "some_option" is changed by the following widgets
210 new FXTextField(matrix,10,&option_target,FXDataTarget::ID_VALUE,TEXTFIELD_INTEGER|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW);
211 new FXRadioButton(matrix,"Option &1",&option_target,FXDataTarget::ID_OPTION+0,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
212 new FXRadioButton(matrix,"Option &2",&option_target,FXDataTarget::ID_OPTION+1,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
213 new FXRadioButton(matrix,"Option &3",&option_target,FXDataTarget::ID_OPTION+2,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
214 new FXRadioButton(matrix,"Option &4",&option_target,FXDataTarget::ID_OPTION+3,LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT);
215
216 // Even option menus can be hooked up
217 popup=new FXPopup(this);
218 new FXOption(popup,"First",NULL,&option_target,FXDataTarget::ID_OPTION+0,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
219 new FXOption(popup,"Second",NULL,&option_target,FXDataTarget::ID_OPTION+1,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
220 new FXOption(popup,"Third",NULL,&option_target,FXDataTarget::ID_OPTION+2,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
221 new FXOption(popup,"Fourth",NULL,&option_target,FXDataTarget::ID_OPTION+3,JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
222 FXOptionMenu *options=new FXOptionMenu(matrix,popup,LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|JUSTIFY_HZ_APART|ICON_AFTER_TEXT);
223 options->setTarget(&option_target);
224 options->setSelector(FXDataTarget::ID_VALUE);
225
226 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
227
228 // Fifth
229 new FXLabel(matrix,"&Color",NULL,LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW);
230
231 // Two colorwells connect to the variable "some_color"
232 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);
233 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);
234 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
235 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
236 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
237 new FXFrame(matrix,LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
238
239 // Install an accelerator
240 getAccelTable()->addAccel(fxparseAccel("Ctl-Q"),getApp(),FXSEL(SEL_COMMAND,FXApp::ID_QUIT));
241
242 }
243
244
245 // Clean up
~DataTargetWindow()246 DataTargetWindow::~DataTargetWindow(){
247 getApp()->removeTimeout(this,ID_TIMER);
248 delete progressdialog;
249 delete filemenu;
250 delete optionmenu;
251 delete popup;
252 }
253
254
255 // Timer
onCmdTimer(FXObject *,FXSelector,void *)256 long DataTargetWindow::onCmdTimer(FXObject*,FXSelector,void*){
257
258 // Increment modulo 100
259 some_progress=(some_progress+1)%100;
260
261 // Reset timer for next time
262 getApp()->addTimeout(this,ID_TIMER,80);
263 return 1;
264 }
265
266
267 // Quit
onCmdQuit(FXObject *,FXSelector,void *)268 long DataTargetWindow::onCmdQuit(FXObject*,FXSelector,void*){
269 getApp()->exit(0);
270 return 1;
271 }
272
273
274 // Show progress
onCmdProgress(FXObject *,FXSelector,void *)275 long DataTargetWindow::onCmdProgress(FXObject*,FXSelector,void*){
276 progressdialog->show(PLACEMENT_OWNER);
277 return 1;
278 }
279
280
281 // Start
create()282 void DataTargetWindow::create(){
283
284 // Create windows
285 FXMainWindow::create();
286
287 // Kick off the timer
288 getApp()->addTimeout(this,ID_TIMER,80);
289
290 // Show
291 show(PLACEMENT_SCREEN);
292 }
293
294
295 /*******************************************************************************/
296
297
298 // Start the whole thing
main(int argc,char * argv[])299 int main(int argc,char *argv[]){
300
301 // Make application
302 FXApp application("DataTarget","FoxTest");
303
304 // Open display
305 application.init(argc,argv);
306
307 // Main window
308 DataTargetWindow* window=new DataTargetWindow(&application);
309
310 // Handle interrupt to save stuff nicely
311 application.addSignal(SIGINT,window,DataTargetWindow::ID_QUIT);
312
313 // Create app
314 application.create();
315
316 // Run
317 return application.run();
318 }
319