1/////////////////////////////////////////////////////////////////////////////// 2// Name: src/aui/floatpane.cpp 3// Purpose: wxaui: wx advanced user interface - docking window manager 4// Author: Benjamin I. Williams 5// Modified by: 6// Created: 2005-05-17 7// RCS-ID: $Id: floatpane.cpp 54904 2008-08-01 16:07:46Z BIW $ 8// Copyright: (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved 9// Licence: wxWindows Library Licence, Version 3.1 10/////////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// ---------------------------------------------------------------------------- 17// headers 18// ---------------------------------------------------------------------------- 19 20#include "wx/wxprec.h" 21 22#ifdef __BORLANDC__ 23 #pragma hdrstop 24#endif 25 26#if wxUSE_AUI 27 28#include "wx/aui/framemanager.h" 29#include "wx/aui/floatpane.h" 30#include "wx/aui/dockart.h" 31 32#ifndef WX_PRECOMP 33#endif 34 35#ifdef __WXMSW__ 36#include "wx/msw/private.h" 37#endif 38 39IMPLEMENT_CLASS(wxAuiFloatingFrame, wxAuiFloatingFrameBaseClass) 40 41wxAuiFloatingFrame::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 | 47 wxCLIP_CHILDREN 48 */) 49 : wxAuiFloatingFrameBaseClass(parent, id, wxEmptyString, 50 pane.floating_pos, pane.floating_size, 51 style | 52 (pane.HasCloseButton()?wxCLOSE_BOX:0) | 53 (pane.HasMaximizeButton()?wxMAXIMIZE_BOX:0) | 54 (pane.IsFixed()?0:wxRESIZE_BORDER) 55 ) 56{ 57 m_owner_mgr = owner_mgr; 58 m_moving = false; 59 m_mgr.SetManagedWindow(this); 60 m_solid_drag = true; 61 62 // find out if the system supports solid window drag. 63 // on non-msw systems, this is assumed to be the case 64#ifdef __WXMSW__ 65 BOOL b = TRUE; 66 SystemParametersInfo(38 /*SPI_GETDRAGFULLWINDOWS*/, 0, &b, 0); 67 m_solid_drag = b ? true : false; 68#endif 69 70 SetExtraStyle(wxWS_EX_PROCESS_IDLE); 71} 72 73wxAuiFloatingFrame::~wxAuiFloatingFrame() 74{ 75 // if we do not do this, then we can crash... 76 if(m_owner_mgr && m_owner_mgr->m_action_window == this) 77 { 78 m_owner_mgr->m_action_window = NULL; 79 } 80 m_mgr.UnInit(); 81} 82 83void wxAuiFloatingFrame::SetPaneWindow(const wxAuiPaneInfo& pane) 84{ 85 m_pane_window = pane.window; 86 m_pane_window->Reparent(this); 87 88 wxAuiPaneInfo contained_pane = pane; 89 contained_pane.Dock().Center().Show(). 90 CaptionVisible(false). 91 PaneBorder(false). 92 Layer(0).Row(0).Position(0); 93 94 // Carry over the minimum size 95 wxSize pane_min_size = pane.window->GetMinSize(); 96 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.IsFullySpecified() && 101 (cur_max_size.x < pane.min_size.x || 102 cur_max_size.y < pane.min_size.y) 103 ) 104 { 105 SetMaxSize(pane_min_size); 106 } 107 108 SetMinSize(pane.window->GetMinSize()); 109 110 m_mgr.AddPane(m_pane_window, contained_pane); 111 m_mgr.Update(); 112 113 if (pane.min_size.IsFullySpecified()) 114 { 115 // because SetSizeHints() calls Fit() too (which sets the window 116 // size to its minimum allowed), we keep the size before calling 117 // SetSizeHints() and reset it afterwards... 118 wxSize tmp = GetSize(); 119 GetSizer()->SetSizeHints(this); 120 SetSize(tmp); 121 } 122 123 SetTitle(pane.caption); 124 125 if (pane.floating_size != wxDefaultSize) 126 { 127 SetSize(pane.floating_size); 128 } 129 else 130 { 131 wxSize size = pane.best_size; 132 if (size == wxDefaultSize) 133 size = pane.min_size; 134 if (size == wxDefaultSize) 135 size = m_pane_window->GetSize(); 136 if (pane.HasGripper()) 137 { 138 if (pane.HasGripperTop()) 139 size.y += m_owner_mgr->m_art->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE); 140 else 141 size.x += m_owner_mgr->m_art->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE); 142 } 143 144 SetClientSize(size); 145 } 146 147 if (pane.IsFixed()) 148 { 149 SetWindowStyleFlag(GetWindowStyleFlag() & ~wxRESIZE_BORDER); 150 } 151} 152 153wxAuiManager* wxAuiFloatingFrame::GetOwnerManager() const 154{ 155 return m_owner_mgr; 156} 157 158 159void wxAuiFloatingFrame::OnSize(wxSizeEvent& event) 160{ 161 m_owner_mgr->OnFloatingPaneResized(m_pane_window, event.GetSize()); 162} 163 164void wxAuiFloatingFrame::OnClose(wxCloseEvent& evt) 165{ 166 m_owner_mgr->OnFloatingPaneClosed(m_pane_window, evt); 167 if (!evt.GetVeto()) { 168 m_mgr.DetachPane(m_pane_window); 169 Destroy(); 170 } 171} 172 173void wxAuiFloatingFrame::OnMoveEvent(wxMoveEvent& event) 174{ 175 if (!m_solid_drag) 176 { 177 // systems without solid window dragging need to be 178 // handled slightly differently, due to the lack of 179 // the constant stream of EVT_MOVING events 180 if (!isMouseDown()) 181 return; 182 OnMoveStart(); 183 OnMoving(event.GetRect(), wxNORTH); 184 m_moving = true; 185 return; 186 } 187 188 189 wxRect win_rect = GetRect(); 190 191 if (win_rect == m_last_rect) 192 return; 193 194 // skip the first move event 195 if (m_last_rect.IsEmpty()) 196 { 197 m_last_rect = win_rect; 198 return; 199 } 200 201 // skip if moving too fast to avoid massive redraws and 202 // jumping hint windows 203 if ((abs(win_rect.x - m_last_rect.x) > 3) || 204 (abs(win_rect.y - m_last_rect.y) > 3)) 205 { 206 m_last3_rect = m_last2_rect; 207 m_last2_rect = m_last_rect; 208 m_last_rect = win_rect; 209 return; 210 } 211 212 // prevent frame redocking during resize 213 if (m_last_rect.GetSize() != win_rect.GetSize()) 214 { 215 m_last3_rect = m_last2_rect; 216 m_last2_rect = m_last_rect; 217 m_last_rect = win_rect; 218 return; 219 } 220 221 wxDirection dir = wxALL; 222 223 int horiz_dist = abs(win_rect.x - m_last3_rect.x); 224 int vert_dist = abs(win_rect.y - m_last3_rect.y); 225 226 if (vert_dist >= horiz_dist) 227 { 228 if (win_rect.y < m_last3_rect.y) 229 dir = wxNORTH; 230 else 231 dir = wxSOUTH; 232 } 233 else 234 { 235 if (win_rect.x < m_last3_rect.x) 236 dir = wxWEST; 237 else 238 dir = wxEAST; 239 } 240 241 m_last3_rect = m_last2_rect; 242 m_last2_rect = m_last_rect; 243 m_last_rect = win_rect; 244 245 if (!isMouseDown()) 246 return; 247 248 if (!m_moving) 249 { 250 OnMoveStart(); 251 m_moving = true; 252 } 253 254 if (m_last3_rect.IsEmpty()) 255 return; 256 257 OnMoving(event.GetRect(), dir); 258} 259 260void wxAuiFloatingFrame::OnIdle(wxIdleEvent& event) 261{ 262 if (m_moving) 263 { 264 if (!isMouseDown()) 265 { 266 m_moving = false; 267 OnMoveFinished(); 268 } 269 else 270 { 271 event.RequestMore(); 272 } 273 } 274} 275 276void wxAuiFloatingFrame::OnMoveStart() 277{ 278 // notify the owner manager that the pane has started to move 279 m_owner_mgr->OnFloatingPaneMoveStart(m_pane_window); 280} 281 282void wxAuiFloatingFrame::OnMoving(const wxRect& WXUNUSED(window_rect), wxDirection dir) 283{ 284 // notify the owner manager that the pane is moving 285 m_owner_mgr->OnFloatingPaneMoving(m_pane_window, dir); 286 m_lastDirection = dir; 287} 288 289void wxAuiFloatingFrame::OnMoveFinished() 290{ 291 // notify the owner manager that the pane has finished moving 292 m_owner_mgr->OnFloatingPaneMoved(m_pane_window, m_lastDirection); 293} 294 295void wxAuiFloatingFrame::OnActivate(wxActivateEvent& event) 296{ 297 if (event.GetActive()) 298 { 299 m_owner_mgr->OnFloatingPaneActivated(m_pane_window); 300 } 301} 302 303// utility function which determines the state of the mouse button 304// (independant of having a wxMouseEvent handy) - utimately a better 305// mechanism for this should be found (possibly by adding the 306// functionality to wxWidgets itself) 307bool wxAuiFloatingFrame::isMouseDown() 308{ 309 return wxGetMouseState().LeftDown(); 310} 311 312 313BEGIN_EVENT_TABLE(wxAuiFloatingFrame, wxAuiFloatingFrameBaseClass) 314 EVT_SIZE(wxAuiFloatingFrame::OnSize) 315 EVT_MOVE(wxAuiFloatingFrame::OnMoveEvent) 316 EVT_MOVING(wxAuiFloatingFrame::OnMoveEvent) 317 EVT_CLOSE(wxAuiFloatingFrame::OnClose) 318 EVT_IDLE(wxAuiFloatingFrame::OnIdle) 319 EVT_ACTIVATE(wxAuiFloatingFrame::OnActivate) 320END_EVENT_TABLE() 321 322 323#endif // wxUSE_AUI 324