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 
   9 // Copyright:   (c) 2001 Matt Kimball 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 #include "wx/gizmos/dynamicsash.h" 
  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 
  25     A resulting tree might look something like this: 
  29      +- wxDynamicSashWindowImpl 
  31          +- wxDynamicSashWindowLeaf 
  35          +- wxDynamicSashWindowImpl 
  37              +- wxDynamicSashWindowLeaf 
  41              +- wxDynamicSashWindowLeaf 
  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 
  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. 
  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. 
  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> 
  70 #define wxEVT_DYNAMIC_SASH_PRIVATE          (wxEVT_DYNAMIC_SASH_BASE + 8) 
  71 #define wxEVT_DYNAMIC_SASH_REPARENT         (wxEVT_DYNAMIC_SASH_PRIVATE + 1) 
  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. 
  82 class wxDynamicSashReparentEvent 
: public wxEvent 
{ 
  84     wxDynamicSashReparentEvent(); 
  85     wxDynamicSashReparentEvent(wxObject 
*object
); 
  86     wxDynamicSashReparentEvent(const wxDynamicSashReparentEvent
& evt
); 
  88     virtual wxEvent
* Clone() const { return new wxDynamicSashReparentEvent(*this); } 
  90     DECLARE_DYNAMIC_CLASS(wxDynamicSashReparentEvent
); 
  94 enum DynamicSashRegion 
{ 
 106 class wxDynamicSashWindowImpl 
: public wxEvtHandler 
{ 
 108     wxDynamicSashWindowImpl(wxDynamicSashWindow 
*window
); 
 109     ~wxDynamicSashWindowImpl(); 
 112     void AddChild(wxWindow 
*window
); 
 113     void DrawSash(int x
, int y
) const; 
 114     void ConstrainChildren(int px
, int py
); 
 115     void Split(int x
, int y
); 
 116     void Unify(int panel
); 
 117     void Resize(int x
, int y
); 
 118     wxDynamicSashWindowImpl 
*FindParent(DynamicSashRegion side
) const; 
 119     wxDynamicSashWindowImpl 
*FindUpperParent(wxDynamicSashWindowImpl 
*sash_a
, 
 120                                              wxDynamicSashWindowImpl 
*sash_b
) const; 
 121     wxWindow 
*FindFrame() const; 
 122     wxScrollBar 
*FindScrollBar(const wxWindow 
*child
, int vert
) const; 
 124     void OnSize(wxSizeEvent 
&event
); 
 125     void OnPaint(wxPaintEvent 
&event
); 
 126     void OnMouseMove(wxMouseEvent 
&event
); 
 127     void OnLeave(wxMouseEvent 
&event
); 
 128     void OnPress(wxMouseEvent 
&event
); 
 129     void OnRelease(wxMouseEvent 
&event
); 
 131     wxDynamicSashWindow 
*m_window
; 
 132     wxDynamicSashWindowImpl 
*m_add_child_target
; 
 134     /*  This is the window we are responsible for managing.  Either of 
 135         leaf or our children are in this window.  For the top level 
 136         implementation object, this is the same as m_window. 
 137         Otherwise it is a window we've created an will destroy when we 
 139     wxWindow 
*m_container
; 
 141     wxDynamicSashWindowImpl 
*m_parent
; 
 142     wxDynamicSashWindowImpl 
*m_top
; 
 143     wxDynamicSashWindowImpl 
*m_child
[2]; 
 145     class wxDynamicSashWindowLeaf 
*m_leaf
; 
 147     /*  If the implementation is split horizontally or vertically, m_split 
 148         is set to DSR_HORIZONTAL_TAB or DSR_VERTICAL_TAB, respectively. 
 149         Otherwise it is set to DSR_NONE.  */ 
 150     DynamicSashRegion m_split
; 
 152     /*  These are used to keep track of a sash as it is being dragged, for 
 153         drawing the user interface correctly.  */ 
 154     DynamicSashRegion m_dragging
; 
 155     int m_drag_x
, m_drag_y
; 
 158 class wxDynamicSashWindowLeaf 
: public wxEvtHandler 
{ 
 160     wxDynamicSashWindowLeaf(wxDynamicSashWindowImpl 
*impl
); 
 161     ~wxDynamicSashWindowLeaf(); 
 164     void AddChild(wxWindow 
*window
); 
 165     DynamicSashRegion 
GetRegion(int x
, int y
); 
 166     void ResizeChild(wxSize size
); 
 167     wxScrollBar 
*FindScrollBar(const wxWindow 
*child
, int vert
) const; 
 169     void OnSize(wxSizeEvent 
&event
); 
 170     void OnPaint(wxPaintEvent 
&event
); 
 171     void OnScroll(wxScrollEvent 
&event
); 
 172     void OnFocus(wxFocusEvent 
&event
); 
 173     void OnMouseMove(wxMouseEvent 
&event
); 
 174     void OnLeave(wxMouseEvent 
&event
); 
 175     void OnPress(wxMouseEvent 
&event
); 
 176     void OnRelease(wxMouseEvent 
&event
); 
 177     void OnReparent(wxEvent 
&event
); 
 179     wxDynamicSashWindowImpl 
*m_impl
; 
 181     wxScrollBar 
*m_vscroll
, *m_hscroll
; 
 183     /*  m_child is the window provided to us by the application developer. 
 184         m_viewport is a window we've created, and it is the immediately 
 185         parent of m_child.  We scroll m_child by moving it around within 
 187     wxWindow 
*m_viewport
, *m_child
; 
 190 // wxDynamicSashWindow ////////////////////////////////////////////////////// 
 192 wxDynamicSashWindow::wxDynamicSashWindow() { 
 196 wxDynamicSashWindow::wxDynamicSashWindow(wxWindow 
*parent
, wxWindowID id
, 
 197                                          const wxPoint
& pos
, const wxSize
& size
, 
 198                                          long style
, const wxString
& name
) { 
 200     Create(parent
, id
, pos
, size
, style
, name
); 
 203 wxDynamicSashWindow::~wxDynamicSashWindow() { 
 204     SetEventHandler(this); 
 208 bool wxDynamicSashWindow::Create(wxWindow 
*parent
, wxWindowID id
, 
 209                                  const wxPoint
& pos
, const wxSize
& size
, 
 210                                  long style
, const wxString
& name
) { 
 214     if (!wxWindow::Create(parent
, id
, pos
, size
, style
, name
)) 
 217     m_impl 
= new wxDynamicSashWindowImpl(this); 
 221     if (!m_impl
->Create()) { 
 230 void wxDynamicSashWindow::AddChild(wxWindowBase 
*child
) { 
 231     wxWindow::AddChild(child
); 
 233     m_impl
->AddChild(wxDynamicCast(child
, wxWindow
)); 
 236 wxScrollBar 
*wxDynamicSashWindow::GetHScrollBar(const wxWindow 
*child
) const { 
 237     return m_impl
->FindScrollBar(child
, 0); 
 240 wxScrollBar 
*wxDynamicSashWindow::GetVScrollBar(const wxWindow 
*child
) const { 
 241     return m_impl
->FindScrollBar(child
, 1); 
 244 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashWindow
, wxWindow
) 
 246 // wxDynamicSashWindowImpl ////////////////////////////////////////////////// 
 248 wxDynamicSashWindowImpl::wxDynamicSashWindowImpl(wxDynamicSashWindow 
*window
) { 
 250     m_add_child_target 
= this; 
 255     m_child
[0] = m_child
[1] = NULL
; 
 257     m_dragging 
= DSR_NONE
; 
 261 wxDynamicSashWindowImpl::~wxDynamicSashWindowImpl() { 
 269     if (m_container 
!= m_window 
&& m_container
) { 
 270         m_container
->SetEventHandler(m_container
); 
 271         m_container
->Destroy(); 
 275 bool wxDynamicSashWindowImpl::Create() { 
 277         m_container 
= m_window
; 
 280     wxCursor 
cursor(wxCURSOR_ARROW
); 
 281     m_container
->SetCursor(cursor
); 
 283     m_leaf 
= new wxDynamicSashWindowLeaf(this); 
 287     if (!m_leaf
->Create()) { 
 293     m_container
->SetEventHandler(this); 
 295     Connect(-1, wxEVT_SIZE
, (wxObjectEventFunction
)&wxDynamicSashWindowImpl::OnSize
); 
 296     Connect(-1, wxEVT_PAINT
, (wxObjectEventFunction
)&wxDynamicSashWindowImpl::OnPaint
); 
 297     Connect(-1, wxEVT_MOTION
, (wxObjectEventFunction
)&wxDynamicSashWindowImpl::OnMouseMove
); 
 298     Connect(-1, wxEVT_ENTER_WINDOW
, (wxObjectEventFunction
)&wxDynamicSashWindowImpl::OnMouseMove
); 
 299     Connect(-1, wxEVT_LEAVE_WINDOW
, (wxObjectEventFunction
)&wxDynamicSashWindowImpl::OnLeave
); 
 300     Connect(-1, wxEVT_LEFT_DOWN
, (wxObjectEventFunction
)&wxDynamicSashWindowImpl::OnPress
); 
 301     Connect(-1, wxEVT_LEFT_UP
, (wxObjectEventFunction
)&wxDynamicSashWindowImpl::OnRelease
); 
 306 void wxDynamicSashWindowImpl::AddChild(wxWindow 
*window
) { 
 307     if (m_add_child_target 
&& m_add_child_target
->m_leaf
) { 
 308         m_add_child_target
->m_leaf
->AddChild(window
); 
 312 void wxDynamicSashWindowImpl::DrawSash(int x
, int y
) const { 
 316     dc
.StartDrawingOnTop(m_container
); 
 320     bdc
.SelectObject(bmp
); 
 321     bdc
.DrawRectangle(-1, -1, 10, 10); 
 322     for (i 
= 0; i 
< 8; i
++) { 
 323         for (j 
= 0; j 
< 8; j
++) { 
 332     dc
.SetLogicalFunction(wxXOR
); 
 334     if (m_dragging 
== DSR_CORNER
) { 
 338         m_container
->ClientToScreen(&cx
, &cy
); 
 339         m_container
->ClientToScreen(&x
, &y
); 
 341         if (cx 
< x 
&& cy 
< y
) { 
 342             dc
.DrawRectangle(cx 
- 2, cy 
- 2, x 
- cx 
+ 4, 4); 
 343             dc
.DrawRectangle(x 
- 2, cy 
+ 2, 4, y 
- cy
); 
 344             dc
.DrawRectangle(cx 
- 2, cy 
+ 2, 4, y 
- cy
); 
 345             dc
.DrawRectangle(cx 
+ 2, y 
- 2, x 
- cx 
- 4, 4); 
 349         m_container
->GetClientSize(&body_w
, &body_h
); 
 360         if (m_dragging 
== DSR_HORIZONTAL_TAB
) 
 365         m_container
->ClientToScreen(&x
, &y
); 
 368         w 
= body_w
;  h 
= body_h
; 
 370         if (m_dragging 
== DSR_HORIZONTAL_TAB
) 
 371             dc
.DrawRectangle(x
, y 
- 2, w
, 4); 
 373             dc
.DrawRectangle(x 
- 2, y
, 4, h
); 
 376     dc
.EndDrawingOnTop(); 
 379 wxDynamicSashWindowImpl 
*wxDynamicSashWindowImpl::FindParent(DynamicSashRegion side
) const { 
 380     if (m_parent 
== NULL
) { 
 384     if (m_parent
->m_split 
== DSR_HORIZONTAL_TAB
) { 
 385         if (side 
== DSR_TOP_EDGE 
&& m_parent
->m_child
[1] == this) 
 387         if (side 
== DSR_BOTTOM_EDGE 
&& m_parent
->m_child
[0] == this) 
 389     } else if (m_parent
->m_split 
== DSR_VERTICAL_TAB
) { 
 390         if (side 
== DSR_LEFT_EDGE 
&& m_parent
->m_child
[1] == this) 
 392         if (side 
== DSR_RIGHT_EDGE 
&& m_parent
->m_child
[0] == this) 
 396     return m_parent
->FindParent(side
); 
 399 wxDynamicSashWindowImpl 
*wxDynamicSashWindowImpl::FindUpperParent(wxDynamicSashWindowImpl 
*sash_a
, 
 400                                                                   wxDynamicSashWindowImpl 
*sash_b
) const { 
 402     win 
= sash_a
->m_container
->GetParent(); 
 403     while (win 
&& !win
->IsTopLevel()) { 
 404         if (win 
== sash_b
->m_container
) { 
 408         win 
= win
->GetParent(); 
 415 wxWindow 
*wxDynamicSashWindowImpl::FindFrame() const { 
 418     win 
= m_window
->GetParent(); 
 419     while (win 
&& !win
->IsTopLevel()) { 
 420         win 
= win
->GetParent(); 
 426 wxScrollBar 
*wxDynamicSashWindowImpl::FindScrollBar(const wxWindow 
*child
, int vert
) const { 
 427     if (m_child
[0] == NULL 
&& m_leaf 
== NULL
) { 
 432         return m_leaf
->FindScrollBar(child
, vert
); 
 434         wxScrollBar 
*ret 
= m_child
[0]->FindScrollBar(child
, vert
); 
 436             ret 
= m_child
[1]->FindScrollBar(child
, vert
); 
 443 void wxDynamicSashWindowImpl::ConstrainChildren(int px
, int py
) { 
 444     wxLayoutConstraints 
*layout 
= new wxLayoutConstraints(); 
 445     layout
->left
.SameAs(m_container
, wxLeft
); 
 446     layout
->top
.SameAs(m_container
, wxTop
); 
 447     if (m_split 
== DSR_HORIZONTAL_TAB
) { 
 448         layout
->right
.SameAs(m_container
, wxRight
); 
 449         layout
->height
.PercentOf(m_container
, wxHeight
, py
); 
 451         layout
->bottom
.SameAs(m_container
, wxBottom
); 
 452         layout
->width
.PercentOf(m_container
, wxWidth
, px
); 
 454     m_child
[0]->m_container
->SetConstraints(layout
); 
 456     layout 
= new wxLayoutConstraints(); 
 457     layout
->right
.SameAs(m_container
, wxRight
); 
 458     layout
->bottom
.SameAs(m_container
, wxBottom
); 
 459     if (m_split 
== DSR_HORIZONTAL_TAB
) { 
 460         layout
->top
.Below(m_child
[0]->m_container
, 1); 
 461         layout
->left
.SameAs(m_container
, wxLeft
); 
 463         layout
->left
.RightOf(m_child
[0]->m_container
, 1); 
 464         layout
->top
.SameAs(m_container
, wxTop
); 
 466     m_child
[1]->m_container
->SetConstraints(layout
); 
 469 void wxDynamicSashWindowImpl::Unify(int panel
) { 
 475     if (m_child
[panel
]->m_leaf
) { 
 476         wxDynamicSashWindowImpl 
*child
[2]; 
 478         child
[0] = m_child
[0]; 
 479         child
[1] = m_child
[1]; 
 481         m_child
[0] = m_child
[1] = NULL
; 
 483         m_leaf 
= new wxDynamicSashWindowLeaf(this); 
 485         m_leaf
->m_child 
= child
[panel
]->m_leaf
->m_child
; 
 487         m_leaf
->m_vscroll
->SetScrollbar(child
[panel
]->m_leaf
->m_vscroll
->GetThumbPosition(), 
 488                                         child
[panel
]->m_leaf
->m_vscroll
->GetThumbSize(), 
 489                                         child
[panel
]->m_leaf
->m_vscroll
->GetRange(), 
 490                                         child
[panel
]->m_leaf
->m_vscroll
->GetPageSize()); 
 491         m_leaf
->m_hscroll
->SetScrollbar(child
[panel
]->m_leaf
->m_hscroll
->GetThumbPosition(), 
 492                                         child
[panel
]->m_leaf
->m_hscroll
->GetThumbSize(), 
 493                                         child
[panel
]->m_leaf
->m_hscroll
->GetRange(), 
 494                                         child
[panel
]->m_leaf
->m_hscroll
->GetPageSize()); 
 495         m_add_child_target 
= NULL
; 
 496         wxDynamicSashReparentEvent 
event(m_leaf
); 
 497         m_leaf
->ProcessEvent(event
); 
 504         wxDynamicSashUnifyEvent 
unify(m_leaf
->m_child
); 
 505         m_leaf
->m_child
->ProcessEvent(unify
); 
 507         m_split 
= m_child
[panel
]->m_split
; 
 509         delete m_child
[other
]; 
 511         wxDynamicSashWindowImpl 
*child_panel 
= m_child
[panel
]; 
 512         m_child
[0] = child_panel
->m_child
[0]; 
 513         m_child
[1] = child_panel
->m_child
[1]; 
 515         m_child
[0]->m_parent 
= this; 
 516         m_child
[1]->m_parent 
= this; 
 518         m_add_child_target 
= NULL
; 
 519         m_child
[0]->m_container
->Reparent(m_container
); 
 520         m_child
[1]->m_container
->Reparent(m_container
); 
 522         child_panel
->m_child
[0] = child_panel
->m_child
[1] = NULL
; 
 525         wxSize size 
= m_container
->GetSize(); 
 526         wxSize child_size 
= m_child
[0]->m_container
->GetSize(); 
 528         ConstrainChildren(child_size
.GetWidth() * 100 / size
.GetWidth(), 
 529                             child_size
.GetHeight() * 100 / size
.GetHeight()); 
 531         m_container
->Layout(); 
 535 void wxDynamicSashWindowImpl::Split(int px
, int py
) { 
 538     m_add_child_target 
= NULL
; 
 540     m_child
[0] = new wxDynamicSashWindowImpl(m_window
); 
 541     m_child
[0]->m_container 
= new wxWindow(m_container
, -1); 
 542     m_child
[0]->m_parent 
= this; 
 543     m_child
[0]->m_top 
= m_top
; 
 544     m_child
[0]->Create(); 
 545     if (m_leaf
->m_child
) { 
 546         m_leaf
->m_child
->Reparent(m_container
); 
 547         m_child
[0]->AddChild(m_leaf
->m_child
); 
 550     m_child
[1] = new wxDynamicSashWindowImpl(m_window
); 
 551     m_child
[1]->m_container 
= new wxWindow(m_container
, -1); 
 552     m_child
[1]->m_parent 
= this; 
 553     m_child
[1]->m_top 
= m_top
; 
 554     m_child
[1]->Create(); 
 556     m_split 
= m_dragging
; 
 557     ConstrainChildren(px
, py
); 
 559     m_top
->m_add_child_target 
= m_child
[1]; 
 560     wxDynamicSashSplitEvent 
split(m_child
[0]->m_leaf
->m_child
); 
 561     m_child
[0]->m_leaf
->m_child
->ProcessEvent(split
); 
 563     m_child
[0]->m_leaf
->m_vscroll
->SetScrollbar(m_leaf
->m_vscroll
->GetThumbPosition(), 
 564                                                 m_leaf
->m_vscroll
->GetThumbSize(), 
 565                                                 m_leaf
->m_vscroll
->GetRange(), 
 566                                                 m_leaf
->m_vscroll
->GetPageSize()); 
 567     m_child
[0]->m_leaf
->m_hscroll
->SetScrollbar(m_leaf
->m_hscroll
->GetThumbPosition(), 
 568                                                 m_leaf
->m_hscroll
->GetThumbSize(), 
 569                                                 m_leaf
->m_hscroll
->GetRange(), 
 570                                                 m_leaf
->m_hscroll
->GetPageSize()); 
 571     m_child
[1]->m_leaf
->m_vscroll
->SetScrollbar(m_leaf
->m_vscroll
->GetThumbPosition(), 
 572                                                 m_leaf
->m_vscroll
->GetThumbSize(), 
 573                                                 m_leaf
->m_vscroll
->GetRange(), 
 574                                                 m_leaf
->m_vscroll
->GetPageSize()); 
 575     m_child
[1]->m_leaf
->m_hscroll
->SetScrollbar(m_leaf
->m_hscroll
->GetThumbPosition(), 
 576                                                 m_leaf
->m_hscroll
->GetThumbSize(), 
 577                                                 m_leaf
->m_hscroll
->GetRange(), 
 578                                                 m_leaf
->m_hscroll
->GetPageSize()); 
 582     m_container
->Layout(); 
 587 /*  This code is called when you finish resizing a view by dragging the 
 588     corner tab, but I think this implementation is lousy and will surprise 
 589     the user more often than it will do what they are trying to do.  What 
 590     I really need to be doing here is do a rewrite such that *no* sashes 
 591     move except the ones immediately to the bottom and right of this window, 
 592     and handle the case where you resize a window larger than it's neighbors 
 593     by destroying the neighbors. 
 595     But this will do for now.  */ 
 596 void wxDynamicSashWindowImpl::Resize(int x
, int y
) { 
 597     wxDynamicSashWindowImpl 
*h_parent 
= FindParent(DSR_BOTTOM_EDGE
); 
 598     wxDynamicSashWindowImpl 
*v_parent 
= FindParent(DSR_RIGHT_EDGE
); 
 601     wxWindow 
*frame 
= FindFrame(); 
 611         m_container
->ClientToScreen(NULL
, &y
); 
 612         h_parent
->m_container
->ScreenToClient(NULL
, &y
); 
 614         int py 
= (int)((y 
* 100) / h_parent
->m_container
->GetSize().GetHeight() + 0.5); 
 617             wxDynamicSashWindowImpl 
*ho_parent 
= FindParent(DSR_TOP_EDGE
); 
 620                 if (FindUpperParent(h_parent
, ho_parent
) == ho_parent
) { 
 623                     py 
= (int)((ho_parent
->m_child
[0]->m_container
->GetSize().GetHeight() * 100) 
 624                                 / h_parent
->m_container
->GetSize().GetHeight() + 0.5); 
 625                     h_parent
->m_child
[0]->m_container
->GetConstraints()->height
.PercentOf( 
 626                             h_parent
->m_container
, wxHeight
, py
); 
 628                     h_parent 
= ho_parent
; 
 634         } else if (py 
> 90) { 
 637             h_parent
->m_child
[0]->m_container
->GetConstraints()->height
.PercentOf( 
 638                     h_parent
->m_container
, wxHeight
, py
); 
 639             h_parent
->m_container
->Layout(); 
 643         h_parent 
= FindParent(DSR_TOP_EDGE
); 
 646             int py 
= (int)((y 
* 100) / 
 647                         (h_parent
->m_container
->GetSize().GetHeight() + 
 648                                 y 
- m_container
->GetSize().GetHeight()) + 0.5); 
 658             wxSize size 
= frame
->GetSize(); 
 659             frame
->SetSize(size
.GetWidth(), size
.GetHeight() + y 
- m_container
->GetSize().GetHeight()); 
 664         m_container
->ClientToScreen(&x
, NULL
); 
 665         v_parent
->m_container
->ScreenToClient(&x
, NULL
); 
 667         int px 
= (int)((x 
* 100) / v_parent
->m_container
->GetSize().GetWidth() + 0.5); 
 670             wxDynamicSashWindowImpl 
*vo_parent 
= FindParent(DSR_LEFT_EDGE
); 
 673                 if (FindUpperParent(v_parent
, vo_parent
) == vo_parent
) { 
 676                     px 
= (int)((vo_parent
->m_child
[0]->m_container
->GetSize().GetWidth() * 100) 
 677                                 / v_parent
->m_container
->GetSize().GetWidth() + 0.5); 
 678                     v_parent
->m_child
[0]->m_container
->GetConstraints()->width
.PercentOf( 
 679                             v_parent
->m_container
, wxWidth
, px
); 
 681                     v_parent 
= vo_parent
; 
 687         } else if (px 
> 90) { 
 690             v_parent
->m_child
[0]->m_container
->GetConstraints()->width
.PercentOf( 
 691                     v_parent
->m_container
, wxWidth
, px
); 
 692             v_parent
->m_container
->Layout(); 
 696         v_parent 
= FindParent(DSR_LEFT_EDGE
); 
 699             int px 
= (int)((x 
* 100) / 
 700                         (v_parent
->m_container
->GetSize().GetWidth() + 
 701                                 x 
- m_container
->GetSize().GetWidth()) + 0.5); 
 711             wxSize size 
= frame
->GetSize(); 
 712             frame
->SetSize(size
.GetWidth() + x 
- m_container
->GetSize().GetWidth(), size
.GetHeight()); 
 716     if (h_unify 
!= -1 && v_unify 
!= -1) { 
 717         wxDynamicSashWindowImpl 
*parent 
= FindUpperParent(h_parent
, v_parent
); 
 719         if (parent 
== h_parent
) { 
 720             h_parent
->Unify(h_unify
); 
 722             v_parent
->Unify(v_unify
); 
 724     } else if (h_unify 
!= -1) { 
 725         h_parent
->Unify(h_unify
); 
 726     } else if (v_unify 
!= -1) { 
 727         v_parent
->Unify(v_unify
); 
 732 void wxDynamicSashWindowImpl::OnSize(wxSizeEvent 
&event
) { 
 733     m_container
->Layout(); 
 736         m_leaf
->OnSize(event
); 
 739 void wxDynamicSashWindowImpl::OnPaint(wxPaintEvent 
&event
) { 
 741         m_leaf
->OnPaint(event
); 
 743         wxPaintDC 
dc(m_container
); 
 744         dc
.SetBackground(wxBrush(m_container
->GetBackgroundColour(), wxSOLID
)); 
 749 void wxDynamicSashWindowImpl::OnMouseMove(wxMouseEvent 
&event
) { 
 751         DrawSash(m_drag_x
, m_drag_y
); 
 752         m_drag_x 
= event
.m_x
;  m_drag_y 
= event
.m_y
; 
 753         DrawSash(m_drag_x
, m_drag_y
); 
 755         m_leaf
->OnMouseMove(event
); 
 759 void wxDynamicSashWindowImpl::OnLeave(wxMouseEvent 
&event
) { 
 761         m_leaf
->OnLeave(event
); 
 765 void wxDynamicSashWindowImpl::OnPress(wxMouseEvent 
&event
) { 
 767         m_leaf
->OnPress(event
); 
 769         m_dragging 
= m_split
; 
 770         m_drag_x 
= event
.m_x
; 
 771         m_drag_y 
= event
.m_y
; 
 772         DrawSash(m_drag_x
, m_drag_y
); 
 773         m_container
->CaptureMouse(); 
 777 void wxDynamicSashWindowImpl::OnRelease(wxMouseEvent 
&event
) { 
 778     if (m_dragging 
== DSR_CORNER
) { 
 779         DrawSash(m_drag_x
, m_drag_y
); 
 780         m_container
->ReleaseMouse(); 
 782         Resize(event
.m_x
, event
.m_y
); 
 784         m_dragging 
= DSR_NONE
; 
 785     } else if (m_dragging
) { 
 786         DrawSash(m_drag_x
, m_drag_y
); 
 787         m_container
->ReleaseMouse(); 
 789         wxSize size 
= m_container
->GetSize(); 
 790         int px 
= (int)((event
.m_x 
* 100) / size
.GetWidth() + 0.5); 
 791         int py 
= (int)((event
.m_y 
* 100) / size
.GetHeight() + 0.5); 
 793         if ((m_dragging 
== DSR_HORIZONTAL_TAB 
&& py 
>= 10 && py 
<= 90) 
 794                     || (m_dragging 
== DSR_VERTICAL_TAB 
&& px 
>= 10 && px 
<= 90)) { 
 795             if (m_child
[0] == NULL
) { 
 798                 /*  It would be nice if moving *this* sash didn't implicitly move 
 799                     the sashes of our children (if any).  But this will do.  */ 
 800                 wxLayoutConstraints 
*layout 
= m_child
[0]->m_container
->GetConstraints(); 
 801                 if (m_split 
== DSR_HORIZONTAL_TAB
) { 
 802                     layout
->height
.PercentOf(m_container
, wxHeight
, py
); 
 804                     layout
->width
.PercentOf(m_container
, wxWidth
, px
); 
 806                 m_container
->Layout(); 
 809             if (m_child
[0] != NULL
) { 
 810                 if ((m_dragging 
== DSR_HORIZONTAL_TAB 
&& py 
<= 10) 
 811                         || (m_dragging 
== DSR_VERTICAL_TAB 
&& px 
<= 10)) { 
 819         wxCursor 
cursor(wxCURSOR_ARROW
); 
 820         if (m_split 
== DSR_HORIZONTAL_TAB
) { 
 821             cursor 
= wxCursor(wxCURSOR_SIZENS
); 
 822         } else if (m_split 
== DSR_VERTICAL_TAB
) { 
 823             cursor 
= wxCursor(wxCURSOR_SIZEWE
); 
 825         m_container
->SetCursor(cursor
); 
 827         m_dragging 
= DSR_NONE
; 
 829         m_leaf
->OnRelease(event
); 
 833 // wxDynamicSashWindowLeaf ////////////////////////////////////////////////// 
 835 wxDynamicSashWindowLeaf::wxDynamicSashWindowLeaf(wxDynamicSashWindowImpl 
*impl
) { 
 838     m_hscroll 
= m_vscroll 
= NULL
; 
 842 wxDynamicSashWindowLeaf::~wxDynamicSashWindowLeaf() { 
 843     m_hscroll
->SetEventHandler(m_hscroll
); 
 844     m_vscroll
->SetEventHandler(m_vscroll
); 
 845     m_viewport
->SetEventHandler(m_viewport
); 
 847     m_hscroll
->Destroy(); 
 848     m_vscroll
->Destroy(); 
 849     m_viewport
->Destroy(); 
 852 bool wxDynamicSashWindowLeaf::Create() { 
 855     m_hscroll 
= new wxScrollBar(); 
 856     m_vscroll 
= new wxScrollBar(); 
 857     m_viewport 
= new wxWindow(); 
 859     if (!m_hscroll 
|| !m_vscroll 
|| !m_viewport
) { 
 863     wxDynamicSashWindowImpl 
*add_child_target 
= m_impl
->m_add_child_target
; 
 864     m_impl
->m_add_child_target 
= NULL
; 
 865     success 
= m_hscroll
->Create(m_impl
->m_container
, -1, wxDefaultPosition
, wxDefaultSize
, 
 867     success 
= success 
&& m_vscroll
->Create(m_impl
->m_container
, -1, wxDefaultPosition
, wxDefaultSize
, 
 869     success 
= success 
&& m_viewport
->Create(m_impl
->m_container
, -1); 
 870     m_impl
->m_add_child_target 
= add_child_target
; 
 872     wxCursor 
cursor(wxCURSOR_ARROW
); 
 873     m_hscroll
->SetCursor(cursor
); 
 874     m_vscroll
->SetCursor(cursor
); 
 875     m_viewport
->SetCursor(cursor
); 
 877     m_viewport
->SetEventHandler(this); 
 878     Connect(-1, wxEVT_DYNAMIC_SASH_REPARENT
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnReparent
); 
 880     if (m_impl
->m_window
->GetWindowStyle() & wxMANAGE_SCROLLBARS
) { 
 881         m_hscroll
->SetEventHandler(this); 
 882         m_vscroll
->SetEventHandler(this); 
 884         Connect(-1, wxEVT_SET_FOCUS
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnFocus
); 
 885         Connect(-1, wxEVT_SCROLL_TOP
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 886         Connect(-1, wxEVT_SCROLL_BOTTOM
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 887         Connect(-1, wxEVT_SCROLL_LINEUP
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 888         Connect(-1, wxEVT_SCROLL_LINEDOWN
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 889         Connect(-1, wxEVT_SCROLL_PAGEUP
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 890         Connect(-1, wxEVT_SCROLL_PAGEDOWN
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 891         Connect(-1, wxEVT_SCROLL_THUMBTRACK
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 892         Connect(-1, wxEVT_SCROLL_THUMBRELEASE
, (wxObjectEventFunction
)&wxDynamicSashWindowLeaf::OnScroll
); 
 895     wxLayoutConstraints 
*layout 
= new wxLayoutConstraints(); 
 898     wxSize size 
= m_hscroll
->GetBestSize(); 
 900     size 
= m_hscroll
->GetSize(); 
 903     layout
->left
.SameAs(m_impl
->m_container
, wxLeft
, 10); 
 904     layout
->right
.LeftOf(m_vscroll
); 
 905     layout
->bottom
.SameAs(m_impl
->m_container
, wxBottom
, 3); 
 906     layout
->height
.Absolute(size
.GetHeight()); 
 907     m_hscroll
->SetConstraints(layout
); 
 909     layout 
= new wxLayoutConstraints(); 
 912     size 
= size 
= m_vscroll
->GetBestSize(); 
 914     size 
= m_vscroll
->GetSize(); 
 917     layout
->top
.SameAs(m_impl
->m_container
, wxTop
, 10); 
 918     layout
->bottom
.Above(m_hscroll
); 
 919     layout
->right
.SameAs(m_impl
->m_container
, wxRight
, 3); 
 920     layout
->width
.Absolute(size
.GetWidth()); 
 921     m_vscroll
->SetConstraints(layout
); 
 923     layout 
= new wxLayoutConstraints(); 
 926     layout
->left
.SameAs(m_impl
->m_container
, wxLeft
, 3); 
 927     layout
->right
.LeftOf(m_vscroll
); 
 928     layout
->top
.SameAs(m_impl
->m_container
, wxTop
, 3); 
 929     layout
->bottom
.Above(m_hscroll
); 
 930     m_viewport
->SetConstraints(layout
); 
 932     m_impl
->m_container
->Layout(); 
 937 void wxDynamicSashWindowLeaf::AddChild(wxWindow 
*window
) { 
 944     wxDynamicSashReparentEvent 
event(this); 
 945     AddPendingEvent(event
); 
 948 DynamicSashRegion 
wxDynamicSashWindowLeaf::GetRegion(int x
, int y
) { 
 949     wxSize size 
= m_impl
->m_container
->GetSize(); 
 950     int w 
= size
.GetWidth(); 
 951     int h 
= size
.GetHeight(); 
 952     size 
= m_hscroll
->GetSize(); 
 953     int sh 
= size
.GetHeight(); 
 954     size 
= m_vscroll
->GetSize(); 
 955     int sw 
= size
.GetWidth(); 
 957     if (x 
>= w 
- sw 
- 3 && x 
< w 
&& y 
>= h 
- sh 
- 3 && y 
< h
) 
 959     if (x 
>= 3 && x 
< 10 && y 
>= h 
- sh 
- 3 && y 
< h 
- 2) 
 960         return DSR_VERTICAL_TAB
; 
 961     if (x 
>= w 
- sw 
- 3 && x 
< w 
- 2 && y 
>= 3 && y 
< 10) 
 962         return DSR_HORIZONTAL_TAB
; 
 964         return DSR_LEFT_EDGE
; 
 968         return DSR_RIGHT_EDGE
; 
 970         return DSR_BOTTOM_EDGE
; 
 975 void wxDynamicSashWindowLeaf::ResizeChild(wxSize size
) { 
 977         if (m_impl
->m_window
->GetWindowStyle() & wxMANAGE_SCROLLBARS
) { 
 978             m_child
->SetSize(size
); 
 979             wxSize best_size 
= m_child
->GetBestSize(); 
 980             if (best_size
.GetWidth() < size
.GetWidth()) { 
 981                 best_size
.SetWidth(size
.GetWidth()); 
 983             if (best_size
.GetHeight() < size
.GetHeight()) { 
 984                 best_size
.SetHeight(size
.GetHeight()); 
 986             m_child
->SetSize(best_size
); 
 988             int hpos 
= m_hscroll
->GetThumbPosition(); 
 989             int vpos 
= m_vscroll
->GetThumbPosition(); 
 997             if (hpos 
> best_size
.GetWidth() - size
.GetWidth()) { 
 998                 hpos 
= best_size
.GetWidth() - size
.GetWidth(); 
1000             if (vpos 
> best_size
.GetHeight() - size
.GetHeight()) { 
1001                 vpos 
= best_size
.GetHeight() - size
.GetHeight(); 
1004             m_hscroll
->SetScrollbar(hpos
, size
.GetWidth(), 
1005                                     best_size
.GetWidth(), size
.GetWidth()); 
1006             m_vscroll
->SetScrollbar(vpos
, size
.GetHeight(), 
1007                                     best_size
.GetHeight(), size
.GetHeight()); 
1009             //  Umm, the scrollbars are doing something insane under GTK+ and subtracting 
1010             //  one from the position I pass in.  This works around that. 
1011             m_hscroll
->SetThumbPosition(hpos 
+ hpos 
- m_hscroll
->GetThumbPosition()); 
1012             m_vscroll
->SetThumbPosition(vpos 
+ vpos 
- m_vscroll
->GetThumbPosition()); 
1014             wxPoint pos 
= m_child
->GetPosition(); 
1015             m_viewport
->ScrollWindow(-hpos 
- pos
.x
, -vpos 
- pos
.y
); 
1017             m_child
->SetSize(size
); 
1022 wxScrollBar 
*wxDynamicSashWindowLeaf::FindScrollBar(const wxWindow 
*child
, int vert
) const { 
1023     if (m_child 
== child
) { 
1034 void wxDynamicSashWindowLeaf::OnSize(wxSizeEvent 
&event
) { 
1035     m_impl
->m_container
->Refresh(); 
1036     ResizeChild(m_viewport
->GetSize()); 
1039 void wxDynamicSashWindowLeaf::OnPaint(wxPaintEvent 
&event
) { 
1040     wxPaintDC 
dc(m_impl
->m_container
); 
1041     dc
.SetBackground(wxBrush(m_impl
->m_container
->GetBackgroundColour(), wxSOLID
)); 
1044     wxPen 
highlight(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNHIGHLIGHT
), 1, wxSOLID
); 
1045     wxPen 
shadow(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNSHADOW
), 1, wxSOLID
); 
1046     wxPen 
black(*wxBLACK
, 1, wxSOLID
); 
1048     wxSize size 
= m_impl
->m_container
->GetSize(); 
1049     int w 
= size
.GetWidth(); 
1050     int h 
= size
.GetHeight(); 
1051     size 
= m_hscroll
->GetSize(); 
1052     int sh 
= size
.GetHeight(); 
1053     size 
= m_vscroll
->GetSize(); 
1054     int sw 
= size
.GetWidth(); 
1057     dc
.DrawLine(1, 1, 1, h 
- 2); 
1058     dc
.DrawLine(1, 1, w 
- 2, 1); 
1060     dc
.DrawLine(2, 2, 2, h 
- 3); 
1061     dc
.DrawLine(2, 2, w 
- 3, 2); 
1062     dc
.SetPen(highlight
); 
1063     dc
.DrawLine(w 
- 2, 2, w 
- 2, h 
- sh 
- 2); 
1064     dc
.DrawLine(w 
- 2, h 
- sh 
- 2, w 
- sw 
- 2, h 
- sh 
- 2); 
1065     dc
.DrawLine(w 
- sw 
- 2, h 
- sh 
- 2, w 
- sw 
- 2, h 
- 2); 
1066     dc
.DrawLine(w 
- sw 
- 2, h 
- 2, 2, h 
- 2); 
1068     dc
.SetPen(highlight
); 
1069     dc
.DrawLine(w 
- sw 
- 2, 8, w 
- sw 
- 2, 4); 
1070     dc
.DrawLine(w 
- sw 
- 2, 4, w 
- 5, 4); 
1072     dc
.DrawLine(w 
- 5, 4, w 
- 5, 8); 
1073     dc
.DrawLine(w 
- 5, 8, w 
- sw 
- 2, 8); 
1075     dc
.DrawLine(w 
- 4, 3, w 
- 4, 9); 
1076     dc
.DrawLine(w 
- 4, 9, w 
- sw 
- 3, 9); 
1078     dc
.SetPen(highlight
); 
1079     dc
.DrawLine(4, h 
- 5, 4, h 
- sh 
- 2); 
1080     dc
.DrawLine(4, h 
- sh 
- 2, 8, h 
- sh 
- 2); 
1082     dc
.DrawLine(8, h 
- sh 
- 2, 8, h 
- 5); 
1083     dc
.DrawLine(8, h 
- 5, 4, h 
- 5); 
1085     dc
.DrawLine(9, h 
- sh 
- 3, 9, h 
- 4); 
1086     dc
.DrawLine(9, h 
- 4, 3, h 
- 4); 
1089     int cy 
= (h 
- sh 
+ h 
- 6) / 2 + 1; 
1090     int cx 
= (w 
- sw 
+ w 
- 6) / 2 + 1; 
1099     for (y 
= sy
; y 
< h 
- 2; y 
+= 4) { 
1100         for (x 
= sx
; x 
< w 
- 2; x 
+= 4) { 
1101             if (x 
- cx 
>= -(y 
- cy
)) { 
1102                 dc
.SetPen(highlight
); 
1105                 dc
.DrawPoint(x 
+ 1, y 
+ 1); 
1111 void wxDynamicSashWindowLeaf::OnScroll(wxScrollEvent 
&event
) { 
1112     int nx 
= -m_hscroll
->GetThumbPosition(); 
1113     int ny 
= -m_vscroll
->GetThumbPosition(); 
1116         wxPoint pos 
= m_child
->GetPosition(); 
1118         m_viewport
->ScrollWindow(nx 
- pos
.x
, ny 
- pos
.y
); 
1122 void wxDynamicSashWindowLeaf::OnFocus(wxFocusEvent 
&event
) { 
1123     if (event
.m_eventObject 
== m_hscroll 
|| event
.m_eventObject 
== m_vscroll
) { 
1124         m_child
->SetFocus(); 
1129 void wxDynamicSashWindowLeaf::OnMouseMove(wxMouseEvent 
&event
) { 
1130     if (m_impl
->m_dragging
) { 
1134     DynamicSashRegion region 
= GetRegion(event
.m_x
, event
.m_y
); 
1136     wxCursor 
cursor(wxCURSOR_ARROW
); 
1137     if (region 
== DSR_HORIZONTAL_TAB
) { 
1138         cursor 
= wxCursor(wxCURSOR_SIZENS
); 
1139     } else if (region 
== DSR_VERTICAL_TAB
) { 
1140         cursor 
= wxCursor(wxCURSOR_SIZEWE
); 
1141     } else if (region 
== DSR_CORNER
) { 
1142         cursor 
= wxCursor(wxCURSOR_SIZENWSE
); 
1143     } else if (region 
== DSR_LEFT_EDGE 
|| region 
== DSR_TOP_EDGE
 
1144                 || region 
== DSR_RIGHT_EDGE 
|| region 
== DSR_BOTTOM_EDGE
) { 
1145         if (m_impl
->FindParent(region
)) { 
1146             if (region 
== DSR_LEFT_EDGE 
|| region 
== DSR_RIGHT_EDGE
) { 
1147                 cursor 
= wxCursor(wxCURSOR_SIZEWE
); 
1149                 cursor 
= wxCursor(wxCURSOR_SIZENS
); 
1154     m_impl
->m_container
->SetCursor(cursor
); 
1157 void wxDynamicSashWindowLeaf::OnLeave(wxMouseEvent 
&event
) { 
1158     wxCursor 
cursor(wxCURSOR_ARROW
); 
1159     m_impl
->m_container
->SetCursor(cursor
); 
1163 void wxDynamicSashWindowLeaf::OnPress(wxMouseEvent 
&event
) { 
1164     DynamicSashRegion region 
= GetRegion(event
.m_x
, event
.m_y
); 
1166     if (region 
== DSR_HORIZONTAL_TAB 
|| region 
== DSR_VERTICAL_TAB 
|| region 
== DSR_CORNER
) { 
1167         m_impl
->m_dragging 
= region
; 
1168         m_impl
->m_drag_x 
= event
.m_x
; 
1169         m_impl
->m_drag_y 
= event
.m_y
; 
1170         m_impl
->DrawSash(event
.m_x
, event
.m_y
); 
1171         m_impl
->m_container
->CaptureMouse(); 
1172     } else if (region 
== DSR_LEFT_EDGE 
|| region 
== DSR_TOP_EDGE
 
1173                 || region 
== DSR_RIGHT_EDGE 
|| region 
== DSR_BOTTOM_EDGE
) { 
1174         wxDynamicSashWindowImpl 
*parent 
= m_impl
->FindParent(region
); 
1180             m_impl
->m_container
->ClientToScreen(&x
, &y
); 
1181             parent
->m_container
->ScreenToClient(&x
, &y
); 
1183             parent
->m_dragging 
= parent
->m_split
; 
1184             parent
->m_drag_x 
= x
; 
1185             parent
->m_drag_y 
= y
; 
1186             parent
->DrawSash(x
, y
); 
1187             parent
->m_container
->CaptureMouse(); 
1192 void wxDynamicSashWindowLeaf::OnRelease(wxMouseEvent 
&event
) { 
1195 void wxDynamicSashWindowLeaf::OnReparent(wxEvent 
&event
) { 
1197         m_child
->Reparent(m_viewport
); 
1200     ResizeChild(m_viewport
->GetSize()); 
1203 // wxDynamicSashSplitEvent ////////////////////////////////////////////////// 
1205 wxDynamicSashSplitEvent::wxDynamicSashSplitEvent() { 
1206     m_eventObject 
= NULL
; 
1207     m_eventType 
= wxEVT_DYNAMIC_SASH_SPLIT
; 
1210 wxDynamicSashSplitEvent::wxDynamicSashSplitEvent(wxObject 
*object
) { 
1211     m_eventObject 
= object
; 
1212     m_eventType 
= wxEVT_DYNAMIC_SASH_SPLIT
; 
1215 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashSplitEvent
, wxCommandEvent
) 
1217 // wxDynamicSashUnifyEvent ////////////////////////////////////////////////// 
1219 wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent() { 
1220     m_eventObject 
= NULL
; 
1221     m_eventType 
= wxEVT_DYNAMIC_SASH_UNIFY
; 
1224 wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent(wxObject 
*object
) { 
1225     m_eventObject 
= object
; 
1226     m_eventType 
= wxEVT_DYNAMIC_SASH_UNIFY
; 
1229 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashUnifyEvent
, wxCommandEvent
) 
1231 // wxDynamicSsahReparentEvent /////////////////////////////////////////////// 
1233 wxDynamicSashReparentEvent::wxDynamicSashReparentEvent() { 
1234     m_eventObject 
= NULL
; 
1235     m_eventType 
= wxEVT_DYNAMIC_SASH_REPARENT
; 
1238 wxDynamicSashReparentEvent::wxDynamicSashReparentEvent(wxObject 
*object
) { 
1239     m_eventObject 
= object
; 
1240     m_eventType 
= wxEVT_DYNAMIC_SASH_REPARENT
; 
1243 wxDynamicSashReparentEvent::wxDynamicSashReparentEvent(const wxDynamicSashReparentEvent
& evt
) 
1248 IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashReparentEvent
, wxEvent
) 
1250 /////////////////////////////////////////////////////////////////////////////