1 /*****************************************************************************
2 *                                                                            *
3 *                                 Layout Example                             *
4 *                                                                            *
5 ******************************************************************************
6 * Copyright (C) 2004 by Bill Baxter.   All Rights Reserved.                  *
7 ******************************************************************************
8 * $Id: layout.cpp,v 1.5 2004/03/27 17:11:47 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 
209   // Controls on right
210   controls=new FXVerticalFrame(this,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y);
211 
212   // Separator
213   new FXVerticalSeparator(this,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|SEPARATOR_GROOVE);
214 
215   // Contents
216   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);
217   contents->setBackColor(FXRGB(192,128,128));
218 
219   new FXLabel(controls,"Widget Layout Styles\tLayout flags for added buttons",NULL,LAYOUT_CENTER_X);
220   new FXHorizontalSeparator(controls);
221 
222   new FXLabel(controls,"Packing Side:",NULL,LAYOUT_CENTER_X);
223   new FXRadioButton(controls,"LAYOUT_SIDE_LEFT",this,ID_LAYOUT_SIDE_LEFT);
224   new FXRadioButton(controls,"LAYOUT_SIDE_RIGHT",this,ID_LAYOUT_SIDE_RIGHT);
225   new FXRadioButton(controls,"LAYOUT_SIDE_TOP",this,ID_LAYOUT_SIDE_TOP);
226   new FXRadioButton(controls,"LAYOUT_SIDE_BOTTOM",this,ID_LAYOUT_SIDE_BOTTOM);
227 
228   new FXLabel(controls,"Horizontal alignment:",NULL,LAYOUT_CENTER_X);
229   new FXRadioButton(controls,"LAYOUT_LEFT",this,ID_LAYOUT_LEFT);
230   new FXRadioButton(controls,"LAYOUT_RIGHT",this,ID_LAYOUT_RIGHT);
231   new FXRadioButton(controls,"LAYOUT_CENTER_X",this,ID_LAYOUT_CENTER_X);
232   FXComposite *xposcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
233     new FXRadioButton(xposcontrols,"LAYOUT_FIX_X:",this,ID_LAYOUT_FIX_X,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
234     FXSpinner *xspin=new FXSpinner(xposcontrols,3,this,ID_FIX_X_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
235     xspin->setIncrement(10);
236     xspin->setRange(0,10000);
237 
238   new FXLabel(controls,"Vertical alignment:",NULL,LAYOUT_CENTER_X);
239   new FXRadioButton(controls,"LAYOUT_TOP",this,ID_LAYOUT_TOP);
240   new FXRadioButton(controls,"LAYOUT_BOTTOM",this,ID_LAYOUT_BOTTOM);
241   new FXRadioButton(controls,"LAYOUT_CENTER_Y",this,ID_LAYOUT_CENTER_Y);
242   FXComposite *yposcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
243     new FXRadioButton(yposcontrols,"LAYOUT_FIX_Y:",this,ID_LAYOUT_FIX_Y,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
244     FXSpinner *yspin=new FXSpinner(yposcontrols,3,this,ID_FIX_Y_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
245     yspin->setIncrement(10);
246     yspin->setRange(0,10000);
247 
248   new FXLabel(controls,"Width control:",NULL,LAYOUT_CENTER_X);
249   new FXRadioButton(controls,"LAYOUT_MIN_WIDTH",this,ID_LAYOUT_MIN_WIDTH);
250   new FXRadioButton(controls,"LAYOUT_FILL_X",this,ID_LAYOUT_FILL_X);
251   FXComposite *wcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
252     new FXRadioButton(wcontrols,"LAYOUT_FIX_WIDTH:",this,ID_LAYOUT_FIX_WIDTH,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
253     FXSpinner *wspin=new FXSpinner(wcontrols,3,this,ID_FIX_W_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
254     wspin->setIncrement(10);
255     wspin->setRange(0,10000);
256 
257   new FXLabel(controls,"Height control:",NULL,LAYOUT_CENTER_X);
258   new FXRadioButton(controls,"LAYOUT_MIN_HEIGHT",this,ID_LAYOUT_MIN_HEIGHT);
259   new FXRadioButton(controls,"LAYOUT_FILL_Y",this,ID_LAYOUT_FILL_Y);
260   FXComposite *hcontrols=new FXHorizontalFrame(controls,LAYOUT_SIDE_RIGHT|LAYOUT_FILL_X,0,0,0,0, 0,0,0,0);
261     new FXRadioButton(hcontrols,"LAYOUT_FIX_HEIGHT:",this,ID_LAYOUT_FIX_HEIGHT,ICON_BEFORE_TEXT|LAYOUT_CENTER_Y);
262     FXSpinner *hspin=new FXSpinner(hcontrols,3,this,ID_FIX_H_VAL,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y|LAYOUT_RIGHT);
263     hspin->setIncrement(10);
264     hspin->setRange(0,10000);
265 
266   new FXLabel(controls,"Matrix flags:",NULL,LAYOUT_CENTER_X);
267   new FXCheckButton(controls,"LAYOUT_FILL_COLUMN",this,ID_LAYOUT_FILL_COLUMN);
268   new FXCheckButton(controls,"LAYOUT_FILL_ROW",this,ID_LAYOUT_FILL_ROW);
269 
270 
271   new FXHorizontalSeparator(controls);
272   new FXLabel(controls,"Container Packing Styles\tPacking flags for container",NULL,LAYOUT_CENTER_X);
273 
274   FXComposite *ctrlsB = new FXHorizontalFrame(controls,LAYOUT_FILL);
275   FXGroupBox *group=new FXGroupBox(ctrlsB,"Container Type",GROUPBOX_TITLE_CENTER|FRAME_RIDGE|LAYOUT_FILL_X);
276   new FXRadioButton(group,"FXComposite\tMake left pane an FXComposite",this,ID_CONTAINER_COMPOSITE);
277   new FXRadioButton(group,"FXHorizonalFrame\tMake left pane an FXHorizontalFrame",this,ID_CONTAINER_HORIZONTAL_FRAME);
278   new FXRadioButton(group,"FXVerticalFrame\tMake left pane an FXVerticalFrame",this,ID_CONTAINER_VERTICAL_FRAME);
279   new FXRadioButton(group,"FXPacker\tMake left pane an FXPacker",this,ID_CONTAINER_PACKER);
280   new FXRadioButton(group,"FXMatrix\tMake left pane an FXMatrix",this,ID_CONTAINER_MATRIX);
281 
282   FXComposite *checksBR=new FXVerticalFrame(ctrlsB,LAYOUT_SIDE_RIGHT|LAYOUT_FILL);
283   new FXCheckButton(checksBR,"PACK_UNIFORM_HEIGHT", this, ID_PACK_UNIFORM_HEIGHT);
284   new FXCheckButton(checksBR,"PACK_UNIFORM_WIDTH", this, ID_PACK_UNIFORM_WIDTH);
285   new FXRadioButton(checksBR,"MATRIX_BY_ROWS", this, ID_MATRIX_BY_ROWS);
286   new FXRadioButton(checksBR,"MATRIX_BY_COLUMNS", this, ID_MATRIX_BY_COLUMNS);
287   FXComposite *hf = new FXHorizontalFrame(checksBR,LAYOUT_FILL_X);
288   new FXLabel(hf, "Matrix Rows/cols:");
289   new FXSpinner(hf, 4, this, ID_MATRIX_ROWS_COLS,FRAME_SUNKEN|FRAME_THICK|SPIN_NOMAX|LAYOUT_CENTER_Y);
290 
291   FXComposite *bframe = new FXHorizontalFrame(controls,LAYOUT_BOTTOM|LAYOUT_FILL_X);
292   new FXButton(bframe,"&Add\tAdd a button",NULL,this,ID_ADD_BUTTON,FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X);
293   new FXButton(bframe,"&Clear\tRemove all buttons",NULL,this,ID_CLEAR_BUTTON,FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X);
294   new FXButton(bframe,"&Quit\tQuit program",NULL,getApp(),FXApp::ID_QUIT,FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_BOTTOM);
295   }
296 
297 
298 // Start
create()299 void ButtonWindow::create(){
300   FXMainWindow::create();
301   show(PLACEMENT_SCREEN);
302   }
303 
304 
305 // Change side of item inside packer
onCmdLayoutSide(FXObject *,FXSelector sel,void *)306 long ButtonWindow::onCmdLayoutSide(FXObject*,FXSelector sel,void*){
307   if(lastButton){
308     layoutHints=lastButton->getLayoutHints()&~LAYOUT_SIDE_MASK;
309     switch(FXSELID(sel)){
310       case ID_LAYOUT_SIDE_TOP:    layoutHints|=LAYOUT_SIDE_TOP; break;
311       case ID_LAYOUT_SIDE_BOTTOM: layoutHints|=LAYOUT_SIDE_BOTTOM; break;
312       case ID_LAYOUT_SIDE_LEFT:   layoutHints|=LAYOUT_SIDE_LEFT; break;
313       case ID_LAYOUT_SIDE_RIGHT:  layoutHints|=LAYOUT_SIDE_RIGHT; break;
314       }
315     lastButton->setLayoutHints(layoutHints);
316     }
317   return 1;
318   }
319 
320 
321 // Update side of item inside packer
onUpdLayoutSide(FXObject * sender,FXSelector sel,void *)322 long ButtonWindow::onUpdLayoutSide(FXObject* sender,FXSelector sel,void*){
323   if(lastButton){
324     FXuint hints=lastButton->getLayoutHints()&LAYOUT_SIDE_MASK;
325     FXint equal=FALSE;
326     switch(FXSELID(sel)){
327       case ID_LAYOUT_SIDE_TOP:    equal=(hints==LAYOUT_SIDE_TOP); break;
328       case ID_LAYOUT_SIDE_BOTTOM: equal=(hints==LAYOUT_SIDE_BOTTOM); break;
329       case ID_LAYOUT_SIDE_LEFT:   equal=(hints==LAYOUT_SIDE_LEFT); break;
330       case ID_LAYOUT_SIDE_RIGHT:  equal=(hints==LAYOUT_SIDE_RIGHT); break;
331       }
332     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
333     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
334     }
335   else{
336     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
337     }
338   return 1;
339   }
340 
341 // Change horizontal alignment
onCmdLayoutHorz(FXObject *,FXSelector sel,void *)342 long ButtonWindow::onCmdLayoutHorz(FXObject*,FXSelector sel,void*){
343   if(lastButton){
344     layoutHints=lastButton->getLayoutHints()&~LAYOUT_HORZ_MASK;
345     switch(FXSELID(sel)){
346       case ID_LAYOUT_LEFT:     layoutHints|=LAYOUT_LEFT; break;
347       case ID_LAYOUT_RIGHT:    layoutHints|=LAYOUT_RIGHT; break;
348       case ID_LAYOUT_CENTER_X: layoutHints|=LAYOUT_CENTER_X; break;
349       case ID_LAYOUT_FIX_X:    layoutHints|=LAYOUT_FIX_X; break;
350       }
351     lastButton->setLayoutHints(layoutHints);
352     }
353   return 1;
354   }
355 
356 
357 // Update horizontal alignment
onUpdLayoutHorz(FXObject * sender,FXSelector sel,void *)358 long ButtonWindow::onUpdLayoutHorz(FXObject* sender,FXSelector sel,void*){
359   if(lastButton){
360     FXuint hints=lastButton->getLayoutHints()&LAYOUT_HORZ_MASK;
361     FXint equal=FALSE;
362     switch(FXSELID(sel)){
363       case ID_LAYOUT_LEFT:     equal=(hints==LAYOUT_LEFT); break;
364       case ID_LAYOUT_RIGHT:    equal=(hints==LAYOUT_RIGHT); break;
365       case ID_LAYOUT_CENTER_X: equal=(hints==LAYOUT_CENTER_X); break;
366       case ID_LAYOUT_FIX_X:    equal=(hints==LAYOUT_FIX_X); break;
367       }
368     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
369     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
370     }
371   else{
372     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
373     }
374   return 1;
375   }
376 
377 
378 // Change vertical alignment
onCmdLayoutVert(FXObject *,FXSelector sel,void *)379 long ButtonWindow::onCmdLayoutVert(FXObject*,FXSelector sel,void*){
380   if(lastButton){
381     layoutHints=lastButton->getLayoutHints()&~LAYOUT_VERT_MASK;
382     switch(FXSELID(sel)){
383       case ID_LAYOUT_TOP:      layoutHints|=LAYOUT_TOP; break;
384       case ID_LAYOUT_BOTTOM:   layoutHints|=LAYOUT_BOTTOM; break;
385       case ID_LAYOUT_CENTER_Y: layoutHints|=LAYOUT_CENTER_Y; break;
386       case ID_LAYOUT_FIX_Y:    layoutHints|=LAYOUT_FIX_Y; break;
387       }
388     lastButton->setLayoutHints(layoutHints);
389     }
390   return 1;
391   }
392 
393 
394 // Update vertical alignment
onUpdLayoutVert(FXObject * sender,FXSelector sel,void *)395 long ButtonWindow::onUpdLayoutVert(FXObject* sender,FXSelector sel,void*){
396   if(lastButton){
397     FXuint hints=lastButton->getLayoutHints()&LAYOUT_VERT_MASK;
398     FXint equal=FALSE;
399     switch(FXSELID(sel)){
400       case ID_LAYOUT_TOP:      equal=(hints==LAYOUT_TOP); break;
401       case ID_LAYOUT_BOTTOM:   equal=(hints==LAYOUT_BOTTOM); break;
402       case ID_LAYOUT_CENTER_Y: equal=(hints==LAYOUT_CENTER_Y); break;
403       case ID_LAYOUT_FIX_Y:    equal=(hints==LAYOUT_FIX_Y); break;
404       }
405     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
406     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
407     }
408   else{
409     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
410     }
411   return 1;
412   }
413 
414 
415 // Change width
onCmdLayoutWidth(FXObject *,FXSelector sel,void *)416 long ButtonWindow::onCmdLayoutWidth(FXObject*,FXSelector sel,void*){
417   if(lastButton){
418     layoutHints=lastButton->getLayoutHints()&~LAYOUT_WIDTH_MASK;
419     switch(FXSELID(sel)){
420       case ID_LAYOUT_MIN_WIDTH: layoutHints|=LAYOUT_MIN_WIDTH; break;
421       case ID_LAYOUT_FIX_WIDTH: layoutHints|=LAYOUT_FIX_WIDTH; break;
422       case ID_LAYOUT_FILL_X:    layoutHints|=LAYOUT_FILL_X; break;
423       }
424     lastButton->setLayoutHints(layoutHints);
425     }
426   return 1;
427   }
428 
429 
430 // Update width
onUpdLayoutWidth(FXObject * sender,FXSelector sel,void *)431 long ButtonWindow::onUpdLayoutWidth(FXObject* sender,FXSelector sel,void*){
432   if(lastButton){
433     FXuint hints=lastButton->getLayoutHints()&LAYOUT_WIDTH_MASK;
434     FXint equal=FALSE;
435     switch(FXSELID(sel)){
436       case ID_LAYOUT_MIN_WIDTH: equal=(hints==LAYOUT_MIN_WIDTH); break;
437       case ID_LAYOUT_FIX_WIDTH: equal=(hints==LAYOUT_FIX_WIDTH); break;
438       case ID_LAYOUT_FILL_X:    equal=(hints==LAYOUT_FILL_X); break;
439       }
440     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
441     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
442     }
443   else{
444     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
445     }
446   return 1;
447   }
448 
449 // Change height
onCmdLayoutHeight(FXObject *,FXSelector sel,void *)450 long ButtonWindow::onCmdLayoutHeight(FXObject*,FXSelector sel,void*){
451   if(lastButton){
452     layoutHints=lastButton->getLayoutHints()&~LAYOUT_HEIGHT_MASK;
453     switch(FXSELID(sel)){
454       case ID_LAYOUT_MIN_HEIGHT: layoutHints|=LAYOUT_MIN_HEIGHT; break;
455       case ID_LAYOUT_FIX_HEIGHT: layoutHints|=LAYOUT_FIX_HEIGHT; break;
456       case ID_LAYOUT_FILL_Y:     layoutHints|=LAYOUT_FILL_Y; break;
457       }
458     lastButton->setLayoutHints(layoutHints);
459     }
460   return 1;
461   }
462 
463 
464 // Update height
onUpdLayoutHeight(FXObject * sender,FXSelector sel,void *)465 long ButtonWindow::onUpdLayoutHeight(FXObject* sender,FXSelector sel,void*){
466   if(lastButton){
467     FXuint hints=lastButton->getLayoutHints()&LAYOUT_HEIGHT_MASK;
468     FXint equal=FALSE;
469     switch(FXSELID(sel)){
470       case ID_LAYOUT_MIN_HEIGHT: equal=(hints==LAYOUT_MIN_HEIGHT); break;
471       case ID_LAYOUT_FIX_HEIGHT: equal=(hints==LAYOUT_FIX_HEIGHT); break;
472       case ID_LAYOUT_FILL_Y:     equal=(hints==LAYOUT_FILL_Y); break;
473       }
474     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
475     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
476     }
477   else{
478     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
479     }
480   return 1;
481   }
482 
483 // Change matrix layout
onCmdLayoutMatrix(FXObject *,FXSelector sel,void *)484 long ButtonWindow::onCmdLayoutMatrix(FXObject*,FXSelector sel,void*){
485   if(lastButton){
486     layoutHints=lastButton->getLayoutHints();
487     switch(FXSELID(sel)){
488       case ID_LAYOUT_FILL_COLUMN: layoutHints^=LAYOUT_FILL_COLUMN; break;
489       case ID_LAYOUT_FILL_ROW:  layoutHints^=LAYOUT_FILL_ROW; break;
490       }
491     lastButton->setLayoutHints(layoutHints);
492     }
493   return 1;
494   }
495 
496 
497 // Update matrix layout
onUpdLayoutMatrix(FXObject * sender,FXSelector sel,void *)498 long ButtonWindow::onUpdLayoutMatrix(FXObject* sender,FXSelector sel,void*){
499   if(lastButton){
500     FXuint hints=lastButton->getLayoutHints();
501     FXuint equal=0;
502     switch(FXSELID(sel)){
503       case ID_LAYOUT_FILL_COLUMN: equal=(hints&LAYOUT_FILL_COLUMN)!=0; break;
504       case ID_LAYOUT_FILL_ROW:    equal=(hints&LAYOUT_FILL_ROW)!=0; break;
505       }
506     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
507     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
508     }
509   else{
510     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
511     }
512   return 1;
513   }
514 
515 
516 // Change packing
onCmdPackHints(FXObject *,FXSelector sel,void *)517 long ButtonWindow::onCmdPackHints(FXObject*,FXSelector sel,void*){
518   FXPacker *packer=dynamic_cast<FXPacker*>(contents);
519   if(packer){
520     FXuint hints=packer->getPackingHints();
521     switch(FXSELID(sel)){
522       case ID_PACK_UNIFORM_HEIGHT: hints^=PACK_UNIFORM_HEIGHT; break;
523       case ID_PACK_UNIFORM_WIDTH:  hints^=PACK_UNIFORM_WIDTH; break;
524       }
525     packer->setPackingHints(hints);
526     }
527   return 1;
528   }
529 
530 
531 // Update packing
onUpdPackHints(FXObject * sender,FXSelector sel,void *)532 long ButtonWindow::onUpdPackHints(FXObject* sender,FXSelector sel,void*){
533   FXPacker *packer=dynamic_cast<FXPacker*>(contents);
534   if(packer){
535     FXuint hints=packer->getPackingHints()&(PACK_UNIFORM_HEIGHT|PACK_UNIFORM_WIDTH);
536     FXuint equal=0;
537     switch(FXSELID(sel)){
538       case ID_PACK_UNIFORM_HEIGHT: equal=(hints&PACK_UNIFORM_HEIGHT)!=0; break;
539       case ID_PACK_UNIFORM_WIDTH:  equal=(hints&PACK_UNIFORM_WIDTH)!=0; break;
540       }
541     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
542     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
543     }
544   else{
545     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
546     }
547   return 1;
548   }
549 
550 
551 // Change Matrix mode
onCmdMatrixMode(FXObject *,FXSelector sel,void *)552 long ButtonWindow::onCmdMatrixMode(FXObject*,FXSelector sel,void*){
553   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
554   if(matrix){
555     FXuint style=matrix->getMatrixStyle();
556     switch(FXSELID(sel)){
557       case ID_MATRIX_BY_COLUMNS: style|=MATRIX_BY_COLUMNS; break;
558       case ID_MATRIX_BY_ROWS:    style&=~MATRIX_BY_COLUMNS; break;
559       }
560     matrix->setMatrixStyle(style);
561     }
562   return 1;
563   }
564 
565 
566 // Update Matrix mode
onUpdMatrixMode(FXObject * sender,FXSelector sel,void *)567 long ButtonWindow::onUpdMatrixMode(FXObject* sender,FXSelector sel,void*){
568   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
569   if(matrix){
570     FXuint style=matrix->getMatrixStyle();
571     FXuint equal=0;
572     switch(FXSELID(sel)){
573       case ID_MATRIX_BY_COLUMNS: equal=(style&MATRIX_BY_COLUMNS)!=0; break;
574       case ID_MATRIX_BY_ROWS:    equal=(style&MATRIX_BY_COLUMNS)==0; break;
575       }
576     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&equal);
577     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
578     }
579   else{
580     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
581     }
582   return 1;
583   }
584 
585 
586 // Change container type, reparent existing widgets into it
onCmdContainerType(FXObject *,FXSelector sel,void *)587 long ButtonWindow::onCmdContainerType(FXObject*,FXSelector sel,void*){
588   FXComposite *old=contents;
589   switch(FXSELID(sel)){
590     case ID_CONTAINER_COMPOSITE:
591       contents=new FXComposite(this,LAYOUT_SIDE_LEFT|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
592       contents->create();
593       break;
594     case ID_CONTAINER_HORIZONTAL_FRAME:
595       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);
596       contents->create();
597       break;
598     case ID_CONTAINER_VERTICAL_FRAME:
599       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);
600       contents->create();
601       break;
602     case ID_CONTAINER_PACKER:
603       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);
604       contents->create();
605       break;
606     case ID_CONTAINER_MATRIX:
607       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);
608       contents->create();
609       break;
610     }
611   while(old->getFirst()){
612     old->getFirst()->reparent(contents);
613     }
614   contents->setBackColor(FXRGB(192,128,128));
615   contents->recalc();
616   delete old;
617   return 1;
618   }
619 
620 
621 // Update container type
onUpdContainerType(FXObject * sender,FXSelector sel,void *)622 long ButtonWindow::onUpdContainerType(FXObject* sender,FXSelector sel,void*){
623   const FXMetaClass *mc=contents->getMetaClass();
624   switch(FXSELID(sel)){
625     case ID_CONTAINER_COMPOSITE:
626       sender->handle(this,(mc==&FXComposite::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
627       break;
628     case ID_CONTAINER_HORIZONTAL_FRAME:
629       sender->handle(this,(mc==&FXHorizontalFrame::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
630       break;
631     case ID_CONTAINER_VERTICAL_FRAME:
632       sender->handle(this,(mc==&FXVerticalFrame::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
633       break;
634     case ID_CONTAINER_PACKER:
635       sender->handle(this,(mc==&FXPacker::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
636       break;
637     case ID_CONTAINER_MATRIX:
638       sender->handle(this,(mc==&FXMatrix::metaClass)?FXSEL(SEL_COMMAND,ID_CHECK):FXSEL(SEL_COMMAND,ID_UNCHECK),NULL);
639       break;
640     }
641   return 1;
642   }
643 
644 
645 // Change fixed stuff
onChgFixVal(FXObject * sender,FXSelector sel,void *)646 long ButtonWindow::onChgFixVal(FXObject*sender,FXSelector sel,void*){
647   FXint val=0;
648   if(lastButton){
649     sender->handle(this,FXSEL(SEL_COMMAND,ID_GETINTVALUE),(void*)&val);
650     switch(FXSELID(sel)){
651       case ID_FIX_X_VAL: lastButton->setX(val); break;
652       case ID_FIX_Y_VAL: lastButton->setY(val); break;
653       case ID_FIX_W_VAL: lastButton->setWidth(val); break;
654       case ID_FIX_H_VAL: lastButton->setHeight(val); break;
655       }
656     contents->recalc();
657     }
658   return 1;
659   }
660 
661 
662 // Update fixed stuff
onUpdFixVal(FXObject * sender,FXSelector sel,void *)663 long ButtonWindow::onUpdFixVal(FXObject*sender,FXSelector sel,void*){
664   if(lastButton){
665     FXint val=0;
666     switch(FXSELID(sel)){
667       case ID_FIX_X_VAL: val=lastButton->getX(); break;
668       case ID_FIX_Y_VAL: val=lastButton->getY(); break;
669       case ID_FIX_W_VAL: val=lastButton->getWidth(); break;
670       case ID_FIX_H_VAL: val=lastButton->getHeight(); break;
671       }
672     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),(void*)&val);
673     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
674     }
675   else{
676     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
677     }
678   return 1;
679   }
680 
681 
682 // Change number of rows or columns
onChgMatVal(FXObject * sender,FXSelector,void *)683 long ButtonWindow::onChgMatVal(FXObject*sender,FXSelector,void*){
684   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
685   if(matrix){
686     FXint val;
687     sender->handle(this,FXSEL(SEL_COMMAND,ID_GETINTVALUE),(void*)&val);
688     if(matrix->getMatrixStyle()&MATRIX_BY_COLUMNS){
689       matrix->setNumColumns(val);
690       }
691     else{
692       matrix->setNumRows(val);
693       }
694     }
695   return 1;
696   }
697 
698 
699 // Update number of rows or columns
onUpdMatVal(FXObject * sender,FXSelector,void *)700 long ButtonWindow::onUpdMatVal(FXObject* sender,FXSelector,void*){
701   FXMatrix *matrix=dynamic_cast<FXMatrix*>(contents);
702   if(matrix){
703     FXint val;
704     if(matrix->getMatrixStyle()&MATRIX_BY_COLUMNS){
705       val=matrix->getNumColumns();
706       }
707     else{
708       val=matrix->getNumRows();
709       }
710     sender->handle(this,FXSEL(SEL_COMMAND,ID_SETINTVALUE),&val);
711     sender->handle(this,FXSEL(SEL_COMMAND,ID_ENABLE),NULL);
712     }
713   else{
714     sender->handle(this,FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
715     }
716   return 1;
717   }
718 
719 
720 // Clear buttons from the container
onCmdClearButton(FXObject *,FXSelector,void *)721 long ButtonWindow::onCmdClearButton(FXObject*,FXSelector,void*){
722   while(contents->getFirst()){
723     delete contents->getFirst();
724     }
725   contents->recalc();
726   lastButton=NULL;
727   nextButtonNum=0;
728   return 1;
729   }
730 
731 
onUpdClearButton(FXObject * sender,FXSelector,void *)732 long ButtonWindow::onUpdClearButton(FXObject* sender,FXSelector,void*){
733   sender->handle(this,contents->getFirst()?FXSEL(SEL_COMMAND,ID_ENABLE):FXSEL(SEL_COMMAND,ID_DISABLE),NULL);
734   return 1;
735   }
736 
737 // Add a button to the container
onCmdAddButton(FXObject *,FXSelector,void *)738 long ButtonWindow::onCmdAddButton(FXObject*,FXSelector,void*){
739   static const FXchar *titles[]={"Button %d\tClick to make active", "Wide Button %d\tClick to make active", "Tall\nButton %d\tClick to make active"};
740   FXString string;
741   string.format(titles[nextButtonNum%3],nextButtonNum);
742   lastButton=new FXButton(contents,string,NULL,this,ID_BUTTON,FRAME_THICK|FRAME_RAISED|layoutHints);
743   lastButton->create();
744   lastButton->recalc();
745   nextButtonNum++;
746   return 1;
747   }
748 
749 
750 // Make this one the active button
onCmdButton(FXObject * sender,FXSelector,void *)751 long ButtonWindow::onCmdButton(FXObject* sender,FXSelector,void*){
752   lastButton=(FXButton*)sender;
753   layoutHints=lastButton->getLayoutHints();
754   return 1;
755   }
756 
757 
758 /*******************************************************************************/
759 
760 
761 // Start the whole thing
main(int argc,char * argv[])762 int main(int argc,char *argv[]){
763 
764   // Make application
765   FXApp application("Layout","FoxTest");
766 
767   // Open display
768   application.init(argc,argv);
769 
770   // Main window
771   new ButtonWindow(&application);
772 
773   // Create app
774   application.create();
775 
776   // Run
777   return application.run();
778   }
779 
780 
781