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