1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "window/window.hh"
|
---|
10 | #include "area/rectlist.hh"
|
---|
11 | #include "device/kernel.hh"
|
---|
12 | #include "error/error.hh"
|
---|
13 | #include "window/win_evt.hh"
|
---|
14 | #include "image/image.hh"
|
---|
15 | #include "window/cursor.hh"
|
---|
16 | #include "time/profile.hh"
|
---|
17 |
|
---|
18 | i4_profile_class pf_child_draw_prepare("window::child_prepare"),
|
---|
19 | pf_parent_draw_prepare("window::parent_prepare");
|
---|
20 |
|
---|
21 | #include <stdlib.h>
|
---|
22 |
|
---|
23 | i4_parent_window_class *i4_window_class::root_window()
|
---|
24 | {
|
---|
25 | if (parent)
|
---|
26 | return parent->root_window();
|
---|
27 | else return 0;
|
---|
28 | }
|
---|
29 |
|
---|
30 | i4_parent_window_class *i4_parent_window_class::root_window()
|
---|
31 | {
|
---|
32 | if (parent)
|
---|
33 | return parent->root_window();
|
---|
34 | else return this;
|
---|
35 | }
|
---|
36 |
|
---|
37 | i4_bool i4_window_class::isa_parent(i4_window_class *who)
|
---|
38 | {
|
---|
39 | if (who==0)
|
---|
40 | return i4_F;
|
---|
41 | else if (who==parent)
|
---|
42 | return i4_T;
|
---|
43 | else if (parent)
|
---|
44 | return parent->isa_parent(who);
|
---|
45 | else return i4_F;
|
---|
46 | }
|
---|
47 |
|
---|
48 | void i4_window_class::receive_event(i4_event *ev)
|
---|
49 | {
|
---|
50 | if (ev->type()==i4_event::MOUSE_MOVE)
|
---|
51 | {
|
---|
52 | CAST_PTR(move, i4_mouse_move_event_class, ev);
|
---|
53 | mouse_x=move->x;
|
---|
54 | mouse_y=move->y;
|
---|
55 | }
|
---|
56 |
|
---|
57 | if (cursor && parent) // if we have a cursor we need to load when we get a mouse focus
|
---|
58 | {
|
---|
59 | if (ev->type()==i4_event::WINDOW_MESSAGE)
|
---|
60 | {
|
---|
61 | CAST_PTR(wev,i4_window_message_class,ev);
|
---|
62 | if (wev->sub_type==i4_window_message_class::GOT_MOUSE_FOCUS)
|
---|
63 | {
|
---|
64 | CAST_PTR(mev, i4_window_got_mouse_focus_class, ev);
|
---|
65 |
|
---|
66 | mouse_x=mev->x;
|
---|
67 | mouse_y=mev->y;
|
---|
68 |
|
---|
69 | i4_window_change_cursor_class c(this,cursor);
|
---|
70 | i4_kernel.send_event(parent,&c);
|
---|
71 | } else if (wev->sub_type==i4_window_message_class::LOST_MOUSE_FOCUS)
|
---|
72 | {
|
---|
73 | i4_window_change_cursor_class c(this,0); // unload the cursor
|
---|
74 | i4_kernel.send_event(parent,&c);
|
---|
75 | }
|
---|
76 | }
|
---|
77 | }
|
---|
78 | }
|
---|
79 |
|
---|
80 | void i4_window_class::set_cursor(i4_cursor_class *Cursor)
|
---|
81 | {
|
---|
82 | if (cursor)
|
---|
83 | delete cursor;
|
---|
84 |
|
---|
85 | if (Cursor)
|
---|
86 | cursor=Cursor->copy();
|
---|
87 | else
|
---|
88 | cursor=0;
|
---|
89 |
|
---|
90 | if (parent)
|
---|
91 | {
|
---|
92 | i4_window_change_cursor_class c(this,cursor,i4_F);
|
---|
93 | i4_kernel.send_event(parent,&c);
|
---|
94 | }
|
---|
95 | }
|
---|
96 |
|
---|
97 | i4_window_class::~i4_window_class()
|
---|
98 | {
|
---|
99 | if (cursor)
|
---|
100 | delete cursor;
|
---|
101 |
|
---|
102 | if (parent)
|
---|
103 | parent->remove_child(this);
|
---|
104 | }
|
---|
105 |
|
---|
106 |
|
---|
107 | void i4_window_class::resize(w16 new_width, w16 new_height)
|
---|
108 | {
|
---|
109 | if (parent)
|
---|
110 | {
|
---|
111 | i4_window_notify_resize_class resize(this,new_width,new_height);
|
---|
112 | i4_kernel.send_event(parent,&resize);
|
---|
113 | }
|
---|
114 | private_resize(new_width,new_height);
|
---|
115 | }
|
---|
116 |
|
---|
117 | void i4_parent_window_class::resize(w16 new_width, w16 new_height)
|
---|
118 | {
|
---|
119 | i4_window_class::resize(new_width, new_height);
|
---|
120 |
|
---|
121 | i4_window_notify_resize_class resize(this,new_width,new_height);
|
---|
122 |
|
---|
123 | for (win_iter c=children.begin(); c!=children.end(); ++c)
|
---|
124 | send_event_to_child(&*c,&resize);
|
---|
125 | }
|
---|
126 |
|
---|
127 |
|
---|
128 | void i4_window_class::private_resize(w16 new_width, w16 new_height)
|
---|
129 | {
|
---|
130 | i4_rect_list_class parent_dirty;
|
---|
131 | if (width() && height())
|
---|
132 | parent_dirty.add_area(0,0,width()-1, height()-1);
|
---|
133 |
|
---|
134 | w=new_width;
|
---|
135 | h=new_height;
|
---|
136 | parent_dirty.remove_area(0,0,width()-1,height()-1);
|
---|
137 |
|
---|
138 | if (width() && height())
|
---|
139 | note_undrawn(0,0,width()-1,height()-1);
|
---|
140 |
|
---|
141 |
|
---|
142 | if (parent)
|
---|
143 | {
|
---|
144 | for (i4_rect_list_class::area_iter a=parent_dirty.list.begin();
|
---|
145 | a!=parent_dirty.list.end(); ++a)
|
---|
146 | {
|
---|
147 | parent->note_undrawn(a->x1 + x() - parent->x(),
|
---|
148 | a->y1 + y() - parent->y(),
|
---|
149 | a->x2 + x() - parent->x(),
|
---|
150 | a->y2 + y() - parent->y());
|
---|
151 |
|
---|
152 | }
|
---|
153 | }
|
---|
154 |
|
---|
155 | request_redraw();
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 | void i4_window_class::reparent(i4_image_class *draw_area, i4_parent_window_class *Parent)
|
---|
160 | {
|
---|
161 | parent=Parent;
|
---|
162 | if (parent)
|
---|
163 | {
|
---|
164 | mouse_x=parent->last_mouse_x()+parent->x()-x();
|
---|
165 | mouse_y=parent->last_mouse_y()+parent->y()-y();
|
---|
166 | }
|
---|
167 | else
|
---|
168 | {
|
---|
169 | mouse_x=-10000;
|
---|
170 | mouse_y=-10000;
|
---|
171 | }
|
---|
172 |
|
---|
173 | if (local_image)
|
---|
174 | local_image=0;
|
---|
175 |
|
---|
176 | global_image=draw_area;
|
---|
177 | if (global_image)
|
---|
178 | {
|
---|
179 | local_image=global_image;
|
---|
180 |
|
---|
181 | if (width() & height())
|
---|
182 | note_undrawn(0,0,width()-1,height()-1);
|
---|
183 |
|
---|
184 | request_redraw();
|
---|
185 | }
|
---|
186 | }
|
---|
187 |
|
---|
188 | void i4_window_class::private_move(i4_coord x_offset, i4_coord y_offset)
|
---|
189 | {
|
---|
190 | global_x+=x_offset;
|
---|
191 | global_y+=y_offset;
|
---|
192 |
|
---|
193 | if (width() && height())
|
---|
194 | note_undrawn(0,0,width()-1,height()-1);
|
---|
195 |
|
---|
196 |
|
---|
197 | request_redraw();
|
---|
198 | }
|
---|
199 |
|
---|
200 | void i4_window_class::move(i4_coord x_offset, i4_coord y_offset, i4_bool draw_under)
|
---|
201 | {
|
---|
202 | private_move(x_offset,y_offset);
|
---|
203 | if (parent)
|
---|
204 | {
|
---|
205 | i4_window_notify_move_class move(this,x_offset,y_offset,draw_under);
|
---|
206 | i4_kernel.send_event(parent,&move);
|
---|
207 | }
|
---|
208 | }
|
---|
209 |
|
---|
210 | void i4_window_class::draw(i4_draw_context_class &context)
|
---|
211 | {
|
---|
212 | redraw_flag=i4_F;
|
---|
213 | }
|
---|
214 |
|
---|
215 | void i4_window_class::request_redraw(i4_bool for_a_child)
|
---|
216 | {
|
---|
217 | redraw_flag=i4_T;
|
---|
218 |
|
---|
219 | if (parent)
|
---|
220 | {
|
---|
221 | if (transparent() && width() && height())
|
---|
222 | {
|
---|
223 | int x1=x()-parent->x(), y1=y()-parent->y();
|
---|
224 | int x2=x1+width()-1, y2=y1+height()-1;
|
---|
225 |
|
---|
226 | parent->note_undrawn(x1,y1,x2,y2, i4_F);
|
---|
227 | }
|
---|
228 |
|
---|
229 | parent->request_redraw(i4_T);
|
---|
230 | }
|
---|
231 | }
|
---|
232 |
|
---|
233 | void i4_window_class::note_undrawn(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2,
|
---|
234 | i4_bool propogate_to_children)
|
---|
235 | {
|
---|
236 | request_redraw(i4_F);
|
---|
237 | }
|
---|
238 |
|
---|
239 |
|
---|
240 |
|
---|
241 | void i4_parent_window_class::parent_draw(i4_draw_context_class &context)
|
---|
242 | {
|
---|
243 | redraw_flag=i4_F;
|
---|
244 | }
|
---|
245 |
|
---|
246 | // draw should redraw supplied area of self
|
---|
247 | void i4_parent_window_class::draw(i4_draw_context_class &context)
|
---|
248 |
|
---|
249 | {
|
---|
250 | if (!undrawn_area.empty() || redraw_flag)
|
---|
251 | {
|
---|
252 | pf_parent_draw_prepare.start();
|
---|
253 |
|
---|
254 | redraw_flag=i4_F;
|
---|
255 | // copy the clip list, which should already be in our coordinates
|
---|
256 | i4_rect_list_class child_clip(&context.clip,0,0);
|
---|
257 |
|
---|
258 | // remove the area of other children above us
|
---|
259 | win_iter d=children.begin();
|
---|
260 | for (;d!=children.end();++d)
|
---|
261 | {
|
---|
262 | if (!d->transparent())
|
---|
263 | child_clip.remove_area(d->x()-x(),
|
---|
264 | d->y()-y(),
|
---|
265 | d->x()+d->width()-1-x(),
|
---|
266 | d->y()+d->height()-1-y());
|
---|
267 | }
|
---|
268 |
|
---|
269 | child_clip.swap(&context.clip);
|
---|
270 |
|
---|
271 | pf_parent_draw_prepare.stop();
|
---|
272 |
|
---|
273 | parent_draw(context);
|
---|
274 |
|
---|
275 | pf_parent_draw_prepare.start();
|
---|
276 | undrawn_area.delete_list();
|
---|
277 |
|
---|
278 | child_clip.swap(&context.clip);
|
---|
279 | pf_parent_draw_prepare.stop();
|
---|
280 |
|
---|
281 | }
|
---|
282 |
|
---|
283 | if (child_need_redraw)
|
---|
284 | {
|
---|
285 | child_need_redraw=i4_F;
|
---|
286 | win_iter c=children.begin();
|
---|
287 | for (;c!=children.end();++c)
|
---|
288 | {
|
---|
289 | if (c->need_redraw())
|
---|
290 | {
|
---|
291 | pf_child_draw_prepare.start();
|
---|
292 |
|
---|
293 | i4_coord x1=c->x()-x(),
|
---|
294 | y1=c->y()-y(),
|
---|
295 | x2=c->x()+c->width()-1-x(),
|
---|
296 | y2=c->y()+c->height()-1-y();
|
---|
297 |
|
---|
298 | // copy the clip list, and move it to local coordinates
|
---|
299 | i4_rect_list_class child_clip(&context.clip,
|
---|
300 | -(c->x()-x()),
|
---|
301 | -(c->y()-y()));
|
---|
302 |
|
---|
303 | // intersect the clip with what our area is supposed to be
|
---|
304 | child_clip.intersect_area(0,0,
|
---|
305 | c->width()-1,
|
---|
306 | c->height()-1);
|
---|
307 |
|
---|
308 | // save the old context xoff and yoff
|
---|
309 | sw16 old_xoff=context.xoff,old_yoff=context.yoff;
|
---|
310 |
|
---|
311 | // move the context offset to the child's x,y
|
---|
312 | context.xoff+=(c->x()-x());
|
---|
313 | context.yoff+=(c->y()-y());
|
---|
314 |
|
---|
315 | // remove the area of other children above us
|
---|
316 | i4_window_class *d=c->next;
|
---|
317 | for (;d;d=d->next)
|
---|
318 | child_clip.remove_area(d->x()-c->x(),
|
---|
319 | d->y()-c->y(),
|
---|
320 | d->x()+d->width()-1-c->x(),
|
---|
321 | d->y()+d->height()-1-c->y());
|
---|
322 |
|
---|
323 | c->call_stack_counter++; // make sure window doesn't get deleted during it's draw
|
---|
324 |
|
---|
325 | // the child is covered completely by other windows
|
---|
326 | // tell it this in case it depends on draw()
|
---|
327 | if (child_clip.empty())
|
---|
328 | c->forget_redraw();
|
---|
329 | else
|
---|
330 | {
|
---|
331 | child_clip.swap(&context.clip);
|
---|
332 |
|
---|
333 | child_rerequested_redraw = i4_F;
|
---|
334 |
|
---|
335 | pf_child_draw_prepare.stop();
|
---|
336 |
|
---|
337 | c->draw(context); // the child is ready to draw
|
---|
338 |
|
---|
339 | pf_child_draw_prepare.start();
|
---|
340 | if (!child_rerequested_redraw)
|
---|
341 | c->i4_window_class::forget_redraw();
|
---|
342 |
|
---|
343 | child_clip.swap(&context.clip); // restore the old clip list
|
---|
344 | }
|
---|
345 |
|
---|
346 | context.xoff=old_xoff; // restore the context's x & y offsets
|
---|
347 | context.yoff=old_yoff;
|
---|
348 |
|
---|
349 | c->call_stack_counter--;
|
---|
350 | pf_child_draw_prepare.stop();
|
---|
351 |
|
---|
352 | }
|
---|
353 | }
|
---|
354 | }
|
---|
355 |
|
---|
356 | }
|
---|
357 |
|
---|
358 | #if ( __linux || __sgi)
|
---|
359 | //extern void db_show();
|
---|
360 | #else
|
---|
361 | //void db_show() { ; }
|
---|
362 | #endif
|
---|
363 |
|
---|
364 | void i4_window_class::show_context(i4_draw_context_class &context)
|
---|
365 | {
|
---|
366 | i4_draw_context_class nc(0,0,local_image->width(),local_image->height());
|
---|
367 | local_image->clear(0xffff,nc);
|
---|
368 | i4_rect_list_class::area_iter c=context.clip.list.begin();
|
---|
369 | for (; c!=context.clip.list.end(); ++c)
|
---|
370 | local_image->rectangle(c->x1,c->y1,c->x2,c->y2,0,nc);
|
---|
371 |
|
---|
372 | // db_show();
|
---|
373 | }
|
---|
374 |
|
---|
375 |
|
---|
376 | i4_window_class::i4_window_class(w16 w, w16 h) : w(w),h(h)
|
---|
377 | {
|
---|
378 | mouse_x=-10000;
|
---|
379 | mouse_y=-10000;
|
---|
380 |
|
---|
381 | global_x=0;
|
---|
382 | global_y=0;
|
---|
383 | local_image=0;
|
---|
384 | global_image=0;
|
---|
385 | parent=0;
|
---|
386 | cursor=0;
|
---|
387 | }
|
---|
388 |
|
---|
389 |
|
---|
390 | i4_parent_window_class::i4_parent_window_class(w16 w, w16 h) : i4_window_class(w,h)
|
---|
391 | {
|
---|
392 | have_mouse_focus=i4_F;
|
---|
393 | mouse_focus_grabbed=i4_F;
|
---|
394 | key_focus=children.end();
|
---|
395 | mouse_focus=children.end();
|
---|
396 | drag_drop_focus=children.end();
|
---|
397 | }
|
---|
398 |
|
---|
399 | i4_parent_window_class::win_iter i4_parent_window_class::find_window(i4_coord global_mouse_x,
|
---|
400 | i4_coord global_mouse_y)
|
---|
401 | {
|
---|
402 | win_iter c=children.begin(),
|
---|
403 | find=children.end();
|
---|
404 |
|
---|
405 | for (;c!=children.end();++c)
|
---|
406 | {
|
---|
407 | if (global_mouse_x>=c->x() &&
|
---|
408 | global_mouse_y>=c->y() &&
|
---|
409 | global_mouse_x<c->x()+c->width() &&
|
---|
410 | global_mouse_y<c->y()+c->height())
|
---|
411 | find=c;
|
---|
412 | }
|
---|
413 | return find;
|
---|
414 | }
|
---|
415 |
|
---|
416 | void i4_parent_window_class::drag_drop_move(i4_event *ev)
|
---|
417 | {
|
---|
418 | CAST_PTR(move, i4_window_drag_drop_move_class, ev);
|
---|
419 | i4_coord real_mx=move->x+x(),
|
---|
420 | real_my=move->y+y();
|
---|
421 |
|
---|
422 | win_iter find=find_window(real_mx, real_my);
|
---|
423 | if (find != drag_drop_focus)
|
---|
424 | {
|
---|
425 | if (drag_drop_focus != children.end())
|
---|
426 | {
|
---|
427 | i4_window_lost_drag_drop_focus_class lost(this);
|
---|
428 | send_event_to_child(&*drag_drop_focus, &lost);
|
---|
429 | }
|
---|
430 |
|
---|
431 | drag_drop_focus = find;
|
---|
432 | if (find != children.end())
|
---|
433 | {
|
---|
434 | i4_window_class *prev_from=move->from_window;
|
---|
435 | move->from_window=this;
|
---|
436 |
|
---|
437 | send_event_to_child(&*find, move);
|
---|
438 |
|
---|
439 | move->from_window=prev_from;
|
---|
440 | }
|
---|
441 | }
|
---|
442 |
|
---|
443 | if (drag_drop_focus != children.end())
|
---|
444 | send_event_to_child(&*drag_drop_focus,ev);
|
---|
445 | }
|
---|
446 |
|
---|
447 |
|
---|
448 | i4_bool i4_parent_window_class::find_new_mouse_focus()
|
---|
449 | {
|
---|
450 | if (!mouse_focus_grabbed) // see if we need to change the mouse focus
|
---|
451 | {
|
---|
452 | win_iter new_mouse_focus=find_window(mouse_x + x(), mouse_y + y());
|
---|
453 |
|
---|
454 | if (new_mouse_focus!=mouse_focus)
|
---|
455 | {
|
---|
456 | change_mouse_focus(&*new_mouse_focus);
|
---|
457 | return i4_T;
|
---|
458 | }
|
---|
459 |
|
---|
460 | else return i4_F;
|
---|
461 | }
|
---|
462 | else return i4_F;
|
---|
463 | }
|
---|
464 |
|
---|
465 | void i4_parent_window_class::mouse_move(i4_event *ev)
|
---|
466 | {
|
---|
467 | CAST_PTR(move, i4_mouse_move_event_class, ev);
|
---|
468 | mouse_x=move->x;
|
---|
469 | mouse_y=move->y;
|
---|
470 |
|
---|
471 | find_new_mouse_focus();
|
---|
472 |
|
---|
473 | if (mouse_focus!=children.end())
|
---|
474 | send_event_to_child(&*mouse_focus,ev);
|
---|
475 | }
|
---|
476 |
|
---|
477 | void i4_parent_window_class::send_event_to_child(i4_window_class *w, i4_event *ev)
|
---|
478 | {
|
---|
479 | sw32 xo=(sw32)x()-(sw32)w->x(), yo=(sw32)y()-(sw32)w->y();
|
---|
480 |
|
---|
481 | ev->move(xo, yo);
|
---|
482 | i4_kernel.send_event(w, ev);
|
---|
483 | ev->move(-xo, -yo);
|
---|
484 | }
|
---|
485 |
|
---|
486 | // passes events to mouse_focus or key_focus depending on the event type
|
---|
487 | void i4_parent_window_class::receive_event(i4_event *ev)
|
---|
488 | {
|
---|
489 | switch (ev->type())
|
---|
490 | {
|
---|
491 | case i4_event::IDLE_MESSAGE : // pass idle message to current mouse focus
|
---|
492 | {
|
---|
493 | if (mouse_focus!=children.end())
|
---|
494 | send_event_to_child(&*mouse_focus,ev);
|
---|
495 | } break;
|
---|
496 |
|
---|
497 | case i4_event::MOUSE_MOVE :
|
---|
498 | {
|
---|
499 | mouse_move(ev);
|
---|
500 | } break;
|
---|
501 |
|
---|
502 | case i4_event::MOUSE_BUTTON_DOWN :
|
---|
503 | {
|
---|
504 | if (mouse_focus!=children.end())
|
---|
505 | send_event_to_child(&*mouse_focus,ev);
|
---|
506 | } break;
|
---|
507 |
|
---|
508 | case i4_event::MOUSE_BUTTON_UP :
|
---|
509 | {
|
---|
510 | if (mouse_focus!=children.end())
|
---|
511 | send_event_to_child(&*mouse_focus,ev);
|
---|
512 | } break;
|
---|
513 |
|
---|
514 | case i4_event::KEY_PRESS :
|
---|
515 | case i4_event::KEY_RELEASE :
|
---|
516 | {
|
---|
517 | if (key_focus!=children.end())
|
---|
518 | send_event_to_child(&*key_focus,ev);
|
---|
519 | else if (mouse_focus!=children.end())
|
---|
520 | send_event_to_child(&*mouse_focus,ev);
|
---|
521 | } break;
|
---|
522 |
|
---|
523 |
|
---|
524 | case i4_event::WINDOW_MESSAGE :
|
---|
525 | {
|
---|
526 | CAST_PTR(mess,i4_window_message_class,ev);
|
---|
527 | switch (mess->sub_type)
|
---|
528 | {
|
---|
529 | case i4_window_message_class::GOT_DROP :
|
---|
530 | {
|
---|
531 | if (drag_drop_focus != children.end())
|
---|
532 | {
|
---|
533 | send_event_to_child(&*drag_drop_focus, ev);
|
---|
534 | drag_drop_focus=children.end();
|
---|
535 | }
|
---|
536 | else
|
---|
537 | {
|
---|
538 | CAST_PTR(dev, i4_window_got_drop_class, ev);
|
---|
539 |
|
---|
540 | i4_parent_window_class::win_iter w=find_window(dev->drag_info.x+x(),
|
---|
541 | dev->drag_info.y+y());
|
---|
542 | if (w!=children.end())
|
---|
543 | send_event_to_child(&*w, ev);
|
---|
544 | }
|
---|
545 | } break;
|
---|
546 |
|
---|
547 | case i4_window_message_class::REQUEST_DRAG_DROP_START :
|
---|
548 | case i4_window_message_class::REQUEST_DRAG_DROP_END :
|
---|
549 | {
|
---|
550 | if (parent)
|
---|
551 | parent->receive_event(ev);
|
---|
552 | } break;
|
---|
553 | case i4_window_message_class::DRAG_DROP_MOVE :
|
---|
554 | {
|
---|
555 | drag_drop_move(ev);
|
---|
556 | } break;
|
---|
557 |
|
---|
558 | case i4_window_message_class::CHANGE_CURSOR :
|
---|
559 | {
|
---|
560 | CAST_PTR(cc,i4_window_change_cursor_class,ev);
|
---|
561 | if (parent && (!cc->only_if_active || cc->from()==&*mouse_focus))
|
---|
562 | {
|
---|
563 | i4_window_change_cursor_class scope(this,cc->cursor,cc->only_if_active);
|
---|
564 | parent->receive_event(&scope);
|
---|
565 | }
|
---|
566 |
|
---|
567 | } break;
|
---|
568 | case i4_window_message_class::REQUEST_KEY_GRAB :
|
---|
569 | {
|
---|
570 | CAST_PTR(grab,i4_window_request_key_grab_class,ev);
|
---|
571 | grab->return_result=i4_T;
|
---|
572 |
|
---|
573 | if (parent)
|
---|
574 | {
|
---|
575 | i4_window_request_key_grab_class ask_parent(this);
|
---|
576 | i4_kernel.send_event(parent,&ask_parent);
|
---|
577 | if (ask_parent.return_result==i4_F)
|
---|
578 | grab->return_result=i4_F;
|
---|
579 | }
|
---|
580 |
|
---|
581 | if (grab->return_result)
|
---|
582 | {
|
---|
583 | win_iter c=children.begin();
|
---|
584 | for (;c!=children.end() && c!=mess->from();++c);
|
---|
585 | if (c!=children.end())
|
---|
586 | {
|
---|
587 | if (c != key_focus)
|
---|
588 | change_key_focus(&*c);
|
---|
589 | }
|
---|
590 | else
|
---|
591 | i4_warning("got key grab from unknown child");
|
---|
592 | }
|
---|
593 | } break;
|
---|
594 | case i4_window_message_class::REQUEST_DELETE :
|
---|
595 | {
|
---|
596 | remove_child(mess->from());
|
---|
597 | delete mess->from();
|
---|
598 | } break;
|
---|
599 |
|
---|
600 | case i4_window_message_class::REQUEST_NEXT_KEY_FOCUS : next_key_focus(); break;
|
---|
601 | case i4_window_message_class::REQUEST_LEFT_KEY_FOCUS : left_key_focus(); break;
|
---|
602 | case i4_window_message_class::REQUEST_RIGHT_KEY_FOCUS : right_key_focus(); break;
|
---|
603 | case i4_window_message_class::REQUEST_UP_KEY_FOCUS : up_key_focus(); break;
|
---|
604 | case i4_window_message_class::REQUEST_DOWN_KEY_FOCUS : down_key_focus(); break;
|
---|
605 | case i4_window_message_class::REQUEST_MOUSE_GRAB :
|
---|
606 | {
|
---|
607 | CAST_PTR(grab,i4_window_request_mouse_grab_class,ev);
|
---|
608 |
|
---|
609 | grab->return_result=i4_T; // defulat return is false
|
---|
610 |
|
---|
611 | if (!mouse_focus_grabbed) // see if we need to change the mouse focus
|
---|
612 | {
|
---|
613 | if (parent)
|
---|
614 | {
|
---|
615 | i4_window_request_mouse_grab_class ask_parent(this);
|
---|
616 | i4_kernel.send_event(parent,&ask_parent);
|
---|
617 | if (ask_parent.return_result==i4_F)
|
---|
618 | grab->return_result=i4_F;
|
---|
619 | else grab->return_result=i4_T;
|
---|
620 | }
|
---|
621 |
|
---|
622 | if (grab->return_result)
|
---|
623 | {
|
---|
624 | mouse_focus_grabbed=i4_T;
|
---|
625 |
|
---|
626 | if (&(*mouse_focus) != grab->from())
|
---|
627 | change_mouse_focus(grab->from());
|
---|
628 | }
|
---|
629 |
|
---|
630 | } else
|
---|
631 | grab->return_result=i4_F;
|
---|
632 | } break;
|
---|
633 |
|
---|
634 | case i4_window_message_class::REQUEST_MOUSE_UNGRAB :
|
---|
635 | {
|
---|
636 | if (mouse_focus_grabbed)
|
---|
637 | {
|
---|
638 | mouse_focus_grabbed=i4_F;
|
---|
639 | if (parent)
|
---|
640 | i4_kernel.send_event(parent,ev);
|
---|
641 |
|
---|
642 | find_new_mouse_focus();
|
---|
643 | }
|
---|
644 | else i4_warning("mouse not grabbed");
|
---|
645 |
|
---|
646 | } break;
|
---|
647 |
|
---|
648 |
|
---|
649 | case i4_window_message_class::NOTIFY_RESIZE :
|
---|
650 | {
|
---|
651 | CAST_PTR(resize,i4_window_notify_resize_class,ev);
|
---|
652 | i4_window_class *cf=resize->from();
|
---|
653 |
|
---|
654 | if (cf!=parent) // if this is from our parent, ignore it
|
---|
655 | {
|
---|
656 | i4_rect_list_class dirty;
|
---|
657 | if (cf->width() && cf->height())
|
---|
658 | dirty.add_area (cf->x(),cf->y(),cf->x()+cf->width()-1,cf->y()+cf->height()-1);
|
---|
659 |
|
---|
660 | if (resize->new_width && resize->new_height)
|
---|
661 | dirty.remove_area(cf->x(),cf->y(),
|
---|
662 | cf->x()+resize->new_width-1,
|
---|
663 | cf->y()+resize->new_height-1);
|
---|
664 |
|
---|
665 | if (width() && height())
|
---|
666 | dirty.intersect_area(x(),y(),x()+width()-1,y()+height()-1);
|
---|
667 |
|
---|
668 | if (resize->draw_covered)
|
---|
669 | {
|
---|
670 | // check to see if any child were under this window
|
---|
671 | // will need to be redraw because of this
|
---|
672 | win_iter c=children.begin();
|
---|
673 | for (;c!=children.end() && c!=cf;++c)
|
---|
674 | {
|
---|
675 | if (c->width() && c->height() &&
|
---|
676 | !dirty.clipped_away(c->x(),c->y(),c->x()+c->width()-1,c->y()+height()-1))
|
---|
677 | {
|
---|
678 | i4_rect_list_class::area_iter a=dirty.list.begin();
|
---|
679 | for (;a!=dirty.list.end();++a)
|
---|
680 | {
|
---|
681 | if (c->width() && c->height())
|
---|
682 | {
|
---|
683 | i4_coord x1=a->x1-c->x(),y1=a->y1-c->y(),x2=a->x2-c->x(),y2=a->y2-c->y();
|
---|
684 |
|
---|
685 | if (x1<0) x1=0;
|
---|
686 | if (y1<0) y1=0;
|
---|
687 | if (x2>=c->width()) x2=c->width()-1;
|
---|
688 | if (y2>=c->height()) y2=c->height()-1;
|
---|
689 | if (x1<=x2 && y1<=y2)
|
---|
690 | c->note_undrawn(x1,y1,x2,y2);
|
---|
691 | }
|
---|
692 | }
|
---|
693 | }
|
---|
694 | }
|
---|
695 |
|
---|
696 | // add this dirty area to the parent's undrawn_area list,
|
---|
697 | // so the parent knows what part of itself it needs to redraw
|
---|
698 | i4_rect_list_class::area_iter a=dirty.list.begin();
|
---|
699 | for (;a!=dirty.list.end();++a)
|
---|
700 | undrawn_area.add_area(a->x1-x(), // make sure we add in parent-local coordinates
|
---|
701 | a->y1-y(),
|
---|
702 | a->x2-x(),
|
---|
703 | a->y2-y());
|
---|
704 | }
|
---|
705 | }
|
---|
706 | else
|
---|
707 | request_redraw(i4_F);
|
---|
708 | } break;
|
---|
709 |
|
---|
710 | case i4_window_message_class::NOTIFY_MOVE :
|
---|
711 | {
|
---|
712 | CAST_PTR(move_event,i4_window_notify_move_class,ev);
|
---|
713 | i4_window_class *child=move_event->from();
|
---|
714 | i4_coord old_x=child->x()-move_event->x_offset,old_y=child->y()-move_event->y_offset;
|
---|
715 |
|
---|
716 | i4_coord new_x=child->x(),new_y=child->y();
|
---|
717 |
|
---|
718 | if (move_event->draw_covered)
|
---|
719 | {
|
---|
720 | i4_rect_list_class dirty;
|
---|
721 |
|
---|
722 | if (child->width() && child->height())
|
---|
723 | dirty.add_area(old_x,old_y,old_x+child->width()-1,old_y+child->height()-1);
|
---|
724 |
|
---|
725 | if (width() && height())
|
---|
726 | dirty.intersect_area(x(),y(),x()+width()-1,y()+height()-1);
|
---|
727 |
|
---|
728 | if (child->width() && child->height())
|
---|
729 | dirty.remove_area(new_x,new_y,new_x+child->width()-1,new_y+child->height()-1);
|
---|
730 |
|
---|
731 |
|
---|
732 | // check to see if any child were under this window will need to be redraw because of this
|
---|
733 | win_iter c=children.begin();
|
---|
734 | for (;c!=children.end() && c!=child;++c)
|
---|
735 | {
|
---|
736 | if (c->width() && c->height() &&
|
---|
737 | !dirty.clipped_away(c->x(),c->y(),c->x()+c->width()-1,c->y()+height()-1))
|
---|
738 | {
|
---|
739 | i4_rect_list_class::area_iter a=dirty.list.begin();
|
---|
740 | for (;a!=dirty.list.end();++a)
|
---|
741 | {
|
---|
742 | if (c->width() && c->height())
|
---|
743 | {
|
---|
744 | i4_coord x1=a->x1-c->x(),y1=a->y1-c->y(),x2=a->x2-c->x(),y2=a->y2-c->y();
|
---|
745 |
|
---|
746 | if (x1<0) x1=0;
|
---|
747 | if (y1<0) y1=0;
|
---|
748 | if (x2>=c->width()) x2=c->width()-1;
|
---|
749 | if (y2>=c->height()) y2=c->height()-1;
|
---|
750 | if (x1<=x2 && y1<=y2)
|
---|
751 | c->note_undrawn(x1,y1,x2,y2);
|
---|
752 | }
|
---|
753 | }
|
---|
754 | }
|
---|
755 | }
|
---|
756 |
|
---|
757 | // add this dirty area to the parent's dirty_area list,
|
---|
758 | // so the parent knows what part of itself it needs to redraw
|
---|
759 | i4_rect_list_class::area_iter a=dirty.list.begin();
|
---|
760 | for (;a!=dirty.list.end();++a)
|
---|
761 | undrawn_area.add_area(a->x1-x(), // add in local coordinates
|
---|
762 | a->y1-y(),
|
---|
763 | a->x2-x(),
|
---|
764 | a->y2-y());
|
---|
765 | }
|
---|
766 |
|
---|
767 | } break;
|
---|
768 |
|
---|
769 | case i4_window_message_class::GOT_MOUSE_FOCUS :
|
---|
770 | {
|
---|
771 | have_mouse_focus=i4_T;
|
---|
772 |
|
---|
773 | CAST_PTR(mev, i4_window_got_mouse_focus_class, ev);
|
---|
774 | mouse_x=mev->x;
|
---|
775 | mouse_y=mev->y;
|
---|
776 |
|
---|
777 | i4_window_change_cursor_class c(this,cursor);
|
---|
778 | i4_kernel.send_event(parent,&c);
|
---|
779 |
|
---|
780 | find_new_mouse_focus();
|
---|
781 | } break;
|
---|
782 |
|
---|
783 |
|
---|
784 | case i4_window_message_class::LOST_DROP_FOCUS :
|
---|
785 | {
|
---|
786 | if (drag_drop_focus!=children.end())
|
---|
787 | {
|
---|
788 | send_event_to_child(&*drag_drop_focus,ev);
|
---|
789 | drag_drop_focus=children.end();
|
---|
790 | }
|
---|
791 | i4_window_class::receive_event(ev);
|
---|
792 | } break;
|
---|
793 |
|
---|
794 | case i4_window_message_class::LOST_MOUSE_FOCUS :
|
---|
795 | {
|
---|
796 | if (mouse_focus!=children.end())
|
---|
797 | {
|
---|
798 | send_event_to_child(&*mouse_focus,ev);
|
---|
799 | mouse_focus=children.end();
|
---|
800 | }
|
---|
801 | i4_window_class::receive_event(ev);
|
---|
802 | have_mouse_focus=i4_F;
|
---|
803 |
|
---|
804 | } break;
|
---|
805 | case i4_window_message_class::LOST_KEYBOARD_FOCUS :
|
---|
806 | {
|
---|
807 | change_key_focus(0);
|
---|
808 | } break;
|
---|
809 | default :
|
---|
810 | i4_window_class::receive_event(ev);
|
---|
811 |
|
---|
812 | }
|
---|
813 | } break;
|
---|
814 | default :
|
---|
815 | i4_window_class::receive_event(ev);
|
---|
816 |
|
---|
817 | }
|
---|
818 | }
|
---|
819 |
|
---|
820 | void i4_parent_window_class::change_key_focus(i4_window_class *new_focus)
|
---|
821 | {
|
---|
822 | if (key_focus!=children.end())
|
---|
823 | {
|
---|
824 | i4_window_message_class lost(i4_window_message_class::LOST_KEYBOARD_FOCUS,this);
|
---|
825 | send_event_to_child(&*key_focus,&lost);
|
---|
826 | }
|
---|
827 |
|
---|
828 | key_focus=new_focus;
|
---|
829 |
|
---|
830 | if (new_focus)
|
---|
831 | {
|
---|
832 | i4_window_message_class got(i4_window_message_class::GOT_KEYBOARD_FOCUS,this);
|
---|
833 | send_event_to_child(&*key_focus,&got);
|
---|
834 | }
|
---|
835 | }
|
---|
836 |
|
---|
837 |
|
---|
838 | void i4_parent_window_class::change_mouse_focus(i4_window_class *new_focus)
|
---|
839 | {
|
---|
840 | if (mouse_focus!=children.end())
|
---|
841 | {
|
---|
842 | i4_window_lost_mouse_focus_class lost(this, new_focus);
|
---|
843 | send_event_to_child(&*mouse_focus,&lost);
|
---|
844 | }
|
---|
845 |
|
---|
846 |
|
---|
847 | mouse_focus=new_focus;
|
---|
848 |
|
---|
849 | if (mouse_focus!=children.end())
|
---|
850 | {
|
---|
851 | i4_window_got_mouse_focus_class got(this, mouse_x, mouse_y);
|
---|
852 | send_event_to_child(&*mouse_focus,&got);
|
---|
853 | }
|
---|
854 | }
|
---|
855 |
|
---|
856 |
|
---|
857 | void i4_parent_window_class::next_key_focus()
|
---|
858 | {
|
---|
859 | if (key_focus!=children.end())
|
---|
860 | change_key_focus(key_focus->next);
|
---|
861 | }
|
---|
862 |
|
---|
863 |
|
---|
864 | void i4_parent_window_class::left_key_focus()
|
---|
865 | {
|
---|
866 | if (key_focus!=children.end())
|
---|
867 | {
|
---|
868 | win_iter c=children.begin(),closest=children.end();
|
---|
869 | w32 closest_distance=0xffffffff;
|
---|
870 | i4_coord cx1=key_focus->x()+key_focus->width()/2,
|
---|
871 | cy1=key_focus->y()+key_focus->height()/2;
|
---|
872 |
|
---|
873 |
|
---|
874 | for (;c!=children.end();++c)
|
---|
875 | {
|
---|
876 | if (c->x()<key_focus->x())
|
---|
877 | {
|
---|
878 | i4_coord cx2=c->x()+c->width()/2,cy2=c->y()+c->height()/2;
|
---|
879 |
|
---|
880 | w32 dist=(cx2-cx1)*(cx2-cx1)+(cy2-cy1)*(cy2-cy1);
|
---|
881 | if (dist<closest_distance)
|
---|
882 | {
|
---|
883 | closest_distance=dist;
|
---|
884 | closest=c;
|
---|
885 | }
|
---|
886 | }
|
---|
887 | }
|
---|
888 |
|
---|
889 | if (closest!=children.end())
|
---|
890 | change_key_focus(&*closest);
|
---|
891 | }
|
---|
892 | }
|
---|
893 |
|
---|
894 |
|
---|
895 | void i4_parent_window_class::right_key_focus()
|
---|
896 | {
|
---|
897 | if (key_focus!=children.end())
|
---|
898 | {
|
---|
899 | win_iter c=children.begin(),closest=children.end();
|
---|
900 | w32 closest_distance=0xffffffff;
|
---|
901 | i4_coord cx1=key_focus->x()+key_focus->width()/2,
|
---|
902 | cy1=key_focus->y()+key_focus->height()/2;
|
---|
903 |
|
---|
904 |
|
---|
905 | for (;c!=children.end();++c)
|
---|
906 | {
|
---|
907 | if (c->x()>cx1)
|
---|
908 | {
|
---|
909 | i4_coord cx2=c->x()+c->width()/2,
|
---|
910 | cy2=c->y()+c->height()/2;
|
---|
911 | w32 dist=(cx2-cx1)*(cx2-cx1)+(cy2-cy1)*(cy2-cy1);
|
---|
912 | if (dist<closest_distance)
|
---|
913 | {
|
---|
914 | closest_distance=dist;
|
---|
915 | closest=c;
|
---|
916 | }
|
---|
917 | }
|
---|
918 | }
|
---|
919 |
|
---|
920 | if (closest!=children.end())
|
---|
921 | change_key_focus(&*closest);
|
---|
922 | }
|
---|
923 | }
|
---|
924 |
|
---|
925 |
|
---|
926 | void i4_parent_window_class::up_key_focus()
|
---|
927 | {
|
---|
928 | if (key_focus!=children.end())
|
---|
929 | {
|
---|
930 | win_iter c=children.begin(),closest=children.end();
|
---|
931 | w32 closest_distance=0xffffffff;
|
---|
932 | i4_coord cx1=key_focus->x()+key_focus->width()/2,
|
---|
933 | cy1=key_focus->y()+key_focus->height()/2;
|
---|
934 |
|
---|
935 |
|
---|
936 | for (;c!=children.end();++c)
|
---|
937 | {
|
---|
938 | if (c->y()<key_focus->y())
|
---|
939 | {
|
---|
940 | i4_coord cx2=c->x()+c->width()/2,
|
---|
941 | cy2=c->y()+c->height()/2;
|
---|
942 | w32 dist=(cx2-cx1)*(cx2-cx1)+(cy2-cy1)*(cy2-cy1);
|
---|
943 | if (dist<closest_distance)
|
---|
944 | {
|
---|
945 | closest_distance=dist;
|
---|
946 | closest=c;
|
---|
947 | }
|
---|
948 | }
|
---|
949 | }
|
---|
950 |
|
---|
951 | if (closest!=children.end())
|
---|
952 | change_key_focus(&*closest);
|
---|
953 | }
|
---|
954 | }
|
---|
955 |
|
---|
956 |
|
---|
957 | void i4_parent_window_class::down_key_focus()
|
---|
958 | {
|
---|
959 | if (key_focus!=children.end())
|
---|
960 | {
|
---|
961 | win_iter c=children.begin(),closest=children.end();
|
---|
962 | w32 closest_distance=0xffffffff;
|
---|
963 | i4_coord cx1=key_focus->x()+key_focus->width()/2,
|
---|
964 | cy1=key_focus->y()+key_focus->height()/2;
|
---|
965 |
|
---|
966 | for (;c!=children.end();++c)
|
---|
967 | {
|
---|
968 | if (c->y()>key_focus->y())
|
---|
969 | {
|
---|
970 | i4_coord cx2=c->x()+c->width()/2,
|
---|
971 | cy2=c->y()+c->height()/2;
|
---|
972 | w32 dist=(cx2-cx1)*(cx2-cx1)+(cy2-cy1)*(cy2-cy1);
|
---|
973 | if (dist<closest_distance)
|
---|
974 | {
|
---|
975 | closest_distance=dist;
|
---|
976 | closest=c;
|
---|
977 | }
|
---|
978 | }
|
---|
979 | }
|
---|
980 |
|
---|
981 | if (closest!=children.end())
|
---|
982 | change_key_focus(&*closest);
|
---|
983 | }
|
---|
984 | }
|
---|
985 |
|
---|
986 | void i4_parent_window_class::reparent(i4_image_class *draw_area, i4_parent_window_class *_parent)
|
---|
987 | {
|
---|
988 | // reparent children first, in case the have a mouse grab and need to tell our
|
---|
989 | // original parent to ungrab
|
---|
990 | for (win_iter c=children.begin();c!=children.end();++c)
|
---|
991 | c->reparent(draw_area,this);
|
---|
992 |
|
---|
993 | i4_window_class::reparent(draw_area,_parent);
|
---|
994 |
|
---|
995 | if (have_mouse_focus)
|
---|
996 | find_new_mouse_focus();
|
---|
997 | }
|
---|
998 |
|
---|
999 | void i4_parent_window_class::add_child(i4_coord x_, i4_coord y_, i4_window_class *child)
|
---|
1000 | {
|
---|
1001 | children.insert_end(*child);
|
---|
1002 | child->reparent(global_image,this);
|
---|
1003 | child->private_move(x()+x_-child->x(),y()+y_-child->y());
|
---|
1004 |
|
---|
1005 | if (have_mouse_focus)
|
---|
1006 | find_new_mouse_focus();
|
---|
1007 | }
|
---|
1008 |
|
---|
1009 | void i4_parent_window_class::add_child_front(i4_coord x_, i4_coord y_, i4_window_class *child)
|
---|
1010 | {
|
---|
1011 | children.insert(*child);
|
---|
1012 | child->reparent(global_image,this);
|
---|
1013 | child->private_move(x()+x_-child->x(),y()+y_-child->y());
|
---|
1014 |
|
---|
1015 | if (have_mouse_focus)
|
---|
1016 | find_new_mouse_focus();
|
---|
1017 | }
|
---|
1018 |
|
---|
1019 |
|
---|
1020 | void i4_parent_window_class::forget_redraw()
|
---|
1021 | {
|
---|
1022 | undrawn_area.delete_list();
|
---|
1023 | for (win_iter c=children.begin();c!=children.end();++c)
|
---|
1024 | c->forget_redraw();
|
---|
1025 | }
|
---|
1026 |
|
---|
1027 | void i4_parent_window_class::transfer_children(i4_parent_window_class *other_parent,
|
---|
1028 | i4_coord x_offset, i4_coord y_offset)
|
---|
1029 | {
|
---|
1030 | while (children.begin() != children.end())
|
---|
1031 | {
|
---|
1032 | i4_window_class *c=&*children.begin();
|
---|
1033 | i4_coord xn=c->x()-x();
|
---|
1034 | i4_coord yn=c->y()-y();
|
---|
1035 |
|
---|
1036 | remove_child(c);
|
---|
1037 | other_parent->add_child(xn+x_offset,
|
---|
1038 | yn+y_offset,c);
|
---|
1039 | }
|
---|
1040 |
|
---|
1041 | if (have_mouse_focus)
|
---|
1042 | find_new_mouse_focus();
|
---|
1043 |
|
---|
1044 | if (other_parent->has_mouse_focus())
|
---|
1045 | other_parent->find_new_mouse_focus();
|
---|
1046 | }
|
---|
1047 |
|
---|
1048 | void i4_parent_window_class::remove_child(i4_window_class *child)
|
---|
1049 | {
|
---|
1050 | if (&*key_focus==child)
|
---|
1051 | change_key_focus(0);
|
---|
1052 |
|
---|
1053 | if (&*mouse_focus==child)
|
---|
1054 | {
|
---|
1055 | if (mouse_focus_grabbed)
|
---|
1056 | {
|
---|
1057 | if (parent)
|
---|
1058 | {
|
---|
1059 | i4_window_request_mouse_ungrab_class ungrab(this);
|
---|
1060 | i4_kernel.send_event(parent, &ungrab);
|
---|
1061 | }
|
---|
1062 |
|
---|
1063 | mouse_focus_grabbed=i4_F;
|
---|
1064 | }
|
---|
1065 | }
|
---|
1066 |
|
---|
1067 | if (child==&*children.begin())
|
---|
1068 | children.erase();
|
---|
1069 | else
|
---|
1070 | {
|
---|
1071 | win_iter f=children.begin(),last=children.end();
|
---|
1072 | for (;f!=children.end() && f!=&*child;)
|
---|
1073 | {
|
---|
1074 | last=f;
|
---|
1075 | ++f;
|
---|
1076 | }
|
---|
1077 | if (f!=children.end())
|
---|
1078 | children.erase_after(last);
|
---|
1079 | else
|
---|
1080 | i4_error("child not found");
|
---|
1081 | }
|
---|
1082 |
|
---|
1083 | if (child->width() && child->height())
|
---|
1084 | {
|
---|
1085 | note_undrawn(child->x()-x(),
|
---|
1086 | child->y()-y(),
|
---|
1087 | child->x()+child->width()-1-x(),
|
---|
1088 | child->y()+child->height()-1-y());
|
---|
1089 | }
|
---|
1090 |
|
---|
1091 | if (&*mouse_focus==child)
|
---|
1092 | {
|
---|
1093 | i4_window_lost_mouse_focus_class lost(this, 0);
|
---|
1094 | send_event_to_child(child, &lost);
|
---|
1095 | mouse_focus=children.end();
|
---|
1096 | }
|
---|
1097 |
|
---|
1098 |
|
---|
1099 | child->reparent(0,0); // tell the child it doesn't have a parent or a draw_area anymore
|
---|
1100 |
|
---|
1101 | if (have_mouse_focus)
|
---|
1102 | find_new_mouse_focus();
|
---|
1103 |
|
---|
1104 | }
|
---|
1105 |
|
---|
1106 | void i4_parent_window_class::request_redraw(i4_bool for_a_child)
|
---|
1107 | {
|
---|
1108 | if (for_a_child)
|
---|
1109 | {
|
---|
1110 | child_need_redraw=i4_T;
|
---|
1111 | child_rerequested_redraw=i4_T;
|
---|
1112 | }
|
---|
1113 | else
|
---|
1114 | redraw_flag=i4_T;
|
---|
1115 | if (parent)
|
---|
1116 | parent->request_redraw(i4_T);
|
---|
1117 | }
|
---|
1118 |
|
---|
1119 | void i4_parent_window_class::note_undrawn(i4_coord x1, i4_coord y1,
|
---|
1120 | i4_coord x2, i4_coord y2,
|
---|
1121 | i4_bool propogate_to_children)
|
---|
1122 | {
|
---|
1123 |
|
---|
1124 | undrawn_area.add_area(x1,y1,x2,y2);
|
---|
1125 | request_redraw();
|
---|
1126 |
|
---|
1127 | win_iter c=children.begin();
|
---|
1128 |
|
---|
1129 |
|
---|
1130 | x1+=x(); y1+=y(); // transform to global coordinates
|
---|
1131 | x2+=x(); y2+=y();
|
---|
1132 |
|
---|
1133 | if (propogate_to_children)
|
---|
1134 | {
|
---|
1135 | for (;c!=children.end();++c)
|
---|
1136 | {
|
---|
1137 | if (c->width() && c->height())
|
---|
1138 | {
|
---|
1139 | if (!(c->x()>x2 ||
|
---|
1140 | c->y()>y2 ||
|
---|
1141 | c->x()+c->width()-1 < x1 ||
|
---|
1142 | c->y()+c->height()-1 < y1))
|
---|
1143 | {
|
---|
1144 | i4_coord ax1=x1-c->x(),
|
---|
1145 | ay1=y1-c->y(),
|
---|
1146 | ax2=x2-c->x(),
|
---|
1147 | ay2=y2-c->y();
|
---|
1148 | if (ax1<0) ax1=0;
|
---|
1149 | if (ay1<0) ay1=0;
|
---|
1150 | if (ax2>=c->width()) ax2=c->width()-1;
|
---|
1151 | if (ay2>=c->height()) ay2=c->height()-1;
|
---|
1152 | if (ax1<=ax2 && ay1<=ay2)
|
---|
1153 | c->note_undrawn(ax1,ay1,ax2,ay2);
|
---|
1154 | }
|
---|
1155 | }
|
---|
1156 | }
|
---|
1157 | }
|
---|
1158 | }
|
---|
1159 |
|
---|
1160 |
|
---|
1161 |
|
---|
1162 | void i4_parent_window_class::private_move(i4_coord x_offset, i4_coord y_offset)
|
---|
1163 | {
|
---|
1164 | i4_window_class::private_move(x_offset,y_offset);
|
---|
1165 | win_iter c=children.begin();
|
---|
1166 | for (;c!=children.end();++c)
|
---|
1167 | {
|
---|
1168 | c->private_move(x_offset,y_offset);
|
---|
1169 | }
|
---|
1170 | // use private move so child doesn't tell us it moved (we know!)
|
---|
1171 | }
|
---|
1172 |
|
---|
1173 |
|
---|
1174 | void i4_parent_window_class::redraw_area(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2)
|
---|
1175 | {
|
---|
1176 | if (!(x2<0 || y2<0 || x1>=width() || y1>=height()))
|
---|
1177 | undrawn_area.add_area(x1,y1,x2,y2);
|
---|
1178 | }
|
---|
1179 |
|
---|
1180 | // arranges child windows from left to right then down
|
---|
1181 | void i4_parent_window_class::arrange_right_down()
|
---|
1182 | {
|
---|
1183 | i4_coord x1=x(),y1=y(),mh=0;
|
---|
1184 | win_iter c=children.begin();
|
---|
1185 | for (;c!=children.end();++c)
|
---|
1186 | {
|
---|
1187 |
|
---|
1188 | if (c->width()+x1>x()+width())
|
---|
1189 | {
|
---|
1190 | y1+=mh;
|
---|
1191 | x1=x();
|
---|
1192 | mh=0;
|
---|
1193 | }
|
---|
1194 |
|
---|
1195 | c->move(x1-c->x(),y1-c->y());
|
---|
1196 |
|
---|
1197 | if (c->height()>mh)
|
---|
1198 | mh=c->height();
|
---|
1199 |
|
---|
1200 | x1+=c->width();
|
---|
1201 |
|
---|
1202 |
|
---|
1203 | }
|
---|
1204 | }
|
---|
1205 |
|
---|
1206 | void i4_parent_window_class::resize_to_fit_children()
|
---|
1207 | {
|
---|
1208 | i4_coord x2=0,y2=0;
|
---|
1209 | win_iter c=children.begin();
|
---|
1210 | for (;c!=children.end();++c)
|
---|
1211 | {
|
---|
1212 | if (c->x()-x()+c->width()>x2)
|
---|
1213 | x2=c->x()-x()+c->width();
|
---|
1214 | if (c->y()-y()+c->height()>y2)
|
---|
1215 | y2=c->y()-y()+c->height();
|
---|
1216 | }
|
---|
1217 |
|
---|
1218 | resize(x2,y2);
|
---|
1219 | }
|
---|
1220 |
|
---|
1221 | void i4_parent_window_class::arrange_down_right() // arranges child windows from top to bottom then right
|
---|
1222 | {
|
---|
1223 | i4_coord x1=x(),y1=y(),mw=0;
|
---|
1224 | win_iter c=children.begin();
|
---|
1225 | for (;c!=children.end();++c)
|
---|
1226 | {
|
---|
1227 | if (c->height()+y1>=height())
|
---|
1228 | {
|
---|
1229 | x1+=mw;
|
---|
1230 | y1=y();
|
---|
1231 | mw=0;
|
---|
1232 | }
|
---|
1233 |
|
---|
1234 | c->move(x1-c->x(),y1-c->y());
|
---|
1235 | y1+=c->height();
|
---|
1236 |
|
---|
1237 | if (c->width()>mw)
|
---|
1238 | mw=c->width();
|
---|
1239 |
|
---|
1240 |
|
---|
1241 | }
|
---|
1242 | }
|
---|
1243 |
|
---|
1244 |
|
---|
1245 | i4_parent_window_class::~i4_parent_window_class()
|
---|
1246 | {
|
---|
1247 | while (children.begin() != children.end())
|
---|
1248 | {
|
---|
1249 | win_iter c=children.begin();
|
---|
1250 | children.erase();
|
---|
1251 | c->reparent(0,0);
|
---|
1252 |
|
---|
1253 | i4_kernel.delete_handler(&*c);
|
---|
1254 | }
|
---|
1255 | }
|
---|
1256 |
|
---|
1257 | i4_window_class *i4_parent_window_class::get_nth_window(w32 win_num)
|
---|
1258 | {
|
---|
1259 | win_iter i=children.begin();
|
---|
1260 | while (win_num && i!=children.end())
|
---|
1261 | {
|
---|
1262 | ++i;
|
---|
1263 | win_num--;
|
---|
1264 | }
|
---|
1265 | if (i==children.end())
|
---|
1266 | return 0;
|
---|
1267 | else return &*i;
|
---|
1268 | }
|
---|
1269 |
|
---|
1270 |
|
---|
1271 | #ifndef I4_RETAIL
|
---|
1272 | void i4_window_class::debug_show()
|
---|
1273 | {
|
---|
1274 | i4_warning("%s",name());
|
---|
1275 | if (parent)
|
---|
1276 | parent->debug_show();
|
---|
1277 | }
|
---|
1278 | #endif
|
---|
1279 |
|
---|
1280 | i4_bool i4_parent_window_class::isa_child(i4_window_class *w)
|
---|
1281 | {
|
---|
1282 | win_iter c=children.begin();
|
---|
1283 | for (;c!=children.end();++c)
|
---|
1284 | if (&*c==w)
|
---|
1285 | return i4_T;
|
---|
1286 |
|
---|
1287 | return i4_F;
|
---|
1288 | }
|
---|