Add expand/collapse button to wxRibbonBar.
[wxWidgets.git] / src / ribbon / art_msw.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/ribbon/art_msw.cpp
3 // Purpose: MSW style art provider for ribbon interface
4 // Author: Peter Cawley
5 // Modified by:
6 // Created: 2009-05-25
7 // RCS-ID: $Id$
8 // Copyright: (C) Peter Cawley
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #if wxUSE_RIBBON
19
20 #include "wx/ribbon/art.h"
21 #include "wx/ribbon/art_internal.h"
22 #include "wx/ribbon/bar.h"
23 #include "wx/ribbon/buttonbar.h"
24 #include "wx/ribbon/gallery.h"
25 #include "wx/ribbon/toolbar.h"
26
27 #ifndef WX_PRECOMP
28 #include "wx/dcmemory.h"
29 #endif
30
31 #ifdef __WXMSW__
32 #include "wx/msw/private.h"
33 #endif
34
35 static const char* const gallery_up_xpm[] = {
36 "5 5 2 1",
37 " c None",
38 "x c #FF00FF",
39 " ",
40 " x ",
41 " xxx ",
42 "xxxxx",
43 " "};
44
45 static const char* const gallery_down_xpm[] = {
46 "5 5 2 1",
47 " c None",
48 "x c #FF00FF",
49 " ",
50 "xxxxx",
51 " xxx ",
52 " x ",
53 " "};
54
55 static const char* const gallery_left_xpm[] = {
56 "5 5 2 1",
57 " c None",
58 "x c #FF00FF",
59 " x ",
60 " xx ",
61 " xxx ",
62 " xx ",
63 " x "};
64
65 static const char* const gallery_right_xpm[] = {
66 "5 5 2 1",
67 " c None",
68 "x c #FF00FF",
69 " x ",
70 " xx ",
71 " xxx ",
72 " xx ",
73 " x "};
74
75 static const char* const gallery_extension_xpm[] = {
76 "5 5 2 1",
77 " c None",
78 "x c #FF00FF",
79 "xxxxx",
80 " ",
81 "xxxxx",
82 " xxx ",
83 " x "};
84
85 static const char* const panel_extension_xpm[] = {
86 "7 7 2 1",
87 " c None",
88 "x c #FF00FF",
89 "xxxxxx ",
90 "x ",
91 "x ",
92 "x x x",
93 "x xxx",
94 "x xxx",
95 " xxxx"};
96
97 static const char* const panel_toggle_down_xpm[] = {
98 "7 9 2 1",
99 " c None",
100 "x c #FF00FF",
101 " ",
102 "x x",
103 "xx xx",
104 " xx xx ",
105 "x xxx x",
106 "xx x xx",
107 " xx xx ",
108 " xxx ",
109 " x ",};
110
111 static const char* const panel_toggle_up_xpm[] = {
112 "7 9 2 1",
113 " c None",
114 "x c #FF00FF",
115 " x ",
116 " xxx ",
117 " xx xx ",
118 "xx x xx",
119 "x xxx x",
120 " xx xx ",
121 "xx xx",
122 "x x",
123 " ",};
124
125 wxRibbonMSWArtProvider::wxRibbonMSWArtProvider(bool set_colour_scheme)
126 {
127 m_flags = 0;
128 #if defined( __WXMAC__ )
129 m_tab_label_font = *wxSMALL_FONT;
130 #else
131 m_tab_label_font = *wxNORMAL_FONT;
132 #endif
133 m_button_bar_label_font = m_tab_label_font;
134 m_panel_label_font = m_tab_label_font;
135
136 if(set_colour_scheme)
137 {
138 SetColourScheme(
139 wxColour(194, 216, 241),
140 wxColour(255, 223, 114),
141 wxColour( 0, 0, 0));
142 }
143
144 m_cached_tab_separator_visibility = -10.0; // valid visibilities are in range [0, 1]
145 m_tab_separation_size = 3;
146 m_page_border_left = 2;
147 m_page_border_top = 1;
148 m_page_border_right = 2;
149 m_page_border_bottom = 3;
150 m_panel_x_separation_size = 1;
151 m_panel_y_separation_size = 1;
152 m_tool_group_separation_size = 3;
153 m_gallery_bitmap_padding_left_size = 4;
154 m_gallery_bitmap_padding_right_size = 4;
155 m_gallery_bitmap_padding_top_size = 4;
156 m_gallery_bitmap_padding_bottom_size = 4;
157 }
158
159 wxRibbonMSWArtProvider::~wxRibbonMSWArtProvider()
160 {
161 }
162
163 void wxRibbonMSWArtProvider::GetColourScheme(
164 wxColour* primary,
165 wxColour* secondary,
166 wxColour* tertiary) const
167 {
168 if(primary != NULL)
169 *primary = m_primary_scheme_colour;
170 if(secondary != NULL)
171 *secondary = m_secondary_scheme_colour;
172 if(tertiary != NULL)
173 *tertiary = m_tertiary_scheme_colour;
174 }
175
176 void wxRibbonMSWArtProvider::SetColourScheme(
177 const wxColour& primary,
178 const wxColour& secondary,
179 const wxColour& tertiary)
180 {
181 m_primary_scheme_colour = primary;
182 m_secondary_scheme_colour = secondary;
183 m_tertiary_scheme_colour = tertiary;
184
185 wxRibbonHSLColour primary_hsl(primary);
186 wxRibbonHSLColour secondary_hsl(secondary);
187 // tertiary not used for anything
188
189 // Map primary saturation from [0, 1] to [.25, .75]
190 bool primary_is_gray = false;
191 static const double gray_saturation_threshold = 0.01;
192 if(primary_hsl.saturation <= gray_saturation_threshold)
193 primary_is_gray = true;
194 else
195 {
196 primary_hsl.saturation = cos(primary_hsl.saturation * M_PI)
197 * -0.25 + 0.5;
198 }
199
200 // Map primary luminance from [0, 1] to [.23, .83]
201 primary_hsl.luminance = cos(primary_hsl.luminance * M_PI) * -0.3 + 0.53;
202
203 // Map secondary saturation from [0, 1] to [0.16, 0.84]
204 bool secondary_is_gray = false;
205 if(secondary_hsl.saturation <= gray_saturation_threshold)
206 secondary_is_gray = true;
207 else
208 {
209 secondary_hsl.saturation = cos(secondary_hsl.saturation * M_PI)
210 * -0.34 + 0.5;
211 }
212
213 // Map secondary luminance from [0, 1] to [0.1, 0.9]
214 secondary_hsl.luminance = cos(secondary_hsl.luminance * M_PI) * -0.4 + 0.5;
215
216 #define LikePrimary(h, s, l) \
217 primary_hsl.ShiftHue(h ## f).Saturated(primary_is_gray ? 0 : s ## f) \
218 .Lighter(l ## f).ToRGB()
219 #define LikeSecondary(h, s, l) \
220 secondary_hsl.ShiftHue(h ## f).Saturated(secondary_is_gray ? 0 : s ## f) \
221 .Lighter(l ## f).ToRGB()
222
223 m_page_border_pen = LikePrimary(1.4, 0.00, -0.08);
224
225 m_page_background_top_colour = LikePrimary(-0.1, -0.03, 0.12);
226 m_page_hover_background_top_colour = LikePrimary(-2.8, 0.27, 0.17);
227 m_page_background_top_gradient_colour = LikePrimary(0.1, -0.10, 0.08);
228 m_page_hover_background_top_gradient_colour = LikePrimary(3.2, 0.16, 0.13);
229 m_page_background_colour = LikePrimary(0.4, -0.09, 0.05);
230 m_page_hover_background_colour = LikePrimary(0.1, 0.19, 0.10);
231 m_page_background_gradient_colour = LikePrimary(-3.2, 0.27, 0.10);
232 m_page_hover_background_gradient_colour = LikePrimary(1.8, 0.01, 0.15);
233
234 m_tab_active_background_colour = LikePrimary(-0.1, -0.31, 0.16);
235 m_tab_active_background_gradient_colour = LikePrimary(-0.1, -0.03, 0.12);
236 m_tab_separator_colour = LikePrimary(0.9, 0.24, 0.05);
237 m_tab_ctrl_background_brush = LikePrimary(1.0, 0.39, 0.07);
238 m_tab_hover_background_colour = LikePrimary(1.3, 0.15, 0.10);
239 m_tab_hover_background_top_colour = LikePrimary(1.4, 0.36, 0.08);
240 m_tab_border_pen = LikePrimary(1.4, 0.03, -0.05);
241 m_tab_separator_gradient_colour = LikePrimary(1.7, -0.15, -0.18);
242 m_tab_hover_background_top_gradient_colour = LikePrimary(1.8, 0.34, 0.13);
243 m_tab_label_colour = LikePrimary(4.3, 0.13, -0.49);
244 m_tab_hover_background_gradient_colour = LikeSecondary(-1.5, -0.34, 0.01);
245
246 m_panel_minimised_border_gradient_pen = LikePrimary(-6.9, -0.17, -0.09);
247 m_panel_minimised_border_pen = LikePrimary(-5.3, -0.24, -0.06);
248 m_panel_border_gradient_pen = LikePrimary(-5.2, -0.15, -0.06);
249 m_panel_border_pen = LikePrimary(-2.8, -0.32, 0.02);
250 m_panel_label_background_brush = LikePrimary(-1.5, 0.03, 0.05);
251 m_panel_active_background_gradient_colour = LikePrimary(0.5, 0.34, 0.05);
252 m_panel_hover_label_background_brush = LikePrimary(1.0, 0.30, 0.09);
253 m_panel_active_background_top_gradient_colour = LikePrimary(1.4, -0.17, -0.13);
254 m_panel_active_background_colour = LikePrimary(1.6, -0.18, -0.18);
255 m_panel_active_background_top_colour = LikePrimary(1.7, -0.20, -0.03);
256 m_panel_label_colour = LikePrimary(2.8, -0.14, -0.35);
257 m_panel_hover_label_colour = m_panel_label_colour;
258 m_panel_minimised_label_colour = m_tab_label_colour;
259 m_panel_hover_button_background_brush = LikeSecondary(-0.9, 0.16, -0.07);
260 m_panel_hover_button_border_pen = LikeSecondary(-3.9, -0.16, -0.14);
261 SetColour(wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR, LikePrimary(1.4, -0.21, -0.23));
262 SetColour(wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR, LikePrimary(1.5, -0.24, -0.29));
263
264 m_ribbon_toggle_brush = LikeSecondary(-0.9, 0.16, -0.07);
265 m_ribbon_toggle_pen = LikeSecondary(-3.9, -0.16, -0.14);
266 SetColour(wxRIBBON_ART_PAGE_TOGGLE_FACE_COLOUR, LikePrimary(1.7, -0.20, -0.15));
267 SetColour(wxRIBBON_ART_PAGE_TOGGLE_HOVER_FACE_COLOUR, LikePrimary(1.8, -0.23, -0.21));
268
269 m_gallery_button_disabled_background_colour = LikePrimary(-2.8, -0.46, 0.09);
270 m_gallery_button_disabled_background_top_brush = LikePrimary(-2.8, -0.36, 0.15);
271 m_gallery_hover_background_brush = LikePrimary(-0.8, 0.05, 0.15);
272 m_gallery_border_pen = LikePrimary(0.7, -0.02, 0.03);
273 m_gallery_button_background_top_brush = LikePrimary(0.8, 0.34, 0.13);
274 m_gallery_button_background_colour = LikePrimary(1.3, 0.10, 0.08);
275 // SetColour used so that the relevant bitmaps are generated
276 SetColour(wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR, LikePrimary(1.4, -0.21, -0.23));
277 SetColour(wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR, LikePrimary(1.5, -0.24, -0.29));
278 SetColour(wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR, LikePrimary(1.5, -0.24, -0.29));
279 SetColour(wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR, LikePrimary(0.0, -1.0, 0.0));
280 m_gallery_button_disabled_background_gradient_colour = LikePrimary(1.5, -0.43, 0.12);
281 m_gallery_button_background_gradient_colour = LikePrimary(1.7, 0.11, 0.09);
282 m_gallery_item_border_pen = LikeSecondary(-3.9, -0.16, -0.14);
283 m_gallery_button_hover_background_colour = LikeSecondary(-0.9, 0.16, -0.07);
284 m_gallery_button_hover_background_gradient_colour = LikeSecondary(0.1, 0.12, 0.03);
285 m_gallery_button_hover_background_top_brush = LikeSecondary(4.3, 0.16, 0.17);
286
287 m_gallery_button_active_background_colour = LikeSecondary(-9.9, 0.03, -0.22);
288 m_gallery_button_active_background_gradient_colour = LikeSecondary(-9.5, 0.14, -0.11);
289 m_gallery_button_active_background_top_brush = LikeSecondary(-9.0, 0.15, -0.08);
290
291 m_button_bar_label_colour = m_tab_label_colour;
292 m_button_bar_hover_border_pen = LikeSecondary(-6.2, -0.47, -0.14);
293 m_button_bar_hover_background_gradient_colour = LikeSecondary(-0.6, 0.16, 0.04);
294 m_button_bar_hover_background_colour = LikeSecondary(-0.2, 0.16, -0.10);
295 m_button_bar_hover_background_top_gradient_colour = LikeSecondary(0.2, 0.16, 0.03);
296 m_button_bar_hover_background_top_colour = LikeSecondary(8.8, 0.16, 0.17);
297 m_button_bar_active_border_pen = LikeSecondary(-6.2, -0.47, -0.25);
298 m_button_bar_active_background_top_colour = LikeSecondary(-8.4, 0.08, 0.06);
299 m_button_bar_active_background_top_gradient_colour = LikeSecondary(-9.7, 0.13, -0.07);
300 m_button_bar_active_background_colour = LikeSecondary(-9.9, 0.14, -0.14);
301 m_button_bar_active_background_gradient_colour = LikeSecondary(-8.7, 0.17, -0.03);
302
303 m_toolbar_border_pen = LikePrimary(1.4, -0.21, -0.16);
304 SetColour(wxRIBBON_ART_TOOLBAR_FACE_COLOUR, LikePrimary(1.4, -0.17, -0.22));
305 m_tool_background_top_colour = LikePrimary(-1.9, -0.07, 0.06);
306 m_tool_background_top_gradient_colour = LikePrimary(1.4, 0.12, 0.08);
307 m_tool_background_colour = LikePrimary(1.4, -0.09, 0.03);
308 m_tool_background_gradient_colour = LikePrimary(1.9, 0.11, 0.09);
309 m_tool_hover_background_top_colour = LikeSecondary(3.4, 0.11, 0.16);
310 m_tool_hover_background_top_gradient_colour = LikeSecondary(-1.4, 0.04, 0.08);
311 m_tool_hover_background_colour = LikeSecondary(-1.8, 0.16, -0.12);
312 m_tool_hover_background_gradient_colour = LikeSecondary(-2.6, 0.16, 0.05);
313 m_tool_active_background_top_colour = LikeSecondary(-9.9, -0.12, -0.09);
314 m_tool_active_background_top_gradient_colour = LikeSecondary(-8.5, 0.16, -0.12);
315 m_tool_active_background_colour = LikeSecondary(-7.9, 0.16, -0.20);
316 m_tool_active_background_gradient_colour = LikeSecondary(-6.6, 0.16, -0.10);
317
318 #undef LikePrimary
319 #undef LikeSecondary
320
321 // Invalidate cached tab separator
322 m_cached_tab_separator_visibility = -1.0;
323 }
324
325 wxRibbonArtProvider* wxRibbonMSWArtProvider::Clone() const
326 {
327 wxRibbonMSWArtProvider *copy = new wxRibbonMSWArtProvider;
328 CloneTo(copy);
329 return copy;
330 }
331
332 void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
333 {
334 int i;
335 for(i = 0; i < 4; ++i)
336 {
337 copy->m_gallery_up_bitmap[i] = m_gallery_up_bitmap[i];
338 copy->m_gallery_down_bitmap[i] = m_gallery_down_bitmap[i];
339 copy->m_gallery_extension_bitmap[i] = m_gallery_extension_bitmap[i];
340 }
341 for(i = 0; i < 2; ++i)
342 {
343 copy->m_panel_extension_bitmap[i] = m_panel_extension_bitmap[i];
344 copy->m_ribbon_toggle_up_bitmap[i] = m_ribbon_toggle_up_bitmap[i];
345 copy->m_ribbon_toggle_down_bitmap[i] = m_ribbon_toggle_down_bitmap[i];
346 }
347 copy->m_toolbar_drop_bitmap = m_toolbar_drop_bitmap;
348
349 copy->m_primary_scheme_colour = m_primary_scheme_colour;
350 copy->m_secondary_scheme_colour = m_secondary_scheme_colour;
351 copy->m_tertiary_scheme_colour = m_tertiary_scheme_colour;
352
353 copy->m_page_toggle_face_colour = m_page_toggle_face_colour;
354 copy->m_page_toggle_hover_face_colour = m_page_toggle_hover_face_colour;
355
356 copy->m_button_bar_label_colour = m_button_bar_label_colour;
357 copy->m_tab_label_colour = m_tab_label_colour;
358 copy->m_tab_separator_colour = m_tab_separator_colour;
359 copy->m_tab_separator_gradient_colour = m_tab_separator_gradient_colour;
360 copy->m_tab_active_background_colour = m_tab_hover_background_colour;
361 copy->m_tab_active_background_gradient_colour = m_tab_hover_background_gradient_colour;
362 copy->m_tab_hover_background_colour = m_tab_hover_background_colour;
363 copy->m_tab_hover_background_gradient_colour = m_tab_hover_background_gradient_colour;
364 copy->m_tab_hover_background_top_colour = m_tab_hover_background_top_colour;
365 copy->m_tab_hover_background_top_gradient_colour = m_tab_hover_background_top_gradient_colour;
366 copy->m_panel_label_colour = m_panel_label_colour;
367 copy->m_panel_hover_label_colour = m_panel_hover_label_colour;
368 copy->m_panel_minimised_label_colour = m_panel_minimised_label_colour;
369 copy->m_panel_button_face_colour = m_panel_button_face_colour;
370 copy->m_panel_button_hover_face_colour = m_panel_button_hover_face_colour;
371 copy->m_panel_active_background_colour = m_panel_active_background_colour;
372 copy->m_panel_active_background_gradient_colour = m_panel_active_background_gradient_colour;
373 copy->m_panel_active_background_top_colour = m_panel_active_background_top_colour;
374 copy->m_panel_active_background_top_gradient_colour = m_panel_active_background_top_gradient_colour;
375 copy->m_page_background_colour = m_page_background_colour;
376 copy->m_page_background_gradient_colour = m_page_background_gradient_colour;
377 copy->m_page_background_top_colour = m_page_background_top_colour;
378 copy->m_page_background_top_gradient_colour = m_page_background_top_gradient_colour;
379 copy->m_page_hover_background_colour = m_page_hover_background_colour;
380 copy->m_page_hover_background_gradient_colour = m_page_hover_background_gradient_colour;
381 copy->m_page_hover_background_top_colour = m_page_hover_background_top_colour;
382 copy->m_page_hover_background_top_gradient_colour = m_page_hover_background_top_gradient_colour;
383 copy->m_button_bar_hover_background_colour = m_button_bar_hover_background_colour;
384 copy->m_button_bar_hover_background_gradient_colour = m_button_bar_hover_background_gradient_colour;
385 copy->m_button_bar_hover_background_top_colour = m_button_bar_hover_background_top_colour;
386 copy->m_button_bar_hover_background_top_gradient_colour = m_button_bar_hover_background_top_gradient_colour;
387 copy->m_button_bar_active_background_colour = m_button_bar_active_background_colour;
388 copy->m_button_bar_active_background_gradient_colour = m_button_bar_active_background_gradient_colour;
389 copy->m_button_bar_active_background_top_colour = m_button_bar_active_background_top_colour;
390 copy->m_button_bar_active_background_top_gradient_colour = m_button_bar_active_background_top_gradient_colour;
391 copy->m_gallery_button_background_colour = m_gallery_button_background_colour;
392 copy->m_gallery_button_background_gradient_colour = m_gallery_button_background_gradient_colour;
393 copy->m_gallery_button_hover_background_colour = m_gallery_button_hover_background_colour;
394 copy->m_gallery_button_hover_background_gradient_colour = m_gallery_button_hover_background_gradient_colour;
395 copy->m_gallery_button_active_background_colour = m_gallery_button_active_background_colour;
396 copy->m_gallery_button_active_background_gradient_colour = m_gallery_button_active_background_gradient_colour;
397 copy->m_gallery_button_disabled_background_colour = m_gallery_button_disabled_background_colour;
398 copy->m_gallery_button_disabled_background_gradient_colour = m_gallery_button_disabled_background_gradient_colour;
399 copy->m_gallery_button_face_colour = m_gallery_button_face_colour;
400 copy->m_gallery_button_hover_face_colour = m_gallery_button_hover_face_colour;
401 copy->m_gallery_button_active_face_colour = m_gallery_button_active_face_colour;
402 copy->m_gallery_button_disabled_face_colour = m_gallery_button_disabled_face_colour;
403
404 copy->m_tab_ctrl_background_brush = m_tab_ctrl_background_brush;
405 copy->m_panel_label_background_brush = m_panel_label_background_brush;
406 copy->m_panel_hover_label_background_brush = m_panel_hover_label_background_brush;
407 copy->m_panel_hover_button_background_brush = m_panel_hover_button_background_brush;
408 copy->m_gallery_hover_background_brush = m_gallery_hover_background_brush;
409 copy->m_gallery_button_background_top_brush = m_gallery_button_background_top_brush;
410 copy->m_gallery_button_hover_background_top_brush = m_gallery_button_hover_background_top_brush;
411 copy->m_gallery_button_active_background_top_brush = m_gallery_button_active_background_top_brush;
412 copy->m_gallery_button_disabled_background_top_brush = m_gallery_button_disabled_background_top_brush;
413 copy->m_ribbon_toggle_brush = m_ribbon_toggle_brush;
414
415 copy->m_tab_label_font = m_tab_label_font;
416 copy->m_button_bar_label_font = m_button_bar_label_font;
417 copy->m_panel_label_font = m_panel_label_font;
418
419 copy->m_page_border_pen = m_page_border_pen;
420 copy->m_panel_border_pen = m_panel_border_pen;
421 copy->m_panel_border_gradient_pen = m_panel_border_gradient_pen;
422 copy->m_panel_minimised_border_pen = m_panel_minimised_border_pen;
423 copy->m_panel_minimised_border_gradient_pen = m_panel_minimised_border_gradient_pen;
424 copy->m_panel_hover_button_border_pen = m_panel_hover_button_border_pen;
425 copy->m_tab_border_pen = m_tab_border_pen;
426 copy->m_gallery_border_pen = m_gallery_border_pen;
427 copy->m_button_bar_hover_border_pen = m_button_bar_hover_border_pen;
428 copy->m_button_bar_active_border_pen = m_button_bar_active_border_pen;
429 copy->m_gallery_item_border_pen = m_gallery_item_border_pen;
430 copy->m_toolbar_border_pen = m_toolbar_border_pen;
431 copy->m_ribbon_toggle_pen = m_ribbon_toggle_pen;
432
433 copy->m_flags = m_flags;
434 copy->m_tab_separation_size = m_tab_separation_size;
435 copy->m_page_border_left = m_page_border_left;
436 copy->m_page_border_top = m_page_border_top;
437 copy->m_page_border_right = m_page_border_right;
438 copy->m_page_border_bottom = m_page_border_bottom;
439 copy->m_panel_x_separation_size = m_panel_x_separation_size;
440 copy->m_panel_y_separation_size = m_panel_y_separation_size;
441 copy->m_gallery_bitmap_padding_left_size = m_gallery_bitmap_padding_left_size;
442 copy->m_gallery_bitmap_padding_right_size = m_gallery_bitmap_padding_right_size;
443 copy->m_gallery_bitmap_padding_top_size = m_gallery_bitmap_padding_top_size;
444 copy->m_gallery_bitmap_padding_bottom_size = m_gallery_bitmap_padding_bottom_size;
445 }
446
447 long wxRibbonMSWArtProvider::GetFlags() const
448 {
449 return m_flags;
450 }
451
452 void wxRibbonMSWArtProvider::SetFlags(long flags)
453 {
454 if((flags ^ m_flags) & wxRIBBON_BAR_FLOW_VERTICAL)
455 {
456 if(flags & wxRIBBON_BAR_FLOW_VERTICAL)
457 {
458 m_page_border_left++;
459 m_page_border_right++;
460 m_page_border_top--;
461 m_page_border_bottom--;
462 }
463 else
464 {
465 m_page_border_left--;
466 m_page_border_right--;
467 m_page_border_top++;
468 m_page_border_bottom++;
469 }
470 }
471 m_flags = flags;
472
473 // Need to reload some bitmaps when flags change
474 #define Reload(setting) SetColour(setting, GetColour(setting))
475 Reload(wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR);
476 Reload(wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR);
477 Reload(wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR);
478 Reload(wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR);
479 Reload(wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR);
480 Reload(wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR);
481 #undef Reload
482 }
483
484 int wxRibbonMSWArtProvider::GetMetric(int id) const
485 {
486 switch(id)
487 {
488 case wxRIBBON_ART_TAB_SEPARATION_SIZE:
489 return m_tab_separation_size;
490 case wxRIBBON_ART_PAGE_BORDER_LEFT_SIZE:
491 return m_page_border_left;
492 case wxRIBBON_ART_PAGE_BORDER_TOP_SIZE:
493 return m_page_border_top;
494 case wxRIBBON_ART_PAGE_BORDER_RIGHT_SIZE:
495 return m_page_border_right;
496 case wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE:
497 return m_page_border_bottom;
498 case wxRIBBON_ART_PANEL_X_SEPARATION_SIZE:
499 return m_panel_x_separation_size;
500 case wxRIBBON_ART_PANEL_Y_SEPARATION_SIZE:
501 return m_panel_y_separation_size;
502 case wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE:
503 return m_tool_group_separation_size;
504 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE:
505 return m_gallery_bitmap_padding_left_size;
506 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_RIGHT_SIZE:
507 return m_gallery_bitmap_padding_right_size;
508 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE:
509 return m_gallery_bitmap_padding_top_size;
510 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_BOTTOM_SIZE:
511 return m_gallery_bitmap_padding_bottom_size;
512 default:
513 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
514 break;
515 }
516
517 return 0;
518 }
519
520 void wxRibbonMSWArtProvider::SetMetric(int id, int new_val)
521 {
522 switch(id)
523 {
524 case wxRIBBON_ART_TAB_SEPARATION_SIZE:
525 m_tab_separation_size = new_val;
526 break;
527 case wxRIBBON_ART_PAGE_BORDER_LEFT_SIZE:
528 m_page_border_left = new_val;
529 break;
530 case wxRIBBON_ART_PAGE_BORDER_TOP_SIZE:
531 m_page_border_top = new_val;
532 break;
533 case wxRIBBON_ART_PAGE_BORDER_RIGHT_SIZE:
534 m_page_border_right = new_val;
535 break;
536 case wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE:
537 m_page_border_bottom = new_val;
538 break;
539 case wxRIBBON_ART_PANEL_X_SEPARATION_SIZE:
540 m_panel_x_separation_size = new_val;
541 break;
542 case wxRIBBON_ART_PANEL_Y_SEPARATION_SIZE:
543 m_panel_y_separation_size = new_val;
544 break;
545 case wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE:
546 m_tool_group_separation_size = new_val;
547 break;
548 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE:
549 m_gallery_bitmap_padding_left_size = new_val;
550 break;
551 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_RIGHT_SIZE:
552 m_gallery_bitmap_padding_right_size = new_val;
553 break;
554 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE:
555 m_gallery_bitmap_padding_top_size = new_val;
556 break;
557 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_BOTTOM_SIZE:
558 m_gallery_bitmap_padding_bottom_size = new_val;
559 break;
560 default:
561 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
562 break;
563 }
564 }
565
566 void wxRibbonMSWArtProvider::SetFont(int id, const wxFont& font)
567 {
568 switch(id)
569 {
570 case wxRIBBON_ART_TAB_LABEL_FONT:
571 m_tab_label_font = font;
572 break;
573 case wxRIBBON_ART_BUTTON_BAR_LABEL_FONT:
574 m_button_bar_label_font = font;
575 break;
576 case wxRIBBON_ART_PANEL_LABEL_FONT:
577 m_panel_label_font = font;
578 break;
579 default:
580 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
581 break;
582 }
583 }
584
585 wxFont wxRibbonMSWArtProvider::GetFont(int id) const
586 {
587 switch(id)
588 {
589 case wxRIBBON_ART_TAB_LABEL_FONT:
590 return m_tab_label_font;
591 case wxRIBBON_ART_BUTTON_BAR_LABEL_FONT:
592 return m_button_bar_label_font;
593 case wxRIBBON_ART_PANEL_LABEL_FONT:
594 return m_panel_label_font;
595 default:
596 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
597 break;
598 }
599
600 return wxNullFont;
601 }
602
603 wxColour wxRibbonMSWArtProvider::GetColour(int id) const
604 {
605 switch(id)
606 {
607 case wxRIBBON_ART_BUTTON_BAR_LABEL_COLOUR:
608 return m_button_bar_label_colour;
609 case wxRIBBON_ART_BUTTON_BAR_HOVER_BORDER_COLOUR:
610 return m_button_bar_hover_border_pen.GetColour();
611 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_COLOUR:
612 return m_button_bar_hover_background_top_colour;
613 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
614 return m_button_bar_hover_background_top_gradient_colour;
615 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_COLOUR:
616 return m_button_bar_hover_background_colour;
617 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_GRADIENT_COLOUR:
618 return m_button_bar_hover_background_gradient_colour;
619 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BORDER_COLOUR:
620 return m_button_bar_active_border_pen.GetColour();
621 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_COLOUR:
622 return m_button_bar_active_background_top_colour;
623 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
624 return m_button_bar_active_background_top_gradient_colour;
625 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_COLOUR:
626 return m_button_bar_active_background_colour;
627 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
628 return m_button_bar_active_background_gradient_colour;
629 case wxRIBBON_ART_GALLERY_BORDER_COLOUR:
630 return m_gallery_border_pen.GetColour();
631 case wxRIBBON_ART_GALLERY_HOVER_BACKGROUND_COLOUR:
632 return m_gallery_hover_background_brush.GetColour();
633 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_COLOUR:
634 return m_gallery_button_background_colour;
635 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_GRADIENT_COLOUR:
636 return m_gallery_button_background_gradient_colour;
637 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_TOP_COLOUR:
638 return m_gallery_button_background_top_brush.GetColour();
639 case wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR:
640 return m_gallery_button_face_colour;
641 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_COLOUR:
642 return m_gallery_button_hover_background_colour;
643 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_GRADIENT_COLOUR:
644 return m_gallery_button_hover_background_gradient_colour;
645 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_TOP_COLOUR:
646 return m_gallery_button_hover_background_top_brush.GetColour();
647 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR:
648 return m_gallery_button_face_colour;
649 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_COLOUR:
650 return m_gallery_button_active_background_colour;
651 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
652 return m_gallery_button_active_background_gradient_colour;
653 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_TOP_COLOUR:
654 return m_gallery_button_background_top_brush.GetColour();
655 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR:
656 return m_gallery_button_active_face_colour;
657 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_COLOUR:
658 return m_gallery_button_disabled_background_colour;
659 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_GRADIENT_COLOUR:
660 return m_gallery_button_disabled_background_gradient_colour;
661 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_TOP_COLOUR:
662 return m_gallery_button_disabled_background_top_brush.GetColour();
663 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR:
664 return m_gallery_button_disabled_face_colour;
665 case wxRIBBON_ART_GALLERY_ITEM_BORDER_COLOUR:
666 return m_gallery_item_border_pen.GetColour();
667 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_COLOUR:
668 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_GRADIENT_COLOUR:
669 return m_tab_ctrl_background_brush.GetColour();
670 case wxRIBBON_ART_TAB_LABEL_COLOUR:
671 return m_tab_label_colour;
672 case wxRIBBON_ART_TAB_SEPARATOR_COLOUR:
673 return m_tab_separator_colour;
674 case wxRIBBON_ART_TAB_SEPARATOR_GRADIENT_COLOUR:
675 return m_tab_separator_gradient_colour;
676 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_COLOUR:
677 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
678 return wxColour(0, 0, 0);
679 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_COLOUR:
680 return m_tab_active_background_colour;
681 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
682 return m_tab_active_background_gradient_colour;
683 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_COLOUR:
684 return m_tab_hover_background_top_colour;
685 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
686 return m_tab_hover_background_top_gradient_colour;
687 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_COLOUR:
688 return m_tab_hover_background_colour;
689 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_GRADIENT_COLOUR:
690 return m_tab_hover_background_gradient_colour;
691 case wxRIBBON_ART_TAB_BORDER_COLOUR:
692 return m_tab_border_pen.GetColour();
693 case wxRIBBON_ART_PANEL_BORDER_COLOUR:
694 return m_panel_border_pen.GetColour();
695 case wxRIBBON_ART_PANEL_BORDER_GRADIENT_COLOUR:
696 return m_panel_border_gradient_pen.GetColour();
697 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_COLOUR:
698 return m_panel_minimised_border_pen.GetColour();
699 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_GRADIENT_COLOUR:
700 return m_panel_minimised_border_gradient_pen.GetColour();
701 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_COLOUR:
702 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_GRADIENT_COLOUR:
703 return m_panel_label_background_brush.GetColour();
704 case wxRIBBON_ART_PANEL_LABEL_COLOUR:
705 return m_panel_label_colour;
706 case wxRIBBON_ART_PANEL_MINIMISED_LABEL_COLOUR:
707 return m_panel_minimised_label_colour;
708 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_COLOUR:
709 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_GRADIENT_COLOUR:
710 return m_panel_hover_label_background_brush.GetColour();
711 case wxRIBBON_ART_PANEL_HOVER_LABEL_COLOUR:
712 return m_panel_hover_label_colour;
713 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_COLOUR:
714 return m_panel_active_background_top_colour;
715 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
716 return m_panel_active_background_top_gradient_colour;
717 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_COLOUR:
718 return m_panel_active_background_colour;
719 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
720 return m_panel_active_background_gradient_colour;
721 case wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR:
722 return m_panel_button_face_colour;
723 case wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR:
724 return m_panel_button_hover_face_colour;
725 case wxRIBBON_ART_PAGE_BORDER_COLOUR:
726 return m_page_border_pen.GetColour();
727 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_COLOUR:
728 return m_page_background_top_colour;
729 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_GRADIENT_COLOUR:
730 return m_page_background_top_gradient_colour;
731 case wxRIBBON_ART_PAGE_BACKGROUND_COLOUR:
732 return m_page_background_colour;
733 case wxRIBBON_ART_PAGE_BACKGROUND_GRADIENT_COLOUR:
734 return m_page_background_gradient_colour;
735 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_COLOUR:
736 return m_page_hover_background_top_colour;
737 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
738 return m_page_hover_background_top_gradient_colour;
739 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_COLOUR:
740 return m_page_hover_background_colour;
741 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_GRADIENT_COLOUR:
742 return m_page_hover_background_gradient_colour;
743 case wxRIBBON_ART_TOOLBAR_BORDER_COLOUR:
744 case wxRIBBON_ART_TOOLBAR_HOVER_BORDER_COLOUR:
745 return m_toolbar_border_pen.GetColour();
746 case wxRIBBON_ART_TOOLBAR_FACE_COLOUR:
747 return m_tool_face_colour;
748 case wxRIBBON_ART_PAGE_TOGGLE_FACE_COLOUR:
749 return m_page_toggle_face_colour;
750 case wxRIBBON_ART_PAGE_TOGGLE_HOVER_FACE_COLOUR:
751 return m_page_toggle_hover_face_colour;
752 default:
753 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
754 break;
755 }
756
757 return wxColour();
758 }
759
760 void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour)
761 {
762 switch(id)
763 {
764 case wxRIBBON_ART_BUTTON_BAR_LABEL_COLOUR:
765 m_button_bar_label_colour = colour;
766 break;
767 case wxRIBBON_ART_BUTTON_BAR_HOVER_BORDER_COLOUR:
768 m_button_bar_hover_border_pen.SetColour(colour);
769 break;
770 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_COLOUR:
771 m_button_bar_hover_background_top_colour = colour;
772 break;
773 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
774 m_button_bar_hover_background_top_gradient_colour = colour;
775 break;
776 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_COLOUR:
777 m_button_bar_hover_background_colour = colour;
778 break;
779 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_GRADIENT_COLOUR:
780 m_button_bar_hover_background_gradient_colour = colour;
781 break;
782 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BORDER_COLOUR:
783 m_button_bar_active_border_pen.SetColour(colour);
784 break;
785 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_COLOUR:
786 m_button_bar_active_background_top_colour = colour;
787 break;
788 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
789 m_button_bar_active_background_top_gradient_colour = colour;
790 break;
791 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_COLOUR:
792 m_button_bar_active_background_colour = colour;
793 break;
794 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
795 m_button_bar_active_background_gradient_colour = colour;
796 break;
797 case wxRIBBON_ART_GALLERY_BORDER_COLOUR:
798 m_gallery_border_pen.SetColour(colour);
799 break;
800 case wxRIBBON_ART_GALLERY_HOVER_BACKGROUND_COLOUR:
801 m_gallery_hover_background_brush.SetColour(colour);
802 break;
803 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_COLOUR:
804 m_gallery_button_background_colour = colour;
805 break;
806 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_GRADIENT_COLOUR:
807 m_gallery_button_background_gradient_colour = colour;
808 break;
809 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_TOP_COLOUR:
810 m_gallery_button_background_top_brush.SetColour(colour);
811 break;
812 case wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR:
813 m_gallery_button_face_colour = colour;
814 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
815 {
816 m_gallery_up_bitmap[0] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
817 m_gallery_down_bitmap[0] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
818 }
819 else
820 {
821 m_gallery_up_bitmap[0] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
822 m_gallery_down_bitmap[0] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
823 }
824 m_gallery_extension_bitmap[0] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
825 break;
826 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_COLOUR:
827 m_gallery_button_hover_background_colour = colour;
828 break;
829 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_GRADIENT_COLOUR:
830 m_gallery_button_hover_background_gradient_colour = colour;
831 break;
832 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_TOP_COLOUR:
833 m_gallery_button_hover_background_top_brush.SetColour(colour);
834 break;
835 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR:
836 m_gallery_button_hover_face_colour = colour;
837 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
838 {
839 m_gallery_up_bitmap[1] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
840 m_gallery_down_bitmap[1] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
841 }
842 else
843 {
844 m_gallery_up_bitmap[1] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
845 m_gallery_down_bitmap[1] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
846 }
847 m_gallery_extension_bitmap[1] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
848 break;
849 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_COLOUR:
850 m_gallery_button_active_background_colour = colour;
851 break;
852 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
853 m_gallery_button_active_background_gradient_colour = colour;
854 break;
855 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_TOP_COLOUR:
856 m_gallery_button_background_top_brush.SetColour(colour);
857 break;
858 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR:
859 m_gallery_button_active_face_colour = colour;
860 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
861 {
862 m_gallery_up_bitmap[2] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
863 m_gallery_down_bitmap[2] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
864 }
865 else
866 {
867 m_gallery_up_bitmap[2] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
868 m_gallery_down_bitmap[2] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
869 }
870 m_gallery_extension_bitmap[2] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
871 break;
872 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_COLOUR:
873 m_gallery_button_disabled_background_colour = colour;
874 break;
875 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_GRADIENT_COLOUR:
876 m_gallery_button_disabled_background_gradient_colour = colour;
877 break;
878 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_TOP_COLOUR:
879 m_gallery_button_disabled_background_top_brush.SetColour(colour);
880 break;
881 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR:
882 m_gallery_button_disabled_face_colour = colour;
883 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
884 {
885 m_gallery_up_bitmap[3] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
886 m_gallery_down_bitmap[3] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
887 }
888 else
889 {
890 m_gallery_up_bitmap[3] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
891 m_gallery_down_bitmap[3] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
892 }
893 m_gallery_extension_bitmap[3] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
894 break;
895 case wxRIBBON_ART_GALLERY_ITEM_BORDER_COLOUR:
896 m_gallery_item_border_pen.SetColour(colour);
897 break;
898 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_COLOUR:
899 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_GRADIENT_COLOUR:
900 m_tab_ctrl_background_brush.SetColour(colour);
901 m_cached_tab_separator_visibility = -1.0;
902 break;
903 case wxRIBBON_ART_TAB_LABEL_COLOUR:
904 m_tab_label_colour = colour;
905 break;
906 case wxRIBBON_ART_TAB_SEPARATOR_COLOUR:
907 m_tab_separator_colour = colour;
908 m_cached_tab_separator_visibility = -1.0;
909 break;
910 case wxRIBBON_ART_TAB_SEPARATOR_GRADIENT_COLOUR:
911 m_tab_separator_gradient_colour = colour;
912 m_cached_tab_separator_visibility = -1.0;
913 break;
914 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_COLOUR:
915 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
916 break;
917 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_COLOUR:
918 m_tab_active_background_colour = colour;
919 break;
920 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
921 m_tab_active_background_gradient_colour = colour;
922 break;
923 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_COLOUR:
924 m_tab_hover_background_top_colour = colour;
925 break;
926 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
927 m_tab_hover_background_top_gradient_colour = colour;
928 break;
929 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_COLOUR:
930 m_tab_hover_background_colour = colour;
931 break;
932 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_GRADIENT_COLOUR:
933 m_tab_hover_background_gradient_colour = colour;
934 break;
935 case wxRIBBON_ART_TAB_BORDER_COLOUR:
936 m_tab_border_pen.SetColour(colour);
937 break;
938 case wxRIBBON_ART_PANEL_BORDER_COLOUR:
939 m_panel_border_pen.SetColour(colour);
940 break;
941 case wxRIBBON_ART_PANEL_BORDER_GRADIENT_COLOUR:
942 m_panel_border_gradient_pen.SetColour(colour);
943 break;
944 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_COLOUR:
945 m_panel_minimised_border_pen.SetColour(colour);
946 break;
947 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_GRADIENT_COLOUR:
948 m_panel_minimised_border_gradient_pen.SetColour(colour);
949 break;
950 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_COLOUR:
951 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_GRADIENT_COLOUR:
952 m_panel_label_background_brush.SetColour(colour);
953 break;
954 case wxRIBBON_ART_PANEL_LABEL_COLOUR:
955 m_panel_label_colour = colour;
956 break;
957 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_COLOUR:
958 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_GRADIENT_COLOUR:
959 m_panel_hover_label_background_brush.SetColour(colour);
960 break;
961 case wxRIBBON_ART_PANEL_HOVER_LABEL_COLOUR:
962 m_panel_hover_label_colour = colour;
963 break;
964 case wxRIBBON_ART_PANEL_MINIMISED_LABEL_COLOUR:
965 m_panel_minimised_label_colour = colour;
966 break;
967 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_COLOUR:
968 m_panel_active_background_top_colour = colour;
969 break;
970 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
971 m_panel_active_background_top_gradient_colour = colour;
972 break;
973 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_COLOUR:
974 m_panel_active_background_colour = colour;
975 break;
976 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
977 m_panel_active_background_gradient_colour = colour;
978 break;
979 case wxRIBBON_ART_PANEL_BUTTON_FACE_COLOUR:
980 m_panel_button_face_colour = colour;
981 m_panel_extension_bitmap[0] = wxRibbonLoadPixmap(panel_extension_xpm, colour);
982 break;
983 case wxRIBBON_ART_PANEL_BUTTON_HOVER_FACE_COLOUR:
984 m_panel_button_hover_face_colour = colour;
985 m_panel_extension_bitmap[1] = wxRibbonLoadPixmap(panel_extension_xpm, colour);
986 break;
987 case wxRIBBON_ART_PAGE_BORDER_COLOUR:
988 m_page_border_pen.SetColour(colour);
989 break;
990 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_COLOUR:
991 m_page_background_top_colour = colour;
992 break;
993 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_GRADIENT_COLOUR:
994 m_page_background_top_gradient_colour = colour;
995 break;
996 case wxRIBBON_ART_PAGE_BACKGROUND_COLOUR:
997 m_page_background_colour = colour;
998 break;
999 case wxRIBBON_ART_PAGE_BACKGROUND_GRADIENT_COLOUR:
1000 m_page_background_gradient_colour = colour;
1001 break;
1002 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_COLOUR:
1003 m_page_hover_background_top_colour = colour;
1004 break;
1005 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
1006 m_page_hover_background_top_gradient_colour = colour;
1007 break;
1008 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_COLOUR:
1009 m_page_hover_background_colour = colour;
1010 break;
1011 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_GRADIENT_COLOUR:
1012 m_page_hover_background_gradient_colour = colour;
1013 break;
1014 case wxRIBBON_ART_TOOLBAR_BORDER_COLOUR:
1015 case wxRIBBON_ART_TOOLBAR_HOVER_BORDER_COLOUR:
1016 m_toolbar_border_pen.SetColour(colour);
1017 break;
1018 case wxRIBBON_ART_TOOLBAR_FACE_COLOUR:
1019 m_tool_face_colour = colour;
1020 m_toolbar_drop_bitmap = wxRibbonLoadPixmap(gallery_down_xpm, colour);
1021 break;
1022 case wxRIBBON_ART_PAGE_TOGGLE_FACE_COLOUR:
1023 m_page_toggle_face_colour = colour;
1024 m_ribbon_toggle_down_bitmap[0] = wxRibbonLoadPixmap(panel_toggle_down_xpm, colour);
1025 m_ribbon_toggle_up_bitmap[0] = wxRibbonLoadPixmap(panel_toggle_up_xpm, colour);
1026 break;
1027 case wxRIBBON_ART_PAGE_TOGGLE_HOVER_FACE_COLOUR:
1028 m_page_toggle_hover_face_colour = colour;
1029 m_ribbon_toggle_down_bitmap[1] = wxRibbonLoadPixmap(panel_toggle_down_xpm, colour);
1030 m_ribbon_toggle_up_bitmap[1] = wxRibbonLoadPixmap(panel_toggle_up_xpm, colour);
1031 break;
1032 default:
1033 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
1034 break;
1035 }
1036 }
1037
1038 void wxRibbonMSWArtProvider::DrawTabCtrlBackground(
1039 wxDC& dc,
1040 wxWindow* WXUNUSED(wnd),
1041 const wxRect& rect)
1042 {
1043 dc.SetPen(*wxTRANSPARENT_PEN);
1044 dc.SetBrush(m_tab_ctrl_background_brush);
1045 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
1046
1047 dc.SetPen(m_page_border_pen);
1048 if(rect.width > 6)
1049 {
1050 dc.DrawLine(rect.x + 3, rect.y + rect.height - 1, rect.x + rect.width - 3, rect.y + rect.height - 1);
1051 }
1052 else
1053 {
1054 dc.DrawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1);
1055 }
1056 }
1057
1058 void wxRibbonMSWArtProvider::DrawTab(
1059 wxDC& dc,
1060 wxWindow* WXUNUSED(wnd),
1061 const wxRibbonPageTabInfo& tab)
1062 {
1063 if(tab.rect.height <= 2)
1064 return;
1065
1066 if(tab.active || tab.hovered)
1067 {
1068 if(tab.active)
1069 {
1070 wxRect background(tab.rect);
1071
1072 background.x += 2;
1073 background.y += 2;
1074 background.width -= 4;
1075 background.height -= 2;
1076
1077 dc.GradientFillLinear(background, m_tab_active_background_colour,
1078 m_tab_active_background_gradient_colour, wxSOUTH);
1079
1080 // TODO: active and hovered
1081 }
1082 else if(tab.hovered)
1083 {
1084 wxRect background(tab.rect);
1085
1086 background.x += 2;
1087 background.y += 2;
1088 background.width -= 4;
1089 background.height -= 3;
1090 int h = background.height;
1091 background.height /= 2;
1092 dc.GradientFillLinear(background,
1093 m_tab_hover_background_top_colour,
1094 m_tab_hover_background_top_gradient_colour, wxSOUTH);
1095
1096 background.y += background.height;
1097 background.height = h - background.height;
1098 dc.GradientFillLinear(background, m_tab_hover_background_colour,
1099 m_tab_hover_background_gradient_colour, wxSOUTH);
1100 }
1101
1102 wxPoint border_points[6];
1103 border_points[0] = wxPoint(1, tab.rect.height - 2);
1104 border_points[1] = wxPoint(1, 3);
1105 border_points[2] = wxPoint(3, 1);
1106 border_points[3] = wxPoint(tab.rect.width - 4, 1);
1107 border_points[4] = wxPoint(tab.rect.width - 2, 3);
1108 border_points[5] = wxPoint(tab.rect.width - 2, tab.rect.height - 1);
1109
1110 dc.SetPen(m_tab_border_pen);
1111 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, tab.rect.x, tab.rect.y);
1112
1113 if(tab.active)
1114 {
1115 // Give the tab a curved outward border at the bottom
1116 dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 2);
1117 dc.DrawPoint(tab.rect.x + tab.rect.width - 1, tab.rect.y + tab.rect.height - 2);
1118
1119 wxPen p(m_tab_active_background_gradient_colour);
1120 dc.SetPen(p);
1121
1122 // Technically the first two points are the wrong colour, but they're near enough
1123 dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 2);
1124 dc.DrawPoint(tab.rect.x + tab.rect.width - 2, tab.rect.y + tab.rect.height - 2);
1125 dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 1);
1126 dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 1);
1127 dc.DrawPoint(tab.rect.x + tab.rect.width - 2, tab.rect.y + tab.rect.height - 1);
1128 dc.DrawPoint(tab.rect.x + tab.rect.width - 1, tab.rect.y + tab.rect.height - 1);
1129 }
1130 }
1131
1132 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
1133 {
1134 wxBitmap icon = tab.page->GetIcon();
1135 if(icon.IsOk())
1136 {
1137 int x = tab.rect.x + 4;
1138 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) == 0)
1139 x = tab.rect.x + (tab.rect.width - icon.GetWidth()) / 2;
1140 dc.DrawBitmap(icon, x, tab.rect.y + 1 + (tab.rect.height - 1 -
1141 icon.GetHeight()) / 2, true);
1142 }
1143 }
1144 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS)
1145 {
1146 wxString label = tab.page->GetLabel();
1147 if(!label.IsEmpty())
1148 {
1149 dc.SetFont(m_tab_label_font);
1150 dc.SetTextForeground(m_tab_label_colour);
1151 dc.SetBackgroundMode(wxTRANSPARENT);
1152
1153 int text_height;
1154 int text_width;
1155 dc.GetTextExtent(label, &text_width, &text_height);
1156 int width = tab.rect.width - 5;
1157 int x = tab.rect.x + 3;
1158 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
1159 {
1160 x += 3 + tab.page->GetIcon().GetWidth();
1161 width -= 3 + tab.page->GetIcon().GetWidth();
1162 }
1163 int y = tab.rect.y + (tab.rect.height - text_height) / 2;
1164
1165 if(width <= text_width)
1166 {
1167 dc.SetClippingRegion(x, tab.rect.y, width, tab.rect.height);
1168 dc.DrawText(label, x, y);
1169 }
1170 else
1171 {
1172 dc.DrawText(label, x + (width - text_width) / 2 + 1, y);
1173 }
1174 }
1175 }
1176 }
1177
1178 void wxRibbonMSWArtProvider::DrawTabSeparator(
1179 wxDC& dc,
1180 wxWindow* wnd,
1181 const wxRect& rect,
1182 double visibility)
1183 {
1184 if(visibility <= 0.0)
1185 {
1186 return;
1187 }
1188 if(visibility > 1.0)
1189 {
1190 visibility = 1.0;
1191 }
1192
1193 // The tab separator is relatively expensive to draw (for its size), and is
1194 // usually drawn multiple times sequentially (in different positions), so it
1195 // makes sense to draw it once and cache it.
1196 if(!m_cached_tab_separator.IsOk() || m_cached_tab_separator.GetSize() != rect.GetSize() || visibility != m_cached_tab_separator_visibility)
1197 {
1198 wxRect size(rect.GetSize());
1199 ReallyDrawTabSeparator(wnd, size, visibility);
1200 }
1201 dc.DrawBitmap(m_cached_tab_separator, rect.x, rect.y, false);
1202 }
1203
1204 void wxRibbonMSWArtProvider::ReallyDrawTabSeparator(wxWindow* wnd, const wxRect& rect, double visibility)
1205 {
1206 if(!m_cached_tab_separator.IsOk() || m_cached_tab_separator.GetSize() != rect.GetSize())
1207 {
1208 m_cached_tab_separator = wxBitmap(rect.GetSize());
1209 }
1210
1211 wxMemoryDC dc(m_cached_tab_separator);
1212 DrawTabCtrlBackground(dc, wnd, rect);
1213
1214 wxCoord x = rect.x + rect.width / 2;
1215 double h = (double)(rect.height - 1);
1216
1217 double r1 = m_tab_ctrl_background_brush.GetColour().Red() * (1.0 - visibility) + 0.5;
1218 double g1 = m_tab_ctrl_background_brush.GetColour().Green() * (1.0 - visibility) + 0.5;
1219 double b1 = m_tab_ctrl_background_brush.GetColour().Blue() * (1.0 - visibility) + 0.5;
1220 double r2 = m_tab_separator_colour.Red();
1221 double g2 = m_tab_separator_colour.Green();
1222 double b2 = m_tab_separator_colour.Blue();
1223 double r3 = m_tab_separator_gradient_colour.Red();
1224 double g3 = m_tab_separator_gradient_colour.Green();
1225 double b3 = m_tab_separator_gradient_colour.Blue();
1226
1227 for(int i = 0; i < rect.height - 1; ++i)
1228 {
1229 double p = ((double)i)/h;
1230
1231 double r = (p * r3 + (1.0 - p) * r2) * visibility + r1;
1232 double g = (p * g3 + (1.0 - p) * g2) * visibility + g1;
1233 double b = (p * b3 + (1.0 - p) * b2) * visibility + b1;
1234
1235 wxPen P(wxColour((unsigned char)r, (unsigned char)g, (unsigned char)b));
1236 dc.SetPen(P);
1237 dc.DrawPoint(x, rect.y + i);
1238 }
1239
1240 m_cached_tab_separator_visibility = visibility;
1241 }
1242
1243 void wxRibbonMSWArtProvider::DrawPartialPageBackground(wxDC& dc,
1244 wxWindow* wnd, const wxRect& rect, wxRibbonPage* page,
1245 wxPoint offset, bool hovered)
1246 {
1247 wxRect background;
1248 // Expanded panels need a background - the expanded panel at
1249 // best size may have a greater Y dimension higher than when
1250 // on the bar if it has a sizer. AUI art provider does not need this
1251 // because it paints the panel without reference to its parent's size.
1252 // Expanded panels use a wxFrame as parent (not a wxRibbonPage).
1253
1254 if(wnd->GetSizer() && wnd->GetParent() != page)
1255 {
1256 background = wnd->GetParent()->GetSize();
1257 offset = wxPoint(0,0);
1258 }
1259 else
1260 {
1261 background = page->GetSize();
1262 page->AdjustRectToIncludeScrollButtons(&background);
1263 background.height -= 2;
1264 }
1265 // Page background isn't dependant upon the width of the page
1266 // (at least not the part of it intended to be painted by this
1267 // function). Set to wider than the page itself for when externally
1268 // expanded panels need a background - the expanded panel can be wider
1269 // than the bar.
1270 background.x = 0;
1271 background.width = INT_MAX;
1272
1273 // upper_rect, lower_rect, paint_rect are all in page co-ordinates
1274 wxRect upper_rect(background);
1275 upper_rect.height /= 5;
1276
1277 wxRect lower_rect(background);
1278 lower_rect.y += upper_rect.height;
1279 lower_rect.height -= upper_rect.height;
1280
1281 wxRect paint_rect(rect);
1282 paint_rect.x += offset.x;
1283 paint_rect.y += offset.y;
1284
1285 wxColour bg_top, bg_top_grad, bg_btm, bg_btm_grad;
1286 if(hovered)
1287 {
1288 bg_top = m_page_hover_background_top_colour;
1289 bg_top_grad = m_page_hover_background_top_gradient_colour;
1290 bg_btm = m_page_hover_background_colour;
1291 bg_btm_grad = m_page_hover_background_gradient_colour;
1292 }
1293 else
1294 {
1295 bg_top = m_page_background_top_colour;
1296 bg_top_grad = m_page_background_top_gradient_colour;
1297 bg_btm = m_page_background_colour;
1298 bg_btm_grad = m_page_background_gradient_colour;
1299 }
1300
1301 if(paint_rect.Intersects(upper_rect))
1302 {
1303 wxRect rect(upper_rect);
1304 rect.Intersect(paint_rect);
1305 rect.x -= offset.x;
1306 rect.y -= offset.y;
1307 wxColour starting_colour(wxRibbonInterpolateColour(bg_top, bg_top_grad,
1308 paint_rect.y, upper_rect.y, upper_rect.y + upper_rect.height));
1309 wxColour ending_colour(wxRibbonInterpolateColour(bg_top, bg_top_grad,
1310 paint_rect.y + paint_rect.height, upper_rect.y,
1311 upper_rect.y + upper_rect.height));
1312 dc.GradientFillLinear(rect, starting_colour, ending_colour, wxSOUTH);
1313 }
1314
1315 if(paint_rect.Intersects(lower_rect))
1316 {
1317 wxRect rect(lower_rect);
1318 rect.Intersect(paint_rect);
1319 rect.x -= offset.x;
1320 rect.y -= offset.y;
1321 wxColour starting_colour(wxRibbonInterpolateColour(bg_btm, bg_btm_grad,
1322 paint_rect.y, lower_rect.y, lower_rect.y + lower_rect.height));
1323 wxColour ending_colour(wxRibbonInterpolateColour(bg_btm, bg_btm_grad,
1324 paint_rect.y + paint_rect.height,
1325 lower_rect.y, lower_rect.y + lower_rect.height));
1326 dc.GradientFillLinear(rect, starting_colour, ending_colour, wxSOUTH);
1327 }
1328 }
1329
1330 void wxRibbonMSWArtProvider::DrawPageBackground(
1331 wxDC& dc,
1332 wxWindow* WXUNUSED(wnd),
1333 const wxRect& rect)
1334 {
1335 dc.SetPen(*wxTRANSPARENT_PEN);
1336 dc.SetBrush(m_tab_ctrl_background_brush);
1337
1338 {
1339 wxRect edge(rect);
1340
1341 edge.width = 2;
1342 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1343
1344 edge.x += rect.width - 2;
1345 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1346
1347 edge = rect;
1348 edge.height = 2;
1349 edge.y += (rect.height - edge.height);
1350 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1351 }
1352
1353 {
1354 wxRect background(rect);
1355 background.x += 2;
1356 background.width -= 4;
1357 background.height -= 2;
1358
1359 background.height /= 5;
1360 dc.GradientFillLinear(background, m_page_background_top_colour,
1361 m_page_background_top_gradient_colour, wxSOUTH);
1362
1363 background.y += background.height;
1364 background.height = rect.height - 2 - background.height;
1365 dc.GradientFillLinear(background, m_page_background_colour,
1366 m_page_background_gradient_colour, wxSOUTH);
1367 }
1368
1369 {
1370 wxPoint border_points[8];
1371 border_points[0] = wxPoint(2, 0);
1372 border_points[1] = wxPoint(1, 1);
1373 border_points[2] = wxPoint(1, rect.height - 4);
1374 border_points[3] = wxPoint(3, rect.height - 2);
1375 border_points[4] = wxPoint(rect.width - 4, rect.height - 2);
1376 border_points[5] = wxPoint(rect.width - 2, rect.height - 4);
1377 border_points[6] = wxPoint(rect.width - 2, 1);
1378 border_points[7] = wxPoint(rect.width - 4, -1);
1379
1380 dc.SetPen(m_page_border_pen);
1381 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1382 }
1383 }
1384
1385 void wxRibbonMSWArtProvider::DrawScrollButton(
1386 wxDC& dc,
1387 wxWindow* WXUNUSED(wnd),
1388 const wxRect& rect_,
1389 long style)
1390 {
1391 wxRect rect(rect_);
1392
1393 if((style & wxRIBBON_SCROLL_BTN_FOR_MASK) == wxRIBBON_SCROLL_BTN_FOR_PAGE)
1394 {
1395 // Page scroll buttons do not have the luxury of rendering on top of anything
1396 // else, and their size includes some padding, hence the background painting
1397 // and size adjustment.
1398 dc.SetPen(*wxTRANSPARENT_PEN);
1399 dc.SetBrush(m_tab_ctrl_background_brush);
1400 dc.DrawRectangle(rect);
1401 dc.SetClippingRegion(rect);
1402 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1403 {
1404 case wxRIBBON_SCROLL_BTN_LEFT:
1405 rect.x++;
1406 case wxRIBBON_SCROLL_BTN_RIGHT:
1407 rect.y--;
1408 rect.width--;
1409 break;
1410 case wxRIBBON_SCROLL_BTN_UP:
1411 rect.x++;
1412 rect.y--;
1413 rect.width -= 2;
1414 rect.height++;
1415 break;
1416 case wxRIBBON_SCROLL_BTN_DOWN:
1417 rect.x++;
1418 rect.width -= 2;
1419 rect.height--;
1420 break;
1421 }
1422 }
1423
1424 {
1425 wxRect background(rect);
1426 background.x++;
1427 background.y++;
1428 background.width -= 2;
1429 background.height -= 2;
1430
1431 if(style & wxRIBBON_SCROLL_BTN_UP)
1432 background.height /= 2;
1433 else
1434 background.height /= 5;
1435 dc.GradientFillLinear(background, m_page_background_top_colour,
1436 m_page_background_top_gradient_colour, wxSOUTH);
1437
1438 background.y += background.height;
1439 background.height = rect.height - 2 - background.height;
1440 dc.GradientFillLinear(background, m_page_background_colour,
1441 m_page_background_gradient_colour, wxSOUTH);
1442 }
1443
1444 {
1445 wxPoint border_points[7];
1446 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1447 {
1448 case wxRIBBON_SCROLL_BTN_LEFT:
1449 border_points[0] = wxPoint(2, 0);
1450 border_points[1] = wxPoint(rect.width - 1, 0);
1451 border_points[2] = wxPoint(rect.width - 1, rect.height - 1);
1452 border_points[3] = wxPoint(2, rect.height - 1);
1453 border_points[4] = wxPoint(0, rect.height - 3);
1454 border_points[5] = wxPoint(0, 2);
1455 break;
1456 case wxRIBBON_SCROLL_BTN_RIGHT:
1457 border_points[0] = wxPoint(0, 0);
1458 border_points[1] = wxPoint(rect.width - 3, 0);
1459 border_points[2] = wxPoint(rect.width - 1, 2);
1460 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
1461 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
1462 border_points[5] = wxPoint(0, rect.height - 1);
1463 break;
1464 case wxRIBBON_SCROLL_BTN_UP:
1465 border_points[0] = wxPoint(2, 0);
1466 border_points[1] = wxPoint(rect.width - 3, 0);
1467 border_points[2] = wxPoint(rect.width - 1, 2);
1468 border_points[3] = wxPoint(rect.width - 1, rect.height - 1);
1469 border_points[4] = wxPoint(0, rect.height - 1);
1470 border_points[5] = wxPoint(0, 2);
1471 break;
1472 case wxRIBBON_SCROLL_BTN_DOWN:
1473 border_points[0] = wxPoint(0, 0);
1474 border_points[1] = wxPoint(rect.width - 1, 0);
1475 border_points[2] = wxPoint(rect.width - 1, rect.height - 3);
1476 border_points[3] = wxPoint(rect.width - 3, rect.height - 1);
1477 border_points[4] = wxPoint(2, rect.height - 1);
1478 border_points[5] = wxPoint(0, rect.height - 3);
1479 break;
1480 }
1481 border_points[6] = border_points[0];
1482
1483 dc.SetPen(m_page_border_pen);
1484 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1485 }
1486
1487 {
1488 // NB: Code for handling hovered/active state is temporary
1489 wxPoint arrow_points[3];
1490 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1491 {
1492 case wxRIBBON_SCROLL_BTN_LEFT:
1493 arrow_points[0] = wxPoint(rect.width / 2 - 2, rect.height / 2);
1494 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1495 arrow_points[0].y += 1;
1496 arrow_points[1] = arrow_points[0] + wxPoint(3, -3);
1497 arrow_points[2] = arrow_points[0] + wxPoint(3, 3);
1498 break;
1499 case wxRIBBON_SCROLL_BTN_RIGHT:
1500 arrow_points[0] = wxPoint(rect.width / 2 + 2, rect.height / 2);
1501 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1502 arrow_points[0].y += 1;
1503 arrow_points[1] = arrow_points[0] - wxPoint(3, 3);
1504 arrow_points[2] = arrow_points[0] - wxPoint(3, -3);
1505 break;
1506 case wxRIBBON_SCROLL_BTN_UP:
1507 arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 - 2);
1508 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1509 arrow_points[0].y += 1;
1510 arrow_points[1] = arrow_points[0] + wxPoint( 3, 3);
1511 arrow_points[2] = arrow_points[0] + wxPoint(-3, 3);
1512 break;
1513 case wxRIBBON_SCROLL_BTN_DOWN:
1514 arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 + 2);
1515 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1516 arrow_points[0].y += 1;
1517 arrow_points[1] = arrow_points[0] - wxPoint( 3, 3);
1518 arrow_points[2] = arrow_points[0] - wxPoint(-3, 3);
1519 break;
1520 }
1521
1522 dc.SetPen(*wxTRANSPARENT_PEN);
1523 wxBrush B(style & wxRIBBON_SCROLL_BTN_HOVERED ? m_tab_active_background_colour : m_tab_label_colour);
1524 dc.SetBrush(B);
1525 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points, rect.x, rect.y);
1526 }
1527 }
1528
1529 void wxRibbonMSWArtProvider::DrawDropdownArrow(wxDC& dc, int x, int y, const wxColour& colour)
1530 {
1531 wxPoint arrow_points[3];
1532 wxBrush brush(colour);
1533 arrow_points[0] = wxPoint(1, 2);
1534 arrow_points[1] = arrow_points[0] + wxPoint(-3, -3);
1535 arrow_points[2] = arrow_points[0] + wxPoint( 3, -3);
1536 dc.SetPen(*wxTRANSPARENT_PEN);
1537 dc.SetBrush(brush);
1538 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points, x, y);
1539 }
1540
1541 void wxRibbonMSWArtProvider::RemovePanelPadding(wxRect* rect)
1542 {
1543 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1544 {
1545 rect->y += 1;
1546 rect->height -= 2;
1547 }
1548 else
1549 {
1550 rect->x += 1;
1551 rect->width -= 2;
1552 }
1553 }
1554
1555 void wxRibbonMSWArtProvider::DrawPanelBackground(
1556 wxDC& dc,
1557 wxRibbonPanel* wnd,
1558 const wxRect& rect)
1559 {
1560 DrawPartialPageBackground(dc, wnd, rect, false);
1561
1562 wxRect true_rect(rect);
1563 RemovePanelPadding(&true_rect);
1564 bool has_ext_button = wnd->HasExtButton();
1565
1566 int label_height;
1567 {
1568 dc.SetFont(m_panel_label_font);
1569 dc.SetPen(*wxTRANSPARENT_PEN);
1570 if(wnd->IsHovered())
1571 {
1572 dc.SetBrush(m_panel_hover_label_background_brush);
1573 dc.SetTextForeground(m_panel_hover_label_colour);
1574 }
1575 else
1576 {
1577 dc.SetBrush(m_panel_label_background_brush);
1578 dc.SetTextForeground(m_panel_label_colour);
1579 }
1580
1581 wxRect label_rect(true_rect);
1582 wxString label = wnd->GetLabel();
1583 bool clip_label = false;
1584 wxSize label_size(dc.GetTextExtent(label));
1585
1586 label_rect.SetX(label_rect.GetX() + 1);
1587 label_rect.SetWidth(label_rect.GetWidth() - 2);
1588 label_rect.SetHeight(label_size.GetHeight() + 2);
1589 label_rect.SetY(true_rect.GetBottom() - label_rect.GetHeight());
1590 label_height = label_rect.GetHeight();
1591
1592 wxRect label_bg_rect = label_rect;
1593
1594 if(has_ext_button)
1595 label_rect.SetWidth(label_rect.GetWidth() - 13);
1596
1597 if(label_size.GetWidth() > label_rect.GetWidth())
1598 {
1599 // Test if there is enough length for 3 letters and ...
1600 wxString new_label = label.Mid(0, 3) + wxT("...");
1601 label_size = dc.GetTextExtent(new_label);
1602 if(label_size.GetWidth() > label_rect.GetWidth())
1603 {
1604 // Not enough room for three characters and ...
1605 // Display the entire label and just crop it
1606 clip_label = true;
1607 }
1608 else
1609 {
1610 // Room for some characters and ...
1611 // Display as many characters as possible and append ...
1612 for(size_t len = label.Len() - 1; len >= 3; --len)
1613 {
1614 new_label = label.Mid(0, len) + wxT("...");
1615 label_size = dc.GetTextExtent(new_label);
1616 if(label_size.GetWidth() <= label_rect.GetWidth())
1617 {
1618 label = new_label;
1619 break;
1620 }
1621 }
1622 }
1623 }
1624
1625 dc.DrawRectangle(label_bg_rect);
1626 if(clip_label)
1627 {
1628 wxDCClipper clip(dc, label_rect);
1629 dc.DrawText(label, label_rect.x, label_rect.y +
1630 (label_rect.GetHeight() - label_size.GetHeight()) / 2);
1631 }
1632 else
1633 {
1634 dc.DrawText(label, label_rect.x +
1635 (label_rect.GetWidth() - label_size.GetWidth()) / 2,
1636 label_rect.y +
1637 (label_rect.GetHeight() - label_size.GetHeight()) / 2);
1638 }
1639
1640 if(has_ext_button)
1641 {
1642 if(wnd->IsExtButtonHovered())
1643 {
1644 dc.SetPen(m_panel_hover_button_border_pen);
1645 dc.SetBrush(m_panel_hover_button_background_brush);
1646 dc.DrawRoundedRectangle(label_rect.GetRight(), label_rect.GetBottom() - 13, 13, 13, 1.0);
1647 dc.DrawBitmap(m_panel_extension_bitmap[1], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
1648 }
1649 else
1650 dc.DrawBitmap(m_panel_extension_bitmap[0], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
1651 }
1652 }
1653
1654 if(wnd->IsHovered())
1655 {
1656 wxRect client_rect(true_rect);
1657 client_rect.x++;
1658 client_rect.width -= 2;
1659 client_rect.y++;
1660 client_rect.height -= 2 + label_height;
1661 DrawPartialPageBackground(dc, wnd, client_rect, true);
1662 }
1663
1664 DrawPanelBorder(dc, true_rect, m_panel_border_pen, m_panel_border_gradient_pen);
1665 }
1666
1667 wxRect wxRibbonMSWArtProvider::GetPanelExtButtonArea(wxDC& WXUNUSED(dc),
1668 const wxRibbonPanel* WXUNUSED(wnd),
1669 wxRect rect)
1670 {
1671 RemovePanelPadding(&rect);
1672 rect = wxRect(rect.GetRight()-13, rect.GetBottom()-13, 13, 13);
1673 return rect;
1674 }
1675
1676 void wxRibbonMSWArtProvider::DrawGalleryBackground(
1677 wxDC& dc,
1678 wxRibbonGallery* wnd,
1679 const wxRect& rect)
1680 {
1681 DrawPartialPageBackground(dc, wnd, rect);
1682
1683 if(wnd->IsHovered())
1684 {
1685 dc.SetPen(*wxTRANSPARENT_PEN);
1686 dc.SetBrush(m_gallery_hover_background_brush);
1687 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1688 {
1689 dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 2,
1690 rect.height - 16);
1691 }
1692 else
1693 {
1694 dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 16,
1695 rect.height - 2);
1696 }
1697 }
1698
1699 dc.SetPen(m_gallery_border_pen);
1700 // Outline
1701 dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
1702 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
1703 dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
1704 rect.y + rect.height - 1);
1705 dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
1706 rect.y + rect.height - 1);
1707
1708 DrawGalleryBackgroundCommon(dc, wnd, rect);
1709 }
1710
1711 void wxRibbonMSWArtProvider::DrawGalleryBackgroundCommon(wxDC& dc,
1712 wxRibbonGallery* wnd,
1713 const wxRect& rect)
1714 {
1715 wxRect up_btn, down_btn, ext_btn;
1716
1717 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1718 {
1719 // Divider between items and buttons
1720 dc.DrawLine(rect.x, rect.y + rect.height - 15, rect.x + rect.width,
1721 rect.y + rect.height - 15);
1722
1723 up_btn = wxRect(rect.x, rect.y + rect.height - 15, rect.width / 3, 15);
1724
1725 down_btn = wxRect(up_btn.GetRight() + 1, up_btn.GetTop(),
1726 up_btn.GetWidth(), up_btn.GetHeight());
1727 dc.DrawLine(down_btn.GetLeft(), down_btn.GetTop(), down_btn.GetLeft(),
1728 down_btn.GetBottom());
1729
1730 ext_btn = wxRect(down_btn.GetRight() + 1, up_btn.GetTop(), rect.width -
1731 up_btn.GetWidth() - down_btn.GetWidth() - 1, up_btn.GetHeight());
1732 dc.DrawLine(ext_btn.GetLeft(), ext_btn.GetTop(), ext_btn.GetLeft(),
1733 ext_btn.GetBottom());
1734 }
1735 else
1736 {
1737 // Divider between items and buttons
1738 dc.DrawLine(rect.x + rect.width - 15, rect.y, rect.x + rect.width - 15,
1739 rect.y + rect.height);
1740
1741 up_btn = wxRect(rect.x + rect.width - 15, rect.y, 15, rect.height / 3);
1742
1743 down_btn = wxRect(up_btn.GetLeft(), up_btn.GetBottom() + 1,
1744 up_btn.GetWidth(), up_btn.GetHeight());
1745 dc.DrawLine(down_btn.GetLeft(), down_btn.GetTop(), down_btn.GetRight(),
1746 down_btn.GetTop());
1747
1748 ext_btn = wxRect(up_btn.GetLeft(), down_btn.GetBottom() + 1, up_btn.GetWidth(),
1749 rect.height - up_btn.GetHeight() - down_btn.GetHeight() - 1);
1750 dc.DrawLine(ext_btn.GetLeft(), ext_btn.GetTop(), ext_btn.GetRight(),
1751 ext_btn.GetTop());
1752 }
1753
1754 DrawGalleryButton(dc, up_btn, wnd->GetUpButtonState(),
1755 m_gallery_up_bitmap);
1756 DrawGalleryButton(dc, down_btn, wnd->GetDownButtonState(),
1757 m_gallery_down_bitmap);
1758 DrawGalleryButton(dc, ext_btn, wnd->GetExtensionButtonState(),
1759 m_gallery_extension_bitmap);
1760 }
1761
1762 void wxRibbonMSWArtProvider::DrawGalleryButton(wxDC& dc,
1763 wxRect rect,
1764 wxRibbonGalleryButtonState state,
1765 wxBitmap* bitmaps)
1766 {
1767 wxBitmap btn_bitmap;
1768 wxBrush btn_top_brush;
1769 wxColour btn_colour;
1770 wxColour btn_grad_colour;
1771 switch(state)
1772 {
1773 case wxRIBBON_GALLERY_BUTTON_NORMAL:
1774 btn_top_brush = m_gallery_button_background_top_brush;
1775 btn_colour = m_gallery_button_background_colour;
1776 btn_grad_colour = m_gallery_button_background_gradient_colour;
1777 btn_bitmap = bitmaps[0];
1778 break;
1779 case wxRIBBON_GALLERY_BUTTON_HOVERED:
1780 btn_top_brush = m_gallery_button_hover_background_top_brush;
1781 btn_colour = m_gallery_button_hover_background_colour;
1782 btn_grad_colour = m_gallery_button_hover_background_gradient_colour;
1783 btn_bitmap = bitmaps[1];
1784 break;
1785 case wxRIBBON_GALLERY_BUTTON_ACTIVE:
1786 btn_top_brush = m_gallery_button_active_background_top_brush;
1787 btn_colour = m_gallery_button_active_background_colour;
1788 btn_grad_colour = m_gallery_button_active_background_gradient_colour;
1789 btn_bitmap = bitmaps[2];
1790 break;
1791 case wxRIBBON_GALLERY_BUTTON_DISABLED:
1792 btn_top_brush = m_gallery_button_disabled_background_top_brush;
1793 btn_colour = m_gallery_button_disabled_background_colour;
1794 btn_grad_colour = m_gallery_button_disabled_background_gradient_colour;
1795 btn_bitmap = bitmaps[3];
1796 break;
1797 }
1798
1799 rect.x++;
1800 rect.y++;
1801 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1802 {
1803 rect.width--;;
1804 rect.height -= 2;
1805 }
1806 else
1807 {
1808 rect.width -= 2;
1809 rect.height--;
1810 }
1811
1812 dc.SetPen(*wxTRANSPARENT_PEN);
1813 dc.SetBrush(btn_top_brush);
1814 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height / 2);
1815
1816 wxRect lower(rect);
1817 lower.height = (lower.height + 1) / 2;
1818 lower.y += rect.height - lower.height;
1819 dc.GradientFillLinear(lower, btn_colour, btn_grad_colour, wxSOUTH);
1820
1821 dc.DrawBitmap(btn_bitmap, rect.x + rect.width / 2 - 2, lower.y - 2, true);
1822 }
1823
1824 void wxRibbonMSWArtProvider::DrawGalleryItemBackground(
1825 wxDC& dc,
1826 wxRibbonGallery* wnd,
1827 const wxRect& rect,
1828 wxRibbonGalleryItem* item)
1829 {
1830 if(wnd->GetHoveredItem() != item && wnd->GetActiveItem() != item &&
1831 wnd->GetSelection() != item)
1832 return;
1833
1834 dc.SetPen(m_gallery_item_border_pen);
1835 dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
1836 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
1837 dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
1838 rect.y + rect.height - 1);
1839 dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
1840 rect.y + rect.height - 1);
1841
1842 wxBrush top_brush;
1843 wxColour bg_colour;
1844 wxColour bg_gradient_colour;
1845
1846 if(wnd->GetActiveItem() == item || wnd->GetSelection() == item)
1847 {
1848 top_brush = m_gallery_button_active_background_top_brush;
1849 bg_colour = m_gallery_button_active_background_colour;
1850 bg_gradient_colour = m_gallery_button_active_background_gradient_colour;
1851 }
1852 else
1853 {
1854 top_brush = m_gallery_button_hover_background_top_brush;
1855 bg_colour = m_gallery_button_hover_background_colour;
1856 bg_gradient_colour = m_gallery_button_hover_background_gradient_colour;
1857 }
1858
1859 wxRect upper(rect);
1860 upper.x += 1;
1861 upper.width -= 2;
1862 upper.y += 1;
1863 upper.height /= 3;
1864 dc.SetPen(*wxTRANSPARENT_PEN);
1865 dc.SetBrush(top_brush);
1866 dc.DrawRectangle(upper.x, upper.y, upper.width, upper.height);
1867
1868 wxRect lower(upper);
1869 lower.y += lower.height;
1870 lower.height = rect.height - 2 - lower.height;
1871 dc.GradientFillLinear(lower, bg_colour, bg_gradient_colour, wxSOUTH);
1872 }
1873
1874 void wxRibbonMSWArtProvider::DrawPanelBorder(wxDC& dc, const wxRect& rect,
1875 wxPen& primary_colour,
1876 wxPen& secondary_colour)
1877 {
1878 wxPoint border_points[9];
1879 border_points[0] = wxPoint(2, 0);
1880 border_points[1] = wxPoint(rect.width - 3, 0);
1881 border_points[2] = wxPoint(rect.width - 1, 2);
1882 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
1883 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
1884 border_points[5] = wxPoint(2, rect.height - 1);
1885 border_points[6] = wxPoint(0, rect.height - 3);
1886 border_points[7] = wxPoint(0, 2);
1887
1888 if(primary_colour.GetColour() == secondary_colour.GetColour())
1889 {
1890 border_points[8] = border_points[0];
1891 dc.SetPen(primary_colour);
1892 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1893 }
1894 else
1895 {
1896 dc.SetPen(primary_colour);
1897 dc.DrawLines(3, border_points, rect.x, rect.y);
1898
1899 #define SingleLine(start, finish) \
1900 dc.DrawLine(start.x + rect.x, start.y + rect.y, finish.x + rect.x, finish.y + rect.y)
1901
1902 SingleLine(border_points[0], border_points[7]);
1903 dc.SetPen(secondary_colour);
1904 dc.DrawLines(3, border_points + 4, rect.x, rect.y);
1905 SingleLine(border_points[4], border_points[3]);
1906
1907 #undef SingleLine
1908
1909 border_points[6] = border_points[2];
1910 wxRibbonDrawParallelGradientLines(dc, 2, border_points + 6, 0, 1,
1911 border_points[3].y - border_points[2].y + 1, rect.x, rect.y,
1912 primary_colour.GetColour(), secondary_colour.GetColour());
1913 }
1914 }
1915
1916 void wxRibbonMSWArtProvider::DrawMinimisedPanel(
1917 wxDC& dc,
1918 wxRibbonPanel* wnd,
1919 const wxRect& rect,
1920 wxBitmap& bitmap)
1921 {
1922 DrawPartialPageBackground(dc, wnd, rect, false);
1923
1924 wxRect true_rect(rect);
1925 RemovePanelPadding(&true_rect);
1926
1927 if(wnd->GetExpandedPanel() != NULL)
1928 {
1929 wxRect client_rect(true_rect);
1930 client_rect.x++;
1931 client_rect.width -= 2;
1932 client_rect.y++;
1933 client_rect.height = (rect.y + rect.height / 5) - client_rect.x;
1934 dc.GradientFillLinear(client_rect,
1935 m_panel_active_background_top_colour,
1936 m_panel_active_background_top_gradient_colour, wxSOUTH);
1937
1938 client_rect.y += client_rect.height;
1939 client_rect.height = (true_rect.y + true_rect.height) - client_rect.y;
1940 dc.GradientFillLinear(client_rect,
1941 m_panel_active_background_colour,
1942 m_panel_active_background_gradient_colour, wxSOUTH);
1943 }
1944 else if(wnd->IsHovered())
1945 {
1946 wxRect client_rect(true_rect);
1947 client_rect.x++;
1948 client_rect.width -= 2;
1949 client_rect.y++;
1950 client_rect.height -= 2;
1951 DrawPartialPageBackground(dc, wnd, client_rect, true);
1952 }
1953
1954 wxRect preview;
1955 DrawMinimisedPanelCommon(dc, wnd, true_rect, &preview);
1956
1957 dc.SetBrush(m_panel_hover_label_background_brush);
1958 dc.SetPen(*wxTRANSPARENT_PEN);
1959 dc.DrawRectangle(preview.x + 1, preview.y + preview.height - 8,
1960 preview.width - 2, 7);
1961
1962 int mid_pos = rect.y + rect.height / 5 - preview.y;
1963 if(mid_pos < 0 || mid_pos >= preview.height)
1964 {
1965 wxRect full_rect(preview);
1966 full_rect.x += 1;
1967 full_rect.y += 1;
1968 full_rect.width -= 2;
1969 full_rect.height -= 9;
1970 if(mid_pos < 0)
1971 {
1972 dc.GradientFillLinear(full_rect,
1973 m_page_hover_background_colour,
1974 m_page_hover_background_gradient_colour, wxSOUTH);
1975 }
1976 else
1977 {
1978 dc.GradientFillLinear(full_rect,
1979 m_page_hover_background_top_colour,
1980 m_page_hover_background_top_gradient_colour, wxSOUTH);
1981 }
1982 }
1983 else
1984 {
1985 wxRect top_rect(preview);
1986 top_rect.x += 1;
1987 top_rect.y += 1;
1988 top_rect.width -= 2;
1989 top_rect.height = mid_pos;
1990 dc.GradientFillLinear(top_rect,
1991 m_page_hover_background_top_colour,
1992 m_page_hover_background_top_gradient_colour, wxSOUTH);
1993
1994 wxRect btm_rect(top_rect);
1995 btm_rect.y = preview.y + mid_pos;
1996 btm_rect.height = preview.y + preview.height - 7 - btm_rect.y;
1997 dc.GradientFillLinear(btm_rect,
1998 m_page_hover_background_colour,
1999 m_page_hover_background_gradient_colour, wxSOUTH);
2000 }
2001
2002 if(bitmap.IsOk())
2003 {
2004 dc.DrawBitmap(bitmap, preview.x + (preview.width - bitmap.GetWidth()) / 2,
2005 preview.y + (preview.height - 7 - bitmap.GetHeight()) / 2, true);
2006 }
2007
2008 DrawPanelBorder(dc, preview, m_panel_border_pen, m_panel_border_gradient_pen);
2009
2010 DrawPanelBorder(dc, true_rect, m_panel_minimised_border_pen,
2011 m_panel_minimised_border_gradient_pen);
2012 }
2013
2014 void wxRibbonMSWArtProvider::DrawMinimisedPanelCommon(
2015 wxDC& dc,
2016 wxRibbonPanel* wnd,
2017 const wxRect& true_rect,
2018 wxRect* preview_rect)
2019 {
2020 wxRect preview(0, 0, 32, 32);
2021 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2022 {
2023 preview.x = true_rect.x + 4;
2024 preview.y = true_rect.y + (true_rect.height - preview.height) / 2;
2025 }
2026 else
2027 {
2028 preview.x = true_rect.x + (true_rect.width - preview.width) / 2;
2029 preview.y = true_rect.y + 4;
2030 }
2031 if(preview_rect)
2032 *preview_rect = preview;
2033
2034 wxCoord label_width, label_height;
2035 dc.SetFont(m_panel_label_font);
2036 dc.GetTextExtent(wnd->GetLabel(), &label_width, &label_height);
2037
2038 int xpos = true_rect.x + (true_rect.width - label_width + 1) / 2;
2039 int ypos = preview.y + preview.height + 5;
2040
2041 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2042 {
2043 xpos = preview.x + preview.width + 5;
2044 ypos = true_rect.y + (true_rect.height - label_height) / 2;
2045 }
2046
2047 dc.SetTextForeground(m_panel_minimised_label_colour);
2048 dc.DrawText(wnd->GetLabel(), xpos, ypos);
2049
2050
2051 wxPoint arrow_points[3];
2052 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2053 {
2054 xpos += label_width;
2055 arrow_points[0] = wxPoint(xpos + 5, ypos + label_height / 2);
2056 arrow_points[1] = arrow_points[0] + wxPoint(-3, 3);
2057 arrow_points[2] = arrow_points[0] + wxPoint(-3, -3);
2058 }
2059 else
2060 {
2061 ypos += label_height;
2062 arrow_points[0] = wxPoint(true_rect.width / 2, ypos + 5);
2063 arrow_points[1] = arrow_points[0] + wxPoint(-3, -3);
2064 arrow_points[2] = arrow_points[0] + wxPoint( 3, -3);
2065 }
2066
2067 dc.SetPen(*wxTRANSPARENT_PEN);
2068 wxBrush B(m_panel_minimised_label_colour);
2069 dc.SetBrush(B);
2070 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points,
2071 true_rect.x, true_rect.y);
2072 }
2073
2074 void wxRibbonMSWArtProvider::DrawButtonBarBackground(
2075 wxDC& dc,
2076 wxWindow* wnd,
2077 const wxRect& rect)
2078 {
2079 DrawPartialPageBackground(dc, wnd, rect, true);
2080 }
2081
2082 void wxRibbonMSWArtProvider::DrawPartialPageBackground(
2083 wxDC& dc,
2084 wxWindow* wnd,
2085 const wxRect& rect,
2086 bool allow_hovered)
2087 {
2088 // Assume the window is a child of a ribbon page, and also check for a
2089 // hovered panel somewhere between the window and the page, as it causes
2090 // the background to change.
2091 wxPoint offset(wnd->GetPosition());
2092 wxRibbonPage* page = NULL;
2093 wxWindow* parent = wnd->GetParent();
2094 wxRibbonPanel* panel = wxDynamicCast(wnd, wxRibbonPanel);
2095 bool hovered = false;
2096
2097 if(panel != NULL)
2098 {
2099 hovered = allow_hovered && panel->IsHovered();
2100 if(panel->GetExpandedDummy() != NULL)
2101 {
2102 offset = panel->GetExpandedDummy()->GetPosition();
2103 parent = panel->GetExpandedDummy()->GetParent();
2104 }
2105 }
2106 for(; parent; parent = parent->GetParent())
2107 {
2108 if(panel == NULL)
2109 {
2110 panel = wxDynamicCast(parent, wxRibbonPanel);
2111 if(panel != NULL)
2112 {
2113 hovered = allow_hovered && panel->IsHovered();
2114 if(panel->GetExpandedDummy() != NULL)
2115 {
2116 parent = panel->GetExpandedDummy();
2117 }
2118 }
2119 }
2120 page = wxDynamicCast(parent, wxRibbonPage);
2121 if(page != NULL)
2122 {
2123 break;
2124 }
2125 offset += parent->GetPosition();
2126 }
2127 if(page != NULL)
2128 {
2129 DrawPartialPageBackground(dc, wnd, rect, page, offset, hovered);
2130 return;
2131 }
2132
2133 // No page found - fallback to painting with a stock brush
2134 dc.SetBrush(*wxWHITE_BRUSH);
2135 dc.SetPen(*wxTRANSPARENT_PEN);
2136 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
2137 }
2138
2139 void wxRibbonMSWArtProvider::DrawButtonBarButton(
2140 wxDC& dc,
2141 wxWindow* WXUNUSED(wnd),
2142 const wxRect& rect,
2143 wxRibbonButtonKind kind,
2144 long state,
2145 const wxString& label,
2146 const wxBitmap& bitmap_large,
2147 const wxBitmap& bitmap_small)
2148 {
2149 if(kind == wxRIBBON_BUTTON_TOGGLE)
2150 {
2151 kind = wxRIBBON_BUTTON_NORMAL;
2152 if(state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED)
2153 state ^= wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
2154 }
2155
2156 if(state & (wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK |
2157 wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK))
2158 {
2159 if(state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK)
2160 dc.SetPen(m_button_bar_active_border_pen);
2161 else
2162 dc.SetPen(m_button_bar_hover_border_pen);
2163
2164 wxRect bg_rect(rect);
2165 bg_rect.x++;
2166 bg_rect.y++;
2167 bg_rect.width -= 2;
2168 bg_rect.height -= 2;
2169
2170 wxRect bg_rect_top(bg_rect);
2171 bg_rect_top.height /= 3;
2172 bg_rect.y += bg_rect_top.height;
2173 bg_rect.height -= bg_rect_top.height;
2174
2175 if(kind == wxRIBBON_BUTTON_HYBRID)
2176 {
2177 switch(state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2178 {
2179 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2180 {
2181 int iYBorder = rect.y + bitmap_large.GetHeight() + 4;
2182 wxRect partial_bg(rect);
2183 if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
2184 {
2185 partial_bg.SetBottom(iYBorder - 1);
2186 }
2187 else
2188 {
2189 partial_bg.height -= (iYBorder - partial_bg.y + 1);
2190 partial_bg.y = iYBorder + 1;
2191 }
2192 dc.DrawLine(rect.x, iYBorder, rect.x + rect.width, iYBorder);
2193 bg_rect.Intersect(partial_bg);
2194 bg_rect_top.Intersect(partial_bg);
2195 }
2196 break;
2197 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2198 {
2199 int iArrowWidth = 9;
2200 if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
2201 {
2202 bg_rect.width -= iArrowWidth;
2203 bg_rect_top.width -= iArrowWidth;
2204 dc.DrawLine(bg_rect_top.x + bg_rect_top.width,
2205 rect.y, bg_rect_top.x + bg_rect_top.width,
2206 rect.y + rect.height);
2207 }
2208 else
2209 {
2210 --iArrowWidth;
2211 bg_rect.x += bg_rect.width - iArrowWidth;
2212 bg_rect_top.x += bg_rect_top.width - iArrowWidth;
2213 bg_rect.width = iArrowWidth;
2214 bg_rect_top.width = iArrowWidth;
2215 dc.DrawLine(bg_rect_top.x - 1, rect.y,
2216 bg_rect_top.x - 1, rect.y + rect.height);
2217 }
2218 }
2219 break;
2220 case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
2221 break;
2222 }
2223 }
2224
2225 if(state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK)
2226 {
2227 dc.GradientFillLinear(bg_rect_top,
2228 m_button_bar_active_background_top_colour,
2229 m_button_bar_active_background_top_gradient_colour, wxSOUTH);
2230 dc.GradientFillLinear(bg_rect,
2231 m_button_bar_active_background_colour,
2232 m_button_bar_active_background_gradient_colour, wxSOUTH);
2233 }
2234 else
2235 {
2236 dc.GradientFillLinear(bg_rect_top,
2237 m_button_bar_hover_background_top_colour,
2238 m_button_bar_hover_background_top_gradient_colour, wxSOUTH);
2239 dc.GradientFillLinear(bg_rect,
2240 m_button_bar_hover_background_colour,
2241 m_button_bar_hover_background_gradient_colour, wxSOUTH);
2242 }
2243
2244 wxPoint border_points[9];
2245 border_points[0] = wxPoint(2, 0);
2246 border_points[1] = wxPoint(rect.width - 3, 0);
2247 border_points[2] = wxPoint(rect.width - 1, 2);
2248 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
2249 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
2250 border_points[5] = wxPoint(2, rect.height - 1);
2251 border_points[6] = wxPoint(0, rect.height - 3);
2252 border_points[7] = wxPoint(0, 2);
2253 border_points[8] = border_points[0];
2254
2255 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
2256 rect.x, rect.y);
2257 }
2258
2259 dc.SetFont(m_button_bar_label_font);
2260 dc.SetTextForeground(m_button_bar_label_colour);
2261 DrawButtonBarButtonForeground(dc, rect, kind, state, label, bitmap_large,
2262 bitmap_small);
2263 }
2264
2265 void wxRibbonMSWArtProvider::DrawButtonBarButtonForeground(
2266 wxDC& dc,
2267 const wxRect& rect,
2268 wxRibbonButtonKind kind,
2269 long state,
2270 const wxString& label,
2271 const wxBitmap& bitmap_large,
2272 const wxBitmap& bitmap_small)
2273 {
2274 switch(state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2275 {
2276 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2277 {
2278 const int padding = 2;
2279 dc.DrawBitmap(bitmap_large,
2280 rect.x + (rect.width - bitmap_large.GetWidth()) / 2,
2281 rect.y + padding, true);
2282 int ypos = rect.y + padding + bitmap_large.GetHeight() + padding;
2283 int arrow_width = kind == wxRIBBON_BUTTON_NORMAL ? 0 : 8;
2284 wxCoord label_w, label_h;
2285 dc.GetTextExtent(label, &label_w, &label_h);
2286 if(label_w + 2 * padding <= rect.width)
2287 {
2288 dc.DrawText(label, rect.x + (rect.width - label_w) / 2, ypos);
2289 if(arrow_width != 0)
2290 {
2291 DrawDropdownArrow(dc, rect.x + rect.width / 2,
2292 ypos + (label_h * 3) / 2,
2293 m_button_bar_label_colour);
2294 }
2295 }
2296 else
2297 {
2298 size_t breaki = label.Len();
2299 do
2300 {
2301 --breaki;
2302 if(wxRibbonCanLabelBreakAtPosition(label, breaki))
2303 {
2304 wxString label_top = label.Mid(0, breaki);
2305 dc.GetTextExtent(label_top, &label_w, &label_h);
2306 if(label_w + 2 * padding <= rect.width)
2307 {
2308 dc.DrawText(label_top,
2309 rect.x + (rect.width - label_w) / 2, ypos);
2310 ypos += label_h;
2311 wxString label_bottom = label.Mid(breaki + 1);
2312 dc.GetTextExtent(label_bottom, &label_w, &label_h);
2313 label_w += arrow_width;
2314 int iX = rect.x + (rect.width - label_w) / 2;
2315 dc.DrawText(label_bottom, iX, ypos);
2316 if(arrow_width != 0)
2317 {
2318 DrawDropdownArrow(dc,
2319 iX + 2 +label_w - arrow_width,
2320 ypos + label_h / 2 + 1,
2321 m_button_bar_label_colour);
2322 }
2323 break;
2324 }
2325 }
2326 } while(breaki > 0);
2327 }
2328 }
2329 break;
2330 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2331 {
2332 int x_cursor = rect.x + 2;
2333 dc.DrawBitmap(bitmap_small, x_cursor,
2334 rect.y + (rect.height - bitmap_small.GetHeight())/2, true);
2335 x_cursor += bitmap_small.GetWidth() + 2;
2336 wxCoord label_w, label_h;
2337 dc.GetTextExtent(label, &label_w, &label_h);
2338 dc.DrawText(label, x_cursor,
2339 rect.y + (rect.height - label_h) / 2);
2340 x_cursor += label_w + 3;
2341 if(kind != wxRIBBON_BUTTON_NORMAL)
2342 {
2343 DrawDropdownArrow(dc, x_cursor, rect.y + rect.height / 2,
2344 m_button_bar_label_colour);
2345 }
2346 break;
2347 }
2348 default:
2349 // TODO
2350 break;
2351 }
2352 }
2353
2354 void wxRibbonMSWArtProvider::DrawToolBarBackground(
2355 wxDC& dc,
2356 wxWindow* wnd,
2357 const wxRect& rect)
2358 {
2359 DrawPartialPageBackground(dc, wnd, rect);
2360 }
2361
2362 void wxRibbonMSWArtProvider::DrawToolGroupBackground(
2363 wxDC& dc,
2364 wxWindow* WXUNUSED(wnd),
2365 const wxRect& rect)
2366 {
2367 dc.SetPen(m_toolbar_border_pen);
2368 wxPoint outline[9];
2369 outline[0] = wxPoint(2, 0);
2370 outline[1] = wxPoint(rect.width - 3, 0);
2371 outline[2] = wxPoint(rect.width - 1, 2);
2372 outline[3] = wxPoint(rect.width - 1, rect.height - 3);
2373 outline[4] = wxPoint(rect.width - 3, rect.height - 1);
2374 outline[5] = wxPoint(2, rect.height - 1);
2375 outline[6] = wxPoint(0, rect.height - 3);
2376 outline[7] = wxPoint(0, 2);
2377 outline[8] = outline[0];
2378
2379 dc.DrawLines(sizeof(outline)/sizeof(wxPoint), outline, rect.x, rect.y);
2380 }
2381
2382 void wxRibbonMSWArtProvider::DrawTool(
2383 wxDC& dc,
2384 wxWindow* WXUNUSED(wnd),
2385 const wxRect& rect,
2386 const wxBitmap& bitmap,
2387 wxRibbonButtonKind kind,
2388 long state)
2389 {
2390 if(kind == wxRIBBON_BUTTON_TOGGLE)
2391 {
2392 if(state & wxRIBBON_TOOLBAR_TOOL_TOGGLED)
2393 state ^= wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
2394 }
2395
2396 wxRect bg_rect(rect);
2397 bg_rect.Deflate(1);
2398 if((state & wxRIBBON_TOOLBAR_TOOL_LAST) == 0)
2399 bg_rect.width++;
2400 bool is_split_hybrid = (kind == wxRIBBON_BUTTON_HYBRID && (state &
2401 (wxRIBBON_TOOLBAR_TOOL_HOVER_MASK | wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)));
2402
2403 // Background
2404 wxRect bg_rect_top(bg_rect);
2405 bg_rect_top.height = (bg_rect_top.height * 2) / 5;
2406 wxRect bg_rect_btm(bg_rect);
2407 bg_rect_btm.y += bg_rect_top.height;
2408 bg_rect_btm.height -= bg_rect_top.height;
2409 wxColour bg_top_colour = m_tool_background_top_colour;
2410 wxColour bg_top_grad_colour = m_tool_background_top_gradient_colour;
2411 wxColour bg_colour = m_tool_background_colour;
2412 wxColour bg_grad_colour = m_tool_background_gradient_colour;
2413 if(state & wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)
2414 {
2415 bg_top_colour = m_tool_active_background_top_colour;
2416 bg_top_grad_colour = m_tool_active_background_top_gradient_colour;
2417 bg_colour = m_tool_active_background_colour;
2418 bg_grad_colour = m_tool_active_background_gradient_colour;
2419 }
2420 else if(state & wxRIBBON_TOOLBAR_TOOL_HOVER_MASK)
2421 {
2422 bg_top_colour = m_tool_hover_background_top_colour;
2423 bg_top_grad_colour = m_tool_hover_background_top_gradient_colour;
2424 bg_colour = m_tool_hover_background_colour;
2425 bg_grad_colour = m_tool_hover_background_gradient_colour;
2426 }
2427 dc.GradientFillLinear(bg_rect_top, bg_top_colour, bg_top_grad_colour, wxSOUTH);
2428 dc.GradientFillLinear(bg_rect_btm, bg_colour, bg_grad_colour, wxSOUTH);
2429 if(is_split_hybrid)
2430 {
2431 wxRect nonrect(bg_rect);
2432 if(state & (wxRIBBON_TOOLBAR_TOOL_DROPDOWN_HOVERED |
2433 wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE))
2434 {
2435 nonrect.width -= 8;
2436 }
2437 else
2438 {
2439 nonrect.x += nonrect.width - 8;
2440 nonrect.width = 8;
2441 }
2442 wxBrush B(m_tool_hover_background_top_colour);
2443 dc.SetPen(*wxTRANSPARENT_PEN);
2444 dc.SetBrush(B);
2445 dc.DrawRectangle(nonrect.x, nonrect.y, nonrect.width, nonrect.height);
2446 }
2447
2448 // Border
2449 dc.SetPen(m_toolbar_border_pen);
2450 if(state & wxRIBBON_TOOLBAR_TOOL_FIRST)
2451 {
2452 dc.DrawPoint(rect.x + 1, rect.y + 1);
2453 dc.DrawPoint(rect.x + 1, rect.y + rect.height - 2);
2454 }
2455 else
2456 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
2457
2458 if(state & wxRIBBON_TOOLBAR_TOOL_LAST)
2459 {
2460 dc.DrawPoint(rect.x + rect.width - 2, rect.y + 1);
2461 dc.DrawPoint(rect.x + rect.width - 2, rect.y + rect.height - 2);
2462 }
2463
2464 // Foreground
2465 int avail_width = bg_rect.GetWidth();
2466 if(kind & wxRIBBON_BUTTON_DROPDOWN)
2467 {
2468 avail_width -= 8;
2469 if(is_split_hybrid)
2470 {
2471 dc.DrawLine(rect.x + avail_width + 1, rect.y,
2472 rect.x + avail_width + 1, rect.y + rect.height);
2473 }
2474 dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2,
2475 bg_rect.y + (bg_rect.height / 2) - 2, true);
2476 }
2477 dc.DrawBitmap(bitmap, bg_rect.x + (avail_width - bitmap.GetWidth()) / 2,
2478 bg_rect.y + (bg_rect.height - bitmap.GetHeight()) / 2, true);
2479 }
2480
2481 void
2482 wxRibbonMSWArtProvider::DrawToggleButton(wxDC& dc,
2483 wxRibbonBar* wnd,
2484 const wxRect& rect,
2485 bool upBitmap)
2486 {
2487 DrawPartialPageBackground(dc, wnd, rect, false);
2488
2489 dc.DestroyClippingRegion();
2490 dc.SetClippingRegion(rect);
2491
2492 if(wnd->IsToggleButtonHovered())
2493 {
2494 dc.SetPen(m_ribbon_toggle_pen);
2495 dc.SetBrush(m_ribbon_toggle_brush);
2496 dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 12, 12, 1.0);
2497 if(upBitmap)
2498 dc.DrawBitmap(m_ribbon_toggle_up_bitmap[1], rect.GetX()+2, rect.GetY()+2, true);
2499 else
2500 dc.DrawBitmap(m_ribbon_toggle_down_bitmap[1], rect.GetX()+2, rect.GetY()+2, true);
2501 }
2502 else
2503 {
2504 if(upBitmap)
2505 dc.DrawBitmap(m_ribbon_toggle_up_bitmap[0], rect.GetX()+2, rect.GetY()+2, true);
2506 else
2507 dc.DrawBitmap(m_ribbon_toggle_down_bitmap[0], rect.GetX()+2, rect.GetY()+2, true);
2508 }
2509 }
2510
2511 void wxRibbonMSWArtProvider::GetBarTabWidth(
2512 wxDC& dc,
2513 wxWindow* WXUNUSED(wnd),
2514 const wxString& label,
2515 const wxBitmap& bitmap,
2516 int* ideal,
2517 int* small_begin_need_separator,
2518 int* small_must_have_separator,
2519 int* minimum)
2520 {
2521 int width = 0;
2522 int min = 0;
2523 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) && !label.IsEmpty())
2524 {
2525 dc.SetFont(m_tab_label_font);
2526 width += dc.GetTextExtent(label).GetWidth();
2527 min += wxMin(25, width); // enough for a few chars
2528 if(bitmap.IsOk())
2529 {
2530 // gap between label and bitmap
2531 width += 4;
2532 min += 2;
2533 }
2534 }
2535 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS) && bitmap.IsOk())
2536 {
2537 width += bitmap.GetWidth();
2538 min += bitmap.GetWidth();
2539 }
2540
2541 if(ideal != NULL)
2542 {
2543 *ideal = width + 30;
2544 }
2545 if(small_begin_need_separator != NULL)
2546 {
2547 *small_begin_need_separator = width + 20;
2548 }
2549 if(small_must_have_separator != NULL)
2550 {
2551 *small_must_have_separator = width + 10;
2552 }
2553 if(minimum != NULL)
2554 {
2555 *minimum = min;
2556 }
2557 }
2558
2559 int wxRibbonMSWArtProvider::GetTabCtrlHeight(
2560 wxDC& dc,
2561 wxWindow* WXUNUSED(wnd),
2562 const wxRibbonPageTabInfoArray& pages)
2563 {
2564 int text_height = 0;
2565 int icon_height = 0;
2566
2567 if(pages.GetCount() <= 1 && (m_flags & wxRIBBON_BAR_ALWAYS_SHOW_TABS) == 0)
2568 {
2569 // To preserve space, a single tab need not be displayed. We still need
2570 // two pixels of border / padding though.
2571 return 2;
2572 }
2573
2574 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS)
2575 {
2576 dc.SetFont(m_tab_label_font);
2577 text_height = dc.GetTextExtent(wxT("ABCDEFXj")).GetHeight() + 10;
2578 }
2579 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
2580 {
2581 size_t numpages = pages.GetCount();
2582 for(size_t i = 0; i < numpages; ++i)
2583 {
2584 const wxRibbonPageTabInfo& info = pages.Item(i);
2585 if(info.page->GetIcon().IsOk())
2586 {
2587 icon_height = wxMax(icon_height, info.page->GetIcon().GetHeight() + 4);
2588 }
2589 }
2590 }
2591
2592 return wxMax(text_height, icon_height);
2593 }
2594
2595 wxSize wxRibbonMSWArtProvider::GetScrollButtonMinimumSize(
2596 wxDC& WXUNUSED(dc),
2597 wxWindow* WXUNUSED(wnd),
2598 long WXUNUSED(style))
2599 {
2600 return wxSize(12, 12);
2601 }
2602
2603 wxSize wxRibbonMSWArtProvider::GetPanelSize(
2604 wxDC& dc,
2605 const wxRibbonPanel* wnd,
2606 wxSize client_size,
2607 wxPoint* client_offset)
2608 {
2609 dc.SetFont(m_panel_label_font);
2610 wxSize label_size = dc.GetTextExtent(wnd->GetLabel());
2611
2612 client_size.IncBy(0, label_size.GetHeight());
2613 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2614 client_size.IncBy(4, 8);
2615 else
2616 client_size.IncBy(6, 6);
2617
2618 if(client_offset != NULL)
2619 {
2620 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2621 *client_offset = wxPoint(2, 3);
2622 else
2623 *client_offset = wxPoint(3, 2);
2624 }
2625
2626 return client_size;
2627 }
2628
2629 wxSize wxRibbonMSWArtProvider::GetPanelClientSize(
2630 wxDC& dc,
2631 const wxRibbonPanel* wnd,
2632 wxSize size,
2633 wxPoint* client_offset)
2634 {
2635 dc.SetFont(m_panel_label_font);
2636 wxSize label_size = dc.GetTextExtent(wnd->GetLabel());
2637
2638 size.DecBy(0, label_size.GetHeight());
2639 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2640 size.DecBy(4, 8);
2641 else
2642 size.DecBy(6, 6);
2643
2644 if(client_offset != NULL)
2645 {
2646 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2647 *client_offset = wxPoint(2, 3);
2648 else
2649 *client_offset = wxPoint(3, 2);
2650 }
2651 if (size.x < 0) size.x = 0;
2652 if (size.y < 0) size.y = 0;
2653
2654 return size;
2655 }
2656
2657 wxSize wxRibbonMSWArtProvider::GetGallerySize(
2658 wxDC& WXUNUSED(dc),
2659 const wxRibbonGallery* WXUNUSED(wnd),
2660 wxSize client_size)
2661 {
2662 client_size.IncBy( 2, 1); // Left / top padding
2663 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2664 client_size.IncBy(1, 16); // Right / bottom padding
2665 else
2666 client_size.IncBy(16, 1); // Right / bottom padding
2667 return client_size;
2668 }
2669
2670 wxSize wxRibbonMSWArtProvider::GetGalleryClientSize(
2671 wxDC& WXUNUSED(dc),
2672 const wxRibbonGallery* WXUNUSED(wnd),
2673 wxSize size,
2674 wxPoint* client_offset,
2675 wxRect* scroll_up_button,
2676 wxRect* scroll_down_button,
2677 wxRect* extension_button)
2678 {
2679 wxRect scroll_up;
2680 wxRect scroll_down;
2681 wxRect extension;
2682 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2683 {
2684 // Flow is vertical - put buttons on bottom
2685 scroll_up.y = size.GetHeight() - 15;
2686 scroll_up.height = 15;
2687 scroll_up.x = 0;
2688 scroll_up.width = (size.GetWidth() + 2) / 3;
2689 scroll_down.y = scroll_up.y;
2690 scroll_down.height = scroll_up.height;
2691 scroll_down.x = scroll_up.x + scroll_up.width;
2692 scroll_down.width = scroll_up.width;
2693 extension.y = scroll_down.y;
2694 extension.height = scroll_down.height;
2695 extension.x = scroll_down.x + scroll_down.width;
2696 extension.width = size.GetWidth() - scroll_up.width - scroll_down.width;
2697 size.DecBy(1, 16);
2698 size.DecBy( 2, 1);
2699 }
2700 else
2701 {
2702 // Flow is horizontal - put buttons on right
2703 scroll_up.x = size.GetWidth() - 15;
2704 scroll_up.width = 15;
2705 scroll_up.y = 0;
2706 scroll_up.height = (size.GetHeight() + 2) / 3;
2707 scroll_down.x = scroll_up.x;
2708 scroll_down.width = scroll_up.width;
2709 scroll_down.y = scroll_up.y + scroll_up.height;
2710 scroll_down.height = scroll_up.height;
2711 extension.x = scroll_down.x;
2712 extension.width = scroll_down.width;
2713 extension.y = scroll_down.y + scroll_down.height;
2714 extension.height = size.GetHeight() - scroll_up.height - scroll_down.height;
2715 size.DecBy(16, 1);
2716 size.DecBy( 2, 1);
2717 }
2718
2719 if(client_offset != NULL)
2720 *client_offset = wxPoint(2, 1);
2721 if(scroll_up_button != NULL)
2722 *scroll_up_button = scroll_up;
2723 if(scroll_down_button != NULL)
2724 *scroll_down_button = scroll_down;
2725 if(extension_button != NULL)
2726 *extension_button = extension;
2727
2728 return size;
2729 }
2730
2731 wxRect wxRibbonMSWArtProvider::GetPageBackgroundRedrawArea(
2732 wxDC& WXUNUSED(dc),
2733 const wxRibbonPage* WXUNUSED(wnd),
2734 wxSize page_old_size,
2735 wxSize page_new_size)
2736 {
2737 wxRect new_rect, old_rect;
2738
2739 if(page_new_size.GetWidth() != page_old_size.GetWidth())
2740 {
2741 if(page_new_size.GetHeight() != page_old_size.GetHeight())
2742 {
2743 // Width and height both changed - redraw everything
2744 return wxRect(page_new_size);
2745 }
2746 else
2747 {
2748 // Only width changed - redraw right hand side
2749 const int right_edge_width = 4;
2750
2751 new_rect = wxRect(page_new_size.GetWidth() - right_edge_width, 0, right_edge_width, page_new_size.GetHeight());
2752 old_rect = wxRect(page_old_size.GetWidth() - right_edge_width, 0, right_edge_width, page_old_size.GetHeight());
2753 }
2754 }
2755 else
2756 {
2757 if(page_new_size.GetHeight() == page_old_size.GetHeight())
2758 {
2759 // Nothing changed (should never happen) - redraw nothing
2760 return wxRect(0, 0, 0, 0);
2761 }
2762 else
2763 {
2764 // Height changed - need to redraw everything (as the background
2765 // gradient is done vertically).
2766 return page_new_size;
2767 }
2768 }
2769
2770 new_rect.Union(old_rect);
2771 new_rect.Intersect(wxRect(page_new_size));
2772 return new_rect;
2773 }
2774
2775 bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
2776 wxDC& dc,
2777 wxWindow* wnd,
2778 wxRibbonButtonKind kind,
2779 wxRibbonButtonBarButtonState size,
2780 const wxString& label,
2781 wxSize bitmap_size_large,
2782 wxSize bitmap_size_small,
2783 wxSize* button_size,
2784 wxRect* normal_region,
2785 wxRect* dropdown_region)
2786 {
2787 const int drop_button_width = 8;
2788
2789 dc.SetFont(m_button_bar_label_font);
2790 switch(size & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2791 {
2792 case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
2793 // Small bitmap, no label
2794 *button_size = bitmap_size_small + wxSize(6, 4);
2795 switch(kind)
2796 {
2797 case wxRIBBON_BUTTON_NORMAL:
2798 case wxRIBBON_BUTTON_TOGGLE:
2799 *normal_region = wxRect(*button_size);
2800 *dropdown_region = wxRect(0, 0, 0, 0);
2801 break;
2802 case wxRIBBON_BUTTON_DROPDOWN:
2803 *button_size += wxSize(drop_button_width, 0);
2804 *dropdown_region = wxRect(*button_size);
2805 *normal_region = wxRect(0, 0, 0, 0);
2806 break;
2807 case wxRIBBON_BUTTON_HYBRID:
2808 *normal_region = wxRect(*button_size);
2809 *dropdown_region = wxRect(button_size->GetWidth(), 0,
2810 drop_button_width, button_size->GetHeight());
2811 *button_size += wxSize(drop_button_width, 0);
2812 break;
2813 }
2814 break;
2815 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2816 // Small bitmap, with label to the right
2817 {
2818 GetButtonBarButtonSize(dc, wnd, kind, wxRIBBON_BUTTONBAR_BUTTON_SMALL,
2819 label, bitmap_size_large, bitmap_size_small, button_size,
2820 normal_region, dropdown_region);
2821 int text_size = dc.GetTextExtent(label).GetWidth();
2822 button_size->SetWidth(button_size->GetWidth() + text_size);
2823 switch(kind)
2824 {
2825 case wxRIBBON_BUTTON_DROPDOWN:
2826 dropdown_region->SetWidth(dropdown_region->GetWidth() + text_size);
2827 break;
2828 case wxRIBBON_BUTTON_HYBRID:
2829 dropdown_region->SetX(dropdown_region->GetX() + text_size);
2830 // no break
2831 case wxRIBBON_BUTTON_NORMAL:
2832 case wxRIBBON_BUTTON_TOGGLE:
2833 normal_region->SetWidth(normal_region->GetWidth() + text_size);
2834 break;
2835 }
2836 break;
2837 }
2838 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2839 // Large bitmap, with label below (possibly split over 2 lines)
2840 {
2841 wxSize icon_size(bitmap_size_large);
2842 icon_size += wxSize(4, 4);
2843 wxCoord label_height;
2844 wxCoord best_width;
2845 dc.GetTextExtent(label, &best_width, &label_height);
2846 int last_line_extra_width = 0;
2847 if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE)
2848 {
2849 last_line_extra_width += 8;
2850 }
2851 size_t i;
2852 for(i = 0; i < label.Len(); ++i)
2853 {
2854 if(wxRibbonCanLabelBreakAtPosition(label, i))
2855 {
2856 int width = wxMax(
2857 dc.GetTextExtent(label.Mid(0, i - 1)).GetWidth(),
2858 dc.GetTextExtent(label.Mid(i + 1)).GetWidth() + last_line_extra_width);
2859 if(width < best_width)
2860 {
2861 best_width = width;
2862 }
2863 }
2864 }
2865 label_height *= 2; // Assume two lines even when only one is used
2866 // (to give all buttons a consistent height)
2867 icon_size.SetWidth(wxMax(icon_size.GetWidth(), best_width) + 6);
2868 icon_size.SetHeight(icon_size.GetHeight() + label_height);
2869 *button_size = icon_size;
2870 switch(kind)
2871 {
2872 case wxRIBBON_BUTTON_DROPDOWN:
2873 *dropdown_region = wxRect(icon_size);
2874 break;
2875 case wxRIBBON_BUTTON_HYBRID:
2876 *normal_region = wxRect(icon_size);
2877 normal_region->height -= 2 + label_height;
2878 dropdown_region->x = 0;
2879 dropdown_region->y = normal_region->height;
2880 dropdown_region->width = icon_size.GetWidth();
2881 dropdown_region->height = icon_size.GetHeight() - normal_region->height;
2882 break;
2883 case wxRIBBON_BUTTON_NORMAL:
2884 case wxRIBBON_BUTTON_TOGGLE:
2885 *normal_region = wxRect(icon_size);
2886 break;
2887 }
2888 break;
2889 }
2890 };
2891 return true;
2892 }
2893
2894 wxSize wxRibbonMSWArtProvider::GetMinimisedPanelMinimumSize(
2895 wxDC& dc,
2896 const wxRibbonPanel* wnd,
2897 wxSize* desired_bitmap_size,
2898 wxDirection* expanded_panel_direction)
2899 {
2900 if(desired_bitmap_size != NULL)
2901 {
2902 *desired_bitmap_size = wxSize(16, 16);
2903 }
2904 if(expanded_panel_direction != NULL)
2905 {
2906 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2907 *expanded_panel_direction = wxEAST;
2908 else
2909 *expanded_panel_direction = wxSOUTH;
2910 }
2911 wxSize base_size(42, 42);
2912
2913 dc.SetFont(m_panel_label_font);
2914 wxSize label_size(dc.GetTextExtent(wnd->GetLabel()));
2915 label_size.IncBy(2, 2); // Allow for differences between this DC and a paint DC
2916 label_size.IncBy(6, 0); // Padding
2917 label_size.y *= 2; // Second line for dropdown button
2918
2919 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2920 {
2921 // Label alongside icon
2922 return wxSize(base_size.x + label_size.x,
2923 wxMax(base_size.y, label_size.y));
2924 }
2925 else
2926 {
2927 // Label beneath icon
2928 return wxSize(wxMax(base_size.x, label_size.x),
2929 base_size.y + label_size.y);
2930 }
2931 }
2932
2933 wxSize wxRibbonMSWArtProvider::GetToolSize(
2934 wxDC& WXUNUSED(dc),
2935 wxWindow* WXUNUSED(wnd),
2936 wxSize bitmap_size,
2937 wxRibbonButtonKind kind,
2938 bool WXUNUSED(is_first),
2939 bool is_last,
2940 wxRect* dropdown_region)
2941 {
2942 wxSize size(bitmap_size);
2943 size.IncBy(7, 6);
2944 if(is_last)
2945 size.IncBy(1, 0);
2946 if(kind & wxRIBBON_BUTTON_DROPDOWN)
2947 {
2948 size.IncBy(8, 0);
2949 if(dropdown_region)
2950 {
2951 if(kind == wxRIBBON_BUTTON_DROPDOWN)
2952 *dropdown_region = size;
2953 else
2954 *dropdown_region = wxRect(size.GetWidth() - 8, 0, 8, size.GetHeight());
2955 }
2956 }
2957 else
2958 {
2959 if(dropdown_region)
2960 *dropdown_region = wxRect(0, 0, 0, 0);
2961 }
2962 return size;
2963 }
2964
2965 wxRect
2966 wxRibbonMSWArtProvider::GetBarToggleButtonArea(wxDC& WXUNUSED(dc),
2967 const wxRibbonBar* WXUNUSED(wnd),
2968 wxRect rect)
2969 {
2970 rect = wxRect(rect.GetWidth()-30, 6, 12, 12);
2971 return rect;
2972 }
2973
2974 #endif // wxUSE_RIBBON