]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/renderer.cpp
don't hang forever in Dispatch() if there is no event loop
[wxWidgets.git] / src / gtk / 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>
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
38c4cb6a
VZ
33#include "wx/window.h"
34#include "wx/dc.h"
9c7f49f5
VZ
35#include "wx/renderer.h"
36
3dd570e5
VZ
37#ifdef __WXGTK20__
38 #include "wx/settings.h"
39#endif // GTK 2.0
40
af99040c
VZ
41#ifdef __WXGTK20__
42 #define WXUNUSED_IN_GTK1(arg) arg
43#else
44 #define WXUNUSED_IN_GTK1(arg)
45#endif
46
9c7f49f5 47// ----------------------------------------------------------------------------
38c4cb6a 48// wxRendererGTK: our wxRendererNative implementation
9c7f49f5
VZ
49// ----------------------------------------------------------------------------
50
38c4cb6a 51class WXDLLEXPORT wxRendererGTK : public wxDelegateRendererNative
9c7f49f5
VZ
52{
53public:
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
d16cf3cd
VZ
68 virtual void DrawSplitterBorder(wxWindow *win,
69 wxDC& dc,
af99040c
VZ
70 const wxRect& rect,
71 int flags = 0);
95155e75
VZ
72 virtual void DrawSplitterSash(wxWindow *win,
73 wxDC& dc,
74 const wxSize& size,
d16cf3cd 75 wxCoord position,
af99040c
VZ
76 wxOrientation orient,
77 int flags = 0);
d16cf3cd 78
af99040c 79 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
9c7f49f5
VZ
80};
81
82// ============================================================================
83// implementation
84// ============================================================================
85
86/* static */
f0244295 87wxRendererNative& wxRendererNative::GetDefault()
9c7f49f5
VZ
88{
89 static wxRendererGTK s_rendererGTK;
90
91 return s_rendererGTK;
92}
93
d16cf3cd
VZ
94// ----------------------------------------------------------------------------
95// list/tree controls drawing
96// ----------------------------------------------------------------------------
97
9c7f49f5
VZ
98void
99wxRendererGTK::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,
38c4cb6a
VZ
110 (GdkRectangle*) NULL,
111 win->m_wxwindow,
9c7f49f5 112 (char *)"button", // const_cast
38c4cb6a 113 dc.XLOG2DEV(rect.x) - 1, rect.y - 1, rect.width + 2, rect.height + 2
9c7f49f5
VZ
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?
122void
9a0b7e33
VS
123wxRendererGTK::DrawTreeItemButton(wxWindow* WXUNUSED(win),
124 wxDC& dc, const wxRect& rect, int flags)
9c7f49f5 125{
3dd570e5
VZ
126 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT),
127 wxSOLID));
9c7f49f5
VZ
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
d16cf3cd
VZ
158// ----------------------------------------------------------------------------
159// splitter sash drawing
160// ----------------------------------------------------------------------------
161
af99040c
VZ
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;
d16cf3cd 172
af99040c
VZ
173 // the full sash size
174 static const wxCoord SASH_FULL_SIZE = SASH_SIZE + SASH_MARGIN;
175#endif // GTK+ 2.x/1.x
d16cf3cd 176
af99040c
VZ
177wxSplitterRenderParams
178wxRendererGTK::GetSplitterParams(const wxWindow * WXUNUSED(win))
d16cf3cd 179{
af99040c
VZ
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 );
d16cf3cd
VZ
191}
192
193void
194wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
195 wxDC& WXUNUSED(dc),
af99040c
VZ
196 const wxRect& WXUNUSED(rect),
197 int WXUNUSED(flags))
d16cf3cd
VZ
198{
199 // nothing to do
200}
95155e75 201
95155e75
VZ
202void
203wxRendererGTK::DrawSplitterSash(wxWindow *win,
204 wxDC& dc,
205 const wxSize& size,
d16cf3cd 206 wxCoord position,
af99040c
VZ
207 wxOrientation orient,
208 int WXUNUSED_IN_GTK1(flags))
95155e75
VZ
209{
210 if ( !win->m_wxwindow->window )
211 {
212 // VZ: this happens on startup -- why?
213 return;
214 }
215
d16cf3cd
VZ
216 // are we drawing vertical or horizontal splitter?
217 const bool isVert = orient == wxVERTICAL;
218
d16cf3cd
VZ
219 GdkRectangle rect;
220 if ( isVert )
221 {
222 rect.x = position;
223 rect.y = 0;
af99040c 224 rect.width = SASH_FULL_SIZE;
d16cf3cd
VZ
225 rect.height = size.y;
226 }
227 else // horz
228 {
229 rect.x = 0;
230 rect.y = position;
af99040c 231 rect.height = SASH_FULL_SIZE;
d16cf3cd
VZ
232 rect.width = size.x;
233 }
234
af99040c
VZ
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?
d16cf3cd
VZ
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 *,
ef9bfb71 276 gchar *,
ef9bfb71 277 gint, gint, gint);
d16cf3cd
VZ
278
279 GtkPaintLineFunc func = isVert ? gtk_paint_vline : gtk_paint_hline;
280
281 (*func)
95155e75
VZ
282 (
283 win->m_wxwindow->style,
d16cf3cd 284 GTK_PIZZA(win->m_wxwindow)->bin_window,
95155e75 285 GTK_STATE_NORMAL,
d16cf3cd 286 NULL,
95155e75 287 win->m_wxwindow,
d16cf3cd
VZ
288 (char *)"paned", // const_cast
289 0, isVert ? size.y : size.x, position + SASH_SIZE / 2 - 1
95155e75
VZ
290 );
291
292 gtk_paint_box
293 (
294 win->m_wxwindow->style,
d16cf3cd 295 GTK_PIZZA(win->m_wxwindow)->bin_window,
95155e75
VZ
296 GTK_STATE_NORMAL,
297 GTK_SHADOW_OUT,
d16cf3cd 298 (GdkRectangle*) NULL,
95155e75
VZ
299 win->m_wxwindow,
300 (char *)"paned", // const_cast
d16cf3cd
VZ
301 isVert ? position : size.x - 2*SASH_SIZE,
302 isVert ? size.y - 2*SASH_SIZE : position,
303 SASH_SIZE, SASH_SIZE
95155e75 304 );
af99040c 305#endif // GTK+ 2.x/1.x
95155e75
VZ
306}
307