From: Robert Roebling Date: Wed, 23 Aug 2006 11:17:13 +0000 (+0000) Subject: Added direction sensitive docking. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/322c5ec4c0f5df842ac82c17274dbd2191b021a6 Added direction sensitive docking. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40769 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/aui/floatpane.h b/include/wx/aui/floatpane.h index d2ef1b0600..41678295a3 100644 --- a/include/wx/aui/floatpane.h +++ b/include/wx/aui/floatpane.h @@ -45,7 +45,7 @@ private: void OnMoveEvent(wxMoveEvent& event); void OnIdle(wxIdleEvent& event); void OnMoveStart(); - void OnMoving(const wxRect& window_rect); + void OnMoving(const wxRect& window_rect, wxDirection dir); void OnMoveFinished(); void OnActivate(wxActivateEvent& event); static bool isMouseDown(); @@ -53,7 +53,10 @@ private: wxWindow* m_pane_window; // pane window being managed bool m_moving; wxRect m_last_rect; + wxRect m_last2_rect; + wxRect m_last3_rect; wxSize m_last_size; + wxDirection m_lastDirection; wxFrameManager* m_owner_mgr; wxFrameManager m_mgr; diff --git a/include/wx/aui/framemanager.h b/include/wx/aui/framemanager.h index d91bc6e60f..c613ceaa3e 100644 --- a/include/wx/aui/framemanager.h +++ b/include/wx/aui/framemanager.h @@ -492,8 +492,8 @@ protected: wxDockUIPart* GetPanePart(wxWindow* pane); int GetDockPixelOffset(wxPaneInfo& test); void OnFloatingPaneMoveStart(wxWindow* window); - void OnFloatingPaneMoving(wxWindow* window); - void OnFloatingPaneMoved(wxWindow* window); + void OnFloatingPaneMoving(wxWindow* window, wxDirection dir ); + void OnFloatingPaneMoved(wxWindow* window, wxDirection dir); void OnFloatingPaneActivated(wxWindow* window); void OnFloatingPaneClosed(wxWindow* window, wxCloseEvent& evt); void OnFloatingPaneResized(wxWindow* window, const wxSize& size); diff --git a/src/aui/floatpane.cpp b/src/aui/floatpane.cpp index bc8e52be6e..d8e436dc26 100644 --- a/src/aui/floatpane.cpp +++ b/src/aui/floatpane.cpp @@ -49,9 +49,8 @@ wxFloatingPane::wxFloatingPane(wxWindow* parent, { m_owner_mgr = owner_mgr; m_moving = false; - m_last_rect = wxRect(); m_mgr.SetManagedWindow(this); - // SetExtraStyle(wxWS_EX_PROCESS_IDLE); + SetExtraStyle(wxWS_EX_PROCESS_IDLE); } wxFloatingPane::~wxFloatingPane() @@ -127,6 +126,9 @@ void wxFloatingPane::OnMoveEvent(wxMoveEvent& event) { wxRect win_rect = GetRect(); + if (win_rect == m_last_rect) + return; + // skip the first move event if (m_last_rect.IsEmpty()) { @@ -134,10 +136,13 @@ void wxFloatingPane::OnMoveEvent(wxMoveEvent& event) return; } - // skip if moving fast - if ((abs(win_rect.x - m_last_rect.x) > 1) || - (abs(win_rect.y - m_last_rect.y) > 1)) + // skip if moving too fast to avoid massive redraws and + // jumping hint windows + if ((abs(win_rect.x - m_last_rect.x) > 3) || + (abs(win_rect.y - m_last_rect.y) > 3)) { + m_last3_rect = m_last2_rect; + m_last2_rect = m_last_rect; m_last_rect = win_rect; return; } @@ -145,10 +150,34 @@ void wxFloatingPane::OnMoveEvent(wxMoveEvent& event) // prevent frame redocking during resize if (m_last_rect.GetSize() != win_rect.GetSize()) { + m_last3_rect = m_last2_rect; + m_last2_rect = m_last_rect; m_last_rect = win_rect; return; } + wxDirection dir = wxALL; + + int horiz_dist = abs(win_rect.x - m_last3_rect.x); + int vert_dist = abs(win_rect.y - m_last3_rect.y); + + if (vert_dist >= horiz_dist) + { + if (win_rect.y < m_last3_rect.y) + dir = wxNORTH; + else + dir = wxSOUTH; + } + else + { + if (win_rect.x < m_last3_rect.x) + dir = wxWEST; + else + dir = wxEAST; + } + + m_last3_rect = m_last2_rect; + m_last2_rect = m_last_rect; m_last_rect = win_rect; if (!isMouseDown()) @@ -160,7 +189,10 @@ void wxFloatingPane::OnMoveEvent(wxMoveEvent& event) m_moving = true; } - OnMoving(event.GetRect()); + if (m_last3_rect.IsEmpty()) + return; + + OnMoving(event.GetRect(), dir ); } void wxFloatingPane::OnIdle(wxIdleEvent& event) @@ -185,16 +217,17 @@ void wxFloatingPane::OnMoveStart() m_owner_mgr->OnFloatingPaneMoveStart(m_pane_window); } -void wxFloatingPane::OnMoving(const wxRect& WXUNUSED(window_rect)) +void wxFloatingPane::OnMoving(const wxRect& WXUNUSED(window_rect), wxDirection dir) { // notify the owner manager that the pane is moving - m_owner_mgr->OnFloatingPaneMoving(m_pane_window); + m_owner_mgr->OnFloatingPaneMoving(m_pane_window, dir); + m_lastDirection = dir; } void wxFloatingPane::OnMoveFinished() { // notify the owner manager that the pane has finished moving - m_owner_mgr->OnFloatingPaneMoved(m_pane_window); + m_owner_mgr->OnFloatingPaneMoved(m_pane_window, m_lastDirection); } void wxFloatingPane::OnActivate(wxActivateEvent& event) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 45f36c9967..2b42cb8f8e 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -2874,13 +2874,48 @@ void wxFrameManager::OnFloatingPaneMoveStart(wxWindow* wnd) #endif } -void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) +void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd, wxDirection dir) { // try to find the pane wxPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); wxPoint pt = ::wxGetMousePosition(); + +#if 1 + // Adapt pt to direction + if (dir == wxNORTH) + { + // move to pane's upper border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + // and some more pixels for the title bar + pt.y -= 5; + } else + if (dir == wxWEST) + { + // move to pane's left border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxEAST) + { + // move to pane's right border + wxPoint pos( wnd->GetSize().x, 0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxSOUTH) + { + // move to pane's bottom border + wxPoint pos( 0, wnd->GetSize().y ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + } +#endif + wxPoint client_pt = m_frame->ScreenToClient(pt); // calculate the offset from the upper left-hand corner @@ -2940,13 +2975,48 @@ void wxFrameManager::OnFloatingPaneMoving(wxWindow* wnd) m_frame->Update(); } -void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd) +void wxFrameManager::OnFloatingPaneMoved(wxWindow* wnd, wxDirection dir) { // try to find the pane wxPaneInfo& pane = GetPane(wnd); wxASSERT_MSG(pane.IsOk(), wxT("Pane window not found")); wxPoint pt = ::wxGetMousePosition(); + +#if 1 + // Adapt pt to direction + if (dir == wxNORTH) + { + // move to pane's upper border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + // and some more pixels for the title bar + pt.y -= 10; + } else + if (dir == wxWEST) + { + // move to pane's left border + wxPoint pos( 0,0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxEAST) + { + // move to pane's right border + wxPoint pos( wnd->GetSize().x, 0 ); + pos = wnd->ClientToScreen( pos ); + pt.x = pos.x; + } else + if (dir == wxSOUTH) + { + // move to pane's bottom border + wxPoint pos( 0, wnd->GetSize().y ); + pos = wnd->ClientToScreen( pos ); + pt.y = pos.y; + } +#endif + wxPoint client_pt = m_frame->ScreenToClient(pt); // calculate the offset from the upper left-hand corner