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
; 
  83 void wxAuiFloatingFrame::SetPaneWindow(const wxAuiPaneInfo
& pane
) 
  85     m_pane_window 
= pane
.window
; 
  86     m_pane_window
->Reparent(this); 
  88     wxAuiPaneInfo contained_pane 
= pane
; 
  89     contained_pane
.Dock().Center().Show(). 
  90                     CaptionVisible(false). 
  92                     Layer(0).Row(0).Position(0); 
  94     // Carry over the minimum size 
  95     wxSize pane_min_size 
= pane
.window
->GetMinSize(); 
  97     // if the frame window's max size is greater than the min size 
  98     // then set the max size to the min size as well 
  99     wxSize cur_max_size 
= GetMaxSize(); 
 100     if (cur_max_size
.x 
< pane
.min_size
.x 
|| 
 101         cur_max_size
.y 
< pane
.min_size
.y
) 
 103         SetMaxSize(pane_min_size
); 
 106     SetMinSize(pane
.window
->GetMinSize()); 
 108     m_mgr
.AddPane(m_pane_window
, contained_pane
); 
 111     if (pane
.min_size
.IsFullySpecified()) 
 113         // because SetSizeHints() calls Fit() too (which sets the window 
 114         // size to its minimum allowed), we keep the size before calling 
 115         // SetSizeHints() and reset it afterwards... 
 116         wxSize tmp 
= GetSize(); 
 117         GetSizer()->SetSizeHints(this); 
 121     SetTitle(pane
.caption
); 
 123     if (pane
.floating_size 
!= wxDefaultSize
) 
 125         SetSize(pane
.floating_size
); 
 129         wxSize size 
= pane
.best_size
; 
 130         if (size 
== wxDefaultSize
) 
 131             size 
= pane
.min_size
; 
 132         if (size 
== wxDefaultSize
) 
 133             size 
= m_pane_window
->GetSize(); 
 134         if (pane
.HasGripper()) 
 136             if (pane
.HasGripperTop()) 
 137                 size
.y 
+= m_owner_mgr
->m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
 139                 size
.x 
+= m_owner_mgr
->m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
 146 wxAuiManager
* wxAuiFloatingFrame::GetOwnerManager() const 
 152 void wxAuiFloatingFrame::OnSize(wxSizeEvent
& event
) 
 154     m_owner_mgr
->OnFloatingPaneResized(m_pane_window
, event
.GetSize()); 
 157 void wxAuiFloatingFrame::OnClose(wxCloseEvent
& evt
) 
 159     m_owner_mgr
->OnFloatingPaneClosed(m_pane_window
, evt
); 
 164 void wxAuiFloatingFrame::OnMoveEvent(wxMoveEvent
& event
) 
 168         // systems without solid window dragging need to be 
 169         // handled slightly differently, due to the lack of 
 170         // the constant stream of EVT_MOVING events 
 174         OnMoving(event
.GetRect(), wxNORTH
); 
 180     wxRect win_rect 
= GetRect(); 
 182     if (win_rect 
== m_last_rect
) 
 185     // skip the first move event 
 186     if (m_last_rect
.IsEmpty()) 
 188         m_last_rect 
= win_rect
; 
 192     // skip if moving too fast to avoid massive redraws and  
 193     // jumping hint windows 
 194     if ((abs(win_rect
.x 
- m_last_rect
.x
) > 3) || 
 195         (abs(win_rect
.y 
- m_last_rect
.y
) > 3)) 
 197         m_last3_rect 
= m_last2_rect
; 
 198         m_last2_rect 
= m_last_rect
; 
 199         m_last_rect 
= win_rect
; 
 203     // prevent frame redocking during resize 
 204     if (m_last_rect
.GetSize() != win_rect
.GetSize()) 
 206         m_last3_rect 
= m_last2_rect
; 
 207         m_last2_rect 
= m_last_rect
; 
 208         m_last_rect 
= win_rect
; 
 212     wxDirection dir 
= wxALL
; 
 214     int horiz_dist 
= abs(win_rect
.x 
- m_last3_rect
.x
); 
 215     int vert_dist 
= abs(win_rect
.y 
- m_last3_rect
.y
); 
 217     if (vert_dist 
>= horiz_dist
) 
 219         if (win_rect
.y 
< m_last3_rect
.y
) 
 226         if (win_rect
.x 
< m_last3_rect
.x
) 
 232     m_last3_rect 
= m_last2_rect
; 
 233     m_last2_rect 
= m_last_rect
; 
 234     m_last_rect 
= win_rect
; 
 245     if (m_last3_rect
.IsEmpty()) 
 248     OnMoving(event
.GetRect(), dir
); 
 251 void wxAuiFloatingFrame::OnIdle(wxIdleEvent
& event
) 
 267 void wxAuiFloatingFrame::OnMoveStart() 
 269     // notify the owner manager that the pane has started to move 
 270     m_owner_mgr
->OnFloatingPaneMoveStart(m_pane_window
); 
 273 void wxAuiFloatingFrame::OnMoving(const wxRect
& WXUNUSED(window_rect
), wxDirection dir
) 
 275     // notify the owner manager that the pane is moving 
 276     m_owner_mgr
->OnFloatingPaneMoving(m_pane_window
, dir
); 
 277     m_lastDirection 
= dir
; 
 280 void wxAuiFloatingFrame::OnMoveFinished() 
 282     // notify the owner manager that the pane has finished moving 
 283     m_owner_mgr
->OnFloatingPaneMoved(m_pane_window
, m_lastDirection
); 
 286 void wxAuiFloatingFrame::OnActivate(wxActivateEvent
& event
) 
 288     if (event
.GetActive()) 
 290         m_owner_mgr
->OnFloatingPaneActivated(m_pane_window
); 
 294 // utility function which determines the state of the mouse button 
 295 // (independant of having a wxMouseEvent handy) - utimately a better 
 296 // mechanism for this should be found (possibly by adding the 
 297 // functionality to wxWidgets itself) 
 298 bool wxAuiFloatingFrame::isMouseDown() 
 300     return wxGetMouseState().LeftDown(); 
 304 BEGIN_EVENT_TABLE(wxAuiFloatingFrame
, wxAuiFloatingFrameBaseClass
) 
 305     EVT_SIZE(wxAuiFloatingFrame::OnSize
) 
 306     EVT_MOVE(wxAuiFloatingFrame::OnMoveEvent
) 
 307     EVT_MOVING(wxAuiFloatingFrame::OnMoveEvent
) 
 308     EVT_CLOSE(wxAuiFloatingFrame::OnClose
) 
 309     EVT_IDLE(wxAuiFloatingFrame::OnIdle
) 
 310     EVT_ACTIVATE(wxAuiFloatingFrame::OnActivate
)