// set the sash position and send an event about it having been changed
void SetSashPositionAndNotify(int sashPos);
+ // callbacks executed when we detect that the mouse has entered or left
+ // the sash
+ virtual void OnEnterSash();
+ virtual void OnLeaveSash();
+
// set the cursor appropriate for the current split mode
void SetResizeCursor();
+ // redraw the splitter if its "hotness" changed if necessary
+ void RedrawIfHotSensitive(bool isHot);
+
wxSplitMode m_splitMode;
- bool m_permitUnsplitAlways;
- bool m_needUpdating; // when in live mode, set this to TRUE to resize children in idle
wxWindow* m_windowOne;
wxWindow* m_windowTwo;
int m_dragMode;
wxCursor m_sashCursorNS;
wxPen *m_sashTrackerPen;
+ // when in live mode, set this to TRUE to resize children in idle
+ bool m_needUpdating:1;
+ bool m_permitUnsplitAlways:1;
+ bool m_isHot:1;
+
private:
WX_DECLARE_CONTROL_CONTAINER();
wxCONTROL_DIRTY = 0x80000000
};
+// ----------------------------------------------------------------------------
+// helper structs
+// ----------------------------------------------------------------------------
+
+// wxSplitterWindow parameters
+struct WXDLLEXPORT wxSplitterRenderParams
+{
+ // the only way to initialize this struct is by using this ctor
+ wxSplitterRenderParams(wxCoord widthSash_, wxCoord border_, bool isSens_)
+ : widthSash(widthSash_), border(border_), isHotSensitive(isSens_)
+ {
+ }
+
+ // the width of the splitter sash
+ const wxCoord widthSash;
+
+ // the width of the border of the splitter window
+ const wxCoord border;
+
+ // true if the splitter changes its appearance when the mouse is over it
+ const bool isHotSensitive;
+};
+
// ----------------------------------------------------------------------------
// wxRendererNative: abstracts drawing methods needed by the native controls
// ----------------------------------------------------------------------------
// drawn by DrawSash() blends into it well
virtual void DrawSplitterBorder(wxWindow *win,
wxDC& dc,
- const wxRect& rect) = 0;
+ const wxRect& rect,
+ int flags = 0) = 0;
// draw a (vertical) sash
virtual void DrawSplitterSash(wxWindow *win,
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient) = 0;
+ wxOrientation orient,
+ int flags = 0) = 0;
// geometry functions
// get the splitter parameters: the x field of the returned point is the
// sash width and the y field is the border width
- virtual wxPoint GetSplitterSashAndBorder(const wxWindow *win) = 0;
+ virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win) = 0;
// pseudo constructors
virtual void DrawSplitterBorder(wxWindow *win,
wxDC& dc,
- const wxRect& rect)
+ const wxRect& rect,
+ int flags = 0)
{ m_rendererNative.DrawSplitterBorder(win, dc, rect); }
virtual void DrawSplitterSash(wxWindow *win,
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient)
+ wxOrientation orient,
+ int flags = 0)
{ m_rendererNative.DrawSplitterSash(win, dc, size, position, orient); }
- virtual wxPoint GetSplitterSashAndBorder(const wxWindow *win)
- { return m_rendererNative.GetSplitterSashAndBorder(win); }
+ virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win)
+ { return m_rendererNative.GetSplitterParams(win); }
protected:
wxRendererNative& m_rendererNative;
virtual void DrawSplitterBorder(wxWindow *win,
wxDC& dc,
- const wxRect& rect);
+ const wxRect& rect,
+ int flags = 0);
virtual void DrawSplitterSash(wxWindow *win,
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient);
+ wxOrientation orient,
+ int flags = 0);
- virtual wxPoint GetSplitterSashAndBorder(const wxWindow *win);
+ virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
protected:
// sash drawing
// ----------------------------------------------------------------------------
-wxPoint
-wxRendererGeneric::GetSplitterSashAndBorder(const wxWindow *win)
+wxSplitterRenderParams
+wxRendererGeneric::GetSplitterParams(const wxWindow *win)
{
// see below
- return win->HasFlag(wxSP_3D) ? wxPoint(7, 2) : wxPoint(3, 0);
+ wxCoord sashWidth,
+ border;
+
+ if ( win->HasFlag(wxSP_3D) )
+ {
+ sashWidth = 7;
+ border = 3;
+ }
+ else // no 3D effect
+ {
+ sashWidth = 2;
+ border = 0;
+ }
+
+ return wxSplitterRenderParams(sashWidth, border, false);
}
void
wxRendererGeneric::DrawSplitterBorder(wxWindow *win,
wxDC& dc,
- const wxRect& rectOrig)
+ const wxRect& rectOrig,
+ int WXUNUSED(falgs))
{
if ( win->HasFlag(wxSP_3D) )
{
wxDC& dcReal,
const wxSize& sizeReal,
wxCoord position,
- wxOrientation orient)
+ wxOrientation orient,
+ int WXUNUSED(flags))
{
// to avoid duplicating the same code for horizontal and vertical sashes,
// simply mirror the DC instead if needed (i.e. if horz splitter)
m_sashTrackerPen = new wxPen(*wxBLACK, 2, wxSOLID);
m_needUpdating = FALSE;
+ m_isHot = false;
}
wxSplitterWindow::~wxSplitterWindow()
delete m_sashTrackerPen;
}
+// ----------------------------------------------------------------------------
+// entering/leaving sash
+// ----------------------------------------------------------------------------
+
+void wxSplitterWindow::RedrawIfHotSensitive(bool isHot)
+{
+ if ( wxRendererNative::Get().GetSplitterParams(this).isHotSensitive )
+ {
+ m_isHot = isHot;
+
+ wxClientDC dc(this);
+ DrawSash(dc);
+ }
+ //else: we don't change our appearance, don't redraw to avoid flicker
+}
+
+void wxSplitterWindow::OnEnterSash()
+{
+ SetResizeCursor();
+
+ RedrawIfHotSensitive(true);
+}
+
+void wxSplitterWindow::OnLeaveSash()
+{
+ SetCursor(*wxSTANDARD_CURSOR);
+
+ RedrawIfHotSensitive(false);
+}
+
void wxSplitterWindow::SetResizeCursor()
{
SetCursor(m_splitMode == wxSPLIT_VERTICAL ? m_sashCursorWE
: m_sashCursorNS);
}
+// ----------------------------------------------------------------------------
+// other event handlers
+// ----------------------------------------------------------------------------
+
void wxSplitterWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
} // left up && dragging
else if ((event.Moving() || event.Leaving() || event.Entering()) && (m_dragMode == wxSPLIT_DRAG_NONE))
{
- // Just change the cursor as required
- if ( !event.Leaving() && SashHitTest(x, y) )
- {
- SetResizeCursor();
- }
+ if ( event.Leaving() || !SashHitTest(x, y) )
+ OnLeaveSash();
else
- {
- SetCursor(* wxSTANDARD_CURSOR);
- }
+ OnEnterSash();
}
else if (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING))
{
int wxSplitterWindow::GetSashSize() const
{
- return wxRendererNative::Get().GetSplitterSashAndBorder(this).x;
+ return wxRendererNative::Get().GetSplitterParams(this).widthSash;
}
int wxSplitterWindow::GetBorderSize() const
{
- return wxRendererNative::Get().GetSplitterSashAndBorder(this).y;
+ return wxRendererNative::Get().GetSplitterParams(this).border;
}
// Draw the sash
dc,
GetClientSize(),
m_sashPosition,
- m_splitMode == wxSPLIT_VERTICAL
- ? wxVERTICAL
- : wxHORIZONTAL
+ m_splitMode == wxSPLIT_VERTICAL ? wxVERTICAL
+ : wxHORIZONTAL,
+ m_isHot ? wxCONTROL_CURRENT : 0
);
}
#include "wx/settings.h"
#endif // GTK 2.0
+#ifdef __WXGTK20__
+ #define WXUNUSED_IN_GTK1(arg) arg
+#else
+ #define WXUNUSED_IN_GTK1(arg)
+#endif
+
// ----------------------------------------------------------------------------
// wxRendererGTK: our wxRendererNative implementation
// ----------------------------------------------------------------------------
virtual void DrawSplitterBorder(wxWindow *win,
wxDC& dc,
- const wxRect& rect) ;
+ const wxRect& rect,
+ int flags = 0);
virtual void DrawSplitterSash(wxWindow *win,
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient);
+ wxOrientation orient,
+ int flags = 0);
- virtual wxPoint GetSplitterSashAndBorder(const wxWindow *win);
+ virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
};
// ============================================================================
// splitter sash drawing
// ----------------------------------------------------------------------------
-// the full sash width (should be even)
-static const wxCoord SASH_SIZE = 10;
+// all this should probably be read from the current theme settings somehow?
+#ifdef __WXGTK20__
+ // the full sash size
+ static const wxCoord SASH_FULL_SIZE = 5;
+#else // GTK+ 1.x
+ // the full sash width (should be even)
+ static const wxCoord SASH_SIZE = 10;
+
+ // margin around the sash
+ static const wxCoord SASH_MARGIN = 5;
-// margin around the sash
-static const wxCoord SASH_MARGIN = 5;
+ // the full sash size
+ static const wxCoord SASH_FULL_SIZE = SASH_SIZE + SASH_MARGIN;
+#endif // GTK+ 2.x/1.x
-wxPoint
-wxRendererGTK::GetSplitterSashAndBorder(const wxWindow * WXUNUSED(win))
+wxSplitterRenderParams
+wxRendererGTK::GetSplitterParams(const wxWindow * WXUNUSED(win))
{
- // we don't draw any border, hence 0 for the second field, but we must
- // leave some margin around the sash
- return wxPoint(SASH_SIZE + SASH_MARGIN, 0);
+ // we don't draw any border, hence 0 for the second field
+ return wxSplitterRenderParams
+ (
+ SASH_FULL_SIZE,
+ 0,
+#ifdef __WXGTK20__
+ true // hot sensitive
+#else // GTK+ 1.x
+ false // not
+#endif // GTK+ 2.x/1.x
+ );
}
void
wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
wxDC& WXUNUSED(dc),
- const wxRect& WXUNUSED(rect))
+ const wxRect& WXUNUSED(rect),
+ int WXUNUSED(flags))
{
// nothing to do
}
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient)
+ wxOrientation orient,
+ int WXUNUSED_IN_GTK1(flags))
{
if ( !win->m_wxwindow->window )
{
// are we drawing vertical or horizontal splitter?
const bool isVert = orient == wxVERTICAL;
- // we must erase everything first, otherwise the garbage from the old sash
- // is left when dragging it
- //
- // TODO: is this the right way to draw themed background?
GdkRectangle rect;
if ( isVert )
{
rect.x = position;
rect.y = 0;
- rect.width = SASH_SIZE + SASH_MARGIN;
+ rect.width = SASH_FULL_SIZE;
rect.height = size.y;
}
else // horz
{
rect.x = 0;
rect.y = position;
- rect.height = SASH_SIZE + SASH_MARGIN;
+ rect.height = SASH_FULL_SIZE;
rect.width = size.x;
}
+#ifdef __WXGTK20__
+ gtk_paint_handle
+ (
+ win->m_wxwindow->style,
+ GTK_PIZZA(win->m_wxwindow)->bin_window,
+ flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
+ GTK_SHADOW_NONE,
+ NULL /* no clipping */,
+ win->m_wxwindow,
+ "paned",
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height,
+ isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
+ );
+#else // GTK+ 1.x
+ // we must erase everything first, otherwise the garbage from the old sash
+ // is left when dragging it
+ //
+ // TODO: is this the right way to draw themed background?
gtk_paint_flat_box
(
win->m_wxwindow->style,
typedef void (*GtkPaintLineFunc)(GtkStyle *, GdkWindow *,
GtkStateType,
GdkRectangle *, GtkWidget *,
-#ifdef __WXGTK20__
- const gchar *,
-#else
gchar *,
-#endif
gint, gint, gint);
GtkPaintLineFunc func = isVert ? gtk_paint_vline : gtk_paint_hline;
isVert ? size.y - 2*SASH_SIZE : position,
SASH_SIZE, SASH_SIZE
);
+#endif // GTK+ 2.x/1.x
}
#include "wx/settings.h"
#endif // GTK 2.0
+#ifdef __WXGTK20__
+ #define WXUNUSED_IN_GTK1(arg) arg
+#else
+ #define WXUNUSED_IN_GTK1(arg)
+#endif
+
// ----------------------------------------------------------------------------
// wxRendererGTK: our wxRendererNative implementation
// ----------------------------------------------------------------------------
virtual void DrawSplitterBorder(wxWindow *win,
wxDC& dc,
- const wxRect& rect) ;
+ const wxRect& rect,
+ int flags = 0);
virtual void DrawSplitterSash(wxWindow *win,
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient);
+ wxOrientation orient,
+ int flags = 0);
- virtual wxPoint GetSplitterSashAndBorder(const wxWindow *win);
+ virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
};
// ============================================================================
// splitter sash drawing
// ----------------------------------------------------------------------------
-// the full sash width (should be even)
-static const wxCoord SASH_SIZE = 10;
+// all this should probably be read from the current theme settings somehow?
+#ifdef __WXGTK20__
+ // the full sash size
+ static const wxCoord SASH_FULL_SIZE = 5;
+#else // GTK+ 1.x
+ // the full sash width (should be even)
+ static const wxCoord SASH_SIZE = 10;
+
+ // margin around the sash
+ static const wxCoord SASH_MARGIN = 5;
-// margin around the sash
-static const wxCoord SASH_MARGIN = 5;
+ // the full sash size
+ static const wxCoord SASH_FULL_SIZE = SASH_SIZE + SASH_MARGIN;
+#endif // GTK+ 2.x/1.x
-wxPoint
-wxRendererGTK::GetSplitterSashAndBorder(const wxWindow * WXUNUSED(win))
+wxSplitterRenderParams
+wxRendererGTK::GetSplitterParams(const wxWindow * WXUNUSED(win))
{
- // we don't draw any border, hence 0 for the second field, but we must
- // leave some margin around the sash
- return wxPoint(SASH_SIZE + SASH_MARGIN, 0);
+ // we don't draw any border, hence 0 for the second field
+ return wxSplitterRenderParams
+ (
+ SASH_FULL_SIZE,
+ 0,
+#ifdef __WXGTK20__
+ true // hot sensitive
+#else // GTK+ 1.x
+ false // not
+#endif // GTK+ 2.x/1.x
+ );
}
void
wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
wxDC& WXUNUSED(dc),
- const wxRect& WXUNUSED(rect))
+ const wxRect& WXUNUSED(rect),
+ int WXUNUSED(flags))
{
// nothing to do
}
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient)
+ wxOrientation orient,
+ int WXUNUSED_IN_GTK1(flags))
{
if ( !win->m_wxwindow->window )
{
// are we drawing vertical or horizontal splitter?
const bool isVert = orient == wxVERTICAL;
- // we must erase everything first, otherwise the garbage from the old sash
- // is left when dragging it
- //
- // TODO: is this the right way to draw themed background?
GdkRectangle rect;
if ( isVert )
{
rect.x = position;
rect.y = 0;
- rect.width = SASH_SIZE + SASH_MARGIN;
+ rect.width = SASH_FULL_SIZE;
rect.height = size.y;
}
else // horz
{
rect.x = 0;
rect.y = position;
- rect.height = SASH_SIZE + SASH_MARGIN;
+ rect.height = SASH_FULL_SIZE;
rect.width = size.x;
}
+#ifdef __WXGTK20__
+ gtk_paint_handle
+ (
+ win->m_wxwindow->style,
+ GTK_PIZZA(win->m_wxwindow)->bin_window,
+ flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
+ GTK_SHADOW_NONE,
+ NULL /* no clipping */,
+ win->m_wxwindow,
+ "paned",
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height,
+ isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
+ );
+#else // GTK+ 1.x
+ // we must erase everything first, otherwise the garbage from the old sash
+ // is left when dragging it
+ //
+ // TODO: is this the right way to draw themed background?
gtk_paint_flat_box
(
win->m_wxwindow->style,
typedef void (*GtkPaintLineFunc)(GtkStyle *, GdkWindow *,
GtkStateType,
GdkRectangle *, GtkWidget *,
-#ifdef __WXGTK20__
- const gchar *,
-#else
gchar *,
-#endif
gint, gint, gint);
GtkPaintLineFunc func = isVert ? gtk_paint_vline : gtk_paint_hline;
isVert ? size.y - 2*SASH_SIZE : position,
SASH_SIZE, SASH_SIZE
);
+#endif // GTK+ 2.x/1.x
}
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient);
+ wxOrientation orient,
+ int flags = 0);
private:
// the tree buttons
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient)
+ wxOrientation orient,
+ int WXUNUSED(flags))
{
// VZ: we have to somehow determine if we're drawing a normal sash or
// a brushed metal one as they look quite differently... this is
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient);
+ wxOrientation orient,
+ int flags = 0);
private:
// the tree buttons
wxDC& dc,
const wxSize& size,
wxCoord position,
- wxOrientation orient)
+ wxOrientation orient,
+ int WXUNUSED(flags))
{
// VZ: we have to somehow determine if we're drawing a normal sash or
// a brushed metal one as they look quite differently... this is