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>
11 #include <sal/log.hxx>
12 #include <osl/module.h>
14 #include <config_cairo_canvas.h>
16 #include <unx/gtk/gtkframe.hxx>
17 #include <unx/gtk/gtkdata.hxx>
18 #include <unx/gtk/gtkinst.hxx>
19 #include <unx/gtk/gtkgdi.hxx>
20 #include <unx/gtk/gtkbackend.hxx>
21 #include <vcl/decoview.hxx>
22 #include <vcl/settings.hxx>
23 #include <unx/fontmanager.hxx>
25 #include "cairo_gtk3_cairo.hxx"
28 GtkStyleContext
* GtkSalGraphics::mpWindowStyle
= nullptr;
29 GtkStyleContext
* GtkSalGraphics::mpButtonStyle
= nullptr;
30 GtkStyleContext
* GtkSalGraphics::mpLinkButtonStyle
= nullptr;
31 GtkStyleContext
* GtkSalGraphics::mpEntryStyle
= nullptr;
32 GtkStyleContext
* GtkSalGraphics::mpTextViewStyle
= nullptr;
33 GtkStyleContext
* GtkSalGraphics::mpVScrollbarStyle
= nullptr;
34 GtkStyleContext
* GtkSalGraphics::mpVScrollbarContentsStyle
= nullptr;
35 GtkStyleContext
* GtkSalGraphics::mpVScrollbarTroughStyle
= nullptr;
36 GtkStyleContext
* GtkSalGraphics::mpVScrollbarSliderStyle
= nullptr;
37 GtkStyleContext
* GtkSalGraphics::mpVScrollbarButtonStyle
= nullptr;
38 GtkStyleContext
* GtkSalGraphics::mpHScrollbarStyle
= nullptr;
39 GtkStyleContext
* GtkSalGraphics::mpHScrollbarContentsStyle
= nullptr;
40 GtkStyleContext
* GtkSalGraphics::mpHScrollbarTroughStyle
= nullptr;
41 GtkStyleContext
* GtkSalGraphics::mpHScrollbarSliderStyle
= nullptr;
42 GtkStyleContext
* GtkSalGraphics::mpHScrollbarButtonStyle
= nullptr;
43 GtkStyleContext
* GtkSalGraphics::mpToolbarStyle
= nullptr;
44 GtkStyleContext
* GtkSalGraphics::mpToolButtonStyle
= nullptr;
45 GtkStyleContext
* GtkSalGraphics::mpToolbarSeparatorStyle
= nullptr;
46 GtkStyleContext
* GtkSalGraphics::mpCheckButtonStyle
= nullptr;
47 GtkStyleContext
* GtkSalGraphics::mpCheckButtonCheckStyle
= nullptr;
48 GtkStyleContext
* GtkSalGraphics::mpRadioButtonStyle
= nullptr;
49 GtkStyleContext
* GtkSalGraphics::mpRadioButtonRadioStyle
= nullptr;
50 GtkStyleContext
* GtkSalGraphics::mpSpinStyle
= nullptr;
51 GtkStyleContext
* GtkSalGraphics::mpSpinUpStyle
= nullptr;
52 GtkStyleContext
* GtkSalGraphics::mpSpinDownStyle
= nullptr;
53 GtkStyleContext
* GtkSalGraphics::mpComboboxStyle
= nullptr;
54 GtkStyleContext
* GtkSalGraphics::mpComboboxBoxStyle
= nullptr;
55 GtkStyleContext
* GtkSalGraphics::mpComboboxEntryStyle
= nullptr;
56 GtkStyleContext
* GtkSalGraphics::mpComboboxButtonStyle
= nullptr;
57 GtkStyleContext
* GtkSalGraphics::mpComboboxButtonBoxStyle
= nullptr;
58 GtkStyleContext
* GtkSalGraphics::mpComboboxButtonArrowStyle
= nullptr;
59 GtkStyleContext
* GtkSalGraphics::mpListboxStyle
= nullptr;
60 GtkStyleContext
* GtkSalGraphics::mpListboxBoxStyle
= nullptr;
61 GtkStyleContext
* GtkSalGraphics::mpListboxButtonStyle
= nullptr;
62 GtkStyleContext
* GtkSalGraphics::mpListboxButtonBoxStyle
= nullptr;
63 GtkStyleContext
* GtkSalGraphics::mpListboxButtonArrowStyle
= nullptr;
64 GtkStyleContext
* GtkSalGraphics::mpFrameInStyle
= nullptr;
65 GtkStyleContext
* GtkSalGraphics::mpFrameOutStyle
= nullptr;
66 GtkStyleContext
* GtkSalGraphics::mpFixedHoriLineStyle
= nullptr;
67 GtkStyleContext
* GtkSalGraphics::mpFixedVertLineStyle
= nullptr;
68 GtkStyleContext
* GtkSalGraphics::mpTreeHeaderButtonStyle
= nullptr;
69 GtkStyleContext
* GtkSalGraphics::mpProgressBarStyle
= nullptr;
70 GtkStyleContext
* GtkSalGraphics::mpProgressBarTroughStyle
= nullptr;
71 GtkStyleContext
* GtkSalGraphics::mpProgressBarProgressStyle
= nullptr;
72 GtkStyleContext
* GtkSalGraphics::mpNotebookStyle
= nullptr;
73 GtkStyleContext
* GtkSalGraphics::mpNotebookStackStyle
= nullptr;
74 GtkStyleContext
* GtkSalGraphics::mpNotebookHeaderStyle
= nullptr;
75 GtkStyleContext
* GtkSalGraphics::mpNotebookHeaderTabsStyle
= nullptr;
76 GtkStyleContext
* GtkSalGraphics::mpNotebookHeaderTabsTabStyle
= nullptr;
77 GtkStyleContext
* GtkSalGraphics::mpNotebookHeaderTabsTabLabelStyle
= nullptr;
78 GtkStyleContext
* GtkSalGraphics::mpNotebookHeaderTabsTabActiveLabelStyle
= nullptr;
79 GtkStyleContext
* GtkSalGraphics::mpNotebookHeaderTabsTabHoverLabelStyle
= nullptr;
80 GtkStyleContext
* GtkSalGraphics::mpMenuBarStyle
= nullptr;
81 GtkStyleContext
* GtkSalGraphics::mpMenuBarItemStyle
= nullptr;
82 GtkStyleContext
* GtkSalGraphics::mpMenuWindowStyle
= nullptr;
83 GtkStyleContext
* GtkSalGraphics::mpMenuStyle
= nullptr;
84 GtkStyleContext
* GtkSalGraphics::mpMenuItemStyle
= nullptr;
85 GtkStyleContext
* GtkSalGraphics::mpMenuItemArrowStyle
= nullptr;
86 GtkStyleContext
* GtkSalGraphics::mpMenuItemLabelStyle
= nullptr;
87 GtkStyleContext
* GtkSalGraphics::mpCheckMenuItemStyle
= nullptr;
88 GtkStyleContext
* GtkSalGraphics::mpCheckMenuItemCheckStyle
= nullptr;
89 GtkStyleContext
* GtkSalGraphics::mpRadioMenuItemStyle
= nullptr;
90 GtkStyleContext
* GtkSalGraphics::mpRadioMenuItemRadioStyle
= nullptr;
91 GtkStyleContext
* GtkSalGraphics::mpSeparatorMenuItemStyle
= nullptr;
92 GtkStyleContext
* GtkSalGraphics::mpSeparatorMenuItemSeparatorStyle
= nullptr;
94 bool GtkSalGraphics::style_loaded
= false;
95 /************************************************************************
97 ************************************************************************/
98 static GtkStateFlags
NWConvertVCLStateToGTKState(ControlState nVCLState
)
100 GtkStateFlags nGTKState
= GTK_STATE_FLAG_NORMAL
;
102 if (!( nVCLState
& ControlState::ENABLED
))
104 nGTKState
= GTK_STATE_FLAG_INSENSITIVE
;
107 if ( nVCLState
& ControlState::PRESSED
)
109 nGTKState
= static_cast<GtkStateFlags
>(nGTKState
| GTK_STATE_FLAG_ACTIVE
);
112 if ( nVCLState
& ControlState::ROLLOVER
)
114 nGTKState
= static_cast<GtkStateFlags
>(nGTKState
| GTK_STATE_FLAG_PRELIGHT
);
117 if ( nVCLState
& ControlState::SELECTED
)
118 nGTKState
= static_cast<GtkStateFlags
>(nGTKState
| GTK_STATE_FLAG_SELECTED
);
120 if ( nVCLState
& ControlState::FOCUSED
)
121 nGTKState
= static_cast<GtkStateFlags
>(nGTKState
| GTK_STATE_FLAG_FOCUSED
);
123 if (AllSettings::GetLayoutRTL())
125 nGTKState
= static_cast<GtkStateFlags
>(nGTKState
| GTK_STATE_FLAG_DIR_RTL
);
129 nGTKState
= static_cast<GtkStateFlags
>(nGTKState
| GTK_STATE_FLAG_DIR_LTR
);
137 enum class RenderType
{
138 BackgroundAndFrame
= 1,
158 static void NWCalcArrowRect( const tools::Rectangle
& rButton
, tools::Rectangle
& rArrow
)
160 // Size the arrow appropriately
161 Size
aSize( rButton
.GetWidth()/2, rButton
.GetHeight()/2 );
162 rArrow
.SetSize( aSize
);
164 rArrow
.SetPos( Point(
165 rButton
.Left() + ( rButton
.GetWidth() - rArrow
.GetWidth() ) / 2,
166 rButton
.Top() + ( rButton
.GetHeight() - rArrow
.GetHeight() ) / 2
170 tools::Rectangle
GtkSalGraphics::NWGetSpinButtonRect( ControlPart nPart
, tools::Rectangle aAreaRect
)
173 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU
, &w
, &h
);
174 gint icon_size
= std::max(w
, h
);
176 GtkBorder padding
, border
;
177 gtk_style_context_get_padding(mpSpinUpStyle
, gtk_style_context_get_state(mpSpinUpStyle
), &padding
);
178 gtk_style_context_get_border(mpSpinUpStyle
, gtk_style_context_get_state(mpSpinUpStyle
), &border
);
180 gint buttonWidth
= icon_size
+ padding
.left
+ padding
.right
+
181 border
.left
+ border
.right
;
183 gint buttonHeight
= icon_size
+ padding
.top
+ padding
.bottom
+
184 border
.top
+ border
.bottom
;
186 tools::Rectangle buttonRect
;
187 buttonRect
.SetSize(Size(buttonWidth
, buttonHeight
));
188 buttonRect
.setY(aAreaRect
.Top());
189 buttonRect
.SetBottom( buttonRect
.Top() + aAreaRect
.GetHeight() );
190 tools::Rectangle
partRect(buttonRect
);
191 if ( nPart
== ControlPart::ButtonUp
)
193 if (AllSettings::GetLayoutRTL())
194 partRect
.setX(aAreaRect
.Left());
196 partRect
.setX(aAreaRect
.Left() + (aAreaRect
.GetWidth() - buttonRect
.GetWidth()));
198 else if( nPart
== ControlPart::ButtonDown
)
200 if (AllSettings::GetLayoutRTL())
201 partRect
.setX(aAreaRect
.Left() + buttonRect
.GetWidth());
203 partRect
.setX(aAreaRect
.Left() + (aAreaRect
.GetWidth() - 2 * buttonRect
.GetWidth()));
207 if (AllSettings::GetLayoutRTL())
209 partRect
.SetRight( aAreaRect
.Left() + aAreaRect
.GetWidth() );
210 partRect
.SetLeft( aAreaRect
.Left() + (2 * buttonRect
.GetWidth()) - 1 );
214 partRect
.SetRight( (aAreaRect
.Left() + (aAreaRect
.GetWidth() - 2 * buttonRect
.GetWidth())) - 1 );
215 partRect
.SetLeft( aAreaRect
.Left() );
217 partRect
.SetTop( aAreaRect
.Top() );
218 partRect
.SetBottom( aAreaRect
.Bottom() );
226 void QuerySize(GtkStyleContext
*pContext
, Size
&rSize
)
228 GtkBorder margin
, border
, padding
;
229 GtkStateFlags stateflags
= gtk_style_context_get_state (pContext
);
231 gtk_style_context_get_margin(pContext
, stateflags
, &margin
);
232 gtk_style_context_get_border(pContext
, stateflags
, &border
);
233 gtk_style_context_get_padding(pContext
, stateflags
, &padding
);
235 int nMinWidth
, nMinHeight
;
236 gtk_style_context_get(pContext
, stateflags
,
237 "min-width", &nMinWidth
, "min-height", &nMinHeight
, nullptr);
239 nMinWidth
+= margin
.left
+ margin
.right
+ border
.left
+ border
.right
+ padding
.left
+ padding
.right
;
240 nMinHeight
+= margin
.top
+ margin
.bottom
+ border
.top
+ border
.bottom
+ padding
.top
+ padding
.bottom
;
242 rSize
= Size(std::max
<tools::Long
>(rSize
.Width(), nMinWidth
), std::max
<tools::Long
>(rSize
.Height(), nMinHeight
));
246 tools::Rectangle
GtkSalGraphics::NWGetScrollButtonRect( ControlPart nPart
, tools::Rectangle aAreaRect
)
248 tools::Rectangle buttonRect
;
250 gboolean has_forward
;
251 gboolean has_forward2
;
252 gboolean has_backward
;
253 gboolean has_backward2
;
255 GtkStyleContext
* pScrollbarStyle
= nullptr;
256 if ((nPart
== ControlPart::ButtonLeft
) || (nPart
== ControlPart::ButtonRight
))
257 pScrollbarStyle
= mpHScrollbarStyle
;
258 else // (nPart == ControlPart::ButtonUp) || (nPart == ControlPart::ButtonDown)
259 pScrollbarStyle
= mpVScrollbarStyle
;
261 gtk_style_context_get_style( pScrollbarStyle
,
262 "has-forward-stepper", &has_forward
,
263 "has-secondary-forward-stepper", &has_forward2
,
264 "has-backward-stepper", &has_backward
,
265 "has-secondary-backward-stepper", &has_backward2
, nullptr );
270 if ( has_forward
) nSecond
+= 1;
271 if ( has_forward2
) nFirst
+= 1;
272 if ( has_backward
) nFirst
+= 1;
273 if ( has_backward2
) nSecond
+= 1;
276 if (nPart
== ControlPart::ButtonLeft
|| nPart
== ControlPart::ButtonRight
)
278 QuerySize(mpHScrollbarStyle
, aSize
);
279 QuerySize(mpHScrollbarContentsStyle
, aSize
);
280 QuerySize(mpHScrollbarButtonStyle
, aSize
);
284 QuerySize(mpVScrollbarStyle
, aSize
);
285 QuerySize(mpVScrollbarContentsStyle
, aSize
);
286 QuerySize(mpVScrollbarButtonStyle
, aSize
);
289 if (nPart
== ControlPart::ButtonUp
)
291 aSize
.setHeight( aSize
.Height() * nFirst
);
292 buttonRect
.setX(aAreaRect
.Left());
293 buttonRect
.setY(aAreaRect
.Top());
295 else if (nPart
== ControlPart::ButtonLeft
)
297 aSize
.setWidth( aSize
.Width() * nFirst
);
298 buttonRect
.setX(aAreaRect
.Left());
299 buttonRect
.setY(aAreaRect
.Top());
301 else if (nPart
== ControlPart::ButtonDown
)
303 aSize
.setHeight( aSize
.Height() * nSecond
);
304 buttonRect
.setX(aAreaRect
.Left());
305 buttonRect
.setY(aAreaRect
.Top() + aAreaRect
.GetHeight() - aSize
.Height());
307 else if (nPart
== ControlPart::ButtonRight
)
309 aSize
.setWidth( aSize
.Width() * nSecond
);
310 buttonRect
.setX(aAreaRect
.Left() + aAreaRect
.GetWidth() - aSize
.Width());
311 buttonRect
.setY(aAreaRect
.Top());
314 buttonRect
.SetSize(aSize
);
319 static GtkWidget
* gCacheWindow
;
320 static GtkWidget
* gDumbContainer
;
321 static GtkWidget
* gSpinBox
;
322 static GtkWidget
* gEntryBox
;
323 static GtkWidget
* gComboBox
;
324 static GtkWidget
* gListBox
;
325 static GtkWidget
* gTreeViewWidget
;
329 void style_context_set_state(GtkStyleContext
* context
, GtkStateFlags flags
)
333 gtk_style_context_set_state(context
, flags
);
335 while ((context
= gtk_style_context_get_parent(context
)));
338 class StyleContextSave
341 std::vector
<std::pair
<GtkStyleContext
*, GtkStateFlags
>> m_aStates
;
343 void save(GtkStyleContext
* context
)
347 m_aStates
.emplace_back(context
, gtk_style_context_get_state(context
));
349 while ((context
= gtk_style_context_get_parent(context
)));
353 for (auto a
= m_aStates
.rbegin(); a
!= m_aStates
.rend(); ++a
)
355 gtk_style_context_set_state(a
->first
, a
->second
);
361 tools::Rectangle
render_common(GtkStyleContext
*pContext
, cairo_t
*cr
, const tools::Rectangle
&rIn
, GtkStateFlags flags
)
366 gtk_style_context_set_state(pContext
, flags
);
368 tools::Rectangle
aRect(rIn
);
370 gtk_style_context_get_margin(pContext
, gtk_style_context_get_state(pContext
), &margin
);
372 aRect
.AdjustLeft(margin
.left
);
373 aRect
.AdjustTop(margin
.top
);
374 aRect
.AdjustRight( -(margin
.right
) );
375 aRect
.AdjustBottom( -(margin
.bottom
) );
377 gtk_render_background(pContext
, cr
, aRect
.Left(), aRect
.Top(),
378 aRect
.GetWidth(), aRect
.GetHeight());
379 gtk_render_frame(pContext
, cr
, aRect
.Left(), aRect
.Top(),
380 aRect
.GetWidth(), aRect
.GetHeight());
382 GtkBorder border
, padding
;
383 gtk_style_context_get_border(pContext
, gtk_style_context_get_state(pContext
), &border
);
384 gtk_style_context_get_padding(pContext
, gtk_style_context_get_state(pContext
), &padding
);
386 aRect
.AdjustLeft(border
.left
+ padding
.left
);
387 aRect
.AdjustTop(border
.top
+ padding
.top
);
388 aRect
.AdjustRight( -(border
.right
+ padding
.right
) );
389 aRect
.AdjustBottom( -(border
.bottom
+ padding
.bottom
) );
395 void GtkSalGraphics::PaintScrollbar(GtkStyleContext
*context
,
397 const tools::Rectangle
& rControlRectangle
,
399 const ImplControlValue
& rValue
)
401 assert(rValue
.getType() == ControlType::Scrollbar
);
402 const ScrollbarValue
& rScrollbarVal
= static_cast<const ScrollbarValue
&>(rValue
);
403 tools::Rectangle scrollbarRect
;
404 GtkStateFlags stateFlags
;
405 GtkOrientation scrollbarOrientation
;
406 tools::Rectangle thumbRect
= rScrollbarVal
.maThumbRect
;
407 tools::Rectangle button11BoundRect
= rScrollbarVal
.maButton1Rect
; // backward
408 tools::Rectangle button22BoundRect
= rScrollbarVal
.maButton2Rect
; // forward
409 tools::Rectangle button12BoundRect
= rScrollbarVal
.maButton1Rect
; // secondary forward
410 tools::Rectangle button21BoundRect
= rScrollbarVal
.maButton2Rect
; // secondary backward
411 gdouble arrow1Angle
; // backward
412 gdouble arrow2Angle
; // forward
413 tools::Rectangle arrowRect
;
414 gint slider_width
= 0;
415 gint stepper_size
= 0;
417 // make controlvalue rectangles relative to area
418 thumbRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
419 button11BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
420 button22BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
421 button12BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
422 button21BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
424 // Find the overall bounding rect of the control
425 scrollbarRect
= rControlRectangle
;
426 if (scrollbarRect
.IsEmpty())
431 if (nPart
== ControlPart::DrawBackgroundHorz
)
433 QuerySize(mpHScrollbarStyle
, aSize
);
434 QuerySize(mpHScrollbarContentsStyle
, aSize
);
435 QuerySize(mpHScrollbarTroughStyle
, aSize
);
436 QuerySize(mpHScrollbarSliderStyle
, aSize
);
437 slider_side
= aSize
.Height();
438 gtk_style_context_get(mpHScrollbarButtonStyle
,
439 gtk_style_context_get_state(mpHScrollbarButtonStyle
),
440 "min-height", &slider_width
,
441 "min-width", &stepper_size
, nullptr);
445 QuerySize(mpVScrollbarStyle
, aSize
);
446 QuerySize(mpVScrollbarContentsStyle
, aSize
);
447 QuerySize(mpVScrollbarTroughStyle
, aSize
);
448 QuerySize(mpVScrollbarSliderStyle
, aSize
);
449 slider_side
= aSize
.Width();
450 gtk_style_context_get(mpVScrollbarButtonStyle
,
451 gtk_style_context_get_state(mpVScrollbarButtonStyle
),
452 "min-width", &slider_width
,
453 "min-height", &stepper_size
, nullptr);
456 gboolean has_forward
;
457 gboolean has_forward2
;
458 gboolean has_backward
;
459 gboolean has_backward2
;
461 gtk_style_context_get_style( context
,
462 "has-forward-stepper", &has_forward
,
463 "has-secondary-forward-stepper", &has_forward2
,
464 "has-backward-stepper", &has_backward
,
465 "has-secondary-backward-stepper", &has_backward2
, nullptr );
467 if ( nPart
== ControlPart::DrawBackgroundHorz
)
469 // Center vertically in the track
470 scrollbarRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_side
) / 2 );
471 scrollbarRect
.SetSize( Size( scrollbarRect
.GetWidth(), slider_side
) );
472 thumbRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_side
) / 2 );
473 thumbRect
.SetSize( Size( thumbRect
.GetWidth(), slider_side
) );
475 scrollbarOrientation
= GTK_ORIENTATION_HORIZONTAL
;
476 arrow1Angle
= G_PI
* 3 / 2;
477 arrow2Angle
= G_PI
/ 2;
481 button12BoundRect
.Move( stepper_size
,
482 (scrollbarRect
.GetHeight() - slider_width
) / 2 );
485 button11BoundRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
486 button11BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
487 button12BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
491 button22BoundRect
.Move( stepper_size
, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
492 button21BoundRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
496 button22BoundRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
499 button21BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
500 button22BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
504 // Center horizontally in the track
505 scrollbarRect
.Move( (scrollbarRect
.GetWidth() - slider_side
) / 2, 0 );
506 scrollbarRect
.SetSize( Size( slider_side
, scrollbarRect
.GetHeight() ) );
507 thumbRect
.Move( (scrollbarRect
.GetWidth() - slider_side
) / 2, 0 );
508 thumbRect
.SetSize( Size( slider_side
, thumbRect
.GetHeight() ) );
510 scrollbarOrientation
= GTK_ORIENTATION_VERTICAL
;
516 button12BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2,
519 button11BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, 0 );
520 button11BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
521 button12BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
525 button22BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, stepper_size
);
526 button21BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, 0 );
530 button22BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, 0 );
533 button21BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
534 button22BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
537 bool has_slider
= !thumbRect
.IsEmpty();
539 // ----------------- CONTENTS
540 GtkStyleContext
* pScrollbarContentsStyle
= scrollbarOrientation
== GTK_ORIENTATION_VERTICAL
?
541 mpVScrollbarContentsStyle
: mpHScrollbarContentsStyle
;
543 gtk_render_background(gtk_widget_get_style_context(gCacheWindow
), cr
, 0, 0,
544 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
546 gtk_render_background(context
, cr
, 0, 0,
547 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
548 gtk_render_frame(context
, cr
, 0, 0,
549 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
551 gtk_render_background(pScrollbarContentsStyle
, cr
, 0, 0,
552 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
553 gtk_render_frame(pScrollbarContentsStyle
, cr
, 0, 0,
554 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
556 bool backwardButtonInsensitive
=
557 rScrollbarVal
.mnCur
== rScrollbarVal
.mnMin
;
558 bool forwardButtonInsensitive
= rScrollbarVal
.mnMax
== 0 ||
559 rScrollbarVal
.mnCur
+ rScrollbarVal
.mnVisibleSize
>= rScrollbarVal
.mnMax
;
561 // ----------------- BUTTON 1
564 stateFlags
= NWConvertVCLStateToGTKState(rScrollbarVal
.mnButton1State
);
565 if ( backwardButtonInsensitive
)
566 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
568 GtkStyleContext
* pScrollbarButtonStyle
= scrollbarOrientation
== GTK_ORIENTATION_VERTICAL
?
569 mpVScrollbarButtonStyle
: mpHScrollbarButtonStyle
;
571 gtk_style_context_set_state(pScrollbarButtonStyle
, stateFlags
);
573 gtk_render_background(pScrollbarButtonStyle
, cr
,
574 button11BoundRect
.Left(), button11BoundRect
.Top(),
575 button11BoundRect
.GetWidth(), button11BoundRect
.GetHeight() );
576 gtk_render_frame(pScrollbarButtonStyle
, cr
,
577 button11BoundRect
.Left(), button11BoundRect
.Top(),
578 button11BoundRect
.GetWidth(), button11BoundRect
.GetHeight() );
580 // ----------------- ARROW 1
581 NWCalcArrowRect( button11BoundRect
, arrowRect
);
582 gtk_render_arrow(pScrollbarButtonStyle
, cr
,
584 arrowRect
.Left(), arrowRect
.Top(),
585 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
589 stateFlags
= NWConvertVCLStateToGTKState(rScrollbarVal
.mnButton2State
);
590 if ( forwardButtonInsensitive
)
591 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
593 GtkStyleContext
* pScrollbarButtonStyle
= scrollbarOrientation
== GTK_ORIENTATION_VERTICAL
?
594 mpVScrollbarButtonStyle
: mpHScrollbarButtonStyle
;
596 gtk_style_context_set_state(pScrollbarButtonStyle
, stateFlags
);
598 gtk_render_background(pScrollbarButtonStyle
, cr
,
599 button12BoundRect
.Left(), button12BoundRect
.Top(),
600 button12BoundRect
.GetWidth(), button12BoundRect
.GetHeight() );
601 gtk_render_frame(pScrollbarButtonStyle
, cr
,
602 button12BoundRect
.Left(), button12BoundRect
.Top(),
603 button12BoundRect
.GetWidth(), button12BoundRect
.GetHeight() );
605 // ----------------- ARROW 1
606 NWCalcArrowRect( button12BoundRect
, arrowRect
);
607 gtk_render_arrow(pScrollbarButtonStyle
, cr
,
609 arrowRect
.Left(), arrowRect
.Top(),
610 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
612 // ----------------- BUTTON 2
616 stateFlags
= NWConvertVCLStateToGTKState(rScrollbarVal
.mnButton2State
);
617 if ( forwardButtonInsensitive
)
618 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
620 GtkStyleContext
* pScrollbarButtonStyle
= scrollbarOrientation
== GTK_ORIENTATION_VERTICAL
?
621 mpVScrollbarButtonStyle
: mpHScrollbarButtonStyle
;
623 gtk_style_context_set_state(pScrollbarButtonStyle
, stateFlags
);
625 gtk_render_background(pScrollbarButtonStyle
, cr
,
626 button22BoundRect
.Left(), button22BoundRect
.Top(),
627 button22BoundRect
.GetWidth(), button22BoundRect
.GetHeight() );
628 gtk_render_frame(pScrollbarButtonStyle
, cr
,
629 button22BoundRect
.Left(), button22BoundRect
.Top(),
630 button22BoundRect
.GetWidth(), button22BoundRect
.GetHeight() );
632 // ----------------- ARROW 2
633 NWCalcArrowRect( button22BoundRect
, arrowRect
);
634 gtk_render_arrow(pScrollbarButtonStyle
, cr
,
636 arrowRect
.Left(), arrowRect
.Top(),
637 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
642 stateFlags
= NWConvertVCLStateToGTKState(rScrollbarVal
.mnButton1State
);
643 if ( backwardButtonInsensitive
)
644 stateFlags
= GTK_STATE_FLAG_INSENSITIVE
;
646 GtkStyleContext
* pScrollbarButtonStyle
= scrollbarOrientation
== GTK_ORIENTATION_VERTICAL
?
647 mpVScrollbarButtonStyle
: mpHScrollbarButtonStyle
;
649 gtk_style_context_set_state(pScrollbarButtonStyle
, stateFlags
);
651 gtk_render_background(pScrollbarButtonStyle
, cr
,
652 button21BoundRect
.Left(), button21BoundRect
.Top(),
653 button21BoundRect
.GetWidth(), button21BoundRect
.GetHeight() );
654 gtk_render_frame(pScrollbarButtonStyle
, cr
,
655 button21BoundRect
.Left(), button21BoundRect
.Top(),
656 button21BoundRect
.GetWidth(), button21BoundRect
.GetHeight() );
658 // ----------------- ARROW 2
659 NWCalcArrowRect( button21BoundRect
, arrowRect
);
660 gtk_render_arrow(pScrollbarButtonStyle
, cr
,
662 arrowRect
.Left(), arrowRect
.Top(),
663 MIN(arrowRect
.GetWidth(), arrowRect
.GetHeight()) );
666 // ----------------- TROUGH
667 // trackrect matches that of ScrollBar::ImplCalc
668 tools::Rectangle
aTrackRect(Point(0, 0), scrollbarRect
.GetSize());
669 if (nPart
== ControlPart::DrawBackgroundHorz
)
671 tools::Rectangle aBtn1Rect
= NWGetScrollButtonRect(ControlPart::ButtonLeft
, aTrackRect
);
672 tools::Rectangle aBtn2Rect
= NWGetScrollButtonRect(ControlPart::ButtonRight
, aTrackRect
);
673 if (!aBtn1Rect
.IsWidthEmpty())
674 aTrackRect
.SetLeft( aBtn1Rect
.Right() );
675 if (!aBtn2Rect
.IsWidthEmpty())
676 aTrackRect
.SetRight( aBtn2Rect
.Left() );
680 tools::Rectangle aBtn1Rect
= NWGetScrollButtonRect(ControlPart::ButtonUp
, aTrackRect
);
681 tools::Rectangle aBtn2Rect
= NWGetScrollButtonRect(ControlPart::ButtonDown
, aTrackRect
);
682 if (!aBtn1Rect
.IsHeightEmpty())
683 aTrackRect
.SetTop( aBtn1Rect
.Bottom() + 1 );
684 if (!aBtn2Rect
.IsHeightEmpty())
685 aTrackRect
.SetBottom( aBtn2Rect
.Top() );
688 GtkStyleContext
* pScrollbarTroughStyle
= scrollbarOrientation
== GTK_ORIENTATION_VERTICAL
?
689 mpVScrollbarTroughStyle
: mpHScrollbarTroughStyle
;
690 gtk_render_background(pScrollbarTroughStyle
, cr
, aTrackRect
.Left(), aTrackRect
.Top(),
691 aTrackRect
.GetWidth(), aTrackRect
.GetHeight() );
692 gtk_render_frame(pScrollbarTroughStyle
, cr
, aTrackRect
.Left(), aTrackRect
.Top(),
693 aTrackRect
.GetWidth(), aTrackRect
.GetHeight() );
695 // ----------------- THUMB
698 stateFlags
= NWConvertVCLStateToGTKState(rScrollbarVal
.mnThumbState
);
699 if ( rScrollbarVal
.mnThumbState
& ControlState::PRESSED
)
700 stateFlags
= static_cast<GtkStateFlags
>(stateFlags
| GTK_STATE_FLAG_PRELIGHT
);
702 GtkStyleContext
* pScrollbarSliderStyle
= scrollbarOrientation
== GTK_ORIENTATION_VERTICAL
?
703 mpVScrollbarSliderStyle
: mpHScrollbarSliderStyle
;
705 gtk_style_context_set_state(pScrollbarSliderStyle
, stateFlags
);
708 gtk_style_context_get_margin(pScrollbarSliderStyle
, stateFlags
, &margin
);
710 gtk_render_background(pScrollbarSliderStyle
, cr
,
711 thumbRect
.Left() + margin
.left
, thumbRect
.Top() + margin
.top
,
712 thumbRect
.GetWidth() - margin
.left
- margin
.right
,
713 thumbRect
.GetHeight() - margin
.top
- margin
.bottom
);
715 gtk_render_frame(pScrollbarSliderStyle
, cr
,
716 thumbRect
.Left() + margin
.left
, thumbRect
.Top() + margin
.top
,
717 thumbRect
.GetWidth() - margin
.left
- margin
.right
,
718 thumbRect
.GetHeight() - margin
.top
- margin
.bottom
);
722 void GtkSalGraphics::PaintOneSpinButton( GtkStyleContext
*context
,
725 tools::Rectangle aAreaRect
,
726 ControlState nState
)
728 GtkBorder padding
, border
;
730 GtkStateFlags stateFlags
= NWConvertVCLStateToGTKState(nState
);
731 tools::Rectangle buttonRect
= NWGetSpinButtonRect( nPart
, aAreaRect
);
733 gtk_style_context_set_state(context
, stateFlags
);
734 stateFlags
= gtk_style_context_get_state(context
);
736 gtk_style_context_get_padding(context
, stateFlags
, &padding
);
737 gtk_style_context_get_border(context
, stateFlags
, &border
);
739 gtk_render_background(context
, cr
,
740 buttonRect
.Left(), buttonRect
.Top(),
741 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
743 gint iconWidth
= buttonRect
.GetWidth() - padding
.left
- padding
.right
- border
.left
- border
.right
;
744 gint iconHeight
= buttonRect
.GetHeight() - padding
.top
- padding
.bottom
- border
.top
- border
.bottom
;
746 const char* icon
= (nPart
== ControlPart::ButtonUp
) ? "list-add-symbolic" : "list-remove-symbolic";
747 GtkIconTheme
*pIconTheme
= gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow
));
749 gint scale
= gtk_style_context_get_scale (context
);
750 GtkIconInfo
*info
= gtk_icon_theme_lookup_icon_for_scale(pIconTheme
, icon
, std::min(iconWidth
, iconHeight
), scale
,
751 static_cast<GtkIconLookupFlags
>(0));
753 GdkPixbuf
*pixbuf
= gtk_icon_info_load_symbolic_for_context(info
, context
, nullptr, nullptr);
754 g_object_unref(info
);
756 iconWidth
= gdk_pixbuf_get_width(pixbuf
)/scale
;
757 iconHeight
= gdk_pixbuf_get_height(pixbuf
)/scale
;
758 tools::Rectangle arrowRect
;
759 arrowRect
.SetSize(Size(iconWidth
, iconHeight
));
760 arrowRect
.setX( buttonRect
.Left() + (buttonRect
.GetWidth() - arrowRect
.GetWidth()) / 2 );
761 arrowRect
.setY( buttonRect
.Top() + (buttonRect
.GetHeight() - arrowRect
.GetHeight()) / 2 );
763 gtk_style_context_save (context
);
764 gtk_style_context_set_scale (context
, 1);
765 gtk_render_icon(context
, cr
, pixbuf
, arrowRect
.Left(), arrowRect
.Top());
766 gtk_style_context_restore (context
);
767 g_object_unref(pixbuf
);
769 gtk_render_frame(context
, cr
,
770 buttonRect
.Left(), buttonRect
.Top(),
771 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
774 void GtkSalGraphics::PaintSpinButton(GtkStateFlags flags
,
776 const tools::Rectangle
& rControlRectangle
,
778 const ImplControlValue
& rValue
)
780 const SpinbuttonValue
*pSpinVal
= (rValue
.getType() == ControlType::SpinButtons
) ? static_cast<const SpinbuttonValue
*>(&rValue
) : nullptr;
781 ControlPart upBtnPart
= ControlPart::ButtonUp
;
782 ControlState upBtnState
= ControlState::NONE
;
783 ControlPart downBtnPart
= ControlPart::ButtonDown
;
784 ControlState downBtnState
= ControlState::NONE
;
788 upBtnPart
= pSpinVal
->mnUpperPart
;
789 upBtnState
= pSpinVal
->mnUpperState
;
791 downBtnPart
= pSpinVal
->mnLowerPart
;
792 downBtnState
= pSpinVal
->mnLowerState
;
795 if (nPart
== ControlPart::Entire
)
797 gtk_style_context_set_state(mpWindowStyle
, flags
);
799 gtk_render_background(mpWindowStyle
, cr
,
801 rControlRectangle
.GetWidth(), rControlRectangle
.GetHeight());
803 gtk_style_context_set_state(mpSpinStyle
, flags
);
805 gtk_render_background(mpSpinStyle
, cr
,
807 rControlRectangle
.GetWidth(), rControlRectangle
.GetHeight());
810 cairo_translate(cr
, -rControlRectangle
.Left(), -rControlRectangle
.Top());
811 PaintOneSpinButton(mpSpinUpStyle
, cr
, upBtnPart
, rControlRectangle
, upBtnState
);
812 PaintOneSpinButton(mpSpinDownStyle
, cr
, downBtnPart
, rControlRectangle
, downBtnState
);
813 cairo_translate(cr
, rControlRectangle
.Left(), rControlRectangle
.Top());
815 if (nPart
== ControlPart::Entire
)
817 gtk_render_frame(mpSpinStyle
, cr
,
819 rControlRectangle
.GetWidth(), rControlRectangle
.GetHeight() );
823 #define FALLBACK_ARROW_SIZE gint(11 * 0.85)
825 tools::Rectangle
GtkSalGraphics::NWGetComboBoxButtonRect(ControlType nType
,
827 tools::Rectangle aAreaRect
)
829 tools::Rectangle aButtonRect
;
832 if (nType
== ControlType::Listbox
)
833 gtk_style_context_get_padding(mpListboxButtonStyle
, gtk_style_context_get_state(mpListboxButtonStyle
), &padding
);
835 gtk_style_context_get_padding(mpButtonStyle
, gtk_style_context_get_state(mpButtonStyle
), &padding
);
837 gint nArrowWidth
= FALLBACK_ARROW_SIZE
;
838 gtk_style_context_get(mpComboboxButtonArrowStyle
,
839 gtk_style_context_get_state(mpComboboxButtonArrowStyle
),
840 "min-width", &nArrowWidth
, nullptr);
842 gint nButtonWidth
= nArrowWidth
+ padding
.left
+ padding
.right
;
843 if( nPart
== ControlPart::ButtonDown
)
845 Point
aPos(aAreaRect
.Left() + aAreaRect
.GetWidth() - nButtonWidth
, aAreaRect
.Top());
846 if (AllSettings::GetLayoutRTL())
847 aPos
.setX( aAreaRect
.Left() );
848 aButtonRect
.SetSize( Size( nButtonWidth
, aAreaRect
.GetHeight() ) );
849 aButtonRect
.SetPos(aPos
);
851 else if( nPart
== ControlPart::SubEdit
)
853 gint adjust_left
= padding
.left
;
854 gint adjust_top
= padding
.top
;
855 gint adjust_right
= padding
.right
;
856 gint adjust_bottom
= padding
.bottom
;
858 aButtonRect
.SetSize( Size( aAreaRect
.GetWidth() - nButtonWidth
- (adjust_left
+ adjust_right
),
859 aAreaRect
.GetHeight() - (adjust_top
+ adjust_bottom
)) );
860 Point aEditPos
= aAreaRect
.TopLeft();
861 if (AllSettings::GetLayoutRTL())
862 aEditPos
.AdjustX(nButtonWidth
);
864 aEditPos
.AdjustX(adjust_left
);
865 aEditPos
.AdjustY(adjust_top
);
866 aButtonRect
.SetPos( aEditPos
);
872 void GtkSalGraphics::PaintCombobox( GtkStateFlags flags
, cairo_t
*cr
,
873 const tools::Rectangle
& rControlRectangle
,
877 tools::Rectangle areaRect
;
878 tools::Rectangle buttonRect
;
879 tools::Rectangle arrowRect
;
881 // Find the overall bounding rect of the buttons's drawing area,
882 // plus its actual draw rect excluding adornment
883 areaRect
= rControlRectangle
;
885 buttonRect
= NWGetComboBoxButtonRect(ControlType::Combobox
, ControlPart::ButtonDown
, areaRect
);
887 tools::Rectangle
aEditBoxRect( areaRect
);
888 aEditBoxRect
.SetSize( Size( areaRect
.GetWidth() - buttonRect
.GetWidth(), aEditBoxRect
.GetHeight() ) );
889 if (AllSettings::GetLayoutRTL())
890 aEditBoxRect
.SetPos( Point( areaRect
.Left() + buttonRect
.GetWidth(), areaRect
.Top() ) );
892 gint arrow_width
= FALLBACK_ARROW_SIZE
, arrow_height
= FALLBACK_ARROW_SIZE
;
893 if (nType
== ControlType::Combobox
)
895 gtk_style_context_get(mpComboboxButtonArrowStyle
,
896 gtk_style_context_get_state(mpComboboxButtonArrowStyle
),
897 "min-width", &arrow_width
, "min-height", &arrow_height
, nullptr);
899 else if (nType
== ControlType::Listbox
)
901 gtk_style_context_get(mpListboxButtonArrowStyle
,
902 gtk_style_context_get_state(mpListboxButtonArrowStyle
),
903 "min-width", &arrow_width
, "min-height", &arrow_height
, nullptr);
906 arrowRect
.SetSize(Size(arrow_width
, arrow_height
));
907 arrowRect
.SetPos( Point( buttonRect
.Left() + static_cast<gint
>((buttonRect
.GetWidth() - arrowRect
.GetWidth()) / 2),
908 buttonRect
.Top() + static_cast<gint
>((buttonRect
.GetHeight() - arrowRect
.GetHeight()) / 2) ) );
911 tools::Rectangle
aRect(Point(0, 0), Size(areaRect
.GetWidth(), areaRect
.GetHeight()));
913 if (nType
== ControlType::Combobox
)
915 if( nPart
== ControlPart::Entire
)
917 render_common(mpComboboxStyle
, cr
, aRect
, flags
);
918 render_common(mpComboboxBoxStyle
, cr
, aRect
, flags
);
919 tools::Rectangle
aEntryRect(Point(aEditBoxRect
.Left() - areaRect
.Left(),
920 aEditBoxRect
.Top() - areaRect
.Top()),
921 Size(aEditBoxRect
.GetWidth(), aEditBoxRect
.GetHeight()));
923 GtkJunctionSides eJuncSides
= gtk_style_context_get_junction_sides(mpComboboxEntryStyle
);
924 if (AllSettings::GetLayoutRTL())
925 gtk_style_context_set_junction_sides(mpComboboxEntryStyle
, GTK_JUNCTION_LEFT
);
927 gtk_style_context_set_junction_sides(mpComboboxEntryStyle
, GTK_JUNCTION_RIGHT
);
928 render_common(mpComboboxEntryStyle
, cr
, aEntryRect
, flags
);
929 gtk_style_context_set_junction_sides(mpComboboxEntryStyle
, eJuncSides
);
932 tools::Rectangle
aButtonRect(Point(buttonRect
.Left() - areaRect
.Left(), buttonRect
.Top() - areaRect
.Top()),
933 Size(buttonRect
.GetWidth(), buttonRect
.GetHeight()));
934 GtkJunctionSides eJuncSides
= gtk_style_context_get_junction_sides(mpComboboxButtonStyle
);
935 if (AllSettings::GetLayoutRTL())
936 gtk_style_context_set_junction_sides(mpComboboxButtonStyle
, GTK_JUNCTION_RIGHT
);
938 gtk_style_context_set_junction_sides(mpComboboxButtonStyle
, GTK_JUNCTION_LEFT
);
939 render_common(mpComboboxButtonStyle
, cr
, aButtonRect
, flags
);
940 gtk_style_context_set_junction_sides(mpComboboxButtonStyle
, eJuncSides
);
942 gtk_render_arrow(mpComboboxButtonArrowStyle
, cr
,
944 (arrowRect
.Left() - areaRect
.Left()), (arrowRect
.Top() - areaRect
.Top()),
945 arrowRect
.GetWidth() );
947 else if (nType
== ControlType::Listbox
)
949 if( nPart
== ControlPart::ListboxWindow
)
951 /* render the popup window with the menu style */
952 gtk_render_frame(mpMenuStyle
, cr
,
954 areaRect
.GetWidth(), areaRect
.GetHeight());
958 render_common(mpListboxStyle
, cr
, aRect
, flags
);
959 render_common(mpListboxBoxStyle
, cr
, aRect
, flags
);
961 render_common(mpListboxButtonStyle
, cr
, aRect
, flags
);
963 gtk_render_arrow(mpListboxButtonArrowStyle
, cr
,
965 (arrowRect
.Left() - areaRect
.Left()), (arrowRect
.Top() - areaRect
.Top()),
966 arrowRect
.GetWidth() );
971 static void appendComboEntry(GtkWidgetPath
* pSiblingsPath
)
973 gtk_widget_path_append_type(pSiblingsPath
, GTK_TYPE_ENTRY
);
974 gtk_widget_path_iter_set_object_name(pSiblingsPath
, -1, "entry");
975 gtk_widget_path_iter_add_class(pSiblingsPath
, -1, "combo");
978 static void appendComboButton(GtkWidgetPath
* pSiblingsPath
)
980 gtk_widget_path_append_type(pSiblingsPath
, GTK_TYPE_BUTTON
);
981 gtk_widget_path_iter_set_object_name(pSiblingsPath
, -1, "button");
982 gtk_widget_path_iter_add_class(pSiblingsPath
, -1, "combo");
985 static GtkWidgetPath
* buildLTRComboSiblingsPath()
987 GtkWidgetPath
* pSiblingsPath
= gtk_widget_path_new();
989 appendComboEntry(pSiblingsPath
);
990 appendComboButton(pSiblingsPath
);
992 return pSiblingsPath
;
995 static GtkWidgetPath
* buildRTLComboSiblingsPath()
997 GtkWidgetPath
* pSiblingsPath
= gtk_widget_path_new();
999 appendComboButton(pSiblingsPath
);
1000 appendComboEntry(pSiblingsPath
);
1002 return pSiblingsPath
;
1005 GtkStyleContext
* GtkSalGraphics::makeContext(GtkWidgetPath
*pPath
, GtkStyleContext
*pParent
)
1007 GtkStyleContext
* context
= gtk_style_context_new();
1008 gtk_style_context_set_screen(context
, gtk_widget_get_screen(mpWindow
));
1009 gtk_style_context_set_path(context
, pPath
);
1010 if (pParent
== nullptr)
1012 GtkWidget
* pTopLevel
= gtk_widget_get_toplevel(mpWindow
);
1013 GtkStyleContext
* pStyle
= gtk_widget_get_style_context(pTopLevel
);
1014 gtk_style_context_set_parent(context
, pStyle
);
1015 gtk_style_context_set_scale (context
, gtk_style_context_get_scale (pStyle
));
1019 gtk_style_context_set_parent(context
, pParent
);
1020 gtk_style_context_set_scale (context
, gtk_style_context_get_scale (pParent
));
1022 gtk_widget_path_unref(pPath
);
1026 GtkStyleContext
* GtkSalGraphics::createStyleContext(GtkControlPart ePart
)
1030 case GtkControlPart::ToplevelWindow
:
1032 GtkWidgetPath
*path
= gtk_widget_path_new();
1033 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1034 gtk_widget_path_iter_set_object_name(path
, -1, "window");
1035 gtk_widget_path_iter_add_class(path
, -1, "background");
1036 return makeContext(path
, nullptr);
1038 case GtkControlPart::Button
:
1040 GtkWidgetPath
*path
= gtk_widget_path_new();
1041 gtk_widget_path_append_type(path
, GTK_TYPE_BUTTON
);
1042 gtk_widget_path_iter_set_object_name(path
, -1, "button");
1043 return makeContext(path
, nullptr);
1045 case GtkControlPart::LinkButton
:
1047 GtkWidgetPath
*path
= gtk_widget_path_new();
1048 gtk_widget_path_append_type(path
, GTK_TYPE_BUTTON
);
1049 gtk_widget_path_iter_set_object_name(path
, -1, "button");
1050 gtk_widget_path_iter_add_class(path
, -1, "link");
1051 return makeContext(path
, nullptr);
1053 case GtkControlPart::CheckButton
:
1055 GtkWidgetPath
*path
= gtk_widget_path_new();
1056 gtk_widget_path_append_type(path
, GTK_TYPE_CHECK_BUTTON
);
1057 gtk_widget_path_iter_set_object_name(path
, -1, "checkbutton");
1058 return makeContext(path
, nullptr);
1060 case GtkControlPart::CheckButtonCheck
:
1062 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpCheckButtonStyle
));
1063 gtk_widget_path_append_type(path
, GTK_TYPE_CHECK_BUTTON
);
1064 gtk_widget_path_iter_set_object_name(path
, -1, "check");
1065 return makeContext(path
, mpCheckButtonStyle
);
1067 case GtkControlPart::RadioButton
:
1069 GtkWidgetPath
*path
= gtk_widget_path_new();
1070 gtk_widget_path_append_type(path
, GTK_TYPE_RADIO_BUTTON
);
1071 gtk_widget_path_iter_set_object_name(path
, -1, "radiobutton");
1072 return makeContext(path
, nullptr);
1074 case GtkControlPart::RadioButtonRadio
:
1076 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpRadioButtonStyle
));
1077 gtk_widget_path_append_type(path
, GTK_TYPE_RADIO_BUTTON
);
1078 gtk_widget_path_iter_set_object_name(path
, -1, "radio");
1079 return makeContext(path
, mpRadioButtonStyle
);
1081 case GtkControlPart::ComboboxBoxButtonBoxArrow
:
1083 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonBoxStyle
));
1084 gtk_widget_path_append_type(path
, GTK_TYPE_RADIO_BUTTON
);
1085 gtk_widget_path_append_type(path
, GTK_TYPE_BUTTON
);
1086 gtk_widget_path_iter_set_object_name(path
, -1, "arrow");
1087 return makeContext(path
, mpComboboxButtonBoxStyle
);
1089 case GtkControlPart::ListboxBoxButtonBoxArrow
:
1091 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonBoxStyle
));
1092 gtk_widget_path_append_type(path
, GTK_TYPE_RADIO_BUTTON
);
1093 gtk_widget_path_append_type(path
, GTK_TYPE_BUTTON
);
1094 gtk_widget_path_iter_set_object_name(path
, -1, "arrow");
1095 return makeContext(path
, mpListboxButtonBoxStyle
);
1097 case GtkControlPart::Entry
:
1099 GtkWidgetPath
*path
= gtk_widget_path_new();
1100 gtk_widget_path_append_type(path
, GTK_TYPE_ENTRY
);
1101 gtk_widget_path_iter_set_object_name(path
, -1, "entry");
1102 return makeContext(path
, nullptr);
1104 case GtkControlPart::Combobox
:
1105 case GtkControlPart::Listbox
:
1107 GtkWidgetPath
*path
= gtk_widget_path_new();
1108 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1109 gtk_widget_path_iter_set_object_name(path
, -1, "combobox");
1110 return makeContext(path
, nullptr);
1112 case GtkControlPart::ComboboxBox
:
1114 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxStyle
));
1115 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1116 gtk_widget_path_iter_set_object_name(path
, -1, "box");
1117 gtk_widget_path_iter_add_class(path
, -1, "horizontal");
1118 gtk_widget_path_iter_add_class(path
, -1, "linked");
1119 return makeContext(path
, mpComboboxStyle
);
1121 case GtkControlPart::ListboxBox
:
1123 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpListboxStyle
));
1124 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1125 gtk_widget_path_iter_set_object_name(path
, -1, "box");
1126 gtk_widget_path_iter_add_class(path
, -1, "horizontal");
1127 gtk_widget_path_iter_add_class(path
, -1, "linked");
1128 return makeContext(path
, mpListboxStyle
);
1130 case GtkControlPart::ComboboxBoxEntry
:
1132 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle
));
1133 GtkWidgetPath
* pSiblingsPath
;
1134 if (AllSettings::GetLayoutRTL())
1136 pSiblingsPath
= buildRTLComboSiblingsPath();
1137 gtk_widget_path_append_with_siblings(path
, pSiblingsPath
, 1);
1141 pSiblingsPath
= buildLTRComboSiblingsPath();
1142 gtk_widget_path_append_with_siblings(path
, pSiblingsPath
, 0);
1144 gtk_widget_path_unref(pSiblingsPath
);
1145 return makeContext(path
, mpComboboxBoxStyle
);
1147 case GtkControlPart::ComboboxBoxButton
:
1149 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle
));
1150 GtkWidgetPath
* pSiblingsPath
;
1151 if (AllSettings::GetLayoutRTL())
1153 pSiblingsPath
= buildRTLComboSiblingsPath();
1154 gtk_widget_path_append_with_siblings(path
, pSiblingsPath
, 0);
1158 pSiblingsPath
= buildLTRComboSiblingsPath();
1159 gtk_widget_path_append_with_siblings(path
, pSiblingsPath
, 1);
1161 gtk_widget_path_unref(pSiblingsPath
);
1162 return makeContext(path
, mpComboboxBoxStyle
);
1164 case GtkControlPart::ListboxBoxButton
:
1166 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpListboxBoxStyle
));
1167 GtkWidgetPath
* pSiblingsPath
= gtk_widget_path_new();
1169 gtk_widget_path_append_type(pSiblingsPath
, GTK_TYPE_BUTTON
);
1170 gtk_widget_path_iter_set_object_name(pSiblingsPath
, -1, "button");
1171 gtk_widget_path_iter_add_class(pSiblingsPath
, -1, "combo");
1173 gtk_widget_path_append_with_siblings(path
, pSiblingsPath
, 0);
1174 gtk_widget_path_unref(pSiblingsPath
);
1175 return makeContext(path
, mpListboxBoxStyle
);
1177 case GtkControlPart::ComboboxBoxButtonBox
:
1179 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonStyle
));
1180 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1181 gtk_widget_path_iter_set_object_name(path
, -1, "box");
1182 gtk_widget_path_iter_add_class(path
, -1, "horizontal");
1183 return makeContext(path
, mpComboboxButtonStyle
);
1185 case GtkControlPart::ListboxBoxButtonBox
:
1187 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonStyle
));
1188 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1189 gtk_widget_path_iter_set_object_name(path
, -1, "box");
1190 gtk_widget_path_iter_add_class(path
, -1, "horizontal");
1191 return makeContext(path
, mpListboxButtonStyle
);
1193 case GtkControlPart::SpinButton
:
1195 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle
));
1196 gtk_widget_path_append_type(path
, GTK_TYPE_SPIN_BUTTON
);
1197 gtk_widget_path_iter_set_object_name(path
, -1, "spinbutton");
1198 gtk_widget_path_iter_add_class(path
, -1, GTK_STYLE_CLASS_HORIZONTAL
);
1199 return makeContext(path
, mpWindowStyle
);
1201 case GtkControlPart::SpinButtonUpButton
:
1202 case GtkControlPart::SpinButtonDownButton
:
1204 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle
));
1205 gtk_widget_path_append_type(path
, GTK_TYPE_SPIN_BUTTON
);
1206 gtk_widget_path_iter_set_object_name(path
, -1, "button");
1207 gtk_widget_path_iter_add_class(path
, -1, ePart
== GtkControlPart::SpinButtonUpButton
? "up" : "down");
1208 return makeContext(path
, mpSpinStyle
);
1210 case GtkControlPart::ScrollbarVertical
:
1211 case GtkControlPart::ScrollbarHorizontal
:
1213 GtkWidgetPath
*path
= gtk_widget_path_new();
1214 gtk_widget_path_append_type(path
, GTK_TYPE_SCROLLBAR
);
1215 gtk_widget_path_iter_set_object_name(path
, -1, "scrollbar");
1216 gtk_widget_path_iter_add_class(path
, -1, ePart
== GtkControlPart::ScrollbarVertical
? "vertical" : "horizontal");
1217 return makeContext(path
, nullptr);
1219 case GtkControlPart::ScrollbarVerticalContents
:
1220 case GtkControlPart::ScrollbarHorizontalContents
:
1222 GtkStyleContext
*pParent
=
1223 (ePart
== GtkControlPart::ScrollbarVerticalContents
) ? mpVScrollbarStyle
: mpHScrollbarStyle
;
1224 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(pParent
));
1225 gtk_widget_path_append_type(path
, GTK_TYPE_SCROLLBAR
);
1226 gtk_widget_path_iter_set_object_name(path
, -1, "contents");
1227 return makeContext(path
, pParent
);
1229 case GtkControlPart::ScrollbarVerticalTrough
:
1230 case GtkControlPart::ScrollbarHorizontalTrough
:
1232 GtkStyleContext
*pParent
=
1233 (ePart
== GtkControlPart::ScrollbarVerticalTrough
) ? mpVScrollbarContentsStyle
: mpHScrollbarContentsStyle
;
1234 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(pParent
));
1235 gtk_widget_path_append_type(path
, GTK_TYPE_SCROLLBAR
);
1236 gtk_widget_path_iter_set_object_name(path
, -1, "trough");
1237 return makeContext(path
, pParent
);
1239 case GtkControlPart::ScrollbarVerticalSlider
:
1240 case GtkControlPart::ScrollbarHorizontalSlider
:
1242 GtkStyleContext
*pParent
=
1243 (ePart
== GtkControlPart::ScrollbarVerticalSlider
) ? mpVScrollbarTroughStyle
: mpHScrollbarTroughStyle
;
1244 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(pParent
));
1245 gtk_widget_path_append_type(path
, GTK_TYPE_SCROLLBAR
);
1246 gtk_widget_path_iter_set_object_name(path
, -1, "slider");
1247 return makeContext(path
, pParent
);
1249 case GtkControlPart::ScrollbarVerticalButton
:
1250 case GtkControlPart::ScrollbarHorizontalButton
:
1252 GtkStyleContext
*pParent
=
1253 (ePart
== GtkControlPart::ScrollbarVerticalButton
) ? mpVScrollbarStyle
: mpHScrollbarStyle
;
1254 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(pParent
));
1255 gtk_widget_path_append_type(path
, GTK_TYPE_SCROLLBAR
);
1256 gtk_widget_path_iter_set_object_name(path
, -1, "button");
1257 return makeContext(path
, pParent
);
1259 case GtkControlPart::ProgressBar
:
1261 GtkWidgetPath
*path
= gtk_widget_path_new();
1262 gtk_widget_path_append_type(path
, GTK_TYPE_PROGRESS_BAR
);
1263 gtk_widget_path_iter_set_object_name(path
, -1, "progressbar");
1264 gtk_widget_path_iter_add_class(path
, -1, GTK_STYLE_CLASS_HORIZONTAL
);
1265 return makeContext(path
, nullptr);
1267 case GtkControlPart::ProgressBarTrough
:
1269 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle
));
1270 gtk_widget_path_append_type(path
, GTK_TYPE_PROGRESS_BAR
);
1271 gtk_widget_path_iter_set_object_name(path
, -1, "trough");
1272 return makeContext(path
, mpProgressBarStyle
);
1274 case GtkControlPart::ProgressBarProgress
:
1276 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarTroughStyle
));
1277 gtk_widget_path_append_type(path
, GTK_TYPE_PROGRESS_BAR
);
1278 gtk_widget_path_iter_set_object_name(path
, -1, "progress");
1279 return makeContext(path
, mpProgressBarTroughStyle
);
1281 case GtkControlPart::Notebook
:
1283 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle
));
1284 gtk_widget_path_append_type(path
, GTK_TYPE_NOTEBOOK
);
1285 gtk_widget_path_iter_set_object_name(path
, -1, "notebook");
1286 return makeContext(path
, mpWindowStyle
);
1288 case GtkControlPart::NotebookStack
:
1290 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle
));
1291 gtk_widget_path_append_type(path
, GTK_TYPE_NOTEBOOK
);
1292 gtk_widget_path_iter_set_object_name(path
, -1, "stack");
1293 return makeContext(path
, mpNotebookStyle
);
1295 case GtkControlPart::NotebookHeader
:
1297 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle
));
1298 gtk_widget_path_append_type(path
, GTK_TYPE_NOTEBOOK
);
1299 gtk_widget_path_iter_set_object_name(path
, -1, "header");
1300 gtk_widget_path_iter_add_class(path
, -1, "frame");
1301 gtk_widget_path_iter_add_class(path
, -1, "top");
1302 return makeContext(path
, mpNotebookStyle
);
1304 case GtkControlPart::NotebookHeaderTabs
:
1306 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderStyle
));
1307 gtk_widget_path_append_type(path
, GTK_TYPE_NOTEBOOK
);
1308 gtk_widget_path_iter_set_object_name(path
, -1, "tabs");
1309 gtk_widget_path_iter_add_class(path
, -1, "top");
1310 return makeContext(path
, mpNotebookHeaderStyle
);
1312 case GtkControlPart::NotebookHeaderTabsTab
:
1314 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsStyle
));
1315 gtk_widget_path_append_type(path
, GTK_TYPE_NOTEBOOK
);
1316 gtk_widget_path_iter_set_object_name(path
, -1, "tab");
1317 gtk_widget_path_iter_add_class(path
, -1, "top");
1318 return makeContext(path
, mpNotebookHeaderTabsStyle
);
1320 case GtkControlPart::NotebookHeaderTabsTabLabel
:
1322 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle
));
1323 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1324 gtk_widget_path_iter_set_object_name(path
, -1, "label");
1325 return makeContext(path
, mpNotebookHeaderTabsTabStyle
);
1327 case GtkControlPart::NotebookHeaderTabsTabActiveLabel
:
1328 case GtkControlPart::NotebookHeaderTabsTabHoverLabel
:
1329 return mpNotebookHeaderTabsTabLabelStyle
;
1330 case GtkControlPart::FrameBorder
:
1332 GtkWidgetPath
*path
= gtk_widget_path_new();
1333 gtk_widget_path_append_type(path
, GTK_TYPE_FRAME
);
1334 gtk_widget_path_iter_set_object_name(path
, -1, "frame");
1335 gtk_widget_path_iter_add_class(path
, -1, "frame");
1336 return makeContext(path
, nullptr);
1338 case GtkControlPart::MenuBar
:
1340 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle
));
1341 gtk_widget_path_append_type(path
, GTK_TYPE_MENU_BAR
);
1342 gtk_widget_path_iter_set_object_name(path
, -1, "menubar");
1343 return makeContext(path
, mpWindowStyle
);
1345 case GtkControlPart::MenuBarItem
:
1347 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarStyle
));
1348 gtk_widget_path_append_type(path
, GTK_TYPE_MENU_ITEM
);
1349 gtk_widget_path_iter_set_object_name(path
, -1, "menuitem");
1350 return makeContext(path
, mpMenuBarStyle
);
1352 case GtkControlPart::MenuWindow
:
1354 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarItemStyle
));
1355 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1356 gtk_widget_path_iter_set_object_name(path
, -1, "window");
1357 gtk_widget_path_iter_add_class(path
, -1, "background");
1358 gtk_widget_path_iter_add_class(path
, -1, "popup");
1359 return makeContext(path
, mpMenuBarItemStyle
);
1361 case GtkControlPart::Menu
:
1363 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuWindowStyle
));
1364 gtk_widget_path_append_type(path
, GTK_TYPE_MENU
);
1365 gtk_widget_path_iter_set_object_name(path
, -1, "menu");
1366 return makeContext(path
, mpMenuWindowStyle
);
1368 case GtkControlPart::MenuItem
:
1370 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle
));
1371 gtk_widget_path_append_type(path
, GTK_TYPE_MENU_ITEM
);
1372 gtk_widget_path_iter_set_object_name(path
, -1, "menuitem");
1373 return makeContext(path
, mpMenuStyle
);
1375 case GtkControlPart::MenuItemLabel
:
1377 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle
));
1378 gtk_widget_path_append_type(path
, G_TYPE_NONE
);
1379 gtk_widget_path_iter_set_object_name(path
, -1, "label");
1380 return makeContext(path
, mpMenuItemStyle
);
1382 case GtkControlPart::MenuItemArrow
:
1384 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle
));
1385 gtk_widget_path_append_type(path
, GTK_TYPE_MENU_ITEM
);
1386 gtk_widget_path_iter_set_object_name(path
, -1, "arrow");
1387 return makeContext(path
, mpMenuItemStyle
);
1389 case GtkControlPart::CheckMenuItem
:
1391 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle
));
1392 gtk_widget_path_append_type(path
, GTK_TYPE_CHECK_MENU_ITEM
);
1393 gtk_widget_path_iter_set_object_name(path
, -1, "menuitem");
1394 return makeContext(path
, mpMenuStyle
);
1396 case GtkControlPart::CheckMenuItemCheck
:
1398 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpCheckMenuItemStyle
));
1399 gtk_widget_path_append_type(path
, GTK_TYPE_CHECK_MENU_ITEM
);
1400 gtk_widget_path_iter_set_object_name(path
, -1, "check");
1401 return makeContext(path
, mpCheckMenuItemStyle
);
1403 case GtkControlPart::RadioMenuItem
:
1405 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle
));
1406 gtk_widget_path_append_type(path
, GTK_TYPE_RADIO_MENU_ITEM
);
1407 gtk_widget_path_iter_set_object_name(path
, -1, "menuitem");
1408 return makeContext(path
, mpMenuStyle
);
1410 case GtkControlPart::RadioMenuItemRadio
:
1412 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpRadioMenuItemStyle
));
1413 gtk_widget_path_append_type(path
, GTK_TYPE_RADIO_MENU_ITEM
);
1414 gtk_widget_path_iter_set_object_name(path
, -1, "radio");
1415 return makeContext(path
, mpRadioMenuItemStyle
);
1417 case GtkControlPart::SeparatorMenuItem
:
1419 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle
));
1420 gtk_widget_path_append_type(path
, GTK_TYPE_SEPARATOR_MENU_ITEM
);
1421 gtk_widget_path_iter_set_object_name(path
, -1, "menuitem");
1422 return makeContext(path
, mpMenuStyle
);
1424 case GtkControlPart::SeparatorMenuItemSeparator
:
1426 GtkWidgetPath
*path
= gtk_widget_path_copy(gtk_style_context_get_path(mpSeparatorMenuItemStyle
));
1427 gtk_widget_path_append_type(path
, GTK_TYPE_SEPARATOR_MENU_ITEM
);
1428 gtk_widget_path_iter_set_object_name(path
, -1, "separator");
1429 return makeContext(path
, mpSeparatorMenuItemStyle
);
1436 #ifndef GTK_STYLE_CLASS_POPUP
1437 #define GTK_STYLE_CLASS_POPUP "popup"
1439 #ifndef GTK_STYLE_CLASS_LABEL
1440 #define GTK_STYLE_CLASS_LABEL "label"
1443 void GtkSalGraphics::PaintCheckOrRadio(cairo_t
*cr
, GtkStyleContext
*context
,
1444 const tools::Rectangle
& rControlRectangle
, bool bIsCheck
, bool bInMenu
)
1446 gint indicator_size
;
1447 gtk_style_context_get_style(context
, "indicator-size", &indicator_size
, nullptr);
1449 gint x
= (rControlRectangle
.GetWidth() - indicator_size
) / 2;
1450 gint y
= (rControlRectangle
.GetHeight() - indicator_size
) / 2;
1453 gtk_render_background(context
, cr
, x
, y
, indicator_size
, indicator_size
);
1456 gtk_render_check(context
, cr
, x
, y
, indicator_size
, indicator_size
);
1458 gtk_render_option(context
, cr
, x
, y
, indicator_size
, indicator_size
);
1460 gtk_render_frame(context
, cr
, x
, y
, indicator_size
, indicator_size
);
1463 void GtkSalGraphics::PaintCheck(cairo_t
*cr
, GtkStyleContext
*context
,
1464 const tools::Rectangle
& rControlRectangle
, bool bInMenu
)
1466 PaintCheckOrRadio(cr
, context
, rControlRectangle
, true, bInMenu
);
1469 void GtkSalGraphics::PaintRadio(cairo_t
*cr
, GtkStyleContext
*context
,
1470 const tools::Rectangle
& rControlRectangle
, bool bInMenu
)
1472 PaintCheckOrRadio(cr
, context
, rControlRectangle
, false, bInMenu
);
1475 static gfloat
getArrowSize(GtkStyleContext
* context
)
1477 gint min_width
, min_weight
;
1478 gtk_style_context_get_style(context
, "min-width", &min_width
, nullptr);
1479 gtk_style_context_get_style(context
, "min-height", &min_weight
, nullptr);
1480 gfloat arrow_size
= 11 * MAX (min_width
, min_weight
);
1486 void draw_vertical_separator(GtkStyleContext
*context
, cairo_t
*cr
, const tools::Rectangle
& rControlRegion
)
1491 gint nSeparatorWidth
= 1;
1493 gtk_style_context_get(context
,
1494 gtk_style_context_get_state(context
),
1495 "min-width", &nSeparatorWidth
, nullptr);
1497 gint nHalfSeparatorWidth
= nSeparatorWidth
/ 2;
1498 gint nHalfRegionWidth
= rControlRegion
.GetWidth() / 2;
1500 nX
= nX
+ nHalfRegionWidth
- nHalfSeparatorWidth
;
1501 nY
= rControlRegion
.GetHeight() > 5 ? 1 : 0;
1502 int nHeight
= rControlRegion
.GetHeight() - (2 * nY
);
1504 gtk_render_background(context
, cr
, nX
, nY
, nSeparatorWidth
, nHeight
);
1505 gtk_render_frame(context
, cr
, nX
, nY
, nSeparatorWidth
, nHeight
);
1508 void draw_horizontal_separator(GtkStyleContext
*context
, cairo_t
*cr
, const tools::Rectangle
& rControlRegion
)
1513 gint nSeparatorHeight
= 1;
1515 gtk_style_context_get(context
,
1516 gtk_style_context_get_state(context
),
1517 "min-height", &nSeparatorHeight
, nullptr);
1519 gint nHalfSeparatorHeight
= nSeparatorHeight
/ 2;
1520 gint nHalfRegionHeight
= rControlRegion
.GetHeight() / 2;
1522 nY
= nY
+ nHalfRegionHeight
- nHalfSeparatorHeight
;
1523 nX
= rControlRegion
.GetWidth() > 5 ? 1 : 0;
1524 int nWidth
= rControlRegion
.GetWidth() - (2 * nX
);
1526 gtk_render_background(context
, cr
, nX
, nY
, nWidth
, nSeparatorHeight
);
1527 gtk_render_frame(context
, cr
, nX
, nY
, nWidth
, nSeparatorHeight
);
1531 void GtkSalGraphics::handleDamage(const tools::Rectangle
& rDamagedRegion
)
1533 assert(m_pWidgetDraw
);
1534 assert(!rDamagedRegion
.IsEmpty());
1535 mpFrame
->damaged(rDamagedRegion
.Left(), rDamagedRegion
.Top(), rDamagedRegion
.GetWidth(), rDamagedRegion
.GetHeight());
1538 bool GtkSalGraphics::drawNativeControl( ControlType nType
, ControlPart nPart
, const tools::Rectangle
& rControlRegion
,
1539 ControlState nState
, const ImplControlValue
& rValue
,
1540 const OUString
&, const Color
& rBackgroundColor
)
1542 RenderType renderType
= nPart
== ControlPart::Focus
? RenderType::Focus
: RenderType::BackgroundAndFrame
;
1543 GtkStyleContext
*context
= nullptr;
1544 GdkPixbuf
*pixbuf
= nullptr;
1545 bool bInMenu
= false;
1547 GtkStateFlags flags
= NWConvertVCLStateToGTKState(nState
);
1551 case ControlType::Spinbox
:
1552 case ControlType::SpinButtons
:
1553 context
= mpSpinStyle
;
1554 renderType
= RenderType::Spinbutton
;
1556 case ControlType::Editbox
:
1557 context
= mpEntryStyle
;
1559 case ControlType::MultilineEditbox
:
1560 context
= mpTextViewStyle
;
1562 case ControlType::Combobox
:
1563 context
= mpComboboxStyle
;
1564 renderType
= RenderType::Combobox
;
1566 case ControlType::Listbox
:
1567 if (nPart
== ControlPart::Focus
)
1569 renderType
= RenderType::Focus
;
1570 context
= mpListboxButtonStyle
;
1574 renderType
= RenderType::Combobox
;
1575 context
= mpListboxStyle
;
1578 case ControlType::MenuPopup
:
1581 // map selected menu entries in vcl parlance to gtk prelight
1582 if (nPart
>= ControlPart::MenuItem
&& nPart
<= ControlPart::SubmenuArrow
&& (nState
& ControlState::SELECTED
))
1583 flags
= static_cast<GtkStateFlags
>(flags
| GTK_STATE_FLAG_PRELIGHT
);
1584 flags
= static_cast<GtkStateFlags
>(flags
& ~GTK_STATE_FLAG_ACTIVE
);
1587 case ControlPart::MenuItem
:
1588 context
= mpMenuItemStyle
;
1589 renderType
= RenderType::BackgroundAndFrame
;
1591 case ControlPart::MenuItemCheckMark
:
1592 context
= mpCheckMenuItemCheckStyle
;
1593 renderType
= RenderType::Check
;
1594 nType
= ControlType::Checkbox
;
1595 if (nState
& ControlState::PRESSED
)
1597 flags
= static_cast<GtkStateFlags
>(flags
| GTK_STATE_FLAG_CHECKED
);
1600 case ControlPart::MenuItemRadioMark
:
1601 context
= mpRadioMenuItemRadioStyle
;
1602 renderType
= RenderType::Radio
;
1603 nType
= ControlType::Radiobutton
;
1604 if (nState
& ControlState::PRESSED
)
1606 flags
= static_cast<GtkStateFlags
>(flags
| GTK_STATE_FLAG_CHECKED
);
1609 case ControlPart::Separator
:
1610 context
= mpSeparatorMenuItemSeparatorStyle
;
1611 flags
= GtkStateFlags(GTK_STATE_FLAG_BACKDROP
| GTK_STATE_FLAG_INSENSITIVE
); //GTK_STATE_FLAG_BACKDROP hack ?
1612 renderType
= RenderType::MenuSeparator
;
1614 case ControlPart::SubmenuArrow
:
1615 context
= mpMenuItemArrowStyle
;
1616 renderType
= RenderType::Arrow
;
1618 case ControlPart::Entire
:
1619 context
= mpMenuStyle
;
1620 renderType
= RenderType::Background
;
1625 case ControlType::Toolbar
:
1628 case ControlPart::DrawBackgroundHorz
:
1629 case ControlPart::DrawBackgroundVert
:
1630 context
= mpToolbarStyle
;
1632 case ControlPart::Button
:
1633 /* For all checkbuttons in the toolbars */
1634 flags
= static_cast<GtkStateFlags
>(flags
|
1635 ( (rValue
.getTristateVal() == ButtonValue::On
) ? GTK_STATE_FLAG_CHECKED
: GTK_STATE_FLAG_NORMAL
));
1636 context
= mpToolButtonStyle
;
1638 case ControlPart::SeparatorVert
:
1639 context
= mpToolbarSeparatorStyle
;
1640 renderType
= RenderType::ToolbarSeparator
;
1646 case ControlType::Radiobutton
:
1647 flags
= static_cast<GtkStateFlags
>(flags
|
1648 ( (rValue
.getTristateVal() == ButtonValue::On
) ? GTK_STATE_FLAG_CHECKED
: GTK_STATE_FLAG_NORMAL
));
1649 context
= mpRadioButtonRadioStyle
;
1650 renderType
= nPart
== ControlPart::Focus
? RenderType::Focus
: RenderType::Radio
;
1652 case ControlType::Checkbox
:
1653 flags
= static_cast<GtkStateFlags
>(flags
|
1654 ( (rValue
.getTristateVal() == ButtonValue::On
) ? GTK_STATE_FLAG_CHECKED
:
1655 (rValue
.getTristateVal() == ButtonValue::Mixed
) ? GTK_STATE_FLAG_INCONSISTENT
:
1656 GTK_STATE_FLAG_NORMAL
));
1657 context
= mpCheckButtonCheckStyle
;
1658 renderType
= nPart
== ControlPart::Focus
? RenderType::Focus
: RenderType::Check
;
1660 case ControlType::Pushbutton
:
1661 context
= mpButtonStyle
;
1663 case ControlType::Scrollbar
:
1666 case ControlPart::DrawBackgroundVert
:
1667 case ControlPart::DrawBackgroundHorz
:
1668 context
= (nPart
== ControlPart::DrawBackgroundVert
)
1669 ? mpVScrollbarStyle
: mpHScrollbarStyle
;
1670 renderType
= RenderType::Scrollbar
;
1675 case ControlType::ListNet
:
1678 case ControlType::TabPane
:
1679 context
= mpNotebookStyle
;
1681 case ControlType::TabBody
:
1682 context
= mpNotebookStackStyle
;
1684 case ControlType::TabHeader
:
1685 context
= mpNotebookHeaderStyle
;
1687 case ControlType::TabItem
:
1688 context
= mpNotebookHeaderTabsTabStyle
;
1689 if (nState
& ControlState::SELECTED
)
1690 flags
= static_cast<GtkStateFlags
>(flags
| GTK_STATE_FLAG_CHECKED
);
1691 renderType
= RenderType::TabItem
;
1693 case ControlType::WindowBackground
:
1694 context
= gtk_widget_get_style_context(gtk_widget_get_toplevel(mpWindow
));
1696 case ControlType::Frame
:
1698 DrawFrameStyle nStyle
= static_cast<DrawFrameStyle
>(rValue
.getNumericVal() & 0x0f);
1699 if (nStyle
== DrawFrameStyle::In
)
1700 context
= mpFrameOutStyle
;
1702 context
= mpFrameInStyle
;
1705 case ControlType::Menubar
:
1706 if (nPart
== ControlPart::MenuItem
)
1708 context
= mpMenuBarItemStyle
;
1710 flags
= (!(nState
& ControlState::ENABLED
)) ? GTK_STATE_FLAG_INSENSITIVE
: GTK_STATE_FLAG_NORMAL
;
1711 if (nState
& ControlState::SELECTED
)
1712 flags
= static_cast<GtkStateFlags
>(flags
| GTK_STATE_FLAG_PRELIGHT
);
1716 context
= mpMenuBarStyle
;
1719 case ControlType::Fixedline
:
1720 context
= nPart
== ControlPart::SeparatorHorz
? mpFixedHoriLineStyle
: mpFixedVertLineStyle
;
1721 renderType
= RenderType::Separator
;
1723 case ControlType::ListNode
:
1725 context
= mpTreeHeaderButtonStyle
;
1726 ButtonValue aButtonValue
= rValue
.getTristateVal();
1727 if (aButtonValue
== ButtonValue::On
)
1728 flags
= static_cast<GtkStateFlags
>(flags
| GTK_STATE_FLAG_CHECKED
);
1729 renderType
= RenderType::Expander
;
1732 case ControlType::ListHeader
:
1733 context
= mpTreeHeaderButtonStyle
;
1734 if (nPart
== ControlPart::Arrow
)
1736 const char* icon
= (rValue
.getNumericVal() & 1) ? "pan-down-symbolic" : "pan-up-symbolic";
1737 GtkIconTheme
*pIconTheme
= gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow
));
1738 pixbuf
= gtk_icon_theme_load_icon_for_scale(pIconTheme
, icon
,
1739 std::max(rControlRegion
.GetWidth(), rControlRegion
.GetHeight()),
1740 gtk_style_context_get_scale (context
),
1741 static_cast<GtkIconLookupFlags
>(0), nullptr);
1742 flags
= GTK_STATE_FLAG_SELECTED
;
1743 renderType
= RenderType::Icon
;
1746 case ControlType::Progress
:
1747 context
= mpProgressBarProgressStyle
;
1748 renderType
= RenderType::Progress
;
1754 cairo_t
*cr
= getCairoContext(false);
1756 cairo_translate(cr
, rControlRegion
.Left(), rControlRegion
.Top());
1760 tools::Long nWidth
= rControlRegion
.GetWidth();
1761 tools::Long nHeight
= rControlRegion
.GetHeight();
1763 StyleContextSave aContextState
;
1764 aContextState
.save(context
);
1765 style_context_set_state(context
, flags
);
1767 // apply background in style, if explicitly set
1768 // note: for more complex controls that use multiple styles for their elements,
1769 // background may have to be applied for more of those as well (s. case RenderType::Combobox below)
1770 GtkCssProvider
* pBgCssProvider
= nullptr;
1771 if (rBackgroundColor
!= COL_AUTO
)
1773 const OUString sColorCss
= "* { background-color: #" + rBackgroundColor
.AsRGBHexString() + "; }";
1774 const OString aResult
= OUStringToOString(sColorCss
, RTL_TEXTENCODING_UTF8
);
1775 pBgCssProvider
= gtk_css_provider_new();
1776 gtk_css_provider_load_from_data(pBgCssProvider
, aResult
.getStr(), aResult
.getLength(), nullptr);
1777 gtk_style_context_add_provider(context
, GTK_STYLE_PROVIDER(pBgCssProvider
),
1778 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
);
1783 case RenderType::Background
:
1784 case RenderType::BackgroundAndFrame
:
1785 gtk_render_background(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1786 if (renderType
== RenderType::BackgroundAndFrame
)
1788 gtk_render_frame(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1791 case RenderType::Check
:
1793 PaintCheck(cr
, context
, rControlRegion
, bInMenu
);
1796 case RenderType::Radio
:
1798 PaintRadio(cr
, context
, rControlRegion
, bInMenu
);
1801 case RenderType::MenuSeparator
:
1802 gtk_render_line(context
, cr
,
1803 0, rControlRegion
.GetHeight() / 2,
1804 rControlRegion
.GetWidth() - 1, rControlRegion
.GetHeight() / 2);
1806 case RenderType::ToolbarSeparator
:
1808 draw_vertical_separator(context
, cr
, rControlRegion
);
1811 case RenderType::Separator
:
1812 if (nPart
== ControlPart::SeparatorHorz
)
1813 draw_horizontal_separator(context
, cr
, rControlRegion
);
1815 draw_vertical_separator(context
, cr
, rControlRegion
);
1817 case RenderType::Arrow
:
1818 gtk_render_arrow(context
, cr
,
1820 MIN(rControlRegion
.GetWidth(), 1 + rControlRegion
.GetHeight()));
1822 case RenderType::Expander
:
1823 gtk_render_expander(context
, cr
, -2, -2, nWidth
+4, nHeight
+4);
1825 case RenderType::Scrollbar
:
1826 PaintScrollbar(context
, cr
, rControlRegion
, nPart
, rValue
);
1828 case RenderType::Spinbutton
:
1829 PaintSpinButton(flags
, cr
, rControlRegion
, nPart
, rValue
);
1831 case RenderType::Combobox
:
1834 gtk_style_context_add_provider(mpComboboxEntryStyle
, GTK_STYLE_PROVIDER(pBgCssProvider
),
1835 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
);
1837 PaintCombobox(flags
, cr
, rControlRegion
, nType
, nPart
);
1840 gtk_style_context_remove_provider(mpComboboxEntryStyle
, GTK_STYLE_PROVIDER(pBgCssProvider
));
1843 case RenderType::Icon
:
1844 gtk_style_context_save (context
);
1845 gtk_style_context_set_scale (context
, 1);
1846 gtk_render_icon(context
, cr
, pixbuf
, nX
, nY
);
1847 gtk_style_context_restore (context
);
1848 g_object_unref(pixbuf
);
1850 case RenderType::Focus
:
1852 if (nType
== ControlType::Checkbox
||
1853 nType
== ControlType::Radiobutton
)
1856 nHeight
+= 4; nWidth
+= 4;
1862 gtk_style_context_get_border(context
, flags
, &border
);
1866 nWidth
-= border
.left
+ border
.right
;
1867 nHeight
-= border
.top
+ border
.bottom
;
1870 gtk_render_focus(context
, cr
, nX
, nY
, nWidth
, nHeight
);
1874 case RenderType::Progress
:
1876 gtk_render_background(mpProgressBarTroughStyle
, cr
, nX
, nY
, nWidth
, nHeight
);
1878 tools::Long nProgressWidth
= rValue
.getNumericVal();
1882 gtk_style_context_get_padding(context
, gtk_style_context_get_state(context
), &padding
);
1886 nHeight
-= (padding
.top
+ padding
.bottom
);
1887 nProgressWidth
-= (padding
.left
+ padding
.right
);
1888 gtk_render_background(context
, cr
, nX
, nY
, nProgressWidth
, nHeight
);
1889 gtk_render_frame(context
, cr
, nX
, nY
, nProgressWidth
, nHeight
);
1892 gtk_render_frame(mpProgressBarTroughStyle
, cr
, nX
, nY
, nWidth
, nHeight
);
1896 case RenderType::TabItem
:
1898 gint
initial_gap(0);
1899 gtk_style_context_get_style(mpNotebookStyle
,
1900 "initial-gap", &initial_gap
,
1903 nX
+= initial_gap
/2;
1904 nWidth
-= initial_gap
;
1905 tools::Rectangle
aRect(Point(nX
, nY
), Size(nWidth
, nHeight
));
1906 render_common(mpNotebookHeaderTabsTabStyle
, cr
, aRect
, flags
);
1915 gtk_style_context_remove_provider(context
, GTK_STYLE_PROVIDER(pBgCssProvider
));
1917 aContextState
.restore();
1919 cairo_destroy(cr
); // unref
1921 if (!rControlRegion
.IsEmpty())
1922 mpFrame
->damaged(rControlRegion
.Left(), rControlRegion
.Top(), rControlRegion
.GetWidth(), rControlRegion
.GetHeight());
1927 static tools::Rectangle
GetWidgetSize(const tools::Rectangle
& rControlRegion
, GtkWidget
* widget
)
1929 GtkRequisition aReq
;
1930 gtk_widget_get_preferred_size(widget
, nullptr, &aReq
);
1931 tools::Long nHeight
= std::max
<tools::Long
>(rControlRegion
.GetHeight(), aReq
.height
);
1932 return tools::Rectangle(rControlRegion
.TopLeft(), Size(rControlRegion
.GetWidth(), nHeight
));
1935 static tools::Rectangle
AdjustRectForTextBordersPadding(GtkStyleContext
* pStyle
, tools::Long nContentWidth
, tools::Long nContentHeight
, const tools::Rectangle
& rControlRegion
)
1938 gtk_style_context_get_border(pStyle
, gtk_style_context_get_state(pStyle
), &border
);
1941 gtk_style_context_get_padding(pStyle
, gtk_style_context_get_state(pStyle
), &padding
);
1943 gint nWidgetHeight
= nContentHeight
+ padding
.top
+ padding
.bottom
+ border
.top
+ border
.bottom
;
1944 nWidgetHeight
= std::max(std::max
<gint
>(nWidgetHeight
, rControlRegion
.GetHeight()), 34);
1946 gint nWidgetWidth
= nContentWidth
+ padding
.left
+ padding
.right
+ border
.left
+ border
.right
;
1947 nWidgetWidth
= std::max
<gint
>(nWidgetWidth
, rControlRegion
.GetWidth());
1949 tools::Rectangle
aEditRect(rControlRegion
.TopLeft(), Size(nWidgetWidth
, nWidgetHeight
));
1954 bool GtkSalGraphics::getNativeControlRegion( ControlType nType
, ControlPart nPart
, const tools::Rectangle
& rControlRegion
, ControlState
,
1955 const ImplControlValue
& rValue
, const OUString
&,
1956 tools::Rectangle
&rNativeBoundingRegion
, tools::Rectangle
&rNativeContentRegion
)
1958 /* TODO: all this functions needs improvements */
1959 tools::Rectangle aEditRect
= rControlRegion
;
1960 gint indicator_size
, indicator_spacing
;
1962 if(((nType
== ControlType::Checkbox
) || (nType
== ControlType::Radiobutton
)) &&
1963 nPart
== ControlPart::Entire
)
1965 rNativeBoundingRegion
= rControlRegion
;
1967 GtkStyleContext
*pButtonStyle
= (nType
== ControlType::Checkbox
) ? mpCheckButtonCheckStyle
: mpRadioButtonRadioStyle
;
1970 gtk_style_context_get_style( pButtonStyle
,
1971 "indicator-size", &indicator_size
,
1972 "indicator-spacing", &indicator_spacing
,
1976 gtk_style_context_get_border(pButtonStyle
, gtk_style_context_get_state(pButtonStyle
), &border
);
1979 gtk_style_context_get_padding(pButtonStyle
, gtk_style_context_get_state(pButtonStyle
), &padding
);
1982 indicator_size
+= 2*indicator_spacing
+ border
.left
+ padding
.left
+ border
.right
+ padding
.right
;
1983 tools::Rectangle
aIndicatorRect( Point( 0,
1984 (rControlRegion
.GetHeight()-indicator_size
)/2),
1985 Size( indicator_size
, indicator_size
) );
1986 rNativeContentRegion
= aIndicatorRect
;
1990 else if( nType
== ControlType::MenuPopup
)
1992 if ((nPart
== ControlPart::MenuItemCheckMark
) ||
1993 (nPart
== ControlPart::MenuItemRadioMark
) )
1997 GtkStyleContext
*pMenuItemStyle
= (nPart
== ControlPart::MenuItemCheckMark
) ? mpCheckMenuItemCheckStyle
1998 : mpRadioMenuItemRadioStyle
;
2000 gtk_style_context_get_style( pMenuItemStyle
,
2001 "indicator-size", &indicator_size
,
2004 gint point
= MAX(0, rControlRegion
.GetHeight() - indicator_size
);
2005 aEditRect
= tools::Rectangle( Point( 0, point
/ 2),
2006 Size( indicator_size
, indicator_size
) );
2008 else if (nPart
== ControlPart::Separator
)
2010 gint separator_height
, separator_width
, wide_separators
;
2012 gtk_style_context_get_style (mpSeparatorMenuItemSeparatorStyle
,
2013 "wide-separators", &wide_separators
,
2014 "separator-width", &separator_width
,
2015 "separator-height", &separator_height
,
2018 aEditRect
= tools::Rectangle( aEditRect
.TopLeft(),
2019 Size( aEditRect
.GetWidth(), wide_separators
? separator_height
: 1 ) );
2021 else if (nPart
== ControlPart::SubmenuArrow
)
2023 gfloat arrow_size
= getArrowSize(mpMenuItemArrowStyle
);
2024 aEditRect
= tools::Rectangle( aEditRect
.TopLeft(),
2025 Size( arrow_size
, arrow_size
) );
2028 else if ( (nType
==ControlType::Scrollbar
) &&
2029 ((nPart
==ControlPart::ButtonLeft
) || (nPart
==ControlPart::ButtonRight
) ||
2030 (nPart
==ControlPart::ButtonUp
) || (nPart
==ControlPart::ButtonDown
) ) )
2032 rNativeBoundingRegion
= NWGetScrollButtonRect( nPart
, rControlRegion
);
2033 rNativeContentRegion
= rNativeBoundingRegion
;
2035 if (!rNativeContentRegion
.GetWidth())
2036 rNativeContentRegion
.SetRight( rNativeContentRegion
.Left() + 1 );
2037 if (!rNativeContentRegion
.GetHeight())
2038 rNativeContentRegion
.SetBottom( rNativeContentRegion
.Top() + 1 );
2042 else if ( (nType
==ControlType::Spinbox
) &&
2043 ((nPart
==ControlPart::ButtonUp
) || (nPart
==ControlPart::ButtonDown
) ||
2044 (nPart
==ControlPart::SubEdit
)) )
2046 tools::Rectangle
aControlRegion(GetWidgetSize(rControlRegion
, gSpinBox
));
2047 aEditRect
= NWGetSpinButtonRect(nPart
, aControlRegion
);
2049 else if ( (nType
==ControlType::Combobox
) &&
2050 ((nPart
==ControlPart::ButtonDown
) || (nPart
==ControlPart::SubEdit
)) )
2052 aEditRect
= NWGetComboBoxButtonRect(nType
, nPart
, rControlRegion
);
2054 else if ( (nType
==ControlType::Listbox
) &&
2055 ((nPart
==ControlPart::ButtonDown
) || (nPart
==ControlPart::SubEdit
)) )
2057 aEditRect
= NWGetComboBoxButtonRect(nType
, nPart
, rControlRegion
);
2059 else if (nType
== ControlType::Editbox
&& nPart
== ControlPart::Entire
)
2061 aEditRect
= GetWidgetSize(rControlRegion
, gEntryBox
);
2063 else if (nType
== ControlType::Listbox
&& nPart
== ControlPart::Entire
)
2065 aEditRect
= GetWidgetSize(rControlRegion
, gListBox
);
2067 else if (nType
== ControlType::Combobox
&& nPart
== ControlPart::Entire
)
2069 aEditRect
= GetWidgetSize(rControlRegion
, gComboBox
);
2071 else if (nType
== ControlType::Spinbox
&& nPart
== ControlPart::Entire
)
2073 aEditRect
= GetWidgetSize(rControlRegion
, gSpinBox
);
2075 else if (nType
== ControlType::TabItem
&& nPart
== ControlPart::Entire
)
2077 const TabitemValue
& rTabitemValue
= static_cast<const TabitemValue
&>(rValue
);
2078 const tools::Rectangle
& rTabitemRect
= rTabitemValue
.getContentRect();
2080 aEditRect
= AdjustRectForTextBordersPadding(mpNotebookHeaderTabsTabStyle
, rTabitemRect
.GetWidth(),
2081 rTabitemRect
.GetHeight(), rControlRegion
);
2083 else if (nType
== ControlType::Frame
&& nPart
== ControlPart::Border
)
2085 aEditRect
= rControlRegion
;
2088 gtk_style_context_get_padding(mpFrameInStyle
, gtk_style_context_get_state(mpFrameInStyle
), &padding
);
2091 gtk_style_context_get_border(mpFrameInStyle
, gtk_style_context_get_state(mpFrameInStyle
), &border
);
2093 int x1
= aEditRect
.Left();
2094 int y1
= aEditRect
.Top();
2095 int x2
= aEditRect
.Right();
2096 int y2
= aEditRect
.Bottom();
2098 rNativeBoundingRegion
= aEditRect
;
2099 rNativeContentRegion
= tools::Rectangle(x1
+ (padding
.left
+ border
.left
),
2100 y1
+ (padding
.top
+ border
.top
),
2101 x2
- (padding
.right
+ border
.right
),
2102 y2
- (padding
.bottom
+ border
.bottom
));
2111 rNativeBoundingRegion
= aEditRect
;
2112 rNativeContentRegion
= rNativeBoundingRegion
;
2116 /************************************************************************
2117 * helper for GtkSalFrame
2118 ************************************************************************/
2119 static ::Color
getColor( const GdkRGBA
& rCol
)
2121 return ::Color( static_cast<int>(rCol
.red
* 0xFFFF) >> 8, static_cast<int>(rCol
.green
* 0xFFFF) >> 8, static_cast<int>(rCol
.blue
* 0xFFFF) >> 8 );
2124 static vcl::Font
getFont(GtkStyleContext
* pStyle
, const css::lang::Locale
& rLocale
)
2126 const PangoFontDescription
* font
= gtk_style_context_get_font(pStyle
, gtk_style_context_get_state(pStyle
));
2127 return pango_to_vcl(font
, rLocale
);
2130 vcl::Font
pango_to_vcl(const PangoFontDescription
* font
, const css::lang::Locale
& rLocale
)
2132 OString aFamily
= pango_font_description_get_family( font
);
2133 int nPangoHeight
= pango_font_description_get_size( font
);
2134 PangoStyle eStyle
= pango_font_description_get_style( font
);
2135 PangoWeight eWeight
= pango_font_description_get_weight( font
);
2136 PangoStretch eStretch
= pango_font_description_get_stretch( font
);
2138 psp::FastPrintFontInfo aInfo
;
2140 aInfo
.m_aFamilyName
= OStringToOUString( aFamily
, RTL_TEXTENCODING_UTF8
);
2144 case PANGO_STYLE_NORMAL
: aInfo
.m_eItalic
= ITALIC_NONE
;break;
2145 case PANGO_STYLE_ITALIC
: aInfo
.m_eItalic
= ITALIC_NORMAL
;break;
2146 case PANGO_STYLE_OBLIQUE
: aInfo
.m_eItalic
= ITALIC_OBLIQUE
;break;
2149 if( eWeight
<= PANGO_WEIGHT_ULTRALIGHT
)
2150 aInfo
.m_eWeight
= WEIGHT_ULTRALIGHT
;
2151 else if( eWeight
<= PANGO_WEIGHT_LIGHT
)
2152 aInfo
.m_eWeight
= WEIGHT_LIGHT
;
2153 else if( eWeight
<= PANGO_WEIGHT_NORMAL
)
2154 aInfo
.m_eWeight
= WEIGHT_NORMAL
;
2155 else if( eWeight
<= PANGO_WEIGHT_BOLD
)
2156 aInfo
.m_eWeight
= WEIGHT_BOLD
;
2158 aInfo
.m_eWeight
= WEIGHT_ULTRABOLD
;
2162 case PANGO_STRETCH_ULTRA_CONDENSED
: aInfo
.m_eWidth
= WIDTH_ULTRA_CONDENSED
;break;
2163 case PANGO_STRETCH_EXTRA_CONDENSED
: aInfo
.m_eWidth
= WIDTH_EXTRA_CONDENSED
;break;
2164 case PANGO_STRETCH_CONDENSED
: aInfo
.m_eWidth
= WIDTH_CONDENSED
;break;
2165 case PANGO_STRETCH_SEMI_CONDENSED
: aInfo
.m_eWidth
= WIDTH_SEMI_CONDENSED
;break;
2166 case PANGO_STRETCH_NORMAL
: aInfo
.m_eWidth
= WIDTH_NORMAL
;break;
2167 case PANGO_STRETCH_SEMI_EXPANDED
: aInfo
.m_eWidth
= WIDTH_SEMI_EXPANDED
;break;
2168 case PANGO_STRETCH_EXPANDED
: aInfo
.m_eWidth
= WIDTH_EXPANDED
;break;
2169 case PANGO_STRETCH_EXTRA_EXPANDED
: aInfo
.m_eWidth
= WIDTH_EXTRA_EXPANDED
;break;
2170 case PANGO_STRETCH_ULTRA_EXPANDED
: aInfo
.m_eWidth
= WIDTH_ULTRA_EXPANDED
;break;
2173 #if OSL_DEBUG_LEVEL > 1
2174 SAL_INFO("vcl.gtk3", "font name BEFORE system match: \""
2175 << aFamily
<< "\".");
2178 // match font to e.g. resolve "Sans"
2179 psp::PrintFontManager::get().matchFont(aInfo
, rLocale
);
2181 #if OSL_DEBUG_LEVEL > 1
2182 SAL_INFO("vcl.gtk3", "font match "
2183 << (aInfo
.m_nID
!= 0 ? "succeeded" : "failed")
2184 << ", name AFTER: \""
2185 << aInfo
.m_aFamilyName
2189 int nPointHeight
= nPangoHeight
/PANGO_SCALE
;
2191 vcl::Font
aFont( aInfo
.m_aFamilyName
, Size( 0, nPointHeight
) );
2192 if( aInfo
.m_eWeight
!= WEIGHT_DONTKNOW
)
2193 aFont
.SetWeight( aInfo
.m_eWeight
);
2194 if( aInfo
.m_eWidth
!= WIDTH_DONTKNOW
)
2195 aFont
.SetWidthType( aInfo
.m_eWidth
);
2196 if( aInfo
.m_eItalic
!= ITALIC_DONTKNOW
)
2197 aFont
.SetItalic( aInfo
.m_eItalic
);
2198 if( aInfo
.m_ePitch
!= PITCH_DONTKNOW
)
2199 aFont
.SetPitch( aInfo
.m_ePitch
);
2203 bool GtkSalGraphics::updateSettings(AllSettings
& rSettings
)
2205 GtkWidget
* pTopLevel
= gtk_widget_get_toplevel(mpWindow
);
2206 GtkStyleContext
* pStyle
= gtk_widget_get_style_context(pTopLevel
);
2207 StyleContextSave aContextState
;
2208 aContextState
.save(pStyle
);
2209 GtkSettings
* pSettings
= gtk_widget_get_settings(pTopLevel
);
2210 StyleSettings aStyleSet
= rSettings
.GetStyleSettings();
2215 style_context_set_state(pStyle
, GTK_STATE_FLAG_NORMAL
);
2216 gtk_style_context_get_color(pStyle
, gtk_style_context_get_state(pStyle
), &text_color
);
2217 ::Color aTextColor
= getColor( text_color
);
2218 aStyleSet
.SetDialogTextColor( aTextColor
);
2219 aStyleSet
.SetButtonTextColor( aTextColor
);
2220 aStyleSet
.SetDefaultActionButtonTextColor(aTextColor
);
2221 aStyleSet
.SetActionButtonTextColor(aTextColor
);
2222 aStyleSet
.SetRadioCheckTextColor( aTextColor
);
2223 aStyleSet
.SetGroupTextColor( aTextColor
);
2224 aStyleSet
.SetLabelTextColor( aTextColor
);
2225 aStyleSet
.SetWindowTextColor( aTextColor
);
2226 aStyleSet
.SetFieldTextColor( aTextColor
);
2228 // background colors
2229 GdkRGBA background_color
;
2230 gtk_style_context_get_background_color(pStyle
, gtk_style_context_get_state(pStyle
), &background_color
);
2232 ::Color aBackColor
= getColor( background_color
);
2233 aStyleSet
.BatchSetBackgrounds( aBackColor
);
2236 vcl::Font
aFont(getFont(pStyle
, rSettings
.GetUILanguageTag().getLocale()));
2238 aStyleSet
.BatchSetFonts( aFont
, aFont
);
2240 aFont
.SetWeight( WEIGHT_BOLD
);
2241 aStyleSet
.SetTitleFont( aFont
);
2242 aStyleSet
.SetFloatTitleFont( aFont
);
2244 // mouse over text colors
2245 style_context_set_state(pStyle
, GTK_STATE_FLAG_PRELIGHT
);
2246 gtk_style_context_get_color(pStyle
, gtk_style_context_get_state(pStyle
), &text_color
);
2247 aTextColor
= getColor(text_color
);
2248 aStyleSet
.SetDefaultButtonRolloverTextColor(aTextColor
);
2249 aStyleSet
.SetButtonRolloverTextColor(aTextColor
);
2250 aStyleSet
.SetDefaultActionButtonRolloverTextColor(aTextColor
);
2251 aStyleSet
.SetActionButtonRolloverTextColor(aTextColor
);
2252 aStyleSet
.SetFlatButtonRolloverTextColor(aTextColor
);
2253 aStyleSet
.SetFieldRolloverTextColor(aTextColor
);
2255 aContextState
.restore();
2257 // button mouse over colors
2259 GdkRGBA normal_button_rollover_text_color
, pressed_button_rollover_text_color
;
2260 aContextState
.save(mpButtonStyle
);
2261 style_context_set_state(mpButtonStyle
, GTK_STATE_FLAG_PRELIGHT
);
2262 gtk_style_context_get_color(mpButtonStyle
, gtk_style_context_get_state(mpButtonStyle
), &normal_button_rollover_text_color
);
2263 aTextColor
= getColor(normal_button_rollover_text_color
);
2264 aStyleSet
.SetButtonRolloverTextColor( aTextColor
);
2265 style_context_set_state(mpButtonStyle
, static_cast<GtkStateFlags
>(GTK_STATE_FLAG_PRELIGHT
| GTK_STATE_FLAG_ACTIVE
));
2266 gtk_style_context_get_color(mpButtonStyle
, gtk_style_context_get_state(mpButtonStyle
), &pressed_button_rollover_text_color
);
2267 aTextColor
= getColor(pressed_button_rollover_text_color
);
2268 style_context_set_state(mpButtonStyle
, GTK_STATE_FLAG_NORMAL
);
2269 aStyleSet
.SetButtonPressedRolloverTextColor( aTextColor
);
2270 aContextState
.restore();
2275 GtkWidgetPath
*pCPath
= gtk_widget_path_new();
2276 guint pos
= gtk_widget_path_append_type(pCPath
, GTK_TYPE_WINDOW
);
2277 gtk_widget_path_iter_add_class(pCPath
, pos
, GTK_STYLE_CLASS_TOOLTIP
);
2278 pos
= gtk_widget_path_append_type (pCPath
, GTK_TYPE_LABEL
);
2279 gtk_widget_path_iter_add_class(pCPath
, pos
, GTK_STYLE_CLASS_LABEL
);
2280 GtkStyleContext
*pCStyle
= makeContext (pCPath
, nullptr);
2281 aContextState
.save(pCStyle
);
2283 GdkRGBA tooltip_bg_color
, tooltip_fg_color
;
2284 style_context_set_state(pCStyle
, GTK_STATE_FLAG_NORMAL
);
2285 gtk_style_context_get_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &tooltip_fg_color
);
2286 gtk_style_context_get_background_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &tooltip_bg_color
);
2288 aContextState
.restore();
2289 g_object_unref( pCStyle
);
2291 aStyleSet
.SetHelpColor( getColor( tooltip_bg_color
));
2292 aStyleSet
.SetHelpTextColor( getColor( tooltip_fg_color
));
2296 // construct style context for text view
2297 GtkWidgetPath
*pCPath
= gtk_widget_path_new();
2298 gtk_widget_path_append_type( pCPath
, GTK_TYPE_TEXT_VIEW
);
2299 gtk_widget_path_iter_add_class( pCPath
, -1, GTK_STYLE_CLASS_VIEW
);
2300 GtkStyleContext
*pCStyle
= makeContext( pCPath
, nullptr );
2301 aContextState
.save(pCStyle
);
2303 // highlighting colors
2304 style_context_set_state(pCStyle
, GTK_STATE_FLAG_SELECTED
);
2305 gtk_style_context_get_background_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &text_color
);
2306 ::Color aHighlightColor
= getColor( text_color
);
2307 gtk_style_context_get_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &text_color
);
2308 ::Color aHighlightTextColor
= getColor( text_color
);
2309 aStyleSet
.SetHighlightColor( aHighlightColor
);
2310 aStyleSet
.SetHighlightTextColor( aHighlightTextColor
);
2311 // make active like highlight, except with a small contrast. Note, see
2312 // a GtkListBoxRow in a GtkStackSidebar for a gtk widget with a
2313 // difference between highlighted and highlighted with focus.
2314 aHighlightColor
.IncreaseLuminance(16);
2315 aStyleSet
.SetActiveColor( aHighlightColor
);
2316 aStyleSet
.SetActiveTextColor( aHighlightTextColor
);
2318 // field background color
2319 GdkRGBA field_background_color
;
2320 style_context_set_state(pCStyle
, GTK_STATE_FLAG_NORMAL
);
2321 gtk_style_context_get_background_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &field_background_color
);
2323 ::Color aBackFieldColor
= getColor( field_background_color
);
2324 aStyleSet
.SetFieldColor( aBackFieldColor
);
2325 // This baby is the default page/paper color
2326 aStyleSet
.SetWindowColor( aBackFieldColor
);
2329 gfloat caretAspectRatio
= 0.04f
;
2330 gtk_style_context_get_style( pCStyle
, "cursor-aspect-ratio", &caretAspectRatio
, nullptr );
2331 // Assume 20px tall for the ratio computation, which should give reasonable results
2332 aStyleSet
.SetCursorSize( 20 * caretAspectRatio
+ 1 );
2334 // Dark shadow color
2335 style_context_set_state(pCStyle
, GTK_STATE_FLAG_INSENSITIVE
);
2336 gtk_style_context_get_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &color
);
2337 ::Color aDarkShadowColor
= getColor( color
);
2338 aStyleSet
.SetDarkShadowColor( aDarkShadowColor
);
2340 ::Color
aShadowColor(aBackColor
);
2341 if (aDarkShadowColor
.GetLuminance() > aBackColor
.GetLuminance())
2342 aShadowColor
.IncreaseLuminance(64);
2344 aShadowColor
.DecreaseLuminance(64);
2345 aStyleSet
.SetShadowColor(aShadowColor
);
2347 aContextState
.restore();
2348 g_object_unref( pCStyle
);
2351 aStyleSet
.SetActiveTabColor( aBackFieldColor
); // same as the window color.
2352 aStyleSet
.SetInactiveTabColor( aBackColor
);
2355 // menu disabled entries handling
2356 aStyleSet
.SetSkipDisabledInMenus( true );
2357 aStyleSet
.SetPreferredContextMenuShortcuts( false );
2359 aContextState
.save(mpMenuItemLabelStyle
);
2362 style_context_set_state(mpMenuStyle
, GTK_STATE_FLAG_NORMAL
);
2363 gtk_style_context_get_background_color( mpMenuStyle
, gtk_style_context_get_state(mpMenuStyle
), &background_color
);
2364 aBackColor
= getColor( background_color
);
2365 aStyleSet
.SetMenuColor( aBackColor
);
2368 style_context_set_state(mpMenuBarStyle
, GTK_STATE_FLAG_NORMAL
);
2369 gtk_style_context_get_background_color( mpMenuBarStyle
, gtk_style_context_get_state(mpMenuBarStyle
), &background_color
);
2370 aBackColor
= getColor( background_color
);
2371 aStyleSet
.SetMenuBarColor( aBackColor
);
2372 aStyleSet
.SetMenuBarRolloverColor( aBackColor
);
2374 style_context_set_state(mpMenuBarItemStyle
, GTK_STATE_FLAG_NORMAL
);
2375 gtk_style_context_get_color( mpMenuBarItemStyle
, gtk_style_context_get_state(mpMenuBarItemStyle
), &text_color
);
2376 aTextColor
= aStyleSet
.GetPersonaMenuBarTextColor().value_or( getColor( text_color
) );
2377 aStyleSet
.SetMenuBarTextColor( aTextColor
);
2378 aStyleSet
.SetMenuBarRolloverTextColor( aTextColor
);
2380 style_context_set_state(mpMenuBarItemStyle
, GTK_STATE_FLAG_PRELIGHT
);
2381 gtk_style_context_get_color( mpMenuBarItemStyle
, gtk_style_context_get_state(mpMenuBarItemStyle
), &text_color
);
2382 aTextColor
= aStyleSet
.GetPersonaMenuBarTextColor().value_or( getColor( text_color
) );
2383 aStyleSet
.SetMenuBarHighlightTextColor( aTextColor
);
2386 style_context_set_state(mpMenuItemLabelStyle
, GTK_STATE_FLAG_NORMAL
);
2387 gtk_style_context_get_color(mpMenuItemLabelStyle
, gtk_style_context_get_state(mpMenuItemLabelStyle
), &color
);
2388 aTextColor
= getColor(color
);
2389 aStyleSet
.SetMenuTextColor(aTextColor
);
2391 style_context_set_state(mpMenuItemLabelStyle
, GTK_STATE_FLAG_PRELIGHT
);
2392 gtk_style_context_get_background_color( mpMenuItemLabelStyle
, gtk_style_context_get_state(mpMenuItemLabelStyle
), &background_color
);
2393 ::Color aHighlightColor
= getColor( background_color
);
2394 aStyleSet
.SetMenuHighlightColor( aHighlightColor
);
2396 gtk_style_context_get_color( mpMenuItemLabelStyle
, gtk_style_context_get_state(mpMenuItemLabelStyle
), &color
);
2397 ::Color aHighlightTextColor
= getColor( color
);
2398 aStyleSet
.SetMenuHighlightTextColor( aHighlightTextColor
);
2400 aContextState
.restore();
2403 aContextState
.save(mpLinkButtonStyle
);
2404 style_context_set_state(mpLinkButtonStyle
, GTK_STATE_FLAG_LINK
);
2405 gtk_style_context_get_color(mpLinkButtonStyle
, gtk_style_context_get_state(mpLinkButtonStyle
), &text_color
);
2406 aStyleSet
.SetLinkColor(getColor(text_color
));
2407 style_context_set_state(mpLinkButtonStyle
, GTK_STATE_FLAG_VISITED
);
2408 gtk_style_context_get_color(mpLinkButtonStyle
, gtk_style_context_get_state(mpLinkButtonStyle
), &text_color
);
2409 aStyleSet
.SetVisitedLinkColor(getColor(text_color
));
2410 aContextState
.restore();
2413 GtkStyleContext
*pCStyle
= mpNotebookHeaderTabsTabLabelStyle
;
2414 aContextState
.save(pCStyle
);
2415 style_context_set_state(pCStyle
, GTK_STATE_FLAG_NORMAL
);
2416 gtk_style_context_get_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &text_color
);
2417 aTextColor
= getColor( text_color
);
2418 aStyleSet
.SetTabTextColor(aTextColor
);
2419 aStyleSet
.SetTabFont(getFont(mpNotebookHeaderTabsTabLabelStyle
, rSettings
.GetUILanguageTag().getLocale()));
2420 aContextState
.restore();
2424 GtkStyleContext
*pCStyle
= mpToolButtonStyle
;
2425 aContextState
.save(pCStyle
);
2426 style_context_set_state(pCStyle
, GTK_STATE_FLAG_NORMAL
);
2427 gtk_style_context_get_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &text_color
);
2428 aTextColor
= getColor( text_color
);
2429 aStyleSet
.SetToolTextColor(aTextColor
);
2430 aStyleSet
.SetToolFont(getFont(mpToolButtonStyle
, rSettings
.GetUILanguageTag().getLocale()));
2431 aContextState
.restore();
2434 // mouse over text colors
2436 GtkStyleContext
*pCStyle
= mpNotebookHeaderTabsTabHoverLabelStyle
;
2437 aContextState
.save(pCStyle
);
2438 style_context_set_state(pCStyle
, GTK_STATE_FLAG_PRELIGHT
);
2439 gtk_style_context_get_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &text_color
);
2440 aTextColor
= getColor( text_color
);
2441 aStyleSet
.SetTabRolloverTextColor(aTextColor
);
2442 aContextState
.restore();
2446 GtkStyleContext
*pCStyle
= mpNotebookHeaderTabsTabActiveLabelStyle
;
2447 aContextState
.save(pCStyle
);
2448 style_context_set_state(pCStyle
, GTK_STATE_FLAG_CHECKED
);
2449 gtk_style_context_get_color(pCStyle
, gtk_style_context_get_state(pCStyle
), &text_color
);
2450 aTextColor
= getColor( text_color
);
2451 aStyleSet
.SetTabHighlightTextColor(aTextColor
);
2452 aContextState
.restore();
2455 // get cursor blink time
2456 gboolean blink
= false;
2458 g_object_get( pSettings
, "gtk-cursor-blink", &blink
, nullptr );
2461 gint blink_time
= static_cast<gint
>(STYLE_CURSOR_NOBLINKTIME
);
2462 g_object_get( pSettings
, "gtk-cursor-blink-time", &blink_time
, nullptr );
2463 // set the blink_time if there is a setting and it is reasonable
2464 // else leave the default value
2465 if( blink_time
> 100 )
2466 aStyleSet
.SetCursorBlinkTime( blink_time
/2 );
2469 aStyleSet
.SetCursorBlinkTime( STYLE_CURSOR_NOBLINKTIME
);
2471 MouseSettings aMouseSettings
= rSettings
.GetMouseSettings();
2472 int iDoubleClickTime
, iDoubleClickDistance
, iDragThreshold
;
2473 static const int MENU_POPUP_DELAY
= 225;
2474 g_object_get( pSettings
,
2475 "gtk-double-click-time", &iDoubleClickTime
,
2476 "gtk-double-click-distance", &iDoubleClickDistance
,
2477 "gtk-dnd-drag-threshold", &iDragThreshold
,
2479 aMouseSettings
.SetDoubleClickTime( iDoubleClickTime
);
2480 aMouseSettings
.SetDoubleClickWidth( iDoubleClickDistance
);
2481 aMouseSettings
.SetDoubleClickHeight( iDoubleClickDistance
);
2482 aMouseSettings
.SetStartDragWidth( iDragThreshold
);
2483 aMouseSettings
.SetStartDragHeight( iDragThreshold
);
2484 aMouseSettings
.SetMenuDelay( MENU_POPUP_DELAY
);
2485 rSettings
.SetMouseSettings( aMouseSettings
);
2487 gboolean primarybuttonwarps
= false;
2488 g_object_get( pSettings
,
2489 "gtk-primary-button-warps-slider", &primarybuttonwarps
,
2491 aStyleSet
.SetPreferredUseImagesInMenus(false);
2492 aStyleSet
.SetPrimaryButtonWarpsSlider(primarybuttonwarps
);
2494 // set scrollbar settings
2495 gint min_slider_length
= 21;
2497 // Grab some button style attributes
2499 QuerySize(mpHScrollbarStyle
, aSize
);
2500 QuerySize(mpHScrollbarContentsStyle
, aSize
);
2501 QuerySize(mpHScrollbarTroughStyle
, aSize
);
2502 QuerySize(mpHScrollbarSliderStyle
, aSize
);
2504 gboolean has_forward
, has_forward2
, has_backward
, has_backward2
;
2505 gtk_style_context_get_style(mpHScrollbarStyle
,
2506 "has-forward-stepper", &has_forward
,
2507 "has-secondary-forward-stepper", &has_forward2
,
2508 "has-backward-stepper", &has_backward
,
2509 "has-secondary-backward-stepper", &has_backward2
, nullptr);
2510 if (has_forward
|| has_backward
|| has_forward2
|| has_backward2
)
2511 QuerySize(mpHScrollbarButtonStyle
, aSize
);
2513 aStyleSet
.SetScrollBarSize(aSize
.Height());
2515 gtk_style_context_get(mpVScrollbarSliderStyle
, gtk_style_context_get_state(mpVScrollbarSliderStyle
),
2516 "min-height", &min_slider_length
,
2518 aStyleSet
.SetMinThumbSize(min_slider_length
);
2520 // preferred icon style
2521 gchar
* pIconThemeName
= nullptr;
2522 gboolean bDarkIconTheme
= false;
2523 g_object_get(pSettings
, "gtk-icon-theme-name", &pIconThemeName
,
2524 "gtk-application-prefer-dark-theme", &bDarkIconTheme
,
2526 OUString
sIconThemeName(OUString::createFromAscii(pIconThemeName
));
2527 aStyleSet
.SetPreferredIconTheme(sIconThemeName
, bDarkIconTheme
);
2528 g_free( pIconThemeName
);
2530 aStyleSet
.SetToolbarIconSize( ToolbarIconSize::Large
);
2532 // finally update the collected settings
2533 rSettings
.SetStyleSettings( aStyleSet
);
2534 #if OSL_DEBUG_LEVEL > 1
2535 gchar
* pThemeName
= NULL
;
2536 g_object_get( pSettings
, "gtk-theme-name", &pThemeName
, nullptr );
2537 SAL_INFO("vcl.gtk3", "Theme name is \""
2546 bool GtkSalGraphics::isNativeControlSupported( ControlType nType
, ControlPart nPart
)
2550 case ControlType::Pushbutton
:
2551 case ControlType::Radiobutton
:
2552 case ControlType::Checkbox
:
2553 case ControlType::Progress
:
2554 case ControlType::ListNode
:
2555 case ControlType::ListNet
:
2556 if (nPart
==ControlPart::Entire
|| nPart
== ControlPart::Focus
)
2560 case ControlType::Scrollbar
:
2561 if(nPart
==ControlPart::DrawBackgroundHorz
|| nPart
==ControlPart::DrawBackgroundVert
||
2562 nPart
==ControlPart::Entire
|| nPart
==ControlPart::HasThreeButtons
)
2566 case ControlType::Editbox
:
2567 case ControlType::MultilineEditbox
:
2568 if (nPart
==ControlPart::Entire
|| nPart
==ControlPart::HasBackgroundTexture
)
2572 case ControlType::Combobox
:
2573 if (nPart
==ControlPart::Entire
|| nPart
==ControlPart::HasBackgroundTexture
|| nPart
== ControlPart::AllButtons
)
2577 case ControlType::Spinbox
:
2578 if (nPart
==ControlPart::Entire
|| nPart
==ControlPart::HasBackgroundTexture
|| nPart
== ControlPart::AllButtons
|| nPart
== ControlPart::ButtonUp
|| nPart
== ControlPart::ButtonDown
)
2582 case ControlType::SpinButtons
:
2583 if (nPart
==ControlPart::Entire
|| nPart
==ControlPart::AllButtons
)
2587 case ControlType::Frame
:
2588 case ControlType::WindowBackground
:
2591 case ControlType::TabItem
:
2592 case ControlType::TabHeader
:
2593 case ControlType::TabPane
:
2594 case ControlType::TabBody
:
2595 if(nPart
==ControlPart::Entire
|| nPart
==ControlPart::TabsDrawRtl
)
2599 case ControlType::Listbox
:
2600 if (nPart
==ControlPart::Entire
|| nPart
==ControlPart::ListboxWindow
|| nPart
==ControlPart::HasBackgroundTexture
|| nPart
== ControlPart::Focus
)
2604 case ControlType::Toolbar
:
2605 if( nPart
==ControlPart::Entire
2606 // || nPart==ControlPart::DrawBackgroundHorz
2607 // || nPart==ControlPart::DrawBackgroundVert
2608 // || nPart==ControlPart::ThumbHorz
2609 // || nPart==ControlPart::ThumbVert
2610 || nPart
==ControlPart::Button
2611 // || nPart==ControlPart::SeparatorHorz
2612 || nPart
==ControlPart::SeparatorVert
2617 case ControlType::Menubar
:
2618 if (nPart
==ControlPart::Entire
|| nPart
==ControlPart::MenuItem
)
2622 case ControlType::MenuPopup
:
2623 if (nPart
==ControlPart::Entire
2624 || nPart
==ControlPart::MenuItem
2625 || nPart
==ControlPart::MenuItemCheckMark
2626 || nPart
==ControlPart::MenuItemRadioMark
2627 || nPart
==ControlPart::Separator
2628 || nPart
==ControlPart::SubmenuArrow
2633 // case ControlType::Slider:
2634 // if(nPart == ControlPart::TrackHorzArea || nPart == ControlPart::TrackVertArea)
2638 case ControlType::Fixedline
:
2639 if (nPart
== ControlPart::SeparatorVert
|| nPart
== ControlPart::SeparatorHorz
)
2643 case ControlType::ListHeader
:
2644 if (nPart
== ControlPart::Button
|| nPart
== ControlPart::Arrow
)
2650 SAL_INFO("vcl.gtk", "Unhandled is native supported for Type:" << static_cast<int>(nType
) << ", Part" << static_cast<int>(nPart
));
2655 #if ENABLE_CAIRO_CANVAS
2657 bool GtkSalGraphics::SupportsCairo() const
2662 cairo::SurfaceSharedPtr
GtkSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr
& rSurface
) const
2664 return std::make_shared
<cairo::Gtk3Surface
>(rSurface
);
2667 cairo::SurfaceSharedPtr
GtkSalGraphics::CreateSurface(const OutputDevice
& /*rRefDevice*/, int x
, int y
, int width
, int height
) const
2669 return std::make_shared
<cairo::Gtk3Surface
>(this, x
, y
, width
, height
);
2674 void GtkSalGraphics::WidgetQueueDraw() const
2676 //request gtk to sync the entire contents
2677 GtkWidget
*pWidget
= GTK_WIDGET(mpFrame
->getFixedContainer());
2678 gtk_widget_queue_draw(pWidget
);
2683 void getStyleContext(GtkStyleContext
** style
, GtkWidget
* widget
)
2685 gtk_container_add(GTK_CONTAINER(gDumbContainer
), widget
);
2686 *style
= gtk_widget_get_style_context(widget
);
2687 g_object_ref(*style
);
2692 void GtkSalData::initNWF()
2694 ImplSVData
* pSVData
= ImplGetSVData();
2695 pSVData
->maNWFData
.mbFlatMenu
= true;
2696 pSVData
->maNWFData
.mbDockingAreaAvoidTBFrames
= true;
2697 pSVData
->maNWFData
.mbCanDrawWidgetAnySize
= true;
2698 pSVData
->maNWFData
.mbDDListBoxNoTextArea
= true;
2699 pSVData
->maNWFData
.mbNoFocusRects
= true;
2700 pSVData
->maNWFData
.mbNoFocusRectsForFlatButtons
= true;
2701 pSVData
->maNWFData
.mbAutoAccel
= true;
2703 #if defined(GDK_WINDOWING_WAYLAND)
2704 //gnome#768128 for the car crash that is wayland
2705 //and floating dockable toolbars
2706 GdkDisplay
*pDisplay
= gdk_display_get_default();
2707 if (DLSYM_GDK_IS_WAYLAND_DISPLAY(pDisplay
))
2708 pSVData
->maNWFData
.mbCanDetermineWindowPosition
= false;
2712 void GtkSalData::deInitNWF()
2715 gtk_widget_destroy(gCacheWindow
);
2718 GtkSalGraphics::GtkSalGraphics( GtkSalFrame
*pFrame
, GtkWidget
*pWindow
)
2726 style_loaded
= true;
2728 /* Load the GtkStyleContexts, it might be a bit slow, but usually,
2729 * gtk apps create a lot of widgets at startup, so, it shouldn't be
2732 gCacheWindow
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
2733 gDumbContainer
= gtk_fixed_new();
2734 gtk_container_add(GTK_CONTAINER(gCacheWindow
), gDumbContainer
);
2735 gtk_widget_realize(gDumbContainer
);
2736 gtk_widget_realize(gCacheWindow
);
2738 gEntryBox
= gtk_entry_new();
2739 gtk_container_add(GTK_CONTAINER(gDumbContainer
), gEntryBox
);
2741 mpWindowStyle
= createStyleContext(GtkControlPart::ToplevelWindow
);
2742 mpEntryStyle
= createStyleContext(GtkControlPart::Entry
);
2744 getStyleContext(&mpTextViewStyle
, gtk_text_view_new());
2746 mpButtonStyle
= createStyleContext(GtkControlPart::Button
);
2747 mpLinkButtonStyle
= createStyleContext(GtkControlPart::LinkButton
);
2749 GtkWidget
* pToolbar
= gtk_toolbar_new();
2750 mpToolbarStyle
= gtk_widget_get_style_context(pToolbar
);
2751 gtk_style_context_add_class(mpToolbarStyle
, GTK_STYLE_CLASS_TOOLBAR
);
2753 GtkToolItem
*item
= gtk_separator_tool_item_new();
2754 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar
), item
, -1);
2755 mpToolbarSeparatorStyle
= gtk_widget_get_style_context(GTK_WIDGET(item
));
2757 GtkWidget
*pButton
= gtk_button_new();
2758 item
= gtk_tool_button_new(pButton
, nullptr);
2759 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar
), item
, -1);
2760 mpToolButtonStyle
= gtk_widget_get_style_context(GTK_WIDGET(pButton
));
2762 mpVScrollbarStyle
= createStyleContext(GtkControlPart::ScrollbarVertical
);
2763 mpVScrollbarContentsStyle
= createStyleContext(GtkControlPart::ScrollbarVerticalContents
);
2764 mpVScrollbarTroughStyle
= createStyleContext(GtkControlPart::ScrollbarVerticalTrough
);
2765 mpVScrollbarSliderStyle
= createStyleContext(GtkControlPart::ScrollbarVerticalSlider
);
2766 mpVScrollbarButtonStyle
= createStyleContext(GtkControlPart::ScrollbarVerticalButton
);
2767 mpHScrollbarStyle
= createStyleContext(GtkControlPart::ScrollbarHorizontal
);
2768 mpHScrollbarContentsStyle
= createStyleContext(GtkControlPart::ScrollbarHorizontalContents
);
2769 mpHScrollbarTroughStyle
= createStyleContext(GtkControlPart::ScrollbarHorizontalTrough
);
2770 mpHScrollbarSliderStyle
= createStyleContext(GtkControlPart::ScrollbarHorizontalSlider
);
2771 mpHScrollbarButtonStyle
= createStyleContext(GtkControlPart::ScrollbarHorizontalButton
);
2773 mpCheckButtonStyle
= createStyleContext(GtkControlPart::CheckButton
);
2774 mpCheckButtonCheckStyle
= createStyleContext(GtkControlPart::CheckButtonCheck
);
2776 mpRadioButtonStyle
= createStyleContext(GtkControlPart::RadioButton
);
2777 mpRadioButtonRadioStyle
= createStyleContext(GtkControlPart::RadioButtonRadio
);
2780 gSpinBox
= gtk_spin_button_new(nullptr, 0, 0);
2781 gtk_container_add(GTK_CONTAINER(gDumbContainer
), gSpinBox
);
2782 mpSpinStyle
= createStyleContext(GtkControlPart::SpinButton
);
2783 mpSpinUpStyle
= createStyleContext(GtkControlPart::SpinButtonUpButton
);
2784 mpSpinDownStyle
= createStyleContext(GtkControlPart::SpinButtonDownButton
);
2787 mpNotebookStyle
= createStyleContext(GtkControlPart::Notebook
);
2788 mpNotebookStackStyle
= createStyleContext(GtkControlPart::NotebookStack
);
2789 mpNotebookHeaderStyle
= createStyleContext(GtkControlPart::NotebookHeader
);
2790 mpNotebookHeaderTabsStyle
= createStyleContext(GtkControlPart::NotebookHeaderTabs
);
2791 mpNotebookHeaderTabsTabStyle
= createStyleContext(GtkControlPart::NotebookHeaderTabsTab
);
2792 mpNotebookHeaderTabsTabLabelStyle
= createStyleContext(GtkControlPart::NotebookHeaderTabsTabLabel
);
2793 mpNotebookHeaderTabsTabActiveLabelStyle
= createStyleContext(GtkControlPart::NotebookHeaderTabsTabActiveLabel
);
2794 mpNotebookHeaderTabsTabHoverLabelStyle
= createStyleContext(GtkControlPart::NotebookHeaderTabsTabHoverLabel
);
2797 gComboBox
= gtk_combo_box_text_new_with_entry();
2798 gtk_container_add(GTK_CONTAINER(gDumbContainer
), gComboBox
);
2799 mpComboboxStyle
= createStyleContext(GtkControlPart::Combobox
);
2800 mpComboboxBoxStyle
= createStyleContext(GtkControlPart::ComboboxBox
);
2801 mpComboboxEntryStyle
= createStyleContext(GtkControlPart::ComboboxBoxEntry
);
2802 mpComboboxButtonStyle
= createStyleContext(GtkControlPart::ComboboxBoxButton
);
2803 mpComboboxButtonBoxStyle
= createStyleContext(GtkControlPart::ComboboxBoxButtonBox
);
2804 mpComboboxButtonArrowStyle
= createStyleContext(GtkControlPart::ComboboxBoxButtonBoxArrow
);
2807 gListBox
= gtk_combo_box_text_new();
2808 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gListBox
), "sample");
2809 gtk_container_add(GTK_CONTAINER(gDumbContainer
), gListBox
);
2810 mpListboxStyle
= createStyleContext(GtkControlPart::Listbox
);
2811 mpListboxBoxStyle
= createStyleContext(GtkControlPart::ListboxBox
);
2812 mpListboxButtonStyle
= createStyleContext(GtkControlPart::ListboxBoxButton
);
2813 mpListboxButtonBoxStyle
= createStyleContext(GtkControlPart::ListboxBoxButtonBox
);
2814 mpListboxButtonArrowStyle
= createStyleContext(GtkControlPart::ListboxBoxButtonBoxArrow
);
2816 mpMenuBarStyle
= createStyleContext(GtkControlPart::MenuBar
);
2817 mpMenuBarItemStyle
= createStyleContext(GtkControlPart::MenuBarItem
);
2820 mpMenuWindowStyle
= createStyleContext(GtkControlPart::MenuWindow
);
2821 mpMenuStyle
= createStyleContext(GtkControlPart::Menu
);
2823 mpMenuItemStyle
= createStyleContext(GtkControlPart::MenuItem
);
2824 mpMenuItemLabelStyle
= createStyleContext(GtkControlPart::MenuItemLabel
);
2825 mpMenuItemArrowStyle
= createStyleContext(GtkControlPart::MenuItemArrow
);
2826 mpCheckMenuItemStyle
= createStyleContext(GtkControlPart::CheckMenuItem
);
2827 mpCheckMenuItemCheckStyle
= createStyleContext(GtkControlPart::CheckMenuItemCheck
);
2828 mpRadioMenuItemStyle
= createStyleContext(GtkControlPart::RadioMenuItem
);
2829 mpRadioMenuItemRadioStyle
= createStyleContext(GtkControlPart::RadioMenuItemRadio
);
2830 mpSeparatorMenuItemStyle
= createStyleContext(GtkControlPart::SeparatorMenuItem
);
2831 mpSeparatorMenuItemSeparatorStyle
= createStyleContext(GtkControlPart::SeparatorMenuItemSeparator
);
2834 mpFrameOutStyle
= mpFrameInStyle
= createStyleContext(GtkControlPart::FrameBorder
);
2835 getStyleContext(&mpFixedHoriLineStyle
, gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
));
2836 getStyleContext(&mpFixedVertLineStyle
, gtk_separator_new(GTK_ORIENTATION_VERTICAL
));
2840 gTreeViewWidget
= gtk_tree_view_new();
2841 gtk_container_add(GTK_CONTAINER(gDumbContainer
), gTreeViewWidget
);
2843 GtkTreeViewColumn
* firstTreeViewColumn
= gtk_tree_view_column_new();
2844 gtk_tree_view_column_set_title(firstTreeViewColumn
, "M");
2845 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget
), firstTreeViewColumn
);
2847 GtkTreeViewColumn
* middleTreeViewColumn
= gtk_tree_view_column_new();
2848 gtk_tree_view_column_set_title(middleTreeViewColumn
, "M");
2849 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget
), middleTreeViewColumn
);
2850 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gTreeViewWidget
), middleTreeViewColumn
);
2852 GtkTreeViewColumn
* lastTreeViewColumn
= gtk_tree_view_column_new();
2853 gtk_tree_view_column_set_title(lastTreeViewColumn
, "M");
2854 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget
), lastTreeViewColumn
);
2856 /* Use the middle column's header for our button */
2857 GtkWidget
* pTreeHeaderCellWidget
= gtk_tree_view_column_get_button(middleTreeViewColumn
);
2858 mpTreeHeaderButtonStyle
= gtk_widget_get_style_context(pTreeHeaderCellWidget
);
2861 mpProgressBarStyle
= createStyleContext(GtkControlPart::ProgressBar
);
2862 mpProgressBarTroughStyle
= createStyleContext(GtkControlPart::ProgressBarTrough
);
2863 mpProgressBarProgressStyle
= createStyleContext(GtkControlPart::ProgressBarProgress
);
2865 gtk_widget_show_all(gDumbContainer
);
2868 void GtkSalGraphics::GetResolution(sal_Int32
& rDPIX
, sal_Int32
& rDPIY
)
2871 if ((pForceDpi
= getenv("SAL_FORCEDPI")))
2873 OString
sForceDPI(pForceDpi
);
2874 rDPIX
= rDPIY
= sForceDPI
.toInt32();
2878 GdkScreen
* pScreen
= gtk_widget_get_screen(mpWindow
);
2879 double fResolution
= -1.0;
2880 g_object_get(pScreen
, "resolution", &fResolution
, nullptr);
2882 if (fResolution
> 0.0)
2883 rDPIX
= rDPIY
= sal_Int32(fResolution
);
2888 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */