1 /*****************************************************************************
2 *                                                                            *
3 *                                 Layout Example                             *
4 *                                                                            *
5 ******************************************************************************
6 * Copyright (C) 2004,2006 by Bill Baxter.   All Rights Reserved.             *
7 ******************************************************************************
8 * $Id: layout.cpp,v 1.7 2006/02/09 03:42:07 fox Exp $                        *
9 *****************************************************************************/
10 #include "fx.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 
15 /*
16   Notes:
17   - Contributed by Bill Baxter.
18   - Some coding style changes by Jeroen van der Zijp.
19 */
20 
21 /****************************************************************************/
22 
23 
24 // Main Window
25 class ButtonWindow : public FXMainWindow {
26   FXDECLARE(ButtonWindow)
27 protected:
28   FXComposite*     contents;            // Container for buttons
29   FXVerticalFrame* controls;            // Switchs to set various modes
30   FXButton*        lastButton;          // Current child
31   FXint            nextButtonNum;
32   FXuint           layoutHints;
33 protected:
ButtonWindow()34   ButtonWindow(){}
35 public:
36   enum {
37     ID_BUTTON=FXMainWindow::ID_LAST,
38 
39     // Horizontal alignment
40     ID_LAYOUT_LEFT,             // Stick on left (default)
41     ID_LAYOUT_RIGHT,            // Stick on right
42     ID_LAYOUT_CENTER_X,         // Center horizontally
43     ID_LAYOUT_FIX_X,            // X fixed
44 
45     // Vertical alignment
46     ID_LAYOUT_TOP,              // Stick on top (default)
47     ID_LAYOUT_BOTTOM,           // Stick on bottom
48     ID_LAYOUT_CENTER_Y,         // Center vertically
49     ID_LAYOUT_FIX_Y,            // Y fixed
50 
51     // Width
52     ID_LAYOUT_MIN_WIDTH,        // Minimum width is the default
53     ID_LAYOUT_FIX_WIDTH,        // Width fixed
54     ID_LAYOUT_FILL_X,           // Stretch or shrink horizontally
55 
56     // Height
57     ID_LAYOUT_MIN_HEIGHT,       // Minimum height is the default
58     ID_LAYOUT_FIX_HEIGHT,       // height fixed
59     ID_LAYOUT_FILL_Y,           // Stretch or shrink vertically
60 
61     // In a matrix
62     ID_LAYOUT_FILL_ROW,         // Matrix row is stretchable
63     ID_LAYOUT_FILL_COLUMN,      // Matrix column is stretchable
64 
65     // Side in a packer
66     ID_LAYOUT_SIDE_TOP,         // Pack on top side (default)
67     ID_LAYOUT_SIDE_BOTTOM,      // Pack on bottom side
68     ID_LAYOUT_SIDE_LEFT,        // Pack on left side
69     ID_LAYOUT_SIDE_RIGHT,       // Pack on right side
70 
71     ID_PACK_UNIFORM_HEIGHT,     // Uniform height
72     ID_PACK_UNIFORM_WIDTH,      // Uniform width
73 
74     ID_MATRIX_BY_ROWS,          // Uniform width
75     ID_MATRIX_BY_COLUMNS,       // Uniform width
76 
77     ID_CONTAINER_COMPOSITE,
78     ID_CONTAINER_HORIZONTAL_FRAME,
79     ID_CONTAINER_VERTICAL_FRAME,
80     ID_CONTAINER_PACKER,
81     ID_CONTAINER_MATRIX,
82 
83     ID_FIX_X_VAL,
84     ID_FIX_Y_VAL,
85     ID_FIX_W_VAL,
86     ID_FIX_H_VAL,
87     ID_MATRIX_ROWS_COLS,
88 
89     ID_ADD_BUTTON,
90     ID_CLEAR_BUTTON
91     };
92 public:
93   long onCmdAddButton(FXObject*,FXSelector,void*);
94   long onCmdClearButton(FXObject*,FXSelector,void*);
95   long onUpdClearButton(FXObject*,FXSelector,void*);
96   long onCmdLayoutSide(FXObject*,FXSelector,void*);
97   long onUpdLayoutSide(FXObject*,FXSelector,void*);
98   long onCmdLayoutHorz(FXObject*,FXSelector,void*);
99   long onUpdLayoutHorz(FXObject*,FXSelector,void*);
100   long onCmdLayoutVert(FXObject*,FXSelector,void*);
101   long onUpdLayoutVert(FXObject*,FXSelector,void*);
102   long onCmdLayoutWidth(FXObject*,FXSelector,void*);
103   long onUpdLayoutWidth(FXObject*,FXSelector,void*);
104   long onCmdLayoutHeight(FXObject*,FXSelector,void*);
105   long onUpdLayoutHeight(FXObject*,FXSelector,void*);
106   long onCmdLayoutMatrix(FXObject*,FXSelector,void*);
107   long onUpdLayoutMatrix(FXObject*,FXSelector,void*);
108   long onCmdPackHints(FXObject*,FXSelector,void*);
109   long onUpdPackHints(FXObject*,FXSelector,void*);
110 
111   long onCmdMatrixMode(FXObject*,FXSelector,void*);
112   long onUpdMatrixMode(FXObject*,FXSelector,void*);
113 
114   long onCmdContainerType(FXObject*,FXSelector,void*);
115   long onUpdContainerType(FXObject*,FXSelector,void*);
116   long onCmdFixVal(FXObject*,FXSelector,void*);
117   long onChgFixVal(FXObject*,FXSelector,void*);
118   long onUpdFixVal(FXObject*,FXSelector,void*);
119 
120   long onCmdMatVal(FXObject*,FXSelector,void*);
121   long onChgMatVal(FXObject*,FXSelector,void*);
122   long onUpdMatVal(FXObject*,FXSelector,void*);
123 
124   long onCmdButton(FXObject*,FXSelector,void*);
125 public:
126   ButtonWindow(FXApp* a);
127   void create();
128   };
129 
130 
131 /*******************************************************************************/
132 
133 
134 // Map
135 FXDEFMAP(ButtonWindow) ButtonWindowMap[]={
136 
137   FXMAPFUNC(SEL_COMMAND,  ButtonWindow::ID_BUTTON,           ButtonWindow::onCmdButton),
138 
139   FXMAPFUNC(SEL_COMMAND,  ButtonWindow::ID_MATRIX_ROWS_COLS, ButtonWindow::onChgMatVal),
140   FXMAPFUNC(SEL_CHANGED,  ButtonWindow::ID_MATRIX_ROWS_COLS, ButtonWindow::onChgMatVal),
141   FXMAPFUNC(SEL_UPDATE,   ButtonWindow::ID_MATRIX_ROWS_COLS, ButtonWindow::onUpdMatVal),
142 
143   FXMAPFUNC(SEL_COMMAND,  ButtonWindow::ID_ADD_BUTTON,       ButtonWindow::onCmdAddButton),
144   FXMAPFUNC(SEL_COMMAND,  ButtonWindow::ID_CLEAR_BUTTON,     ButtonWindow::onCmdClearButton),
145   FXMAPFUNC(SEL_UPDATE,   ButtonWindow::ID_CLEAR_BUTTON,     ButtonWindow::onUpdClearButton),
146 
147   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_LAYOUT_SIDE_TOP,  ButtonWindow::ID_LAYOUT_SIDE_RIGHT, ButtonWindow::onCmdLayoutSide),
148   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_LAYOUT_SIDE_TOP,  ButtonWindow::ID_LAYOUT_SIDE_RIGHT, ButtonWindow::onUpdLayoutSide),
149 
150   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_LAYOUT_LEFT,      ButtonWindow::ID_LAYOUT_FIX_X,      ButtonWindow::onCmdLayoutHorz),
151   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_LAYOUT_LEFT,      ButtonWindow::ID_LAYOUT_FIX_X,      ButtonWindow::onUpdLayoutHorz),
152 
153   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_LAYOUT_TOP,       ButtonWindow::ID_LAYOUT_FIX_Y,      ButtonWindow::onCmdLayoutVert),
154   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_LAYOUT_TOP,       ButtonWindow::ID_LAYOUT_FIX_Y,      ButtonWindow::onUpdLayoutVert),
155 
156   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_LAYOUT_MIN_WIDTH,  ButtonWindow::ID_LAYOUT_FILL_X,    ButtonWindow::onCmdLayoutWidth),
157   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_LAYOUT_MIN_WIDTH,  ButtonWindow::ID_LAYOUT_FILL_X,    ButtonWindow::onUpdLayoutWidth),
158 
159   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_LAYOUT_MIN_HEIGHT, ButtonWindow::ID_LAYOUT_FILL_Y,    ButtonWindow::onCmdLayoutHeight),
160   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_LAYOUT_MIN_HEIGHT, ButtonWindow::ID_LAYOUT_FILL_Y,    ButtonWindow::onUpdLayoutHeight),
161 
162   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_LAYOUT_FILL_ROW,  ButtonWindow::ID_LAYOUT_FILL_COLUMN,ButtonWindow::onCmdLayoutMatrix),
163   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_LAYOUT_FILL_ROW,  ButtonWindow::ID_LAYOUT_FILL_COLUMN,ButtonWindow::onUpdLayoutMatrix),
164 
165   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_PACK_UNIFORM_HEIGHT, ButtonWindow::ID_PACK_UNIFORM_WIDTH,   ButtonWindow::onCmdPackHints),
166   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_PACK_UNIFORM_HEIGHT, ButtonWindow::ID_PACK_UNIFORM_WIDTH,   ButtonWindow::onUpdPackHints),
167 
168   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_CONTAINER_COMPOSITE, ButtonWindow::ID_CONTAINER_MATRIX,   ButtonWindow::onCmdContainerType),
169   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_CONTAINER_COMPOSITE, ButtonWindow::ID_CONTAINER_MATRIX,   ButtonWindow::onUpdContainerType),
170 
171   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_MATRIX_BY_ROWS, ButtonWindow::ID_MATRIX_BY_COLUMNS,   ButtonWindow::onCmdMatrixMode),
172   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_MATRIX_BY_ROWS, ButtonWindow::ID_MATRIX_BY_COLUMNS,   ButtonWindow::onUpdMatrixMode),
173 
174   FXMAPFUNCS(SEL_COMMAND, ButtonWindow::ID_FIX_X_VAL,         ButtonWindow::ID_FIX_H_VAL,          ButtonWindow::onChgFixVal),
175   FXMAPFUNCS(SEL_CHANGED, ButtonWindow::ID_FIX_X_VAL,         ButtonWindow::ID_FIX_H_VAL,          ButtonWindow::onChgFixVal),
176   FXMAPFUNCS(SEL_UPDATE,  ButtonWindow::ID_FIX_X_VAL,         ButtonWindow::ID_FIX_H_VAL,          ButtonWindow::onUpdFixVal)
177   };
178 
179 
180 // ButtonApp implementation
181 FXIMPLEMENT(ButtonWindow,FXMainWindow,ButtonWindowMap,ARRAYNUMBER(ButtonWindowMap))
182 
183 
184 // Layout side
185 const FXuint LAYOUT_SIDE_MASK=(LAYOUT_SIDE_TOP|LAYOUT_SIDE_BOTTOM|LAYOUT_SIDE_LEFT|LAYOUT_SIDE_RIGHT);
186 
187 // Horizontal alignment
188 const FXuint LAYOUT_HORZ_MASK=(LAYOUT_LEFT|LAYOUT_RIGHT|LAYOUT_CENTER_X|LAYOUT_FIX_X);
189 
190 // Vertical alignment
191 const FXuint LAYOUT_VERT_MASK=(LAYOUT_TOP|LAYOUT_BOTTOM|LAYOUT_CENTER_Y|LAYOUT_FIX_Y);
192 
193 // Width
194 const FXuint LAYOUT_WIDTH_MASK=(LAYOUT_MIN_WIDTH|LAYOUT_FIX_WIDTH|LAYOUT_FILL_X);
195 
196 // Height
197 const FXuint LAYOUT_HEIGHT_MASK=(LAYOUT_MIN_HEIGHT|LAYOUT_FIX_HEIGHT|LAYOUT_FILL_Y);
198 
199 
200 // Make some windows
ButtonWindow(FXApp * a)201 ButtonWindow::ButtonWindow(FXApp* a):FXMainWindow(a,"Layout Test",NULL,NULL,DECOR_ALL,0,0,900,900){
202 
203   // Tooltip
204   new FXToolTip(getApp());
205 
206   nextButtonNum=1;
207   lastButton=NULL;
208   layoutHints=0;
209 
210   // Controls on right
211   controls=new FXVerticalFrame(this,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y);
212 
213   // Separator
214   new FXVerticalSeparator(this,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|SEPARATOR_GROOVE);
215 
216   // Contents
217   contents=new FXPacker(this,LAYOUT_SIDE_LEFT|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0, 0,0);
218   contents->setBackColor(FXRGB(192,128,128));
219 
220   new FXLabel(controls,"Widget Layout Styles\tLayout flags for added buttons",NULL,LAYOUT_CENTER_X);
221   new FXHorizontalSeparator(controls);
222 
223   new FXLabel(controls,"Packing Side:",NULL,LAYOUT_CENTER_X);
224   new FXRadioButton(controls,"LAYOUT_SIDE_LEFT",this,ID_LAYOUT_SIDE_LEFT);
225   new FXRadioButton(controls,"LAYOUT_SIDE_RIGHT",this,ID_LAYOUT_SIDE_RIGHT);
226   new FXRadioButton(controls,"LAYOUT_SIDE_TOP",this,ID_LAYOUT_SIDE_TOP);
227   new FXRadioButton(controls,"LAYOUT_SIDE_BOTTOM",this,ID_LAYOUT_SIDE_BOTTOM);
228 
229   new FXLabel(controls,"Horizontal alignment:",NULL,LAYOUT_CENTER_X);
230   new FXRadioButton(controls,"LAYOUT_LEFT",this,ID_LAYOUT_LEFT);
231   new FXRadioButton(controls,"LAYOUT_RIGHT",this,ID_LAYOUT_RIGHT);
232   new FXRadioButton(controls,"LAYOUT_CENTER_X",this,ID_LAYOUT_CENTER_X);
233   FXComposite *xposcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
234     new FXRadioButton(xposcontrols,"LAYOUT_FIX_X:",this,ID_LAYOUT_FIX_X,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
235     FXSpinner *xspin=new FXSpinner(xposcontrols,3,this,ID_FIX_X_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
236     xspin->setIncrement(10);
237     xspin->setRange(0,10000);
238 
239   new FXLabel(controls,"Vertical alignment:",NULL,LAYOUT_CENTER_X);
240   new FXRadioButton(controls,"LAYOUT_TOP",this,ID_LAYOUT_TOP);
241   new FXRadioButton(controls,"LAYOUT_BOTTOM",this,ID_LAYOUT_BOTTOM);
242   new FXRadioButton(controls,"LAYOUT_CENTER_Y",this,ID_LAYOUT_CENTER_Y);
243   FXComposite *yposcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
244     new FXRadioButton(yposcontrols,"LAYOUT_FIX_Y:",this,ID_LAYOUT_FIX_Y,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
245     FXSpinner *yspin=new FXSpinner(yposcontrols,3,this,ID_FIX_Y_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
246     yspin->setIncrement(10);
247     yspin->setRange(0,10000);
248 
249   new FXLabel(controls,"Width control:",NULL,LAYOUT_CENTER_X);
250   new FXRadioButton(controls,"LAYOUT_MIN_WIDTH",this,ID_LAYOUT_MIN_WIDTH);
251   new FXRadioButton(controls,"LAYOUT_FILL_X",this,ID_LAYOUT_FILL_X);
252   FXComposite *wcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
253     new FXRadioButton(wcontrols,"LAYOUT_FIX_WIDTH:",this,ID_LAYOUT_FIX_WIDTH,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
254     FXSpinner *wspin=new FXSpinner(wcontrols,3,this,ID_FIX_W_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
255     wspin->setIncrement(10);
256     wspin->setRange(0,10000);
257 
258   new FXLabel(controls,"Height control:",NULL,LAYOUT_CENTER_X);
259   new FXRadioButton(controls,"LAYOUT_MIN_HEIGHT",this,ID_LAYOUT_MIN_HEIGHT);
260   new FXRadioButton(controls,"LAYOUT_FILL_Y",this,ID_LAYOUT_FILL_Y);
261   FXComposite *hcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
262     new FXRadioButton(hcontrols,"LAYOUT_FIX_HEIGHT:",this,ID_LAYOUT_FIX_HEIGHT,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
263     FXSpinner *hspin=new FXSpinner(hcontrols,3,this,ID_FIX_H_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
264     hspin->setIncrement(10);
265     hspin->setRange(0,10000);
266 
267   new FXLabel(controls,"Matrix flags:",NULL,LAYOUT_CENTER_X);
268   new FXCheckButton(controls,"LAYOUT_FILL_COLUMN",this,ID_LAYOUT_FILL_COLUMN);
269   new FXCheckButton(controls,"LAYOUT_FILL_ROW",this,ID_LAYOUT_FILL_ROW);
270 
271 
272   new FXHorizontalSeparator(controls);
273   new FXLabel(controls,"Container Packing Styles\tPacking flags for container",NULL,LAYOUT_CENTER_X);
274 
275   FXComposite *ctrlsB = new FXHorizontalFrame(controls,LAYOUT_FILL);
276   FXGroupBox *group=new FXGroupBox(ctrlsB,"Container Type",GROUPBOX_TITLE_CENTER|FRAME_RIDGE|LAYOUT_FILL_X);
277   new FXRadioButton(group,"FXComposite\tMake left pane an FXComposite",this,ID_CONTAINER_COMPOSITE);
278   new FXRadioButton(group,"FXHorizonalFrame\tMake left pane an FXHorizontalFrame",this,ID_CONTAINER_HORIZONTAL_FRAME);
279   new FXRadioButton(group,"FXVerticalFrame\tMake left pane an FXVerticalFrame",this,ID_CONTAINER_VERTICAL_FRAME);
280   new FXRadioButton(group,"FXPacker\tMake left pane an FXPacker",this,ID_CONTAINER_PACKER);
281   new FXRadioButton(group,"FXMatrix\tMake left pane an FXMatrix",this,ID_CONTAINER_MATRIX);
282 
283   FXComposite *checksBR=new FXVerticalFrame(ctrlsB,LAYOUT_SIDE_RIGHT|LAYOUT_FILL);
284   new FXCheckButton(checksBR,"PACK_UNIFORM_HEIGHT", this, ID_PACK_UNIFORM_HEIGHT);
285   new FXCheckButton(checksBR,"PACK_UNIFORM_WIDTH", this, ID_PACK_UNIFORM_WIDTH);
286   new FXRadioButton(checksBR,"MATRIX_BY_ROWS", this, ID_MATRIX_BY_ROWS);
287   new FXRadioButton(checksBR,"MATRIX_BY_COLUMNS", this, ID_MATRIX_BY_COLUMNS);
288   FXComposite *hf = new FXHorizontalFrame(checksBR,LAYOUT_FILL_X);
289   new FXLabel(hf, "Matrix Rows/cols:");
290   new FXSpinner(hf, 4, this, ID_MATRIX_ROWS_COLS,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y);
291 
292   FXComposite *bframe = new FXHorizontalFrame(controls,LAYOUT_BOTTOM|LAYOUT_FILL_X);
293   new FXButton(bframe,"&Add\tAdd a button",NULL,this,ID_ADD_BUTTON,FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X);
294   new FXButton(bframe,"&Clear\tRemove all buttons",NULL,this,ID_CLEAR_BUTTON,FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X);
295   new FXButton(bframe,"&Quit\tQuit program",NULL,getApp(),FXApp::ID_QUIT,FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_BOTTOM);
296   }
297 
298 
299 // Start
create()300 void ButtonWindow::create(){
301   FXMainWindow::create();
302   show(PLACEMENT_SCREEN);
303   }
304 
305 
306 // Change side of item inside packer
onCmdLayoutSide(FXObject *,FXSelector sel,void *)307 long ButtonWindow::onCmdLayoutSide(FXObject*,FXSelector sel,void*){
308   if(lastButton){
309     layoutHints=lastButton->getLayoutHints()&~LAYOUT_SIDE_MASK;
310     switch(FXSELID(sel)){
311       case ID_LAYOUT_SIDE_TOP:    layoutHints|=LAYOUT_SIDE_TOP; break;
312       case ID_LAYOUT_SIDE_BOTTOM: layoutHints|=LAYOUT_SIDE_BOTTOM; break;
313       case ID_LAYOUT_SIDE_LEFT:   layoutHints|=LAYOUT_SIDE_LEFT; break;
314       case ID_LAYOUT_SIDE_RIGHT:  layoutHints|=LAYOUT_SIDE_RIGHT; break;
315       }
316     lastButton->setLayoutHints(layoutHints);
317     }
318   return 1;
319   }
320 
321 
322 // Update side of item inside packer
onUpdLayoutSide(FXObject * sender,FXSelector sel,void *)323 long ButtonWindow::onUpdLayoutSide(FXObject* sender,FXSelector sel,void*){
324   if(lastButton){
325     FXuint hints=lastButton->getLayoutHints()&LAYOUT_SIDE_MASK;
326     FXint equal=FALSE;
327     switch(FXSELID(sel)){
328       case ID_LAYOUT_SIDE_TOP:    equal=(hints==LAYOUT_SIDE_TOP); break;
329       case ID_LAYOUT_SIDE_BOTTOM: equal=(hints==LAYOUT_SIDE_BOTTOM); break;
330       case ID_LAYOUT_SIDE_LEFT:   equal=(hints==LAYOUT_SIDE_LEFT); break;
331       case ID_LAYOUT_SIDE_RIGHT:  equal=(hints==LAYOUT_SIDE_RIGHT); break;
332       }
333     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
334     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
335     }
336   else{
337     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
338     }
339   return 1;
340   }
341 
342 // Change horizontal alignment
onCmdLayoutHorz(FXObject *,FXSelector sel,void *)343 long ButtonWindow::onCmdLayoutHorz(FXObject*,FXSelector sel,void*){
344   if(lastButton){
345     layoutHints=lastButton->getLayoutHints()&~LAYOUT_HORZ_MASK;
346     switch(FXSELID(sel)){
347       case ID_LAYOUT_LEFT:     layoutHints|=LAYOUT_LEFT; break;
348       case ID_LAYOUT_RIGHT:    layoutHints|=LAYOUT_RIGHT; break;
349       case ID_LAYOUT_CENTER_X: layoutHints|=LAYOUT_CENTER_X; break;
350       case ID_LAYOUT_FIX_X:    layoutHints|=LAYOUT_FIX_X; break;
351       }
352     lastButton->setLayoutHints(layoutHints);
353     }
354   return 1;
355   }
356 
357 
358 // Update horizontal alignment
onUpdLayoutHorz(FXObject * sender,FXSelector sel,void *)359 long ButtonWindow::onUpdLayoutHorz(FXObject* sender,FXSelector sel,void*){
360   if(lastButton){
361     FXuint hints=lastButton->getLayoutHints()&LAYOUT_HORZ_MASK;
362     FXint equal=FALSE;
363     switch(FXSELID(sel)){
364       case ID_LAYOUT_LEFT:     equal=(hints==LAYOUT_LEFT); break;
365       case ID_LAYOUT_RIGHT:    equal=(hints==LAYOUT_RIGHT); break;
366       case ID_LAYOUT_CENTER_X: equal=(hints==LAYOUT_CENTER_X); break;
367       case ID_LAYOUT_FIX_X:    equal=(hints==LAYOUT_FIX_X); break;
368       }
369     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
370     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
371     }
372   else{
373     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
374     }
375   return 1;
376   }
377 
378 
379 // Change vertical alignment
onCmdLayoutVert(FXObject *,FXSelector sel,void *)380 long ButtonWindow::onCmdLayoutVert(FXObject*,FXSelector sel,void*){
381   if(lastButton){
382     layoutHints=lastButton->getLayoutHints()&~LAYOUT_VERT_MASK;
383     switch(FXSELID(sel)){
384       case ID_LAYOUT_TOP:      layoutHints|=LAYOUT_TOP; break;
385       case ID_LAYOUT_BOTTOM:   layoutHints|=LAYOUT_BOTTOM; break;
386       case ID_LAYOUT_CENTER_Y: layoutHints|=LAYOUT_CENTER_Y; break;
387       case ID_LAYOUT_FIX_Y:    layoutHints|=LAYOUT_FIX_Y; break;
388       }
389     lastButton->setLayoutHints(layoutHints);
390     }
391   return 1;
392   }
393 
394 
395 // Update vertical alignment
onUpdLayoutVert(FXObject * sender,FXSelector sel,void *)396 long ButtonWindow::onUpdLayoutVert(FXObject* sender,FXSelector sel,void*){
397   if(lastButton){
398     FXuint hints=lastButton->getLayoutHints()&LAYOUT_VERT_MASK;
399     FXint equal=FALSE;
400     switch(FXSELID(sel)){
401       case ID_LAYOUT_TOP:      equal=(hints==LAYOUT_TOP); break;
402       case ID_LAYOUT_BOTTOM:   equal=(hints==LAYOUT_BOTTOM); break;
403       case ID_LAYOUT_CENTER_Y: equal=(hints==LAYOUT_CENTER_Y); break;
404       case ID_LAYOUT_FIX_Y:    equal=(hints==LAYOUT_FIX_Y); break;
405       }
406     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
407     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
408     }
409   else{
410     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
411     }
412   return 1;
413   }
414 
415 
416 // Change width
onCmdLayoutWidth(FXObject *,FXSelector sel,void *)417 long ButtonWindow::onCmdLayoutWidth(FXObject*,FXSelector sel,void*){
418   if(lastButton){
419     layoutHints=lastButton->getLayoutHints()&~LAYOUT_WIDTH_MASK;
420     switch(FXSELID(sel)){
421       case ID_LAYOUT_MIN_WIDTH: layoutHints|=LAYOUT_MIN_WIDTH; break;
422       case ID_LAYOUT_FIX_WIDTH: layoutHints|=LAYOUT_FIX_WIDTH; break;
423       case ID_LAYOUT_FILL_X:    layoutHints|=LAYOUT_FILL_X; break;
424       }
425     lastButton->setLayoutHints(layoutHints);
426     }
427   return 1;
428   }
429 
430 
431 // Update width
onUpdLayoutWidth(FXObject * sender,FXSelector sel,void *)432 long ButtonWindow::onUpdLayoutWidth(FXObject* sender,FXSelector sel,void*){
433   if(lastButton){
434     FXuint hints=lastButton->getLayoutHints()&LAYOUT_WIDTH_MASK;
435     FXint equal=FALSE;
436     switch(FXSELID(sel)){
437       case ID_LAYOUT_MIN_WIDTH: equal=(hints==LAYOUT_MIN_WIDTH); break;
438       case ID_LAYOUT_FIX_WIDTH: equal=(hints==LAYOUT_FIX_WIDTH); break;
439       case ID_LAYOUT_FILL_X:    equal=(hints==LAYOUT_FILL_X); break;
440       }
441     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
442     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
443     }
444   else{
445     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
446     }
447   return 1;
448   }
449 
450 // Change height
onCmdLayoutHeight(FXObject *,FXSelector sel,void *)451 long ButtonWindow::onCmdLayoutHeight(FXObject*,FXSelector sel,void*){
452   if(lastButton){
453     layoutHints=lastButton->getLayoutHints()&~LAYOUT_HEIGHT_MASK;
454     switch(FXSELID(sel)){
455       case ID_LAYOUT_MIN_HEIGHT: layoutHints|=LAYOUT_MIN_HEIGHT; break;
456       case ID_LAYOUT_FIX_HEIGHT: layoutHints|=LAYOUT_FIX_HEIGHT; break;
457       case ID_LAYOUT_FILL_Y:     layoutHints|=LAYOUT_FILL_Y; break;
458       }
459     lastButton->setLayoutHints(layoutHints);
460     }
461   return 1;
462   }
463 
464 
465 // Update height
onUpdLayoutHeight(FXObject * sender,FXSelector sel,void *)466 long ButtonWindow::onUpdLayoutHeight(FXObject* sender,FXSelector sel,void*){
467   if(lastButton){
468     FXuint hints=lastButton->getLayoutHints()&LAYOUT_HEIGHT_MASK;
469     FXint equal=FALSE;
470     switch(FXSELID(sel)){
471       case ID_LAYOUT_MIN_HEIGHT: equal=(hints==LAYOUT_MIN_HEIGHT); break;
472       case ID_LAYOUT_FIX_HEIGHT: equal=(hints==LAYOUT_FIX_HEIGHT); break;
473       case ID_LAYOUT_FILL_Y:     equal=(hints==LAYOUT_FILL_Y); break;
474       }
475     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
476     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
477     }
478   else{
479     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
480     }
481   return 1;
482   }
483 
484 // Change matrix layout
onCmdLayoutMatrix(FXObject *,FXSelector sel,void *)485 long ButtonWindow::onCmdLayoutMatrix(FXObject*,FXSelector sel,void*){
486   if(lastButton){
487     layoutHints=lastButton->getLayoutHints();
488     switch(FXSELID(sel)){
489       case ID_LAYOUT_FILL_COLUMN: layoutHints^=LAYOUT_FILL_COLUMN; break;
490       case ID_LAYOUT_FILL_ROW:  layoutHints^=LAYOUT_FILL_ROW; break;
491       }
492     lastButton->setLayoutHints(layoutHints);
493     }
494   return 1;
495   }
496 
497 
498 // Update matrix layout
onUpdLayoutMatrix(FXObject * sender,FXSelector sel,void *)499 long ButtonWindow::onUpdLayoutMatrix(FXObject* sender,FXSelector sel,void*){
500   if(lastButton){
501     FXuint hints=lastButton->getLayoutHints();
502     FXuint equal=0;
503     switch(FXSELID(sel)){
504       case ID_LAYOUT_FILL_COLUMN: equal=(hints&LAYOUT_FILL_COLUMN)!=0; break;
505       case ID_LAYOUT_FILL_ROW:    equal=(hints&LAYOUT_FILL_ROW)!=0; break;
506       }
507     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
508     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
509     }
510   else{
511     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
512     }
513   return 1;
514   }
515 
516 
517 // Change packing
onCmdPackHints(FXObject *,FXSelector sel,void *)518 long ButtonWindow::onCmdPackHints(FXObject*,FXSelector sel,void*){
519   FXPacker *packer=dynamic_cast<FXPacker*>(contents);
520   if(packer){
521     FXuint hints=packer->getPackingHints();
522     switch(FXSELID(sel)){
523       case ID_PACK_UNIFORM_HEIGHT: hints^=PACK_UNIFORM_HEIGHT; break;
524       case ID_PACK_UNIFORM_WIDTH:  hints^=PACK_UNIFORM_WIDTH; break;
525       }
526     packer->setPackingHints(hints);
527     }
528   return 1;
529   }
530 
531 
532 // Update packing
onUpdPackHints(FXObject * sender,FXSelector sel,void *)533 long ButtonWindow::onUpdPackHints(FXObject* sender,FXSelector sel,void*){
534   FXPacker *packer=dynamic_cast<FXPacker*>(contents);
535   if(packer){
536     FXuint hints=packer->getPackingHints()&(PACK_UNIFORM_HEIGHT|PACK_UNIFORM_WIDTH);
537     FXuint equal=0;
538     switch(FXSELID(sel)){
539       case ID_PACK_UNIFORM_HEIGHT: equal=(hints&PACK_UNIFORM_HEIGHT)!=0; break;
540       case ID_PACK_UNIFORM_WIDTH:  equal=(hints&PACK_UNIFORM_WIDTH)!=0; break;
541       }
542     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
543     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
544     }
545   else{
546     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
547     }
548   return 1;
549   }
550 
551 
552 // Change Matrix mode
onCmdMatrixMode(FXObject *,FXSelector sel,void *)553 long ButtonWindow::onCmdMatrixMode(FXObject*,FXSelector sel,void*){
554   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
555   if(matrix){
556     FXuint style=matrix->getMatrixStyle();
557     switch(FXSELID(sel)){
558       case ID_MATRIX_BY_COLUMNS: style|=MATRIX_BY_COLUMNS; break;
559       case ID_MATRIX_BY_ROWS:    style&=~MATRIX_BY_COLUMNS; break;
560       }
561     matrix->setMatrixStyle(style);
562     }
563   return 1;
564   }
565 
566 
567 // Update Matrix mode
onUpdMatrixMode(FXObject * sender,FXSelector sel,void *)568 long ButtonWindow::onUpdMatrixMode(FXObject* sender,FXSelector sel,void*){
569   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
570   if(matrix){
571     FXuint style=matrix->getMatrixStyle();
572     FXuint equal=0;
573     switch(FXSELID(sel)){
574       case ID_MATRIX_BY_COLUMNS: equal=(style&MATRIX_BY_COLUMNS)!=0; break;
575       case ID_MATRIX_BY_ROWS:    equal=(style&MATRIX_BY_COLUMNS)==0; break;
576       }
577     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
578     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
579     }
580   else{
581     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
582     }
583   return 1;
584   }
585 
586 
587 // Change container type, reparent existing widgets into it
onCmdContainerType(FXObject *,FXSelector sel,void *)588 long ButtonWindow::onCmdContainerType(FXObject*,FXSelector sel,void*){
589   FXComposite *old=contents;
590   switch(FXSELID(sel)){
591     case ID_CONTAINER_COMPOSITE:
592       contents=new FXComposite(this,LAYOUT_SIDE_LEFT|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
593       contents->create();
594       break;
595     case ID_CONTAINER_HORIZONTAL_FRAME:
596       contents=new FXHorizontalFrame(this,LAYOUT_SIDE_LEFT|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH,0,0,0,0, 0,0,0,0, 0,0);
597       contents->create();
598       break;
599     case ID_CONTAINER_VERTICAL_FRAME:
600       contents=new FXVerticalFrame(this,LAYOUT_SIDE_LEFT|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0, 0,0);
601       contents->create();
602       break;
603     case ID_CONTAINER_PACKER:
604       contents=new FXPacker(this,LAYOUT_SIDE_LEFT|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0, 0,0);
605       contents->create();
606       break;
607     case ID_CONTAINER_MATRIX:
608       contents=new FXMatrix(this,3,LAYOUT_SIDE_LEFT|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0, 0,0);
609       contents->create();
610       break;
611     }
612   while(old->getFirst()){
613     old->getFirst()->reparent(contents);
614     }
615   contents->setBackColor(FXRGB(192,128,128));
616   contents->recalc();
617   delete old;
618   return 1;
619   }
620 
621 
622 // Update container type
onUpdContainerType(FXObject * sender,FXSelector sel,void *)623 long ButtonWindow::onUpdContainerType(FXObject* sender,FXSelector sel,void*){
624   const FXMetaClass *mc=contents->getMetaClass();
625   switch(FXSELID(sel)){
626     case ID_CONTAINER_COMPOSITE:
627       sender->handle(this,(mc==&FXComposite::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
628       break;
629     case ID_CONTAINER_HORIZONTAL_FRAME:
630       sender->handle(this,(mc==&FXHorizontalFrame::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
631       break;
632     case ID_CONTAINER_VERTICAL_FRAME:
633       sender->handle(this,(mc==&FXVerticalFrame::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
634       break;
635     case ID_CONTAINER_PACKER:
636       sender->handle(this,(mc==&FXPacker::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
637       break;
638     case ID_CONTAINER_MATRIX:
639       sender->handle(this,(mc==&FXMatrix::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
640       break;
641     }
642   return 1;
643   }
644 
645 
646 // Change fixed stuff
onChgFixVal(FXObject * sender,FXSelector sel,void *)647 long ButtonWindow::onChgFixVal(FXObject*sender,FXSelector sel,void*){
648   FXint val=0;
649   if(lastButton){
650     sender->handle(this,FXSEL(SEL_COMMAND,ID_GETINTVALUE),(void*)&val);
651     switch(FXSELID(sel)){
652       case ID_FIX_X_VAL: lastButton->setX(val); break;
653       case ID_FIX_Y_VAL: lastButton->setY(val); break;
654       case ID_FIX_W_VAL: lastButton->setWidth(val); break;
655       case ID_FIX_H_VAL: lastButton->setHeight(val); break;
656       }
657     contents->recalc();
658     }
659   return 1;
660   }
661 
662 
663 // Update fixed stuff
onUpdFixVal(FXObject * sender,FXSelector sel,void *)664 long ButtonWindow::onUpdFixVal(FXObject*sender,FXSelector sel,void*){
665   if(lastButton){
666     FXint val=0;
667     switch(FXSELID(sel)){
668       case ID_FIX_X_VAL: val=lastButton->getX(); break;
669       case ID_FIX_Y_VAL: val=lastButton->getY(); break;
670       case ID_FIX_W_VAL: val=lastButton->getWidth(); break;
671       case ID_FIX_H_VAL: val=lastButton->getHeight(); break;
672       }
673     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&val);
674     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
675     }
676   else{
677     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
678     }
679   return 1;
680   }
681 
682 
683 // Change number of rows or columns
onChgMatVal(FXObject * sender,FXSelector,void *)684 long ButtonWindow::onChgMatVal(FXObject*sender,FXSelector,void*){
685   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
686   if(matrix){
687     FXint val;
688     sender->handle(this,FXSEL(SEL_COMMAND,ID_GETINTVALUE),(void*)&val);
689     if(matrix->getMatrixStyle()&MATRIX_BY_COLUMNS){
690       matrix->setNumColumns(val);
691       }
692     else{
693       matrix->setNumRows(val);
694       }
695     }
696   return 1;
697   }
698 
699 
700 // Update number of rows or columns
onUpdMatVal(FXObject * sender,FXSelector,void *)701 long ButtonWindow::onUpdMatVal(FXObject* sender,FXSelector,void*){
702   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
703   if(matrix){
704     FXint val;
705     if(matrix->getMatrixStyle()&MATRIX_BY_COLUMNS){
706       val=matrix->getNumColumns();
707       }
708     else{
709       val=matrix->getNumRows();
710       }
711     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),&val);
712     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
713     }
714   else{
715     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
716     }
717   return 1;
718   }
719 
720 
721 // Clear buttons from the container
onCmdClearButton(FXObject *,FXSelector,void *)722 long ButtonWindow::onCmdClearButton(FXObject*,FXSelector,void*){
723   while(contents->getFirst()){
724     delete contents->getFirst();
725     }
726   contents->recalc();
727   lastButton=NULL;
728   nextButtonNum=0;
729   return 1;
730   }
731 
732 
onUpdClearButton(FXObject * sender,FXSelector,void *)733 long ButtonWindow::onUpdClearButton(FXObject* sender,FXSelector,void*){
734   sender->handle(this,contents->getFirst()?FXSEL(SEL_COMMAND,ID_ENABLE):FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
735   return 1;
736   }
737 
738 // Add a button to the container
onCmdAddButton(FXObject *,FXSelector,void *)739 long ButtonWindow::onCmdAddButton(FXObject*,FXSelector,void*){
740   static const FXchar *titles[]={"Button %d\tClick to make active", "Wide Button %d\tClick to make active", "Tall\nButton %d\tClick to make active"};
741   FXString string;
742   string.format(titles[nextButtonNum%3],nextButtonNum);
743   lastButton=new FXButton(contents,string,NULL,this,ID_BUTTON,FRAME_THICK|FRAME_RAISED|layoutHints);
744   lastButton->create();
745   lastButton->recalc();
746   nextButtonNum++;
747   return 1;
748   }
749 
750 
751 // Make this one the active button
onCmdButton(FXObject * sender,FXSelector,void *)752 long ButtonWindow::onCmdButton(FXObject* sender,FXSelector,void*){
753   lastButton=(FXButton*)sender;
754   layoutHints=lastButton->getLayoutHints();
755   return 1;
756   }
757 
758 
759 /*******************************************************************************/
760 
761 
762 // Start the whole thing
main(int argc,char * argv[])763 int main(int argc,char *argv[]){
764 
765   // Make application
766   FXApp application("Layout","FoxTest");
767 
768   // Open display
769   application.init(argc,argv);
770 
771   // Main window
772   new ButtonWindow(&application);
773 
774   // Create app
775   application.create();
776 
777   // Run
778   return application.run();
779   }
780 
781 
782