1 /********************************************************************************
2 *                                                                               *
3 *                         Scribble  Application coding sample                   *
4 *                                                                               *
5 ********************************************************************************/
6 #include "fx.h"
7 
8 
9 
10 // Main Window
11 class ScribbleWindow : public FXMainWindow {
12 
13   // Macro for class hierarchy declarations
14   FXDECLARE(ScribbleWindow)
15 
16 private:
17 
18   FXHorizontalFrame *contents;                // Content frame
19   FXVerticalFrame   *canvasFrame;             // Canvas frame
20   FXVerticalFrame   *buttonFrame;             // Button frame
21   FXCanvas          *canvas;                  // Canvas to draw into
22   int                mdflag;                  // Mouse button down?
23   int                dirty;                   // Canvas has been painted?
24   FXColor            drawColor;               // Color for the line
25 protected:
ScribbleWindow()26   ScribbleWindow(){}
27 
28 public:
29 
30   // Message handlers
31   long onPaint(FXObject*,FXSelector,void*);
32   long onMouseDown(FXObject*,FXSelector,void*);
33   long onMouseUp(FXObject*,FXSelector,void*);
34   long onMouseMove(FXObject*,FXSelector,void*);
35   long onCmdClear(FXObject*,FXSelector,void*);
36   long onUpdClear(FXObject*,FXSelector,void*);
37 
38 public:
39 
40   // Messages for our class
41   enum{
42     ID_CANVAS=FXMainWindow::ID_LAST,
43     ID_CLEAR,
44     ID_LAST
45     };
46 
47 public:
48 
49   // ScribbleWindow's constructor
50   ScribbleWindow(FXApp* a);
51 
52   // Initialize
53   virtual void create();
54 
55   virtual ~ScribbleWindow();
56   };
57 
58 
59 
60 // Message Map for the Scribble Window class
61 FXDEFMAP(ScribbleWindow) ScribbleWindowMap[]={
62 
63   //________Message_Type_____________________ID____________Message_Handler_______
64   FXMAPFUNC(SEL_PAINT,             ScribbleWindow::ID_CANVAS, ScribbleWindow::onPaint),
65   FXMAPFUNC(SEL_LEFTBUTTONPRESS,   ScribbleWindow::ID_CANVAS, ScribbleWindow::onMouseDown),
66   FXMAPFUNC(SEL_LEFTBUTTONRELEASE, ScribbleWindow::ID_CANVAS, ScribbleWindow::onMouseUp),
67   FXMAPFUNC(SEL_MOTION,            ScribbleWindow::ID_CANVAS, ScribbleWindow::onMouseMove),
68   FXMAPFUNC(SEL_COMMAND,           ScribbleWindow::ID_CLEAR,  ScribbleWindow::onCmdClear),
69   FXMAPFUNC(SEL_UPDATE,            ScribbleWindow::ID_CLEAR,  ScribbleWindow::onUpdClear),
70   };
71 
72 
73 
74 // Macro for the ScribbleApp class hierarchy implementation
FXIMPLEMENT(ScribbleWindow,FXMainWindow,ScribbleWindowMap,ARRAYNUMBER (ScribbleWindowMap))75 FXIMPLEMENT(ScribbleWindow,FXMainWindow,ScribbleWindowMap,ARRAYNUMBER(ScribbleWindowMap))
76 
77 
78 
79 // Construct a ScribbleWindow
80 ScribbleWindow::ScribbleWindow(FXApp *a):FXMainWindow(a,"Scribble Application",NULL,NULL,DECOR_ALL,0,0,800,600){
81 
82   contents=new FXHorizontalFrame(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0);
83 
84   // LEFT pane to contain the canvas
85   canvasFrame=new FXVerticalFrame(contents,FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,10,10);
86 
87     // Label above the canvas
88     new FXLabel(canvasFrame,"Canvas Frame",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X);
89 
90     // Horizontal divider line
91     new FXHorizontalSeparator(canvasFrame,SEPARATOR_GROOVE|LAYOUT_FILL_X);
92 
93 
94     // Drawing canvas
95     canvas=new FXCanvas(canvasFrame,this,ID_CANVAS,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_ROW|LAYOUT_FILL_COLUMN);
96 
97   // RIGHT pane for the buttons
98   buttonFrame=new FXVerticalFrame(contents,FRAME_SUNKEN|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,10,10);
99 
100     // Label above the buttons
101     new FXLabel(buttonFrame,"Button Frame",NULL,JUSTIFY_CENTER_X|LAYOUT_FILL_X);
102 
103     // Horizontal divider line
104     new FXHorizontalSeparator(buttonFrame,SEPARATOR_RIDGE|LAYOUT_FILL_X);
105 
106     // Button to clear
107     new FXButton(buttonFrame,"&Clear",NULL,this,ID_CLEAR,FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,5,5);
108 
109     // Exit button
110     new FXButton(buttonFrame,"&Exit",NULL,getApp(),FXApp::ID_QUIT,FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT,0,0,0,0,10,10,5,5);
111 
112   // Initialize private variables
113   drawColor=FXRGB(255,0,0);
114   mdflag=0;
115   dirty=0;
116   }
117 
118 
~ScribbleWindow()119 ScribbleWindow::~ScribbleWindow(){
120   }
121 
122 
123 // Create and initialize
create()124 void ScribbleWindow::create(){
125 
126   // Create the windows
127   FXMainWindow::create();
128 
129   // Make the main window appear
130   show(PLACEMENT_SCREEN);
131   }
132 
133 
134 
135 // Mouse button was pressed somewhere
onMouseDown(FXObject *,FXSelector,void *)136 long ScribbleWindow::onMouseDown(FXObject*,FXSelector,void*){
137   canvas->grab();
138 
139   // While the mouse is down, we'll draw lines
140   mdflag=1;
141 
142   return 1;
143   }
144 
145 
146 
147 // The mouse has moved, draw a line
onMouseMove(FXObject *,FXSelector,void * ptr)148 long ScribbleWindow::onMouseMove(FXObject*, FXSelector, void* ptr){
149   FXEvent *ev=(FXEvent*)ptr;
150 
151   // Draw
152   if(mdflag){
153 
154     // Get DC for the canvas
155     FXDCWindow dc(canvas);
156 
157     // Set foreground color
158     dc.setForeground(drawColor);
159 
160     // Draw line
161     dc.drawLine(ev->last_x, ev->last_y, ev->win_x, ev->win_y);
162 
163     // We have drawn something, so now the canvas is dirty
164     dirty=1;
165     }
166   return 1;
167   }
168 
169 
170 
171 // The mouse button was released again
onMouseUp(FXObject *,FXSelector,void * ptr)172 long ScribbleWindow::onMouseUp(FXObject*,FXSelector,void* ptr){
173   FXEvent *ev=(FXEvent*) ptr;
174   canvas->ungrab();
175   if(mdflag){
176     FXDCWindow dc(canvas);
177 
178     dc.setForeground(drawColor);
179     dc.drawLine(ev->last_x, ev->last_y, ev->win_x, ev->win_y);
180 
181     // We have drawn something, so now the canvas is dirty
182     dirty=1;
183 
184     // Mouse no longer down
185     mdflag=0;
186     }
187   return 1;
188   }
189 
190 
191 // Paint the canvas
onPaint(FXObject *,FXSelector,void * ptr)192 long ScribbleWindow::onPaint(FXObject*,FXSelector,void* ptr){
193   FXEvent *ev=(FXEvent*)ptr;
194   FXDCWindow dc(canvas,ev);
195   dc.setForeground(canvas->getBackColor());
196   dc.fillRectangle(ev->rect.x,ev->rect.y,ev->rect.w,ev->rect.h);
197   return 1;
198   }
199 
200 
201 // Handle the clear message
onCmdClear(FXObject *,FXSelector,void *)202 long ScribbleWindow::onCmdClear(FXObject*,FXSelector,void*){
203   FXDCWindow dc(canvas);
204   dc.setForeground(canvas->getBackColor());
205   dc.fillRectangle(0,0,canvas->getWidth(),canvas->getHeight());
206   dirty=0;
207   return 1;
208   }
209 
210 
211 
212 // Update the clear button:- each gui element (widget) in FOX
213 // receives a message during idle processing asking it to be updated.
214 // For example, buttons can be sensitized or desensitized when the
215 // state of the application changes.
216 // In this case, we desensitize the sender (the clear button) when
217 // the canvas has already been cleared, and sensitize it when it has
218 // been painted (as indicated by the dirty flag).
onUpdClear(FXObject * sender,FXSelector,void *)219 long ScribbleWindow::onUpdClear(FXObject* sender,FXSelector,void*){
220 
221   if(dirty)
222     sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_ENABLE),NULL);
223   else
224     sender->handle(this,FXSEL(SEL_COMMAND,FXWindow::ID_DISABLE),NULL);
225 
226   return 1;
227   }
228 
229 
230 // Here we begin
main(int argc,char * argv[])231 int main(int argc,char *argv[]){
232 
233   // Make application
234   FXApp application("Scribble","FoxTest");
235 
236   // Start app
237   application.init(argc,argv);
238 
239   // Scribble window
240   new ScribbleWindow(&application);
241 
242   // Create the application's windows
243   application.create();
244 
245   // Run the application
246   return application.run();
247   }
248 
249 
250 
251 
252