1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sal/config.h>
12 #include <basegfx/range/b2ibox.hxx>
13 #include <unx/gtk/gtkframe.hxx>
14 #include <unx/gtk/gtkdata.hxx>
15 #include <unx/gtk/gtkinst.hxx>
16 #include <unx/gtk/gtkgdi.hxx>
17 #include <vcl/decoview.hxx>
18 #include <vcl/settings.hxx>
19 #include "fontmanager.hxx"
20 #include "gtk3cairotextrender.hxx"
21 #include "cairo_gtk3_cairo.hxx"
23 GtkStyleContext
* GtkSalGraphics::mpButtonStyle
= NULL
;
24 GtkStyleContext
* GtkSalGraphics::mpEntryStyle
= NULL
;
25 GtkStyleContext
* GtkSalGraphics::mpTextViewStyle
= NULL
;
26 GtkStyleContext
* GtkSalGraphics::mpVScrollbarStyle
= NULL
;
27 GtkStyleContext
* GtkSalGraphics::mpHScrollbarStyle
= NULL
;
28 GtkStyleContext
* GtkSalGraphics::mpToolbarStyle
= NULL
;
29 GtkStyleContext
* GtkSalGraphics::mpToolButtonStyle
= NULL
;
30 GtkStyleContext
* GtkSalGraphics::mpToolbarSeperatorStyle
= NULL
;
31 GtkStyleContext
* GtkSalGraphics::mpCheckButtonStyle
= NULL
;
32 GtkStyleContext
* GtkSalGraphics::mpMenuBarStyle
= NULL
;
33 GtkStyleContext
* GtkSalGraphics::mpMenuBarItemStyle
= NULL
;
34 GtkStyleContext
* GtkSalGraphics::mpMenuStyle
= NULL
;
35 GtkStyleContext
* GtkSalGraphics::mpCheckMenuItemStyle
= NULL
;
36 GtkStyleContext
* GtkSalGraphics::mpSpinStyle
= NULL
;
37 GtkStyleContext
* GtkSalGraphics::mpComboboxStyle
= NULL
;
38 GtkStyleContext
* GtkSalGraphics::mpComboboxButtonStyle
= NULL
;
39 GtkStyleContext
* GtkSalGraphics::mpListboxStyle
= NULL
;
40 GtkStyleContext
* GtkSalGraphics::mpListboxButtonStyle
= NULL
;
41 GtkStyleContext
* GtkSalGraphics::mpNoteBookStyle
= NULL
;
42 GtkStyleContext
* GtkSalGraphics::mpFrameInStyle
= NULL
;
43 GtkStyleContext
* GtkSalGraphics::mpFrameOutStyle
= NULL
;
44 GtkStyleContext
* GtkSalGraphics::mpFixedHoriLineStyle
= NULL
;
45 GtkStyleContext
* GtkSalGraphics::mpFixedVertLineStyle
= NULL
;
46 GtkStyleContext
* GtkSalGraphics::mpTreeHeaderButtonStyle
= NULL
;
47 GtkStyleContext
* GtkSalGraphics::mpProgressBarStyle
= NULL
;
49 bool GtkSalGraphics::style_loaded
= false;
50 /************************************************************************
52 ************************************************************************/
53 static void NWConvertVCLStateToGTKState( ControlState nVCLState
,
54 GtkStateFlags
* nGTKState
, GtkShadowType
* nGTKShadow
)
56 *nGTKShadow
= GTK_SHADOW_OUT
;
57 *nGTKState
= GTK_STATE_FLAG_NORMAL
;
59 if (!( nVCLState
& ControlState::ENABLED
))
61 *nGTKState
= GTK_STATE_FLAG_INSENSITIVE
;
64 if ( nVCLState
& ControlState::PRESSED
)
66 *nGTKState
= (GtkStateFlags
) (*nGTKState
| GTK_STATE_FLAG_ACTIVE
);
67 *nGTKShadow
= GTK_SHADOW_IN
;
70 if ( nVCLState
& ControlState::ROLLOVER
)
72 *nGTKState
= (GtkStateFlags
) (*nGTKState
| GTK_STATE_FLAG_PRELIGHT
);
75 if ( nVCLState
& ControlState::SELECTED
)
76 *nGTKState
= (GtkStateFlags
) (*nGTKState
| GTK_STATE_FLAG_SELECTED
);
78 if ( nVCLState
& ControlState::FOCUSED
)
79 *nGTKState
= (GtkStateFlags
) (*nGTKState
| GTK_STATE_FLAG_FOCUSED
);
81 if (AllSettings::GetLayoutRTL())
83 *nGTKState
= (GtkStateFlags
) (*nGTKState
| GTK_STATE_FLAG_DIR_RTL
);
88 RENDER_BACKGROUND_AND_FRAME
= 1,
90 RENDER_BACKGROUND
= 3,
91 RENDER_MENU_SEPERATOR
= 4,
92 RENDER_TOOLBAR_SEPERATOR
= 5,
97 RENDER_SPINBUTTON
= 10,
101 RENDER_PROGRESS
= 14,
105 static void NWCalcArrowRect( const Rectangle
& rButton
, Rectangle
& rArrow
)
107 // Size the arrow appropriately
108 Size
aSize( rButton
.GetWidth()/2, rButton
.GetHeight()/2 );
109 rArrow
.SetSize( aSize
);
111 rArrow
.SetPos( Point(
112 rButton
.Left() + ( rButton
.GetWidth() - rArrow
.GetWidth() ) / 2,
113 rButton
.Top() + ( rButton
.GetHeight() - rArrow
.GetHeight() ) / 2
117 Rectangle
GtkSalGraphics::NWGetSpinButtonRect( ControlPart nPart
, Rectangle aAreaRect
)
119 gtk_style_context_save(mpSpinStyle
);
120 gtk_style_context_add_class(mpSpinStyle
, GTK_STYLE_CLASS_BUTTON
);
123 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU
, &w
, &h
);
124 gint icon_size
= std::max(w
, h
);
126 GtkBorder padding
, border
;
127 gtk_style_context_get_padding(mpSpinStyle
, GTK_STATE_FLAG_NORMAL
, &padding
);
128 gtk_style_context_get_border(mpSpinStyle
, GTK_STATE_FLAG_NORMAL
, &border
);
130 gint buttonWidth
= icon_size
+ padding
.left
+ padding
.right
+
131 border
.left
+ border
.right
;
133 gint buttonHeight
= icon_size
+ padding
.top
+ padding
.bottom
+
134 border
.top
+ border
.bottom
;
136 Rectangle buttonRect
;
137 buttonRect
.SetSize(Size(buttonWidth
, buttonHeight
));
138 buttonRect
.setY(aAreaRect
.Top());
139 buttonRect
.Bottom() = buttonRect
.Top() + aAreaRect
.GetHeight();
140 Rectangle
partRect(buttonRect
);
141 if ( nPart
== PART_BUTTON_UP
)
143 if (AllSettings::GetLayoutRTL())
144 partRect
.setX(aAreaRect
.Left());
146 partRect
.setX(aAreaRect
.Left() + (aAreaRect
.GetWidth() - buttonRect
.GetWidth()));
148 else if( nPart
== PART_BUTTON_DOWN
)
150 if (AllSettings::GetLayoutRTL())
151 partRect
.setX(aAreaRect
.Left() + buttonRect
.GetWidth());
153 partRect
.setX(aAreaRect
.Left() + (aAreaRect
.GetWidth() - 2 * buttonRect
.GetWidth()));
157 if (AllSettings::GetLayoutRTL())
159 partRect
.Right() = aAreaRect
.Left() + aAreaRect
.GetWidth();
160 partRect
.Left() = aAreaRect
.Left() + (2 * buttonRect
.GetWidth()) - 1;
164 partRect
.Right() = (aAreaRect
.Left() + (aAreaRect
.GetWidth() - 2 * buttonRect
.GetWidth())) - 1;
165 partRect
.Left() = aAreaRect
.Left();
167 partRect
.Top() = aAreaRect
.Top();
168 partRect
.Bottom() = aAreaRect
.Bottom();
171 gtk_style_context_restore(mpSpinStyle
);
176 Rectangle
GtkSalGraphics::NWGetScrollButtonRect( ControlPart nPart
, Rectangle aAreaRect
)
178 GtkStyleContext
* pScrollbarStyle
= NULL
;
179 if ((nPart
== PART_BUTTON_LEFT
) || (nPart
== PART_BUTTON_RIGHT
))
180 pScrollbarStyle
= mpHScrollbarStyle
;
181 else // (nPart == PART_BUTTON_UP) || (nPart == PART_BUTTON_DOWN)
182 pScrollbarStyle
= mpVScrollbarStyle
;
186 gint stepper_spacing
;
189 // Grab some button style attributes
190 gtk_style_context_get_style( pScrollbarStyle
,
191 "slider-width", &slider_width
,
192 "stepper-size", &stepper_size
,
193 "trough-border", &trough_border
,
194 "stepper-spacing", &stepper_spacing
, (char *)NULL
);
196 gboolean has_forward
;
197 gboolean has_forward2
;
198 gboolean has_backward
;
199 gboolean has_backward2
;
201 gtk_style_context_get_style( pScrollbarStyle
,
202 "has-forward-stepper", &has_forward
,
203 "has-secondary-forward-stepper", &has_forward2
,
204 "has-backward-stepper", &has_backward
,
205 "has-secondary-backward-stepper", &has_backward2
, (char *)NULL
);
208 Rectangle buttonRect
;
213 if ( has_forward
) nSecond
+= 1;
214 if ( has_forward2
) nFirst
+= 1;
215 if ( has_backward
) nFirst
+= 1;
216 if ( has_backward2
) nSecond
+= 1;
218 if ( ( nPart
== PART_BUTTON_UP
) || ( nPart
== PART_BUTTON_DOWN
) )
220 buttonWidth
= slider_width
+ 2 * trough_border
;
221 buttonHeight
= stepper_size
+ trough_border
+ stepper_spacing
;
225 buttonWidth
= stepper_size
+ trough_border
+ stepper_spacing
;
226 buttonHeight
= slider_width
+ 2 * trough_border
;
229 if ( nPart
== PART_BUTTON_UP
)
231 buttonHeight
*= nFirst
;
233 buttonRect
.setX( aAreaRect
.Left() );
234 buttonRect
.setY( aAreaRect
.Top() );
236 else if ( nPart
== PART_BUTTON_LEFT
)
238 buttonWidth
*= nFirst
;
240 buttonRect
.setX( aAreaRect
.Left() );
241 buttonRect
.setY( aAreaRect
.Top() );
243 else if ( nPart
== PART_BUTTON_DOWN
)
245 buttonHeight
*= nSecond
;
246 buttonRect
.setX( aAreaRect
.Left() );
247 buttonRect
.setY( aAreaRect
.Top() + aAreaRect
.GetHeight() - buttonHeight
);
249 else if ( nPart
== PART_BUTTON_RIGHT
)
251 buttonWidth
*= nSecond
;
252 buttonRect
.setX( aAreaRect
.Left() + aAreaRect
.GetWidth() - buttonWidth
);
253 buttonRect
.setY( aAreaRect
.Top() );
256 buttonRect
.SetSize( Size( buttonWidth
, buttonHeight
) );
261 void GtkSalGraphics::PaintScrollbar(GtkStyleContext
*context
,
263 const Rectangle
& rControlRectangle
,
266 const ImplControlValue
& rValue
)
269 OSL_ASSERT( rValue
.getType() == CTRL_SCROLLBAR
);
270 const ScrollbarValue
& rScrollbarVal
= static_cast<const ScrollbarValue
&>(rValue
);
271 Rectangle scrollbarRect
;
272 GtkStateFlags stateFlags
;
273 GtkShadowType shadowType
;
274 GtkOrientation scrollbarOrientation
;
275 Rectangle thumbRect
= rScrollbarVal
.maThumbRect
;
276 Rectangle button11BoundRect
= rScrollbarVal
.maButton1Rect
; // backward
277 Rectangle button22BoundRect
= rScrollbarVal
.maButton2Rect
; // forward
278 Rectangle button12BoundRect
= rScrollbarVal
.maButton1Rect
; // secondary forward
279 Rectangle button21BoundRect
= rScrollbarVal
.maButton2Rect
; // secondary backward
280 gdouble arrow1Angle
; // backward
281 gdouble arrow2Angle
; // forward
283 const gchar
* button1StyleClass
= NULL
;
284 const gchar
* button2StyleClass
= NULL
;
285 gint slider_width
= 0;
286 gint stepper_size
= 0;
287 gint stepper_spacing
= 0;
288 gint trough_border
= 0;
289 gint min_slider_length
= 0;
291 // make controlvalue rectangles relative to area
292 thumbRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
293 button11BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
294 button22BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
295 button12BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
296 button21BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
298 // Find the overall bounding rect of the control
299 scrollbarRect
= rControlRectangle
;
300 scrollbarRect
.SetSize( Size( scrollbarRect
.GetWidth() + 1,
301 scrollbarRect
.GetHeight() + 1 ) );
303 if ( (scrollbarRect
.GetWidth() <= 1) || (scrollbarRect
.GetHeight() <= 1) )
306 // Grab some button style attributes
307 gtk_style_context_get_style( context
,
308 "slider_width", &slider_width
,
309 "stepper_size", &stepper_size
,
310 "trough_border", &trough_border
,
311 "stepper_spacing", &stepper_spacing
,
312 "min_slider_length", &min_slider_length
, (char *)NULL
);
313 gboolean has_forward
;
314 gboolean has_forward2
;
315 gboolean has_backward
;
316 gboolean has_backward2
;
318 gtk_style_context_get_style( context
,
319 "has-forward-stepper", &has_forward
,
320 "has-secondary-forward-stepper", &has_forward2
,
321 "has-backward-stepper", &has_backward
,
322 "has-secondary-backward-stepper", &has_backward2
, (char *)NULL
);
323 gint magic
= trough_border
? 1 : 0;
325 gint slider_side
= slider_width
+ (trough_border
* 2);
327 if ( has_backward
) nFirst
+= 1;
328 if ( has_forward2
) nFirst
+= 1;
330 if ( nPart
== PART_DRAW_BACKGROUND_HORZ
)
332 scrollbarRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_side
) / 2 );
333 scrollbarRect
.SetSize( Size( scrollbarRect
.GetWidth(), slider_side
) );
335 scrollbarOrientation
= GTK_ORIENTATION_HORIZONTAL
;
336 arrow1Angle
= G_PI
* 3 / 2;
337 arrow2Angle
= G_PI
/ 2;
338 button1StyleClass
= GTK_STYLE_CLASS_LEFT
;
339 button2StyleClass
= GTK_STYLE_CLASS_RIGHT
;
343 button12BoundRect
.Move( stepper_size
- trough_border
,
344 (scrollbarRect
.GetHeight() - slider_width
) / 2 );
347 button11BoundRect
.Move( trough_border
, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
348 button11BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
349 button12BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
353 button22BoundRect
.Move( stepper_size
+(trough_border
+1)/2, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
354 button21BoundRect
.Move( (trough_border
+1)/2, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
358 button22BoundRect
.Move( (trough_border
+1)/2, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
361 button21BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
362 button22BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
364 thumbRect
.Bottom() = thumbRect
.Top() + slider_width
- 1;
365 // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
366 // but if the VCL gives us a size smaller than the theme's default thumb size,
367 // honor the VCL size
368 thumbRect
.Right() += magic
;
369 // Center vertically in the track
370 thumbRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
374 scrollbarRect
.Move( (scrollbarRect
.GetWidth() - slider_side
) / 2, 0 );
375 scrollbarRect
.SetSize( Size( slider_side
, scrollbarRect
.GetHeight() ) );
377 scrollbarOrientation
= GTK_ORIENTATION_VERTICAL
;
380 button1StyleClass
= GTK_STYLE_CLASS_TOP
;
381 button2StyleClass
= GTK_STYLE_CLASS_BOTTOM
;
385 button12BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2,
386 stepper_size
+ trough_border
);
388 button11BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, trough_border
);
389 button11BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
390 button12BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
394 button22BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, stepper_size
+(trough_border
+1)/2 );
395 button21BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, (trough_border
+1)/2 );
399 button22BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, (trough_border
+1)/2 );
402 button21BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
403 button22BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
405 thumbRect
.Right() = thumbRect
.Left() + slider_width
- 1;
407 thumbRect
.Bottom() += magic
;
408 // Center horizontally in the track
409 thumbRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, 0 );
412 bool has_slider
= ( thumbRect
.GetWidth() > 0 && thumbRect
.GetHeight() > 0 );
414 // ----------------- TROUGH
415 gtk_style_context_save(context
);
416 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_TROUGH
);
417 gtk_render_background(context
, cr
, 0, 0,
418 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
419 gtk_render_frame(context
, cr
, 0, 0,
420 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
422 gtk_style_context_restore(context
);
424 // ----------------- THUMB
427 NWConvertVCLStateToGTKState( rScrollbarVal
.mnThumbState
, &stateFlags
, &shadowType
);
428 if ( rScrollbarVal
.mnThumbState
& ControlState::PRESSED
)
429 stateFlags
= (GtkStateFlags
) (stateFlags
| GTK_STATE_PRELIGHT
);
431 gtk_style_context_save(context
);
432 gtk_style_context_set_state(context
, stateFlags
);
433 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_SLIDER
);
436 gtk_style_context_get_margin(context
, stateFlags
, &margin
);
439 gtk_render_slider(context
, cr
,
440 thumbRect
.Left() + margin
.left
, thumbRect
.Top() + margin
.top
,
441 thumbRect
.GetWidth() - margin
.left
- margin
.right
,
442 thumbRect
.GetHeight() - margin
.top
- margin
.bottom
,
443 scrollbarOrientation
);
445 gtk_style_context_restore(context
);
448 bool backwardButtonInsensitive
=
449 rScrollbarVal
.mnCur
== rScrollbarVal
.mnMin
;
450 bool forwardButtonInsensitive
= rScrollbarVal
.mnMax
== 0 ||
451 rScrollbarVal
.mnCur
+ rScrollbarVal
.mnVisibleSize
>= rScrollbarVal
.mnMax
;
453 // ----------------- BUTTON 1
456 NWConvertVCLStateToGTKState( rScrollbarVal
.mnButton1State
, &stateFlags
, &shadowType
);
457 if ( backwardButtonInsensitive
)
458 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
460 gtk_style_context_save(context
);
461 gtk_style_context_set_state(context
, stateFlags
);
462 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_BUTTON
);
463 gtk_style_context_add_class(context
, button1StyleClass
);
465 gtk_render_background(context
, cr
,
466 button11BoundRect
.Left(), button11BoundRect
.Top(),
467 button11BoundRect
.GetWidth(), button11BoundRect
.GetHeight() );
468 gtk_render_frame(context
, cr
,
469 button11BoundRect
.Left(), button11BoundRect
.Top(),
470 button11BoundRect
.GetWidth(), button11BoundRect
.GetHeight() );
472 // ----------------- ARROW 1
473 NWCalcArrowRect( button11BoundRect
, arrowRect
);
474 gtk_render_arrow(context
, cr
,
476 arrowRect
.Left(), arrowRect
.Top(),
477 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
479 gtk_style_context_restore(context
);
483 NWConvertVCLStateToGTKState( rScrollbarVal
.mnButton2State
, &stateFlags
, &shadowType
);
484 if ( forwardButtonInsensitive
)
485 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
487 gtk_style_context_save(context
);
488 gtk_style_context_set_state(context
, stateFlags
);
489 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_BUTTON
);
490 gtk_style_context_add_class(context
, button1StyleClass
);
492 gtk_render_background(context
, cr
,
493 button12BoundRect
.Left(), button12BoundRect
.Top(),
494 button12BoundRect
.GetWidth(), button12BoundRect
.GetHeight() );
495 gtk_render_frame(context
, cr
,
496 button12BoundRect
.Left(), button12BoundRect
.Top(),
497 button12BoundRect
.GetWidth(), button12BoundRect
.GetHeight() );
499 // ----------------- ARROW 1
500 NWCalcArrowRect( button12BoundRect
, arrowRect
);
501 gtk_render_arrow(context
, cr
,
503 arrowRect
.Left(), arrowRect
.Top(),
504 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
506 gtk_style_context_restore(context
);
508 // ----------------- BUTTON 2
511 NWConvertVCLStateToGTKState( rScrollbarVal
.mnButton1State
, &stateFlags
, &shadowType
);
512 if ( backwardButtonInsensitive
)
513 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
515 gtk_style_context_save(context
);
516 gtk_style_context_set_state(context
, stateFlags
);
517 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_BUTTON
);
518 gtk_style_context_add_class(context
, button2StyleClass
);
520 gtk_render_background(context
, cr
,
521 button21BoundRect
.Left(), button21BoundRect
.Top(),
522 button21BoundRect
.GetWidth(), button21BoundRect
.GetHeight() );
523 gtk_render_frame(context
, cr
,
524 button21BoundRect
.Left(), button21BoundRect
.Top(),
525 button21BoundRect
.GetWidth(), button21BoundRect
.GetHeight() );
527 // ----------------- ARROW 2
528 NWCalcArrowRect( button21BoundRect
, arrowRect
);
529 gtk_render_arrow(context
, cr
,
531 arrowRect
.Left(), arrowRect
.Top(),
532 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
534 gtk_style_context_restore(context
);
538 NWConvertVCLStateToGTKState( rScrollbarVal
.mnButton2State
, &stateFlags
, &shadowType
);
539 if ( forwardButtonInsensitive
)
540 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
542 gtk_style_context_save(context
);
543 gtk_style_context_set_state(context
, stateFlags
);
544 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_BUTTON
);
545 gtk_style_context_add_class(context
, button2StyleClass
);
547 gtk_render_background(context
, cr
,
548 button22BoundRect
.Left(), button22BoundRect
.Top(),
549 button22BoundRect
.GetWidth(), button22BoundRect
.GetHeight() );
550 gtk_render_frame(context
, cr
,
551 button22BoundRect
.Left(), button22BoundRect
.Top(),
552 button22BoundRect
.GetWidth(), button22BoundRect
.GetHeight() );
554 // ----------------- ARROW 2
555 NWCalcArrowRect( button22BoundRect
, arrowRect
);
556 gtk_render_arrow(context
, cr
,
558 arrowRect
.Left(), arrowRect
.Top(),
559 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
561 gtk_style_context_restore(context
);
565 void GtkSalGraphics::PaintOneSpinButton( GtkStyleContext
*context
,
570 ControlState nState
)
573 Rectangle buttonRect
;
574 GtkStateFlags stateFlags
;
575 GtkShadowType shadowType
;
576 GtkBorder padding
, border
;
578 NWConvertVCLStateToGTKState( nState
, &stateFlags
, &shadowType
);
579 buttonRect
= NWGetSpinButtonRect( nPart
, aAreaRect
);
581 gtk_style_context_save(context
);
582 gtk_style_context_set_state(context
, stateFlags
);
583 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_BUTTON
);
585 gtk_style_context_get_padding(context
, GTK_STATE_FLAG_NORMAL
, &padding
);
586 gtk_style_context_get_border(context
, GTK_STATE_FLAG_NORMAL
, &border
);
588 gtk_render_background(context
, cr
,
589 buttonRect
.Left(), buttonRect
.Top(),
590 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
591 gtk_render_frame(context
, cr
,
592 buttonRect
.Left(), buttonRect
.Top(),
593 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
595 gint iconWidth
= (buttonRect
.GetWidth() - padding
.left
- padding
.right
- border
.left
- border
.right
);
596 gint iconHeight
= (buttonRect
.GetHeight() - padding
.top
- padding
.bottom
- border
.top
- border
.bottom
);
598 const char* icon
= (nPart
== PART_BUTTON_UP
) ? "list-add-symbolic" : "list-remove-symbolic";
599 GtkIconTheme
*pIconTheme
= gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow
));
601 GtkIconInfo
*info
= gtk_icon_theme_lookup_icon(pIconTheme
, icon
, std::min(iconWidth
, iconHeight
),
602 static_cast<GtkIconLookupFlags
>(0));
604 GdkPixbuf
*pixbuf
= gtk_icon_info_load_symbolic_for_context
609 iconWidth
= gdk_pixbuf_get_width(pixbuf
);
610 iconHeight
= gdk_pixbuf_get_height(pixbuf
);
612 arrowRect
.SetSize(Size(iconWidth
, iconHeight
));
613 arrowRect
.setX( buttonRect
.Left() + (buttonRect
.GetWidth() - arrowRect
.GetWidth()) / 2 );
614 arrowRect
.setY( buttonRect
.Top() + (buttonRect
.GetHeight() - arrowRect
.GetHeight()) / 2 );
616 gtk_render_icon(context
, cr
, pixbuf
, arrowRect
.Left(), arrowRect
.Top());
617 g_object_unref(pixbuf
);
618 gtk_icon_info_free(info
);
620 gtk_style_context_restore(context
);
623 void GtkSalGraphics::PaintSpinButton(GtkStyleContext
*context
,
625 const Rectangle
& rControlRectangle
,
627 ControlPart
/*nPart*/,
628 const ImplControlValue
& rValue
)
631 const SpinbuttonValue
*pSpinVal
= (rValue
.getType() == CTRL_SPINBUTTONS
) ? static_cast<const SpinbuttonValue
*>(&rValue
) : NULL
;
632 ControlPart upBtnPart
= PART_BUTTON_UP
;
633 ControlState upBtnState
= ControlState::NONE
;
634 ControlPart downBtnPart
= PART_BUTTON_DOWN
;
635 ControlState downBtnState
= ControlState::NONE
;
639 upBtnPart
= pSpinVal
->mnUpperPart
;
640 upBtnState
= pSpinVal
->mnUpperState
;
642 downBtnPart
= pSpinVal
->mnLowerPart
;
643 downBtnState
= pSpinVal
->mnLowerState
;
646 areaRect
= rControlRectangle
;
648 gtk_render_background(context
, cr
,
650 areaRect
.GetWidth(), areaRect
.GetHeight() );
651 gtk_render_frame(context
, cr
,
653 areaRect
.GetWidth(), areaRect
.GetHeight() );
655 // CTRL_SPINBUTTONS pass their area in pSpinVal, not in rControlRectangle
658 areaRect
= pSpinVal
->maUpperRect
;
659 areaRect
.Union( pSpinVal
->maLowerRect
);
662 PaintOneSpinButton(context
, cr
, nType
, upBtnPart
, areaRect
, upBtnState
);
663 PaintOneSpinButton(context
, cr
, nType
, downBtnPart
, areaRect
, downBtnState
);
666 #define ARROW_SIZE 11 * 0.85
667 Rectangle
GtkSalGraphics::NWGetComboBoxButtonRect( ControlType nType
,
669 Rectangle aAreaRect
)
673 Rectangle aButtonRect
;
678 gtk_style_context_get_padding( mpButtonStyle
, GTK_STATE_FLAG_NORMAL
, &padding
);
680 nArrowWidth
= ARROW_SIZE
;
681 nButtonWidth
= nArrowWidth
+ padding
.left
+ padding
.right
;
682 if( nPart
== PART_BUTTON_DOWN
)
684 Point aPos
= Point(aAreaRect
.Left() + aAreaRect
.GetWidth() - nButtonWidth
, aAreaRect
.Top());
685 if (AllSettings::GetLayoutRTL())
686 aPos
.X() = aAreaRect
.Left();
687 aButtonRect
.SetSize( Size( nButtonWidth
, aAreaRect
.GetHeight() ) );
688 aButtonRect
.SetPos(aPos
);
690 else if( nPart
== PART_SUB_EDIT
)
692 gint adjust_left
= padding
.left
;
693 gint adjust_top
= padding
.top
;
694 gint adjust_right
= padding
.right
;
695 gint adjust_bottom
= padding
.bottom
;
697 aButtonRect
.SetSize( Size( aAreaRect
.GetWidth() - nButtonWidth
- (adjust_left
+ adjust_right
),
698 aAreaRect
.GetHeight() - (adjust_top
+ adjust_bottom
)) );
699 Point aEditPos
= aAreaRect
.TopLeft();
700 if (AllSettings::GetLayoutRTL())
701 aEditPos
.X() += nButtonWidth
;
703 aEditPos
.X() += adjust_left
;
704 aEditPos
.Y() += adjust_top
;
705 aButtonRect
.SetPos( aEditPos
);
711 void GtkSalGraphics::PaintCombobox( GtkStateFlags flags
, cairo_t
*cr
,
712 const Rectangle
& rControlRectangle
,
715 const ImplControlValue
& /*rValue*/ )
718 Rectangle buttonRect
;
721 // Find the overall bounding rect of the buttons's drawing area,
722 // plus its actual draw rect excluding adornment
723 areaRect
= rControlRectangle
;
725 buttonRect
= NWGetComboBoxButtonRect( nType
, PART_BUTTON_DOWN
, areaRect
);
726 if( nPart
== PART_BUTTON_DOWN
)
727 buttonRect
.Left() += 1;
729 Rectangle
aEditBoxRect( areaRect
);
730 aEditBoxRect
.SetSize( Size( areaRect
.GetWidth() - buttonRect
.GetWidth(), aEditBoxRect
.GetHeight() ) );
731 if (AllSettings::GetLayoutRTL())
732 aEditBoxRect
.SetPos( Point( areaRect
.Left() + buttonRect
.GetWidth(), areaRect
.Top() ) );
734 arrowRect
.SetSize( Size( (gint
)(ARROW_SIZE
),
735 (gint
)(ARROW_SIZE
) ) );
736 arrowRect
.SetPos( Point( buttonRect
.Left() + (gint
)((buttonRect
.GetWidth() - arrowRect
.GetWidth()) / 2),
737 buttonRect
.Top() + (gint
)((buttonRect
.GetHeight() - arrowRect
.GetHeight()) / 2) ) );
740 if ( nType
== CTRL_COMBOBOX
)
742 gtk_style_context_save(mpComboboxButtonStyle
);
743 gtk_style_context_set_state(mpComboboxButtonStyle
, flags
);
745 if( nPart
== PART_ENTIRE_CONTROL
)
747 gtk_style_context_save(mpEntryStyle
);
748 gtk_style_context_set_state(mpEntryStyle
, flags
);
749 if (AllSettings::GetLayoutRTL())
750 gtk_style_context_set_junction_sides(mpEntryStyle
, GTK_JUNCTION_LEFT
);
752 gtk_style_context_set_junction_sides(mpEntryStyle
, GTK_JUNCTION_RIGHT
);
754 gtk_render_background(mpComboboxStyle
, cr
,
756 areaRect
.GetWidth(), areaRect
.GetHeight());
757 gtk_render_frame(mpComboboxStyle
, cr
,
759 areaRect
.GetWidth(), areaRect
.GetHeight());
760 gtk_render_background(mpEntryStyle
, cr
,
761 (aEditBoxRect
.Left() - areaRect
.Left()),
762 (aEditBoxRect
.Top() - areaRect
.Top()),
763 aEditBoxRect
.GetWidth(), aEditBoxRect
.GetHeight() );
764 gtk_render_frame(mpEntryStyle
, cr
,
765 (aEditBoxRect
.Left() - areaRect
.Left()),
766 (aEditBoxRect
.Top() - areaRect
.Top()),
767 aEditBoxRect
.GetWidth(), aEditBoxRect
.GetHeight() );
769 gtk_style_context_restore(mpEntryStyle
);
772 gtk_render_background(mpComboboxButtonStyle
, cr
,
773 (buttonRect
.Left() - areaRect
.Left()),
774 (buttonRect
.Top() - areaRect
.Top()),
775 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
776 gtk_render_frame(mpComboboxButtonStyle
, cr
,
777 (buttonRect
.Left() - areaRect
.Left()),
778 (buttonRect
.Top() - areaRect
.Top()),
779 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
781 gtk_render_arrow(mpComboboxStyle
, cr
,
783 (arrowRect
.Left() - areaRect
.Left()), (arrowRect
.Top() - areaRect
.Top()),
784 arrowRect
.GetWidth() );
786 gtk_style_context_restore(mpComboboxButtonStyle
);
788 else if (nType
== CTRL_LISTBOX
)
790 if( nPart
== PART_WINDOW
)
792 /* render the popup window with the menu style */
793 gtk_render_frame(mpMenuStyle
, cr
,
795 areaRect
.GetWidth(), areaRect
.GetHeight());
799 gtk_style_context_save(mpListboxButtonStyle
);
800 gtk_style_context_set_state(mpListboxButtonStyle
, flags
);
802 gtk_render_background(mpListboxStyle
, cr
,
804 areaRect
.GetWidth(), areaRect
.GetHeight());
805 gtk_render_frame(mpListboxStyle
, cr
,
807 areaRect
.GetWidth(), areaRect
.GetHeight());
809 gtk_render_background(mpListboxButtonStyle
, cr
,
811 areaRect
.GetWidth(), areaRect
.GetHeight());
812 gtk_render_frame(mpListboxButtonStyle
, cr
,
814 areaRect
.GetWidth(), areaRect
.GetHeight());
816 gtk_render_arrow(mpListboxStyle
, cr
,
818 (arrowRect
.Left() - areaRect
.Left()), (arrowRect
.Top() - areaRect
.Top()),
819 arrowRect
.GetWidth() );
821 gtk_style_context_restore(mpListboxButtonStyle
);
826 void GtkSalGraphics::PaintCheckOrRadio(GtkStyleContext
*context
,
828 const Rectangle
& rControlRectangle
,
832 gtk_style_context_get_style(mpCheckButtonStyle
,
833 "indicator-size", &indicator_size
,
836 gint x
= (rControlRectangle
.GetWidth() - indicator_size
) / 2;
837 gint y
= (rControlRectangle
.GetHeight() - indicator_size
) / 2;
839 if (nType
== CTRL_CHECKBOX
)
840 gtk_render_check(context
, cr
, x
, y
, indicator_size
, indicator_size
);
841 else if (nType
== CTRL_RADIOBUTTON
)
842 gtk_render_option(context
, cr
, x
, y
, indicator_size
, indicator_size
);
845 #if GTK_CHECK_VERSION(3,14,0)
846 # define CHECKED GTK_STATE_FLAG_CHECKED
848 # define CHECKED GTK_STATE_FLAG_ACTIVE
851 static GtkWidget
* gCacheWindow
;
852 static GtkWidget
* gDumbContainer
;
853 static GtkWidget
* gSpinBox
;
854 static GtkWidget
* gEntryBox
;
855 static GtkWidget
* gComboBox
;
856 static GtkWidget
* gComboBoxButtonWidget
;
857 static GtkWidget
* gComboBoxEntryWidget
;
858 static GtkWidget
* gListBox
;
859 static GtkWidget
* gListBoxButtonWidget
;
860 static GtkWidget
* gFrameIn
;
861 static GtkWidget
* gFrameOut
;
862 static GtkWidget
* gMenuBarWidget
;
863 static GtkWidget
* gMenuItemMenuBarWidget
;
864 static GtkWidget
* gCheckMenuItemWidget
;
865 static GtkWidget
* gTreeViewWidget
;
867 bool GtkSalGraphics::drawNativeControl( ControlType nType
, ControlPart nPart
, const Rectangle
& rControlRegion
,
868 ControlState nState
, const ImplControlValue
& rValue
,
872 GtkShadowType shadow
;
873 gint renderType
= nPart
== PART_FOCUS
? RENDER_FOCUS
: RENDER_BACKGROUND_AND_FRAME
;
874 GtkStyleContext
*context
= NULL
;
875 const gchar
*styleClass
= NULL
;
876 GdkPixbuf
*pixbuf
= NULL
;
878 NWConvertVCLStateToGTKState(nState
, &flags
, &shadow
);
883 case CTRL_SPINBUTTONS
:
884 context
= mpSpinStyle
;
885 renderType
= RENDER_SPINBUTTON
;
888 context
= mpEntryStyle
;
890 case CTRL_MULTILINE_EDITBOX
:
891 context
= mpTextViewStyle
;
894 context
= mpComboboxStyle
;
895 renderType
= RENDER_COMBOBOX
;
898 context
= mpListboxStyle
;
899 renderType
= nPart
== PART_FOCUS
? RENDER_FOCUS
: RENDER_COMBOBOX
;
901 case CTRL_MENU_POPUP
:
903 // map selected menu entries in vcl parlance to gtk prelight
904 if (nPart
>= PART_MENU_ITEM
&& nPart
<= PART_MENU_SUBMENU_ARROW
&& (nState
& ControlState::SELECTED
))
905 flags
= (GtkStateFlags
) (flags
| GTK_STATE_FLAG_PRELIGHT
);
910 styleClass
= GTK_STYLE_CLASS_MENUITEM
;
911 context
= mpCheckMenuItemStyle
;
912 renderType
= RENDER_BACKGROUND_AND_FRAME
;
914 case PART_MENU_ITEM_CHECK_MARK
:
915 styleClass
= GTK_STYLE_CLASS_CHECK
;
916 context
= mpCheckMenuItemStyle
;
917 renderType
= RENDER_CHECK
;
918 nType
= CTRL_CHECKBOX
;
919 if (nState
& ControlState::PRESSED
)
920 flags
= (GtkStateFlags
)(flags
| CHECKED
);
922 case PART_MENU_ITEM_RADIO_MARK
:
923 styleClass
= GTK_STYLE_CLASS_RADIO
;
924 context
= mpCheckMenuItemStyle
;
925 renderType
= RENDER_RADIO
;
926 nType
= CTRL_RADIOBUTTON
;
927 if (nState
& ControlState::PRESSED
)
928 flags
= (GtkStateFlags
)(flags
| CHECKED
);
930 case PART_MENU_SEPARATOR
:
931 styleClass
= GTK_STYLE_CLASS_SEPARATOR
;
932 context
= mpCheckMenuItemStyle
;
933 renderType
= RENDER_MENU_SEPERATOR
;
935 case PART_MENU_SUBMENU_ARROW
:
936 styleClass
= GTK_STYLE_CLASS_ARROW
;
937 context
= mpCheckMenuItemStyle
;
938 renderType
= RENDER_ARROW
;
940 case PART_ENTIRE_CONTROL
:
941 context
= mpMenuStyle
;
942 renderType
= RENDER_BACKGROUND
;
949 case PART_DRAW_BACKGROUND_HORZ
:
950 context
= mpToolbarStyle
;
953 /* For all checkbuttons in the toolbars */
954 flags
= (GtkStateFlags
)(flags
|
955 ( (rValue
.getTristateVal() == BUTTONVALUE_ON
) ? GTK_STATE_FLAG_ACTIVE
: GTK_STATE_FLAG_NORMAL
));
956 context
= mpToolButtonStyle
;
958 case PART_SEPARATOR_VERT
:
959 context
= mpToolbarSeperatorStyle
;
960 renderType
= RENDER_TOOLBAR_SEPERATOR
;
967 flags
= (GtkStateFlags
)(flags
|
968 ( (rValue
.getTristateVal() == BUTTONVALUE_ON
) ? CHECKED
:
969 (rValue
.getTristateVal() == BUTTONVALUE_MIXED
) ? GTK_STATE_FLAG_INCONSISTENT
:
970 GTK_STATE_FLAG_NORMAL
));
971 context
= mpCheckButtonStyle
;
972 styleClass
= GTK_STYLE_CLASS_CHECK
;
973 renderType
= nPart
== PART_FOCUS
? RENDER_FOCUS
: RENDER_CHECK
;
975 case CTRL_RADIOBUTTON
:
976 flags
= (GtkStateFlags
)(flags
|
977 ( (rValue
.getTristateVal() == BUTTONVALUE_ON
) ? CHECKED
: GTK_STATE_FLAG_NORMAL
));
978 context
= mpCheckButtonStyle
;
979 styleClass
= GTK_STYLE_CLASS_RADIO
;
980 renderType
= nPart
== PART_FOCUS
? RENDER_FOCUS
: RENDER_RADIO
;
982 case CTRL_PUSHBUTTON
:
983 context
= mpButtonStyle
;
988 case PART_DRAW_BACKGROUND_VERT
:
989 case PART_DRAW_BACKGROUND_HORZ
:
990 context
= (nPart
== PART_DRAW_BACKGROUND_VERT
)
991 ? mpVScrollbarStyle
: mpHScrollbarStyle
;
992 renderType
= RENDER_SCROLLBAR
;
1001 context
= mpNoteBookStyle
;
1003 case CTRL_TAB_HEADER
:
1004 context
= mpNoteBookStyle
;
1005 styleClass
= GTK_STYLE_CLASS_HEADER
;
1008 context
= mpNoteBookStyle
;
1009 if (nState
& ControlState::SELECTED
)
1010 flags
= (GtkStateFlags
) (flags
| GTK_STATE_FLAG_ACTIVE
);
1013 case CTRL_WINDOW_BACKGROUND
:
1014 context
= gtk_widget_get_style_context(mpWindow
);
1018 DrawFrameStyle nStyle
= static_cast<DrawFrameStyle
>(rValue
.getNumericVal() & 0x0f);
1019 if (nStyle
== DrawFrameStyle::In
)
1020 context
= mpFrameOutStyle
;
1022 context
= mpFrameInStyle
;
1026 if (nPart
== PART_MENU_ITEM
)
1028 context
= mpMenuBarItemStyle
;
1029 styleClass
= GTK_STYLE_CLASS_MENUBAR
;
1031 flags
= (!(nState
& ControlState::ENABLED
)) ? GTK_STATE_FLAG_INSENSITIVE
: GTK_STATE_FLAG_NORMAL
;
1032 if (nState
& ControlState::SELECTED
)
1033 flags
= (GtkStateFlags
) (flags
| GTK_STATE_FLAG_PRELIGHT
);
1037 context
= gtk_widget_get_style_context(gMenuBarWidget
);
1038 styleClass
= GTK_STYLE_CLASS_BACKGROUND
;
1041 case CTRL_FIXEDLINE
:
1042 context
= nPart
== PART_SEPARATOR_HORZ
? mpFixedHoriLineStyle
: mpFixedVertLineStyle
;
1043 renderType
= RENDER_SEPERATOR
;
1047 context
= mpTreeHeaderButtonStyle
;
1048 ButtonValue aButtonValue
= rValue
.getTristateVal();
1049 if (aButtonValue
== BUTTONVALUE_ON
)
1050 flags
= (GtkStateFlags
) (flags
| CHECKED
);
1051 renderType
= RENDER_EXPANDER
;
1052 styleClass
= GTK_STYLE_CLASS_EXPANDER
;
1055 case CTRL_LISTHEADER
:
1056 context
= mpTreeHeaderButtonStyle
;
1057 if (nPart
== PART_ARROW
)
1059 const char* icon
= (rValue
.getNumericVal() & 1) ? "pan-down-symbolic" : "pan-up-symbolic";
1060 GtkIconTheme
*pIconTheme
= gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow
));
1061 pixbuf
= gtk_icon_theme_load_icon(pIconTheme
, icon
,
1062 std::max(rControlRegion
.GetWidth(), rControlRegion
.GetHeight()),
1063 static_cast<GtkIconLookupFlags
>(0), NULL
);
1064 flags
= GTK_STATE_FLAG_SELECTED
;
1065 renderType
= RENDER_ICON
;
1066 styleClass
= GTK_STYLE_CLASS_ARROW
;
1070 context
= mpProgressBarStyle
;
1071 renderType
= RENDER_PROGRESS
;
1072 styleClass
= GTK_STYLE_CLASS_TROUGH
;
1078 cairo_t
*cr
= getCairoContext();
1080 cairo_translate(cr
, rControlRegion
.Left(), rControlRegion
.Top());
1084 long nWidth
= rControlRegion
.GetWidth();
1085 long nHeight
= rControlRegion
.GetHeight();
1087 gtk_style_context_save(context
);
1088 gtk_style_context_set_state(context
, flags
);
1089 if (nType
== CTRL_TAB_ITEM
)
1092 const TabitemValue
& rTabitemValue
= static_cast<const TabitemValue
&>(rValue
);
1094 GtkRegionFlags
eFlags(GTK_REGION_EVEN
);
1095 if (rTabitemValue
.isFirst() && rTabitemValue
.isLast())
1096 eFlags
= GTK_REGION_ONLY
;
1097 else if (rTabitemValue
.isFirst())
1098 eFlags
= GTK_REGION_FIRST
;
1099 else if (rTabitemValue
.isLast())
1100 eFlags
= GTK_REGION_LAST
;
1102 gtk_style_context_add_region(mpNoteBookStyle
, GTK_STYLE_REGION_TAB
, eFlags
);
1103 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_TOP
);
1105 gint
initial_gap(0);
1106 gtk_style_context_get_style(mpNoteBookStyle
,
1107 "initial-gap", &initial_gap
,
1110 nX
+= initial_gap
/2;
1111 nWidth
-= initial_gap
;
1115 gtk_style_context_add_class(context
, styleClass
);
1117 if (nType
== CTRL_TAB_HEADER
|| nType
== CTRL_TAB_PANE
)
1119 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_FRAME
);
1124 case RENDER_BACKGROUND
:
1125 case RENDER_BACKGROUND_AND_FRAME
:
1126 gtk_render_background(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1127 if (renderType
== RENDER_BACKGROUND_AND_FRAME
)
1129 gtk_render_frame(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1134 PaintCheckOrRadio(context
, cr
, rControlRegion
, nType
);
1136 case RENDER_MENU_SEPERATOR
:
1137 gtk_render_line(context
, cr
,
1138 3, rControlRegion
.GetHeight() / 2,
1139 rControlRegion
.GetWidth() - 3, rControlRegion
.GetHeight() / 2);
1141 case RENDER_TOOLBAR_SEPERATOR
:
1142 gtk_render_line(context
, cr
,
1143 rControlRegion
.GetWidth() / 2, rControlRegion
.GetHeight() * 0.2,
1144 rControlRegion
.GetWidth() / 2, rControlRegion
.GetHeight() * 0.8 );
1146 case RENDER_SEPERATOR
:
1147 if (nPart
== PART_SEPARATOR_HORZ
)
1148 gtk_render_line(context
, cr
, 0, nHeight
/ 2, nWidth
- 1, nHeight
/ 2);
1150 gtk_render_line(context
, cr
, nWidth
/ 2, 0, nWidth
/ 2, nHeight
- 1);
1153 gtk_render_arrow(context
, cr
,
1155 MIN(rControlRegion
.GetWidth(), 1 + rControlRegion
.GetHeight()));
1157 case RENDER_EXPANDER
:
1158 gtk_render_expander(context
, cr
, -2, -2, nWidth
+4, nHeight
+4);
1160 case RENDER_SCROLLBAR
:
1161 PaintScrollbar(context
, cr
, rControlRegion
, nType
, nPart
, rValue
);
1163 case RENDER_SPINBUTTON
:
1164 PaintSpinButton(context
, cr
, rControlRegion
, nType
, nPart
, rValue
);
1166 case RENDER_COMBOBOX
:
1167 PaintCombobox(flags
, cr
, rControlRegion
, nType
, nPart
, rValue
);
1170 gtk_render_icon(context
, cr
, pixbuf
, nX
, nY
);
1171 g_object_unref(pixbuf
);
1175 if (nType
!= CTRL_CHECKBOX
)
1179 gtk_style_context_get_border(context
, flags
, &border
);
1183 nWidth
-= border
.left
+ border
.right
;
1184 nHeight
-= border
.top
+ border
.bottom
;
1187 gtk_render_focus(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1191 case RENDER_PROGRESS
:
1193 gtk_render_background(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1194 gtk_render_frame(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1195 long nProgressWidth
= rValue
.getNumericVal();
1199 gtk_style_context_get_padding(context
, GTK_STATE_FLAG_NORMAL
, &padding
);
1201 gtk_style_context_remove_class(context
, GTK_STYLE_CLASS_TROUGH
);
1202 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_PROGRESSBAR
);
1203 gtk_style_context_add_class(context
, GTK_STYLE_CLASS_PULSE
);
1206 nHeight
-= (padding
.top
+ padding
.bottom
);
1207 nProgressWidth
-= (padding
.left
+ padding
.right
);
1208 gtk_render_background(context
, cr
, nX
, nY
, nProgressWidth
, nHeight
);
1209 gtk_render_frame(context
, cr
, nX
, nY
, nProgressWidth
, nHeight
);
1218 gtk_style_context_restore(context
);
1219 cairo_surface_flush(cairo_get_target(cr
));
1220 cairo_destroy(cr
); // unref
1221 mpFrame
->damaged(basegfx::B2IBox(rControlRegion
.Left(), rControlRegion
.Top(), rControlRegion
.Right(), rControlRegion
.Bottom()));
1226 Rectangle
GetWidgetSize(const Rectangle
& rControlRegion
, GtkWidget
* widget
)
1228 GtkRequisition aReq
;
1229 gtk_widget_get_preferred_size(widget
, NULL
, &aReq
);
1230 long nHeight
= (rControlRegion
.GetHeight() > aReq
.height
) ? rControlRegion
.GetHeight() : aReq
.height
;
1231 return Rectangle(rControlRegion
.TopLeft(), Size(rControlRegion
.GetWidth(), nHeight
));
1234 Rectangle
AdjustRectForTextBordersPadding(GtkStyleContext
* pStyle
, long nContentWidth
, long nContentHeight
, const Rectangle
& rControlRegion
)
1236 gtk_style_context_save(pStyle
);
1239 gtk_style_context_get_border(pStyle
, GTK_STATE_FLAG_NORMAL
, &border
);
1242 gtk_style_context_get_padding(pStyle
, GTK_STATE_FLAG_NORMAL
, &padding
);
1244 gint nWidgetHeight
= nContentHeight
+ padding
.top
+ padding
.bottom
+ border
.top
+ border
.bottom
;
1245 nWidgetHeight
= std::max
<gint
>(nWidgetHeight
, rControlRegion
.GetHeight());
1247 gint nWidgetWidth
= nContentWidth
+ padding
.left
+ padding
.right
+ border
.left
+ border
.right
;
1248 nWidgetWidth
= std::max
<gint
>(nWidgetWidth
, rControlRegion
.GetWidth());
1250 Rectangle
aEditRect(rControlRegion
.TopLeft(), Size(nWidgetWidth
, nWidgetHeight
));
1252 gtk_style_context_restore(pStyle
);
1257 bool GtkSalGraphics::getNativeControlRegion( ControlType nType
, ControlPart nPart
, const Rectangle
& rControlRegion
, ControlState
,
1258 const ImplControlValue
& rValue
, const OUString
&,
1259 Rectangle
&rNativeBoundingRegion
, Rectangle
&rNativeContentRegion
)
1261 /* TODO: all this funcions needs improvements */
1262 Rectangle aEditRect
= rControlRegion
;
1263 gint indicator_size
, indicator_spacing
, point
;
1265 if(((nType
== CTRL_CHECKBOX
) || (nType
== CTRL_RADIOBUTTON
)) &&
1266 nPart
== PART_ENTIRE_CONTROL
)
1268 rNativeBoundingRegion
= rControlRegion
;
1270 gtk_style_context_get_style( mpCheckButtonStyle
,
1271 "indicator-size", &indicator_size
,
1272 "indicator-spacing", &indicator_spacing
,
1276 gtk_style_context_get_border(mpCheckButtonStyle
, GTK_STATE_FLAG_NORMAL
, &border
);
1279 gtk_style_context_get_padding(mpCheckButtonStyle
, GTK_STATE_FLAG_NORMAL
, &padding
);
1282 indicator_size
+= 2*indicator_spacing
+ border
.left
+ padding
.left
+ border
.right
+ padding
.right
;
1283 Rectangle
aIndicatorRect( Point( 0,
1284 (rControlRegion
.GetHeight()-indicator_size
)/2),
1285 Size( indicator_size
, indicator_size
) );
1286 rNativeContentRegion
= aIndicatorRect
;
1290 else if( nType
== CTRL_MENU_POPUP
)
1292 if (((nPart
== PART_MENU_ITEM_CHECK_MARK
) ||
1293 (nPart
== PART_MENU_ITEM_RADIO_MARK
) ))
1297 gtk_style_context_get_style( mpCheckMenuItemStyle
,
1298 "indicator-size", &indicator_size
,
1301 point
= MAX(0, rControlRegion
.GetHeight() - indicator_size
);
1302 aEditRect
= Rectangle( Point( 0, point
/ 2),
1303 Size( indicator_size
, indicator_size
) );
1305 else if (nPart
== PART_MENU_SEPARATOR
)
1307 gint separator_height
, separator_width
, wide_separators
;
1309 gtk_style_context_get_style (mpCheckMenuItemStyle
,
1310 "wide-separators", &wide_separators
,
1311 "separator-width", &separator_width
,
1312 "separator-height", &separator_height
,
1315 aEditRect
= Rectangle( aEditRect
.TopLeft(),
1316 Size( aEditRect
.GetWidth(), wide_separators
? separator_height
: 1 ) );
1318 else if (nPart
== PART_MENU_SUBMENU_ARROW
)
1320 gfloat arrow_scaling
, arrow_size
;
1323 gtk_style_context_get_style (mpCheckMenuItemStyle
,
1324 "arrow-scaling", &arrow_scaling
,
1327 arrow_size
= 11 * arrow_scaling
;
1328 aEditRect
= Rectangle( aEditRect
.TopLeft(),
1329 Size( arrow_size
, arrow_size
) );
1332 else if ( (nType
==CTRL_SCROLLBAR
) &&
1333 ((nPart
==PART_BUTTON_LEFT
) || (nPart
==PART_BUTTON_RIGHT
) ||
1334 (nPart
==PART_BUTTON_UP
) || (nPart
==PART_BUTTON_DOWN
) ) )
1336 rNativeBoundingRegion
= NWGetScrollButtonRect( nPart
, rControlRegion
);
1337 rNativeContentRegion
= rNativeBoundingRegion
;
1339 if (!rNativeContentRegion
.GetWidth())
1340 rNativeContentRegion
.Right() = rNativeContentRegion
.Left() + 1;
1341 if (!rNativeContentRegion
.GetHeight())
1342 rNativeContentRegion
.Bottom() = rNativeContentRegion
.Top() + 1;
1346 if( (nType
== CTRL_MENUBAR
) && (nPart
== PART_ENTIRE_CONTROL
) )
1348 aEditRect
= GetWidgetSize(rControlRegion
, gMenuBarWidget
);
1350 else if ( (nType
==CTRL_SPINBOX
) &&
1351 ((nPart
==PART_BUTTON_UP
) || (nPart
==PART_BUTTON_DOWN
) ||
1352 (nPart
==PART_SUB_EDIT
)) )
1354 Rectangle
aControlRegion(GetWidgetSize(rControlRegion
, gSpinBox
));
1355 aEditRect
= NWGetSpinButtonRect(nPart
, aControlRegion
);
1357 else if ( (nType
==CTRL_COMBOBOX
) &&
1358 ((nPart
==PART_BUTTON_DOWN
) || (nPart
==PART_SUB_EDIT
)) )
1360 aEditRect
= NWGetComboBoxButtonRect( nType
, nPart
, rControlRegion
);
1362 else if ( (nType
==CTRL_LISTBOX
) &&
1363 ((nPart
==PART_BUTTON_DOWN
) || (nPart
==PART_SUB_EDIT
)) )
1365 aEditRect
= NWGetComboBoxButtonRect( nType
, nPart
, rControlRegion
);
1367 else if (nType
== CTRL_EDITBOX
&& nPart
== PART_ENTIRE_CONTROL
)
1369 aEditRect
= GetWidgetSize(rControlRegion
, gEntryBox
);
1371 else if (nType
== CTRL_LISTBOX
&& nPart
== PART_ENTIRE_CONTROL
)
1373 aEditRect
= GetWidgetSize(rControlRegion
, gListBox
);
1375 else if (nType
== CTRL_COMBOBOX
&& nPart
== PART_ENTIRE_CONTROL
)
1377 aEditRect
= GetWidgetSize(rControlRegion
, gComboBox
);
1379 else if (nType
== CTRL_SPINBOX
&& nPart
== PART_ENTIRE_CONTROL
)
1381 aEditRect
= GetWidgetSize(rControlRegion
, gSpinBox
);
1383 else if (nType
== CTRL_TAB_ITEM
&& nPart
== PART_ENTIRE_CONTROL
)
1385 gtk_style_context_save(mpNoteBookStyle
);
1387 gtk_style_context_add_region(mpNoteBookStyle
, GTK_STYLE_REGION_TAB
, GTK_REGION_ONLY
);
1388 gtk_style_context_add_class(mpNoteBookStyle
, GTK_STYLE_CLASS_TOP
);
1390 const TabitemValue
& rTabitemValue
= static_cast<const TabitemValue
&>(rValue
);
1391 const Rectangle
& rTabitemRect
= rTabitemValue
.getContentRect();
1393 aEditRect
= AdjustRectForTextBordersPadding(mpNoteBookStyle
, rTabitemRect
.GetWidth(),
1394 rTabitemRect
.GetHeight(), rControlRegion
);
1396 gtk_style_context_restore(mpNoteBookStyle
);
1398 else if (nType
== CTRL_FRAME
&& nPart
== PART_BORDER
)
1400 aEditRect
= rControlRegion
;
1401 DrawFrameFlags nStyle
= static_cast<DrawFrameFlags
>(rValue
.getNumericVal() & 0xfff0);
1402 if (nStyle
& DrawFrameFlags::NoDraw
)
1404 gtk_style_context_save(mpFrameInStyle
);
1405 gtk_style_context_add_class(mpFrameInStyle
, GTK_STYLE_CLASS_FRAME
);
1408 gtk_style_context_get_padding(mpFrameInStyle
, GTK_STATE_FLAG_NORMAL
, &padding
);
1411 gtk_style_context_get_border(mpFrameInStyle
, GTK_STATE_FLAG_NORMAL
, &border
);
1413 int x1
= aEditRect
.Left();
1414 int y1
= aEditRect
.Top();
1415 int x2
= aEditRect
.Right();
1416 int y2
= aEditRect
.Bottom();
1418 rNativeBoundingRegion
= aEditRect
;
1419 rNativeContentRegion
= Rectangle(x1
+ (padding
.left
+ border
.left
),
1420 y1
+ (padding
.top
+ border
.top
),
1421 x2
- (padding
.right
+ border
.right
),
1422 y2
- (padding
.bottom
+ border
.bottom
));
1424 gtk_style_context_restore(mpFrameInStyle
);
1428 rNativeContentRegion
= rControlRegion
;
1435 rNativeBoundingRegion
= aEditRect
;
1436 rNativeContentRegion
= rNativeBoundingRegion
;
1440 /************************************************************************
1441 * helper for GtkSalFrame
1442 ************************************************************************/
1443 static inline ::Color
getColor( const GdkRGBA
& rCol
)
1445 return ::Color( (int)(rCol
.red
* 0xFFFF) >> 8, (int)(rCol
.green
* 0xFFFF) >> 8, (int)(rCol
.blue
* 0xFFFF) >> 8 );
1448 static inline ::Color
getColorFromColor( const GdkColor
& rCol
)
1450 return ::Color( rCol
.red
>> 8, rCol
.green
>> 8, rCol
.blue
>> 8 );
1453 void GtkSalGraphics::updateSettings( AllSettings
& rSettings
)
1455 GdkScreen
* pScreen
= gtk_widget_get_screen( mpWindow
);
1456 GtkStyleContext
* pStyle
= gtk_widget_get_style_context( mpWindow
);
1457 GtkSettings
* pSettings
= gtk_widget_get_settings( mpWindow
);
1458 StyleSettings aStyleSet
= rSettings
.GetStyleSettings();
1463 gtk_style_context_get_color(pStyle
, GTK_STATE_FLAG_NORMAL
, &text_color
);
1464 ::Color aTextColor
= getColor( text_color
);
1465 aStyleSet
.SetDialogTextColor( aTextColor
);
1466 aStyleSet
.SetButtonTextColor( aTextColor
);
1467 aStyleSet
.SetRadioCheckTextColor( aTextColor
);
1468 aStyleSet
.SetGroupTextColor( aTextColor
);
1469 aStyleSet
.SetLabelTextColor( aTextColor
);
1470 aStyleSet
.SetInfoTextColor( aTextColor
);
1471 aStyleSet
.SetWindowTextColor( aTextColor
);
1472 aStyleSet
.SetFieldTextColor( aTextColor
);
1474 // mouse over text colors
1475 gtk_style_context_get_color(pStyle
, GTK_STATE_FLAG_PRELIGHT
, &text_color
);
1476 aTextColor
= getColor( text_color
);
1477 aStyleSet
.SetButtonRolloverTextColor( aTextColor
);
1478 aStyleSet
.SetFieldRolloverTextColor( aTextColor
);
1480 // background colors
1481 GdkRGBA background_color
;
1482 gtk_style_context_get_background_color(pStyle
, GTK_STATE_FLAG_NORMAL
, &background_color
);
1484 ::Color aBackColor
= getColor( background_color
);
1485 aStyleSet
.Set3DColors( aBackColor
);
1486 aStyleSet
.SetFaceColor( aBackColor
);
1487 aStyleSet
.SetDialogColor( aBackColor
);
1488 aStyleSet
.SetWorkspaceColor( aBackColor
);
1489 aStyleSet
.SetCheckedColorSpecialCase( );
1493 GtkStyleContext
*pCStyle
= gtk_style_context_new();
1494 gtk_style_context_set_screen( pCStyle
, gtk_window_get_screen( GTK_WINDOW( mpWindow
) ) );
1495 GtkWidgetPath
*pCPath
= gtk_widget_path_new();
1496 guint pos
= gtk_widget_path_append_type(pCPath
, GTK_TYPE_WINDOW
);
1497 gtk_widget_path_iter_add_class(pCPath
, pos
, GTK_STYLE_CLASS_TOOLTIP
);
1498 pos
= gtk_widget_path_append_type (pCPath
, GTK_TYPE_LABEL
);
1499 #if GTK_CHECK_VERSION(3,16,0)
1500 gtk_widget_path_iter_add_class(pCPath
, pos
, GTK_STYLE_CLASS_LABEL
);
1502 pCStyle
= gtk_style_context_new();
1503 gtk_style_context_set_path(pCStyle
, pCPath
);
1504 gtk_widget_path_free(pCPath
);
1506 GdkRGBA tooltip_bg_color
, tooltip_fg_color
;
1507 gtk_style_context_get_color(pCStyle
, GTK_STATE_FLAG_NORMAL
, &tooltip_fg_color
);
1508 gtk_style_context_get_background_color(pCStyle
, GTK_STATE_FLAG_NORMAL
, &tooltip_bg_color
);
1509 g_object_unref( pCStyle
);
1511 aStyleSet
.SetHelpColor( getColor( tooltip_bg_color
));
1512 aStyleSet
.SetHelpTextColor( getColor( tooltip_fg_color
));
1516 // construct style context for text view
1517 GtkStyleContext
*pCStyle
= gtk_style_context_new();
1518 gtk_style_context_set_screen( pCStyle
, gtk_window_get_screen( GTK_WINDOW( mpWindow
) ) );
1519 GtkWidgetPath
*pCPath
= gtk_widget_path_new();
1520 gtk_widget_path_append_type( pCPath
, GTK_TYPE_TEXT_VIEW
);
1521 gtk_widget_path_iter_add_class( pCPath
, -1, GTK_STYLE_CLASS_VIEW
);
1522 gtk_style_context_set_path( pCStyle
, pCPath
);
1523 gtk_widget_path_free( pCPath
);
1525 // highlighting colors
1526 gtk_style_context_get_background_color(pCStyle
, GTK_STATE_FLAG_SELECTED
, &text_color
);
1527 ::Color aHighlightColor
= getColor( text_color
);
1528 gtk_style_context_get_color(pCStyle
, GTK_STATE_FLAG_SELECTED
, &text_color
);
1529 ::Color aHighlightTextColor
= getColor( text_color
);
1530 aStyleSet
.SetHighlightColor( aHighlightColor
);
1531 aStyleSet
.SetHighlightTextColor( aHighlightTextColor
);
1533 // field background color
1534 GdkRGBA field_background_color
;
1535 gtk_style_context_get_background_color(pCStyle
, GTK_STATE_FLAG_NORMAL
, &field_background_color
);
1536 g_object_unref( pCStyle
);
1538 ::Color aBackFieldColor
= getColor( field_background_color
);
1539 aStyleSet
.SetFieldColor( aBackFieldColor
);
1540 // This baby is the default page/paper color
1541 aStyleSet
.SetWindowColor( aBackFieldColor
);
1544 // menu disabled entries handling
1545 aStyleSet
.SetSkipDisabledInMenus( true );
1546 aStyleSet
.SetAcceleratorsInContextMenus( false );
1549 gtk_style_context_get_background_color( mpMenuStyle
, GTK_STATE_FLAG_NORMAL
, &background_color
);
1550 aBackColor
= getColor( background_color
);
1551 aStyleSet
.SetMenuColor( aBackColor
);
1554 gtk_style_context_get_background_color( mpMenuBarStyle
, GTK_STATE_FLAG_NORMAL
, &background_color
);
1555 aBackColor
= getColor( background_color
);
1556 aStyleSet
.SetMenuBarColor( aBackColor
);
1557 aStyleSet
.SetMenuBarRolloverColor( aBackColor
);
1559 gtk_style_context_get_color( mpMenuBarItemStyle
, GTK_STATE_FLAG_NORMAL
, &text_color
);
1560 aTextColor
= aStyleSet
.GetPersonaMenuBarTextColor().get_value_or( getColor( text_color
) );
1561 aStyleSet
.SetMenuBarTextColor( aTextColor
);
1562 aStyleSet
.SetMenuBarRolloverTextColor( aTextColor
);
1564 gtk_style_context_get_color( mpMenuBarItemStyle
, GTK_STATE_FLAG_PRELIGHT
, &text_color
);
1565 aTextColor
= aStyleSet
.GetPersonaMenuBarTextColor().get_value_or( getColor( text_color
) );
1566 aStyleSet
.SetMenuBarHighlightTextColor( aTextColor
);
1569 gtk_style_context_get_color( mpMenuStyle
, GTK_STATE_FLAG_NORMAL
, &color
);
1570 aTextColor
= getColor( color
);
1571 aStyleSet
.SetMenuTextColor( aTextColor
);
1573 // Awful hack for menu separators in the Sonar and similar themes.
1574 // If the menu color is not too dark, and the menu text color is lighter,
1575 // make the "light" color lighter than the menu color and the "shadow"
1576 // color darker than it.
1577 if ( aStyleSet
.GetMenuColor().GetLuminance() >= 32 &&
1578 aStyleSet
.GetMenuColor().GetLuminance() <= aStyleSet
.GetMenuTextColor().GetLuminance() )
1580 ::Color temp
= aStyleSet
.GetMenuColor();
1581 temp
.IncreaseLuminance( 8 );
1582 aStyleSet
.SetLightColor( temp
);
1583 temp
= aStyleSet
.GetMenuColor();
1584 temp
.DecreaseLuminance( 16 );
1585 aStyleSet
.SetShadowColor( temp
);
1588 gtk_style_context_get_background_color( mpCheckMenuItemStyle
, GTK_STATE_FLAG_PRELIGHT
, &background_color
);
1589 ::Color aHighlightColor
= getColor( background_color
);
1590 aStyleSet
.SetMenuHighlightColor( aHighlightColor
);
1592 gtk_style_context_get_color( mpCheckMenuItemStyle
, GTK_STATE_FLAG_PRELIGHT
, &color
);
1593 ::Color aHighlightTextColor
= getColor( color
);
1594 aStyleSet
.SetMenuHighlightTextColor( aHighlightTextColor
);
1597 GdkColor
*link_color
= NULL
;
1598 gtk_style_context_get_style(pStyle
,
1599 "link-color", &link_color
,
1602 aStyleSet
.SetLinkColor(getColorFromColor(*link_color
));
1603 gdk_color_free(link_color
);
1607 gtk_style_context_get_style(pStyle
,
1608 "visited-link-color", &link_color
,
1611 aStyleSet
.SetVisitedLinkColor(getColorFromColor(*link_color
));
1612 gdk_color_free(link_color
);
1616 GtkStyleContext
*pCStyle
= gtk_style_context_new();
1617 gtk_style_context_set_screen( pCStyle
, gtk_window_get_screen( GTK_WINDOW( mpWindow
) ) );
1618 GtkWidgetPath
*pCPath
= gtk_widget_path_new();
1619 guint pos
= gtk_widget_path_append_type(pCPath
, GTK_TYPE_NOTEBOOK
);
1620 gtk_widget_path_iter_add_class(pCPath
, pos
, GTK_STYLE_CLASS_NOTEBOOK
);
1621 gtk_widget_path_iter_add_region(pCPath
, pos
, GTK_STYLE_REGION_TAB
, static_cast<GtkRegionFlags
>(GTK_REGION_EVEN
| GTK_REGION_FIRST
));
1622 pos
= gtk_widget_path_append_type (pCPath
, GTK_TYPE_LABEL
);
1623 #if GTK_CHECK_VERSION(3,16,0)
1624 gtk_widget_path_iter_add_class(pCPath
, pos
, GTK_STYLE_CLASS_LABEL
);
1626 pCStyle
= gtk_style_context_new();
1627 gtk_style_context_set_path(pCStyle
, pCPath
);
1628 gtk_widget_path_free(pCPath
);
1630 gtk_style_context_get_color(pCStyle
, GTK_STATE_FLAG_NORMAL
, &text_color
);
1631 aTextColor
= getColor( text_color
);
1632 aStyleSet
.SetTabTextColor(aTextColor
);
1634 // mouse over text colors
1635 gtk_style_context_add_class(pCStyle
, "prelight-page");
1636 gtk_style_context_get_color(pCStyle
, GTK_STATE_FLAG_PRELIGHT
, &text_color
);
1637 gtk_style_context_remove_class(pCStyle
, "prelight-page");
1638 aTextColor
= getColor( text_color
);
1639 aStyleSet
.SetTabRolloverTextColor(aTextColor
);
1641 gtk_style_context_add_class(pCStyle
, "active-page");
1642 gtk_style_context_get_color(pCStyle
, GTK_STATE_FLAG_ACTIVE
, &text_color
);
1643 gtk_style_context_remove_class(pCStyle
, "active-page");
1644 aTextColor
= getColor( text_color
);
1645 aStyleSet
.SetTabHighlightTextColor(aTextColor
);
1647 g_object_unref( pCStyle
);
1651 const PangoFontDescription
* font
= gtk_style_context_get_font(pStyle
, GTK_STATE_FLAG_NORMAL
);
1652 OString aFamily
= pango_font_description_get_family( font
);
1653 int nPangoHeight
= pango_font_description_get_size( font
);
1654 PangoStyle eStyle
= pango_font_description_get_style( font
);
1655 PangoWeight eWeight
= pango_font_description_get_weight( font
);
1656 PangoStretch eStretch
= pango_font_description_get_stretch( font
);
1658 psp::FastPrintFontInfo aInfo
;
1660 aInfo
.m_aFamilyName
= OStringToOUString( aFamily
, RTL_TEXTENCODING_UTF8
);
1664 case PANGO_STYLE_NORMAL
: aInfo
.m_eItalic
= ITALIC_NONE
;break;
1665 case PANGO_STYLE_ITALIC
: aInfo
.m_eItalic
= ITALIC_NORMAL
;break;
1666 case PANGO_STYLE_OBLIQUE
: aInfo
.m_eItalic
= ITALIC_OBLIQUE
;break;
1669 if( eWeight
<= PANGO_WEIGHT_ULTRALIGHT
)
1670 aInfo
.m_eWeight
= WEIGHT_ULTRALIGHT
;
1671 else if( eWeight
<= PANGO_WEIGHT_LIGHT
)
1672 aInfo
.m_eWeight
= WEIGHT_LIGHT
;
1673 else if( eWeight
<= PANGO_WEIGHT_NORMAL
)
1674 aInfo
.m_eWeight
= WEIGHT_NORMAL
;
1675 else if( eWeight
<= PANGO_WEIGHT_BOLD
)
1676 aInfo
.m_eWeight
= WEIGHT_BOLD
;
1678 aInfo
.m_eWeight
= WEIGHT_ULTRABOLD
;
1682 case PANGO_STRETCH_ULTRA_CONDENSED
: aInfo
.m_eWidth
= WIDTH_ULTRA_CONDENSED
;break;
1683 case PANGO_STRETCH_EXTRA_CONDENSED
: aInfo
.m_eWidth
= WIDTH_EXTRA_CONDENSED
;break;
1684 case PANGO_STRETCH_CONDENSED
: aInfo
.m_eWidth
= WIDTH_CONDENSED
;break;
1685 case PANGO_STRETCH_SEMI_CONDENSED
: aInfo
.m_eWidth
= WIDTH_SEMI_CONDENSED
;break;
1686 case PANGO_STRETCH_NORMAL
: aInfo
.m_eWidth
= WIDTH_NORMAL
;break;
1687 case PANGO_STRETCH_SEMI_EXPANDED
: aInfo
.m_eWidth
= WIDTH_SEMI_EXPANDED
;break;
1688 case PANGO_STRETCH_EXPANDED
: aInfo
.m_eWidth
= WIDTH_EXPANDED
;break;
1689 case PANGO_STRETCH_EXTRA_EXPANDED
: aInfo
.m_eWidth
= WIDTH_EXTRA_EXPANDED
;break;
1690 case PANGO_STRETCH_ULTRA_EXPANDED
: aInfo
.m_eWidth
= WIDTH_ULTRA_EXPANDED
;break;
1693 #if OSL_DEBUG_LEVEL > 1
1694 fprintf( stderr
, "font name BEFORE system match: \"%s\"\n", aFamily
.getStr() );
1697 // match font to e.g. resolve "Sans"
1698 psp::PrintFontManager::get().matchFont( aInfo
, rSettings
.GetUILanguageTag().getLocale() );
1700 #if OSL_DEBUG_LEVEL > 1
1701 fprintf( stderr
, "font match %s, name AFTER: \"%s\"\n",
1702 aInfo
.m_nID
!= 0 ? "succeeded" : "failed",
1703 OUStringToOString( aInfo
.m_aFamilyName
, RTL_TEXTENCODING_ISO_8859_1
).getStr() );
1706 int nPointHeight
= 0;
1707 /*sal_Int32 nDispDPIY = GetDisplay()->GetResolution().B();
1708 static gboolean(*pAbso)(const PangoFontDescription*) =
1709 (gboolean(*)(const PangoFontDescription*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "pango_font_description_get_size_is_absolute" );
1711 if( pAbso && pAbso( font ) )
1712 nPointHeight = (nPangoHeight * 72 + nDispDPIY*PANGO_SCALE/2) / (nDispDPIY * PANGO_SCALE);
1714 nPointHeight
= nPangoHeight
/PANGO_SCALE
;
1716 vcl::Font
aFont( aInfo
.m_aFamilyName
, Size( 0, nPointHeight
) );
1717 if( aInfo
.m_eWeight
!= WEIGHT_DONTKNOW
)
1718 aFont
.SetWeight( aInfo
.m_eWeight
);
1719 if( aInfo
.m_eWidth
!= WIDTH_DONTKNOW
)
1720 aFont
.SetWidthType( aInfo
.m_eWidth
);
1721 if( aInfo
.m_eItalic
!= ITALIC_DONTKNOW
)
1722 aFont
.SetItalic( aInfo
.m_eItalic
);
1723 if( aInfo
.m_ePitch
!= PITCH_DONTKNOW
)
1724 aFont
.SetPitch( aInfo
.m_ePitch
);
1726 aStyleSet
.SetAppFont( aFont
);
1727 aStyleSet
.SetHelpFont( aFont
);
1728 aStyleSet
.SetMenuFont( aFont
);
1729 aStyleSet
.SetToolFont( aFont
);
1730 aStyleSet
.SetLabelFont( aFont
);
1731 aStyleSet
.SetInfoFont( aFont
);
1732 aStyleSet
.SetRadioCheckFont( aFont
);
1733 aStyleSet
.SetPushButtonFont( aFont
);
1734 aStyleSet
.SetFieldFont( aFont
);
1735 aStyleSet
.SetIconFont( aFont
);
1736 aStyleSet
.SetGroupFont( aFont
);
1738 aFont
.SetWeight( WEIGHT_BOLD
);
1739 aStyleSet
.SetTabFont( aFont
); //pull from notebook style + GTK_STYLE_REGION_TAB ?
1740 aStyleSet
.SetTitleFont( aFont
);
1741 aStyleSet
.SetFloatTitleFont( aFont
);
1742 // get cursor blink time
1743 gboolean blink
= false;
1745 g_object_get( pSettings
, "gtk-cursor-blink", &blink
, (char *)NULL
);
1748 gint blink_time
= static_cast<gint
>(STYLE_CURSOR_NOBLINKTIME
);
1749 g_object_get( pSettings
, "gtk-cursor-blink-time", &blink_time
, (char *)NULL
);
1750 // set the blink_time if there is a setting and it is reasonable
1751 // else leave the default value
1752 if( blink_time
> 100 && blink_time
!= gint(STYLE_CURSOR_NOBLINKTIME
) )
1753 aStyleSet
.SetCursorBlinkTime( blink_time
/2 );
1756 aStyleSet
.SetCursorBlinkTime( STYLE_CURSOR_NOBLINKTIME
);
1758 MouseSettings aMouseSettings
= rSettings
.GetMouseSettings();
1759 int iDoubleClickTime
, iDoubleClickDistance
, iDragThreshold
;
1760 static const int MENU_POPUP_DELAY
= 225;
1761 g_object_get( pSettings
,
1762 "gtk-double-click-time", &iDoubleClickTime
,
1763 "gtk-double-click-distance", &iDoubleClickDistance
,
1764 "gtk-dnd-drag-threshold", &iDragThreshold
,
1766 aMouseSettings
.SetDoubleClickTime( iDoubleClickTime
);
1767 aMouseSettings
.SetDoubleClickWidth( iDoubleClickDistance
);
1768 aMouseSettings
.SetDoubleClickHeight( iDoubleClickDistance
);
1769 aMouseSettings
.SetStartDragWidth( iDragThreshold
);
1770 aMouseSettings
.SetStartDragHeight( iDragThreshold
);
1771 aMouseSettings
.SetMenuDelay( MENU_POPUP_DELAY
);
1772 rSettings
.SetMouseSettings( aMouseSettings
);
1774 gboolean primarybuttonwarps
= false;
1775 g_object_get( pSettings
,
1776 "gtk-primary-button-warps-slider", &primarybuttonwarps
,
1778 aStyleSet
.SetPreferredUseImagesInMenus(false);
1779 aStyleSet
.SetPrimaryButtonWarpsSlider(primarybuttonwarps
);
1781 // set scrollbar settings
1782 gint slider_width
= 14;
1783 gint trough_border
= 1;
1784 gint min_slider_length
= 21;
1786 // Grab some button style attributes
1787 gtk_style_context_get_style( mpVScrollbarStyle
,
1788 "slider-width", &slider_width
,
1789 "trough-border", &trough_border
,
1790 "min-slider-length", &min_slider_length
,
1792 gint magic
= trough_border
? 1 : 0;
1793 aStyleSet
.SetScrollBarSize( slider_width
+ 2*trough_border
);
1794 aStyleSet
.SetMinThumbSize( min_slider_length
- magic
);
1796 // preferred icon style
1797 gchar
* pIconThemeName
= NULL
;
1798 g_object_get( pSettings
, "gtk-icon-theme-name", &pIconThemeName
, (char *)NULL
);
1799 aStyleSet
.SetPreferredIconTheme( OUString::createFromAscii( pIconThemeName
) );
1800 g_free( pIconThemeName
);
1802 aStyleSet
.SetToolbarIconSize( ToolbarIconSize::Large
);
1804 const cairo_font_options_t
* pNewOptions
= gdk_screen_get_font_options(pScreen
);
1805 aStyleSet
.SetCairoFontOptions( pNewOptions
);
1806 // finally update the collected settings
1807 rSettings
.SetStyleSettings( aStyleSet
);
1808 gchar
* pThemeName
= NULL
;
1809 g_object_get( pSettings
, "gtk-theme-name", &pThemeName
, (char *)NULL
);
1810 #if OSL_DEBUG_LEVEL > 1
1811 fprintf( stderr
, "Theme name is \"%s\"\n", pThemeName
);
1816 bool GtkSalGraphics::IsNativeControlSupported( ControlType nType
, ControlPart nPart
)
1821 return false; //shaped, punt that problem for now
1823 case CTRL_PUSHBUTTON
:
1824 case CTRL_RADIOBUTTON
:
1829 if (nPart
==PART_ENTIRE_CONTROL
|| nPart
== PART_FOCUS
)
1833 case CTRL_SCROLLBAR
:
1834 if(nPart
==PART_DRAW_BACKGROUND_HORZ
|| nPart
==PART_DRAW_BACKGROUND_VERT
||
1835 nPart
==PART_ENTIRE_CONTROL
|| nPart
==HAS_THREE_BUTTONS
)
1840 case CTRL_MULTILINE_EDITBOX
:
1841 if (nPart
==PART_ENTIRE_CONTROL
|| nPart
==HAS_BACKGROUND_TEXTURE
)
1846 if (nPart
==PART_ENTIRE_CONTROL
|| nPart
==HAS_BACKGROUND_TEXTURE
|| nPart
== PART_ALL_BUTTONS
)
1851 if (nPart
==PART_ENTIRE_CONTROL
|| nPart
==HAS_BACKGROUND_TEXTURE
|| nPart
== PART_ALL_BUTTONS
|| nPart
== PART_BUTTON_UP
|| nPart
== PART_BUTTON_DOWN
)
1855 case CTRL_SPINBUTTONS
:
1856 if (nPart
==PART_ENTIRE_CONTROL
|| nPart
==PART_ALL_BUTTONS
)
1861 case CTRL_WINDOW_BACKGROUND
:
1865 case CTRL_TAB_HEADER
:
1868 if(nPart
==PART_ENTIRE_CONTROL
|| nPart
==PART_TABS_DRAW_RTL
)
1873 if (nPart
==PART_ENTIRE_CONTROL
|| nPart
==PART_WINDOW
|| nPart
==HAS_BACKGROUND_TEXTURE
|| nPart
== PART_FOCUS
)
1878 if( nPart
==PART_ENTIRE_CONTROL
1879 // || nPart==PART_DRAW_BACKGROUND_HORZ
1880 // || nPart==PART_DRAW_BACKGROUND_VERT
1881 // || nPart==PART_THUMB_HORZ
1882 // || nPart==PART_THUMB_VERT
1883 || nPart
==PART_BUTTON
1884 // || nPart==PART_SEPARATOR_HORZ
1885 || nPart
==PART_SEPARATOR_VERT
1891 if (nPart
==PART_ENTIRE_CONTROL
|| nPart
==PART_MENU_ITEM
)
1895 case CTRL_MENU_POPUP
:
1896 if (nPart
==PART_ENTIRE_CONTROL
1897 || nPart
==PART_MENU_ITEM
1898 || nPart
==PART_MENU_ITEM_CHECK_MARK
1899 || nPart
==PART_MENU_ITEM_RADIO_MARK
1900 || nPart
==PART_MENU_SEPARATOR
1901 || nPart
==PART_MENU_SUBMENU_ARROW
1906 // case CTRL_SLIDER:
1907 // if(nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA)
1911 case CTRL_FIXEDLINE
:
1912 if (nPart
== PART_SEPARATOR_VERT
|| nPart
== PART_SEPARATOR_HORZ
)
1916 case CTRL_LISTHEADER
:
1917 if (nPart
== PART_BUTTON
|| nPart
== PART_ARROW
)
1922 SAL_INFO("vcl.gtk", "Unhandled is native supported for Type:" << nType
<< ", Part" << nPart
);
1927 bool GtkSalGraphics::SupportsCairo() const
1932 cairo::SurfaceSharedPtr
GtkSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr
& rSurface
) const
1934 return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(rSurface
));
1937 cairo::SurfaceSharedPtr
GtkSalGraphics::CreateSurface(const OutputDevice
& /*rRefDevice*/, int x
, int y
, int width
, int height
) const
1939 return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(this, x
, y
, width
, height
));
1942 void GtkSalGraphics::WidgetQueueDraw() const
1944 //request gtk to sync the entire contents
1945 gtk_widget_queue_draw(mpWindow
);
1950 void getStyleContext(GtkStyleContext
** style
, GtkWidget
* widget
)
1952 gtk_container_add(GTK_CONTAINER(gDumbContainer
), widget
);
1953 *style
= gtk_widget_get_style_context(widget
);
1954 g_object_ref(*style
);
1959 void GtkData::initNWF()
1961 ImplSVData
* pSVData
= ImplGetSVData();
1962 pSVData
->maNWFData
.mbFlatMenu
= true;
1963 pSVData
->maNWFData
.mbCheckBoxNeedsErase
= true;
1964 pSVData
->maNWFData
.mbCanDrawWidgetAnySize
= true;
1965 pSVData
->maNWFData
.mbDDListBoxNoTextArea
= true;
1966 pSVData
->maNWFData
.mbNoFocusRects
= true;
1967 pSVData
->maNWFData
.mbNoFocusRectsForFlatButtons
= true;
1970 void GtkData::deInitNWF()
1973 gtk_widget_destroy(gCacheWindow
);
1976 static void get_combo_box_entry_inner_widgets(GtkWidget
*widget
, gpointer
)
1978 if (GTK_IS_TOGGLE_BUTTON(widget
))
1980 gComboBoxButtonWidget
= widget
;
1982 else if (GTK_IS_ENTRY(widget
))
1984 gComboBoxEntryWidget
= widget
;
1988 void get_combo_box_inner_button(GtkWidget
*widget
, gpointer
)
1990 if (GTK_IS_TOGGLE_BUTTON(widget
))
1992 gListBoxButtonWidget
= widget
;
1996 GtkSalGraphics::GtkSalGraphics( GtkSalFrame
*pFrame
, GtkWidget
*pWindow
)
2001 m_xTextRenderImpl
.reset(new GtkCairoTextRender(*this));
2006 style_loaded
= true;
2007 gtk_init(NULL
, NULL
);
2008 /* Load the GtkStyleContexts, it might be a bit slow, but usually,
2009 * gtk apps create a lot of widgets at startup, so, it shouldn't be
2011 gCacheWindow
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2012 gDumbContainer
= gtk_fixed_new();
2013 gtk_container_add(GTK_CONTAINER(gCacheWindow
), gDumbContainer
);
2014 gtk_widget_realize(gDumbContainer
);
2015 gtk_widget_realize(gCacheWindow
);
2017 gEntryBox
= gtk_entry_new();
2018 getStyleContext(&mpEntryStyle
, gEntryBox
);
2019 getStyleContext(&mpTextViewStyle
, gtk_text_view_new());
2020 getStyleContext(&mpButtonStyle
, gtk_button_new());
2022 GtkWidget
* pToolbar
= gtk_toolbar_new();
2023 mpToolbarStyle
= gtk_widget_get_style_context(pToolbar
);
2024 gtk_style_context_add_class(mpToolbarStyle
, GTK_STYLE_CLASS_PRIMARY_TOOLBAR
);
2025 gtk_style_context_add_class(mpToolbarStyle
, GTK_STYLE_CLASS_TOOLBAR
);
2027 GtkToolItem
*item
= gtk_separator_tool_item_new();
2028 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar
), item
, -1);
2029 mpToolbarSeperatorStyle
= gtk_widget_get_style_context(GTK_WIDGET(item
));
2031 GtkWidget
*pButton
= gtk_button_new();
2032 item
= gtk_tool_button_new(pButton
, NULL
);
2033 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar
), item
, -1);
2034 mpToolButtonStyle
= gtk_widget_get_style_context(GTK_WIDGET(pButton
));
2036 getStyleContext(&mpVScrollbarStyle
, gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL
, NULL
));
2037 gtk_style_context_add_class(mpVScrollbarStyle
, GTK_STYLE_CLASS_SCROLLBAR
);
2038 getStyleContext(&mpHScrollbarStyle
, gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL
, NULL
));
2039 gtk_style_context_add_class(mpHScrollbarStyle
, GTK_STYLE_CLASS_SCROLLBAR
);
2041 getStyleContext(&mpCheckButtonStyle
, gtk_check_button_new());
2044 gMenuBarWidget
= gtk_menu_bar_new();
2045 gMenuItemMenuBarWidget
= gtk_menu_item_new_with_label( "b" );
2046 gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget
), gMenuItemMenuBarWidget
);
2047 getStyleContext(&mpMenuBarStyle
, gMenuBarWidget
);
2048 mpMenuBarItemStyle
= gtk_widget_get_style_context(gMenuItemMenuBarWidget
);
2051 GtkWidget
*menu
= gtk_menu_new();
2052 mpMenuStyle
= gtk_widget_get_style_context(menu
);
2053 gtk_menu_item_set_submenu(GTK_MENU_ITEM(gMenuItemMenuBarWidget
), menu
);
2056 gCheckMenuItemWidget
= gtk_check_menu_item_new_with_label("M");
2057 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), gCheckMenuItemWidget
);
2058 mpCheckMenuItemStyle
= gtk_widget_get_style_context(gCheckMenuItemWidget
);
2061 gSpinBox
= gtk_spin_button_new(NULL
, 0, 0);
2062 getStyleContext(&mpSpinStyle
, gSpinBox
);
2065 getStyleContext(&mpNoteBookStyle
, gtk_notebook_new());
2068 gComboBox
= gtk_combo_box_text_new_with_entry();
2069 getStyleContext(&mpComboboxStyle
, gComboBox
);
2070 /* Get ComboBox Entry and Button */
2071 gtk_container_forall(GTK_CONTAINER(gComboBox
),
2072 get_combo_box_entry_inner_widgets
,
2074 mpComboboxButtonStyle
= gtk_widget_get_style_context(gComboBoxButtonWidget
);
2077 gListBox
= gtk_combo_box_text_new();
2078 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gListBox
), "sample");
2079 getStyleContext(&mpListboxStyle
, gListBox
);
2080 /* Get ComboBox Button */
2081 gtk_container_forall(GTK_CONTAINER(gListBox
),
2082 get_combo_box_inner_button
,
2084 mpListboxButtonStyle
= gtk_widget_get_style_context(gListBoxButtonWidget
);
2087 gFrameIn
= gtk_frame_new(NULL
);
2088 gtk_frame_set_shadow_type(GTK_FRAME(gFrameIn
), GTK_SHADOW_IN
);
2090 gFrameOut
= gtk_frame_new(NULL
);
2091 gtk_frame_set_shadow_type(GTK_FRAME(gFrameOut
), GTK_SHADOW_OUT
);
2093 getStyleContext(&mpFrameInStyle
, gFrameIn
);
2094 getStyleContext(&mpFrameOutStyle
, gFrameOut
);
2095 getStyleContext(&mpFixedHoriLineStyle
, gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
));
2096 getStyleContext(&mpFixedVertLineStyle
, gtk_separator_new(GTK_ORIENTATION_VERTICAL
));
2100 gTreeViewWidget
= gtk_tree_view_new();
2101 gtk_container_add(GTK_CONTAINER(gDumbContainer
), gTreeViewWidget
);
2103 GtkTreeViewColumn
* firstTreeViewColumn
= gtk_tree_view_column_new();
2104 gtk_tree_view_column_set_title(firstTreeViewColumn
, "M");
2105 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget
), firstTreeViewColumn
);
2107 GtkTreeViewColumn
* middleTreeViewColumn
= gtk_tree_view_column_new();
2108 gtk_tree_view_column_set_title(middleTreeViewColumn
, "M");
2109 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget
), middleTreeViewColumn
);
2110 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gTreeViewWidget
), middleTreeViewColumn
);
2112 GtkTreeViewColumn
* lastTreeViewColumn
= gtk_tree_view_column_new();
2113 gtk_tree_view_column_set_title(lastTreeViewColumn
, "M");
2114 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget
), lastTreeViewColumn
);
2116 /* Use the middle column's header for our button */
2117 GtkWidget
* pTreeHeaderCellWidget
= gtk_tree_view_column_get_button(middleTreeViewColumn
);
2118 mpTreeHeaderButtonStyle
= gtk_widget_get_style_context(pTreeHeaderCellWidget
);
2121 getStyleContext(&mpProgressBarStyle
, gtk_progress_bar_new());
2123 gtk_widget_show_all(gDumbContainer
);
2126 cairo_t
* GtkSalGraphics::getCairoContext() const
2128 return mpFrame
->getCairoContext();
2131 void GtkSalGraphics::GetResolution(sal_Int32
& rDPIX
, sal_Int32
& rDPIY
)
2133 GdkScreen
* pScreen
= gtk_widget_get_screen(mpWindow
);
2134 double fResolution
= -1.0;
2135 g_object_get(pScreen
, "resolution", &fResolution
, nullptr);
2137 int nScaleFactor
= 1;
2139 #if GTK_CHECK_VERSION(3, 10, 0)
2140 nScaleFactor
= gdk_window_get_scale_factor(widget_get_window(mpWindow
));
2143 if (fResolution
> 0.0)
2144 rDPIX
= rDPIY
= sal_Int32(fResolution
* nScaleFactor
);
2149 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */