X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/448af9a46eb58ae17616a4d5e76884dc519f5523..2c304d0a33614d1806dc3fcd9e8054e5881f8c1c:/src/generic/sashwin.cpp diff --git a/src/generic/sashwin.cpp b/src/generic/sashwin.cpp index 18b56afa7b..ad855afdbc 100644 --- a/src/generic/sashwin.cpp +++ b/src/generic/sashwin.cpp @@ -8,10 +8,10 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "sashwin.h" #endif @@ -22,23 +22,23 @@ #pragma hdrstop #endif +#if wxUSE_SASH + #ifndef WX_PRECOMP -#include "wx/wx.h" + #include "wx/dialog.h" + #include "wx/frame.h" + #include "wx/settings.h" #endif -#if !wxUSE_SASH - #error "Thisfile requires wxUSE_SASH to be defined." -#endif // wxUSE_SASH - #include #include -#include "wx/string.h" #include "wx/dcscreen.h" #include "wx/sashwin.h" #include "wx/laywin.h" -#if !USE_SHARED_LIBRARY +DEFINE_EVENT_TYPE(wxEVT_SASH_DRAGGED) + IMPLEMENT_DYNAMIC_CLASS(wxSashWindow, wxWindow) IMPLEMENT_DYNAMIC_CLASS(wxSashEvent, wxCommandEvent) @@ -46,31 +46,25 @@ BEGIN_EVENT_TABLE(wxSashWindow, wxWindow) EVT_PAINT(wxSashWindow::OnPaint) EVT_SIZE(wxSashWindow::OnSize) EVT_MOUSE_EVENTS(wxSashWindow::OnMouseEvent) +#if defined( __WXMSW__ ) || defined( __WXMAC__) + EVT_SET_CURSOR(wxSashWindow::OnSetCursor) +#endif // wxMSW + END_EVENT_TABLE() -#endif -wxSashWindow::wxSashWindow() +bool wxSashWindow::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, + const wxSize& size, long style, const wxString& name) { - m_draggingEdge = wxSASH_NONE; - m_dragMode = wxSASH_DRAG_NONE; - m_oldX = 0; - m_oldY = 0; - m_firstX = 0; - m_firstY = 0; - m_borderSize = 3 ; - m_extraBorderSize = 0; - m_sashCursorWE = NULL; - m_sashCursorNS = NULL; + return wxWindow::Create(parent, id, pos, size, style, name); +} - m_minimumPaneSizeX = 0; - m_minimumPaneSizeY = 0; - m_maximumPaneSizeX = 10000; - m_maximumPaneSizeY = 10000; +wxSashWindow::~wxSashWindow() +{ + delete m_sashCursorWE; + delete m_sashCursorNS; } -wxSashWindow::wxSashWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos, - const wxSize& size, long style, const wxString& name) - :wxWindow(parent, id, pos, size, style, name) +void wxSashWindow::Init() { m_draggingEdge = wxSASH_NONE; m_dragMode = wxSASH_DRAG_NONE; @@ -86,48 +80,35 @@ wxSashWindow::wxSashWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos, m_maximumPaneSizeY = 10000; m_sashCursorWE = new wxCursor(wxCURSOR_SIZEWE); m_sashCursorNS = new wxCursor(wxCURSOR_SIZENS); + m_mouseCaptured = false; + m_currentCursor = NULL; // Eventually, we'll respond to colour change messages InitColours(); } -wxSashWindow::~wxSashWindow() -{ - delete m_sashCursorWE; - delete m_sashCursorNS; -} - void wxSashWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); - // if ( m_borderSize > 0 ) DrawBorders(dc); - DrawSashes(dc); } void wxSashWindow::OnMouseEvent(wxMouseEvent& event) { - long x, y; - event.Position(&x, &y); + wxCoord x, y; + event.GetPosition(&x, &y); wxSashEdgePosition sashHit = SashHitTest(x, y); - // reset the cursor -#ifdef __WXMOTIF__ - SetCursor(* wxSTANDARD_CURSOR); -#endif -#ifdef __WXMSW__ - SetCursor(wxCursor()); -#endif - if (event.LeftDown()) { + CaptureMouse(); + m_mouseCaptured = true; + if ( sashHit != wxSASH_NONE ) { - CaptureMouse(); - // Required for X to specify that // that we wish to draw on top of all windows // - and we optimise by specifying the area @@ -149,12 +130,32 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) m_draggingEdge = sashHit; m_firstX = x; m_firstY = y; + + if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) ) + { + if (m_currentCursor != m_sashCursorWE) + { + SetCursor(*m_sashCursorWE); + } + m_currentCursor = m_sashCursorWE; + } + else + { + if (m_currentCursor != m_sashCursorNS) + { + SetCursor(*m_sashCursorNS); + } + m_currentCursor = m_sashCursorNS; + } } } else if ( event.LeftUp() && m_dragMode == wxSASH_DRAG_LEFT_DOWN ) { // Wasn't a proper drag - ReleaseMouse(); + if (m_mouseCaptured) + ReleaseMouse(); + m_mouseCaptured = false; + wxScreenDC::EndDrawingOnTop(); m_dragMode = wxSASH_DRAG_NONE; m_draggingEdge = wxSASH_NONE; @@ -163,7 +164,10 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) { // We can stop dragging now and see what we've got. m_dragMode = wxSASH_DRAG_NONE; - ReleaseMouse(); + if (m_mouseCaptured) + ReleaseMouse(); + m_mouseCaptured = false; + // Erase old tracker DrawSashTracker(m_draggingEdge, m_oldX, m_oldY); @@ -183,8 +187,8 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) wxSashDragStatus status = wxSASH_STATUS_OK; // the new height and width of the window - if -1, it didn't change - int newHeight = -1, - newWidth = -1; + int newHeight = wxDefaultCoord, + newWidth = wxDefaultCoord; // NB: x and y may be negative and they're relative to the sash window // upper left corner, while xp and yp are expressed in the parent @@ -249,7 +253,7 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) break; } - if ( newHeight == -1 ) + if ( newHeight == wxDefaultCoord ) { // didn't change newHeight = h; @@ -261,7 +265,7 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) newHeight = wxMin(newHeight, m_maximumPaneSizeY); } - if ( newWidth == -1 ) + if ( newWidth == wxDefaultCoord ) { // didn't change newWidth = w; @@ -281,6 +285,12 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) event.SetDragRect(dragRect); GetEventHandler()->ProcessEvent(event); } + else if ( event.LeftUp() ) + { + if (m_mouseCaptured) + ReleaseMouse(); + m_mouseCaptured = false; + } else if (event.Moving() && !event.Dragging()) { // Just change the cursor if required @@ -288,13 +298,26 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) { if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) ) { - SetCursor(*m_sashCursorWE); + if (m_currentCursor != m_sashCursorWE) + { + SetCursor(*m_sashCursorWE); + } + m_currentCursor = m_sashCursorWE; } else { - SetCursor(*m_sashCursorNS); + if (m_currentCursor != m_sashCursorNS) + { + SetCursor(*m_sashCursorNS); + } + m_currentCursor = m_sashCursorNS; } } + else + { + SetCursor(wxNullCursor); + m_currentCursor = NULL; + } } else if ( event.Dragging() && ((m_dragMode == wxSASH_DRAG_DRAGGING) || @@ -302,11 +325,19 @@ void wxSashWindow::OnMouseEvent(wxMouseEvent& event) { if ( (m_draggingEdge == wxSASH_LEFT) || (m_draggingEdge == wxSASH_RIGHT) ) { - SetCursor(*m_sashCursorWE); + if (m_currentCursor != m_sashCursorWE) + { + SetCursor(*m_sashCursorWE); + } + m_currentCursor = m_sashCursorWE; } else { - SetCursor(*m_sashCursorNS); + if (m_currentCursor != m_sashCursorNS) + { + SetCursor(*m_sashCursorNS); + } + m_currentCursor = m_sashCursorNS; } if (m_dragMode == wxSASH_DRAG_LEFT_DOWN) @@ -402,7 +433,7 @@ void wxSashWindow::DrawBorders(wxDC& dc) wxPen lightShadowPen(m_lightShadowColour, 1, wxSOLID); wxPen hilightPen(m_hilightColour, 1, wxSOLID); - if ( GetWindowStyleFlag() & wxSW_3D ) + if ( GetWindowStyleFlag() & wxSW_3DBORDER ) { dc.SetPen(mediumShadowPen); dc.DrawLine(0, 0, w-1, 0); @@ -457,61 +488,53 @@ void wxSashWindow::DrawSash(wxSashEdgePosition edge, wxDC& dc) if ( edge == wxSASH_LEFT || edge == wxSASH_RIGHT ) { - int sashPosition = 0; - if (edge == wxSASH_LEFT) - sashPosition = 0; - else - sashPosition = w - GetEdgeMargin(edge); + int sashPosition = (edge == wxSASH_LEFT) ? 0 : ( w - GetEdgeMargin(edge) ); dc.SetPen(facePen); dc.SetBrush(faceBrush); dc.DrawRectangle(sashPosition, 0, GetEdgeMargin(edge), h); - if (GetWindowStyleFlag() & wxSW_3D) + if (GetWindowStyleFlag() & wxSW_3DSASH) { if (edge == wxSASH_LEFT) { - // Draw a black line on the left to indicate that the + // Draw a dark grey line on the left to indicate that the // sash is raised - dc.SetPen(blackPen); + dc.SetPen(mediumShadowPen); dc.DrawLine(GetEdgeMargin(edge), 0, GetEdgeMargin(edge), h); } else { - // Draw a white line on the right to indicate that the + // Draw a highlight line on the right to indicate that the // sash is raised - dc.SetPen(whitePen); + dc.SetPen(hilightPen); dc.DrawLine(w - GetEdgeMargin(edge), 0, w - GetEdgeMargin(edge), h); } } } else // top or bottom { - int sashPosition = 0; - if (edge == wxSASH_TOP) - sashPosition = 0; - else - sashPosition = h - GetEdgeMargin(edge); + int sashPosition = (edge == wxSASH_TOP) ? 0 : ( h - GetEdgeMargin(edge) ); dc.SetPen(facePen); dc.SetBrush(faceBrush); dc.DrawRectangle(0, sashPosition, w, GetEdgeMargin(edge)); - if (GetWindowStyleFlag() & wxSW_3D) + if (GetWindowStyleFlag() & wxSW_3DSASH) { if (edge == wxSASH_BOTTOM) { - // Draw a black line on the bottom to indicate that the + // Draw a highlight line on the bottom to indicate that the // sash is raised - dc.SetPen(blackPen); + dc.SetPen(hilightPen); dc.DrawLine(0, h - GetEdgeMargin(edge), w, h - GetEdgeMargin(edge)); } else { - // Draw a white line on the top to indicate that the + // Draw a drak grey line on the top to indicate that the // sash is raised - dc.SetPen(whitePen); - dc.DrawLine(0, GetEdgeMargin(edge), w, GetEdgeMargin(edge)); + dc.SetPen(mediumShadowPen); + dc.DrawLine(1, GetEdgeMargin(edge), w-1, GetEdgeMargin(edge)); } } } @@ -586,9 +609,9 @@ void wxSashWindow::SizeWindows() int cw, ch; GetClientSize(&cw, &ch); - if (GetChildren().Number() == 1) + if (GetChildren().GetCount() == 1) { - wxWindow* child = (wxWindow*) (GetChildren().First()->Data()); + wxWindow* child = GetChildren().GetFirst()->GetData(); int x = 0; int y = 0; @@ -627,7 +650,7 @@ void wxSashWindow::SizeWindows() child->SetSize(x, y, width, height); } - else if (GetChildren().Number() > 1) + else if (GetChildren().GetCount() > 1) { // Perhaps multiple children are themselves sash windows. // TODO: this doesn't really work because the subwindows sizes/positions @@ -647,19 +670,11 @@ void wxSashWindow::SizeWindows() void wxSashWindow::InitColours() { // Shadow colours -#if defined(__WIN95__) - m_faceColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); - m_mediumShadowColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW); - m_darkShadowColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DDKSHADOW); - m_lightShadowColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT); - m_hilightColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT); -#else - m_faceColour = *(wxTheColourDatabase->FindColour("LIGHT GREY")); - m_mediumShadowColour = *(wxTheColourDatabase->FindColour("GREY")); - m_darkShadowColour = *(wxTheColourDatabase->FindColour("BLACK")); - m_lightShadowColour = *(wxTheColourDatabase->FindColour("LIGHT GREY")); - m_hilightColour = *(wxTheColourDatabase->FindColour("WHITE")); -#endif + m_faceColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); + m_mediumShadowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW); + m_darkShadowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW); + m_lightShadowColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); + m_hilightColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT); } void wxSashWindow::SetSashVisible(wxSashEdgePosition edge, bool sash) @@ -671,3 +686,23 @@ void wxSashWindow::SetSashVisible(wxSashEdgePosition edge, bool sash) m_sashes[edge].m_margin = 0; } +#if defined( __WXMSW__ ) || defined( __WXMAC__) + +// this is currently called (and needed) under MSW only... +void wxSashWindow::OnSetCursor(wxSetCursorEvent& event) +{ + // if we don't do it, the resizing cursor might be set for child window: + // and like this we explicitly say that our cursor should not be used for + // children windows which overlap us + + if ( SashHitTest(event.GetX(), event.GetY()) != wxSASH_NONE) + { + // default processing is ok + event.Skip(); + } + //else: do nothing, in particular, don't call Skip() +} + +#endif // wxMSW + +#endif // wxUSE_SASH