]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/gizmos/dynamicsash.cpp
reverted the fix for Unicode compilation with VC++ as it breaks other ports (and...
[wxWidgets.git] / contrib / src / gizmos / dynamicsash.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dynamicsash.cpp
3 // Purpose: A window which can be dynamically split to an arbitrary depth
4 // and later reunified through the user interface
5 // Author: Matt Kimball
6 // Modified by:
7 // Created: 7/15/2001
8 // RCS-ID: $Id$
9 // Copyright: (c) 2001 Matt Kimball
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 #include "wx/gizmos/dynamicsash.h"
14
15 /*
16 wxDynamicSashWindow works by internally storing a tree of Implementation
17 objects (wxDynamicSsahWindowImpl) and Leaf objects
18 (wxDynamicSashWindowLeaf). The wxDynamicSashWindow has a pointer to one
19 implementation, and each implementation either has a pointer to a one
20 leaf (m_leaf) or a pointer to two children implementation objects
21 (m_child). The leaves each are responsible for drawing the frame and
22 decorations around one user-provided views and for responding to mouse
23 and scrollbar events.
24
25 A resulting tree might look something like this:
26
27 wxDynamicSashWindow
28 |
29 +- wxDynamicSashWindowImpl
30 |
31 +- wxDynamicSashWindowLeaf
32 | |
33 | +- user view window
34 |
35 +- wxDynamicSashWindowImpl
36 |
37 +- wxDynamicSashWindowLeaf
38 | |
39 | +- user view window
40 |
41 +- wxDynamicSashWindowLeaf
42 |
43 +- user view window
44
45 Each time a split occurs, one of the implementation objects removes its
46 leaf, generates two new implementation object children, each with a new
47 leaf, and reparents the user view which was connected to its old leaf
48 to be one of the new leaf's user view, and sends a Split event to the
49 user view in the hopes that it will generate a new user view for the
50 other new leaf.
51
52 When a unification ocurrs, an implementation object is replaced by one
53 of its children, and the tree of its other child is pruned.
54
55 One quirk is that the top-level implementation object (m_top) always
56 keeps a pointer to the implementation object where a new child is needed.
57 (m_add_child_target). This is so that when a new uesr view is added
58 to the hierarchy, AddChild() is able to reparent the new user view to
59 the correct implementation object's leaf.
60
61 */
62
63 #include <wx/dcmemory.h>
64 #include <wx/dcscreen.h>
65 #include <wx/layout.h>
66 #include <wx/scrolbar.h>
67 #include <wx/settings.h>
68
69
70 #define wxEVT_DYNAMIC_SASH_PRIVATE (wxEVT_DYNAMIC_SASH_BASE + 8)
71 #define wxEVT_DYNAMIC_SASH_REPARENT (wxEVT_DYNAMIC_SASH_PRIVATE + 1)
72
73
74 /*
75 wxDynamicSashReparentEvent is generated by the AddChild() method of
76 wxDynamicSashWindow when it wants a Leaf to reparent a user view window
77 to its viewport at some time in the future. We can't reparent the window
78 immediately, because switching parents in AddChild() confuses the wxWindow
79 class. Instead, we queue up this event, and the window is actually
80 reparented the next time we process events in the idle loop.
81 */
82 class wxDynamicSashReparentEvent : public wxEvent {
83 public:
84 wxDynamicSashReparentEvent();
85 wxDynamicSashReparentEvent(wxObject *object);
86
87 DECLARE_DYNAMIC_CLASS(wxDynamicSashReparentEvent);
88 };
89
90
91 enum DynamicSashRegion {
92 DSR_NONE,
93 DSR_VERTICAL_TAB,
94 DSR_HORIZONTAL_TAB,
95 DSR_CORNER,
96 DSR_LEFT_EDGE,
97 DSR_TOP_EDGE,
98 DSR_RIGHT_EDGE,
99 DSR_BOTTOM_EDGE
100 };
101
102
103 class wxDynamicSashWindowImpl : public wxEvtHandler {
104 public:
105 wxDynamicSashWindowImpl(wxDynamicSashWindow *window);
106 ~wxDynamicSashWindowImpl();
107
108 bool Create();
109 void AddChild(wxWindow *window);
110 void DrawSash(int x, int y) const;
111 void ConstrainChildren(int px, int py);
112 void Split(int x, int y);
113 void Unify(int panel);
114 void Resize(int x, int y);
115 wxDynamicSashWindowImpl *FindParent(DynamicSashRegion side) const;
116 wxDynamicSashWindowImpl *FindUpperParent(wxDynamicSashWindowImpl *sash_a,
117 wxDynamicSashWindowImpl *sash_b) const;
118 wxWindow *FindFrame() const;
119 wxScrollBar *FindScrollBar(const wxWindow *child, int vert) const;
120
121 void OnSize(wxSizeEvent &event);
122 void OnPaint(wxPaintEvent &event);
123 void OnMouseMove(wxMouseEvent &event);
124 void OnLeave(wxMouseEvent &event);
125 void OnPress(wxMouseEvent &event);
126 void OnRelease(wxMouseEvent &event);
127
128 wxDynamicSashWindow *m_window;
129 wxDynamicSashWindowImpl *m_add_child_target;
130
131 /* This is the window we are responsible for managing. Either of
132 leaf or our children are in this window. For the top level
133 implementation object, this is the same as m_window.
134 Otherwise it is a window we've created an will destroy when we
135 are deleted. */
136 wxWindow *m_container;
137
138 wxDynamicSashWindowImpl *m_parent;
139 wxDynamicSashWindowImpl *m_top;
140 wxDynamicSashWindowImpl *m_child[2];
141
142 class wxDynamicSashWindowLeaf *m_leaf;
143
144 /* If the implementation is split horizontally or vertically, m_split
145 is set to DSR_HORIZONTAL_TAB or DSR_VERTICAL_TAB, respectively.
146 Otherwise it is set to DSR_NONE. */
147 DynamicSashRegion m_split;
148
149 /* These are used to keep track of a sash as it is being dragged, for
150 drawing the user interface correctly. */
151 DynamicSashRegion m_dragging;
152 int m_drag_x, m_drag_y;
153 };
154
155 class wxDynamicSashWindowLeaf : public wxEvtHandler {
156 public:
157 wxDynamicSashWindowLeaf(wxDynamicSashWindowImpl *impl);
158 ~wxDynamicSashWindowLeaf();
159
160 bool Create();
161 void AddChild(wxWindow *window);
162 DynamicSashRegion GetRegion(int x, int y);
163 void ResizeChild(wxSize size);
164 wxScrollBar *FindScrollBar(const wxWindow *child, int vert) const;
165
166 void OnSize(wxSizeEvent &event);
167 void OnPaint(wxPaintEvent &event);
168 void OnScroll(wxScrollEvent &event);
169 void OnFocus(wxFocusEvent &event);
170 void OnMouseMove(wxMouseEvent &event);
171 void OnLeave(wxMouseEvent &event);
172 void OnPress(wxMouseEvent &event);
173 void OnRelease(wxMouseEvent &event);
174 void OnReparent(wxEvent &event);
175
176 wxDynamicSashWindowImpl *m_impl;
177
178 wxScrollBar *m_vscroll, *m_hscroll;
179
180 /* m_child is the window provided to us by the application developer.
181 m_viewport is a window we've created, and it is the immediately
182 parent of m_child. We scroll m_child by moving it around within
183 m_viewport. */
184 wxWindow *m_viewport, *m_child;
185 };
186
187 // wxDynamicSashWindow //////////////////////////////////////////////////////
188
189 wxDynamicSashWindow::wxDynamicSashWindow() {
190 m_impl = NULL;
191 }
192
193 wxDynamicSashWindow::wxDynamicSashWindow(wxWindow *parent, wxWindowID id,
194 const wxPoint& pos, const wxSize& size,
195 long style, const wxString& name) {
196 m_impl = NULL;
197 Create(parent, id, pos, size, style, name);
198 }
199
200 wxDynamicSashWindow::~wxDynamicSashWindow() {
201 SetEventHandler(this);
202 delete m_impl;
203 }
204
205 bool wxDynamicSashWindow::Create(wxWindow *parent, wxWindowID id,
206 const wxPoint& pos, const wxSize& size,
207 long style, const wxString& name) {
208 if (m_impl)
209 return FALSE;
210
211 if (!wxWindow::Create(parent, id, pos, size, style, name))
212 return FALSE;
213
214 m_impl = new wxDynamicSashWindowImpl(this);
215 if (!m_impl)
216 return FALSE;
217
218 if (!m_impl->Create()) {
219 delete m_impl;
220 m_impl = NULL;
221 return FALSE;
222 }
223
224 return TRUE;
225 }
226
227 void wxDynamicSashWindow::AddChild(wxWindowBase *child) {
228 wxWindow::AddChild(child);
229
230 m_impl->AddChild(wxDynamicCast(child, wxWindow));
231 }
232
233 wxScrollBar *wxDynamicSashWindow::GetHScrollBar(const wxWindow *child) const {
234 return m_impl->FindScrollBar(child, 0);
235 }
236
237 wxScrollBar *wxDynamicSashWindow::GetVScrollBar(const wxWindow *child) const {
238 return m_impl->FindScrollBar(child, 1);
239 }
240
241 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashWindow, wxWindow)
242
243 // wxDynamicSashWindowImpl //////////////////////////////////////////////////
244
245 wxDynamicSashWindowImpl::wxDynamicSashWindowImpl(wxDynamicSashWindow *window) {
246 m_window = window;
247 m_add_child_target = this;
248
249 m_container = NULL;
250 m_parent = NULL;
251 m_top = this;
252 m_child[0] = m_child[1] = NULL;
253 m_leaf = NULL;
254 m_dragging = DSR_NONE;
255 m_split = DSR_NONE;
256 }
257
258 wxDynamicSashWindowImpl::~wxDynamicSashWindowImpl() {
259 delete m_leaf;
260 delete m_child[0];
261 m_child[0] = NULL;
262 delete m_child[1];
263 m_child[1] = NULL;
264 m_leaf = NULL;
265
266 if (m_container != m_window && m_container) {
267 m_container->SetEventHandler(m_container);
268 m_container->Destroy();
269 }
270 }
271
272 bool wxDynamicSashWindowImpl::Create() {
273 if (!m_container) {
274 m_container = m_window;
275 }
276
277 wxCursor cursor(wxCURSOR_ARROW);
278 m_container->SetCursor(cursor);
279
280 m_leaf = new wxDynamicSashWindowLeaf(this);
281 if (!m_leaf)
282 return FALSE;
283
284 if (!m_leaf->Create()) {
285 delete m_leaf;
286 m_leaf = NULL;
287 return FALSE;
288 }
289
290 m_container->SetEventHandler(this);
291
292 Connect(-1, wxEVT_SIZE, (wxObjectEventFunction)&wxDynamicSashWindowImpl::OnSize);
293 Connect(-1, wxEVT_PAINT, (wxObjectEventFunction)&wxDynamicSashWindowImpl::OnPaint);
294 Connect(-1, wxEVT_MOTION, (wxObjectEventFunction)&wxDynamicSashWindowImpl::OnMouseMove);
295 Connect(-1, wxEVT_ENTER_WINDOW, (wxObjectEventFunction)&wxDynamicSashWindowImpl::OnMouseMove);
296 Connect(-1, wxEVT_LEAVE_WINDOW, (wxObjectEventFunction)&wxDynamicSashWindowImpl::OnLeave);
297 Connect(-1, wxEVT_LEFT_DOWN, (wxObjectEventFunction)&wxDynamicSashWindowImpl::OnPress);
298 Connect(-1, wxEVT_LEFT_UP, (wxObjectEventFunction)&wxDynamicSashWindowImpl::OnRelease);
299
300 return TRUE;
301 }
302
303 void wxDynamicSashWindowImpl::AddChild(wxWindow *window) {
304 if (m_add_child_target && m_add_child_target->m_leaf) {
305 m_add_child_target->m_leaf->AddChild(window);
306 }
307 }
308
309 void wxDynamicSashWindowImpl::DrawSash(int x, int y) const {
310 int i, j;
311
312 wxScreenDC dc;
313 dc.StartDrawingOnTop(m_container);
314
315 wxBitmap bmp(8, 8);
316 wxMemoryDC bdc;
317 bdc.SelectObject(bmp);
318 bdc.DrawRectangle(-1, -1, 10, 10);
319 for (i = 0; i < 8; i++) {
320 for (j = 0; j < 8; j++) {
321 if ((i + j) & 1) {
322 bdc.DrawPoint(i, j);
323 }
324 }
325 }
326
327 wxBrush brush(bmp);
328 dc.SetBrush(brush);
329 dc.SetLogicalFunction(wxXOR);
330
331 if (m_dragging == DSR_CORNER) {
332 int cx = 0;
333 int cy = 0;
334
335 m_container->ClientToScreen(&cx, &cy);
336 m_container->ClientToScreen(&x, &y);
337
338 if (cx < x && cy < y) {
339 dc.DrawRectangle(cx - 2, cy - 2, x - cx + 4, 4);
340 dc.DrawRectangle(x - 2, cy + 2, 4, y - cy);
341 dc.DrawRectangle(cx - 2, cy + 2, 4, y - cy);
342 dc.DrawRectangle(cx + 2, y - 2, x - cx - 4, 4);
343 }
344 } else {
345 int body_w, body_h;
346 m_container->GetClientSize(&body_w, &body_h);
347
348 if (y < 0)
349 y = 0;
350 if (y > body_h)
351 y = body_h;
352 if (x < 0)
353 x = 0;
354 if (x > body_w)
355 x = body_w;
356
357 if (m_dragging == DSR_HORIZONTAL_TAB)
358 x = 0;
359 else
360 y = 0;
361
362 m_container->ClientToScreen(&x, &y);
363
364 int w, h;
365 w = body_w; h = body_h;
366
367 if (m_dragging == DSR_HORIZONTAL_TAB)
368 dc.DrawRectangle(x, y - 2, w, 4);
369 else
370 dc.DrawRectangle(x - 2, y, 4, h);
371 }
372
373 dc.EndDrawingOnTop();
374 }
375
376 wxDynamicSashWindowImpl *wxDynamicSashWindowImpl::FindParent(DynamicSashRegion side) const {
377 if (m_parent == NULL) {
378 return NULL;
379 }
380
381 if (m_parent->m_split == DSR_HORIZONTAL_TAB) {
382 if (side == DSR_TOP_EDGE && m_parent->m_child[1] == this)
383 return m_parent;
384 if (side == DSR_BOTTOM_EDGE && m_parent->m_child[0] == this)
385 return m_parent;
386 } else if (m_parent->m_split == DSR_VERTICAL_TAB) {
387 if (side == DSR_LEFT_EDGE && m_parent->m_child[1] == this)
388 return m_parent;
389 if (side == DSR_RIGHT_EDGE && m_parent->m_child[0] == this)
390 return m_parent;
391 }
392
393 return m_parent->FindParent(side);
394 }
395
396 wxDynamicSashWindowImpl *wxDynamicSashWindowImpl::FindUpperParent(wxDynamicSashWindowImpl *sash_a,
397 wxDynamicSashWindowImpl *sash_b) const {
398 wxWindow *win;
399 win = sash_a->m_container->GetParent();
400 while (win && !win->IsTopLevel()) {
401 if (win == sash_b->m_container) {
402 return sash_b;
403 }
404
405 win = win->GetParent();
406 }
407
408 return sash_a;
409 }
410
411
412 wxWindow *wxDynamicSashWindowImpl::FindFrame() const {
413 wxWindow *win;
414
415 win = m_window->GetParent();
416 while (win && !win->IsTopLevel()) {
417 win = win->GetParent();
418 }
419
420 return win;
421 }
422
423 wxScrollBar *wxDynamicSashWindowImpl::FindScrollBar(const wxWindow *child, int vert) const {
424 if (m_child[0] == NULL && m_leaf == NULL) {
425 return NULL;
426 }
427
428 if (!m_child[0]) {
429 return m_leaf->FindScrollBar(child, vert);
430 } else {
431 wxScrollBar *ret = m_child[0]->FindScrollBar(child, vert);
432 if (!ret) {
433 ret = m_child[1]->FindScrollBar(child, vert);
434 }
435
436 return ret;
437 }
438 }
439
440 void wxDynamicSashWindowImpl::ConstrainChildren(int px, int py) {
441 wxLayoutConstraints *layout = new wxLayoutConstraints();
442 layout->left.SameAs(m_container, wxLeft);
443 layout->top.SameAs(m_container, wxTop);
444 if (m_split == DSR_HORIZONTAL_TAB) {
445 layout->right.SameAs(m_container, wxRight);
446 layout->height.PercentOf(m_container, wxHeight, py);
447 } else {
448 layout->bottom.SameAs(m_container, wxBottom);
449 layout->width.PercentOf(m_container, wxWidth, px);
450 }
451 m_child[0]->m_container->SetConstraints(layout);
452
453 layout = new wxLayoutConstraints();
454 layout->right.SameAs(m_container, wxRight);
455 layout->bottom.SameAs(m_container, wxBottom);
456 if (m_split == DSR_HORIZONTAL_TAB) {
457 layout->top.Below(m_child[0]->m_container, 1);
458 layout->left.SameAs(m_container, wxLeft);
459 } else {
460 layout->left.RightOf(m_child[0]->m_container, 1);
461 layout->top.SameAs(m_container, wxTop);
462 }
463 m_child[1]->m_container->SetConstraints(layout);
464 }
465
466 void wxDynamicSashWindowImpl::Unify(int panel) {
467 int other = 0;
468 if (panel == 0) {
469 other = 1;
470 }
471
472 if (m_child[panel]->m_leaf) {
473 wxDynamicSashWindowImpl *child[2];
474
475 child[0] = m_child[0];
476 child[1] = m_child[1];
477
478 m_child[0] = m_child[1] = NULL;
479
480 m_leaf = new wxDynamicSashWindowLeaf(this);
481 m_leaf->Create();
482 m_leaf->m_child = child[panel]->m_leaf->m_child;
483
484 m_leaf->m_vscroll->SetScrollbar(child[panel]->m_leaf->m_vscroll->GetThumbPosition(),
485 child[panel]->m_leaf->m_vscroll->GetThumbSize(),
486 child[panel]->m_leaf->m_vscroll->GetRange(),
487 child[panel]->m_leaf->m_vscroll->GetPageSize());
488 m_leaf->m_hscroll->SetScrollbar(child[panel]->m_leaf->m_hscroll->GetThumbPosition(),
489 child[panel]->m_leaf->m_hscroll->GetThumbSize(),
490 child[panel]->m_leaf->m_hscroll->GetRange(),
491 child[panel]->m_leaf->m_hscroll->GetPageSize());
492 m_add_child_target = NULL;
493 wxDynamicSashReparentEvent event(m_leaf);
494 m_leaf->ProcessEvent(event);
495
496 delete child[0];
497 delete child[1];
498
499 m_split = DSR_NONE;
500
501 wxDynamicSashUnifyEvent unify(m_leaf->m_child);
502 m_leaf->m_child->ProcessEvent(unify);
503 } else {
504 m_split = m_child[panel]->m_split;
505
506 delete m_child[other];
507
508 wxDynamicSashWindowImpl *child_panel = m_child[panel];
509 m_child[0] = child_panel->m_child[0];
510 m_child[1] = child_panel->m_child[1];
511
512 m_child[0]->m_parent = this;
513 m_child[1]->m_parent = this;
514
515 m_add_child_target = NULL;
516 m_child[0]->m_container->Reparent(m_container);
517 m_child[1]->m_container->Reparent(m_container);
518
519 child_panel->m_child[0] = child_panel->m_child[1] = NULL;
520 delete child_panel;
521
522 wxSize size = m_container->GetSize();
523 wxSize child_size = m_child[0]->m_container->GetSize();
524
525 ConstrainChildren(child_size.GetWidth() * 100 / size.GetWidth(),
526 child_size.GetHeight() * 100 / size.GetHeight());
527
528 m_container->Layout();
529 }
530 }
531
532 void wxDynamicSashWindowImpl::Split(int px, int py) {
533 m_window->Hide();
534
535 m_add_child_target = NULL;
536
537 m_child[0] = new wxDynamicSashWindowImpl(m_window);
538 m_child[0]->m_container = new wxWindow(m_container, -1);
539 m_child[0]->m_parent = this;
540 m_child[0]->m_top = m_top;
541 m_child[0]->Create();
542 if (m_leaf->m_child) {
543 m_leaf->m_child->Reparent(m_container);
544 m_child[0]->AddChild(m_leaf->m_child);
545 }
546
547 m_child[1] = new wxDynamicSashWindowImpl(m_window);
548 m_child[1]->m_container = new wxWindow(m_container, -1);
549 m_child[1]->m_parent = this;
550 m_child[1]->m_top = m_top;
551 m_child[1]->Create();
552
553 m_split = m_dragging;
554 ConstrainChildren(px, py);
555
556 m_top->m_add_child_target = m_child[1];
557 wxDynamicSashSplitEvent split(m_child[0]->m_leaf->m_child);
558 m_child[0]->m_leaf->m_child->ProcessEvent(split);
559
560 m_child[0]->m_leaf->m_vscroll->SetScrollbar(m_leaf->m_vscroll->GetThumbPosition(),
561 m_leaf->m_vscroll->GetThumbSize(),
562 m_leaf->m_vscroll->GetRange(),
563 m_leaf->m_vscroll->GetPageSize());
564 m_child[0]->m_leaf->m_hscroll->SetScrollbar(m_leaf->m_hscroll->GetThumbPosition(),
565 m_leaf->m_hscroll->GetThumbSize(),
566 m_leaf->m_hscroll->GetRange(),
567 m_leaf->m_hscroll->GetPageSize());
568 m_child[1]->m_leaf->m_vscroll->SetScrollbar(m_leaf->m_vscroll->GetThumbPosition(),
569 m_leaf->m_vscroll->GetThumbSize(),
570 m_leaf->m_vscroll->GetRange(),
571 m_leaf->m_vscroll->GetPageSize());
572 m_child[1]->m_leaf->m_hscroll->SetScrollbar(m_leaf->m_hscroll->GetThumbPosition(),
573 m_leaf->m_hscroll->GetThumbSize(),
574 m_leaf->m_hscroll->GetRange(),
575 m_leaf->m_hscroll->GetPageSize());
576 delete m_leaf;
577 m_leaf = NULL;
578
579 m_container->Layout();
580
581 m_window->Show();
582 }
583
584 /* This code is called when you finish resizing a view by dragging the
585 corner tab, but I think this implementation is lousy and will surprise
586 the user more often than it will do what they are trying to do. What
587 I really need to be doing here is do a rewrite such that *no* sashes
588 move except the ones immediately to the bottom and right of this window,
589 and handle the case where you resize a window larger than it's neighbors
590 by destroying the neighbors.
591
592 But this will do for now. */
593 void wxDynamicSashWindowImpl::Resize(int x, int y) {
594 wxDynamicSashWindowImpl *h_parent = FindParent(DSR_BOTTOM_EDGE);
595 wxDynamicSashWindowImpl *v_parent = FindParent(DSR_RIGHT_EDGE);
596 int h_unify = -1;
597 int v_unify = -1;
598 wxWindow *frame = FindFrame();
599
600 if (x < 0) {
601 x = 0;
602 }
603 if (y < 0) {
604 y = 0;
605 }
606
607 if (h_parent) {
608 m_container->ClientToScreen(NULL, &y);
609 h_parent->m_container->ScreenToClient(NULL, &y);
610
611 int py = (int)((y * 100) / h_parent->m_container->GetSize().GetHeight() + 0.5);
612
613 if (py < 10) {
614 wxDynamicSashWindowImpl *ho_parent = FindParent(DSR_TOP_EDGE);
615
616 if (ho_parent) {
617 if (FindUpperParent(h_parent, ho_parent) == ho_parent) {
618 h_unify = 1;
619 } else {
620 py = (int)((ho_parent->m_child[0]->m_container->GetSize().GetHeight() * 100)
621 / h_parent->m_container->GetSize().GetHeight() + 0.5);
622 h_parent->m_child[0]->m_container->GetConstraints()->height.PercentOf(
623 h_parent->m_container, wxHeight, py);
624
625 h_parent = ho_parent;
626 h_unify = 0;
627 }
628 } else {
629 h_unify = 1;
630 }
631 } else if (py > 90) {
632 h_unify = 0;
633 } else {
634 h_parent->m_child[0]->m_container->GetConstraints()->height.PercentOf(
635 h_parent->m_container, wxHeight, py);
636 h_parent->m_container->Layout();
637 }
638 } else {
639 int do_resize = 1;
640 h_parent = FindParent(DSR_TOP_EDGE);
641
642 if (h_parent) {
643 int py = (int)((y * 100) /
644 (h_parent->m_container->GetSize().GetHeight() +
645 y - m_container->GetSize().GetHeight()) + 0.5);
646
647 if (py < 10) {
648 h_unify = 0;
649 }
650 } else if (y < 64) {
651 do_resize = 0;
652 }
653
654 if (do_resize) {
655 wxSize size = frame->GetSize();
656 frame->SetSize(size.GetWidth(), size.GetHeight() + y - m_container->GetSize().GetHeight());
657 }
658 }
659
660 if (v_parent) {
661 m_container->ClientToScreen(&x, NULL);
662 v_parent->m_container->ScreenToClient(&x, NULL);
663
664 int px = (int)((x * 100) / v_parent->m_container->GetSize().GetWidth() + 0.5);
665
666 if (px < 10) {
667 wxDynamicSashWindowImpl *vo_parent = FindParent(DSR_LEFT_EDGE);
668
669 if (vo_parent) {
670 if (FindUpperParent(v_parent, vo_parent) == vo_parent) {
671 v_unify = 1;
672 } else {
673 px = (int)((vo_parent->m_child[0]->m_container->GetSize().GetWidth() * 100)
674 / v_parent->m_container->GetSize().GetWidth() + 0.5);
675 v_parent->m_child[0]->m_container->GetConstraints()->width.PercentOf(
676 v_parent->m_container, wxWidth, px);
677
678 v_parent = vo_parent;
679 v_unify = 0;
680 }
681 } else {
682 v_unify = 1;
683 }
684 } else if (px > 90) {
685 v_unify = 0;
686 } else {
687 v_parent->m_child[0]->m_container->GetConstraints()->width.PercentOf(
688 v_parent->m_container, wxWidth, px);
689 v_parent->m_container->Layout();
690 }
691 } else {
692 int do_resize = 1;
693 v_parent = FindParent(DSR_LEFT_EDGE);
694
695 if (v_parent) {
696 int px = (int)((x * 100) /
697 (v_parent->m_container->GetSize().GetWidth() +
698 x - m_container->GetSize().GetWidth()) + 0.5);
699
700 if (px < 10) {
701 v_unify = 0;
702 }
703 } else if (x < 64) {
704 do_resize = 0;
705 }
706
707 if (do_resize) {
708 wxSize size = frame->GetSize();
709 frame->SetSize(size.GetWidth() + x - m_container->GetSize().GetWidth(), size.GetHeight());
710 }
711 }
712
713 if (h_unify != -1 && v_unify != -1) {
714 wxDynamicSashWindowImpl *parent = FindUpperParent(h_parent, v_parent);
715
716 if (parent == h_parent) {
717 h_parent->Unify(h_unify);
718 } else {
719 v_parent->Unify(v_unify);
720 }
721 } else if (h_unify != -1) {
722 h_parent->Unify(h_unify);
723 } else if (v_unify != -1) {
724 v_parent->Unify(v_unify);
725 }
726 }
727
728
729 void wxDynamicSashWindowImpl::OnSize(wxSizeEvent &event) {
730 m_container->Layout();
731
732 if (m_leaf)
733 m_leaf->OnSize(event);
734 }
735
736 void wxDynamicSashWindowImpl::OnPaint(wxPaintEvent &event) {
737 if (m_leaf)
738 m_leaf->OnPaint(event);
739 else {
740 wxPaintDC dc(m_container);
741 dc.SetBackground(wxBrush(m_container->GetBackgroundColour(), wxSOLID));
742 dc.Clear();
743 }
744 }
745
746 void wxDynamicSashWindowImpl::OnMouseMove(wxMouseEvent &event) {
747 if (m_dragging) {
748 DrawSash(m_drag_x, m_drag_y);
749 m_drag_x = event.m_x; m_drag_y = event.m_y;
750 DrawSash(m_drag_x, m_drag_y);
751 } else if (m_leaf) {
752 m_leaf->OnMouseMove(event);
753 }
754 }
755
756 void wxDynamicSashWindowImpl::OnLeave(wxMouseEvent &event) {
757 if (m_leaf) {
758 m_leaf->OnLeave(event);
759 }
760 }
761
762 void wxDynamicSashWindowImpl::OnPress(wxMouseEvent &event) {
763 if (m_leaf) {
764 m_leaf->OnPress(event);
765 } else {
766 m_dragging = m_split;
767 m_drag_x = event.m_x;
768 m_drag_y = event.m_y;
769 DrawSash(m_drag_x, m_drag_y);
770 m_container->CaptureMouse();
771 }
772 }
773
774 void wxDynamicSashWindowImpl::OnRelease(wxMouseEvent &event) {
775 if (m_dragging == DSR_CORNER) {
776 DrawSash(m_drag_x, m_drag_y);
777 m_container->ReleaseMouse();
778
779 Resize(event.m_x, event.m_y);
780
781 m_dragging = DSR_NONE;
782 } else if (m_dragging) {
783 DrawSash(m_drag_x, m_drag_y);
784 m_container->ReleaseMouse();
785
786 wxSize size = m_container->GetSize();
787 int px = (int)((event.m_x * 100) / size.GetWidth() + 0.5);
788 int py = (int)((event.m_y * 100) / size.GetHeight() + 0.5);
789
790 if ((m_dragging == DSR_HORIZONTAL_TAB && py >= 10 && py <= 90)
791 || (m_dragging == DSR_VERTICAL_TAB && px >= 10 && px <= 90)) {
792 if (m_child[0] == NULL) {
793 Split(px, py);
794 } else {
795 /* It would be nice if moving *this* sash didn't implicitly move
796 the sashes of our children (if any). But this will do. */
797 wxLayoutConstraints *layout = m_child[0]->m_container->GetConstraints();
798 if (m_split == DSR_HORIZONTAL_TAB) {
799 layout->height.PercentOf(m_container, wxHeight, py);
800 } else {
801 layout->width.PercentOf(m_container, wxWidth, px);
802 }
803 m_container->Layout();
804 }
805 } else {
806 if (m_child[0] != NULL) {
807 if ((m_dragging == DSR_HORIZONTAL_TAB && py <= 10)
808 || (m_dragging == DSR_VERTICAL_TAB && px <= 10)) {
809 Unify(1);
810 } else {
811 Unify(0);
812 }
813 }
814 }
815
816 wxCursor cursor(wxCURSOR_ARROW);
817 if (m_split == DSR_HORIZONTAL_TAB) {
818 cursor = wxCursor(wxCURSOR_SIZENS);
819 } else if (m_split == DSR_VERTICAL_TAB) {
820 cursor = wxCursor(wxCURSOR_SIZEWE);
821 }
822 m_container->SetCursor(cursor);
823
824 m_dragging = DSR_NONE;
825 } else if (m_leaf) {
826 m_leaf->OnRelease(event);
827 }
828 }
829
830 // wxDynamicSashWindowLeaf //////////////////////////////////////////////////
831
832 wxDynamicSashWindowLeaf::wxDynamicSashWindowLeaf(wxDynamicSashWindowImpl *impl) {
833 m_impl = impl;
834
835 m_hscroll = m_vscroll = NULL;
836 m_child = NULL;
837 }
838
839 wxDynamicSashWindowLeaf::~wxDynamicSashWindowLeaf() {
840 m_hscroll->SetEventHandler(m_hscroll);
841 m_vscroll->SetEventHandler(m_vscroll);
842 m_viewport->SetEventHandler(m_viewport);
843
844 m_hscroll->Destroy();
845 m_vscroll->Destroy();
846 m_viewport->Destroy();
847 }
848
849 bool wxDynamicSashWindowLeaf::Create() {
850 bool success;
851
852 m_hscroll = new wxScrollBar();
853 m_vscroll = new wxScrollBar();
854 m_viewport = new wxWindow();
855
856 if (!m_hscroll || !m_vscroll || !m_viewport) {
857 return FALSE;
858 }
859
860 wxDynamicSashWindowImpl *add_child_target = m_impl->m_add_child_target;
861 m_impl->m_add_child_target = NULL;
862 success = m_hscroll->Create(m_impl->m_container, -1, wxDefaultPosition, wxDefaultSize,
863 wxSB_HORIZONTAL);
864 success = success && m_vscroll->Create(m_impl->m_container, -1, wxDefaultPosition, wxDefaultSize,
865 wxSB_VERTICAL);
866 success = success && m_viewport->Create(m_impl->m_container, -1);
867 m_impl->m_add_child_target = add_child_target;
868
869 wxCursor cursor(wxCURSOR_ARROW);
870 m_hscroll->SetCursor(cursor);
871 m_vscroll->SetCursor(cursor);
872 m_viewport->SetCursor(cursor);
873
874 m_viewport->SetEventHandler(this);
875 Connect(-1, wxEVT_DYNAMIC_SASH_REPARENT, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnReparent);
876
877 if (m_impl->m_window->GetWindowStyle() & wxMANAGE_SCROLLBARS) {
878 m_hscroll->SetEventHandler(this);
879 m_vscroll->SetEventHandler(this);
880
881 Connect(-1, wxEVT_SET_FOCUS, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnFocus);
882 Connect(-1, wxEVT_SCROLL_TOP, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
883 Connect(-1, wxEVT_SCROLL_BOTTOM, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
884 Connect(-1, wxEVT_SCROLL_LINEUP, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
885 Connect(-1, wxEVT_SCROLL_LINEDOWN, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
886 Connect(-1, wxEVT_SCROLL_PAGEUP, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
887 Connect(-1, wxEVT_SCROLL_PAGEDOWN, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
888 Connect(-1, wxEVT_SCROLL_THUMBTRACK, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
889 Connect(-1, wxEVT_SCROLL_THUMBRELEASE, (wxObjectEventFunction)&wxDynamicSashWindowLeaf::OnScroll);
890 }
891
892 wxLayoutConstraints *layout = new wxLayoutConstraints();
893 if (!layout)
894 return FALSE;
895 wxSize size = m_hscroll->GetBestSize();
896 #ifdef __WXMSW__
897 size = m_hscroll->GetSize();
898 #endif
899
900 layout->left.SameAs(m_impl->m_container, wxLeft, 10);
901 layout->right.LeftOf(m_vscroll);
902 layout->bottom.SameAs(m_impl->m_container, wxBottom, 3);
903 layout->height.Absolute(size.GetHeight());
904 m_hscroll->SetConstraints(layout);
905
906 layout = new wxLayoutConstraints();
907 if (!layout)
908 return FALSE;
909 size = size = m_vscroll->GetBestSize();
910 #ifdef __WXMSW__
911 size = m_vscroll->GetSize();
912 #endif
913
914 layout->top.SameAs(m_impl->m_container, wxTop, 10);
915 layout->bottom.Above(m_hscroll);
916 layout->right.SameAs(m_impl->m_container, wxRight, 3);
917 layout->width.Absolute(size.GetWidth());
918 m_vscroll->SetConstraints(layout);
919
920 layout = new wxLayoutConstraints();
921 if (!layout)
922 return FALSE;
923 layout->left.SameAs(m_impl->m_container, wxLeft, 3);
924 layout->right.LeftOf(m_vscroll);
925 layout->top.SameAs(m_impl->m_container, wxTop, 3);
926 layout->bottom.Above(m_hscroll);
927 m_viewport->SetConstraints(layout);
928
929 m_impl->m_container->Layout();
930
931 return success;
932 }
933
934 void wxDynamicSashWindowLeaf::AddChild(wxWindow *window) {
935 if (m_child) {
936 m_child->Destroy();
937 }
938
939 m_child = window;
940
941 wxDynamicSashReparentEvent event(this);
942 AddPendingEvent(event);
943 }
944
945 DynamicSashRegion wxDynamicSashWindowLeaf::GetRegion(int x, int y) {
946 wxSize size = m_impl->m_container->GetSize();
947 int w = size.GetWidth();
948 int h = size.GetHeight();
949 size = m_hscroll->GetSize();
950 int sh = size.GetHeight();
951 size = m_vscroll->GetSize();
952 int sw = size.GetWidth();
953
954 if (x >= w - sw - 3 && x < w && y >= h - sh - 3 && y < h)
955 return DSR_CORNER;
956 if (x >= 3 && x < 10 && y >= h - sh - 3 && y < h - 2)
957 return DSR_VERTICAL_TAB;
958 if (x >= w - sw - 3 && x < w - 2 && y >= 3 && y < 10)
959 return DSR_HORIZONTAL_TAB;
960 if (x < 3)
961 return DSR_LEFT_EDGE;
962 if (y < 3)
963 return DSR_TOP_EDGE;
964 if (x >= w - 2)
965 return DSR_RIGHT_EDGE;
966 if (y >= h - 2)
967 return DSR_BOTTOM_EDGE;
968
969 return DSR_NONE;
970 }
971
972 void wxDynamicSashWindowLeaf::ResizeChild(wxSize size) {
973 if (m_child) {
974 if (m_impl->m_window->GetWindowStyle() & wxMANAGE_SCROLLBARS) {
975 m_child->SetSize(size);
976 wxSize best_size = m_child->GetBestSize();
977 if (best_size.GetWidth() < size.GetWidth()) {
978 best_size.SetWidth(size.GetWidth());
979 }
980 if (best_size.GetHeight() < size.GetHeight()) {
981 best_size.SetHeight(size.GetHeight());
982 }
983 m_child->SetSize(best_size);
984
985 int hpos = m_hscroll->GetThumbPosition();
986 int vpos = m_vscroll->GetThumbPosition();
987
988 if (hpos < 0) {
989 hpos = 0;
990 }
991 if (vpos < 0) {
992 vpos = 0;
993 }
994 if (hpos > best_size.GetWidth() - size.GetWidth()) {
995 hpos = best_size.GetWidth() - size.GetWidth();
996 }
997 if (vpos > best_size.GetHeight() - size.GetHeight()) {
998 vpos = best_size.GetHeight() - size.GetHeight();
999 }
1000
1001 m_hscroll->SetScrollbar(hpos, size.GetWidth(),
1002 best_size.GetWidth(), size.GetWidth());
1003 m_vscroll->SetScrollbar(vpos, size.GetHeight(),
1004 best_size.GetHeight(), size.GetHeight());
1005
1006 // Umm, the scrollbars are doing something insane under GTK+ and subtracting
1007 // one from the position I pass in. This works around that.
1008 m_hscroll->SetThumbPosition(hpos + hpos - m_hscroll->GetThumbPosition());
1009 m_vscroll->SetThumbPosition(vpos + vpos - m_vscroll->GetThumbPosition());
1010
1011 wxPoint pos = m_child->GetPosition();
1012 m_viewport->ScrollWindow(-hpos - pos.x, -vpos - pos.y);
1013 } else {
1014 m_child->SetSize(size);
1015 }
1016 }
1017 }
1018
1019 wxScrollBar *wxDynamicSashWindowLeaf::FindScrollBar(const wxWindow *child, int vert) const {
1020 if (m_child == child) {
1021 if (vert) {
1022 return m_vscroll;
1023 } else {
1024 return m_hscroll;
1025 }
1026 }
1027
1028 return NULL;
1029 }
1030
1031 void wxDynamicSashWindowLeaf::OnSize(wxSizeEvent &event) {
1032 m_impl->m_container->Refresh();
1033 ResizeChild(m_viewport->GetSize());
1034 }
1035
1036 void wxDynamicSashWindowLeaf::OnPaint(wxPaintEvent &event) {
1037 wxPaintDC dc(m_impl->m_container);
1038 dc.SetBackground(wxBrush(m_impl->m_container->GetBackgroundColour(), wxSOLID));
1039 dc.Clear();
1040
1041 wxPen highlight(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNHIGHLIGHT), 1, wxSOLID);
1042 wxPen shadow(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNSHADOW), 1, wxSOLID);
1043 wxPen black(*wxBLACK, 1, wxSOLID);
1044
1045 wxSize size = m_impl->m_container->GetSize();
1046 int w = size.GetWidth();
1047 int h = size.GetHeight();
1048 size = m_hscroll->GetSize();
1049 int sh = size.GetHeight();
1050 size = m_vscroll->GetSize();
1051 int sw = size.GetWidth();
1052
1053 dc.SetPen(shadow);
1054 dc.DrawLine(1, 1, 1, h - 2);
1055 dc.DrawLine(1, 1, w - 2, 1);
1056 dc.SetPen(black);
1057 dc.DrawLine(2, 2, 2, h - 3);
1058 dc.DrawLine(2, 2, w - 3, 2);
1059 dc.SetPen(highlight);
1060 dc.DrawLine(w - 2, 2, w - 2, h - sh - 2);
1061 dc.DrawLine(w - 2, h - sh - 2, w - sw - 2, h - sh - 2);
1062 dc.DrawLine(w - sw - 2, h - sh - 2, w - sw - 2, h - 2);
1063 dc.DrawLine(w - sw - 2, h - 2, 2, h - 2);
1064
1065 dc.SetPen(highlight);
1066 dc.DrawLine(w - sw - 2, 8, w - sw - 2, 4);
1067 dc.DrawLine(w - sw - 2, 4, w - 5, 4);
1068 dc.SetPen(shadow);
1069 dc.DrawLine(w - 5, 4, w - 5, 8);
1070 dc.DrawLine(w - 5, 8, w - sw - 2, 8);
1071 dc.SetPen(black);
1072 dc.DrawLine(w - 4, 3, w - 4, 9);
1073 dc.DrawLine(w - 4, 9, w - sw - 3, 9);
1074
1075 dc.SetPen(highlight);
1076 dc.DrawLine(4, h - 5, 4, h - sh - 2);
1077 dc.DrawLine(4, h - sh - 2, 8, h - sh - 2);
1078 dc.SetPen(shadow);
1079 dc.DrawLine(8, h - sh - 2, 8, h - 5);
1080 dc.DrawLine(8, h - 5, 4, h - 5);
1081 dc.SetPen(black);
1082 dc.DrawLine(9, h - sh - 3, 9, h - 4);
1083 dc.DrawLine(9, h - 4, 3, h - 4);
1084
1085
1086 int cy = (h - sh + h - 6) / 2 + 1;
1087 int cx = (w - sw + w - 6) / 2 + 1;
1088 int sy = cy;
1089 while (sy > h - sh)
1090 sy -= 4;
1091 int sx = cx;
1092 while (sx > w - sw)
1093 sx -= 4;
1094
1095 int x, y;
1096 for (y = sy; y < h - 2; y += 4) {
1097 for (x = sx; x < w - 2; x += 4) {
1098 if (x - cx >= -(y - cy)) {
1099 dc.SetPen(highlight);
1100 dc.DrawPoint(x, y);
1101 dc.SetPen(shadow);
1102 dc.DrawPoint(x + 1, y + 1);
1103 }
1104 }
1105 }
1106 }
1107
1108 void wxDynamicSashWindowLeaf::OnScroll(wxScrollEvent &event) {
1109 int nx = -m_hscroll->GetThumbPosition();
1110 int ny = -m_vscroll->GetThumbPosition();
1111
1112 if (m_child) {
1113 wxPoint pos = m_child->GetPosition();
1114
1115 m_viewport->ScrollWindow(nx - pos.x, ny - pos.y);
1116 }
1117 }
1118
1119 void wxDynamicSashWindowLeaf::OnFocus(wxFocusEvent &event) {
1120 if (event.m_eventObject == m_hscroll || event.m_eventObject == m_vscroll) {
1121 m_child->SetFocus();
1122 }
1123 }
1124
1125
1126 void wxDynamicSashWindowLeaf::OnMouseMove(wxMouseEvent &event) {
1127 if (m_impl->m_dragging) {
1128 return;
1129 }
1130
1131 DynamicSashRegion region = GetRegion(event.m_x, event.m_y);
1132
1133 wxCursor cursor(wxCURSOR_ARROW);
1134 if (region == DSR_HORIZONTAL_TAB) {
1135 cursor = wxCursor(wxCURSOR_SIZENS);
1136 } else if (region == DSR_VERTICAL_TAB) {
1137 cursor = wxCursor(wxCURSOR_SIZEWE);
1138 } else if (region == DSR_CORNER) {
1139 cursor = wxCursor(wxCURSOR_SIZENWSE);
1140 } else if (region == DSR_LEFT_EDGE || region == DSR_TOP_EDGE
1141 || region == DSR_RIGHT_EDGE || region == DSR_BOTTOM_EDGE) {
1142 if (m_impl->FindParent(region)) {
1143 if (region == DSR_LEFT_EDGE || region == DSR_RIGHT_EDGE) {
1144 cursor = wxCursor(wxCURSOR_SIZEWE);
1145 } else {
1146 cursor = wxCursor(wxCURSOR_SIZENS);
1147 }
1148 }
1149 }
1150
1151 m_impl->m_container->SetCursor(cursor);
1152 }
1153
1154 void wxDynamicSashWindowLeaf::OnLeave(wxMouseEvent &event) {
1155 wxCursor cursor(wxCURSOR_ARROW);
1156 m_impl->m_container->SetCursor(cursor);
1157 }
1158
1159
1160 void wxDynamicSashWindowLeaf::OnPress(wxMouseEvent &event) {
1161 DynamicSashRegion region = GetRegion(event.m_x, event.m_y);
1162
1163 if (region == DSR_HORIZONTAL_TAB || region == DSR_VERTICAL_TAB || region == DSR_CORNER) {
1164 m_impl->m_dragging = region;
1165 m_impl->m_drag_x = event.m_x;
1166 m_impl->m_drag_y = event.m_y;
1167 m_impl->DrawSash(event.m_x, event.m_y);
1168 m_impl->m_container->CaptureMouse();
1169 } else if (region == DSR_LEFT_EDGE || region == DSR_TOP_EDGE
1170 || region == DSR_RIGHT_EDGE || region == DSR_BOTTOM_EDGE) {
1171 wxDynamicSashWindowImpl *parent = m_impl->FindParent(region);
1172
1173 if (parent) {
1174 int x = event.m_x;
1175 int y = event.m_y;
1176
1177 m_impl->m_container->ClientToScreen(&x, &y);
1178 parent->m_container->ScreenToClient(&x, &y);
1179
1180 parent->m_dragging = parent->m_split;
1181 parent->m_drag_x = x;
1182 parent->m_drag_y = y;
1183 parent->DrawSash(x, y);
1184 parent->m_container->CaptureMouse();
1185 }
1186 }
1187 }
1188
1189 void wxDynamicSashWindowLeaf::OnRelease(wxMouseEvent &event) {
1190 }
1191
1192 void wxDynamicSashWindowLeaf::OnReparent(wxEvent &event) {
1193 if (m_child) {
1194 m_child->Reparent(m_viewport);
1195 }
1196
1197 ResizeChild(m_viewport->GetSize());
1198 }
1199
1200 // wxDynamicSashSplitEvent //////////////////////////////////////////////////
1201
1202 wxDynamicSashSplitEvent::wxDynamicSashSplitEvent() {
1203 m_eventObject = NULL;
1204 m_eventType = wxEVT_DYNAMIC_SASH_SPLIT;
1205 }
1206
1207 wxDynamicSashSplitEvent::wxDynamicSashSplitEvent(wxObject *object) {
1208 m_eventObject = object;
1209 m_eventType = wxEVT_DYNAMIC_SASH_SPLIT;
1210 }
1211
1212 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashSplitEvent, wxCommandEvent)
1213
1214 // wxDynamicSashUnifyEvent //////////////////////////////////////////////////
1215
1216 wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent() {
1217 m_eventObject = NULL;
1218 m_eventType = wxEVT_DYNAMIC_SASH_UNIFY;
1219 }
1220
1221 wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent(wxObject *object) {
1222 m_eventObject = object;
1223 m_eventType = wxEVT_DYNAMIC_SASH_UNIFY;
1224 }
1225
1226 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashUnifyEvent, wxCommandEvent)
1227
1228 // wxDynamicSsahReparentEvent ///////////////////////////////////////////////
1229
1230 wxDynamicSashReparentEvent::wxDynamicSashReparentEvent() {
1231 m_eventObject = NULL;
1232 m_eventType = wxEVT_DYNAMIC_SASH_REPARENT;
1233 }
1234
1235 wxDynamicSashReparentEvent::wxDynamicSashReparentEvent(wxObject *object) {
1236 m_eventObject = object;
1237 m_eventType = wxEVT_DYNAMIC_SASH_REPARENT;
1238 }
1239
1240 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashReparentEvent, wxEvent)
1241
1242 /////////////////////////////////////////////////////////////////////////////