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