Add page highlighting 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 || tab.highlight)
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 else if(tab.highlight)
1102 {
1103 wxRect background(tab.rect);
1104
1105 background.x += 2;
1106 background.y += 2;
1107 background.width -= 4;
1108 background.height -= 3;
1109 int h = background.height;
1110 background.height /= 2;
1111
1112 //For highlight pages we show a colour between the active page and for a hovered page:
1113 wxColour top_colour1((m_tab_active_background_colour.Red() + m_tab_hover_background_top_colour.Red())/2,
1114 (m_tab_active_background_colour.Green() + m_tab_hover_background_top_colour.Green())/2,
1115 (m_tab_active_background_colour.Blue() + m_tab_hover_background_top_colour.Blue())/2);
1116
1117 wxColour bottom_colour1((m_tab_active_background_gradient_colour.Red() + m_tab_hover_background_top_gradient_colour.Red())/2,
1118 (m_tab_active_background_gradient_colour.Green() + m_tab_hover_background_top_gradient_colour.Green())/2,
1119 (m_tab_active_background_gradient_colour.Blue() + m_tab_hover_background_top_gradient_colour.Blue())/2);
1120
1121 dc.GradientFillLinear(background, top_colour1, bottom_colour1, wxSOUTH);
1122
1123 background.y += background.height;
1124 background.height = h - background.height;
1125
1126 wxColour top_colour2((m_tab_active_background_colour.Red() + m_tab_hover_background_colour.Red())/2,
1127 (m_tab_active_background_colour.Green() + m_tab_hover_background_colour.Green())/2,
1128 (m_tab_active_background_colour.Blue() + m_tab_hover_background_colour.Blue())/2);
1129
1130 wxColour bottom_colour2((m_tab_active_background_gradient_colour.Red() + m_tab_hover_background_gradient_colour.Red())/2,
1131 (m_tab_active_background_gradient_colour.Green() + m_tab_hover_background_gradient_colour.Green())/2,
1132 (m_tab_active_background_gradient_colour.Blue() + m_tab_hover_background_gradient_colour.Blue())/2);
1133
1134 dc.GradientFillLinear(background, top_colour2, bottom_colour2, wxSOUTH);
1135 }
1136
1137 wxPoint border_points[6];
1138 border_points[0] = wxPoint(1, tab.rect.height - 2);
1139 border_points[1] = wxPoint(1, 3);
1140 border_points[2] = wxPoint(3, 1);
1141 border_points[3] = wxPoint(tab.rect.width - 4, 1);
1142 border_points[4] = wxPoint(tab.rect.width - 2, 3);
1143 border_points[5] = wxPoint(tab.rect.width - 2, tab.rect.height - 1);
1144
1145 dc.SetPen(m_tab_border_pen);
1146 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, tab.rect.x, tab.rect.y);
1147
1148 if(tab.active)
1149 {
1150 // Give the tab a curved outward border at the bottom
1151 dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 2);
1152 dc.DrawPoint(tab.rect.x + tab.rect.width - 1, tab.rect.y + tab.rect.height - 2);
1153
1154 wxPen p(m_tab_active_background_gradient_colour);
1155 dc.SetPen(p);
1156
1157 // Technically the first two points are the wrong colour, but they're near enough
1158 dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 2);
1159 dc.DrawPoint(tab.rect.x + tab.rect.width - 2, tab.rect.y + tab.rect.height - 2);
1160 dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 1);
1161 dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 1);
1162 dc.DrawPoint(tab.rect.x + tab.rect.width - 2, tab.rect.y + tab.rect.height - 1);
1163 dc.DrawPoint(tab.rect.x + tab.rect.width - 1, tab.rect.y + tab.rect.height - 1);
1164 }
1165 }
1166
1167 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
1168 {
1169 wxBitmap icon = tab.page->GetIcon();
1170 if(icon.IsOk())
1171 {
1172 int x = tab.rect.x + 4;
1173 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) == 0)
1174 x = tab.rect.x + (tab.rect.width - icon.GetWidth()) / 2;
1175 dc.DrawBitmap(icon, x, tab.rect.y + 1 + (tab.rect.height - 1 -
1176 icon.GetHeight()) / 2, true);
1177 }
1178 }
1179 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS)
1180 {
1181 wxString label = tab.page->GetLabel();
1182 if(!label.IsEmpty())
1183 {
1184 dc.SetFont(m_tab_label_font);
1185 dc.SetTextForeground(m_tab_label_colour);
1186 dc.SetBackgroundMode(wxTRANSPARENT);
1187
1188 int text_height;
1189 int text_width;
1190 dc.GetTextExtent(label, &text_width, &text_height);
1191 int width = tab.rect.width - 5;
1192 int x = tab.rect.x + 3;
1193 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
1194 {
1195 x += 3 + tab.page->GetIcon().GetWidth();
1196 width -= 3 + tab.page->GetIcon().GetWidth();
1197 }
1198 int y = tab.rect.y + (tab.rect.height - text_height) / 2;
1199
1200 if(width <= text_width)
1201 {
1202 dc.SetClippingRegion(x, tab.rect.y, width, tab.rect.height);
1203 dc.DrawText(label, x, y);
1204 }
1205 else
1206 {
1207 dc.DrawText(label, x + (width - text_width) / 2 + 1, y);
1208 }
1209 }
1210 }
1211 }
1212
1213 void wxRibbonMSWArtProvider::DrawTabSeparator(
1214 wxDC& dc,
1215 wxWindow* wnd,
1216 const wxRect& rect,
1217 double visibility)
1218 {
1219 if(visibility <= 0.0)
1220 {
1221 return;
1222 }
1223 if(visibility > 1.0)
1224 {
1225 visibility = 1.0;
1226 }
1227
1228 // The tab separator is relatively expensive to draw (for its size), and is
1229 // usually drawn multiple times sequentially (in different positions), so it
1230 // makes sense to draw it once and cache it.
1231 if(!m_cached_tab_separator.IsOk() || m_cached_tab_separator.GetSize() != rect.GetSize() || visibility != m_cached_tab_separator_visibility)
1232 {
1233 wxRect size(rect.GetSize());
1234 ReallyDrawTabSeparator(wnd, size, visibility);
1235 }
1236 dc.DrawBitmap(m_cached_tab_separator, rect.x, rect.y, false);
1237 }
1238
1239 void wxRibbonMSWArtProvider::ReallyDrawTabSeparator(wxWindow* wnd, const wxRect& rect, double visibility)
1240 {
1241 if(!m_cached_tab_separator.IsOk() || m_cached_tab_separator.GetSize() != rect.GetSize())
1242 {
1243 m_cached_tab_separator = wxBitmap(rect.GetSize());
1244 }
1245
1246 wxMemoryDC dc(m_cached_tab_separator);
1247 DrawTabCtrlBackground(dc, wnd, rect);
1248
1249 wxCoord x = rect.x + rect.width / 2;
1250 double h = (double)(rect.height - 1);
1251
1252 double r1 = m_tab_ctrl_background_brush.GetColour().Red() * (1.0 - visibility) + 0.5;
1253 double g1 = m_tab_ctrl_background_brush.GetColour().Green() * (1.0 - visibility) + 0.5;
1254 double b1 = m_tab_ctrl_background_brush.GetColour().Blue() * (1.0 - visibility) + 0.5;
1255 double r2 = m_tab_separator_colour.Red();
1256 double g2 = m_tab_separator_colour.Green();
1257 double b2 = m_tab_separator_colour.Blue();
1258 double r3 = m_tab_separator_gradient_colour.Red();
1259 double g3 = m_tab_separator_gradient_colour.Green();
1260 double b3 = m_tab_separator_gradient_colour.Blue();
1261
1262 for(int i = 0; i < rect.height - 1; ++i)
1263 {
1264 double p = ((double)i)/h;
1265
1266 double r = (p * r3 + (1.0 - p) * r2) * visibility + r1;
1267 double g = (p * g3 + (1.0 - p) * g2) * visibility + g1;
1268 double b = (p * b3 + (1.0 - p) * b2) * visibility + b1;
1269
1270 wxPen P(wxColour((unsigned char)r, (unsigned char)g, (unsigned char)b));
1271 dc.SetPen(P);
1272 dc.DrawPoint(x, rect.y + i);
1273 }
1274
1275 m_cached_tab_separator_visibility = visibility;
1276 }
1277
1278 void wxRibbonMSWArtProvider::DrawPartialPageBackground(wxDC& dc,
1279 wxWindow* wnd, const wxRect& rect, wxRibbonPage* page,
1280 wxPoint offset, bool hovered)
1281 {
1282 wxRect background;
1283 // Expanded panels need a background - the expanded panel at
1284 // best size may have a greater Y dimension higher than when
1285 // on the bar if it has a sizer. AUI art provider does not need this
1286 // because it paints the panel without reference to its parent's size.
1287 // Expanded panels use a wxFrame as parent (not a wxRibbonPage).
1288
1289 if(wnd->GetSizer() && wnd->GetParent() != page)
1290 {
1291 background = wnd->GetParent()->GetSize();
1292 offset = wxPoint(0,0);
1293 }
1294 else
1295 {
1296 background = page->GetSize();
1297 page->AdjustRectToIncludeScrollButtons(&background);
1298 background.height -= 2;
1299 }
1300 // Page background isn't dependant upon the width of the page
1301 // (at least not the part of it intended to be painted by this
1302 // function). Set to wider than the page itself for when externally
1303 // expanded panels need a background - the expanded panel can be wider
1304 // than the bar.
1305 background.x = 0;
1306 background.width = INT_MAX;
1307
1308 // upper_rect, lower_rect, paint_rect are all in page co-ordinates
1309 wxRect upper_rect(background);
1310 upper_rect.height /= 5;
1311
1312 wxRect lower_rect(background);
1313 lower_rect.y += upper_rect.height;
1314 lower_rect.height -= upper_rect.height;
1315
1316 wxRect paint_rect(rect);
1317 paint_rect.x += offset.x;
1318 paint_rect.y += offset.y;
1319
1320 wxColour bg_top, bg_top_grad, bg_btm, bg_btm_grad;
1321 if(hovered)
1322 {
1323 bg_top = m_page_hover_background_top_colour;
1324 bg_top_grad = m_page_hover_background_top_gradient_colour;
1325 bg_btm = m_page_hover_background_colour;
1326 bg_btm_grad = m_page_hover_background_gradient_colour;
1327 }
1328 else
1329 {
1330 bg_top = m_page_background_top_colour;
1331 bg_top_grad = m_page_background_top_gradient_colour;
1332 bg_btm = m_page_background_colour;
1333 bg_btm_grad = m_page_background_gradient_colour;
1334 }
1335
1336 if(paint_rect.Intersects(upper_rect))
1337 {
1338 wxRect rect(upper_rect);
1339 rect.Intersect(paint_rect);
1340 rect.x -= offset.x;
1341 rect.y -= offset.y;
1342 wxColour starting_colour(wxRibbonInterpolateColour(bg_top, bg_top_grad,
1343 paint_rect.y, upper_rect.y, upper_rect.y + upper_rect.height));
1344 wxColour ending_colour(wxRibbonInterpolateColour(bg_top, bg_top_grad,
1345 paint_rect.y + paint_rect.height, upper_rect.y,
1346 upper_rect.y + upper_rect.height));
1347 dc.GradientFillLinear(rect, starting_colour, ending_colour, wxSOUTH);
1348 }
1349
1350 if(paint_rect.Intersects(lower_rect))
1351 {
1352 wxRect rect(lower_rect);
1353 rect.Intersect(paint_rect);
1354 rect.x -= offset.x;
1355 rect.y -= offset.y;
1356 wxColour starting_colour(wxRibbonInterpolateColour(bg_btm, bg_btm_grad,
1357 paint_rect.y, lower_rect.y, lower_rect.y + lower_rect.height));
1358 wxColour ending_colour(wxRibbonInterpolateColour(bg_btm, bg_btm_grad,
1359 paint_rect.y + paint_rect.height,
1360 lower_rect.y, lower_rect.y + lower_rect.height));
1361 dc.GradientFillLinear(rect, starting_colour, ending_colour, wxSOUTH);
1362 }
1363 }
1364
1365 void wxRibbonMSWArtProvider::DrawPageBackground(
1366 wxDC& dc,
1367 wxWindow* WXUNUSED(wnd),
1368 const wxRect& rect)
1369 {
1370 dc.SetPen(*wxTRANSPARENT_PEN);
1371 dc.SetBrush(m_tab_ctrl_background_brush);
1372
1373 {
1374 wxRect edge(rect);
1375
1376 edge.width = 2;
1377 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1378
1379 edge.x += rect.width - 2;
1380 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1381
1382 edge = rect;
1383 edge.height = 2;
1384 edge.y += (rect.height - edge.height);
1385 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1386 }
1387
1388 {
1389 wxRect background(rect);
1390 background.x += 2;
1391 background.width -= 4;
1392 background.height -= 2;
1393
1394 background.height /= 5;
1395 dc.GradientFillLinear(background, m_page_background_top_colour,
1396 m_page_background_top_gradient_colour, wxSOUTH);
1397
1398 background.y += background.height;
1399 background.height = rect.height - 2 - background.height;
1400 dc.GradientFillLinear(background, m_page_background_colour,
1401 m_page_background_gradient_colour, wxSOUTH);
1402 }
1403
1404 {
1405 wxPoint border_points[8];
1406 border_points[0] = wxPoint(2, 0);
1407 border_points[1] = wxPoint(1, 1);
1408 border_points[2] = wxPoint(1, rect.height - 4);
1409 border_points[3] = wxPoint(3, rect.height - 2);
1410 border_points[4] = wxPoint(rect.width - 4, rect.height - 2);
1411 border_points[5] = wxPoint(rect.width - 2, rect.height - 4);
1412 border_points[6] = wxPoint(rect.width - 2, 1);
1413 border_points[7] = wxPoint(rect.width - 4, -1);
1414
1415 dc.SetPen(m_page_border_pen);
1416 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1417 }
1418 }
1419
1420 void wxRibbonMSWArtProvider::DrawScrollButton(
1421 wxDC& dc,
1422 wxWindow* WXUNUSED(wnd),
1423 const wxRect& rect_,
1424 long style)
1425 {
1426 wxRect rect(rect_);
1427
1428 if((style & wxRIBBON_SCROLL_BTN_FOR_MASK) == wxRIBBON_SCROLL_BTN_FOR_PAGE)
1429 {
1430 // Page scroll buttons do not have the luxury of rendering on top of anything
1431 // else, and their size includes some padding, hence the background painting
1432 // and size adjustment.
1433 dc.SetPen(*wxTRANSPARENT_PEN);
1434 dc.SetBrush(m_tab_ctrl_background_brush);
1435 dc.DrawRectangle(rect);
1436 dc.SetClippingRegion(rect);
1437 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1438 {
1439 case wxRIBBON_SCROLL_BTN_LEFT:
1440 rect.x++;
1441 case wxRIBBON_SCROLL_BTN_RIGHT:
1442 rect.y--;
1443 rect.width--;
1444 break;
1445 case wxRIBBON_SCROLL_BTN_UP:
1446 rect.x++;
1447 rect.y--;
1448 rect.width -= 2;
1449 rect.height++;
1450 break;
1451 case wxRIBBON_SCROLL_BTN_DOWN:
1452 rect.x++;
1453 rect.width -= 2;
1454 rect.height--;
1455 break;
1456 }
1457 }
1458
1459 {
1460 wxRect background(rect);
1461 background.x++;
1462 background.y++;
1463 background.width -= 2;
1464 background.height -= 2;
1465
1466 if(style & wxRIBBON_SCROLL_BTN_UP)
1467 background.height /= 2;
1468 else
1469 background.height /= 5;
1470 dc.GradientFillLinear(background, m_page_background_top_colour,
1471 m_page_background_top_gradient_colour, wxSOUTH);
1472
1473 background.y += background.height;
1474 background.height = rect.height - 2 - background.height;
1475 dc.GradientFillLinear(background, m_page_background_colour,
1476 m_page_background_gradient_colour, wxSOUTH);
1477 }
1478
1479 {
1480 wxPoint border_points[7];
1481 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1482 {
1483 case wxRIBBON_SCROLL_BTN_LEFT:
1484 border_points[0] = wxPoint(2, 0);
1485 border_points[1] = wxPoint(rect.width - 1, 0);
1486 border_points[2] = wxPoint(rect.width - 1, rect.height - 1);
1487 border_points[3] = wxPoint(2, rect.height - 1);
1488 border_points[4] = wxPoint(0, rect.height - 3);
1489 border_points[5] = wxPoint(0, 2);
1490 break;
1491 case wxRIBBON_SCROLL_BTN_RIGHT:
1492 border_points[0] = wxPoint(0, 0);
1493 border_points[1] = wxPoint(rect.width - 3, 0);
1494 border_points[2] = wxPoint(rect.width - 1, 2);
1495 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
1496 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
1497 border_points[5] = wxPoint(0, rect.height - 1);
1498 break;
1499 case wxRIBBON_SCROLL_BTN_UP:
1500 border_points[0] = wxPoint(2, 0);
1501 border_points[1] = wxPoint(rect.width - 3, 0);
1502 border_points[2] = wxPoint(rect.width - 1, 2);
1503 border_points[3] = wxPoint(rect.width - 1, rect.height - 1);
1504 border_points[4] = wxPoint(0, rect.height - 1);
1505 border_points[5] = wxPoint(0, 2);
1506 break;
1507 case wxRIBBON_SCROLL_BTN_DOWN:
1508 border_points[0] = wxPoint(0, 0);
1509 border_points[1] = wxPoint(rect.width - 1, 0);
1510 border_points[2] = wxPoint(rect.width - 1, rect.height - 3);
1511 border_points[3] = wxPoint(rect.width - 3, rect.height - 1);
1512 border_points[4] = wxPoint(2, rect.height - 1);
1513 border_points[5] = wxPoint(0, rect.height - 3);
1514 break;
1515 }
1516 border_points[6] = border_points[0];
1517
1518 dc.SetPen(m_page_border_pen);
1519 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1520 }
1521
1522 {
1523 // NB: Code for handling hovered/active state is temporary
1524 wxPoint arrow_points[3];
1525 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1526 {
1527 case wxRIBBON_SCROLL_BTN_LEFT:
1528 arrow_points[0] = wxPoint(rect.width / 2 - 2, rect.height / 2);
1529 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1530 arrow_points[0].y += 1;
1531 arrow_points[1] = arrow_points[0] + wxPoint(3, -3);
1532 arrow_points[2] = arrow_points[0] + wxPoint(3, 3);
1533 break;
1534 case wxRIBBON_SCROLL_BTN_RIGHT:
1535 arrow_points[0] = wxPoint(rect.width / 2 + 2, rect.height / 2);
1536 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1537 arrow_points[0].y += 1;
1538 arrow_points[1] = arrow_points[0] - wxPoint(3, 3);
1539 arrow_points[2] = arrow_points[0] - wxPoint(3, -3);
1540 break;
1541 case wxRIBBON_SCROLL_BTN_UP:
1542 arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 - 2);
1543 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1544 arrow_points[0].y += 1;
1545 arrow_points[1] = arrow_points[0] + wxPoint( 3, 3);
1546 arrow_points[2] = arrow_points[0] + wxPoint(-3, 3);
1547 break;
1548 case wxRIBBON_SCROLL_BTN_DOWN:
1549 arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 + 2);
1550 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1551 arrow_points[0].y += 1;
1552 arrow_points[1] = arrow_points[0] - wxPoint( 3, 3);
1553 arrow_points[2] = arrow_points[0] - wxPoint(-3, 3);
1554 break;
1555 }
1556
1557 dc.SetPen(*wxTRANSPARENT_PEN);
1558 wxBrush B(style & wxRIBBON_SCROLL_BTN_HOVERED ? m_tab_active_background_colour : m_tab_label_colour);
1559 dc.SetBrush(B);
1560 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points, rect.x, rect.y);
1561 }
1562 }
1563
1564 void wxRibbonMSWArtProvider::DrawDropdownArrow(wxDC& dc, int x, int y, const wxColour& colour)
1565 {
1566 wxPoint arrow_points[3];
1567 wxBrush brush(colour);
1568 arrow_points[0] = wxPoint(1, 2);
1569 arrow_points[1] = arrow_points[0] + wxPoint(-3, -3);
1570 arrow_points[2] = arrow_points[0] + wxPoint( 3, -3);
1571 dc.SetPen(*wxTRANSPARENT_PEN);
1572 dc.SetBrush(brush);
1573 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points, x, y);
1574 }
1575
1576 void wxRibbonMSWArtProvider::RemovePanelPadding(wxRect* rect)
1577 {
1578 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1579 {
1580 rect->y += 1;
1581 rect->height -= 2;
1582 }
1583 else
1584 {
1585 rect->x += 1;
1586 rect->width -= 2;
1587 }
1588 }
1589
1590 void wxRibbonMSWArtProvider::DrawPanelBackground(
1591 wxDC& dc,
1592 wxRibbonPanel* wnd,
1593 const wxRect& rect)
1594 {
1595 DrawPartialPageBackground(dc, wnd, rect, false);
1596
1597 wxRect true_rect(rect);
1598 RemovePanelPadding(&true_rect);
1599 bool has_ext_button = wnd->HasExtButton();
1600
1601 int label_height;
1602 {
1603 dc.SetFont(m_panel_label_font);
1604 dc.SetPen(*wxTRANSPARENT_PEN);
1605 if(wnd->IsHovered())
1606 {
1607 dc.SetBrush(m_panel_hover_label_background_brush);
1608 dc.SetTextForeground(m_panel_hover_label_colour);
1609 }
1610 else
1611 {
1612 dc.SetBrush(m_panel_label_background_brush);
1613 dc.SetTextForeground(m_panel_label_colour);
1614 }
1615
1616 wxRect label_rect(true_rect);
1617 wxString label = wnd->GetLabel();
1618 bool clip_label = false;
1619 wxSize label_size(dc.GetTextExtent(label));
1620
1621 label_rect.SetX(label_rect.GetX() + 1);
1622 label_rect.SetWidth(label_rect.GetWidth() - 2);
1623 label_rect.SetHeight(label_size.GetHeight() + 2);
1624 label_rect.SetY(true_rect.GetBottom() - label_rect.GetHeight());
1625 label_height = label_rect.GetHeight();
1626
1627 wxRect label_bg_rect = label_rect;
1628
1629 if(has_ext_button)
1630 label_rect.SetWidth(label_rect.GetWidth() - 13);
1631
1632 if(label_size.GetWidth() > label_rect.GetWidth())
1633 {
1634 // Test if there is enough length for 3 letters and ...
1635 wxString new_label = label.Mid(0, 3) + wxT("...");
1636 label_size = dc.GetTextExtent(new_label);
1637 if(label_size.GetWidth() > label_rect.GetWidth())
1638 {
1639 // Not enough room for three characters and ...
1640 // Display the entire label and just crop it
1641 clip_label = true;
1642 }
1643 else
1644 {
1645 // Room for some characters and ...
1646 // Display as many characters as possible and append ...
1647 for(size_t len = label.Len() - 1; len >= 3; --len)
1648 {
1649 new_label = label.Mid(0, len) + wxT("...");
1650 label_size = dc.GetTextExtent(new_label);
1651 if(label_size.GetWidth() <= label_rect.GetWidth())
1652 {
1653 label = new_label;
1654 break;
1655 }
1656 }
1657 }
1658 }
1659
1660 dc.DrawRectangle(label_bg_rect);
1661 if(clip_label)
1662 {
1663 wxDCClipper clip(dc, label_rect);
1664 dc.DrawText(label, label_rect.x, label_rect.y +
1665 (label_rect.GetHeight() - label_size.GetHeight()) / 2);
1666 }
1667 else
1668 {
1669 dc.DrawText(label, label_rect.x +
1670 (label_rect.GetWidth() - label_size.GetWidth()) / 2,
1671 label_rect.y +
1672 (label_rect.GetHeight() - label_size.GetHeight()) / 2);
1673 }
1674
1675 if(has_ext_button)
1676 {
1677 if(wnd->IsExtButtonHovered())
1678 {
1679 dc.SetPen(m_panel_hover_button_border_pen);
1680 dc.SetBrush(m_panel_hover_button_background_brush);
1681 dc.DrawRoundedRectangle(label_rect.GetRight(), label_rect.GetBottom() - 13, 13, 13, 1.0);
1682 dc.DrawBitmap(m_panel_extension_bitmap[1], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
1683 }
1684 else
1685 dc.DrawBitmap(m_panel_extension_bitmap[0], label_rect.GetRight() + 3, label_rect.GetBottom() - 10, true);
1686 }
1687 }
1688
1689 if(wnd->IsHovered())
1690 {
1691 wxRect client_rect(true_rect);
1692 client_rect.x++;
1693 client_rect.width -= 2;
1694 client_rect.y++;
1695 client_rect.height -= 2 + label_height;
1696 DrawPartialPageBackground(dc, wnd, client_rect, true);
1697 }
1698
1699 DrawPanelBorder(dc, true_rect, m_panel_border_pen, m_panel_border_gradient_pen);
1700 }
1701
1702 wxRect wxRibbonMSWArtProvider::GetPanelExtButtonArea(wxDC& WXUNUSED(dc),
1703 const wxRibbonPanel* WXUNUSED(wnd),
1704 wxRect rect)
1705 {
1706 RemovePanelPadding(&rect);
1707 rect = wxRect(rect.GetRight()-13, rect.GetBottom()-13, 13, 13);
1708 return rect;
1709 }
1710
1711 void wxRibbonMSWArtProvider::DrawGalleryBackground(
1712 wxDC& dc,
1713 wxRibbonGallery* wnd,
1714 const wxRect& rect)
1715 {
1716 DrawPartialPageBackground(dc, wnd, rect);
1717
1718 if(wnd->IsHovered())
1719 {
1720 dc.SetPen(*wxTRANSPARENT_PEN);
1721 dc.SetBrush(m_gallery_hover_background_brush);
1722 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1723 {
1724 dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 2,
1725 rect.height - 16);
1726 }
1727 else
1728 {
1729 dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 16,
1730 rect.height - 2);
1731 }
1732 }
1733
1734 dc.SetPen(m_gallery_border_pen);
1735 // Outline
1736 dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
1737 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
1738 dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
1739 rect.y + rect.height - 1);
1740 dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
1741 rect.y + rect.height - 1);
1742
1743 DrawGalleryBackgroundCommon(dc, wnd, rect);
1744 }
1745
1746 void wxRibbonMSWArtProvider::DrawGalleryBackgroundCommon(wxDC& dc,
1747 wxRibbonGallery* wnd,
1748 const wxRect& rect)
1749 {
1750 wxRect up_btn, down_btn, ext_btn;
1751
1752 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1753 {
1754 // Divider between items and buttons
1755 dc.DrawLine(rect.x, rect.y + rect.height - 15, rect.x + rect.width,
1756 rect.y + rect.height - 15);
1757
1758 up_btn = wxRect(rect.x, rect.y + rect.height - 15, rect.width / 3, 15);
1759
1760 down_btn = wxRect(up_btn.GetRight() + 1, up_btn.GetTop(),
1761 up_btn.GetWidth(), up_btn.GetHeight());
1762 dc.DrawLine(down_btn.GetLeft(), down_btn.GetTop(), down_btn.GetLeft(),
1763 down_btn.GetBottom());
1764
1765 ext_btn = wxRect(down_btn.GetRight() + 1, up_btn.GetTop(), rect.width -
1766 up_btn.GetWidth() - down_btn.GetWidth() - 1, up_btn.GetHeight());
1767 dc.DrawLine(ext_btn.GetLeft(), ext_btn.GetTop(), ext_btn.GetLeft(),
1768 ext_btn.GetBottom());
1769 }
1770 else
1771 {
1772 // Divider between items and buttons
1773 dc.DrawLine(rect.x + rect.width - 15, rect.y, rect.x + rect.width - 15,
1774 rect.y + rect.height);
1775
1776 up_btn = wxRect(rect.x + rect.width - 15, rect.y, 15, rect.height / 3);
1777
1778 down_btn = wxRect(up_btn.GetLeft(), up_btn.GetBottom() + 1,
1779 up_btn.GetWidth(), up_btn.GetHeight());
1780 dc.DrawLine(down_btn.GetLeft(), down_btn.GetTop(), down_btn.GetRight(),
1781 down_btn.GetTop());
1782
1783 ext_btn = wxRect(up_btn.GetLeft(), down_btn.GetBottom() + 1, up_btn.GetWidth(),
1784 rect.height - up_btn.GetHeight() - down_btn.GetHeight() - 1);
1785 dc.DrawLine(ext_btn.GetLeft(), ext_btn.GetTop(), ext_btn.GetRight(),
1786 ext_btn.GetTop());
1787 }
1788
1789 DrawGalleryButton(dc, up_btn, wnd->GetUpButtonState(),
1790 m_gallery_up_bitmap);
1791 DrawGalleryButton(dc, down_btn, wnd->GetDownButtonState(),
1792 m_gallery_down_bitmap);
1793 DrawGalleryButton(dc, ext_btn, wnd->GetExtensionButtonState(),
1794 m_gallery_extension_bitmap);
1795 }
1796
1797 void wxRibbonMSWArtProvider::DrawGalleryButton(wxDC& dc,
1798 wxRect rect,
1799 wxRibbonGalleryButtonState state,
1800 wxBitmap* bitmaps)
1801 {
1802 wxBitmap btn_bitmap;
1803 wxBrush btn_top_brush;
1804 wxColour btn_colour;
1805 wxColour btn_grad_colour;
1806 switch(state)
1807 {
1808 case wxRIBBON_GALLERY_BUTTON_NORMAL:
1809 btn_top_brush = m_gallery_button_background_top_brush;
1810 btn_colour = m_gallery_button_background_colour;
1811 btn_grad_colour = m_gallery_button_background_gradient_colour;
1812 btn_bitmap = bitmaps[0];
1813 break;
1814 case wxRIBBON_GALLERY_BUTTON_HOVERED:
1815 btn_top_brush = m_gallery_button_hover_background_top_brush;
1816 btn_colour = m_gallery_button_hover_background_colour;
1817 btn_grad_colour = m_gallery_button_hover_background_gradient_colour;
1818 btn_bitmap = bitmaps[1];
1819 break;
1820 case wxRIBBON_GALLERY_BUTTON_ACTIVE:
1821 btn_top_brush = m_gallery_button_active_background_top_brush;
1822 btn_colour = m_gallery_button_active_background_colour;
1823 btn_grad_colour = m_gallery_button_active_background_gradient_colour;
1824 btn_bitmap = bitmaps[2];
1825 break;
1826 case wxRIBBON_GALLERY_BUTTON_DISABLED:
1827 btn_top_brush = m_gallery_button_disabled_background_top_brush;
1828 btn_colour = m_gallery_button_disabled_background_colour;
1829 btn_grad_colour = m_gallery_button_disabled_background_gradient_colour;
1830 btn_bitmap = bitmaps[3];
1831 break;
1832 }
1833
1834 rect.x++;
1835 rect.y++;
1836 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1837 {
1838 rect.width--;;
1839 rect.height -= 2;
1840 }
1841 else
1842 {
1843 rect.width -= 2;
1844 rect.height--;
1845 }
1846
1847 dc.SetPen(*wxTRANSPARENT_PEN);
1848 dc.SetBrush(btn_top_brush);
1849 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height / 2);
1850
1851 wxRect lower(rect);
1852 lower.height = (lower.height + 1) / 2;
1853 lower.y += rect.height - lower.height;
1854 dc.GradientFillLinear(lower, btn_colour, btn_grad_colour, wxSOUTH);
1855
1856 dc.DrawBitmap(btn_bitmap, rect.x + rect.width / 2 - 2, lower.y - 2, true);
1857 }
1858
1859 void wxRibbonMSWArtProvider::DrawGalleryItemBackground(
1860 wxDC& dc,
1861 wxRibbonGallery* wnd,
1862 const wxRect& rect,
1863 wxRibbonGalleryItem* item)
1864 {
1865 if(wnd->GetHoveredItem() != item && wnd->GetActiveItem() != item &&
1866 wnd->GetSelection() != item)
1867 return;
1868
1869 dc.SetPen(m_gallery_item_border_pen);
1870 dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
1871 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
1872 dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
1873 rect.y + rect.height - 1);
1874 dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
1875 rect.y + rect.height - 1);
1876
1877 wxBrush top_brush;
1878 wxColour bg_colour;
1879 wxColour bg_gradient_colour;
1880
1881 if(wnd->GetActiveItem() == item || wnd->GetSelection() == item)
1882 {
1883 top_brush = m_gallery_button_active_background_top_brush;
1884 bg_colour = m_gallery_button_active_background_colour;
1885 bg_gradient_colour = m_gallery_button_active_background_gradient_colour;
1886 }
1887 else
1888 {
1889 top_brush = m_gallery_button_hover_background_top_brush;
1890 bg_colour = m_gallery_button_hover_background_colour;
1891 bg_gradient_colour = m_gallery_button_hover_background_gradient_colour;
1892 }
1893
1894 wxRect upper(rect);
1895 upper.x += 1;
1896 upper.width -= 2;
1897 upper.y += 1;
1898 upper.height /= 3;
1899 dc.SetPen(*wxTRANSPARENT_PEN);
1900 dc.SetBrush(top_brush);
1901 dc.DrawRectangle(upper.x, upper.y, upper.width, upper.height);
1902
1903 wxRect lower(upper);
1904 lower.y += lower.height;
1905 lower.height = rect.height - 2 - lower.height;
1906 dc.GradientFillLinear(lower, bg_colour, bg_gradient_colour, wxSOUTH);
1907 }
1908
1909 void wxRibbonMSWArtProvider::DrawPanelBorder(wxDC& dc, const wxRect& rect,
1910 wxPen& primary_colour,
1911 wxPen& secondary_colour)
1912 {
1913 wxPoint border_points[9];
1914 border_points[0] = wxPoint(2, 0);
1915 border_points[1] = wxPoint(rect.width - 3, 0);
1916 border_points[2] = wxPoint(rect.width - 1, 2);
1917 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
1918 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
1919 border_points[5] = wxPoint(2, rect.height - 1);
1920 border_points[6] = wxPoint(0, rect.height - 3);
1921 border_points[7] = wxPoint(0, 2);
1922
1923 if(primary_colour.GetColour() == secondary_colour.GetColour())
1924 {
1925 border_points[8] = border_points[0];
1926 dc.SetPen(primary_colour);
1927 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1928 }
1929 else
1930 {
1931 dc.SetPen(primary_colour);
1932 dc.DrawLines(3, border_points, rect.x, rect.y);
1933
1934 #define SingleLine(start, finish) \
1935 dc.DrawLine(start.x + rect.x, start.y + rect.y, finish.x + rect.x, finish.y + rect.y)
1936
1937 SingleLine(border_points[0], border_points[7]);
1938 dc.SetPen(secondary_colour);
1939 dc.DrawLines(3, border_points + 4, rect.x, rect.y);
1940 SingleLine(border_points[4], border_points[3]);
1941
1942 #undef SingleLine
1943
1944 border_points[6] = border_points[2];
1945 wxRibbonDrawParallelGradientLines(dc, 2, border_points + 6, 0, 1,
1946 border_points[3].y - border_points[2].y + 1, rect.x, rect.y,
1947 primary_colour.GetColour(), secondary_colour.GetColour());
1948 }
1949 }
1950
1951 void wxRibbonMSWArtProvider::DrawMinimisedPanel(
1952 wxDC& dc,
1953 wxRibbonPanel* wnd,
1954 const wxRect& rect,
1955 wxBitmap& bitmap)
1956 {
1957 DrawPartialPageBackground(dc, wnd, rect, false);
1958
1959 wxRect true_rect(rect);
1960 RemovePanelPadding(&true_rect);
1961
1962 if(wnd->GetExpandedPanel() != NULL)
1963 {
1964 wxRect client_rect(true_rect);
1965 client_rect.x++;
1966 client_rect.width -= 2;
1967 client_rect.y++;
1968 client_rect.height = (rect.y + rect.height / 5) - client_rect.x;
1969 dc.GradientFillLinear(client_rect,
1970 m_panel_active_background_top_colour,
1971 m_panel_active_background_top_gradient_colour, wxSOUTH);
1972
1973 client_rect.y += client_rect.height;
1974 client_rect.height = (true_rect.y + true_rect.height) - client_rect.y;
1975 dc.GradientFillLinear(client_rect,
1976 m_panel_active_background_colour,
1977 m_panel_active_background_gradient_colour, wxSOUTH);
1978 }
1979 else if(wnd->IsHovered())
1980 {
1981 wxRect client_rect(true_rect);
1982 client_rect.x++;
1983 client_rect.width -= 2;
1984 client_rect.y++;
1985 client_rect.height -= 2;
1986 DrawPartialPageBackground(dc, wnd, client_rect, true);
1987 }
1988
1989 wxRect preview;
1990 DrawMinimisedPanelCommon(dc, wnd, true_rect, &preview);
1991
1992 dc.SetBrush(m_panel_hover_label_background_brush);
1993 dc.SetPen(*wxTRANSPARENT_PEN);
1994 dc.DrawRectangle(preview.x + 1, preview.y + preview.height - 8,
1995 preview.width - 2, 7);
1996
1997 int mid_pos = rect.y + rect.height / 5 - preview.y;
1998 if(mid_pos < 0 || mid_pos >= preview.height)
1999 {
2000 wxRect full_rect(preview);
2001 full_rect.x += 1;
2002 full_rect.y += 1;
2003 full_rect.width -= 2;
2004 full_rect.height -= 9;
2005 if(mid_pos < 0)
2006 {
2007 dc.GradientFillLinear(full_rect,
2008 m_page_hover_background_colour,
2009 m_page_hover_background_gradient_colour, wxSOUTH);
2010 }
2011 else
2012 {
2013 dc.GradientFillLinear(full_rect,
2014 m_page_hover_background_top_colour,
2015 m_page_hover_background_top_gradient_colour, wxSOUTH);
2016 }
2017 }
2018 else
2019 {
2020 wxRect top_rect(preview);
2021 top_rect.x += 1;
2022 top_rect.y += 1;
2023 top_rect.width -= 2;
2024 top_rect.height = mid_pos;
2025 dc.GradientFillLinear(top_rect,
2026 m_page_hover_background_top_colour,
2027 m_page_hover_background_top_gradient_colour, wxSOUTH);
2028
2029 wxRect btm_rect(top_rect);
2030 btm_rect.y = preview.y + mid_pos;
2031 btm_rect.height = preview.y + preview.height - 7 - btm_rect.y;
2032 dc.GradientFillLinear(btm_rect,
2033 m_page_hover_background_colour,
2034 m_page_hover_background_gradient_colour, wxSOUTH);
2035 }
2036
2037 if(bitmap.IsOk())
2038 {
2039 dc.DrawBitmap(bitmap, preview.x + (preview.width - bitmap.GetWidth()) / 2,
2040 preview.y + (preview.height - 7 - bitmap.GetHeight()) / 2, true);
2041 }
2042
2043 DrawPanelBorder(dc, preview, m_panel_border_pen, m_panel_border_gradient_pen);
2044
2045 DrawPanelBorder(dc, true_rect, m_panel_minimised_border_pen,
2046 m_panel_minimised_border_gradient_pen);
2047 }
2048
2049 void wxRibbonMSWArtProvider::DrawMinimisedPanelCommon(
2050 wxDC& dc,
2051 wxRibbonPanel* wnd,
2052 const wxRect& true_rect,
2053 wxRect* preview_rect)
2054 {
2055 wxRect preview(0, 0, 32, 32);
2056 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2057 {
2058 preview.x = true_rect.x + 4;
2059 preview.y = true_rect.y + (true_rect.height - preview.height) / 2;
2060 }
2061 else
2062 {
2063 preview.x = true_rect.x + (true_rect.width - preview.width) / 2;
2064 preview.y = true_rect.y + 4;
2065 }
2066 if(preview_rect)
2067 *preview_rect = preview;
2068
2069 wxCoord label_width, label_height;
2070 dc.SetFont(m_panel_label_font);
2071 dc.GetTextExtent(wnd->GetLabel(), &label_width, &label_height);
2072
2073 int xpos = true_rect.x + (true_rect.width - label_width + 1) / 2;
2074 int ypos = preview.y + preview.height + 5;
2075
2076 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2077 {
2078 xpos = preview.x + preview.width + 5;
2079 ypos = true_rect.y + (true_rect.height - label_height) / 2;
2080 }
2081
2082 dc.SetTextForeground(m_panel_minimised_label_colour);
2083 dc.DrawText(wnd->GetLabel(), xpos, ypos);
2084
2085
2086 wxPoint arrow_points[3];
2087 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2088 {
2089 xpos += label_width;
2090 arrow_points[0] = wxPoint(xpos + 5, ypos + label_height / 2);
2091 arrow_points[1] = arrow_points[0] + wxPoint(-3, 3);
2092 arrow_points[2] = arrow_points[0] + wxPoint(-3, -3);
2093 }
2094 else
2095 {
2096 ypos += label_height;
2097 arrow_points[0] = wxPoint(true_rect.width / 2, ypos + 5);
2098 arrow_points[1] = arrow_points[0] + wxPoint(-3, -3);
2099 arrow_points[2] = arrow_points[0] + wxPoint( 3, -3);
2100 }
2101
2102 dc.SetPen(*wxTRANSPARENT_PEN);
2103 wxBrush B(m_panel_minimised_label_colour);
2104 dc.SetBrush(B);
2105 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points,
2106 true_rect.x, true_rect.y);
2107 }
2108
2109 void wxRibbonMSWArtProvider::DrawButtonBarBackground(
2110 wxDC& dc,
2111 wxWindow* wnd,
2112 const wxRect& rect)
2113 {
2114 DrawPartialPageBackground(dc, wnd, rect, true);
2115 }
2116
2117 void wxRibbonMSWArtProvider::DrawPartialPageBackground(
2118 wxDC& dc,
2119 wxWindow* wnd,
2120 const wxRect& rect,
2121 bool allow_hovered)
2122 {
2123 // Assume the window is a child of a ribbon page, and also check for a
2124 // hovered panel somewhere between the window and the page, as it causes
2125 // the background to change.
2126 wxPoint offset(wnd->GetPosition());
2127 wxRibbonPage* page = NULL;
2128 wxWindow* parent = wnd->GetParent();
2129 wxRibbonPanel* panel = wxDynamicCast(wnd, wxRibbonPanel);
2130 bool hovered = false;
2131
2132 if(panel != NULL)
2133 {
2134 hovered = allow_hovered && panel->IsHovered();
2135 if(panel->GetExpandedDummy() != NULL)
2136 {
2137 offset = panel->GetExpandedDummy()->GetPosition();
2138 parent = panel->GetExpandedDummy()->GetParent();
2139 }
2140 }
2141 for(; parent; parent = parent->GetParent())
2142 {
2143 if(panel == NULL)
2144 {
2145 panel = wxDynamicCast(parent, wxRibbonPanel);
2146 if(panel != NULL)
2147 {
2148 hovered = allow_hovered && panel->IsHovered();
2149 if(panel->GetExpandedDummy() != NULL)
2150 {
2151 parent = panel->GetExpandedDummy();
2152 }
2153 }
2154 }
2155 page = wxDynamicCast(parent, wxRibbonPage);
2156 if(page != NULL)
2157 {
2158 break;
2159 }
2160 offset += parent->GetPosition();
2161 }
2162 if(page != NULL)
2163 {
2164 DrawPartialPageBackground(dc, wnd, rect, page, offset, hovered);
2165 return;
2166 }
2167
2168 // No page found - fallback to painting with a stock brush
2169 dc.SetBrush(*wxWHITE_BRUSH);
2170 dc.SetPen(*wxTRANSPARENT_PEN);
2171 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
2172 }
2173
2174 void wxRibbonMSWArtProvider::DrawButtonBarButton(
2175 wxDC& dc,
2176 wxWindow* WXUNUSED(wnd),
2177 const wxRect& rect,
2178 wxRibbonButtonKind kind,
2179 long state,
2180 const wxString& label,
2181 const wxBitmap& bitmap_large,
2182 const wxBitmap& bitmap_small)
2183 {
2184 if(kind == wxRIBBON_BUTTON_TOGGLE)
2185 {
2186 kind = wxRIBBON_BUTTON_NORMAL;
2187 if(state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED)
2188 state ^= wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
2189 }
2190
2191 if(state & (wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK |
2192 wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK))
2193 {
2194 if(state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK)
2195 dc.SetPen(m_button_bar_active_border_pen);
2196 else
2197 dc.SetPen(m_button_bar_hover_border_pen);
2198
2199 wxRect bg_rect(rect);
2200 bg_rect.x++;
2201 bg_rect.y++;
2202 bg_rect.width -= 2;
2203 bg_rect.height -= 2;
2204
2205 wxRect bg_rect_top(bg_rect);
2206 bg_rect_top.height /= 3;
2207 bg_rect.y += bg_rect_top.height;
2208 bg_rect.height -= bg_rect_top.height;
2209
2210 if(kind == wxRIBBON_BUTTON_HYBRID)
2211 {
2212 switch(state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2213 {
2214 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2215 {
2216 int iYBorder = rect.y + bitmap_large.GetHeight() + 4;
2217 wxRect partial_bg(rect);
2218 if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
2219 {
2220 partial_bg.SetBottom(iYBorder - 1);
2221 }
2222 else
2223 {
2224 partial_bg.height -= (iYBorder - partial_bg.y + 1);
2225 partial_bg.y = iYBorder + 1;
2226 }
2227 dc.DrawLine(rect.x, iYBorder, rect.x + rect.width, iYBorder);
2228 bg_rect.Intersect(partial_bg);
2229 bg_rect_top.Intersect(partial_bg);
2230 }
2231 break;
2232 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2233 {
2234 int iArrowWidth = 9;
2235 if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
2236 {
2237 bg_rect.width -= iArrowWidth;
2238 bg_rect_top.width -= iArrowWidth;
2239 dc.DrawLine(bg_rect_top.x + bg_rect_top.width,
2240 rect.y, bg_rect_top.x + bg_rect_top.width,
2241 rect.y + rect.height);
2242 }
2243 else
2244 {
2245 --iArrowWidth;
2246 bg_rect.x += bg_rect.width - iArrowWidth;
2247 bg_rect_top.x += bg_rect_top.width - iArrowWidth;
2248 bg_rect.width = iArrowWidth;
2249 bg_rect_top.width = iArrowWidth;
2250 dc.DrawLine(bg_rect_top.x - 1, rect.y,
2251 bg_rect_top.x - 1, rect.y + rect.height);
2252 }
2253 }
2254 break;
2255 case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
2256 break;
2257 }
2258 }
2259
2260 if(state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK)
2261 {
2262 dc.GradientFillLinear(bg_rect_top,
2263 m_button_bar_active_background_top_colour,
2264 m_button_bar_active_background_top_gradient_colour, wxSOUTH);
2265 dc.GradientFillLinear(bg_rect,
2266 m_button_bar_active_background_colour,
2267 m_button_bar_active_background_gradient_colour, wxSOUTH);
2268 }
2269 else
2270 {
2271 dc.GradientFillLinear(bg_rect_top,
2272 m_button_bar_hover_background_top_colour,
2273 m_button_bar_hover_background_top_gradient_colour, wxSOUTH);
2274 dc.GradientFillLinear(bg_rect,
2275 m_button_bar_hover_background_colour,
2276 m_button_bar_hover_background_gradient_colour, wxSOUTH);
2277 }
2278
2279 wxPoint border_points[9];
2280 border_points[0] = wxPoint(2, 0);
2281 border_points[1] = wxPoint(rect.width - 3, 0);
2282 border_points[2] = wxPoint(rect.width - 1, 2);
2283 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
2284 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
2285 border_points[5] = wxPoint(2, rect.height - 1);
2286 border_points[6] = wxPoint(0, rect.height - 3);
2287 border_points[7] = wxPoint(0, 2);
2288 border_points[8] = border_points[0];
2289
2290 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
2291 rect.x, rect.y);
2292 }
2293
2294 dc.SetFont(m_button_bar_label_font);
2295 dc.SetTextForeground(m_button_bar_label_colour);
2296 DrawButtonBarButtonForeground(dc, rect, kind, state, label, bitmap_large,
2297 bitmap_small);
2298 }
2299
2300 void wxRibbonMSWArtProvider::DrawButtonBarButtonForeground(
2301 wxDC& dc,
2302 const wxRect& rect,
2303 wxRibbonButtonKind kind,
2304 long state,
2305 const wxString& label,
2306 const wxBitmap& bitmap_large,
2307 const wxBitmap& bitmap_small)
2308 {
2309 switch(state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2310 {
2311 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2312 {
2313 const int padding = 2;
2314 dc.DrawBitmap(bitmap_large,
2315 rect.x + (rect.width - bitmap_large.GetWidth()) / 2,
2316 rect.y + padding, true);
2317 int ypos = rect.y + padding + bitmap_large.GetHeight() + padding;
2318 int arrow_width = kind == wxRIBBON_BUTTON_NORMAL ? 0 : 8;
2319 wxCoord label_w, label_h;
2320 dc.GetTextExtent(label, &label_w, &label_h);
2321 if(label_w + 2 * padding <= rect.width)
2322 {
2323 dc.DrawText(label, rect.x + (rect.width - label_w) / 2, ypos);
2324 if(arrow_width != 0)
2325 {
2326 DrawDropdownArrow(dc, rect.x + rect.width / 2,
2327 ypos + (label_h * 3) / 2,
2328 m_button_bar_label_colour);
2329 }
2330 }
2331 else
2332 {
2333 size_t breaki = label.Len();
2334 do
2335 {
2336 --breaki;
2337 if(wxRibbonCanLabelBreakAtPosition(label, breaki))
2338 {
2339 wxString label_top = label.Mid(0, breaki);
2340 dc.GetTextExtent(label_top, &label_w, &label_h);
2341 if(label_w + 2 * padding <= rect.width)
2342 {
2343 dc.DrawText(label_top,
2344 rect.x + (rect.width - label_w) / 2, ypos);
2345 ypos += label_h;
2346 wxString label_bottom = label.Mid(breaki + 1);
2347 dc.GetTextExtent(label_bottom, &label_w, &label_h);
2348 label_w += arrow_width;
2349 int iX = rect.x + (rect.width - label_w) / 2;
2350 dc.DrawText(label_bottom, iX, ypos);
2351 if(arrow_width != 0)
2352 {
2353 DrawDropdownArrow(dc,
2354 iX + 2 +label_w - arrow_width,
2355 ypos + label_h / 2 + 1,
2356 m_button_bar_label_colour);
2357 }
2358 break;
2359 }
2360 }
2361 } while(breaki > 0);
2362 }
2363 }
2364 break;
2365 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2366 {
2367 int x_cursor = rect.x + 2;
2368 dc.DrawBitmap(bitmap_small, x_cursor,
2369 rect.y + (rect.height - bitmap_small.GetHeight())/2, true);
2370 x_cursor += bitmap_small.GetWidth() + 2;
2371 wxCoord label_w, label_h;
2372 dc.GetTextExtent(label, &label_w, &label_h);
2373 dc.DrawText(label, x_cursor,
2374 rect.y + (rect.height - label_h) / 2);
2375 x_cursor += label_w + 3;
2376 if(kind != wxRIBBON_BUTTON_NORMAL)
2377 {
2378 DrawDropdownArrow(dc, x_cursor, rect.y + rect.height / 2,
2379 m_button_bar_label_colour);
2380 }
2381 break;
2382 }
2383 default:
2384 // TODO
2385 break;
2386 }
2387 }
2388
2389 void wxRibbonMSWArtProvider::DrawToolBarBackground(
2390 wxDC& dc,
2391 wxWindow* wnd,
2392 const wxRect& rect)
2393 {
2394 DrawPartialPageBackground(dc, wnd, rect);
2395 }
2396
2397 void wxRibbonMSWArtProvider::DrawToolGroupBackground(
2398 wxDC& dc,
2399 wxWindow* WXUNUSED(wnd),
2400 const wxRect& rect)
2401 {
2402 dc.SetPen(m_toolbar_border_pen);
2403 wxPoint outline[9];
2404 outline[0] = wxPoint(2, 0);
2405 outline[1] = wxPoint(rect.width - 3, 0);
2406 outline[2] = wxPoint(rect.width - 1, 2);
2407 outline[3] = wxPoint(rect.width - 1, rect.height - 3);
2408 outline[4] = wxPoint(rect.width - 3, rect.height - 1);
2409 outline[5] = wxPoint(2, rect.height - 1);
2410 outline[6] = wxPoint(0, rect.height - 3);
2411 outline[7] = wxPoint(0, 2);
2412 outline[8] = outline[0];
2413
2414 dc.DrawLines(sizeof(outline)/sizeof(wxPoint), outline, rect.x, rect.y);
2415 }
2416
2417 void wxRibbonMSWArtProvider::DrawTool(
2418 wxDC& dc,
2419 wxWindow* WXUNUSED(wnd),
2420 const wxRect& rect,
2421 const wxBitmap& bitmap,
2422 wxRibbonButtonKind kind,
2423 long state)
2424 {
2425 if(kind == wxRIBBON_BUTTON_TOGGLE)
2426 {
2427 if(state & wxRIBBON_TOOLBAR_TOOL_TOGGLED)
2428 state ^= wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
2429 }
2430
2431 wxRect bg_rect(rect);
2432 bg_rect.Deflate(1);
2433 if((state & wxRIBBON_TOOLBAR_TOOL_LAST) == 0)
2434 bg_rect.width++;
2435 bool is_split_hybrid = (kind == wxRIBBON_BUTTON_HYBRID && (state &
2436 (wxRIBBON_TOOLBAR_TOOL_HOVER_MASK | wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)));
2437
2438 // Background
2439 wxRect bg_rect_top(bg_rect);
2440 bg_rect_top.height = (bg_rect_top.height * 2) / 5;
2441 wxRect bg_rect_btm(bg_rect);
2442 bg_rect_btm.y += bg_rect_top.height;
2443 bg_rect_btm.height -= bg_rect_top.height;
2444 wxColour bg_top_colour = m_tool_background_top_colour;
2445 wxColour bg_top_grad_colour = m_tool_background_top_gradient_colour;
2446 wxColour bg_colour = m_tool_background_colour;
2447 wxColour bg_grad_colour = m_tool_background_gradient_colour;
2448 if(state & wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)
2449 {
2450 bg_top_colour = m_tool_active_background_top_colour;
2451 bg_top_grad_colour = m_tool_active_background_top_gradient_colour;
2452 bg_colour = m_tool_active_background_colour;
2453 bg_grad_colour = m_tool_active_background_gradient_colour;
2454 }
2455 else if(state & wxRIBBON_TOOLBAR_TOOL_HOVER_MASK)
2456 {
2457 bg_top_colour = m_tool_hover_background_top_colour;
2458 bg_top_grad_colour = m_tool_hover_background_top_gradient_colour;
2459 bg_colour = m_tool_hover_background_colour;
2460 bg_grad_colour = m_tool_hover_background_gradient_colour;
2461 }
2462 dc.GradientFillLinear(bg_rect_top, bg_top_colour, bg_top_grad_colour, wxSOUTH);
2463 dc.GradientFillLinear(bg_rect_btm, bg_colour, bg_grad_colour, wxSOUTH);
2464 if(is_split_hybrid)
2465 {
2466 wxRect nonrect(bg_rect);
2467 if(state & (wxRIBBON_TOOLBAR_TOOL_DROPDOWN_HOVERED |
2468 wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE))
2469 {
2470 nonrect.width -= 8;
2471 }
2472 else
2473 {
2474 nonrect.x += nonrect.width - 8;
2475 nonrect.width = 8;
2476 }
2477 wxBrush B(m_tool_hover_background_top_colour);
2478 dc.SetPen(*wxTRANSPARENT_PEN);
2479 dc.SetBrush(B);
2480 dc.DrawRectangle(nonrect.x, nonrect.y, nonrect.width, nonrect.height);
2481 }
2482
2483 // Border
2484 dc.SetPen(m_toolbar_border_pen);
2485 if(state & wxRIBBON_TOOLBAR_TOOL_FIRST)
2486 {
2487 dc.DrawPoint(rect.x + 1, rect.y + 1);
2488 dc.DrawPoint(rect.x + 1, rect.y + rect.height - 2);
2489 }
2490 else
2491 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
2492
2493 if(state & wxRIBBON_TOOLBAR_TOOL_LAST)
2494 {
2495 dc.DrawPoint(rect.x + rect.width - 2, rect.y + 1);
2496 dc.DrawPoint(rect.x + rect.width - 2, rect.y + rect.height - 2);
2497 }
2498
2499 // Foreground
2500 int avail_width = bg_rect.GetWidth();
2501 if(kind & wxRIBBON_BUTTON_DROPDOWN)
2502 {
2503 avail_width -= 8;
2504 if(is_split_hybrid)
2505 {
2506 dc.DrawLine(rect.x + avail_width + 1, rect.y,
2507 rect.x + avail_width + 1, rect.y + rect.height);
2508 }
2509 dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2,
2510 bg_rect.y + (bg_rect.height / 2) - 2, true);
2511 }
2512 dc.DrawBitmap(bitmap, bg_rect.x + (avail_width - bitmap.GetWidth()) / 2,
2513 bg_rect.y + (bg_rect.height - bitmap.GetHeight()) / 2, true);
2514 }
2515
2516 void
2517 wxRibbonMSWArtProvider::DrawToggleButton(wxDC& dc,
2518 wxRibbonBar* wnd,
2519 const wxRect& rect,
2520 bool upBitmap)
2521 {
2522 DrawPartialPageBackground(dc, wnd, rect, false);
2523
2524 dc.DestroyClippingRegion();
2525 dc.SetClippingRegion(rect);
2526
2527 if(wnd->IsToggleButtonHovered())
2528 {
2529 dc.SetPen(m_ribbon_toggle_pen);
2530 dc.SetBrush(m_ribbon_toggle_brush);
2531 dc.DrawRoundedRectangle(rect.GetX(), rect.GetY(), 12, 12, 1.0);
2532 if(upBitmap)
2533 dc.DrawBitmap(m_ribbon_toggle_up_bitmap[1], rect.GetX()+2, rect.GetY()+2, true);
2534 else
2535 dc.DrawBitmap(m_ribbon_toggle_down_bitmap[1], rect.GetX()+2, rect.GetY()+2, true);
2536 }
2537 else
2538 {
2539 if(upBitmap)
2540 dc.DrawBitmap(m_ribbon_toggle_up_bitmap[0], rect.GetX()+2, rect.GetY()+2, true);
2541 else
2542 dc.DrawBitmap(m_ribbon_toggle_down_bitmap[0], rect.GetX()+2, rect.GetY()+2, true);
2543 }
2544 }
2545
2546 void wxRibbonMSWArtProvider::GetBarTabWidth(
2547 wxDC& dc,
2548 wxWindow* WXUNUSED(wnd),
2549 const wxString& label,
2550 const wxBitmap& bitmap,
2551 int* ideal,
2552 int* small_begin_need_separator,
2553 int* small_must_have_separator,
2554 int* minimum)
2555 {
2556 int width = 0;
2557 int min = 0;
2558 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) && !label.IsEmpty())
2559 {
2560 dc.SetFont(m_tab_label_font);
2561 width += dc.GetTextExtent(label).GetWidth();
2562 min += wxMin(25, width); // enough for a few chars
2563 if(bitmap.IsOk())
2564 {
2565 // gap between label and bitmap
2566 width += 4;
2567 min += 2;
2568 }
2569 }
2570 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS) && bitmap.IsOk())
2571 {
2572 width += bitmap.GetWidth();
2573 min += bitmap.GetWidth();
2574 }
2575
2576 if(ideal != NULL)
2577 {
2578 *ideal = width + 30;
2579 }
2580 if(small_begin_need_separator != NULL)
2581 {
2582 *small_begin_need_separator = width + 20;
2583 }
2584 if(small_must_have_separator != NULL)
2585 {
2586 *small_must_have_separator = width + 10;
2587 }
2588 if(minimum != NULL)
2589 {
2590 *minimum = min;
2591 }
2592 }
2593
2594 int wxRibbonMSWArtProvider::GetTabCtrlHeight(
2595 wxDC& dc,
2596 wxWindow* WXUNUSED(wnd),
2597 const wxRibbonPageTabInfoArray& pages)
2598 {
2599 int text_height = 0;
2600 int icon_height = 0;
2601
2602 if(pages.GetCount() <= 1 && (m_flags & wxRIBBON_BAR_ALWAYS_SHOW_TABS) == 0)
2603 {
2604 // To preserve space, a single tab need not be displayed. We still need
2605 // two pixels of border / padding though.
2606 return 2;
2607 }
2608
2609 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS)
2610 {
2611 dc.SetFont(m_tab_label_font);
2612 text_height = dc.GetTextExtent(wxT("ABCDEFXj")).GetHeight() + 10;
2613 }
2614 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
2615 {
2616 size_t numpages = pages.GetCount();
2617 for(size_t i = 0; i < numpages; ++i)
2618 {
2619 const wxRibbonPageTabInfo& info = pages.Item(i);
2620 if(info.page->GetIcon().IsOk())
2621 {
2622 icon_height = wxMax(icon_height, info.page->GetIcon().GetHeight() + 4);
2623 }
2624 }
2625 }
2626
2627 return wxMax(text_height, icon_height);
2628 }
2629
2630 wxSize wxRibbonMSWArtProvider::GetScrollButtonMinimumSize(
2631 wxDC& WXUNUSED(dc),
2632 wxWindow* WXUNUSED(wnd),
2633 long WXUNUSED(style))
2634 {
2635 return wxSize(12, 12);
2636 }
2637
2638 wxSize wxRibbonMSWArtProvider::GetPanelSize(
2639 wxDC& dc,
2640 const wxRibbonPanel* wnd,
2641 wxSize client_size,
2642 wxPoint* client_offset)
2643 {
2644 dc.SetFont(m_panel_label_font);
2645 wxSize label_size = dc.GetTextExtent(wnd->GetLabel());
2646
2647 client_size.IncBy(0, label_size.GetHeight());
2648 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2649 client_size.IncBy(4, 8);
2650 else
2651 client_size.IncBy(6, 6);
2652
2653 if(client_offset != NULL)
2654 {
2655 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2656 *client_offset = wxPoint(2, 3);
2657 else
2658 *client_offset = wxPoint(3, 2);
2659 }
2660
2661 return client_size;
2662 }
2663
2664 wxSize wxRibbonMSWArtProvider::GetPanelClientSize(
2665 wxDC& dc,
2666 const wxRibbonPanel* wnd,
2667 wxSize size,
2668 wxPoint* client_offset)
2669 {
2670 dc.SetFont(m_panel_label_font);
2671 wxSize label_size = dc.GetTextExtent(wnd->GetLabel());
2672
2673 size.DecBy(0, label_size.GetHeight());
2674 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2675 size.DecBy(4, 8);
2676 else
2677 size.DecBy(6, 6);
2678
2679 if(client_offset != NULL)
2680 {
2681 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2682 *client_offset = wxPoint(2, 3);
2683 else
2684 *client_offset = wxPoint(3, 2);
2685 }
2686 if (size.x < 0) size.x = 0;
2687 if (size.y < 0) size.y = 0;
2688
2689 return size;
2690 }
2691
2692 wxSize wxRibbonMSWArtProvider::GetGallerySize(
2693 wxDC& WXUNUSED(dc),
2694 const wxRibbonGallery* WXUNUSED(wnd),
2695 wxSize client_size)
2696 {
2697 client_size.IncBy( 2, 1); // Left / top padding
2698 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2699 client_size.IncBy(1, 16); // Right / bottom padding
2700 else
2701 client_size.IncBy(16, 1); // Right / bottom padding
2702 return client_size;
2703 }
2704
2705 wxSize wxRibbonMSWArtProvider::GetGalleryClientSize(
2706 wxDC& WXUNUSED(dc),
2707 const wxRibbonGallery* WXUNUSED(wnd),
2708 wxSize size,
2709 wxPoint* client_offset,
2710 wxRect* scroll_up_button,
2711 wxRect* scroll_down_button,
2712 wxRect* extension_button)
2713 {
2714 wxRect scroll_up;
2715 wxRect scroll_down;
2716 wxRect extension;
2717 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2718 {
2719 // Flow is vertical - put buttons on bottom
2720 scroll_up.y = size.GetHeight() - 15;
2721 scroll_up.height = 15;
2722 scroll_up.x = 0;
2723 scroll_up.width = (size.GetWidth() + 2) / 3;
2724 scroll_down.y = scroll_up.y;
2725 scroll_down.height = scroll_up.height;
2726 scroll_down.x = scroll_up.x + scroll_up.width;
2727 scroll_down.width = scroll_up.width;
2728 extension.y = scroll_down.y;
2729 extension.height = scroll_down.height;
2730 extension.x = scroll_down.x + scroll_down.width;
2731 extension.width = size.GetWidth() - scroll_up.width - scroll_down.width;
2732 size.DecBy(1, 16);
2733 size.DecBy( 2, 1);
2734 }
2735 else
2736 {
2737 // Flow is horizontal - put buttons on right
2738 scroll_up.x = size.GetWidth() - 15;
2739 scroll_up.width = 15;
2740 scroll_up.y = 0;
2741 scroll_up.height = (size.GetHeight() + 2) / 3;
2742 scroll_down.x = scroll_up.x;
2743 scroll_down.width = scroll_up.width;
2744 scroll_down.y = scroll_up.y + scroll_up.height;
2745 scroll_down.height = scroll_up.height;
2746 extension.x = scroll_down.x;
2747 extension.width = scroll_down.width;
2748 extension.y = scroll_down.y + scroll_down.height;
2749 extension.height = size.GetHeight() - scroll_up.height - scroll_down.height;
2750 size.DecBy(16, 1);
2751 size.DecBy( 2, 1);
2752 }
2753
2754 if(client_offset != NULL)
2755 *client_offset = wxPoint(2, 1);
2756 if(scroll_up_button != NULL)
2757 *scroll_up_button = scroll_up;
2758 if(scroll_down_button != NULL)
2759 *scroll_down_button = scroll_down;
2760 if(extension_button != NULL)
2761 *extension_button = extension;
2762
2763 return size;
2764 }
2765
2766 wxRect wxRibbonMSWArtProvider::GetPageBackgroundRedrawArea(
2767 wxDC& WXUNUSED(dc),
2768 const wxRibbonPage* WXUNUSED(wnd),
2769 wxSize page_old_size,
2770 wxSize page_new_size)
2771 {
2772 wxRect new_rect, old_rect;
2773
2774 if(page_new_size.GetWidth() != page_old_size.GetWidth())
2775 {
2776 if(page_new_size.GetHeight() != page_old_size.GetHeight())
2777 {
2778 // Width and height both changed - redraw everything
2779 return wxRect(page_new_size);
2780 }
2781 else
2782 {
2783 // Only width changed - redraw right hand side
2784 const int right_edge_width = 4;
2785
2786 new_rect = wxRect(page_new_size.GetWidth() - right_edge_width, 0, right_edge_width, page_new_size.GetHeight());
2787 old_rect = wxRect(page_old_size.GetWidth() - right_edge_width, 0, right_edge_width, page_old_size.GetHeight());
2788 }
2789 }
2790 else
2791 {
2792 if(page_new_size.GetHeight() == page_old_size.GetHeight())
2793 {
2794 // Nothing changed (should never happen) - redraw nothing
2795 return wxRect(0, 0, 0, 0);
2796 }
2797 else
2798 {
2799 // Height changed - need to redraw everything (as the background
2800 // gradient is done vertically).
2801 return page_new_size;
2802 }
2803 }
2804
2805 new_rect.Union(old_rect);
2806 new_rect.Intersect(wxRect(page_new_size));
2807 return new_rect;
2808 }
2809
2810 bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
2811 wxDC& dc,
2812 wxWindow* wnd,
2813 wxRibbonButtonKind kind,
2814 wxRibbonButtonBarButtonState size,
2815 const wxString& label,
2816 wxSize bitmap_size_large,
2817 wxSize bitmap_size_small,
2818 wxSize* button_size,
2819 wxRect* normal_region,
2820 wxRect* dropdown_region)
2821 {
2822 const int drop_button_width = 8;
2823
2824 dc.SetFont(m_button_bar_label_font);
2825 switch(size & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2826 {
2827 case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
2828 // Small bitmap, no label
2829 *button_size = bitmap_size_small + wxSize(6, 4);
2830 switch(kind)
2831 {
2832 case wxRIBBON_BUTTON_NORMAL:
2833 case wxRIBBON_BUTTON_TOGGLE:
2834 *normal_region = wxRect(*button_size);
2835 *dropdown_region = wxRect(0, 0, 0, 0);
2836 break;
2837 case wxRIBBON_BUTTON_DROPDOWN:
2838 *button_size += wxSize(drop_button_width, 0);
2839 *dropdown_region = wxRect(*button_size);
2840 *normal_region = wxRect(0, 0, 0, 0);
2841 break;
2842 case wxRIBBON_BUTTON_HYBRID:
2843 *normal_region = wxRect(*button_size);
2844 *dropdown_region = wxRect(button_size->GetWidth(), 0,
2845 drop_button_width, button_size->GetHeight());
2846 *button_size += wxSize(drop_button_width, 0);
2847 break;
2848 }
2849 break;
2850 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2851 // Small bitmap, with label to the right
2852 {
2853 GetButtonBarButtonSize(dc, wnd, kind, wxRIBBON_BUTTONBAR_BUTTON_SMALL,
2854 label, bitmap_size_large, bitmap_size_small, button_size,
2855 normal_region, dropdown_region);
2856 int text_size = dc.GetTextExtent(label).GetWidth();
2857 button_size->SetWidth(button_size->GetWidth() + text_size);
2858 switch(kind)
2859 {
2860 case wxRIBBON_BUTTON_DROPDOWN:
2861 dropdown_region->SetWidth(dropdown_region->GetWidth() + text_size);
2862 break;
2863 case wxRIBBON_BUTTON_HYBRID:
2864 dropdown_region->SetX(dropdown_region->GetX() + text_size);
2865 // no break
2866 case wxRIBBON_BUTTON_NORMAL:
2867 case wxRIBBON_BUTTON_TOGGLE:
2868 normal_region->SetWidth(normal_region->GetWidth() + text_size);
2869 break;
2870 }
2871 break;
2872 }
2873 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2874 // Large bitmap, with label below (possibly split over 2 lines)
2875 {
2876 wxSize icon_size(bitmap_size_large);
2877 icon_size += wxSize(4, 4);
2878 wxCoord label_height;
2879 wxCoord best_width;
2880 dc.GetTextExtent(label, &best_width, &label_height);
2881 int last_line_extra_width = 0;
2882 if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE)
2883 {
2884 last_line_extra_width += 8;
2885 }
2886 size_t i;
2887 for(i = 0; i < label.Len(); ++i)
2888 {
2889 if(wxRibbonCanLabelBreakAtPosition(label, i))
2890 {
2891 int width = wxMax(
2892 dc.GetTextExtent(label.Mid(0, i - 1)).GetWidth(),
2893 dc.GetTextExtent(label.Mid(i + 1)).GetWidth() + last_line_extra_width);
2894 if(width < best_width)
2895 {
2896 best_width = width;
2897 }
2898 }
2899 }
2900 label_height *= 2; // Assume two lines even when only one is used
2901 // (to give all buttons a consistent height)
2902 icon_size.SetWidth(wxMax(icon_size.GetWidth(), best_width) + 6);
2903 icon_size.SetHeight(icon_size.GetHeight() + label_height);
2904 *button_size = icon_size;
2905 switch(kind)
2906 {
2907 case wxRIBBON_BUTTON_DROPDOWN:
2908 *dropdown_region = wxRect(icon_size);
2909 break;
2910 case wxRIBBON_BUTTON_HYBRID:
2911 *normal_region = wxRect(icon_size);
2912 normal_region->height -= 2 + label_height;
2913 dropdown_region->x = 0;
2914 dropdown_region->y = normal_region->height;
2915 dropdown_region->width = icon_size.GetWidth();
2916 dropdown_region->height = icon_size.GetHeight() - normal_region->height;
2917 break;
2918 case wxRIBBON_BUTTON_NORMAL:
2919 case wxRIBBON_BUTTON_TOGGLE:
2920 *normal_region = wxRect(icon_size);
2921 break;
2922 }
2923 break;
2924 }
2925 };
2926 return true;
2927 }
2928
2929 wxSize wxRibbonMSWArtProvider::GetMinimisedPanelMinimumSize(
2930 wxDC& dc,
2931 const wxRibbonPanel* wnd,
2932 wxSize* desired_bitmap_size,
2933 wxDirection* expanded_panel_direction)
2934 {
2935 if(desired_bitmap_size != NULL)
2936 {
2937 *desired_bitmap_size = wxSize(16, 16);
2938 }
2939 if(expanded_panel_direction != NULL)
2940 {
2941 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2942 *expanded_panel_direction = wxEAST;
2943 else
2944 *expanded_panel_direction = wxSOUTH;
2945 }
2946 wxSize base_size(42, 42);
2947
2948 dc.SetFont(m_panel_label_font);
2949 wxSize label_size(dc.GetTextExtent(wnd->GetLabel()));
2950 label_size.IncBy(2, 2); // Allow for differences between this DC and a paint DC
2951 label_size.IncBy(6, 0); // Padding
2952 label_size.y *= 2; // Second line for dropdown button
2953
2954 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2955 {
2956 // Label alongside icon
2957 return wxSize(base_size.x + label_size.x,
2958 wxMax(base_size.y, label_size.y));
2959 }
2960 else
2961 {
2962 // Label beneath icon
2963 return wxSize(wxMax(base_size.x, label_size.x),
2964 base_size.y + label_size.y);
2965 }
2966 }
2967
2968 wxSize wxRibbonMSWArtProvider::GetToolSize(
2969 wxDC& WXUNUSED(dc),
2970 wxWindow* WXUNUSED(wnd),
2971 wxSize bitmap_size,
2972 wxRibbonButtonKind kind,
2973 bool WXUNUSED(is_first),
2974 bool is_last,
2975 wxRect* dropdown_region)
2976 {
2977 wxSize size(bitmap_size);
2978 size.IncBy(7, 6);
2979 if(is_last)
2980 size.IncBy(1, 0);
2981 if(kind & wxRIBBON_BUTTON_DROPDOWN)
2982 {
2983 size.IncBy(8, 0);
2984 if(dropdown_region)
2985 {
2986 if(kind == wxRIBBON_BUTTON_DROPDOWN)
2987 *dropdown_region = size;
2988 else
2989 *dropdown_region = wxRect(size.GetWidth() - 8, 0, 8, size.GetHeight());
2990 }
2991 }
2992 else
2993 {
2994 if(dropdown_region)
2995 *dropdown_region = wxRect(0, 0, 0, 0);
2996 }
2997 return size;
2998 }
2999
3000 wxRect
3001 wxRibbonMSWArtProvider::GetBarToggleButtonArea(wxDC& WXUNUSED(dc),
3002 const wxRibbonBar* WXUNUSED(wnd),
3003 wxRect rect)
3004 {
3005 rect = wxRect(rect.GetWidth()-30, 6, 12, 12);
3006 return rect;
3007 }
3008
3009 #endif // wxUSE_RIBBON