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_owner_mgr 
= 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_solid_drag 
= 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_owner_mgr 
&& m_owner_mgr
->m_action_window 
== this) 
  78         m_owner_mgr
->m_action_window 
= NULL
; 
  84 void wxAuiFloatingFrame::SetPaneWindow(const wxAuiPaneInfo
& pane
) 
  86     m_pane_window 
= pane
.window
; 
  87     m_pane_window
->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_pane_window
, 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     if (pane
.floating_size 
!= wxDefaultSize
) 
 128         SetSize(pane
.floating_size
); 
 132         wxSize size 
= pane
.best_size
; 
 133         if (size 
== wxDefaultSize
) 
 134             size 
= pane
.min_size
; 
 135         if (size 
== wxDefaultSize
) 
 136             size 
= m_pane_window
->GetSize(); 
 137         if (m_owner_mgr 
&& pane
.HasGripper()) 
 139             if (pane
.HasGripperTop()) 
 140                 size
.y 
+= m_owner_mgr
->m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
 142                 size
.x 
+= m_owner_mgr
->m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
 149 wxAuiManager
* wxAuiFloatingFrame::GetOwnerManager() const 
 155 void wxAuiFloatingFrame::OnSize(wxSizeEvent
& event
) 
 159         m_owner_mgr
->OnFloatingPaneResized(m_pane_window
, event
.GetSize()); 
 163 void wxAuiFloatingFrame::OnClose(wxCloseEvent
& evt
) 
 167         m_owner_mgr
->OnFloatingPaneClosed(m_pane_window
, evt
); 
 171         m_mgr
.DetachPane(m_pane_window
); 
 176 void wxAuiFloatingFrame::OnMoveEvent(wxMoveEvent
& event
) 
 180         // systems without solid window dragging need to be 
 181         // handled slightly differently, due to the lack of 
 182         // the constant stream of EVT_MOVING events 
 186         OnMoving(event
.GetRect(), wxNORTH
); 
 192     wxRect win_rect 
= GetRect(); 
 194     if (win_rect 
== m_last_rect
) 
 197     // skip the first move event 
 198     if (m_last_rect
.IsEmpty()) 
 200         m_last_rect 
= win_rect
; 
 204     // skip if moving too fast to avoid massive redraws and 
 205     // jumping hint windows 
 206     if ((abs(win_rect
.x 
- m_last_rect
.x
) > 3) || 
 207         (abs(win_rect
.y 
- m_last_rect
.y
) > 3)) 
 209         m_last3_rect 
= m_last2_rect
; 
 210         m_last2_rect 
= m_last_rect
; 
 211         m_last_rect 
= win_rect
; 
 215     // prevent frame redocking during resize 
 216     if (m_last_rect
.GetSize() != win_rect
.GetSize()) 
 218         m_last3_rect 
= m_last2_rect
; 
 219         m_last2_rect 
= m_last_rect
; 
 220         m_last_rect 
= win_rect
; 
 224     wxDirection dir 
= wxALL
; 
 226     int horiz_dist 
= abs(win_rect
.x 
- m_last3_rect
.x
); 
 227     int vert_dist 
= abs(win_rect
.y 
- m_last3_rect
.y
); 
 229     if (vert_dist 
>= horiz_dist
) 
 231         if (win_rect
.y 
< m_last3_rect
.y
) 
 238         if (win_rect
.x 
< m_last3_rect
.x
) 
 244     m_last3_rect 
= m_last2_rect
; 
 245     m_last2_rect 
= m_last_rect
; 
 246     m_last_rect 
= win_rect
; 
 257     if (m_last3_rect
.IsEmpty()) 
 260     OnMoving(event
.GetRect(), dir
); 
 263 void wxAuiFloatingFrame::OnIdle(wxIdleEvent
& event
) 
 279 void wxAuiFloatingFrame::OnMoveStart() 
 281     // notify the owner manager that the pane has started to move 
 284         m_owner_mgr
->OnFloatingPaneMoveStart(m_pane_window
); 
 288 void wxAuiFloatingFrame::OnMoving(const wxRect
& WXUNUSED(window_rect
), wxDirection dir
) 
 290     // notify the owner manager that the pane is moving 
 293         m_owner_mgr
->OnFloatingPaneMoving(m_pane_window
, dir
); 
 295     m_lastDirection 
= dir
; 
 298 void wxAuiFloatingFrame::OnMoveFinished() 
 300     // notify the owner manager that the pane has finished moving 
 303         m_owner_mgr
->OnFloatingPaneMoved(m_pane_window
, m_lastDirection
); 
 307 void wxAuiFloatingFrame::OnActivate(wxActivateEvent
& event
) 
 309     if (m_owner_mgr 
&& event
.GetActive()) 
 311         m_owner_mgr
->OnFloatingPaneActivated(m_pane_window
); 
 315 // utility function which determines the state of the mouse button 
 316 // (independant of having a wxMouseEvent handy) - utimately a better 
 317 // mechanism for this should be found (possibly by adding the 
 318 // functionality to wxWidgets itself) 
 319 bool wxAuiFloatingFrame::isMouseDown() 
 321     return wxGetMouseState().LeftDown(); 
 325 BEGIN_EVENT_TABLE(wxAuiFloatingFrame
, wxAuiFloatingFrameBaseClass
) 
 326     EVT_SIZE(wxAuiFloatingFrame::OnSize
) 
 327     EVT_MOVE(wxAuiFloatingFrame::OnMoveEvent
) 
 328     EVT_MOVING(wxAuiFloatingFrame::OnMoveEvent
) 
 329     EVT_CLOSE(wxAuiFloatingFrame::OnClose
) 
 330     EVT_IDLE(wxAuiFloatingFrame::OnIdle
) 
 331     EVT_ACTIVATE(wxAuiFloatingFrame::OnActivate
)