]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/renderer.cpp
DT_WORD_ELLIPSIS is not defined under CE
[wxWidgets.git] / src / gtk1 / renderer.cpp
... / ...
CommitLineData
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 licence
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#include "wx/renderer.h"
28#include <gtk/gtk.h>
29#include "wx/gtk1/win_gtk.h"
30
31#include "wx/window.h"
32#include "wx/dc.h"
33#include "wx/dcclient.h"
34
35// RR: After a correction to the orientation of the sash
36// this doesn't seem to be required anymore and it
37// seems to confuse some themes so USE_ERASE_RECT=0
38#define USE_ERASE_RECT 0
39
40// ----------------------------------------------------------------------------
41// wxRendererGTK: our wxRendererNative implementation
42// ----------------------------------------------------------------------------
43
44class WXDLLEXPORT wxRendererGTK : public wxDelegateRendererNative
45{
46public:
47 // draw the header control button (used by wxListCtrl)
48 virtual void DrawHeaderButton(wxWindow *win,
49 wxDC& dc,
50 const wxRect& rect,
51 int flags = 0);
52
53 virtual void DrawSplitterBorder(wxWindow *win,
54 wxDC& dc,
55 const wxRect& rect,
56 int flags = 0);
57 virtual void DrawSplitterSash(wxWindow *win,
58 wxDC& dc,
59 const wxSize& size,
60 wxCoord position,
61 wxOrientation orient,
62 int flags = 0);
63
64 virtual void DrawComboBoxDropButton(wxWindow *win,
65 wxDC& dc,
66 const wxRect& rect,
67 int flags = 0);
68
69 virtual void DrawDropArrow(wxWindow *win,
70 wxDC& dc,
71 const wxRect& rect,
72 int flags = 0);
73
74 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
75
76private:
77 // FIXME: shouldn't we destroy these windows somewhere?
78
79 // used by DrawHeaderButton and DrawComboBoxDropButton
80 static GtkWidget *GetButtonWidget();
81};
82
83// ============================================================================
84// implementation
85// ============================================================================
86
87/* static */
88wxRendererNative& wxRendererNative::GetDefault()
89{
90 static wxRendererGTK s_rendererGTK;
91
92 return s_rendererGTK;
93}
94
95// ----------------------------------------------------------------------------
96// helper functions
97// ----------------------------------------------------------------------------
98
99GtkWidget *
100wxRendererGTK::GetButtonWidget()
101{
102 static GtkWidget *s_button = NULL;
103 static GtkWidget *s_window = NULL;
104
105 if ( !s_button )
106 {
107 s_window = gtk_window_new( GTK_WINDOW_POPUP );
108 gtk_widget_realize( s_window );
109 s_button = gtk_button_new();
110 gtk_container_add( GTK_CONTAINER(s_window), s_button );
111 gtk_widget_realize( s_button );
112 }
113
114 return s_button;
115}
116
117// ----------------------------------------------------------------------------
118// list/tree controls drawing
119// ----------------------------------------------------------------------------
120
121void
122wxRendererGTK::DrawHeaderButton(wxWindow *win,
123 wxDC& dc,
124 const wxRect& rect,
125 int flags)
126{
127
128 GtkWidget *button = GetButtonWidget();
129
130 gtk_paint_box
131 (
132 button->style,
133 // FIXME: I suppose GTK_PIZZA(win->m_wxwindow)->bin_window doesn't work with wxMemoryDC.
134 // Maybe use code similar as in DrawComboBoxDropButton below?
135 GTK_PIZZA(win->m_wxwindow)->bin_window,
136 flags & wxCONTROL_DISABLED ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL,
137 GTK_SHADOW_OUT,
138 NULL,
139 button,
140 "button",
141 dc.XLOG2DEV(rect.x) -1, rect.y -1, rect.width +2, rect.height +2
142 );
143}
144
145// ----------------------------------------------------------------------------
146// splitter sash drawing
147// ----------------------------------------------------------------------------
148
149// the full sash width (should be even)
150static const wxCoord SASH_SIZE = 8;
151
152// margin around the sash
153static const wxCoord SASH_MARGIN = 2;
154
155static int GetGtkSplitterFullSize()
156{
157 return SASH_SIZE + SASH_MARGIN;
158}
159
160wxSplitterRenderParams
161wxRendererGTK::GetSplitterParams(const wxWindow *WXUNUSED(win))
162{
163 // we don't draw any border, hence 0 for the second field
164 return wxSplitterRenderParams
165 (
166 GetGtkSplitterFullSize(),
167 0,
168 false // not
169 );
170}
171
172void
173wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
174 wxDC& WXUNUSED(dc),
175 const wxRect& WXUNUSED(rect),
176 int WXUNUSED(flags))
177{
178 // nothing to do
179}
180
181void
182wxRendererGTK::DrawSplitterSash(wxWindow *win,
183 wxDC& dc,
184 const wxSize& size,
185 wxCoord position,
186 wxOrientation orient,
187 int WXUNUSED(flags))
188{
189 if ( !win->m_wxwindow->window )
190 {
191 // window not realized yet
192 return;
193 }
194
195 wxCoord full_size = GetGtkSplitterFullSize();
196
197 // are we drawing vertical or horizontal splitter?
198 const bool isVert = orient == wxVERTICAL;
199
200 GdkRectangle rect;
201#if USE_ERASE_RECT
202 GdkRectangle erase_rect;
203#endif
204
205 if ( isVert )
206 {
207 int h = win->GetClientSize().GetHeight();
208
209 rect.x = position;
210 rect.y = 0;
211 rect.width = full_size;
212 rect.height = h;
213
214#if USE_ERASE_RECT
215 erase_rect.x = position;
216 erase_rect.y = 0;
217 erase_rect.width = full_size;
218 erase_rect.height = h;
219#endif
220 }
221 else // horz
222 {
223 int w = win->GetClientSize().GetWidth();
224
225 rect.x = 0;
226 rect.y = position;
227 rect.height = full_size;
228 rect.width = w;
229
230#if USE_ERASE_RECT
231 erase_rect.y = position;
232 erase_rect.x = 0;
233 erase_rect.height = full_size;
234 erase_rect.width = w;
235#endif
236 }
237
238#if USE_ERASE_RECT
239 // we must erase everything first, otherwise the garbage
240 // from the old sash is left when dragging it
241 gtk_paint_flat_box
242 (
243 win->m_wxwindow->style,
244 GTK_PIZZA(win->m_wxwindow)->bin_window,
245 GTK_STATE_NORMAL,
246 GTK_SHADOW_NONE,
247 NULL,
248 win->m_wxwindow,
249 (char *)"viewportbin", // const_cast
250 erase_rect.x,
251 erase_rect.y,
252 erase_rect.width,
253 erase_rect.height
254 );
255#endif
256
257
258 // leave some margin before sash itself
259 position += SASH_MARGIN / 2;
260
261 // and finally draw it using GTK paint functions
262 typedef void (*GtkPaintLineFunc)(GtkStyle *, GdkWindow *,
263 GtkStateType,
264 GdkRectangle *, GtkWidget *,
265 gchar *,
266 gint, gint, gint);
267
268 GtkPaintLineFunc func = isVert ? gtk_paint_vline : gtk_paint_hline;
269
270 (*func)
271 (
272 win->m_wxwindow->style,
273 GTK_PIZZA(win->m_wxwindow)->bin_window,
274 GTK_STATE_NORMAL,
275 NULL,
276 win->m_wxwindow,
277 (char *)"paned", // const_cast
278 0, isVert ? size.y : size.x, position + SASH_SIZE / 2 - 1
279 );
280
281 gtk_paint_box
282 (
283 win->m_wxwindow->style,
284 GTK_PIZZA(win->m_wxwindow)->bin_window,
285 GTK_STATE_NORMAL,
286 GTK_SHADOW_OUT,
287 (GdkRectangle*) NULL,
288 win->m_wxwindow,
289 (char *)"paned", // const_cast
290 isVert ? position : size.x - 2*SASH_SIZE,
291 isVert ? size.y - 2*SASH_SIZE : position,
292 SASH_SIZE, SASH_SIZE
293 );
294}
295
296void
297wxRendererGTK::DrawDropArrow(wxWindow *win,
298 wxDC& dc,
299 const wxRect& rect,
300 int flags)
301{
302 GtkWidget *button = GetButtonWidget();
303
304 // If we give GTK_PIZZA(win->m_wxwindow)->bin_window as
305 // a window for gtk_paint_xxx function, then it won't
306 // work for wxMemoryDC. So that is why we assume wxDC
307 // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC
308 // are derived from it) and use its m_window.
309 wxWindowDC& wdc = (wxWindowDC&)dc;
310
311 // only doing debug-time checking here (it should
312 // probably be enough)
313 wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) );
314
315 // draw arrow so that there is even space horizontally
316 // on both sides
317 int arrowX = rect.width/4 + 1;
318 int arrowWidth = rect.width - (arrowX*2);
319
320 // scale arrow's height accoording to the width
321 int arrowHeight = rect.width/3;
322 int arrowY = (rect.height-arrowHeight)/2 +
323 ((rect.height-arrowHeight) & 1);
324
325 GtkStateType state;
326
327 if ( flags & wxCONTROL_PRESSED )
328 state = GTK_STATE_ACTIVE;
329 else if ( flags & wxCONTROL_DISABLED )
330 state = GTK_STATE_INSENSITIVE;
331 else if ( flags & wxCONTROL_CURRENT )
332 state = GTK_STATE_PRELIGHT;
333 else
334 state = GTK_STATE_NORMAL;
335
336 // draw arrow on button
337 gtk_paint_arrow
338 (
339 button->style,
340 wdc.m_window,
341 state,
342 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
343 NULL,
344 button,
345 "arrow",
346 GTK_ARROW_DOWN,
347 FALSE,
348 rect.x + arrowX,
349 rect.y + arrowY,
350 arrowWidth,
351 arrowHeight
352 );
353}
354
355void
356wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
357 wxDC& dc,
358 const wxRect& rect,
359 int flags)
360{
361 GtkWidget *button = GetButtonWidget();
362
363 // for reason why we do this, see DrawDropArrow
364 wxWindowDC& wdc = (wxWindowDC&)dc;
365 wxASSERT ( wdc.IsKindOf(CLASSINFO(wxWindowDC)) );
366
367 // draw button
368 GtkStateType state;
369
370 if ( flags & wxCONTROL_PRESSED )
371 state = GTK_STATE_ACTIVE;
372 else if ( flags & wxCONTROL_DISABLED )
373 state = GTK_STATE_INSENSITIVE;
374 else if ( flags & wxCONTROL_CURRENT )
375 state = GTK_STATE_PRELIGHT;
376 else
377 state = GTK_STATE_NORMAL;
378
379 gtk_paint_box
380 (
381 button->style,
382 wdc.m_window,
383 state,
384 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
385 NULL,
386 button,
387 "button",
388 rect.x, rect.y, rect.width, rect.height
389 );
390
391 // draw arrow on button
392 DrawDropArrow(win,dc,rect,flags);
393
394}