]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/renderer.cpp
fixed typo in EVT_COMMAND definition
[wxWidgets.git] / src / gtk1 / renderer.cpp
CommitLineData
9c7f49f5
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: gtk/renderer.cpp
38c4cb6a 3// Purpose: implementation of wxRendererNative for wxGTK
9c7f49f5
VZ
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>
65571936 9// License: wxWindows licence
9c7f49f5
VZ
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
e1bf3ad3 27#include "wx/renderer.h"
9c7f49f5
VZ
28#include <gtk/gtk.h>
29#include "wx/gtk/win_gtk.h"
30
38c4cb6a
VZ
31#include "wx/window.h"
32#include "wx/dc.h"
9c7f49f5 33
3dd570e5
VZ
34#ifdef __WXGTK20__
35 #include "wx/settings.h"
36#endif // GTK 2.0
37
af99040c
VZ
38#ifdef __WXGTK20__
39 #define WXUNUSED_IN_GTK1(arg) arg
40#else
41 #define WXUNUSED_IN_GTK1(arg)
42#endif
43
9c7f49f5 44// ----------------------------------------------------------------------------
38c4cb6a 45// wxRendererGTK: our wxRendererNative implementation
9c7f49f5
VZ
46// ----------------------------------------------------------------------------
47
38c4cb6a 48class WXDLLEXPORT wxRendererGTK : public wxDelegateRendererNative
9c7f49f5
VZ
49{
50public:
51 // draw the header control button (used by wxListCtrl)
52 virtual void DrawHeaderButton(wxWindow *win,
53 wxDC& dc,
54 const wxRect& rect,
55 int flags = 0);
56
57#ifdef __WXGTK20__
58 // draw the expanded/collapsed icon for a tree control item
59 virtual void DrawTreeItemButton(wxWindow *win,
60 wxDC& dc,
61 const wxRect& rect,
62 int flags = 0);
63#endif // GTK 2.0
64
d16cf3cd
VZ
65 virtual void DrawSplitterBorder(wxWindow *win,
66 wxDC& dc,
af99040c
VZ
67 const wxRect& rect,
68 int flags = 0);
95155e75
VZ
69 virtual void DrawSplitterSash(wxWindow *win,
70 wxDC& dc,
71 const wxSize& size,
d16cf3cd 72 wxCoord position,
af99040c
VZ
73 wxOrientation orient,
74 int flags = 0);
d16cf3cd 75
af99040c 76 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
9c7f49f5
VZ
77};
78
79// ============================================================================
80// implementation
81// ============================================================================
82
83/* static */
f0244295 84wxRendererNative& wxRendererNative::GetDefault()
9c7f49f5
VZ
85{
86 static wxRendererGTK s_rendererGTK;
87
88 return s_rendererGTK;
89}
90
d16cf3cd
VZ
91// ----------------------------------------------------------------------------
92// list/tree controls drawing
93// ----------------------------------------------------------------------------
94
9c7f49f5
VZ
95void
96wxRendererGTK::DrawHeaderButton(wxWindow *win,
97 wxDC& dc,
98 const wxRect& rect,
99 int flags)
100{
9b311923
RR
101
102 static GtkWidget *s_button = NULL;
103 static GtkWidget *s_window = NULL;
104 if (s_button == NULL)
105 {
106 s_window = gtk_window_new( GTK_WINDOW_POPUP );
91fdca5b
RR
107 gtk_widget_realize( s_window );
108 s_button = gtk_button_new();
109 gtk_container_add( GTK_CONTAINER(s_window), s_button );
110 gtk_widget_realize( s_button );
9b311923
RR
111 }
112
9c7f49f5
VZ
113 gtk_paint_box
114 (
91fdca5b 115 s_button->style,
9c7f49f5
VZ
116 GTK_PIZZA(win->m_wxwindow)->bin_window,
117 flags & wxCONTROL_DISABLED ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL,
118 GTK_SHADOW_OUT,
91fdca5b 119 NULL,
9b311923
RR
120 s_button,
121 "button",
122 dc.XLOG2DEV(rect.x) -1, rect.y -1, rect.width +2, rect.height +2
9c7f49f5
VZ
123 );
124}
125
126#ifdef __WXGTK20__
127
128// draw a ">" or "v" button
129//
e7846404 130// TODO: replace the code below with gtk_paint_expander()
9c7f49f5 131void
f8b043e7 132wxRendererGTK::DrawTreeItemButton(wxWindow* win,
9a0b7e33 133 wxDC& dc, const wxRect& rect, int flags)
9c7f49f5 134{
f8b043e7
RR
135#define PM_SIZE 8
136
137 GtkPizza *pizza = GTK_PIZZA( win->m_wxwindow );
138 GtkStyle *style = win->m_widget->style;
139 int x = rect.x;
140 int y = rect.y;
91fdca5b
RR
141 y = dc.LogicalToDeviceY( y );
142 x = dc.LogicalToDeviceX( x );
f8b043e7 143
f8b043e7
RR
144 // This draws the GTK+ 2.2.4 triangle
145 x--;
146 GdkPoint points[3];
147
148 if ( flags & wxCONTROL_EXPANDED )
149 {
150 points[0].x = x;
151 points[0].y = y + (PM_SIZE + 2) / 6;
152 points[1].x = points[0].x + (PM_SIZE + 2);
153 points[1].y = points[0].y;
154 points[2].x = (points[0].x + (PM_SIZE + 2) / 2);
155 points[2].y = y + 2 * (PM_SIZE + 2) / 3;
156 }
157 else
158 {
159 points[0].x = x + ((PM_SIZE + 2) / 6 + 2);
160 points[0].y = y - 1;
161 points[1].x = points[0].x;
162 points[1].y = points[0].y + (PM_SIZE + 2);
163 points[2].x = (points[0].x +
91fdca5b 164 (2 * (PM_SIZE + 2) / 3 - 1));
f8b043e7
RR
165 points[2].y = points[0].y + (PM_SIZE + 2) / 2;
166 }
167
168 if ( flags & wxCONTROL_CURRENT )
169 gdk_draw_polygon( pizza->bin_window, style->fg_gc[GTK_STATE_PRELIGHT], TRUE, points, 3);
170 else
171 gdk_draw_polygon( pizza->bin_window, style->base_gc[GTK_STATE_NORMAL], TRUE, points, 3);
172 gdk_draw_polygon( pizza->bin_window, style->fg_gc[GTK_STATE_NORMAL], FALSE, points, 3 );
9c7f49f5
VZ
173}
174
175#endif // GTK 2.0
176
d16cf3cd
VZ
177// ----------------------------------------------------------------------------
178// splitter sash drawing
179// ----------------------------------------------------------------------------
180
af99040c
VZ
181// all this should probably be read from the current theme settings somehow?
182#ifdef __WXGTK20__
183 // the full sash size
184 static const wxCoord SASH_FULL_SIZE = 5;
185#else // GTK+ 1.x
186 // the full sash width (should be even)
35468934 187 static const wxCoord SASH_SIZE = 8;
af99040c
VZ
188
189 // margin around the sash
35468934 190 static const wxCoord SASH_MARGIN = 2;
d16cf3cd 191
af99040c
VZ
192 // the full sash size
193 static const wxCoord SASH_FULL_SIZE = SASH_SIZE + SASH_MARGIN;
194#endif // GTK+ 2.x/1.x
d16cf3cd 195
af99040c
VZ
196wxSplitterRenderParams
197wxRendererGTK::GetSplitterParams(const wxWindow * WXUNUSED(win))
d16cf3cd 198{
af99040c
VZ
199 // we don't draw any border, hence 0 for the second field
200 return wxSplitterRenderParams
201 (
202 SASH_FULL_SIZE,
203 0,
204#ifdef __WXGTK20__
205 true // hot sensitive
206#else // GTK+ 1.x
207 false // not
208#endif // GTK+ 2.x/1.x
209 );
d16cf3cd
VZ
210}
211
212void
213wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
214 wxDC& WXUNUSED(dc),
af99040c
VZ
215 const wxRect& WXUNUSED(rect),
216 int WXUNUSED(flags))
d16cf3cd
VZ
217{
218 // nothing to do
219}
95155e75 220
95155e75
VZ
221void
222wxRendererGTK::DrawSplitterSash(wxWindow *win,
223 wxDC& dc,
224 const wxSize& size,
d16cf3cd 225 wxCoord position,
af99040c
VZ
226 wxOrientation orient,
227 int WXUNUSED_IN_GTK1(flags))
95155e75
VZ
228{
229 if ( !win->m_wxwindow->window )
230 {
0100b858 231 // window not realized yet
95155e75
VZ
232 return;
233 }
234
d16cf3cd
VZ
235 // are we drawing vertical or horizontal splitter?
236 const bool isVert = orient == wxVERTICAL;
237
d16cf3cd 238 GdkRectangle rect;
35468934 239 GdkRectangle erase_rect;
d16cf3cd
VZ
240 if ( isVert )
241 {
0100b858 242 int h = win->GetClientSize().GetHeight();
35468934 243
d16cf3cd 244 rect.x = position;
0100b858 245 rect.y = 0;
af99040c 246 rect.width = SASH_FULL_SIZE;
0100b858 247 rect.height = h;
91fdca5b 248
35468934
RR
249 erase_rect.x = position;
250 erase_rect.y = 0;
251 erase_rect.width = SASH_FULL_SIZE;
252 erase_rect.height = h;
d16cf3cd
VZ
253 }
254 else // horz
255 {
0100b858 256 int w = win->GetClientSize().GetWidth();
35468934 257
0100b858 258 rect.x = 0;
d16cf3cd 259 rect.y = position;
af99040c 260 rect.height = SASH_FULL_SIZE;
0100b858 261 rect.width = w;
91fdca5b 262
35468934
RR
263 erase_rect.y = position;
264 erase_rect.x = 0;
265 erase_rect.height = SASH_FULL_SIZE;
266 erase_rect.width = w;
d16cf3cd
VZ
267 }
268
35468934
RR
269 // we must erase everything first, otherwise the garbage from the old sash
270 // is left when dragging it
271 //
272 // TODO: is this the right way to draw themed background?
273 gtk_paint_flat_box
274 (
275 win->m_wxwindow->style,
276 GTK_PIZZA(win->m_wxwindow)->bin_window,
277 GTK_STATE_NORMAL,
278 GTK_SHADOW_NONE,
279 NULL,
280 win->m_wxwindow,
281 (char *)"base", // const_cast
282 erase_rect.x,
283 erase_rect.y,
284 erase_rect.width,
285 erase_rect.height
286 );
287
af99040c
VZ
288#ifdef __WXGTK20__
289 gtk_paint_handle
290 (
291 win->m_wxwindow->style,
292 GTK_PIZZA(win->m_wxwindow)->bin_window,
293 flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
294 GTK_SHADOW_NONE,
295 NULL /* no clipping */,
296 win->m_wxwindow,
297 "paned",
298 rect.x,
299 rect.y,
300 rect.width,
301 rect.height,
6de9d616 302 !isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
af99040c
VZ
303 );
304#else // GTK+ 1.x
d16cf3cd
VZ
305
306 // leave some margin before sash itself
307 position += SASH_MARGIN / 2;
308
309 // and finally draw it using GTK paint functions
310 typedef void (*GtkPaintLineFunc)(GtkStyle *, GdkWindow *,
311 GtkStateType,
312 GdkRectangle *, GtkWidget *,
ef9bfb71 313 gchar *,
ef9bfb71 314 gint, gint, gint);
d16cf3cd
VZ
315
316 GtkPaintLineFunc func = isVert ? gtk_paint_vline : gtk_paint_hline;
317
318 (*func)
95155e75
VZ
319 (
320 win->m_wxwindow->style,
d16cf3cd 321 GTK_PIZZA(win->m_wxwindow)->bin_window,
95155e75 322 GTK_STATE_NORMAL,
d16cf3cd 323 NULL,
95155e75 324 win->m_wxwindow,
d16cf3cd
VZ
325 (char *)"paned", // const_cast
326 0, isVert ? size.y : size.x, position + SASH_SIZE / 2 - 1
95155e75
VZ
327 );
328
329 gtk_paint_box
330 (
331 win->m_wxwindow->style,
d16cf3cd 332 GTK_PIZZA(win->m_wxwindow)->bin_window,
95155e75
VZ
333 GTK_STATE_NORMAL,
334 GTK_SHADOW_OUT,
d16cf3cd 335 (GdkRectangle*) NULL,
95155e75
VZ
336 win->m_wxwindow,
337 (char *)"paned", // const_cast
d16cf3cd
VZ
338 isVert ? position : size.x - 2*SASH_SIZE,
339 isVert ? size.y - 2*SASH_SIZE : position,
340 SASH_SIZE, SASH_SIZE
95155e75 341 );
af99040c 342#endif // GTK+ 2.x/1.x
95155e75
VZ
343}
344