/////////////////////////////////////////////////////////////////////////////
-// Name: sashwin.cpp
+// Name: src/generic/sashwin.cpp
// Purpose: wxSashWindow implementation. A sash window has an optional
// sash on each edge, allowing it to be dragged. An event
// is generated when the sash is released.
// Created: 01/02/97
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "sashwin.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
+#if wxUSE_SASH
+
+#include "wx/sashwin.h"
+
#ifndef WX_PRECOMP
-#include "wx/wx.h"
+ #include "wx/dialog.h"
+ #include "wx/frame.h"
+ #include "wx/settings.h"
+ #include "wx/dcclient.h"
+ #include "wx/dcscreen.h"
+ #include "wx/math.h"
#endif
-#if !wxUSE_SASH
- #error "Thisfile requires wxUSE_SASH to be defined."
-#endif // wxUSE_SASH
-
-#include <math.h>
#include <stdlib.h>
-#include "wx/string.h"
-#include "wx/dcscreen.h"
-#include "wx/sashwin.h"
#include "wx/laywin.h"
-#if !USE_SHARED_LIBRARY
+wxDEFINE_EVENT( wxEVT_SASH_DRAGGED, wxSashEvent );
+
IMPLEMENT_DYNAMIC_CLASS(wxSashWindow, wxWindow)
IMPLEMENT_DYNAMIC_CLASS(wxSashEvent, wxCommandEvent)
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__ || __WXMAC__
+
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;
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)
{
- wxCoord x, y;
+ wxCoord x = 0, y = 0;
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
// the area to draw on.
wxWindow* parent = this;
- while (parent && !parent->IsKindOf(CLASSINFO(wxDialog)) &&
- !parent->IsKindOf(CLASSINFO(wxFrame)))
+ while (parent && !wxDynamicCast(parent, wxDialog) &&
+ !wxDynamicCast(parent, wxFrame))
parent = parent->GetParent();
wxScreenDC::StartDrawingOnTop(parent);
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;
{
// 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);
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
break;
}
- if ( newHeight == -1 )
+ if ( newHeight == wxDefaultCoord )
{
// didn't change
newHeight = h;
newHeight = wxMin(newHeight, m_maximumPaneSizeY);
}
- if ( newWidth == -1 )
+ if ( newWidth == wxDefaultCoord )
{
// didn't change
newWidth = w;
dragRect = wxRect(x, y, newWidth, newHeight);
- wxSashEvent event(GetId(), edge);
- event.SetEventObject(this);
- event.SetDragStatus(status);
- event.SetDragRect(dragRect);
- GetEventHandler()->ProcessEvent(event);
+ wxSashEvent eventSash(GetId(), edge);
+ eventSash.SetEventObject(this);
+ eventSash.SetDragStatus(status);
+ eventSash.SetDragRect(dragRect);
+ GetEventHandler()->ProcessEvent(eventSash);
+ }
+ else if ( event.LeftUp() )
+ {
+ if (m_mouseCaptured)
+ ReleaseMouse();
+ m_mouseCaptured = false;
}
- else if (event.Moving() && !event.Dragging())
+ else if ((event.Moving() || event.Leaving()) && !event.Dragging())
{
// Just change the cursor if required
if ( sashHit != wxSASH_NONE )
{
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) ||
{
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)
int w, h;
GetClientSize(&w, &h);
- wxPen mediumShadowPen(m_mediumShadowColour, 1, wxSOLID);
- wxPen darkShadowPen(m_darkShadowColour, 1, wxSOLID);
- wxPen lightShadowPen(m_lightShadowColour, 1, wxSOLID);
- wxPen hilightPen(m_hilightColour, 1, wxSOLID);
+ wxPen mediumShadowPen(m_mediumShadowColour, 1, wxPENSTYLE_SOLID);
+ wxPen darkShadowPen(m_darkShadowColour, 1, wxPENSTYLE_SOLID);
+ wxPen lightShadowPen(m_lightShadowColour, 1, wxPENSTYLE_SOLID);
+ wxPen hilightPen(m_hilightColour, 1, wxPENSTYLE_SOLID);
- if ( GetWindowStyleFlag() & wxSW_3D )
+ if ( GetWindowStyleFlag() & wxSW_3DBORDER )
{
dc.SetPen(mediumShadowPen);
dc.DrawLine(0, 0, w-1, 0);
int w, h;
GetClientSize(&w, &h);
- wxPen facePen(m_faceColour, 1, wxSOLID);
- wxBrush faceBrush(m_faceColour, wxSOLID);
- wxPen mediumShadowPen(m_mediumShadowColour, 1, wxSOLID);
- wxPen darkShadowPen(m_darkShadowColour, 1, wxSOLID);
- wxPen lightShadowPen(m_lightShadowColour, 1, wxSOLID);
- wxPen hilightPen(m_hilightColour, 1, wxSOLID);
- wxPen blackPen(wxColour(0, 0, 0), 1, wxSOLID);
- wxPen whitePen(wxColour(255, 255, 255), 1, wxSOLID);
+ wxPen facePen(m_faceColour, 1, wxPENSTYLE_SOLID);
+ wxBrush faceBrush(m_faceColour, wxBRUSHSTYLE_SOLID);
+ wxPen mediumShadowPen(m_mediumShadowColour, 1, wxPENSTYLE_SOLID);
+ wxPen darkShadowPen(m_darkShadowColour, 1, wxPENSTYLE_SOLID);
+ wxPen lightShadowPen(m_lightShadowColour, 1, wxPENSTYLE_SOLID);
+ wxPen hilightPen(m_hilightColour, 1, wxPENSTYLE_SOLID);
+ wxColour blackClr(0, 0, 0);
+ wxColour whiteClr(255, 255, 255);
+ wxPen blackPen(blackClr, 1, wxPENSTYLE_SOLID);
+ wxPen whitePen(whiteClr, 1, wxPENSTYLE_SOLID);
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));
}
}
}
ClientToScreen(&x1, &y1);
ClientToScreen(&x2, &y2);
- wxPen sashTrackerPen(*wxBLACK, 2, wxSOLID);
+ wxPen sashTrackerPen(*wxBLACK, 2, wxPENSTYLE_SOLID);
screenDC.SetLogicalFunction(wxINVERT);
screenDC.SetPen(sashTrackerPen);
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;
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
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)
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__ || __WXMAC__
+
+#endif // wxUSE_SASH