1. added flags to splitter drawing functions and replaced
[wxWidgets.git] / src / gtk / renderer.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: gtk/renderer.cpp
3 // Purpose: implementation of wxRendererNative for wxGTK
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 20.07.2003
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #endif // WX_PRECOMP
29
30 #include <gtk/gtk.h>
31 #include "wx/gtk/win_gtk.h"
32
33 #include "wx/window.h"
34 #include "wx/dc.h"
35 #include "wx/renderer.h"
36
37 #ifdef __WXGTK20__
38 #include "wx/settings.h"
39 #endif // GTK 2.0
40
41 #ifdef __WXGTK20__
42 #define WXUNUSED_IN_GTK1(arg) arg
43 #else
44 #define WXUNUSED_IN_GTK1(arg)
45 #endif
46
47 // ----------------------------------------------------------------------------
48 // wxRendererGTK: our wxRendererNative implementation
49 // ----------------------------------------------------------------------------
50
51 class WXDLLEXPORT wxRendererGTK : public wxDelegateRendererNative
52 {
53 public:
54 // draw the header control button (used by wxListCtrl)
55 virtual void DrawHeaderButton(wxWindow *win,
56 wxDC& dc,
57 const wxRect& rect,
58 int flags = 0);
59
60 #ifdef __WXGTK20__
61 // draw the expanded/collapsed icon for a tree control item
62 virtual void DrawTreeItemButton(wxWindow *win,
63 wxDC& dc,
64 const wxRect& rect,
65 int flags = 0);
66 #endif // GTK 2.0
67
68 virtual void DrawSplitterBorder(wxWindow *win,
69 wxDC& dc,
70 const wxRect& rect,
71 int flags = 0);
72 virtual void DrawSplitterSash(wxWindow *win,
73 wxDC& dc,
74 const wxSize& size,
75 wxCoord position,
76 wxOrientation orient,
77 int flags = 0);
78
79 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
80 };
81
82 // ============================================================================
83 // implementation
84 // ============================================================================
85
86 /* static */
87 wxRendererNative& wxRendererNative::GetDefault()
88 {
89 static wxRendererGTK s_rendererGTK;
90
91 return s_rendererGTK;
92 }
93
94 // ----------------------------------------------------------------------------
95 // list/tree controls drawing
96 // ----------------------------------------------------------------------------
97
98 void
99 wxRendererGTK::DrawHeaderButton(wxWindow *win,
100 wxDC& dc,
101 const wxRect& rect,
102 int flags)
103 {
104 gtk_paint_box
105 (
106 win->m_wxwindow->style,
107 GTK_PIZZA(win->m_wxwindow)->bin_window,
108 flags & wxCONTROL_DISABLED ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL,
109 GTK_SHADOW_OUT,
110 (GdkRectangle*) NULL,
111 win->m_wxwindow,
112 (char *)"button", // const_cast
113 dc.XLOG2DEV(rect.x) - 1, rect.y - 1, rect.width + 2, rect.height + 2
114 );
115 }
116
117 #ifdef __WXGTK20__
118
119 // draw a ">" or "v" button
120 //
121 // TODO: isn't there a GTK function to draw it?
122 void
123 wxRendererGTK::DrawTreeItemButton(wxWindow* WXUNUSED(win),
124 wxDC& dc, const wxRect& rect, int flags)
125 {
126 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT),
127 wxSOLID));
128 dc.SetPen(*wxBLACK_PEN);
129 wxPoint button[3];
130
131 const wxCoord xMiddle = rect.x + rect.width/2;
132 const wxCoord yMiddle = rect.y + rect.height/2;
133
134 if ( flags & wxCONTROL_EXPANDED )
135 {
136 button[0].x = rect.GetLeft();
137 button[0].y = yMiddle - 2;
138 button[1].x = rect.GetRight();
139 button[1].y = yMiddle - 2;
140 button[2].x = xMiddle;
141 button[2].y = yMiddle + 3;
142 }
143 else // collapsed
144 {
145 button[0].y = rect.GetBottom();
146 button[0].x = xMiddle - 2;
147 button[1].y = rect.GetTop();
148 button[1].x = xMiddle - 2;
149 button[2].y = yMiddle;
150 button[2].x = xMiddle + 3;
151 }
152
153 dc.DrawPolygon(3, button);
154 }
155
156 #endif // GTK 2.0
157
158 // ----------------------------------------------------------------------------
159 // splitter sash drawing
160 // ----------------------------------------------------------------------------
161
162 // all this should probably be read from the current theme settings somehow?
163 #ifdef __WXGTK20__
164 // the full sash size
165 static const wxCoord SASH_FULL_SIZE = 5;
166 #else // GTK+ 1.x
167 // the full sash width (should be even)
168 static const wxCoord SASH_SIZE = 10;
169
170 // margin around the sash
171 static const wxCoord SASH_MARGIN = 5;
172
173 // the full sash size
174 static const wxCoord SASH_FULL_SIZE = SASH_SIZE + SASH_MARGIN;
175 #endif // GTK+ 2.x/1.x
176
177 wxSplitterRenderParams
178 wxRendererGTK::GetSplitterParams(const wxWindow * WXUNUSED(win))
179 {
180 // we don't draw any border, hence 0 for the second field
181 return wxSplitterRenderParams
182 (
183 SASH_FULL_SIZE,
184 0,
185 #ifdef __WXGTK20__
186 true // hot sensitive
187 #else // GTK+ 1.x
188 false // not
189 #endif // GTK+ 2.x/1.x
190 );
191 }
192
193 void
194 wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
195 wxDC& WXUNUSED(dc),
196 const wxRect& WXUNUSED(rect),
197 int WXUNUSED(flags))
198 {
199 // nothing to do
200 }
201
202 void
203 wxRendererGTK::DrawSplitterSash(wxWindow *win,
204 wxDC& dc,
205 const wxSize& size,
206 wxCoord position,
207 wxOrientation orient,
208 int WXUNUSED_IN_GTK1(flags))
209 {
210 if ( !win->m_wxwindow->window )
211 {
212 // VZ: this happens on startup -- why?
213 return;
214 }
215
216 // are we drawing vertical or horizontal splitter?
217 const bool isVert = orient == wxVERTICAL;
218
219 GdkRectangle rect;
220 if ( isVert )
221 {
222 rect.x = position;
223 rect.y = 0;
224 rect.width = SASH_FULL_SIZE;
225 rect.height = size.y;
226 }
227 else // horz
228 {
229 rect.x = 0;
230 rect.y = position;
231 rect.height = SASH_FULL_SIZE;
232 rect.width = size.x;
233 }
234
235 #ifdef __WXGTK20__
236 gtk_paint_handle
237 (
238 win->m_wxwindow->style,
239 GTK_PIZZA(win->m_wxwindow)->bin_window,
240 flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
241 GTK_SHADOW_NONE,
242 NULL /* no clipping */,
243 win->m_wxwindow,
244 "paned",
245 rect.x,
246 rect.y,
247 rect.width,
248 rect.height,
249 isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
250 );
251 #else // GTK+ 1.x
252 // we must erase everything first, otherwise the garbage from the old sash
253 // is left when dragging it
254 //
255 // TODO: is this the right way to draw themed background?
256 gtk_paint_flat_box
257 (
258 win->m_wxwindow->style,
259 GTK_PIZZA(win->m_wxwindow)->bin_window,
260 GTK_STATE_NORMAL,
261 GTK_SHADOW_NONE,
262 &rect,
263 win->m_wxwindow,
264 (char *)"base", // const_cast
265 0, 0, -1, -1
266 );
267
268
269 // leave some margin before sash itself
270 position += SASH_MARGIN / 2;
271
272 // and finally draw it using GTK paint functions
273 typedef void (*GtkPaintLineFunc)(GtkStyle *, GdkWindow *,
274 GtkStateType,
275 GdkRectangle *, GtkWidget *,
276 gchar *,
277 gint, gint, gint);
278
279 GtkPaintLineFunc func = isVert ? gtk_paint_vline : gtk_paint_hline;
280
281 (*func)
282 (
283 win->m_wxwindow->style,
284 GTK_PIZZA(win->m_wxwindow)->bin_window,
285 GTK_STATE_NORMAL,
286 NULL,
287 win->m_wxwindow,
288 (char *)"paned", // const_cast
289 0, isVert ? size.y : size.x, position + SASH_SIZE / 2 - 1
290 );
291
292 gtk_paint_box
293 (
294 win->m_wxwindow->style,
295 GTK_PIZZA(win->m_wxwindow)->bin_window,
296 GTK_STATE_NORMAL,
297 GTK_SHADOW_OUT,
298 (GdkRectangle*) NULL,
299 win->m_wxwindow,
300 (char *)"paned", // const_cast
301 isVert ? position : size.x - 2*SASH_SIZE,
302 isVert ? size.y - 2*SASH_SIZE : position,
303 SASH_SIZE, SASH_SIZE
304 );
305 #endif // GTK+ 2.x/1.x
306 }
307