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