1 | // |
---|
2 | // "$Id$" |
---|
3 | // |
---|
4 | // Window type code for the Fast Light Tool Kit (FLTK). |
---|
5 | // |
---|
6 | // The widget describing an Fl_Window. This is also all the code |
---|
7 | // for interacting with the overlay, which allows the user to |
---|
8 | // select, move, and resize the children widgets. |
---|
9 | // |
---|
10 | // Copyright 1998-2006 by Bill Spitzak and others. |
---|
11 | // |
---|
12 | // This library is free software; you can redistribute it and/or |
---|
13 | // modify it under the terms of the GNU Library General Public |
---|
14 | // License as published by the Free Software Foundation; either |
---|
15 | // version 2 of the License, or (at your option) any later version. |
---|
16 | // |
---|
17 | // This library is distributed in the hope that it will be useful, |
---|
18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
20 | // Library General Public License for more details. |
---|
21 | // |
---|
22 | // You should have received a copy of the GNU Library General Public |
---|
23 | // License along with this library; if not, write to the Free Software |
---|
24 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
---|
25 | // USA. |
---|
26 | // |
---|
27 | // Please report all bugs and problems on the following page: |
---|
28 | // |
---|
29 | // http://www.fltk.org/str.php |
---|
30 | // |
---|
31 | |
---|
32 | #include <FL/Fl.H> |
---|
33 | #include <FL/Fl_Overlay_Window.H> |
---|
34 | #include <FL/fl_message.H> |
---|
35 | #include <FL/fl_draw.H> |
---|
36 | #include <FL/x.H> |
---|
37 | #include <FL/Fl_Menu_Item.H> |
---|
38 | #include <FL/Fl_Round_Button.H> |
---|
39 | #include "Fl_Widget_Type.h" |
---|
40 | #include "undo.h" |
---|
41 | #include <math.h> |
---|
42 | #include <stdlib.h> |
---|
43 | #include "alignment_panel.h" |
---|
44 | #include <stdio.h> |
---|
45 | |
---|
46 | extern int gridx; |
---|
47 | extern int gridy; |
---|
48 | extern int snap; |
---|
49 | extern int show_guides; |
---|
50 | |
---|
51 | int include_H_from_C = 1; |
---|
52 | int use_FL_COMMAND = 0; |
---|
53 | extern int i18n_type; |
---|
54 | extern const char* i18n_include; |
---|
55 | extern const char* i18n_function; |
---|
56 | extern const char* i18n_file; |
---|
57 | extern const char* i18n_set; |
---|
58 | |
---|
59 | extern Fl_Preferences fluid_prefs; |
---|
60 | |
---|
61 | inline int fl_min(int a, int b) { return (a < b ? a : b); } |
---|
62 | |
---|
63 | #include "widget_panel.h" |
---|
64 | |
---|
65 | // Update the XYWH values in the widget panel... |
---|
66 | static void update_xywh() { |
---|
67 | if (current_widget && current_widget->is_widget()) { |
---|
68 | widget_x_input->value(((Fl_Widget_Type *)current_widget)->o->x()); |
---|
69 | widget_y_input->value(((Fl_Widget_Type *)current_widget)->o->y()); |
---|
70 | widget_w_input->value(((Fl_Widget_Type *)current_widget)->o->w()); |
---|
71 | widget_h_input->value(((Fl_Widget_Type *)current_widget)->o->h()); |
---|
72 | } |
---|
73 | } |
---|
74 | |
---|
75 | void guides_cb(Fl_Check_Button *i, long) { |
---|
76 | show_guides = i->value(); |
---|
77 | fluid_prefs.set("show_guides", show_guides); |
---|
78 | |
---|
79 | for (Fl_Type *p = Fl_Type::first; p; p = p->next) { |
---|
80 | if (p->is_window()) { |
---|
81 | Fl_Window_Type *w = (Fl_Window_Type *)p; |
---|
82 | ((Fl_Overlay_Window *)(w->o))->redraw_overlay(); |
---|
83 | } |
---|
84 | } |
---|
85 | } |
---|
86 | |
---|
87 | void grid_cb(Fl_Input *i, long v) { |
---|
88 | int n = atoi(i->value()); |
---|
89 | if (n < 0) n = 0; |
---|
90 | switch (v) { |
---|
91 | case 1: |
---|
92 | gridx = n; |
---|
93 | fluid_prefs.set("gridx", n); |
---|
94 | break; |
---|
95 | case 2: |
---|
96 | gridy = n; |
---|
97 | fluid_prefs.set("gridy", n); |
---|
98 | break; |
---|
99 | case 3: |
---|
100 | snap = n; |
---|
101 | fluid_prefs.set("snap", n); |
---|
102 | break; |
---|
103 | } |
---|
104 | |
---|
105 | // Next go through all of the windows in the project and set the |
---|
106 | // stepping for resizes... |
---|
107 | Fl_Type *p; |
---|
108 | Fl_Window_Type *w; |
---|
109 | |
---|
110 | for (p = Fl_Type::first; p; p = p->next) { |
---|
111 | if (p->is_window()) { |
---|
112 | w = (Fl_Window_Type *)p; |
---|
113 | ((Fl_Window *)(w->o))->size_range(gridx, gridy, |
---|
114 | Fl::w(), Fl::h(), |
---|
115 | gridx, gridy, 0); |
---|
116 | } |
---|
117 | } |
---|
118 | } |
---|
119 | |
---|
120 | // Set default widget sizes... |
---|
121 | void default_widget_size_cb(Fl_Round_Button *b, long size) { |
---|
122 | // Update the "normal" text size of new widgets... |
---|
123 | b->setonly(); |
---|
124 | Fl_Widget_Type::default_size = size; |
---|
125 | fluid_prefs.set("widget_size", Fl_Widget_Type::default_size); |
---|
126 | } |
---|
127 | |
---|
128 | |
---|
129 | void i18n_type_cb(Fl_Choice *c, void *) { |
---|
130 | undo_checkpoint(); |
---|
131 | |
---|
132 | switch (i18n_type = c->value()) { |
---|
133 | case 0 : /* None */ |
---|
134 | i18n_include_input->hide(); |
---|
135 | i18n_file_input->hide(); |
---|
136 | i18n_set_input->hide(); |
---|
137 | i18n_function_input->hide(); |
---|
138 | break; |
---|
139 | case 1 : /* GNU gettext */ |
---|
140 | i18n_include_input->value("<libintl.h>"); |
---|
141 | i18n_include = i18n_include_input->value(); |
---|
142 | i18n_function_input->value("gettext"); |
---|
143 | i18n_function = i18n_function_input->value(); |
---|
144 | i18n_include_input->show(); |
---|
145 | i18n_file_input->hide(); |
---|
146 | i18n_set_input->hide(); |
---|
147 | i18n_function_input->show(); |
---|
148 | break; |
---|
149 | case 2 : /* POSIX cat */ |
---|
150 | i18n_include_input->value("<nl_types.h>"); |
---|
151 | i18n_file_input->value(""); |
---|
152 | i18n_file = i18n_file_input->value(); |
---|
153 | i18n_set_input->value("1"); |
---|
154 | i18n_set = i18n_set_input->value(); |
---|
155 | i18n_include_input->show(); |
---|
156 | i18n_include = i18n_include_input->value(); |
---|
157 | i18n_file_input->show(); |
---|
158 | i18n_set_input->show(); |
---|
159 | i18n_function_input->hide(); |
---|
160 | break; |
---|
161 | } |
---|
162 | |
---|
163 | set_modflag(1); |
---|
164 | } |
---|
165 | |
---|
166 | void i18n_text_cb(Fl_Input *i, void *) { |
---|
167 | undo_checkpoint(); |
---|
168 | |
---|
169 | if (i == i18n_function_input) |
---|
170 | i18n_function = i->value(); |
---|
171 | else if (i == i18n_file_input) |
---|
172 | i18n_file = i->value(); |
---|
173 | else if (i == i18n_set_input) |
---|
174 | i18n_set = i->value(); |
---|
175 | else if (i == i18n_include_input) |
---|
176 | i18n_include = i->value(); |
---|
177 | |
---|
178 | set_modflag(1); |
---|
179 | } |
---|
180 | |
---|
181 | extern const char* header_file_name; |
---|
182 | extern const char* code_file_name; |
---|
183 | |
---|
184 | void show_project_cb(Fl_Widget *, void *) { |
---|
185 | if(project_window==0) make_project_window(); |
---|
186 | include_H_from_C_button->value(include_H_from_C); |
---|
187 | use_FL_COMMAND_button->value(use_FL_COMMAND); |
---|
188 | header_file_input->value(header_file_name); |
---|
189 | code_file_input->value(code_file_name); |
---|
190 | i18n_type_chooser->value(i18n_type); |
---|
191 | i18n_function_input->value(i18n_function); |
---|
192 | i18n_file_input->value(i18n_file); |
---|
193 | i18n_set_input->value(i18n_set); |
---|
194 | i18n_include_input->value(i18n_include); |
---|
195 | switch (i18n_type) { |
---|
196 | case 0 : /* None */ |
---|
197 | i18n_include_input->hide(); |
---|
198 | i18n_file_input->hide(); |
---|
199 | i18n_set_input->hide(); |
---|
200 | i18n_function_input->hide(); |
---|
201 | break; |
---|
202 | case 1 : /* GNU gettext */ |
---|
203 | i18n_include_input->show(); |
---|
204 | i18n_file_input->hide(); |
---|
205 | i18n_set_input->hide(); |
---|
206 | i18n_function_input->show(); |
---|
207 | break; |
---|
208 | case 2 : /* POSIX cat */ |
---|
209 | i18n_include_input->show(); |
---|
210 | i18n_file_input->show(); |
---|
211 | i18n_set_input->show(); |
---|
212 | i18n_function_input->hide(); |
---|
213 | break; |
---|
214 | } |
---|
215 | project_window->hotspot(project_window); |
---|
216 | project_window->show(); |
---|
217 | } |
---|
218 | |
---|
219 | void show_grid_cb(Fl_Widget *, void *) { |
---|
220 | char buf[128]; |
---|
221 | sprintf(buf,"%d",gridx); horizontal_input->value(buf); |
---|
222 | sprintf(buf,"%d",gridy); vertical_input->value(buf); |
---|
223 | sprintf(buf,"%d",snap); snap_input->value(buf); |
---|
224 | guides_toggle->value(show_guides); |
---|
225 | int s = Fl_Widget_Type::default_size; |
---|
226 | if (s<=8) def_widget_size[0]->setonly(); |
---|
227 | else if (s<=11) def_widget_size[1]->setonly(); |
---|
228 | else if (s<=14) def_widget_size[2]->setonly(); |
---|
229 | else if (s<=18) def_widget_size[3]->setonly(); |
---|
230 | else if (s<=24) def_widget_size[4]->setonly(); |
---|
231 | else if (s<=32) def_widget_size[5]->setonly(); |
---|
232 | grid_window->hotspot(grid_window); |
---|
233 | grid_window->show(); |
---|
234 | } |
---|
235 | |
---|
236 | void show_settings_cb(Fl_Widget *, void *) { |
---|
237 | settings_window->hotspot(settings_window); |
---|
238 | settings_window->show(); |
---|
239 | } |
---|
240 | |
---|
241 | void header_input_cb(Fl_Input* i, void*) { |
---|
242 | if (header_file_name && strcmp(header_file_name, i->value())) |
---|
243 | set_modflag(1); |
---|
244 | header_file_name = i->value(); |
---|
245 | } |
---|
246 | void code_input_cb(Fl_Input* i, void*) { |
---|
247 | if (code_file_name && strcmp(code_file_name, i->value())) |
---|
248 | set_modflag(1); |
---|
249 | code_file_name = i->value(); |
---|
250 | } |
---|
251 | |
---|
252 | void include_H_from_C_button_cb(Fl_Check_Button* b, void*) { |
---|
253 | if (include_H_from_C != b->value()) { |
---|
254 | set_modflag(1); |
---|
255 | include_H_from_C = b->value(); |
---|
256 | } |
---|
257 | } |
---|
258 | |
---|
259 | void use_FL_COMMAND_button_cb(Fl_Check_Button* b, void*) { |
---|
260 | if (use_FL_COMMAND != b->value()) { |
---|
261 | set_modflag(1); |
---|
262 | use_FL_COMMAND = b->value(); |
---|
263 | } |
---|
264 | } |
---|
265 | |
---|
266 | //////////////////////////////////////////////////////////////// |
---|
267 | |
---|
268 | Fl_Menu_Item window_type_menu[] = { |
---|
269 | {"Single",0,0,(void*)FL_WINDOW}, |
---|
270 | {"Double",0,0,(void*)(FL_WINDOW+1)}, |
---|
271 | {0}}; |
---|
272 | |
---|
273 | static int overlays_invisible; |
---|
274 | |
---|
275 | // The following Fl_Widget is used to simulate the windows. It has |
---|
276 | // an overlay for the fluid ui, and special-cases the FL_NO_BOX. |
---|
277 | |
---|
278 | class Overlay_Window : public Fl_Overlay_Window { |
---|
279 | void draw(); |
---|
280 | void draw_overlay(); |
---|
281 | public: |
---|
282 | Fl_Window_Type *window; |
---|
283 | int handle(int); |
---|
284 | Overlay_Window(int W,int H) : Fl_Overlay_Window(W,H) {Fl_Group::current(0);} |
---|
285 | void resize(int,int,int,int); |
---|
286 | uchar *read_image(int &ww, int &hh); |
---|
287 | }; |
---|
288 | void Overlay_Window::draw() { |
---|
289 | const int CHECKSIZE = 8; |
---|
290 | // see if box is clear or a frame or rounded: |
---|
291 | if ((damage()&FL_DAMAGE_ALL) && |
---|
292 | (!box() || (box()>=4&&!(box()&2)) || box()>=_FL_ROUNDED_BOX)) { |
---|
293 | // if so, draw checkerboard so user can see what areas are clear: |
---|
294 | for (int Y = 0; Y < h(); Y += CHECKSIZE) |
---|
295 | for (int X = 0; X < w(); X += CHECKSIZE) { |
---|
296 | fl_color(((Y/(2*CHECKSIZE))&1) != ((X/(2*CHECKSIZE))&1) ? |
---|
297 | FL_WHITE : FL_BLACK); |
---|
298 | fl_rectf(X,Y,CHECKSIZE,CHECKSIZE); |
---|
299 | } |
---|
300 | } |
---|
301 | Fl_Overlay_Window::draw(); |
---|
302 | } |
---|
303 | |
---|
304 | extern Fl_Window *main_window; |
---|
305 | |
---|
306 | // Read an image of the overlay window |
---|
307 | uchar *Overlay_Window::read_image(int &ww, int &hh) { |
---|
308 | // Create an off-screen buffer for the window... |
---|
309 | main_window->make_current(); |
---|
310 | |
---|
311 | ww = w(); |
---|
312 | hh = h(); |
---|
313 | |
---|
314 | Fl_Offscreen offscreen = fl_create_offscreen(ww, hh); |
---|
315 | uchar *pixels; |
---|
316 | |
---|
317 | // Redraw the window into the offscreen buffer... |
---|
318 | fl_begin_offscreen(offscreen); |
---|
319 | |
---|
320 | if (!shown()) image(Fl::scheme_bg_); |
---|
321 | |
---|
322 | redraw(); |
---|
323 | draw(); |
---|
324 | |
---|
325 | // Read the screen image... |
---|
326 | pixels = fl_read_image(0, 0, 0, ww, hh); |
---|
327 | |
---|
328 | fl_end_offscreen(); |
---|
329 | |
---|
330 | // Cleanup and return... |
---|
331 | fl_delete_offscreen(offscreen); |
---|
332 | |
---|
333 | return pixels; |
---|
334 | } |
---|
335 | |
---|
336 | void Overlay_Window::draw_overlay() { |
---|
337 | window->draw_overlay(); |
---|
338 | } |
---|
339 | int Overlay_Window::handle(int e) { |
---|
340 | int ret = window->handle(e); |
---|
341 | if (ret==0) { |
---|
342 | switch (e) { |
---|
343 | case FL_SHOW: |
---|
344 | case FL_HIDE: |
---|
345 | ret = Fl_Overlay_Window::handle(e); |
---|
346 | } |
---|
347 | } |
---|
348 | return ret; |
---|
349 | } |
---|
350 | |
---|
351 | Fl_Type *Fl_Window_Type::make() { |
---|
352 | Fl_Type *p = Fl_Type::current; |
---|
353 | while (p && !p->is_code_block()) p = p->parent; |
---|
354 | if (!p) { |
---|
355 | fl_message("Please select a function"); |
---|
356 | return 0; |
---|
357 | } |
---|
358 | Fl_Window_Type *myo = new Fl_Window_Type(); |
---|
359 | if (!this->o) {// template widget |
---|
360 | this->o = new Fl_Window(100,100); |
---|
361 | Fl_Group::current(0); |
---|
362 | } |
---|
363 | // Set the size ranges for this window; in order to avoid opening the |
---|
364 | // X display we use an arbitrary maximum size... |
---|
365 | ((Fl_Window *)(this->o))->size_range(gridx, gridy, |
---|
366 | 3072, 2048, |
---|
367 | gridx, gridy, 0); |
---|
368 | myo->factory = this; |
---|
369 | myo->drag = 0; |
---|
370 | myo->numselected = 0; |
---|
371 | Overlay_Window *w = new Overlay_Window(100,100); |
---|
372 | w->window = myo; |
---|
373 | myo->o = w; |
---|
374 | myo->add(p); |
---|
375 | myo->modal = 0; |
---|
376 | myo->non_modal = 0; |
---|
377 | return myo; |
---|
378 | } |
---|
379 | |
---|
380 | void Fl_Window_Type::add_child(Fl_Type* cc, Fl_Type* before) { |
---|
381 | if (!cc->is_widget()) return; |
---|
382 | Fl_Widget_Type* c = (Fl_Widget_Type*)cc; |
---|
383 | Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; |
---|
384 | ((Fl_Window*)o)->insert(*(c->o), b); |
---|
385 | o->redraw(); |
---|
386 | } |
---|
387 | |
---|
388 | void Fl_Window_Type::remove_child(Fl_Type* cc) { |
---|
389 | Fl_Widget_Type* c = (Fl_Widget_Type*)cc; |
---|
390 | ((Fl_Window*)o)->remove(c->o); |
---|
391 | o->redraw(); |
---|
392 | } |
---|
393 | |
---|
394 | void Fl_Window_Type::move_child(Fl_Type* cc, Fl_Type* before) { |
---|
395 | Fl_Widget_Type* c = (Fl_Widget_Type*)cc; |
---|
396 | ((Fl_Window*)o)->remove(c->o); |
---|
397 | Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; |
---|
398 | ((Fl_Window*)o)->insert(*(c->o), b); |
---|
399 | o->redraw(); |
---|
400 | } |
---|
401 | |
---|
402 | //////////////////////////////////////////////////////////////// |
---|
403 | |
---|
404 | // Double-click on window widget shows the window, or if already shown, |
---|
405 | // it shows the control panel. |
---|
406 | void Fl_Window_Type::open() { |
---|
407 | Overlay_Window *w = (Overlay_Window *)o; |
---|
408 | if (w->shown()) { |
---|
409 | w->show(); |
---|
410 | Fl_Widget_Type::open(); |
---|
411 | } else { |
---|
412 | Fl_Widget *p = w->resizable(); |
---|
413 | if (!p) w->resizable(w); |
---|
414 | w->show(); |
---|
415 | w->resizable(p); |
---|
416 | } |
---|
417 | |
---|
418 | w->image(Fl::scheme_bg_); |
---|
419 | w->size_range(gridx, gridy, Fl::w(), Fl::h(), gridx, gridy, 0); |
---|
420 | } |
---|
421 | |
---|
422 | // Read an image of the window |
---|
423 | uchar *Fl_Window_Type::read_image(int &ww, int &hh) { |
---|
424 | Overlay_Window *w = (Overlay_Window *)o; |
---|
425 | |
---|
426 | // Read the screen image... |
---|
427 | return (w->read_image(ww, hh)); |
---|
428 | } |
---|
429 | |
---|
430 | |
---|
431 | // control panel items: |
---|
432 | |
---|
433 | void modal_cb(Fl_Light_Button* i, void* v) { |
---|
434 | if (v == LOAD) { |
---|
435 | if (!current_widget->is_window()) {i->hide(); return;} |
---|
436 | i->show(); |
---|
437 | i->value(((Fl_Window_Type *)current_widget)->modal); |
---|
438 | } else { |
---|
439 | ((Fl_Window_Type *)current_widget)->modal = i->value(); |
---|
440 | set_modflag(1); |
---|
441 | } |
---|
442 | } |
---|
443 | |
---|
444 | void non_modal_cb(Fl_Light_Button* i, void* v) { |
---|
445 | if (v == LOAD) { |
---|
446 | if (!current_widget->is_window()) {i->hide(); return;} |
---|
447 | i->show(); |
---|
448 | i->value(((Fl_Window_Type *)current_widget)->non_modal); |
---|
449 | } else { |
---|
450 | ((Fl_Window_Type *)current_widget)->non_modal = i->value(); |
---|
451 | set_modflag(1); |
---|
452 | } |
---|
453 | } |
---|
454 | |
---|
455 | void border_cb(Fl_Light_Button* i, void* v) { |
---|
456 | if (v == LOAD) { |
---|
457 | if (!current_widget->is_window()) {i->hide(); return;} |
---|
458 | i->show(); |
---|
459 | i->value(((Fl_Window*)(current_widget->o))->border()); |
---|
460 | } else { |
---|
461 | ((Fl_Window*)(current_widget->o))->border(i->value()); |
---|
462 | set_modflag(1); |
---|
463 | } |
---|
464 | } |
---|
465 | |
---|
466 | void xclass_cb(Fl_Input* i, void* v) { |
---|
467 | if (v == LOAD) { |
---|
468 | if (!current_widget->is_window()) { |
---|
469 | i->hide(); |
---|
470 | i->parent()->hide(); // hides the "X Class:" label as well |
---|
471 | return; |
---|
472 | } |
---|
473 | i->show(); |
---|
474 | i->parent()->show(); |
---|
475 | i->value(((Fl_Widget_Type *)current_widget)->xclass); |
---|
476 | } else { |
---|
477 | int mod = 0; |
---|
478 | for (Fl_Type *o = Fl_Type::first; o; o = o->next) { |
---|
479 | if (o->selected && o->is_widget()) { |
---|
480 | mod = 1; |
---|
481 | Fl_Widget_Type* w = (Fl_Widget_Type*)o; |
---|
482 | if (w->is_window() || w->is_button()) |
---|
483 | storestring(i->value(),w->xclass); |
---|
484 | if (w->is_window()) ((Fl_Window*)(w->o))->xclass(w->xclass); |
---|
485 | else if (w->is_menu_item()) w->redraw(); |
---|
486 | } |
---|
487 | } |
---|
488 | if (mod) set_modflag(1); |
---|
489 | } |
---|
490 | } |
---|
491 | |
---|
492 | //////////////////////////////////////////////////////////////// |
---|
493 | |
---|
494 | void Fl_Window_Type::setlabel(const char *n) { |
---|
495 | if (o) ((Fl_Window *)o)->label(n); |
---|
496 | } |
---|
497 | |
---|
498 | // make() is called on this widget when user picks window off New menu: |
---|
499 | Fl_Window_Type Fl_Window_type; |
---|
500 | |
---|
501 | // Resize from window manager... |
---|
502 | void Overlay_Window::resize(int X,int Y,int W,int H) { |
---|
503 | Fl_Widget* t = resizable(); resizable(0); |
---|
504 | |
---|
505 | // do not set the mod flag if the window was not resized. In FLUID, all |
---|
506 | // windows are opened without a given x/y position, so modifying x/y |
---|
507 | // should not mark the project as dirty |
---|
508 | if (W!=w() || H!=h()) |
---|
509 | set_modflag(1); |
---|
510 | |
---|
511 | Fl_Overlay_Window::resize(X,Y,W,H); |
---|
512 | resizable(t); |
---|
513 | update_xywh(); |
---|
514 | } |
---|
515 | |
---|
516 | // calculate actual move by moving mouse position (mx,my) to |
---|
517 | // nearest multiple of gridsize, and snap to original position |
---|
518 | void Fl_Window_Type::newdx() { |
---|
519 | int mydx, mydy; |
---|
520 | if (Fl::event_state(FL_ALT) || !snap) { |
---|
521 | mydx = mx-x1; |
---|
522 | mydy = my-y1; |
---|
523 | |
---|
524 | if (abs(mydx) < 2 && abs(mydy) < 2) mydx = mydy = 0; |
---|
525 | } else { |
---|
526 | int dx0 = mx-x1; |
---|
527 | int ix = (drag&RIGHT) ? br : bx; |
---|
528 | mydx = gridx ? ((ix+dx0+gridx/2)/gridx)*gridx - ix : dx0; |
---|
529 | if (dx0 > snap) { |
---|
530 | if (mydx < 0) mydx = 0; |
---|
531 | } else if (dx0 < -snap) { |
---|
532 | if (mydx > 0) mydx = 0; |
---|
533 | } else |
---|
534 | mydx = 0; |
---|
535 | int dy0 = my-y1; |
---|
536 | int iy = (drag&BOTTOM) ? by : bt; |
---|
537 | mydy = gridy ? ((iy+dy0+gridy/2)/gridy)*gridy - iy : dy0; |
---|
538 | if (dy0 > snap) { |
---|
539 | if (mydy < 0) mydy = 0; |
---|
540 | } else if (dy0 < -snap) { |
---|
541 | if (mydy > 0) mydy = 0; |
---|
542 | } else |
---|
543 | mydy = 0; |
---|
544 | } |
---|
545 | |
---|
546 | if (!(drag & (DRAG | BOX | LEFT | RIGHT))) { |
---|
547 | mydx = 0; |
---|
548 | dx = 0; |
---|
549 | } |
---|
550 | |
---|
551 | if (!(drag & (DRAG | BOX | TOP | BOTTOM))) { |
---|
552 | mydy = 0; |
---|
553 | dy = 0; |
---|
554 | } |
---|
555 | |
---|
556 | if (dx != mydx || dy != mydy) { |
---|
557 | dx = mydx; dy = mydy; |
---|
558 | ((Overlay_Window *)o)->redraw_overlay(); |
---|
559 | } |
---|
560 | } |
---|
561 | |
---|
562 | // Move a widget according to dx and dy calculated above |
---|
563 | void Fl_Window_Type::newposition(Fl_Widget_Type *myo,int &X,int &Y,int &R,int &T) { |
---|
564 | X = myo->o->x(); |
---|
565 | Y = myo->o->y(); |
---|
566 | R = X+myo->o->w(); |
---|
567 | T = Y+myo->o->h(); |
---|
568 | if (!drag) return; |
---|
569 | if (drag&DRAG) { |
---|
570 | X += dx; |
---|
571 | Y += dy; |
---|
572 | R += dx; |
---|
573 | T += dy; |
---|
574 | } else { |
---|
575 | if (drag&LEFT) if (X==bx) X += dx; else if (X<bx+dx) X = bx+dx; |
---|
576 | if (drag&TOP) if (Y==by) Y += dy; else if (Y<by+dy) Y = by+dy; |
---|
577 | if (drag&RIGHT) if (R==br) R += dx; else if (R>br+dx) R = br+dx; |
---|
578 | if (drag&BOTTOM) if (T==bt) T += dy; else if (T>bt+dx) T = bt+dx; |
---|
579 | } |
---|
580 | if (R<X) {int n = X; X = R; R = n;} |
---|
581 | if (T<Y) {int n = Y; Y = T; T = n;} |
---|
582 | } |
---|
583 | |
---|
584 | // draw a vertical arrow pointing toward y2 |
---|
585 | static void draw_v_arrow(int x, int y1, int y2) { |
---|
586 | int dy = (y1>y2) ? -1 : 1 ; |
---|
587 | fl_yxline(x, y1, y2); |
---|
588 | fl_xyline(x-4, y2, x+4); |
---|
589 | fl_line(x-2, y2-dy*5, x, y2-dy); |
---|
590 | fl_line(x+2, y2-dy*5, x, y2-dy); |
---|
591 | } |
---|
592 | |
---|
593 | static void draw_h_arrow(int x1, int y, int x2) { |
---|
594 | int dx = (x1>x2) ? -1 : 1 ; |
---|
595 | fl_xyline(x1, y, x2); |
---|
596 | fl_yxline(x2, y-4, y+4); |
---|
597 | fl_line(x2-dx*5, y-2, x2-dx, y); |
---|
598 | fl_line(x2-dx*5, y+2, x2-dx, y); |
---|
599 | } |
---|
600 | |
---|
601 | static void draw_top_brace(const Fl_Widget *w) { |
---|
602 | fl_yxline(w->x(), w->y()-2, w->y()+6); |
---|
603 | fl_yxline(w->x()+w->w()-1, w->y()-2, w->y()+6); |
---|
604 | fl_xyline(w->x()-2, w->y(), w->x()+w->w()+1); |
---|
605 | } |
---|
606 | |
---|
607 | static void draw_left_brace(const Fl_Widget *w) { |
---|
608 | fl_xyline(w->x()-2, w->y(), w->x()+6); |
---|
609 | fl_xyline(w->x()-2, w->y()+w->h()-1, w->x()+6); |
---|
610 | fl_yxline(w->x(), w->y()-2, w->y()+w->h()+1); |
---|
611 | } |
---|
612 | |
---|
613 | static void draw_right_brace(const Fl_Widget *w) { |
---|
614 | int xx = w->x() + w->w() - 1; |
---|
615 | fl_xyline(xx-6, w->y(), xx+2); |
---|
616 | fl_xyline(xx-6, w->y()+w->h()-1, xx+2); |
---|
617 | fl_yxline(xx, w->y()-2, w->y()+w->h()+1); |
---|
618 | } |
---|
619 | |
---|
620 | static void draw_bottom_brace(const Fl_Widget *w) { |
---|
621 | int yy = w->y() + w->h() - 1; |
---|
622 | fl_yxline(w->x(), yy-6, yy+2); |
---|
623 | fl_yxline(w->x()+w->w()-1, yy-6, yy+2); |
---|
624 | fl_xyline(w->x()-2, yy, w->x()+w->w()+1); |
---|
625 | } |
---|
626 | |
---|
627 | static void draw_height(int x, int y, int b, Fl_Align a) { |
---|
628 | char buf[16]; |
---|
629 | int h = b - y; |
---|
630 | sprintf(buf, "%d", h); |
---|
631 | fl_font(FL_HELVETICA, 9); |
---|
632 | int lw = (int)fl_width(buf); |
---|
633 | int lx; |
---|
634 | |
---|
635 | b --; |
---|
636 | if (h < 30) { |
---|
637 | // Move height to the side... |
---|
638 | if (a == FL_ALIGN_LEFT) lx = x - lw - 2; |
---|
639 | else lx = x + 2; |
---|
640 | |
---|
641 | fl_yxline(x, y, b); |
---|
642 | } else { |
---|
643 | // Put height inside the arrows... |
---|
644 | lx = x - lw / 2; |
---|
645 | |
---|
646 | fl_yxline(x, y, y + (h - 11) / 2); |
---|
647 | fl_yxline(x, y + (h + 11) / 2, b); |
---|
648 | } |
---|
649 | |
---|
650 | // Draw the height... |
---|
651 | fl_draw(buf, lx, y + (h + 9) / 2); |
---|
652 | |
---|
653 | // Draw the arrowheads... |
---|
654 | fl_line(x-2, y+5, x, y+1, x+2, y+5); |
---|
655 | fl_line(x-2, b-5, x, b-1, x+2, b-5); |
---|
656 | |
---|
657 | // Draw the end lines... |
---|
658 | fl_xyline(x - 4, y, x + 4); |
---|
659 | fl_xyline(x - 4, b, x + 4); |
---|
660 | } |
---|
661 | |
---|
662 | static void draw_width(int x, int y, int r, Fl_Align a) { |
---|
663 | char buf[16]; |
---|
664 | int w = r-x; |
---|
665 | sprintf(buf, "%d", w); |
---|
666 | fl_font(FL_HELVETICA, 9); |
---|
667 | int lw = (int)fl_width(buf); |
---|
668 | int ly = y + 4; |
---|
669 | |
---|
670 | r --; |
---|
671 | |
---|
672 | if (lw > (w - 20)) { |
---|
673 | // Move width above/below the arrows... |
---|
674 | if (a == FL_ALIGN_TOP) ly -= 10; |
---|
675 | else ly += 10; |
---|
676 | |
---|
677 | fl_xyline(x, y, r); |
---|
678 | } else { |
---|
679 | // Put width inside the arrows... |
---|
680 | fl_xyline(x, y, x + (w - lw - 2) / 2); |
---|
681 | fl_xyline(x + (w + lw + 2) / 2, y, r); |
---|
682 | } |
---|
683 | |
---|
684 | // Draw the width... |
---|
685 | fl_draw(buf, x + (w - lw) / 2, ly); |
---|
686 | |
---|
687 | // Draw the arrowheads... |
---|
688 | fl_line(x+5, y-2, x+1, y, x+5, y+2); |
---|
689 | fl_line(r-5, y-2, r-1, y, r-5, y+2); |
---|
690 | |
---|
691 | // Draw the end lines... |
---|
692 | fl_yxline(x, y - 4, y + 4); |
---|
693 | fl_yxline(r, y - 4, y + 4); |
---|
694 | } |
---|
695 | |
---|
696 | void Fl_Window_Type::draw_overlay() { |
---|
697 | if (recalc) { |
---|
698 | bx = o->w(); by = o->h(); br = 0; bt = 0; |
---|
699 | numselected = 0; |
---|
700 | for (Fl_Type *q=next; q && q->level>level; q=q->next) |
---|
701 | if (q->selected && q->is_widget() && !q->is_menu_item()) { |
---|
702 | numselected++; |
---|
703 | Fl_Widget_Type* myo = (Fl_Widget_Type*)q; |
---|
704 | if (myo->o->x() < bx) bx = myo->o->x(); |
---|
705 | if (myo->o->y() < by) by = myo->o->y(); |
---|
706 | if (myo->o->x()+myo->o->w() > br) br = myo->o->x()+myo->o->w(); |
---|
707 | if (myo->o->y()+myo->o->h() > bt) bt = myo->o->y()+myo->o->h(); |
---|
708 | } |
---|
709 | recalc = 0; |
---|
710 | sx = bx; sy = by; sr = br; st = bt; |
---|
711 | } |
---|
712 | fl_color(FL_RED); |
---|
713 | if (drag==BOX && (x1 != mx || y1 != my)) { |
---|
714 | int x = x1; int r = mx; if (x > r) {x = mx; r = x1;} |
---|
715 | int y = y1; int b = my; if (y > b) {y = my; b = y1;} |
---|
716 | fl_rect(x,y,r-x,b-y); |
---|
717 | } |
---|
718 | if (overlays_invisible && !drag) return; |
---|
719 | if (selected) fl_rect(0,0,o->w(),o->h()); |
---|
720 | if (!numselected) return; |
---|
721 | int mybx,myby,mybr,mybt; |
---|
722 | int mysx,mysy,mysr,myst; |
---|
723 | mybx = mysx = o->w(); myby = mysy = o->h(); mybr = mysr = 0; mybt = myst = 0; |
---|
724 | Fl_Type *selection = 0L; // used to store the one selected widget (if n==1) |
---|
725 | for (Fl_Type *q=next; q && q->level>level; q = q->next) |
---|
726 | if (q->selected && q->is_widget() && !q->is_menu_item()) { |
---|
727 | selection = q; |
---|
728 | Fl_Widget_Type* myo = (Fl_Widget_Type*)q; |
---|
729 | int x,y,r,t; |
---|
730 | newposition(myo,x,y,r,t); |
---|
731 | if (!show_guides || !drag || numselected != 1) fl_rect(x,y,r-x,t-y); |
---|
732 | if (x < mysx) mysx = x; |
---|
733 | if (y < mysy) mysy = y; |
---|
734 | if (r > mysr) mysr = r; |
---|
735 | if (t > myst) myst = t; |
---|
736 | if (!(myo->o->align() & FL_ALIGN_INSIDE)) { |
---|
737 | // Adjust left/right/top/bottom for top/bottom labels... |
---|
738 | int ww, hh; |
---|
739 | ww = (myo->o->align() & FL_ALIGN_WRAP) ? myo->o->w() : 0; |
---|
740 | hh = myo->o->labelsize(); |
---|
741 | myo->o->measure_label(ww, hh); |
---|
742 | if (myo->o->align() & FL_ALIGN_TOP) y -= hh; |
---|
743 | else if (myo->o->align() & FL_ALIGN_BOTTOM) t += hh; |
---|
744 | else if (myo->o->align() & FL_ALIGN_LEFT) x -= ww + 4; |
---|
745 | else if (myo->o->align() & FL_ALIGN_RIGHT) r += ww + 4; |
---|
746 | } |
---|
747 | if (x < mybx) mybx = x; |
---|
748 | if (y < myby) myby = y; |
---|
749 | if (r > mybr) mybr = r; |
---|
750 | if (t > mybt) mybt = t; |
---|
751 | } |
---|
752 | if (selected) return; |
---|
753 | |
---|
754 | if (show_guides && drag) { |
---|
755 | // draw overlays for UI Guideline distances |
---|
756 | // - check for distance to the window edge |
---|
757 | // * FLTK suggests 10 pixels from the edge |
---|
758 | int d; |
---|
759 | int xsp, ysp; |
---|
760 | int mybx_bak = mybx, myby_bak = myby, mybr_bak = mybr, mybt_bak = mybt; |
---|
761 | Fl_Widget_Type *mysel = (Fl_Widget_Type *)selection; |
---|
762 | |
---|
763 | |
---|
764 | ideal_spacing(xsp, ysp); |
---|
765 | |
---|
766 | if (drag) { |
---|
767 | // Check top spacing... |
---|
768 | if (abs(d = myby - ysp) < 3) { |
---|
769 | dy -= d; |
---|
770 | if (drag & DRAG) mybt -= d; |
---|
771 | myby -= d; |
---|
772 | draw_v_arrow(mybx+5, myby, 0); |
---|
773 | } |
---|
774 | |
---|
775 | // Check bottom spacing... |
---|
776 | if (abs(d = o->h() - mybt - ysp) < 3) { |
---|
777 | dy += d; |
---|
778 | if (drag & DRAG) myby += d; |
---|
779 | mybt += d; |
---|
780 | draw_v_arrow(mybx+5, mybt, o->h()); |
---|
781 | } |
---|
782 | |
---|
783 | // Check left spacing... |
---|
784 | if (abs(d = mybx - xsp) < 3) { |
---|
785 | dx -= d; |
---|
786 | if (drag & DRAG) mybr -= d; |
---|
787 | mybx -= d; |
---|
788 | draw_h_arrow(mybx, myby+5, 0); |
---|
789 | } |
---|
790 | |
---|
791 | // Check right spacing... |
---|
792 | if (abs(d = o->w() - mybr - xsp) < 3) { |
---|
793 | dx += d; |
---|
794 | if (drag & DRAG) mybx += d; |
---|
795 | mybr += d; |
---|
796 | draw_h_arrow(mybr, myby+5, o->w()); |
---|
797 | } |
---|
798 | } |
---|
799 | |
---|
800 | if (numselected==1 && selection && !(drag & DRAG)) { |
---|
801 | // Check ideal sizes |
---|
802 | int x,y,r,t; |
---|
803 | newposition(mysel,x,y,r,t); |
---|
804 | int w = r-x; |
---|
805 | int h = t-y; |
---|
806 | int iw = w, ih = h; |
---|
807 | |
---|
808 | mysel->ideal_size(iw, ih); |
---|
809 | |
---|
810 | if (drag & (TOP | BOTTOM)) { |
---|
811 | // Check height |
---|
812 | if (abs(d = ih - h) < 5) { |
---|
813 | // Resize height |
---|
814 | if (drag & TOP) { |
---|
815 | myby -= d; |
---|
816 | y -= d; |
---|
817 | dy -= d; |
---|
818 | } else { |
---|
819 | mybt += d; |
---|
820 | t += d; |
---|
821 | dy += d; |
---|
822 | } |
---|
823 | } |
---|
824 | |
---|
825 | // Draw height guide |
---|
826 | draw_height(x < 50 ? x+10 : x-10, y, t, |
---|
827 | x < 50 ? FL_ALIGN_RIGHT : FL_ALIGN_LEFT); |
---|
828 | } |
---|
829 | |
---|
830 | if (drag & (LEFT | RIGHT)) { |
---|
831 | // Check width |
---|
832 | if (abs(d = iw - w) < 5) { |
---|
833 | // Resize width |
---|
834 | if (drag & LEFT) { |
---|
835 | mybx -= d; |
---|
836 | x -= d; |
---|
837 | dx -= d; |
---|
838 | } else { |
---|
839 | mybr += d; |
---|
840 | r += d; |
---|
841 | dx += d; |
---|
842 | } |
---|
843 | } |
---|
844 | |
---|
845 | // Draw width guide |
---|
846 | draw_width(x, y < 50 ? y+10 : y-10, r, |
---|
847 | y < 50 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP); |
---|
848 | } |
---|
849 | } |
---|
850 | |
---|
851 | // Check spacing and alignment between individual widgets |
---|
852 | if (drag && selection->is_widget()) { |
---|
853 | for (Fl_Type *q=next; q && q->level>level; q = q->next) |
---|
854 | if (q != selection && q->is_widget()) { |
---|
855 | Fl_Widget_Type *qw = (Fl_Widget_Type*)q; |
---|
856 | // Only check visible widgets... |
---|
857 | if (!qw->o->visible_r()) continue; |
---|
858 | |
---|
859 | // Get bounding box of widget... |
---|
860 | int qx = qw->o->x(); |
---|
861 | int qr = qw->o->x() + qw->o->w(); |
---|
862 | int qy = qw->o->y(); |
---|
863 | int qt = qw->o->y() + qw->o->h(); |
---|
864 | |
---|
865 | if (!(qw->o->align() & FL_ALIGN_INSIDE)) { |
---|
866 | // Adjust top/bottom for top/bottom labels... |
---|
867 | int ww, hh; |
---|
868 | ww = qw->o->w(); |
---|
869 | hh = qw->o->labelsize(); |
---|
870 | qw->o->measure_label(ww, hh); |
---|
871 | if (qw->o->align() & FL_ALIGN_TOP) qy -= hh; |
---|
872 | if (qw->o->align() & FL_ALIGN_BOTTOM) qt += hh; |
---|
873 | } |
---|
874 | |
---|
875 | // Do horizontal alignment when the widget is within 25 |
---|
876 | // pixels vertically... |
---|
877 | if (fl_min(abs(qy - mysel->o->y() - mysel->o->h()), |
---|
878 | abs(mysel->o->y() - qt)) < 25) { |
---|
879 | // Align to left of other widget... |
---|
880 | if ((drag & (LEFT | DRAG)) && abs(d = mybx - qx) < 3) { |
---|
881 | dx += d; |
---|
882 | mybx += d; |
---|
883 | if (drag & DRAG) mybr += d; |
---|
884 | |
---|
885 | draw_left_brace(qw->o); |
---|
886 | } |
---|
887 | |
---|
888 | // Align to right of other widget... |
---|
889 | if ((drag & (RIGHT | DRAG)) && |
---|
890 | abs(d = qr - mybr) < 3) { |
---|
891 | dx += d; |
---|
892 | if (drag & DRAG) mybx += d; |
---|
893 | mybr += d; |
---|
894 | |
---|
895 | draw_right_brace(qw->o); |
---|
896 | } |
---|
897 | } |
---|
898 | |
---|
899 | // Align to top of other widget... |
---|
900 | if ((drag & (TOP | DRAG)) && abs(d = myby - qy) < 3) { |
---|
901 | dy += d; |
---|
902 | myby += d; |
---|
903 | if (drag & DRAG) mybt += d; |
---|
904 | |
---|
905 | draw_top_brace(qw->o); |
---|
906 | } |
---|
907 | |
---|
908 | // Align to bottom of other widget... |
---|
909 | if ((drag & (BOTTOM | DRAG)) && abs(d = qt - mybt) < 3) { |
---|
910 | dy += d; |
---|
911 | if (drag & DRAG) myby += d; |
---|
912 | mybt += d; |
---|
913 | |
---|
914 | draw_bottom_brace(qw->o); |
---|
915 | } |
---|
916 | |
---|
917 | // Check spacing between widgets |
---|
918 | if (mysel->is_group()) mysel->ideal_spacing(xsp, ysp); |
---|
919 | else qw->ideal_spacing(xsp, ysp); |
---|
920 | |
---|
921 | if ((qt)>=myby && qy<=mybt) { |
---|
922 | if (drag & (LEFT | DRAG)) { |
---|
923 | // Compare left of selected to left of current |
---|
924 | if (abs(d = qx - mybx - xsp) >= 3) |
---|
925 | d = qx - mybx + xsp; |
---|
926 | |
---|
927 | if (abs(d) < 3) { |
---|
928 | dx += d; |
---|
929 | mybx += d; |
---|
930 | if (drag & DRAG) mybr += d; |
---|
931 | |
---|
932 | // Draw left arrow |
---|
933 | draw_h_arrow(mybx, (myby+mybt)/2, qx); |
---|
934 | } |
---|
935 | |
---|
936 | // Compare left of selected to right of current |
---|
937 | if (abs(d = qr - mybx - xsp) >= 3) |
---|
938 | d = qr - mybx + xsp; |
---|
939 | |
---|
940 | if (abs(d) < 3) { |
---|
941 | dx += d; |
---|
942 | mybx += d; |
---|
943 | if (drag & DRAG) mybr += d; |
---|
944 | |
---|
945 | // Draw left arrow |
---|
946 | draw_h_arrow(mybx, (myby+mybt)/2, qr); |
---|
947 | } |
---|
948 | } |
---|
949 | |
---|
950 | if (drag & (RIGHT | DRAG)) { |
---|
951 | // Compare right of selected to left of current |
---|
952 | if (abs(d = qx - mybr - xsp) >= 3) |
---|
953 | d = qx - mybr + xsp; |
---|
954 | |
---|
955 | if (abs(d) < 3) { |
---|
956 | dx += d; |
---|
957 | if (drag & DRAG) mybx += d; |
---|
958 | mybr += d; |
---|
959 | |
---|
960 | // Draw right arrow |
---|
961 | draw_h_arrow(mybr, (myby+mybt)/2, qx); |
---|
962 | } |
---|
963 | |
---|
964 | // Compare right of selected to right of current |
---|
965 | if (abs(d = qr - mybr + xsp) >= 3) |
---|
966 | d = qr - mybr - xsp; |
---|
967 | |
---|
968 | if (abs(d) < 3) { |
---|
969 | dx += d; |
---|
970 | if (drag & DRAG) mybx += d; |
---|
971 | mybr += d; |
---|
972 | |
---|
973 | // Draw right arrow |
---|
974 | draw_h_arrow(mybr, (myby+mybt)/2, qr); |
---|
975 | } |
---|
976 | } |
---|
977 | } |
---|
978 | |
---|
979 | if (qr>=mybx && qx<=mybr) { |
---|
980 | // Compare top of selected to top of current |
---|
981 | if (drag & (TOP | DRAG)) { |
---|
982 | if (abs(d = qy - myby - ysp) >= 3) |
---|
983 | d = qy - myby + ysp; |
---|
984 | |
---|
985 | if (abs(d) < 3) { |
---|
986 | dy += d; |
---|
987 | myby += d; |
---|
988 | if (drag & DRAG) mybt += d; |
---|
989 | |
---|
990 | // Draw up arrow... |
---|
991 | draw_v_arrow((mybx+mybr)/2, myby, qy); |
---|
992 | } |
---|
993 | |
---|
994 | // Compare top of selected to bottom of current |
---|
995 | if (abs(d = qt - myby - ysp) >= 3) |
---|
996 | d = qt - myby + ysp; |
---|
997 | |
---|
998 | if (abs(d) < 3) { |
---|
999 | dy += d; |
---|
1000 | myby += d; |
---|
1001 | if (drag & DRAG) mybt += d; |
---|
1002 | |
---|
1003 | // Draw up arrow... |
---|
1004 | draw_v_arrow((mybx+mybr)/2, myby, qt); |
---|
1005 | } |
---|
1006 | } |
---|
1007 | |
---|
1008 | // Compare bottom of selected to top of current |
---|
1009 | if (drag & (BOTTOM | DRAG)) { |
---|
1010 | if (abs(d = qy - mybt - ysp) >= 3) |
---|
1011 | d = qy - mybt + ysp; |
---|
1012 | |
---|
1013 | if (abs(d) < 3) { |
---|
1014 | dy += d; |
---|
1015 | if (drag & DRAG) myby += d; |
---|
1016 | mybt += d; |
---|
1017 | |
---|
1018 | // Draw down arrow... |
---|
1019 | draw_v_arrow((mybx+mybr)/2, mybt, qy); |
---|
1020 | } |
---|
1021 | |
---|
1022 | // Compare bottom of selected to bottom of current |
---|
1023 | if (abs(d = qt - mybt - ysp) >= 3) |
---|
1024 | d = qt - mybt + ysp; |
---|
1025 | |
---|
1026 | if (abs(d) < 3) { |
---|
1027 | dy += d; |
---|
1028 | if (drag & DRAG) myby += d; |
---|
1029 | mybt += d; |
---|
1030 | |
---|
1031 | // Draw down arrow... |
---|
1032 | draw_v_arrow((mybx+mybr)/2, mybt, qt); |
---|
1033 | } |
---|
1034 | } |
---|
1035 | } |
---|
1036 | } |
---|
1037 | } |
---|
1038 | mysx += mybx-mybx_bak; mysr += mybr-mybr_bak; |
---|
1039 | mysy += myby-myby_bak; myst += mybt-mybt_bak; |
---|
1040 | } |
---|
1041 | // align the snapping selection box with the box we draw. |
---|
1042 | sx = mysx; sy = mysy; sr = mysr; st = myst; |
---|
1043 | |
---|
1044 | // Draw selection box + resize handles... |
---|
1045 | // draw box including all labels |
---|
1046 | fl_line_style(FL_DOT); |
---|
1047 | fl_rect(mybx,myby,mybr-mybx,mybt-myby); |
---|
1048 | fl_line_style(FL_SOLID); |
---|
1049 | // draw box excluding labels |
---|
1050 | fl_rect(mysx,mysy,mysr-mysx,myst-mysy); |
---|
1051 | fl_rectf(mysx,mysy,5,5); |
---|
1052 | fl_rectf(mysr-5,mysy,5,5); |
---|
1053 | fl_rectf(mysr-5,myst-5,5,5); |
---|
1054 | fl_rectf(mysx,myst-5,5,5); |
---|
1055 | } |
---|
1056 | |
---|
1057 | extern Fl_Menu_Item Main_Menu[]; |
---|
1058 | |
---|
1059 | // Calculate new bounding box of selected widgets: |
---|
1060 | void Fl_Window_Type::fix_overlay() { |
---|
1061 | Main_Menu[40].label("Hide O&verlays"); |
---|
1062 | overlays_invisible = 0; |
---|
1063 | recalc = 1; |
---|
1064 | ((Overlay_Window *)(this->o))->redraw_overlay(); |
---|
1065 | } |
---|
1066 | |
---|
1067 | // do that for every window (when selected set changes): |
---|
1068 | void redraw_overlays() { |
---|
1069 | for (Fl_Type *o=Fl_Type::first; o; o=o->next) |
---|
1070 | if (o->is_window()) ((Fl_Window_Type*)o)->fix_overlay(); |
---|
1071 | } |
---|
1072 | |
---|
1073 | void toggle_overlays(Fl_Widget *,void *) { |
---|
1074 | overlays_invisible = !overlays_invisible; |
---|
1075 | |
---|
1076 | if (overlays_invisible) Main_Menu[40].label("Show O&verlays"); |
---|
1077 | else Main_Menu[40].label("Hide O&verlays"); |
---|
1078 | |
---|
1079 | for (Fl_Type *o=Fl_Type::first; o; o=o->next) |
---|
1080 | if (o->is_window()) { |
---|
1081 | Fl_Widget_Type* w = (Fl_Widget_Type*)o; |
---|
1082 | ((Overlay_Window*)(w->o))->redraw_overlay(); |
---|
1083 | } |
---|
1084 | } |
---|
1085 | |
---|
1086 | extern void select(Fl_Type *,int); |
---|
1087 | extern void select_only(Fl_Type *); |
---|
1088 | extern void deselect(); |
---|
1089 | extern Fl_Type* in_this_only; |
---|
1090 | extern void fix_group_size(Fl_Type *t); |
---|
1091 | |
---|
1092 | extern Fl_Menu_Item Main_Menu[]; |
---|
1093 | extern Fl_Menu_Item New_Menu[]; |
---|
1094 | |
---|
1095 | // move the selected children according to current dx,dy,drag state: |
---|
1096 | void Fl_Window_Type::moveallchildren() |
---|
1097 | { |
---|
1098 | undo_checkpoint(); |
---|
1099 | Fl_Type *i; |
---|
1100 | for (i=next; i && i->level>level;) { |
---|
1101 | if (i->selected && i->is_widget() && !i->is_menu_item()) { |
---|
1102 | Fl_Widget_Type* myo = (Fl_Widget_Type*)i; |
---|
1103 | int x,y,r,t; |
---|
1104 | newposition(myo,x,y,r,t); |
---|
1105 | myo->o->resize(x,y,r-x,t-y); |
---|
1106 | // move all the children, whether selected or not: |
---|
1107 | Fl_Type* p; |
---|
1108 | for (p = myo->next; p && p->level>myo->level; p = p->next) |
---|
1109 | if (p->is_widget() && !p->is_menu_item()) { |
---|
1110 | Fl_Widget_Type* myo2 = (Fl_Widget_Type*)p; |
---|
1111 | int X,Y,R,T; |
---|
1112 | newposition(myo2,X,Y,R,T); |
---|
1113 | myo2->o->resize(X,Y,R-X,T-Y); |
---|
1114 | } |
---|
1115 | i = p; |
---|
1116 | } else { |
---|
1117 | i = i->next; |
---|
1118 | } |
---|
1119 | } |
---|
1120 | for (i=next; i && i->level>level; i=i->next) |
---|
1121 | fix_group_size(i); |
---|
1122 | o->redraw(); |
---|
1123 | recalc = 1; |
---|
1124 | ((Overlay_Window *)(this->o))->redraw_overlay(); |
---|
1125 | set_modflag(1); |
---|
1126 | dx = dy = 0; |
---|
1127 | |
---|
1128 | update_xywh(); |
---|
1129 | } |
---|
1130 | |
---|
1131 | int Fl_Window_Type::handle(int event) { |
---|
1132 | static Fl_Type* selection; |
---|
1133 | switch (event) { |
---|
1134 | case FL_PUSH: |
---|
1135 | x1 = mx = Fl::event_x(); |
---|
1136 | y1 = my = Fl::event_y(); |
---|
1137 | drag = dx = dy = 0; |
---|
1138 | // test for popup menu: |
---|
1139 | if (Fl::event_button() >= 3) { |
---|
1140 | in_this_only = this; // modifies how some menu items work. |
---|
1141 | static const Fl_Menu_Item* myprev; |
---|
1142 | const Fl_Menu_Item* m = New_Menu->popup(mx,my,"New",myprev); |
---|
1143 | if (m && m->callback()) {myprev = m; m->do_callback(this->o);} |
---|
1144 | in_this_only = 0; |
---|
1145 | return 1; |
---|
1146 | } |
---|
1147 | // find the innermost item clicked on: |
---|
1148 | selection = this; |
---|
1149 | {for (Fl_Type* i=next; i && i->level>level; i=i->next) |
---|
1150 | if (i->is_widget() && !i->is_menu_item()) { |
---|
1151 | Fl_Widget_Type* myo = (Fl_Widget_Type*)i; |
---|
1152 | for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent()) |
---|
1153 | if (!o1->visible()) goto CONTINUE2; |
---|
1154 | if (Fl::event_inside(myo->o)) { |
---|
1155 | selection = myo; |
---|
1156 | if (Fl::event_clicks()==1) |
---|
1157 | reveal_in_browser(myo); |
---|
1158 | } |
---|
1159 | CONTINUE2:; |
---|
1160 | }} |
---|
1161 | // see if user grabs edges of selected region: |
---|
1162 | if (numselected && !(Fl::event_state(FL_SHIFT)) && |
---|
1163 | mx<=br+snap && mx>=bx-snap && my<=bt+snap && my>=by-snap) { |
---|
1164 | int snap1 = snap>5 ? snap : 5; |
---|
1165 | int w1 = (br-bx)/4; if (w1 > snap1) w1 = snap1; |
---|
1166 | if (mx>=br-w1) drag |= RIGHT; |
---|
1167 | else if (mx<bx+w1) drag |= LEFT; |
---|
1168 | w1 = (bt-by)/4; if (w1 > snap1) w1 = snap1; |
---|
1169 | if (my<=by+w1) drag |= TOP; |
---|
1170 | else if (my>bt-w1) drag |= BOTTOM; |
---|
1171 | if (!drag) drag = DRAG; |
---|
1172 | } |
---|
1173 | // do object-specific selection of other objects: |
---|
1174 | {Fl_Type* t = selection->click_test(mx, my); |
---|
1175 | if (t) { |
---|
1176 | //if (t == selection) return 1; // indicates mouse eaten w/o change |
---|
1177 | if (Fl::event_state(FL_SHIFT)) { |
---|
1178 | Fl::event_is_click(0); |
---|
1179 | select(t, !t->selected); |
---|
1180 | } else { |
---|
1181 | deselect(); |
---|
1182 | select(t, 1); |
---|
1183 | if (t->is_menu_item()) t->open(); |
---|
1184 | } |
---|
1185 | selection = t; |
---|
1186 | drag = 0; |
---|
1187 | } else { |
---|
1188 | if (!drag) drag = BOX; // if all else fails, start a new selection region |
---|
1189 | }} |
---|
1190 | return 1; |
---|
1191 | |
---|
1192 | case FL_DRAG: |
---|
1193 | if (!drag) return 0; |
---|
1194 | mx = Fl::event_x(); |
---|
1195 | my = Fl::event_y(); |
---|
1196 | newdx(); |
---|
1197 | return 1; |
---|
1198 | |
---|
1199 | case FL_RELEASE: |
---|
1200 | if (!drag) return 0; |
---|
1201 | mx = Fl::event_x(); |
---|
1202 | my = Fl::event_y(); |
---|
1203 | if (drag != BOX && (dx || dy || !Fl::event_is_click())) { |
---|
1204 | if (dx || dy) moveallchildren(); |
---|
1205 | } else if ((Fl::event_clicks() || Fl::event_state(FL_CTRL))) { |
---|
1206 | Fl_Widget_Type::open(); |
---|
1207 | } else { |
---|
1208 | if (mx<x1) {int t = x1; x1 = mx; mx = t;} |
---|
1209 | if (my<y1) {int t = y1; y1 = my; my = t;} |
---|
1210 | int n = 0; |
---|
1211 | int toggle = Fl::event_state(FL_SHIFT); |
---|
1212 | // clear selection on everything: |
---|
1213 | if (!toggle) deselect(); else Fl::event_is_click(0); |
---|
1214 | // select everything in box: |
---|
1215 | for (Fl_Type*i=next; i&&i->level>level; i=i->next) |
---|
1216 | if (i->is_widget() && !i->is_menu_item()) { |
---|
1217 | Fl_Widget_Type* myo = (Fl_Widget_Type*)i; |
---|
1218 | for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent()) |
---|
1219 | if (!o1->visible()) goto CONTINUE; |
---|
1220 | if (Fl::event_inside(myo->o)) selection = myo; |
---|
1221 | if (myo->o->x()>=x1 && myo->o->y()>y1 && |
---|
1222 | myo->o->x()+myo->o->w()<mx && myo->o->y()+myo->o->h()<my) { |
---|
1223 | n++; |
---|
1224 | select(myo, toggle ? !myo->selected : 1); |
---|
1225 | } |
---|
1226 | CONTINUE:; |
---|
1227 | } |
---|
1228 | // if nothing in box, select what was clicked on: |
---|
1229 | if (!n) { |
---|
1230 | select(selection, toggle ? !selection->selected : 1); |
---|
1231 | } |
---|
1232 | } |
---|
1233 | drag = 0; |
---|
1234 | ((Overlay_Window *)o)->redraw_overlay(); |
---|
1235 | return 1; |
---|
1236 | |
---|
1237 | case FL_KEYBOARD: { |
---|
1238 | |
---|
1239 | int backtab = 0; |
---|
1240 | switch (Fl::event_key()) { |
---|
1241 | |
---|
1242 | case FL_Escape: |
---|
1243 | ((Fl_Window*)o)->hide(); |
---|
1244 | return 1; |
---|
1245 | |
---|
1246 | case 0xFE20: // backtab |
---|
1247 | backtab = 1; |
---|
1248 | case FL_Tab: { |
---|
1249 | if (Fl::event_state(FL_SHIFT)) backtab = 1; |
---|
1250 | // find current child: |
---|
1251 | Fl_Type *i = Fl_Type::current; |
---|
1252 | while (i && (!i->is_widget() || i->is_menu_item())) i = i->parent; |
---|
1253 | if (!i) return 0; |
---|
1254 | Fl_Type *p = i->parent; |
---|
1255 | while (p && p != this) p = p->parent; |
---|
1256 | if (!p || !p->is_widget()) { |
---|
1257 | i = next; if (!i || i->level <= level) return 0; |
---|
1258 | } |
---|
1259 | p = i; |
---|
1260 | for (;;) { |
---|
1261 | i = backtab ? i->prev : i->next; |
---|
1262 | if (!i || i->level <= level) {i = p; break;} |
---|
1263 | if (i->is_widget() && !i->is_menu_item()) break; |
---|
1264 | } |
---|
1265 | deselect(); select(i,1); |
---|
1266 | return 1;} |
---|
1267 | |
---|
1268 | case FL_Left: dx = -1; dy = 0; goto ARROW; |
---|
1269 | case FL_Right: dx = +1; dy = 0; goto ARROW; |
---|
1270 | case FL_Up: dx = 0; dy = -1; goto ARROW; |
---|
1271 | case FL_Down: dx = 0; dy = +1; goto ARROW; |
---|
1272 | ARROW: |
---|
1273 | // for some reason BOTTOM/TOP are swapped... should be fixed... |
---|
1274 | drag = (Fl::event_state(FL_SHIFT)) ? (RIGHT|TOP) : DRAG; |
---|
1275 | if (Fl::event_state(FL_CTRL)) {dx *= gridx; dy *= gridy;} |
---|
1276 | moveallchildren(); |
---|
1277 | drag = 0; |
---|
1278 | return 1; |
---|
1279 | |
---|
1280 | case 'o': |
---|
1281 | toggle_overlays(0, 0); |
---|
1282 | break; |
---|
1283 | |
---|
1284 | default: |
---|
1285 | return 0; |
---|
1286 | }} |
---|
1287 | |
---|
1288 | case FL_SHORTCUT: { |
---|
1289 | in_this_only = this; // modifies how some menu items work. |
---|
1290 | const Fl_Menu_Item* m = Main_Menu->test_shortcut(); |
---|
1291 | if (m && m->callback()) m->do_callback(this->o); |
---|
1292 | in_this_only = 0; |
---|
1293 | return (m != 0);} |
---|
1294 | |
---|
1295 | default: |
---|
1296 | return 0; |
---|
1297 | } |
---|
1298 | } |
---|
1299 | |
---|
1300 | //////////////////////////////////////////////////////////////// |
---|
1301 | |
---|
1302 | #include <stdio.h> |
---|
1303 | #include "../src/flstring.h" |
---|
1304 | |
---|
1305 | void Fl_Window_Type::write_code1() { |
---|
1306 | Fl_Widget_Type::write_code1(); |
---|
1307 | } |
---|
1308 | |
---|
1309 | void Fl_Window_Type::write_code2() { |
---|
1310 | const char *var = is_class() ? "this" : name() ? name() : "o"; |
---|
1311 | write_extra_code(); |
---|
1312 | if (modal) write_c("%s%s->set_modal();\n", indent(), var); |
---|
1313 | else if (non_modal) write_c("%s%s->set_non_modal();\n", indent(), var); |
---|
1314 | if (!((Fl_Window*)o)->border()) { |
---|
1315 | write_c("%s%s->clear_border();\n", indent(), var); |
---|
1316 | } |
---|
1317 | if (xclass) { |
---|
1318 | write_c("%s%s->xclass(", indent(), var); |
---|
1319 | write_cstring(xclass); |
---|
1320 | write_c(");\n"); |
---|
1321 | } |
---|
1322 | if (sr_max_w || sr_max_h) { |
---|
1323 | write_c("%s%s->size_range(%d, %d, %d, %d);\n", indent(), var, |
---|
1324 | sr_min_w, sr_min_h, sr_max_w, sr_max_h); |
---|
1325 | } else if (sr_min_w || sr_min_h) { |
---|
1326 | write_c("%s%s->size_range(%d, %d);\n", indent(), var, sr_min_w, sr_min_h); |
---|
1327 | } |
---|
1328 | write_c("%s%s->end();\n", indent(), var); |
---|
1329 | if (((Fl_Window*)o)->resizable() == o) |
---|
1330 | write_c("%s%s->resizable(%s);\n", indent(), var, var); |
---|
1331 | write_block_close(); |
---|
1332 | } |
---|
1333 | |
---|
1334 | void Fl_Window_Type::write_properties() { |
---|
1335 | Fl_Widget_Type::write_properties(); |
---|
1336 | if (modal) write_string("modal"); |
---|
1337 | else if (non_modal) write_string("non_modal"); |
---|
1338 | if (!((Fl_Window*)o)->border()) write_string("noborder"); |
---|
1339 | if (xclass) {write_string("xclass"); write_word(xclass);} |
---|
1340 | if (sr_min_w || sr_min_h || sr_max_w || sr_max_h) |
---|
1341 | write_string("size_range {%d %d %d %d}", sr_min_w, sr_min_h, sr_max_w, sr_max_h); |
---|
1342 | if (o->visible()) write_string("visible"); |
---|
1343 | } |
---|
1344 | |
---|
1345 | extern int pasteoffset; |
---|
1346 | void Fl_Window_Type::read_property(const char *c) { |
---|
1347 | if (!strcmp(c,"modal")) { |
---|
1348 | modal = 1; |
---|
1349 | } else if (!strcmp(c,"non_modal")) { |
---|
1350 | non_modal = 1; |
---|
1351 | } else if (!strcmp(c, "visible")) { |
---|
1352 | if (Fl::first_window()) open(); // only if we are using user interface |
---|
1353 | } else if (!strcmp(c,"noborder")) { |
---|
1354 | ((Fl_Window*)o)->border(0); |
---|
1355 | } else if (!strcmp(c,"xclass")) { |
---|
1356 | storestring(read_word(),xclass); |
---|
1357 | ((Fl_Window*)o)->xclass(xclass); |
---|
1358 | } else if (!strcmp(c,"size_range")) { |
---|
1359 | int mw, mh, MW, MH; |
---|
1360 | if (sscanf(read_word(),"%d %d %d %d",&mw,&mh,&MW,&MH) == 4) { |
---|
1361 | sr_min_w = mw; sr_min_h = mh; sr_max_w = MW; sr_max_h = MH; |
---|
1362 | } |
---|
1363 | } else if (!strcmp(c,"xywh")) { |
---|
1364 | Fl_Widget_Type::read_property(c); |
---|
1365 | pasteoffset = 0; // make it not apply to contents |
---|
1366 | } else { |
---|
1367 | Fl_Widget_Type::read_property(c); |
---|
1368 | } |
---|
1369 | } |
---|
1370 | |
---|
1371 | int Fl_Window_Type::read_fdesign(const char* propname, const char* value) { |
---|
1372 | int x; |
---|
1373 | o->box(FL_NO_BOX); // because fdesign always puts an Fl_Box next |
---|
1374 | if (!strcmp(propname,"Width")) { |
---|
1375 | if (sscanf(value,"%d",&x) == 1) o->size(x,o->h()); |
---|
1376 | } else if (!strcmp(propname,"Height")) { |
---|
1377 | if (sscanf(value,"%d",&x) == 1) o->size(o->w(),x); |
---|
1378 | } else if (!strcmp(propname,"NumberofWidgets")) { |
---|
1379 | return 1; // we can figure out count from file |
---|
1380 | } else if (!strcmp(propname,"border")) { |
---|
1381 | if (sscanf(value,"%d",&x) == 1) ((Fl_Window*)o)->border(x); |
---|
1382 | } else if (!strcmp(propname,"title")) { |
---|
1383 | label(value); |
---|
1384 | } else { |
---|
1385 | return Fl_Widget_Type::read_fdesign(propname,value); |
---|
1386 | } |
---|
1387 | return 1; |
---|
1388 | } |
---|
1389 | |
---|
1390 | /////////////////////////////////////////////////////////////////////// |
---|
1391 | |
---|
1392 | Fl_Widget_Class_Type Fl_Widget_Class_type; |
---|
1393 | Fl_Widget_Class_Type *current_widget_class = 0; |
---|
1394 | |
---|
1395 | Fl_Type *Fl_Widget_Class_Type::make() { |
---|
1396 | Fl_Type *p = Fl_Type::current; |
---|
1397 | while (p && (!p->is_decl_block() || (p->is_widget() && p->is_class()))) p = p->parent; |
---|
1398 | Fl_Widget_Class_Type *myo = new Fl_Widget_Class_Type(); |
---|
1399 | myo->name("UserInterface"); |
---|
1400 | |
---|
1401 | if (!this->o) {// template widget |
---|
1402 | this->o = new Fl_Window(100,100); |
---|
1403 | Fl_Group::current(0); |
---|
1404 | } |
---|
1405 | // Set the size ranges for this window; in order to avoid opening the |
---|
1406 | // X display we use an arbitrary maximum size... |
---|
1407 | ((Fl_Window *)(this->o))->size_range(gridx, gridy, |
---|
1408 | 3072, 2048, |
---|
1409 | gridx, gridy, 0); |
---|
1410 | myo->factory = this; |
---|
1411 | myo->drag = 0; |
---|
1412 | myo->numselected = 0; |
---|
1413 | Overlay_Window *w = new Overlay_Window(100,100); |
---|
1414 | w->window = myo; |
---|
1415 | myo->o = w; |
---|
1416 | myo->add(p); |
---|
1417 | myo->modal = 0; |
---|
1418 | myo->non_modal = 0; |
---|
1419 | myo->wc_relative = 0; |
---|
1420 | |
---|
1421 | return myo; |
---|
1422 | } |
---|
1423 | |
---|
1424 | void Fl_Widget_Class_Type::write_properties() { |
---|
1425 | Fl_Window_Type::write_properties(); |
---|
1426 | if (wc_relative) write_string("position_relative"); |
---|
1427 | } |
---|
1428 | |
---|
1429 | void Fl_Widget_Class_Type::read_property(const char *c) { |
---|
1430 | if (!strcmp(c,"position_relative")) { |
---|
1431 | wc_relative = 1; |
---|
1432 | } else { |
---|
1433 | Fl_Window_Type::read_property(c); |
---|
1434 | } |
---|
1435 | } |
---|
1436 | |
---|
1437 | void Fl_Widget_Class_Type::write_code1() { |
---|
1438 | #if 0 |
---|
1439 | Fl_Widget_Type::write_code1(); |
---|
1440 | #endif // 0 |
---|
1441 | |
---|
1442 | current_widget_class = this; |
---|
1443 | write_public_state = 1; |
---|
1444 | |
---|
1445 | const char *c = subclass(); |
---|
1446 | if (!c) c = "Fl_Group"; |
---|
1447 | |
---|
1448 | write_h("\nclass %s : public %s {\n", name(), c); |
---|
1449 | if (strstr(c, "Window")) { |
---|
1450 | write_h(" void _%s();\n", name()); |
---|
1451 | write_h("public:\n"); |
---|
1452 | write_h(" %s(int X, int Y, int W, int H, const char *L = 0);\n", name()); |
---|
1453 | write_h(" %s(int W, int H, const char *L = 0);\n", name()); |
---|
1454 | |
---|
1455 | write_c("%s::%s(int X, int Y, int W, int H, const char *L)\n", name(), name()); |
---|
1456 | write_c(" : %s(X, Y, W, H, L) {\n", c); |
---|
1457 | write_c(" _%s();\n", name()); |
---|
1458 | write_c("}\n\n"); |
---|
1459 | |
---|
1460 | write_c("%s::%s(int W, int H, const char *L)\n", name(), name()); |
---|
1461 | write_c(" : %s(0, 0, W, H, L) {\n", c); |
---|
1462 | write_c(" clear_flag(16);\n"); |
---|
1463 | write_c(" _%s();\n", name()); |
---|
1464 | write_c("}\n\n"); |
---|
1465 | |
---|
1466 | write_c("void %s::_%s() {\n", name(), name()); |
---|
1467 | // write_c(" %s *w = this;\n", name()); |
---|
1468 | } else { |
---|
1469 | write_h("public:\n"); |
---|
1470 | write_h(" %s(int X, int Y, int W, int H, const char *L = 0);\n", name()); |
---|
1471 | |
---|
1472 | write_c("%s::%s(int X, int Y, int W, int H, const char *L)\n", name(), name()); |
---|
1473 | if (wc_relative) |
---|
1474 | write_c(" : %s(0, 0, W, H, L) {\n", c); |
---|
1475 | else |
---|
1476 | write_c(" : %s(X, Y, W, H, L) {\n", c); |
---|
1477 | } |
---|
1478 | |
---|
1479 | // write_c(" %s *o = this;\n", name()); |
---|
1480 | |
---|
1481 | write_widget_code(); |
---|
1482 | } |
---|
1483 | |
---|
1484 | void Fl_Widget_Class_Type::write_code2() { |
---|
1485 | write_extra_code(); |
---|
1486 | if (wc_relative) write_c("%sposition(X, Y);\n", indent()); |
---|
1487 | if (modal) write_c("%sset_modal();\n", indent()); |
---|
1488 | else if (non_modal) write_c("%sset_non_modal();\n", indent()); |
---|
1489 | if (!((Fl_Window*)o)->border()) write_c("%sclear_border();\n", indent()); |
---|
1490 | if (xclass) { |
---|
1491 | write_c("%sxclass(", indent()); |
---|
1492 | write_cstring(xclass); |
---|
1493 | write_c(");\n"); |
---|
1494 | } |
---|
1495 | write_c("%send();\n", indent()); |
---|
1496 | if (((Fl_Window*)o)->resizable() == o) |
---|
1497 | write_c("%sresizable(this);\n", indent()); |
---|
1498 | write_c("}\n"); |
---|
1499 | } |
---|
1500 | |
---|
1501 | //////////////////////////////////////////////////////////////// |
---|
1502 | // live mode support |
---|
1503 | |
---|
1504 | Fl_Widget *Fl_Window_Type::enter_live_mode(int) { |
---|
1505 | Fl_Window *win = new Fl_Window(o->x(), o->y(), o->w(), o->h()); |
---|
1506 | live_widget = win; |
---|
1507 | if (live_widget) { |
---|
1508 | copy_properties(); |
---|
1509 | Fl_Type *n; |
---|
1510 | for (n = next; n && n->level > level; n = n->next) { |
---|
1511 | if (n->level == level+1) |
---|
1512 | n->enter_live_mode(); |
---|
1513 | } |
---|
1514 | win->end(); |
---|
1515 | } |
---|
1516 | return live_widget; |
---|
1517 | } |
---|
1518 | |
---|
1519 | void Fl_Window_Type::leave_live_mode() { |
---|
1520 | } |
---|
1521 | |
---|
1522 | /** |
---|
1523 | * copy all properties from the edit widget to the live widget |
---|
1524 | */ |
---|
1525 | void Fl_Window_Type::copy_properties() { |
---|
1526 | Fl_Widget_Type::copy_properties(); |
---|
1527 | /// \todo copy resizing constraints over |
---|
1528 | } |
---|
1529 | |
---|
1530 | |
---|
1531 | // |
---|
1532 | // End of "$Id$". |
---|
1533 | // |
---|