1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/aui/floatpane.cpp 
   3 // Purpose:     wxaui: wx advanced user interface - docking window manager 
   4 // Author:      Benjamin I. Williams 
   8 // Copyright:   (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved 
   9 // Licence:     wxWindows Library Licence, Version 3.1 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #include "wx/wxprec.h" 
  28 #include "wx/aui/framemanager.h" 
  29 #include "wx/aui/floatpane.h" 
  30 #include "wx/aui/dockart.h" 
  36 #include "wx/msw/private.h" 
  39 IMPLEMENT_CLASS(wxAuiFloatingFrame
, wxAuiFloatingFrameBaseClass
) 
  41 wxAuiFloatingFrame::wxAuiFloatingFrame(wxWindow
* parent
, 
  42                 wxAuiManager
* owner_mgr
, 
  43                 const wxAuiPaneInfo
& pane
, 
  44                 wxWindowID id 
/*= wxID_ANY*/, 
  45                 long style 
/*=wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | 
  46                               wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT | 
  49                 : wxAuiFloatingFrameBaseClass(parent
, id
, wxEmptyString
, 
  50                         pane
.floating_pos
, pane
.floating_size
, 
  52                         (pane
.HasCloseButton()?wxCLOSE_BOX
:0) | 
  53                         (pane
.HasMaximizeButton()?wxMAXIMIZE_BOX
:0) | 
  54                         (pane
.IsFixed()?0:wxRESIZE_BORDER
) 
  57     m_ownerMgr 
= owner_mgr
; 
  59     m_mgr
.SetManagedWindow(this); 
  62     // find out if the system supports solid window drag. 
  63     // on non-msw systems, this is assumed to be the case 
  66     SystemParametersInfo(38 /*SPI_GETDRAGFULLWINDOWS*/, 0, &b
, 0); 
  67     m_solidDrag 
= b 
? true : false; 
  70     SetExtraStyle(wxWS_EX_PROCESS_IDLE
); 
  73 wxAuiFloatingFrame::~wxAuiFloatingFrame() 
  75     // if we do not do this, then we can crash... 
  76     if (m_ownerMgr 
&& m_ownerMgr
->m_actionWindow 
== this) 
  78         m_ownerMgr
->m_actionWindow 
= NULL
; 
  84 void wxAuiFloatingFrame::SetPaneWindow(const wxAuiPaneInfo
& pane
) 
  86     m_paneWindow 
= pane
.window
; 
  87     m_paneWindow
->Reparent(this); 
  89     wxAuiPaneInfo contained_pane 
= pane
; 
  90     contained_pane
.Dock().Center().Show(). 
  91                     CaptionVisible(false). 
  93                     Layer(0).Row(0).Position(0); 
  95     // Carry over the minimum size 
  96     wxSize pane_min_size 
= pane
.window
->GetMinSize(); 
  98     // if the frame window's max size is greater than the min size 
  99     // then set the max size to the min size as well 
 100     wxSize cur_max_size 
= GetMaxSize(); 
 101     if (cur_max_size
.IsFullySpecified() && 
 102           (cur_max_size
.x 
< pane
.min_size
.x 
|| 
 103            cur_max_size
.y 
< pane
.min_size
.y
) 
 106         SetMaxSize(pane_min_size
); 
 109     SetMinSize(pane
.window
->GetMinSize()); 
 111     m_mgr
.AddPane(m_paneWindow
, contained_pane
); 
 114     if (pane
.min_size
.IsFullySpecified()) 
 116         // because SetSizeHints() calls Fit() too (which sets the window 
 117         // size to its minimum allowed), we keep the size before calling 
 118         // SetSizeHints() and reset it afterwards... 
 119         wxSize tmp 
= GetSize(); 
 120         GetSizer()->SetSizeHints(this); 
 124     SetTitle(pane
.caption
); 
 126     // This code is slightly awkward because we need to reset wxRESIZE_BORDER 
 127     // before calling SetClientSize() below as doing it after setting the 
 128     // client size would actually change it, at least under MSW, where the 
 129     // total window size doesn't change and hence, as the borders size changes, 
 130     // the client size does change. 
 132     // So we must call it first but doing it generates a size event and updates 
 133     // pane.floating_size from inside it so we must also record its original 
 134     // value before doing it. 
 135     const bool hasFloatingSize 
= pane
.floating_size 
!= wxDefaultSize
; 
 138         SetWindowStyleFlag(GetWindowStyleFlag() & ~wxRESIZE_BORDER
); 
 141     if ( hasFloatingSize 
) 
 143         SetSize(pane
.floating_size
); 
 147         wxSize size 
= pane
.best_size
; 
 148         if (size 
== wxDefaultSize
) 
 149             size 
= pane
.min_size
; 
 150         if (size 
== wxDefaultSize
) 
 151             size 
= m_paneWindow
->GetSize(); 
 152         if (m_ownerMgr 
&& pane
.HasGripper()) 
 154             if (pane
.HasGripperTop()) 
 155                 size
.y 
+= m_ownerMgr
->m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
 157                 size
.x 
+= m_ownerMgr
->m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
 164 wxAuiManager
* wxAuiFloatingFrame::GetOwnerManager() const 
 170 void wxAuiFloatingFrame::OnSize(wxSizeEvent
& WXUNUSED(event
)) 
 174         m_ownerMgr
->OnFloatingPaneResized(m_paneWindow
, GetRect()); 
 178 void wxAuiFloatingFrame::OnClose(wxCloseEvent
& evt
) 
 182         m_ownerMgr
->OnFloatingPaneClosed(m_paneWindow
, evt
); 
 186         m_mgr
.DetachPane(m_paneWindow
); 
 191 void wxAuiFloatingFrame::OnMoveEvent(wxMoveEvent
& event
) 
 195         // systems without solid window dragging need to be 
 196         // handled slightly differently, due to the lack of 
 197         // the constant stream of EVT_MOVING events 
 201         OnMoving(event
.GetRect(), wxNORTH
); 
 207     wxRect winRect 
= GetRect(); 
 209     if (winRect 
== m_lastRect
) 
 212     // skip the first move event 
 213     if (m_lastRect
.IsEmpty()) 
 215         m_lastRect 
= winRect
; 
 219     // as on OSX moving windows are not getting all move events, only sporadically, this difference 
 220     // is almost always big on OSX, so avoid this early exit opportunity 
 222     // skip if moving too fast to avoid massive redraws and 
 223     // jumping hint windows 
 224     if ((abs(winRect
.x 
- m_lastRect
.x
) > 3) || 
 225         (abs(winRect
.y 
- m_lastRect
.y
) > 3)) 
 227         m_last3Rect 
= m_last2Rect
; 
 228         m_last2Rect 
= m_lastRect
; 
 229         m_lastRect 
= winRect
; 
 231         // However still update the internally stored position to avoid 
 232         // snapping back to the old one later. 
 235             m_ownerMgr
->GetPane(m_paneWindow
). 
 236                 floating_pos 
= winRect
.GetPosition(); 
 243     // prevent frame redocking during resize 
 244     if (m_lastRect
.GetSize() != winRect
.GetSize()) 
 246         m_last3Rect 
= m_last2Rect
; 
 247         m_last2Rect 
= m_lastRect
; 
 248         m_lastRect 
= winRect
; 
 252     wxDirection dir 
= wxALL
; 
 254     int horiz_dist 
= abs(winRect
.x 
- m_last3Rect
.x
); 
 255     int vert_dist 
= abs(winRect
.y 
- m_last3Rect
.y
); 
 257     if (vert_dist 
>= horiz_dist
) 
 259         if (winRect
.y 
< m_last3Rect
.y
) 
 266         if (winRect
.x 
< m_last3Rect
.x
) 
 272     m_last3Rect 
= m_last2Rect
; 
 273     m_last2Rect 
= m_lastRect
; 
 274     m_lastRect 
= winRect
; 
 285     if (m_last3Rect
.IsEmpty()) 
 288     if ( event
.GetEventType() == wxEVT_MOVING 
) 
 289         OnMoving(event
.GetRect(), dir
); 
 291         OnMoving(wxRect(event
.GetPosition(),GetSize()), dir
); 
 294 void wxAuiFloatingFrame::OnIdle(wxIdleEvent
& event
) 
 310 void wxAuiFloatingFrame::OnMoveStart() 
 312     // notify the owner manager that the pane has started to move 
 315         m_ownerMgr
->OnFloatingPaneMoveStart(m_paneWindow
); 
 319 void wxAuiFloatingFrame::OnMoving(const wxRect
& WXUNUSED(window_rect
), wxDirection dir
) 
 321     // notify the owner manager that the pane is moving 
 324         m_ownerMgr
->OnFloatingPaneMoving(m_paneWindow
, dir
); 
 326     m_lastDirection 
= dir
; 
 329 void wxAuiFloatingFrame::OnMoveFinished() 
 331     // notify the owner manager that the pane has finished moving 
 334         m_ownerMgr
->OnFloatingPaneMoved(m_paneWindow
, m_lastDirection
); 
 338 void wxAuiFloatingFrame::OnActivate(wxActivateEvent
& event
) 
 340     if (m_ownerMgr 
&& event
.GetActive()) 
 342         m_ownerMgr
->OnFloatingPaneActivated(m_paneWindow
); 
 346 // utility function which determines the state of the mouse button 
 347 // (independent of having a wxMouseEvent handy) - utimately a better 
 348 // mechanism for this should be found (possibly by adding the 
 349 // functionality to wxWidgets itself) 
 350 bool wxAuiFloatingFrame::isMouseDown() 
 352     return wxGetMouseState().LeftIsDown(); 
 356 BEGIN_EVENT_TABLE(wxAuiFloatingFrame
, wxAuiFloatingFrameBaseClass
) 
 357     EVT_SIZE(wxAuiFloatingFrame::OnSize
) 
 358     EVT_MOVE(wxAuiFloatingFrame::OnMoveEvent
) 
 359     EVT_MOVING(wxAuiFloatingFrame::OnMoveEvent
) 
 360     EVT_CLOSE(wxAuiFloatingFrame::OnClose
) 
 361     EVT_IDLE(wxAuiFloatingFrame::OnIdle
) 
 362     EVT_ACTIVATE(wxAuiFloatingFrame::OnActivate
)