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
); 
 150         SetWindowStyleFlag(GetWindowStyleFlag() & ~wxRESIZE_BORDER
); 
 154 wxAuiManager
* wxAuiFloatingFrame::GetOwnerManager() const 
 160 void wxAuiFloatingFrame::OnSize(wxSizeEvent
& event
) 
 164         m_owner_mgr
->OnFloatingPaneResized(m_pane_window
, event
.GetSize()); 
 168 void wxAuiFloatingFrame::OnClose(wxCloseEvent
& evt
) 
 172         m_owner_mgr
->OnFloatingPaneClosed(m_pane_window
, evt
); 
 176         m_mgr
.DetachPane(m_pane_window
); 
 181 void wxAuiFloatingFrame::OnMoveEvent(wxMoveEvent
& event
) 
 185         // systems without solid window dragging need to be 
 186         // handled slightly differently, due to the lack of 
 187         // the constant stream of EVT_MOVING events 
 191         OnMoving(event
.GetRect(), wxNORTH
); 
 197     wxRect win_rect 
= GetRect(); 
 199     if (win_rect 
== m_last_rect
) 
 202     // skip the first move event 
 203     if (m_last_rect
.IsEmpty()) 
 205         m_last_rect 
= win_rect
; 
 209     // skip if moving too fast to avoid massive redraws and 
 210     // jumping hint windows 
 211     if ((abs(win_rect
.x 
- m_last_rect
.x
) > 3) || 
 212         (abs(win_rect
.y 
- m_last_rect
.y
) > 3)) 
 214         m_last3_rect 
= m_last2_rect
; 
 215         m_last2_rect 
= m_last_rect
; 
 216         m_last_rect 
= win_rect
; 
 220     // prevent frame redocking during resize 
 221     if (m_last_rect
.GetSize() != win_rect
.GetSize()) 
 223         m_last3_rect 
= m_last2_rect
; 
 224         m_last2_rect 
= m_last_rect
; 
 225         m_last_rect 
= win_rect
; 
 229     wxDirection dir 
= wxALL
; 
 231     int horiz_dist 
= abs(win_rect
.x 
- m_last3_rect
.x
); 
 232     int vert_dist 
= abs(win_rect
.y 
- m_last3_rect
.y
); 
 234     if (vert_dist 
>= horiz_dist
) 
 236         if (win_rect
.y 
< m_last3_rect
.y
) 
 243         if (win_rect
.x 
< m_last3_rect
.x
) 
 249     m_last3_rect 
= m_last2_rect
; 
 250     m_last2_rect 
= m_last_rect
; 
 251     m_last_rect 
= win_rect
; 
 262     if (m_last3_rect
.IsEmpty()) 
 265     OnMoving(event
.GetRect(), dir
); 
 268 void wxAuiFloatingFrame::OnIdle(wxIdleEvent
& event
) 
 284 void wxAuiFloatingFrame::OnMoveStart() 
 286     // notify the owner manager that the pane has started to move 
 289         m_owner_mgr
->OnFloatingPaneMoveStart(m_pane_window
); 
 293 void wxAuiFloatingFrame::OnMoving(const wxRect
& WXUNUSED(window_rect
), wxDirection dir
) 
 295     // notify the owner manager that the pane is moving 
 298         m_owner_mgr
->OnFloatingPaneMoving(m_pane_window
, dir
); 
 300     m_lastDirection 
= dir
; 
 303 void wxAuiFloatingFrame::OnMoveFinished() 
 305     // notify the owner manager that the pane has finished moving 
 308         m_owner_mgr
->OnFloatingPaneMoved(m_pane_window
, m_lastDirection
); 
 312 void wxAuiFloatingFrame::OnActivate(wxActivateEvent
& event
) 
 314     if (m_owner_mgr 
&& event
.GetActive()) 
 316         m_owner_mgr
->OnFloatingPaneActivated(m_pane_window
); 
 320 // utility function which determines the state of the mouse button 
 321 // (independant of having a wxMouseEvent handy) - utimately a better 
 322 // mechanism for this should be found (possibly by adding the 
 323 // functionality to wxWidgets itself) 
 324 bool wxAuiFloatingFrame::isMouseDown() 
 326     return wxGetMouseState().LeftDown(); 
 330 BEGIN_EVENT_TABLE(wxAuiFloatingFrame
, wxAuiFloatingFrameBaseClass
) 
 331     EVT_SIZE(wxAuiFloatingFrame::OnSize
) 
 332     EVT_MOVE(wxAuiFloatingFrame::OnMoveEvent
) 
 333     EVT_MOVING(wxAuiFloatingFrame::OnMoveEvent
) 
 334     EVT_CLOSE(wxAuiFloatingFrame::OnClose
) 
 335     EVT_IDLE(wxAuiFloatingFrame::OnIdle
) 
 336     EVT_ACTIVATE(wxAuiFloatingFrame::OnActivate
)