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