Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / vcl / unx / gtk3 / gtk3salnativewidgets-gtk.cxx
blob9ed8d7c96dc341ea1e39c381747c2818945f73f6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <sal/config.h>
12 #include <config_cairo_canvas.h>
14 #include <basegfx/range/b2ibox.hxx>
15 #include <unx/gtk/gtkframe.hxx>
16 #include <unx/gtk/gtkdata.hxx>
17 #include <unx/gtk/gtkinst.hxx>
18 #include <unx/gtk/gtkgdi.hxx>
19 #include <vcl/decoview.hxx>
20 #include <vcl/settings.hxx>
21 #include <unx/fontmanager.hxx>
22 #include "cairo_gtk3_cairo.hxx"
23 #if defined(GDK_WINDOWING_WAYLAND)
24 # include <gdk/gdkwayland.h>
25 #endif
26 #include <boost/optional.hpp>
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::mpToolbarSeperatorStyle = 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::mpSpinEntryStyle = nullptr;
52 GtkStyleContext* GtkSalGraphics::mpSpinUpStyle = nullptr;
53 GtkStyleContext* GtkSalGraphics::mpSpinDownStyle = nullptr;
54 GtkStyleContext* GtkSalGraphics::mpComboboxStyle = nullptr;
55 GtkStyleContext* GtkSalGraphics::mpComboboxBoxStyle = nullptr;
56 GtkStyleContext* GtkSalGraphics::mpComboboxEntryStyle = nullptr;
57 GtkStyleContext* GtkSalGraphics::mpComboboxButtonStyle = nullptr;
58 GtkStyleContext* GtkSalGraphics::mpComboboxButtonBoxStyle = nullptr;
59 GtkStyleContext* GtkSalGraphics::mpComboboxButtonArrowStyle = nullptr;
60 GtkStyleContext* GtkSalGraphics::mpListboxStyle = nullptr;
61 GtkStyleContext* GtkSalGraphics::mpListboxBoxStyle = nullptr;
62 GtkStyleContext* GtkSalGraphics::mpListboxButtonStyle = nullptr;
63 GtkStyleContext* GtkSalGraphics::mpListboxButtonBoxStyle= nullptr;
64 GtkStyleContext* GtkSalGraphics::mpListboxButtonArrowStyle = nullptr;
65 GtkStyleContext* GtkSalGraphics::mpFrameInStyle = nullptr;
66 GtkStyleContext* GtkSalGraphics::mpFrameOutStyle = nullptr;
67 GtkStyleContext* GtkSalGraphics::mpFixedHoriLineStyle = nullptr;
68 GtkStyleContext* GtkSalGraphics::mpFixedVertLineStyle = nullptr;
69 GtkStyleContext* GtkSalGraphics::mpTreeHeaderButtonStyle = nullptr;
70 GtkStyleContext* GtkSalGraphics::mpProgressBarStyle = nullptr;
71 GtkStyleContext* GtkSalGraphics::mpProgressBarTroughStyle = nullptr;
72 GtkStyleContext* GtkSalGraphics::mpProgressBarProgressStyle = nullptr;
73 GtkStyleContext* GtkSalGraphics::mpNotebookStyle = nullptr;
74 GtkStyleContext* GtkSalGraphics::mpNotebookStackStyle = nullptr;
75 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderStyle = nullptr;
76 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsStyle = nullptr;
77 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabStyle = nullptr;
78 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabLabelStyle = nullptr;
79 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabActiveLabelStyle = nullptr;
80 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabHoverLabelStyle = nullptr;
81 GtkStyleContext* GtkSalGraphics::mpMenuBarStyle = nullptr;
82 GtkStyleContext* GtkSalGraphics::mpMenuBarItemStyle = nullptr;
83 GtkStyleContext* GtkSalGraphics::mpMenuWindowStyle = nullptr;
84 GtkStyleContext* GtkSalGraphics::mpMenuStyle = nullptr;
85 GtkStyleContext* GtkSalGraphics::mpMenuItemStyle = nullptr;
86 GtkStyleContext* GtkSalGraphics::mpMenuItemArrowStyle = nullptr;
87 GtkStyleContext* GtkSalGraphics::mpMenuItemLabelStyle = nullptr;
88 GtkStyleContext* GtkSalGraphics::mpCheckMenuItemStyle = nullptr;
89 GtkStyleContext* GtkSalGraphics::mpCheckMenuItemCheckStyle = nullptr;
90 GtkStyleContext* GtkSalGraphics::mpRadioMenuItemStyle = nullptr;
91 GtkStyleContext* GtkSalGraphics::mpRadioMenuItemRadioStyle = nullptr;
92 GtkStyleContext* GtkSalGraphics::mpSeparatorMenuItemStyle = nullptr;
93 GtkStyleContext* GtkSalGraphics::mpSeparatorMenuItemSeparatorStyle = nullptr;
95 bool GtkSalGraphics::style_loaded = false;
96 /************************************************************************
97 * State conversion
98 ************************************************************************/
99 static GtkStateFlags NWConvertVCLStateToGTKState(ControlState nVCLState)
101 GtkStateFlags nGTKState = GTK_STATE_FLAG_NORMAL;
103 if (!( nVCLState & ControlState::ENABLED ))
105 nGTKState = GTK_STATE_FLAG_INSENSITIVE;
108 if ( nVCLState & ControlState::PRESSED )
110 nGTKState = static_cast<GtkStateFlags>(nGTKState | GTK_STATE_FLAG_ACTIVE);
113 if ( nVCLState & ControlState::ROLLOVER )
115 nGTKState = static_cast<GtkStateFlags>(nGTKState | GTK_STATE_FLAG_PRELIGHT);
118 if ( nVCLState & ControlState::SELECTED )
119 nGTKState = static_cast<GtkStateFlags>(nGTKState | GTK_STATE_FLAG_SELECTED);
121 if ( nVCLState & ControlState::FOCUSED )
122 nGTKState = static_cast<GtkStateFlags>(nGTKState | GTK_STATE_FLAG_FOCUSED);
124 if (AllSettings::GetLayoutRTL())
126 nGTKState = static_cast<GtkStateFlags>(nGTKState | GTK_STATE_FLAG_DIR_RTL);
128 else
130 nGTKState = static_cast<GtkStateFlags>(nGTKState | GTK_STATE_FLAG_DIR_LTR);
133 return nGTKState;
136 enum class RenderType {
137 BackgroundAndFrame = 1,
138 Check,
139 Background,
140 MenuSeparator,
141 ToolbarSeparator,
142 Separator,
143 Arrow,
144 Radio,
145 Scrollbar,
146 Spinbutton,
147 Combobox,
148 Expander,
149 Icon,
150 Progress,
151 TabItem,
152 Focus
155 static void NWCalcArrowRect( const tools::Rectangle& rButton, tools::Rectangle& rArrow )
157 // Size the arrow appropriately
158 Size aSize( rButton.GetWidth()/2, rButton.GetHeight()/2 );
159 rArrow.SetSize( aSize );
161 rArrow.SetPos( Point(
162 rButton.Left() + ( rButton.GetWidth() - rArrow.GetWidth() ) / 2,
163 rButton.Top() + ( rButton.GetHeight() - rArrow.GetHeight() ) / 2
164 ) );
167 tools::Rectangle GtkSalGraphics::NWGetSpinButtonRect( ControlPart nPart, tools::Rectangle aAreaRect)
169 gint w, h;
170 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
171 gint icon_size = std::max(w, h);
173 GtkBorder padding, border;
174 gtk_style_context_get_padding(mpSpinUpStyle, gtk_style_context_get_state(mpSpinUpStyle), &padding);
175 gtk_style_context_get_border(mpSpinUpStyle, gtk_style_context_get_state(mpSpinUpStyle), &border);
177 gint buttonWidth = icon_size + padding.left + padding.right +
178 border.left + border.right;
180 gint buttonHeight = icon_size + padding.top + padding.bottom +
181 border.top + border.bottom;
183 tools::Rectangle buttonRect;
184 buttonRect.SetSize(Size(buttonWidth, buttonHeight));
185 buttonRect.setY(aAreaRect.Top());
186 buttonRect.SetBottom( buttonRect.Top() + aAreaRect.GetHeight() );
187 tools::Rectangle partRect(buttonRect);
188 if ( nPart == ControlPart::ButtonUp )
190 if (AllSettings::GetLayoutRTL())
191 partRect.setX(aAreaRect.Left());
192 else
193 partRect.setX(aAreaRect.Left() + (aAreaRect.GetWidth() - buttonRect.GetWidth()));
195 else if( nPart == ControlPart::ButtonDown )
197 if (AllSettings::GetLayoutRTL())
198 partRect.setX(aAreaRect.Left() + buttonRect.GetWidth());
199 else
200 partRect.setX(aAreaRect.Left() + (aAreaRect.GetWidth() - 2 * buttonRect.GetWidth()));
202 else
204 if (AllSettings::GetLayoutRTL())
206 partRect.SetRight( aAreaRect.Left() + aAreaRect.GetWidth() );
207 partRect.SetLeft( aAreaRect.Left() + (2 * buttonRect.GetWidth()) - 1 );
209 else
211 partRect.SetRight( (aAreaRect.Left() + (aAreaRect.GetWidth() - 2 * buttonRect.GetWidth())) - 1 );
212 partRect.SetLeft( aAreaRect.Left() );
214 partRect.SetTop( aAreaRect.Top() );
215 partRect.SetBottom( aAreaRect.Bottom() );
218 return partRect;
221 namespace
223 void QuerySize(GtkStyleContext *pContext, Size &rSize)
225 GtkBorder margin, border, padding;
227 gtk_style_context_get_margin(pContext, gtk_style_context_get_state(pContext), &margin);
228 gtk_style_context_get_border(pContext, gtk_style_context_get_state(pContext), &border);
229 gtk_style_context_get_padding(pContext, gtk_style_context_get_state(pContext), &padding);
231 int nMinWidth, nMinHeight;
232 gtk_style_context_get(pContext, gtk_style_context_get_state(pContext),
233 "min-width", &nMinWidth, "min-height", &nMinHeight, nullptr);
235 nMinWidth += margin.left + margin.right + border.left + border.right + padding.left + padding.right;
236 nMinHeight += margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom;
238 rSize = Size(std::max<long>(rSize.Width(), nMinWidth), std::max<long>(rSize.Height(), nMinHeight));
242 tools::Rectangle GtkSalGraphics::NWGetScrollButtonRect( ControlPart nPart, tools::Rectangle aAreaRect )
244 tools::Rectangle buttonRect;
246 gboolean has_forward;
247 gboolean has_forward2;
248 gboolean has_backward;
249 gboolean has_backward2;
251 GtkStyleContext* pScrollbarStyle = nullptr;
252 if ((nPart == ControlPart::ButtonLeft) || (nPart == ControlPart::ButtonRight))
253 pScrollbarStyle = mpHScrollbarStyle;
254 else // (nPart == ControlPart::ButtonUp) || (nPart == ControlPart::ButtonDown)
255 pScrollbarStyle = mpVScrollbarStyle;
257 gtk_style_context_get_style( pScrollbarStyle,
258 "has-forward-stepper", &has_forward,
259 "has-secondary-forward-stepper", &has_forward2,
260 "has-backward-stepper", &has_backward,
261 "has-secondary-backward-stepper", &has_backward2, nullptr );
262 gint buttonWidth;
263 gint buttonHeight;
265 gint nFirst = 0;
266 gint nSecond = 0;
268 if ( has_forward ) nSecond += 1;
269 if ( has_forward2 ) nFirst += 1;
270 if ( has_backward ) nFirst += 1;
271 if ( has_backward2 ) nSecond += 1;
273 if (gtk_check_version(3, 20, 0) == nullptr)
275 Size aSize;
276 if (nPart == ControlPart::ButtonLeft || nPart == ControlPart::ButtonRight)
278 QuerySize(mpHScrollbarStyle, aSize);
279 QuerySize(mpHScrollbarContentsStyle, aSize);
280 QuerySize(mpHScrollbarButtonStyle, aSize);
282 else
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);
316 return buttonRect;
319 gint slider_width;
320 gint stepper_size;
321 gint stepper_spacing;
322 gint trough_border;
324 // Grab some button style attributes
325 gtk_style_context_get_style( pScrollbarStyle,
326 "slider-width", &slider_width,
327 "stepper-size", &stepper_size,
328 "trough-border", &trough_border,
329 "stepper-spacing", &stepper_spacing, nullptr );
331 if ( ( nPart == ControlPart::ButtonUp ) || ( nPart == ControlPart::ButtonDown ) )
333 buttonWidth = slider_width + 2 * trough_border;
334 buttonHeight = stepper_size + trough_border + stepper_spacing;
336 else
338 buttonWidth = stepper_size + trough_border + stepper_spacing;
339 buttonHeight = slider_width + 2 * trough_border;
342 if ( nPart == ControlPart::ButtonUp )
344 buttonHeight *= nFirst;
345 buttonHeight -= 1;
346 buttonRect.setX( aAreaRect.Left() );
347 buttonRect.setY( aAreaRect.Top() );
349 else if ( nPart == ControlPart::ButtonLeft )
351 buttonWidth *= nFirst;
352 buttonWidth -= 1;
353 buttonRect.setX( aAreaRect.Left() );
354 buttonRect.setY( aAreaRect.Top() );
356 else if ( nPart == ControlPart::ButtonDown )
358 buttonHeight *= nSecond;
359 buttonRect.setX( aAreaRect.Left() );
360 buttonRect.setY( aAreaRect.Top() + aAreaRect.GetHeight() - buttonHeight );
362 else if ( nPart == ControlPart::ButtonRight )
364 buttonWidth *= nSecond;
365 buttonRect.setX( aAreaRect.Left() + aAreaRect.GetWidth() - buttonWidth );
366 buttonRect.setY( aAreaRect.Top() );
369 buttonRect.SetSize( Size( buttonWidth, buttonHeight ) );
371 return buttonRect;
374 static GtkWidget* gCacheWindow;
375 static GtkWidget* gDumbContainer;
376 static GtkWidget* gSpinBox;
377 static GtkWidget* gEntryBox;
378 static GtkWidget* gComboBox;
379 static GtkWidget* gListBox;
380 static GtkWidget* gMenuBarWidget;
381 static GtkWidget* gMenuItemMenuBarWidget;
382 static GtkWidget* gCheckMenuItemWidget;
383 static GtkWidget* gTreeViewWidget;
385 namespace
387 void parent_styles_context_set_state(GtkStyleContext* context, GtkStateFlags flags)
389 while ((context = gtk_style_context_get_parent(context)))
391 gtk_style_context_set_state(context, flags);
395 void style_context_set_state(GtkStyleContext* context, GtkStateFlags flags)
397 gtk_style_context_set_state(context, flags);
398 parent_styles_context_set_state(context, flags);
401 tools::Rectangle render_common(GtkStyleContext *pContext, cairo_t *cr, const tools::Rectangle &rIn, GtkStateFlags flags)
403 if (!pContext)
404 return rIn;
406 gtk_style_context_set_state(pContext, flags);
408 tools::Rectangle aRect(rIn);
409 GtkBorder margin;
410 gtk_style_context_get_margin(pContext, gtk_style_context_get_state(pContext), &margin);
412 aRect.AdjustLeft(margin.left );
413 aRect.AdjustTop(margin.top );
414 aRect.AdjustRight( -(margin.right) );
415 aRect.AdjustBottom( -(margin.bottom) );
417 gtk_render_background(pContext, cr, aRect.Left(), aRect.Top(),
418 aRect.GetWidth(), aRect.GetHeight());
419 gtk_render_frame(pContext, cr, aRect.Left(), aRect.Top(),
420 aRect.GetWidth(), aRect.GetHeight());
422 GtkBorder border, padding;
423 gtk_style_context_get_border(pContext, gtk_style_context_get_state(pContext), &border);
424 gtk_style_context_get_padding(pContext, gtk_style_context_get_state(pContext), &padding);
426 aRect.AdjustLeft(border.left + padding.left );
427 aRect.AdjustTop(border.top + padding.top );
428 aRect.AdjustRight( -(border.right + padding.right) );
429 aRect.AdjustBottom( -(border.bottom + padding.bottom) );
431 return aRect;
435 void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
436 cairo_t *cr,
437 const tools::Rectangle& rControlRectangle,
438 ControlPart nPart,
439 const ImplControlValue& rValue )
441 if (gtk_check_version(3, 20, 0) == nullptr)
443 assert(rValue.getType() == ControlType::Scrollbar);
444 const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(rValue);
445 tools::Rectangle scrollbarRect;
446 GtkStateFlags stateFlags;
447 GtkOrientation scrollbarOrientation;
448 tools::Rectangle thumbRect = rScrollbarVal.maThumbRect;
449 tools::Rectangle button11BoundRect = rScrollbarVal.maButton1Rect; // backward
450 tools::Rectangle button22BoundRect = rScrollbarVal.maButton2Rect; // forward
451 tools::Rectangle button12BoundRect = rScrollbarVal.maButton1Rect; // secondary forward
452 tools::Rectangle button21BoundRect = rScrollbarVal.maButton2Rect; // secondary backward
453 gdouble arrow1Angle; // backward
454 gdouble arrow2Angle; // forward
455 tools::Rectangle arrowRect;
456 gint slider_width = 0;
457 gint stepper_size = 0;
459 // make controlvalue rectangles relative to area
460 thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
461 button11BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
462 button22BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
463 button12BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
464 button21BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
466 // Find the overall bounding rect of the control
467 scrollbarRect = rControlRectangle;
468 if (scrollbarRect.GetWidth() <= 0 || scrollbarRect.GetHeight() <= 0)
469 return;
471 gint slider_side;
472 Size aSize;
473 if (nPart == ControlPart::DrawBackgroundHorz)
475 QuerySize(mpHScrollbarStyle, aSize);
476 QuerySize(mpHScrollbarContentsStyle, aSize);
477 QuerySize(mpHScrollbarTroughStyle, aSize);
478 QuerySize(mpHScrollbarSliderStyle, aSize);
479 slider_side = aSize.Height();
480 gtk_style_context_get(mpHScrollbarButtonStyle,
481 gtk_style_context_get_state(mpHScrollbarButtonStyle),
482 "min-height", &slider_width,
483 "min-width", &stepper_size, nullptr);
485 else
487 QuerySize(mpVScrollbarStyle, aSize);
488 QuerySize(mpVScrollbarContentsStyle, aSize);
489 QuerySize(mpVScrollbarTroughStyle, aSize);
490 QuerySize(mpVScrollbarSliderStyle, aSize);
491 slider_side = aSize.Width();
492 gtk_style_context_get(mpVScrollbarButtonStyle,
493 gtk_style_context_get_state(mpVScrollbarButtonStyle),
494 "min-width", &slider_width,
495 "min-height", &stepper_size, nullptr);
498 gboolean has_forward;
499 gboolean has_forward2;
500 gboolean has_backward;
501 gboolean has_backward2;
503 gtk_style_context_get_style( context,
504 "has-forward-stepper", &has_forward,
505 "has-secondary-forward-stepper", &has_forward2,
506 "has-backward-stepper", &has_backward,
507 "has-secondary-backward-stepper", &has_backward2, nullptr );
509 if ( nPart == ControlPart::DrawBackgroundHorz )
511 // Center vertically in the track
512 scrollbarRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
513 scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), slider_side ) );
514 thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
515 thumbRect.SetSize( Size( thumbRect.GetWidth(), slider_side ) );
517 scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
518 arrow1Angle = G_PI * 3 / 2;
519 arrow2Angle = G_PI / 2;
521 if ( has_backward )
523 button12BoundRect.Move( stepper_size,
524 (scrollbarRect.GetHeight() - slider_width) / 2 );
527 button11BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
528 button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
529 button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
531 if ( has_backward2 )
533 button22BoundRect.Move( stepper_size, (scrollbarRect.GetHeight() - slider_width) / 2 );
534 button21BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
536 else
538 button22BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
541 button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
542 button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
544 else
546 // Center horizontally in the track
547 scrollbarRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
548 scrollbarRect.SetSize( Size( slider_side, scrollbarRect.GetHeight() ) );
549 thumbRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
550 thumbRect.SetSize( Size( slider_side, thumbRect.GetHeight() ) );
552 scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
553 arrow1Angle = 0;
554 arrow2Angle = G_PI;
556 if ( has_backward )
558 button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
559 stepper_size );
561 button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
562 button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
563 button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
565 if ( has_backward2 )
567 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size );
568 button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
570 else
572 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
575 button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
576 button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
579 bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
581 // ----------------- CONTENTS
582 GtkStyleContext* pScrollbarContentsStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
583 mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
585 gtk_render_background(gtk_widget_get_style_context(gCacheWindow), cr, 0, 0,
586 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
588 gtk_render_background(context, cr, 0, 0,
589 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
590 gtk_render_frame(context, cr, 0, 0,
591 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
593 gtk_render_background(pScrollbarContentsStyle, cr, 0, 0,
594 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
595 gtk_render_frame(pScrollbarContentsStyle, cr, 0, 0,
596 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
598 bool backwardButtonInsensitive =
599 rScrollbarVal.mnCur == rScrollbarVal.mnMin;
600 bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
601 rScrollbarVal.mnCur + rScrollbarVal.mnVisibleSize >= rScrollbarVal.mnMax;
603 // ----------------- BUTTON 1
604 if ( has_backward )
606 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
607 if ( backwardButtonInsensitive )
608 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
610 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
611 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
613 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
615 gtk_render_background(pScrollbarButtonStyle, cr,
616 button11BoundRect.Left(), button11BoundRect.Top(),
617 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
618 gtk_render_frame(pScrollbarButtonStyle, cr,
619 button11BoundRect.Left(), button11BoundRect.Top(),
620 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
622 // ----------------- ARROW 1
623 NWCalcArrowRect( button11BoundRect, arrowRect );
624 gtk_render_arrow(pScrollbarButtonStyle, cr,
625 arrow1Angle,
626 arrowRect.Left(), arrowRect.Top(),
627 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
629 if ( has_forward2 )
631 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
632 if ( forwardButtonInsensitive )
633 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
635 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
636 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
638 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
640 gtk_render_background(pScrollbarButtonStyle, cr,
641 button12BoundRect.Left(), button12BoundRect.Top(),
642 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
643 gtk_render_frame(pScrollbarButtonStyle, cr,
644 button12BoundRect.Left(), button12BoundRect.Top(),
645 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
647 // ----------------- ARROW 1
648 NWCalcArrowRect( button12BoundRect, arrowRect );
649 gtk_render_arrow(pScrollbarButtonStyle, cr,
650 arrow2Angle,
651 arrowRect.Left(), arrowRect.Top(),
652 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
654 // ----------------- BUTTON 2
656 if ( has_forward )
658 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
659 if ( forwardButtonInsensitive )
660 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
662 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
663 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
665 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
667 gtk_render_background(pScrollbarButtonStyle, cr,
668 button22BoundRect.Left(), button22BoundRect.Top(),
669 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
670 gtk_render_frame(pScrollbarButtonStyle, cr,
671 button22BoundRect.Left(), button22BoundRect.Top(),
672 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
674 // ----------------- ARROW 2
675 NWCalcArrowRect( button22BoundRect, arrowRect );
676 gtk_render_arrow(pScrollbarButtonStyle, cr,
677 arrow2Angle,
678 arrowRect.Left(), arrowRect.Top(),
679 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
682 if ( has_backward2 )
684 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
685 if ( backwardButtonInsensitive )
686 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
688 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
689 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
691 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
693 gtk_render_background(pScrollbarButtonStyle, cr,
694 button21BoundRect.Left(), button21BoundRect.Top(),
695 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
696 gtk_render_frame(pScrollbarButtonStyle, cr,
697 button21BoundRect.Left(), button21BoundRect.Top(),
698 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
700 // ----------------- ARROW 2
701 NWCalcArrowRect( button21BoundRect, arrowRect );
702 gtk_render_arrow(pScrollbarButtonStyle, cr,
703 arrow1Angle,
704 arrowRect.Left(), arrowRect.Top(),
705 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
708 // ----------------- TROUGH
709 // trackrect matches that of ScrollBar::ImplCalc
710 tools::Rectangle aTrackRect(Point(0, 0), scrollbarRect.GetSize());
711 if (nPart == ControlPart::DrawBackgroundHorz)
713 tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonLeft, aTrackRect);
714 tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonRight, aTrackRect);
715 aTrackRect.SetLeft( aBtn1Rect.Right() );
716 aTrackRect.SetRight( aBtn2Rect.Left() );
718 else
720 tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonUp, aTrackRect);
721 tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonDown, aTrackRect);
722 aTrackRect.SetTop( aBtn1Rect.Bottom() + 1 );
723 aTrackRect.SetBottom( aBtn2Rect.Top() );
726 GtkStyleContext* pScrollbarTroughStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
727 mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
728 gtk_render_background(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
729 aTrackRect.GetWidth(), aTrackRect.GetHeight() );
730 gtk_render_frame(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
731 aTrackRect.GetWidth(), aTrackRect.GetHeight() );
733 // ----------------- THUMB
734 if ( has_slider )
736 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnThumbState);
737 if ( rScrollbarVal.mnThumbState & ControlState::PRESSED )
738 stateFlags = static_cast<GtkStateFlags>(stateFlags | GTK_STATE_PRELIGHT);
740 GtkStyleContext* pScrollbarSliderStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
741 mpVScrollbarSliderStyle : mpHScrollbarSliderStyle;
743 gtk_style_context_set_state(pScrollbarSliderStyle, stateFlags);
745 GtkBorder margin;
746 gtk_style_context_get_margin(pScrollbarSliderStyle, stateFlags, &margin);
748 gtk_render_background(pScrollbarSliderStyle, cr,
749 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
750 thumbRect.GetWidth() - margin.left - margin.right,
751 thumbRect.GetHeight() - margin.top - margin.bottom);
753 gtk_render_frame(pScrollbarSliderStyle, cr,
754 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
755 thumbRect.GetWidth() - margin.left - margin.right,
756 thumbRect.GetHeight() - margin.top - margin.bottom);
759 return;
762 OSL_ASSERT( rValue.getType() == ControlType::Scrollbar );
763 const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(rValue);
764 tools::Rectangle scrollbarRect;
765 GtkStateFlags stateFlags;
766 GtkOrientation scrollbarOrientation;
767 tools::Rectangle thumbRect = rScrollbarVal.maThumbRect;
768 tools::Rectangle button11BoundRect = rScrollbarVal.maButton1Rect; // backward
769 tools::Rectangle button22BoundRect = rScrollbarVal.maButton2Rect; // forward
770 tools::Rectangle button12BoundRect = rScrollbarVal.maButton1Rect; // secondary forward
771 tools::Rectangle button21BoundRect = rScrollbarVal.maButton2Rect; // secondary backward
772 gdouble arrow1Angle; // backward
773 gdouble arrow2Angle; // forward
774 tools::Rectangle arrowRect;
775 gint slider_width = 0;
776 gint stepper_size = 0;
777 gint trough_border = 0;
779 // make controlvalue rectangles relative to area
780 thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
781 button11BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
782 button22BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
783 button12BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
784 button21BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
786 // Find the overall bounding rect of the control
787 scrollbarRect = rControlRectangle;
788 scrollbarRect.SetSize( Size( scrollbarRect.GetWidth() + 1,
789 scrollbarRect.GetHeight() + 1 ) );
791 if ( (scrollbarRect.GetWidth() <= 1) || (scrollbarRect.GetHeight() <= 1) )
792 return;
794 // Grab some button style attributes
795 gtk_style_context_get_style( context,
796 "slider_width", &slider_width,
797 "stepper_size", &stepper_size,
798 "trough_border", &trough_border, nullptr );
799 gboolean has_forward;
800 gboolean has_forward2;
801 gboolean has_backward;
802 gboolean has_backward2;
804 gtk_style_context_get_style( context,
805 "has-forward-stepper", &has_forward,
806 "has-secondary-forward-stepper", &has_forward2,
807 "has-backward-stepper", &has_backward,
808 "has-secondary-backward-stepper", &has_backward2, nullptr );
809 gint magic = trough_border ? 1 : 0;
810 gint slider_side = slider_width + (trough_border * 2);
812 if ( nPart == ControlPart::DrawBackgroundHorz )
814 scrollbarRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
815 scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), slider_side ) );
817 scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
818 arrow1Angle = G_PI * 3 / 2;
819 arrow2Angle = G_PI / 2;
821 if ( has_backward )
823 button12BoundRect.Move( stepper_size - trough_border,
824 (scrollbarRect.GetHeight() - slider_width) / 2 );
827 button11BoundRect.Move( trough_border, (scrollbarRect.GetHeight() - slider_width) / 2 );
828 button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
829 button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
831 if ( has_backward2 )
833 button22BoundRect.Move( stepper_size+(trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
834 button21BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
836 else
838 button22BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
841 button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
842 button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
844 thumbRect.SetBottom( thumbRect.Top() + slider_width - 1 );
845 // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
846 // but if the VCL gives us a size smaller than the theme's default thumb size,
847 // honor the VCL size
848 thumbRect.AdjustRight(magic );
849 // Center vertically in the track
850 thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
852 else
854 scrollbarRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
855 scrollbarRect.SetSize( Size( slider_side, scrollbarRect.GetHeight() ) );
857 scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
858 arrow1Angle = 0;
859 arrow2Angle = G_PI;
861 if ( has_backward )
863 button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
864 stepper_size + trough_border );
866 button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, trough_border );
867 button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
868 button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
870 if ( has_backward2 )
872 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size+(trough_border+1)/2 );
873 button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
875 else
877 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
880 button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
881 button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
883 thumbRect.SetRight( thumbRect.Left() + slider_width - 1 );
885 thumbRect.AdjustBottom(magic );
886 // Center horizontally in the track
887 thumbRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
890 bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
892 // ----------------- CONTENTS
893 GtkStyleContext* pScrollbarContentsStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
894 mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
896 gtk_render_background(gtk_widget_get_style_context(gCacheWindow), cr, 0, 0,
897 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
899 gtk_render_background(context, cr, 0, 0,
900 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
901 gtk_render_frame(context, cr, 0, 0,
902 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
904 gtk_render_background(pScrollbarContentsStyle, cr, 0, 0,
905 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
906 gtk_render_frame(pScrollbarContentsStyle, cr, 0, 0,
907 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
909 // ----------------- TROUGH
910 GtkStyleContext* pScrollbarTroughStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
911 mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
912 gtk_render_background(pScrollbarTroughStyle, cr, 0, 0,
913 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
914 gtk_render_frame(pScrollbarTroughStyle, cr, 0, 0,
915 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
917 // ----------------- THUMB
918 if ( has_slider )
920 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnThumbState);
921 if ( rScrollbarVal.mnThumbState & ControlState::PRESSED )
922 stateFlags = static_cast<GtkStateFlags>(stateFlags | GTK_STATE_PRELIGHT);
924 GtkStyleContext* pScrollbarSliderStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
925 mpVScrollbarSliderStyle : mpHScrollbarSliderStyle;
927 gtk_style_context_set_state(pScrollbarSliderStyle, stateFlags);
929 GtkBorder margin;
930 gtk_style_context_get_margin(pScrollbarSliderStyle, stateFlags, &margin);
932 gtk_render_background(pScrollbarSliderStyle, cr,
933 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
934 thumbRect.GetWidth() - margin.left - margin.right,
935 thumbRect.GetHeight() - margin.top - margin.bottom);
937 gtk_render_frame(pScrollbarSliderStyle, cr,
938 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
939 thumbRect.GetWidth() - margin.left - margin.right,
940 thumbRect.GetHeight() - margin.top - margin.bottom);
943 bool backwardButtonInsensitive =
944 rScrollbarVal.mnCur == rScrollbarVal.mnMin;
945 bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
946 rScrollbarVal.mnCur + rScrollbarVal.mnVisibleSize >= rScrollbarVal.mnMax;
948 // ----------------- BUTTON 1
949 if ( has_backward )
951 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
952 if ( backwardButtonInsensitive )
953 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
955 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
956 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
958 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
960 gtk_render_background(pScrollbarButtonStyle, cr,
961 button11BoundRect.Left(), button11BoundRect.Top(),
962 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
963 gtk_render_frame(pScrollbarButtonStyle, cr,
964 button11BoundRect.Left(), button11BoundRect.Top(),
965 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
967 // ----------------- ARROW 1
968 NWCalcArrowRect( button11BoundRect, arrowRect );
969 gtk_render_arrow(pScrollbarButtonStyle, cr,
970 arrow1Angle,
971 arrowRect.Left(), arrowRect.Top(),
972 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
974 if ( has_forward2 )
976 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
977 if ( forwardButtonInsensitive )
978 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
980 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
981 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
983 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
985 gtk_render_background(pScrollbarButtonStyle, cr,
986 button12BoundRect.Left(), button12BoundRect.Top(),
987 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
988 gtk_render_frame(pScrollbarButtonStyle, cr,
989 button12BoundRect.Left(), button12BoundRect.Top(),
990 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
992 // ----------------- ARROW 1
993 NWCalcArrowRect( button12BoundRect, arrowRect );
994 gtk_render_arrow(pScrollbarButtonStyle, cr,
995 arrow2Angle,
996 arrowRect.Left(), arrowRect.Top(),
997 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
999 // ----------------- BUTTON 2
1000 if ( has_backward2 )
1002 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
1003 if ( backwardButtonInsensitive )
1004 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
1006 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
1007 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
1009 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
1011 gtk_render_background(pScrollbarButtonStyle, cr,
1012 button21BoundRect.Left(), button21BoundRect.Top(),
1013 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
1014 gtk_render_frame(pScrollbarButtonStyle, cr,
1015 button21BoundRect.Left(), button21BoundRect.Top(),
1016 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
1018 // ----------------- ARROW 2
1019 NWCalcArrowRect( button21BoundRect, arrowRect );
1020 gtk_render_arrow(pScrollbarButtonStyle, cr,
1021 arrow1Angle,
1022 arrowRect.Left(), arrowRect.Top(),
1023 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
1025 if ( has_forward )
1027 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
1028 if ( forwardButtonInsensitive )
1029 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
1031 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
1032 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
1034 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
1036 gtk_render_background(pScrollbarButtonStyle, cr,
1037 button22BoundRect.Left(), button22BoundRect.Top(),
1038 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
1039 gtk_render_frame(pScrollbarButtonStyle, cr,
1040 button22BoundRect.Left(), button22BoundRect.Top(),
1041 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
1043 // ----------------- ARROW 2
1044 NWCalcArrowRect( button22BoundRect, arrowRect );
1045 gtk_render_arrow(pScrollbarButtonStyle, cr,
1046 arrow2Angle,
1047 arrowRect.Left(), arrowRect.Top(),
1048 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
1052 void GtkSalGraphics::PaintOneSpinButton( GtkStyleContext *context,
1053 cairo_t *cr,
1054 ControlPart nPart,
1055 tools::Rectangle aAreaRect,
1056 ControlState nState )
1058 GtkBorder padding, border;
1060 GtkStateFlags stateFlags = NWConvertVCLStateToGTKState(nState);
1061 tools::Rectangle buttonRect = NWGetSpinButtonRect( nPart, aAreaRect );
1063 gtk_style_context_set_state(context, stateFlags);
1065 gtk_style_context_get_padding(context, gtk_style_context_get_state(context), &padding);
1066 gtk_style_context_get_border(context, gtk_style_context_get_state(context), &border);
1068 gtk_render_background(context, cr,
1069 buttonRect.Left(), buttonRect.Top(),
1070 buttonRect.GetWidth(), buttonRect.GetHeight() );
1072 gint iconWidth = (buttonRect.GetWidth() - padding.left - padding.right - border.left - border.right);
1073 gint iconHeight = (buttonRect.GetHeight() - padding.top - padding.bottom - border.top - border.bottom);
1075 const char* icon = (nPart == ControlPart::ButtonUp) ? "list-add-symbolic" : "list-remove-symbolic";
1076 GtkIconTheme *pIconTheme = gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow));
1078 GtkIconInfo *info = gtk_icon_theme_lookup_icon(pIconTheme, icon, std::min(iconWidth, iconHeight),
1079 static_cast<GtkIconLookupFlags>(0));
1081 GdkPixbuf *pixbuf = gtk_icon_info_load_symbolic_for_context(info, context, nullptr, nullptr);
1082 g_object_unref(info);
1084 iconWidth = gdk_pixbuf_get_width(pixbuf);
1085 iconHeight = gdk_pixbuf_get_height(pixbuf);
1086 tools::Rectangle arrowRect;
1087 arrowRect.SetSize(Size(iconWidth, iconHeight));
1088 arrowRect.setX( buttonRect.Left() + (buttonRect.GetWidth() - arrowRect.GetWidth()) / 2 );
1089 arrowRect.setY( buttonRect.Top() + (buttonRect.GetHeight() - arrowRect.GetHeight()) / 2 );
1091 gtk_render_icon(context, cr, pixbuf, arrowRect.Left(), arrowRect.Top());
1092 g_object_unref(pixbuf);
1094 gtk_render_frame(context, cr,
1095 buttonRect.Left(), buttonRect.Top(),
1096 buttonRect.GetWidth(), buttonRect.GetHeight() );
1099 void GtkSalGraphics::PaintSpinButton(GtkStateFlags flags,
1100 cairo_t *cr,
1101 const tools::Rectangle& rControlRectangle,
1102 ControlPart nPart,
1103 const ImplControlValue& rValue )
1105 const SpinbuttonValue *pSpinVal = (rValue.getType() == ControlType::SpinButtons) ? static_cast<const SpinbuttonValue *>(&rValue) : nullptr;
1106 ControlPart upBtnPart = ControlPart::ButtonUp;
1107 ControlState upBtnState = ControlState::NONE;
1108 ControlPart downBtnPart = ControlPart::ButtonDown;
1109 ControlState downBtnState = ControlState::NONE;
1111 if ( pSpinVal )
1113 upBtnPart = pSpinVal->mnUpperPart;
1114 upBtnState = pSpinVal->mnUpperState;
1116 downBtnPart = pSpinVal->mnLowerPart;
1117 downBtnState = pSpinVal->mnLowerState;
1120 if (nPart == ControlPart::Entire)
1122 gtk_style_context_set_state(mpWindowStyle, flags);
1124 gtk_render_background(mpWindowStyle, cr,
1125 0, 0,
1126 rControlRectangle.GetWidth(), rControlRectangle.GetHeight());
1128 gtk_style_context_set_state(mpSpinStyle, flags);
1130 gtk_render_background(mpSpinStyle, cr,
1131 0, 0,
1132 rControlRectangle.GetWidth(), rControlRectangle.GetHeight());
1135 cairo_translate(cr, -rControlRectangle.Left(), -rControlRectangle.Top());
1136 PaintOneSpinButton(mpSpinUpStyle, cr, upBtnPart, rControlRectangle, upBtnState );
1137 PaintOneSpinButton(mpSpinDownStyle, cr, downBtnPart, rControlRectangle, downBtnState );
1138 cairo_translate(cr, rControlRectangle.Left(), rControlRectangle.Top());
1140 if (nPart == ControlPart::Entire)
1142 gtk_render_frame(mpSpinStyle, cr,
1143 0, 0,
1144 rControlRectangle.GetWidth(), rControlRectangle.GetHeight() );
1148 #define FALLBACK_ARROW_SIZE 11 * 0.85
1150 tools::Rectangle GtkSalGraphics::NWGetComboBoxButtonRect(
1151 ControlPart nPart,
1152 tools::Rectangle aAreaRect )
1154 tools::Rectangle aButtonRect;
1156 GtkBorder padding;
1157 gtk_style_context_get_padding( mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &padding);
1159 gint nArrowWidth = FALLBACK_ARROW_SIZE;
1160 if (gtk_check_version(3, 20, 0) == nullptr)
1162 gtk_style_context_get(mpComboboxButtonArrowStyle,
1163 gtk_style_context_get_state(mpComboboxButtonArrowStyle),
1164 "min-width", &nArrowWidth, nullptr);
1167 gint nButtonWidth = nArrowWidth + padding.left + padding.right;
1168 if( nPart == ControlPart::ButtonDown )
1170 Point aPos = Point(aAreaRect.Left() + aAreaRect.GetWidth() - nButtonWidth, aAreaRect.Top());
1171 if (AllSettings::GetLayoutRTL())
1172 aPos.setX( aAreaRect.Left() );
1173 aButtonRect.SetSize( Size( nButtonWidth, aAreaRect.GetHeight() ) );
1174 aButtonRect.SetPos(aPos);
1176 else if( nPart == ControlPart::SubEdit )
1178 gint adjust_left = padding.left;
1179 gint adjust_top = padding.top;
1180 gint adjust_right = padding.right;
1181 gint adjust_bottom = padding.bottom;
1183 aButtonRect.SetSize( Size( aAreaRect.GetWidth() - nButtonWidth - (adjust_left + adjust_right),
1184 aAreaRect.GetHeight() - (adjust_top + adjust_bottom)) );
1185 Point aEditPos = aAreaRect.TopLeft();
1186 if (AllSettings::GetLayoutRTL())
1187 aEditPos.AdjustX(nButtonWidth );
1188 else
1189 aEditPos.AdjustX(adjust_left );
1190 aEditPos.AdjustY(adjust_top );
1191 aButtonRect.SetPos( aEditPos );
1194 return aButtonRect;
1197 void GtkSalGraphics::PaintCombobox( GtkStateFlags flags, cairo_t *cr,
1198 const tools::Rectangle& rControlRectangle,
1199 ControlType nType,
1200 ControlPart nPart )
1202 tools::Rectangle areaRect;
1203 tools::Rectangle buttonRect;
1204 tools::Rectangle arrowRect;
1206 // Find the overall bounding rect of the buttons's drawing area,
1207 // plus its actual draw rect excluding adornment
1208 areaRect = rControlRectangle;
1210 buttonRect = NWGetComboBoxButtonRect( ControlPart::ButtonDown, areaRect );
1212 tools::Rectangle aEditBoxRect( areaRect );
1213 aEditBoxRect.SetSize( Size( areaRect.GetWidth() - buttonRect.GetWidth(), aEditBoxRect.GetHeight() ) );
1214 if (AllSettings::GetLayoutRTL())
1215 aEditBoxRect.SetPos( Point( areaRect.Left() + buttonRect.GetWidth(), areaRect.Top() ) );
1217 gint arrow_width = FALLBACK_ARROW_SIZE, arrow_height = FALLBACK_ARROW_SIZE;
1218 if (gtk_check_version(3, 20, 0) == nullptr)
1220 if (nType == ControlType::Combobox)
1222 gtk_style_context_get(mpComboboxButtonArrowStyle,
1223 gtk_style_context_get_state(mpComboboxButtonArrowStyle),
1224 "min-width", &arrow_width, "min-height", &arrow_height, nullptr);
1226 else if (nType == ControlType::Listbox)
1228 gtk_style_context_get(mpListboxButtonArrowStyle,
1229 gtk_style_context_get_state(mpListboxButtonArrowStyle),
1230 "min-width", &arrow_width, "min-height", &arrow_height, nullptr);
1234 arrowRect.SetSize(Size(arrow_width, arrow_height));
1235 arrowRect.SetPos( Point( buttonRect.Left() + static_cast<gint>((buttonRect.GetWidth() - arrowRect.GetWidth()) / 2),
1236 buttonRect.Top() + static_cast<gint>((buttonRect.GetHeight() - arrowRect.GetHeight()) / 2) ) );
1239 tools::Rectangle aRect(Point(0, 0), Size(areaRect.GetWidth(), areaRect.GetHeight()));
1241 if (nType == ControlType::Combobox)
1243 if( nPart == ControlPart::Entire )
1245 render_common(mpComboboxStyle, cr, aRect, flags);
1246 render_common(mpComboboxBoxStyle, cr, aRect, flags);
1247 tools::Rectangle aEntryRect(Point(aEditBoxRect.Left() - areaRect.Left(),
1248 aEditBoxRect.Top() - areaRect.Top()),
1249 Size(aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight()));
1251 GtkJunctionSides eJuncSides = gtk_style_context_get_junction_sides(mpComboboxEntryStyle);
1252 if (AllSettings::GetLayoutRTL())
1253 gtk_style_context_set_junction_sides(mpComboboxEntryStyle, GTK_JUNCTION_LEFT);
1254 else
1255 gtk_style_context_set_junction_sides(mpComboboxEntryStyle, GTK_JUNCTION_RIGHT);
1256 render_common(mpComboboxEntryStyle, cr, aEntryRect, flags);
1257 gtk_style_context_set_junction_sides(mpComboboxEntryStyle, eJuncSides);
1260 tools::Rectangle aButtonRect(Point(buttonRect.Left() - areaRect.Left(), buttonRect.Top() - areaRect.Top()),
1261 Size(buttonRect.GetWidth(), buttonRect.GetHeight()));
1262 GtkJunctionSides eJuncSides = gtk_style_context_get_junction_sides(mpComboboxButtonStyle);
1263 if (AllSettings::GetLayoutRTL())
1264 gtk_style_context_set_junction_sides(mpComboboxButtonStyle, GTK_JUNCTION_RIGHT);
1265 else
1266 gtk_style_context_set_junction_sides(mpComboboxButtonStyle, GTK_JUNCTION_LEFT);
1267 render_common(mpComboboxButtonStyle, cr, aButtonRect, flags);
1268 gtk_style_context_set_junction_sides(mpComboboxButtonStyle, eJuncSides);
1270 gtk_render_arrow(mpComboboxButtonArrowStyle, cr,
1271 G_PI,
1272 (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
1273 arrowRect.GetWidth() );
1275 else if (nType == ControlType::Listbox)
1277 if( nPart == ControlPart::ListboxWindow )
1279 /* render the popup window with the menu style */
1280 gtk_render_frame(mpMenuStyle, cr,
1281 0, 0,
1282 areaRect.GetWidth(), areaRect.GetHeight());
1284 else
1286 render_common(mpListboxStyle, cr, aRect, flags);
1287 render_common(mpListboxBoxStyle, cr, aRect, flags);
1289 render_common(mpListboxButtonStyle, cr, aRect, flags);
1291 gtk_render_arrow(mpListboxButtonArrowStyle, cr,
1292 G_PI,
1293 (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
1294 arrowRect.GetWidth() );
1299 static void appendComboEntry(GtkWidgetPath* pSiblingsPath, gtk_widget_path_iter_set_object_nameFunc set_object_name)
1301 gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_ENTRY);
1302 set_object_name(pSiblingsPath, -1, "entry");
1303 gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
1306 static void appendComboButton(GtkWidgetPath* pSiblingsPath, gtk_widget_path_iter_set_object_nameFunc set_object_name)
1308 gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_BUTTON);
1309 set_object_name(pSiblingsPath, -1, "button");
1310 gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
1313 static GtkWidgetPath* buildLTRComboSiblingsPath(gtk_widget_path_iter_set_object_nameFunc set_object_name)
1315 GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
1317 appendComboEntry(pSiblingsPath, set_object_name);
1318 appendComboButton(pSiblingsPath, set_object_name);
1320 return pSiblingsPath;
1323 static GtkWidgetPath* buildRTLComboSiblingsPath(gtk_widget_path_iter_set_object_nameFunc set_object_name)
1325 GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
1327 appendComboButton(pSiblingsPath, set_object_name);
1328 appendComboEntry(pSiblingsPath, set_object_name);
1330 return pSiblingsPath;
1333 GtkStyleContext* GtkSalGraphics::makeContext(GtkWidgetPath *pPath, GtkStyleContext *pParent)
1335 GtkStyleContext* context = gtk_style_context_new();
1336 gtk_style_context_set_screen(context, gtk_window_get_screen(GTK_WINDOW(mpWindow)));
1337 gtk_style_context_set_path(context, pPath);
1338 gtk_style_context_set_parent(context, pParent);
1339 gtk_widget_path_unref(pPath);
1340 return context;
1343 GtkStyleContext* GtkSalGraphics::createNewContext(GtkControlPart ePart, gtk_widget_path_iter_set_object_nameFunc set_object_name)
1345 switch (ePart)
1347 case GtkControlPart::ToplevelWindow:
1349 GtkWidgetPath *path = gtk_widget_path_new();
1350 gtk_widget_path_append_type(path, G_TYPE_NONE);
1351 set_object_name(path, -1, "window");
1352 gtk_widget_path_iter_add_class(path, -1, "background");
1353 return makeContext(path, nullptr);
1355 case GtkControlPart::Button:
1357 GtkWidgetPath *path = gtk_widget_path_new();
1358 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1359 set_object_name(path, -1, "button");
1360 return makeContext(path, nullptr);
1362 case GtkControlPart::LinkButton:
1364 GtkWidgetPath *path = gtk_widget_path_new();
1365 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1366 set_object_name(path, -1, "button");
1367 gtk_widget_path_iter_add_class(path, -1, "link");
1368 return makeContext(path, nullptr);
1370 case GtkControlPart::CheckButton:
1372 GtkWidgetPath *path = gtk_widget_path_new();
1373 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
1374 set_object_name(path, -1, "checkbutton");
1375 return makeContext(path, nullptr);
1377 case GtkControlPart::CheckButtonCheck:
1379 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckButtonStyle));
1380 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
1381 set_object_name(path, -1, "check");
1382 return makeContext(path, mpCheckButtonStyle);
1384 case GtkControlPart::RadioButton:
1386 GtkWidgetPath *path = gtk_widget_path_new();
1387 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1388 set_object_name(path, -1, "radiobutton");
1389 return makeContext(path, nullptr);
1391 case GtkControlPart::RadioButtonRadio:
1393 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioButtonStyle));
1394 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1395 set_object_name(path, -1, "radio");
1396 return makeContext(path, mpRadioButtonStyle);
1398 case GtkControlPart::ComboboxBoxButtonBoxArrow:
1400 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonBoxStyle));
1401 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1402 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1403 set_object_name(path, -1, "arrow");
1404 return makeContext(path, mpComboboxButtonBoxStyle);
1406 case GtkControlPart::ListboxBoxButtonBoxArrow:
1408 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonBoxStyle));
1409 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1410 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1411 set_object_name(path, -1, "arrow");
1412 return makeContext(path, mpListboxButtonBoxStyle);
1414 case GtkControlPart::Entry:
1416 GtkWidgetPath *path = gtk_widget_path_new();
1417 gtk_widget_path_append_type(path, GTK_TYPE_ENTRY);
1418 set_object_name(path, -1, "entry");
1419 return makeContext(path, nullptr);
1421 case GtkControlPart::Combobox:
1422 case GtkControlPart::Listbox:
1424 GtkWidgetPath *path = gtk_widget_path_new();
1425 gtk_widget_path_append_type(path, G_TYPE_NONE);
1426 set_object_name(path, -1, "combobox");
1427 return makeContext(path, nullptr);
1429 case GtkControlPart::ComboboxBox:
1431 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxStyle));
1432 gtk_widget_path_append_type(path, G_TYPE_NONE);
1433 set_object_name(path, -1, "box");
1434 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1435 gtk_widget_path_iter_add_class(path, -1, "linked");
1436 return makeContext(path, mpComboboxStyle);
1438 case GtkControlPart::ListboxBox:
1440 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxStyle));
1441 gtk_widget_path_append_type(path, G_TYPE_NONE);
1442 set_object_name(path, -1, "box");
1443 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1444 gtk_widget_path_iter_add_class(path, -1, "linked");
1445 return makeContext(path, mpListboxStyle);
1447 case GtkControlPart::ComboboxBoxEntry:
1449 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
1450 GtkWidgetPath* pSiblingsPath;
1451 if (AllSettings::GetLayoutRTL())
1453 pSiblingsPath = buildRTLComboSiblingsPath(set_object_name);
1454 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 1);
1456 else
1458 pSiblingsPath = buildLTRComboSiblingsPath(set_object_name);
1459 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
1461 gtk_widget_path_unref(pSiblingsPath);
1462 return makeContext(path, mpComboboxBoxStyle);
1464 case GtkControlPart::ComboboxBoxButton:
1466 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
1467 GtkWidgetPath* pSiblingsPath;
1468 if (AllSettings::GetLayoutRTL())
1470 pSiblingsPath = buildRTLComboSiblingsPath(set_object_name);
1471 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
1473 else
1475 pSiblingsPath = buildLTRComboSiblingsPath(set_object_name);
1476 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 1);
1478 gtk_widget_path_unref(pSiblingsPath);
1479 return makeContext(path, mpComboboxBoxStyle);
1481 case GtkControlPart::ListboxBoxButton:
1483 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxBoxStyle));
1484 GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
1486 gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_BUTTON);
1487 set_object_name(pSiblingsPath, -1, "button");
1488 gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
1490 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
1491 gtk_widget_path_unref(pSiblingsPath);
1492 return makeContext(path, mpListboxBoxStyle);
1494 case GtkControlPart::ComboboxBoxButtonBox:
1496 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonStyle));
1497 gtk_widget_path_append_type(path, G_TYPE_NONE);
1498 set_object_name(path, -1, "box");
1499 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1500 return makeContext(path, mpComboboxButtonStyle);
1502 case GtkControlPart::ListboxBoxButtonBox:
1504 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonStyle));
1505 gtk_widget_path_append_type(path, G_TYPE_NONE);
1506 set_object_name(path, -1, "box");
1507 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1508 return makeContext(path, mpListboxButtonStyle);
1510 case GtkControlPart::SpinButton:
1512 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
1513 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1514 set_object_name(path, -1, "spinbutton");
1515 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1516 return makeContext(path, mpWindowStyle);
1518 case GtkControlPart::SpinButtonEntry:
1520 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
1521 gtk_widget_path_append_type(path, G_TYPE_NONE);
1522 set_object_name(path, -1, "entry");
1523 return makeContext(path, mpSpinStyle);
1525 case GtkControlPart::SpinButtonUpButton:
1526 case GtkControlPart::SpinButtonDownButton:
1528 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
1529 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1530 set_object_name(path, -1, "button");
1531 gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::SpinButtonUpButton ? "up" : "down");
1532 return makeContext(path, mpSpinStyle);
1534 case GtkControlPart::ScrollbarVertical:
1535 case GtkControlPart::ScrollbarHorizontal:
1537 GtkWidgetPath *path = gtk_widget_path_new();
1538 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1539 set_object_name(path, -1, "scrollbar");
1540 gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::ScrollbarVertical ? "vertical" : "horizontal");
1541 return makeContext(path, nullptr);
1543 case GtkControlPart::ScrollbarVerticalContents:
1544 case GtkControlPart::ScrollbarHorizontalContents:
1546 GtkStyleContext *pParent =
1547 (ePart == GtkControlPart::ScrollbarVerticalContents) ? mpVScrollbarStyle : mpHScrollbarStyle;
1548 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1549 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1550 set_object_name(path, -1, "contents");
1551 return makeContext(path, pParent);
1553 case GtkControlPart::ScrollbarVerticalTrough:
1554 case GtkControlPart::ScrollbarHorizontalTrough:
1556 GtkStyleContext *pParent =
1557 (ePart == GtkControlPart::ScrollbarVerticalTrough) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
1558 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1559 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1560 set_object_name(path, -1, "trough");
1561 return makeContext(path, pParent);
1563 case GtkControlPart::ScrollbarVerticalSlider:
1564 case GtkControlPart::ScrollbarHorizontalSlider:
1566 GtkStyleContext *pParent =
1567 (ePart == GtkControlPart::ScrollbarVerticalSlider) ? mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
1568 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1569 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1570 set_object_name(path, -1, "slider");
1571 return makeContext(path, pParent);
1573 case GtkControlPart::ScrollbarVerticalButton:
1574 case GtkControlPart::ScrollbarHorizontalButton:
1576 GtkStyleContext *pParent =
1577 (ePart == GtkControlPart::ScrollbarVerticalButton) ? mpVScrollbarStyle : mpHScrollbarStyle;
1578 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1579 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1580 set_object_name(path, -1, "button");
1581 return makeContext(path, pParent);
1583 case GtkControlPart::ProgressBar:
1585 GtkWidgetPath *path = gtk_widget_path_new();
1586 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1587 set_object_name(path, -1, "progressbar");
1588 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1589 return makeContext(path, nullptr);
1591 case GtkControlPart::ProgressBarTrough:
1593 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle));
1594 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1595 set_object_name(path, -1, "trough");
1596 return makeContext(path, mpProgressBarStyle);
1598 case GtkControlPart::ProgressBarProgress:
1600 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarTroughStyle));
1601 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1602 set_object_name(path, -1, "progress");
1603 return makeContext(path, mpProgressBarTroughStyle);
1605 case GtkControlPart::Notebook:
1607 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
1608 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1609 set_object_name(path, -1, "notebook");
1610 return makeContext(path, mpWindowStyle);
1612 case GtkControlPart::NotebookStack:
1614 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
1615 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1616 set_object_name(path, -1, "stack");
1617 return makeContext(path, mpNotebookStyle);
1619 case GtkControlPart::NotebookHeader:
1621 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
1622 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1623 set_object_name(path, -1, "header");
1624 gtk_widget_path_iter_add_class(path, -1, "frame");
1625 gtk_widget_path_iter_add_class(path, -1, "top");
1626 return makeContext(path, mpNotebookStyle);
1628 case GtkControlPart::NotebookHeaderTabs:
1630 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderStyle));
1631 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1632 set_object_name(path, -1, "tabs");
1633 gtk_widget_path_iter_add_class(path, -1, "top");
1634 return makeContext(path, mpNotebookHeaderStyle);
1636 case GtkControlPart::NotebookHeaderTabsTab:
1638 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsStyle));
1639 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1640 set_object_name(path, -1, "tab");
1641 gtk_widget_path_iter_add_class(path, -1, "top");
1642 return makeContext(path, mpNotebookHeaderTabsStyle);
1644 case GtkControlPart::NotebookHeaderTabsTabLabel:
1646 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
1647 gtk_widget_path_append_type(path, G_TYPE_NONE);
1648 set_object_name(path, -1, "label");
1649 return makeContext(path, mpNotebookHeaderTabsTabStyle);
1651 case GtkControlPart::NotebookHeaderTabsTabActiveLabel:
1652 case GtkControlPart::NotebookHeaderTabsTabHoverLabel:
1653 return mpNotebookHeaderTabsTabLabelStyle;
1654 case GtkControlPart::FrameBorder:
1656 GtkWidgetPath *path = gtk_widget_path_new();
1657 gtk_widget_path_append_type(path, GTK_TYPE_FRAME);
1658 set_object_name(path, -1, "frame");
1659 gtk_widget_path_iter_add_class(path, -1, "frame");
1660 return makeContext(path, nullptr);
1662 case GtkControlPart::MenuBar:
1664 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
1665 gtk_widget_path_append_type(path, GTK_TYPE_MENU_BAR);
1666 set_object_name(path, -1, "menubar");
1667 return makeContext(path, mpWindowStyle);
1669 case GtkControlPart::MenuBarItem:
1671 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarStyle));
1672 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
1673 set_object_name(path, -1, "menuitem");
1674 return makeContext(path, mpMenuBarStyle);
1676 case GtkControlPart::MenuWindow:
1678 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarItemStyle));
1679 gtk_widget_path_append_type(path, G_TYPE_NONE);
1680 set_object_name(path, -1, "window");
1681 gtk_widget_path_iter_add_class(path, -1, "background");
1682 gtk_widget_path_iter_add_class(path, -1, "popup");
1683 return makeContext(path, mpMenuBarItemStyle);
1685 case GtkControlPart::Menu:
1687 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuWindowStyle));
1688 gtk_widget_path_append_type(path, GTK_TYPE_MENU);
1689 set_object_name(path, -1, "menu");
1690 return makeContext(path, mpMenuWindowStyle);
1692 case GtkControlPart::MenuItem:
1694 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1695 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
1696 set_object_name(path, -1, "menuitem");
1697 return makeContext(path, mpMenuStyle);
1699 case GtkControlPart::MenuItemLabel:
1701 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
1702 gtk_widget_path_append_type(path, G_TYPE_NONE);
1703 set_object_name(path, -1, "label");
1704 return makeContext(path, mpMenuItemStyle);
1706 case GtkControlPart::MenuItemArrow:
1708 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
1709 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
1710 set_object_name(path, -1, "arrow");
1711 return makeContext(path, mpMenuItemStyle);
1713 case GtkControlPart::CheckMenuItem:
1715 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1716 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
1717 set_object_name(path, -1, "menuitem");
1718 return makeContext(path, mpMenuStyle);
1720 case GtkControlPart::CheckMenuItemCheck:
1722 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckMenuItemStyle));
1723 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
1724 set_object_name(path, -1, "check");
1725 return makeContext(path, mpCheckMenuItemStyle);
1727 case GtkControlPart::RadioMenuItem:
1729 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1730 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
1731 set_object_name(path, -1, "menuitem");
1732 return makeContext(path, mpMenuStyle);
1734 case GtkControlPart::RadioMenuItemRadio:
1736 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioMenuItemStyle));
1737 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
1738 set_object_name(path, -1, "radio");
1739 return makeContext(path, mpRadioMenuItemStyle);
1741 case GtkControlPart::SeparatorMenuItem:
1743 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1744 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
1745 set_object_name(path, -1, "menuitem");
1746 return makeContext(path, mpMenuStyle);
1748 case GtkControlPart::SeparatorMenuItemSeparator:
1750 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSeparatorMenuItemStyle));
1751 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
1752 set_object_name(path, -1, "separator");
1753 return makeContext(path, mpSeparatorMenuItemStyle);
1757 return nullptr;
1760 #ifndef GTK_STYLE_CLASS_POPUP
1761 #define GTK_STYLE_CLASS_POPUP "popup"
1762 #endif
1763 #ifndef GTK_STYLE_CLASS_LABEL
1764 #define GTK_STYLE_CLASS_LABEL "label"
1765 #endif
1767 GtkStyleContext* GtkSalGraphics::createOldContext(GtkControlPart ePart)
1769 switch (ePart)
1771 case GtkControlPart::ToplevelWindow:
1773 GtkWidgetPath *path = gtk_widget_path_new();
1774 gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
1775 gtk_widget_path_iter_add_class(path, -1, "background");
1776 return makeContext(path, nullptr);
1778 case GtkControlPart::Button:
1780 GtkWidgetPath *path = gtk_widget_path_new();
1781 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1782 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1783 gtk_widget_path_iter_add_class(path, -1, "button");
1784 gtk_widget_path_iter_add_class(path, -1, "text-button");
1785 return makeContext(path, nullptr);
1787 case GtkControlPart::LinkButton:
1789 GtkWidgetPath *path = gtk_widget_path_new();
1790 gtk_widget_path_append_type(path, GTK_TYPE_LINK_BUTTON);
1791 gtk_widget_path_iter_add_class(path, -1, "text-button");
1792 return makeContext(path, nullptr);
1794 case GtkControlPart::CheckButton:
1796 GtkWidgetPath *path = gtk_widget_path_new();
1797 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
1798 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
1799 gtk_widget_path_iter_add_class(path, -1, "text-button");
1800 return makeContext(path, nullptr);
1802 case GtkControlPart::CheckButtonCheck:
1803 return mpCheckButtonStyle;
1804 case GtkControlPart::RadioButton:
1806 GtkWidgetPath *path = gtk_widget_path_new();
1807 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1808 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
1809 gtk_widget_path_iter_add_class(path, -1, "text-button");
1810 return makeContext(path, nullptr);
1812 case GtkControlPart::RadioButtonRadio:
1813 return mpRadioButtonStyle;
1814 case GtkControlPart::ComboboxBoxButtonBoxArrow:
1815 case GtkControlPart::ListboxBoxButtonBoxArrow:
1817 return (ePart == GtkControlPart::ComboboxBoxButtonBoxArrow)
1818 ? mpComboboxButtonStyle : mpListboxButtonStyle;
1820 case GtkControlPart::Entry:
1821 case GtkControlPart::ComboboxBoxEntry:
1822 case GtkControlPart::SpinButtonEntry:
1824 GtkWidgetPath *path = gtk_widget_path_new();
1825 gtk_widget_path_append_type(path, GTK_TYPE_ENTRY);
1826 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ENTRY);
1827 return makeContext(path, nullptr);
1829 case GtkControlPart::Combobox:
1831 GtkWidgetPath *path = gtk_widget_path_new();
1832 gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX_TEXT);
1833 return makeContext(path, nullptr);
1835 case GtkControlPart::Listbox:
1837 GtkWidgetPath *path = gtk_widget_path_new();
1838 gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX);
1839 return makeContext(path, nullptr);
1841 case GtkControlPart::ComboboxBoxButton:
1842 case GtkControlPart::ListboxBoxButton:
1844 GtkStyleContext *pParent =
1845 (ePart == GtkControlPart::ComboboxBoxButton ) ? mpComboboxStyle : mpListboxStyle;
1846 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1847 gtk_widget_path_append_type(path, GTK_TYPE_TOGGLE_BUTTON);
1848 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1849 gtk_widget_path_iter_add_class(path, -1, "the-button-in-the-combobox");
1850 return makeContext(path, pParent);
1852 case GtkControlPart::SpinButton:
1854 GtkWidgetPath *path = gtk_widget_path_new();
1855 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1856 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ENTRY);
1857 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1858 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
1859 return makeContext(path, nullptr);
1861 case GtkControlPart::SpinButtonUpButton:
1862 case GtkControlPart::SpinButtonDownButton:
1864 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
1865 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1866 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
1867 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1868 return makeContext(path, mpSpinStyle);
1870 case GtkControlPart::ScrollbarVertical:
1871 case GtkControlPart::ScrollbarHorizontal:
1873 GtkWidgetPath *path = gtk_widget_path_new();
1874 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1875 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1876 gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::ScrollbarVertical ? "vertical" : "horizontal");
1877 return makeContext(path, nullptr);
1879 case GtkControlPart::ScrollbarVerticalContents:
1880 case GtkControlPart::ScrollbarHorizontalContents:
1882 GtkStyleContext *pParent =
1883 (ePart == GtkControlPart::ScrollbarVerticalContents) ? mpVScrollbarStyle : mpHScrollbarStyle;
1884 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1885 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1886 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1887 gtk_widget_path_iter_add_class(path, -1, "contents");
1888 return makeContext(path, pParent);
1890 case GtkControlPart::ScrollbarHorizontalTrough:
1891 case GtkControlPart::ScrollbarVerticalTrough:
1893 GtkStyleContext *pParent =
1894 (ePart == GtkControlPart::ScrollbarVerticalTrough) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
1895 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1896 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1897 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1898 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_TROUGH);
1899 return makeContext(path, pParent);
1901 case GtkControlPart::ScrollbarHorizontalSlider:
1902 case GtkControlPart::ScrollbarVerticalSlider:
1904 GtkStyleContext *pParent =
1905 (ePart == GtkControlPart::ScrollbarVerticalSlider) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
1906 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1907 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1908 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1909 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SLIDER);
1910 return makeContext(path, pParent);
1912 case GtkControlPart::ScrollbarHorizontalButton:
1913 case GtkControlPart::ScrollbarVerticalButton:
1915 GtkStyleContext *pParent =
1916 (ePart == GtkControlPart::ScrollbarVerticalButton) ? mpVScrollbarStyle : mpHScrollbarStyle;
1917 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1918 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1919 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1920 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1921 return makeContext(path, pParent);
1923 case GtkControlPart::ProgressBar:
1925 GtkWidgetPath *path = gtk_widget_path_new();
1926 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1927 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
1928 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1929 return makeContext(path, nullptr);
1931 case GtkControlPart::ProgressBarTrough:
1933 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle));
1934 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1935 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_TROUGH);
1936 return makeContext(path, mpProgressBarStyle);
1938 case GtkControlPart::ProgressBarProgress:
1940 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarTroughStyle));
1941 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1942 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
1943 return makeContext(path, mpProgressBarTroughStyle);
1945 case GtkControlPart::Notebook:
1947 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
1948 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1949 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_NOTEBOOK);
1950 gtk_widget_path_iter_add_class(path, -1, "frame");
1951 return makeContext(path, mpWindowStyle);
1953 case GtkControlPart::NotebookStack:
1954 return mpNotebookStyle;
1955 case GtkControlPart::NotebookHeader:
1957 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
1958 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
1959 gtk_widget_path_iter_add_class(path, -1, "top");
1960 return makeContext(path, gtk_style_context_get_parent(mpNotebookStyle));
1962 case GtkControlPart::NotebookHeaderTabs:
1963 return mpNotebookHeaderStyle;
1964 case GtkControlPart::NotebookHeaderTabsTab:
1966 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsStyle));
1967 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1968 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
1969 gtk_widget_path_iter_add_class(path, -1, "top");
1970 gtk_widget_path_iter_add_region(path, -1, GTK_STYLE_REGION_TAB, static_cast<GtkRegionFlags>(GTK_REGION_EVEN | GTK_REGION_FIRST));
1971 return makeContext(path, mpNotebookHeaderTabsStyle);
1973 case GtkControlPart::NotebookHeaderTabsTabLabel:
1975 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
1976 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
1977 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
1978 return makeContext(path, mpNotebookHeaderTabsTabStyle);
1980 case GtkControlPart::NotebookHeaderTabsTabActiveLabel:
1982 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
1983 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
1984 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
1985 gtk_widget_path_iter_add_class(path, -1, "active-page");
1986 return makeContext(path, mpNotebookHeaderTabsTabStyle);
1988 case GtkControlPart::NotebookHeaderTabsTabHoverLabel:
1990 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
1991 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
1992 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
1993 gtk_widget_path_iter_add_class(path, -1, "prelight-page");
1994 return makeContext(path, mpNotebookHeaderTabsTabStyle);
1996 case GtkControlPart::FrameBorder:
1998 GtkWidgetPath *path = gtk_widget_path_new();
1999 gtk_widget_path_append_type(path, GTK_TYPE_FRAME);
2000 gtk_widget_path_iter_add_class(path, -1, "frame");
2001 return makeContext(path, nullptr);
2003 case GtkControlPart::MenuBar:
2005 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
2006 gtk_widget_path_append_type(path, GTK_TYPE_MENU_BAR);
2007 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUBAR);
2008 return makeContext(path, mpWindowStyle);
2010 case GtkControlPart::MenuBarItem:
2012 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarStyle));
2013 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
2014 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2015 return makeContext(path, mpMenuBarStyle);
2017 case GtkControlPart::MenuWindow:
2019 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarItemStyle));
2020 gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
2021 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_POPUP);
2022 gtk_widget_path_iter_add_class(path, -1, "background");
2023 return makeContext(path, mpMenuBarItemStyle);
2025 case GtkControlPart::Menu:
2027 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuWindowStyle));
2028 gtk_widget_path_append_type(path, GTK_TYPE_MENU);
2029 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENU);
2030 return makeContext(path, mpMenuWindowStyle);
2032 case GtkControlPart::MenuItem:
2034 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2035 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
2036 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2037 return makeContext(path, mpMenuStyle);
2039 case GtkControlPart::MenuItemLabel:
2041 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
2042 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
2043 return makeContext(path, mpMenuItemStyle);
2045 case GtkControlPart::MenuItemArrow:
2047 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
2048 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
2049 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ARROW);
2050 return makeContext(path, mpMenuItemStyle);
2052 case GtkControlPart::CheckMenuItem:
2054 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2055 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
2056 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
2057 return makeContext(path, mpMenuStyle);
2059 case GtkControlPart::CheckMenuItemCheck:
2061 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckMenuItemStyle));
2062 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
2063 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
2064 return makeContext(path, mpCheckMenuItemStyle);
2066 case GtkControlPart::RadioMenuItem:
2068 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2069 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
2070 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2071 return makeContext(path, mpMenuStyle);
2073 case GtkControlPart::RadioMenuItemRadio:
2075 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioMenuItemStyle));
2076 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
2077 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
2078 return makeContext(path, mpRadioMenuItemStyle);
2080 case GtkControlPart::SeparatorMenuItem:
2082 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2083 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
2084 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2085 return makeContext(path, mpMenuStyle);
2087 case GtkControlPart::SeparatorMenuItemSeparator:
2089 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSeparatorMenuItemStyle));
2090 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
2091 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SEPARATOR);
2092 return makeContext(path, mpSeparatorMenuItemStyle);
2094 case GtkControlPart::ComboboxBox:
2095 case GtkControlPart::ListboxBox:
2096 case GtkControlPart::ComboboxBoxButtonBox:
2097 case GtkControlPart::ListboxBoxButtonBox:
2098 return nullptr;
2099 default:
2100 break;
2103 return mpButtonStyle;
2106 GtkStyleContext* GtkSalGraphics::createStyleContext(gtk_widget_path_iter_set_object_nameFunc set_object_name,
2107 GtkControlPart ePart)
2109 if (set_object_name)
2110 return createNewContext(ePart, set_object_name);
2111 return createOldContext(ePart);
2114 namespace
2116 GtkStateFlags ACTIVE_TAB()
2118 #if GTK_CHECK_VERSION(3,20,0)
2119 if (gtk_check_version(3, 20, 0) == nullptr)
2120 return GTK_STATE_FLAG_CHECKED;
2121 #endif
2122 return GTK_STATE_FLAG_ACTIVE;
2126 void GtkSalGraphics::PaintCheckOrRadio(cairo_t *cr, GtkStyleContext *context,
2127 const tools::Rectangle& rControlRectangle, bool bIsCheck, bool bInMenu)
2129 gint indicator_size;
2130 gtk_style_context_get_style(context, "indicator-size", &indicator_size, nullptr);
2132 gint x = (rControlRectangle.GetWidth() - indicator_size) / 2;
2133 gint y = (rControlRectangle.GetHeight() - indicator_size) / 2;
2135 if (!bInMenu)
2136 gtk_render_background(context, cr, x, y, indicator_size, indicator_size);
2138 if (bIsCheck)
2139 gtk_render_check(context, cr, x, y, indicator_size, indicator_size);
2140 else
2141 gtk_render_option(context, cr, x, y, indicator_size, indicator_size);
2143 gtk_render_frame(context, cr, x, y, indicator_size, indicator_size);
2146 void GtkSalGraphics::PaintCheck(cairo_t *cr, GtkStyleContext *context,
2147 const tools::Rectangle& rControlRectangle, bool bInMenu)
2149 PaintCheckOrRadio(cr, context, rControlRectangle, true, bInMenu);
2152 void GtkSalGraphics::PaintRadio(cairo_t *cr, GtkStyleContext *context,
2153 const tools::Rectangle& rControlRectangle, bool bInMenu)
2155 PaintCheckOrRadio(cr, context, rControlRectangle, false, bInMenu);
2158 static gfloat getArrowSize(GtkStyleContext* context)
2160 gfloat arrow_scaling = 1.0;
2161 gtk_style_context_get_style(context, "arrow-scaling", &arrow_scaling, nullptr);
2162 gfloat arrow_size = 11 * arrow_scaling;
2163 return arrow_size;
2166 bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
2167 ControlState nState, const ImplControlValue& rValue,
2168 const OUString& )
2170 RenderType renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::BackgroundAndFrame;
2171 GtkStyleContext *context = nullptr;
2172 const gchar *styleClass = nullptr;
2173 GdkPixbuf *pixbuf = nullptr;
2174 bool bInMenu = false;
2176 GtkStateFlags flags = NWConvertVCLStateToGTKState(nState);
2178 switch(nType)
2180 case ControlType::Spinbox:
2181 case ControlType::SpinButtons:
2182 context = mpSpinStyle;
2183 renderType = RenderType::Spinbutton;
2184 break;
2185 case ControlType::Editbox:
2186 context = mpEntryStyle;
2187 break;
2188 case ControlType::MultilineEditbox:
2189 context = mpTextViewStyle;
2190 break;
2191 case ControlType::Combobox:
2192 context = mpComboboxStyle;
2193 renderType = RenderType::Combobox;
2194 break;
2195 case ControlType::Listbox:
2196 if (nPart == ControlPart::Focus)
2198 renderType = RenderType::Focus;
2199 context = mpListboxButtonStyle;
2201 else
2203 renderType = RenderType::Combobox;
2204 context = mpListboxStyle;
2206 break;
2207 case ControlType::MenuPopup:
2208 bInMenu = true;
2210 // map selected menu entries in vcl parlance to gtk prelight
2211 if (nPart >= ControlPart::MenuItem && nPart <= ControlPart::SubmenuArrow && (nState & ControlState::SELECTED))
2212 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_PRELIGHT);
2213 flags = static_cast<GtkStateFlags>(flags & ~GTK_STATE_FLAG_ACTIVE);
2214 switch(nPart)
2216 case ControlPart::MenuItem:
2217 context = mpMenuItemStyle;
2218 renderType = RenderType::BackgroundAndFrame;
2219 break;
2220 case ControlPart::MenuItemCheckMark:
2221 if (gtk_check_version(3, 20, 0) == nullptr)
2222 context = mpCheckMenuItemCheckStyle;
2223 else
2225 context = gtk_widget_get_style_context(gCheckMenuItemWidget);
2226 styleClass = GTK_STYLE_CLASS_CHECK;
2228 renderType = RenderType::Check;
2229 nType = ControlType::Checkbox;
2230 if (nState & ControlState::PRESSED)
2232 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_CHECKED);
2234 break;
2235 case ControlPart::MenuItemRadioMark:
2236 if (gtk_check_version(3, 20, 0) == nullptr)
2237 context = mpRadioMenuItemRadioStyle;
2238 else
2240 context = gtk_widget_get_style_context(gCheckMenuItemWidget);
2241 styleClass = GTK_STYLE_CLASS_RADIO;
2243 renderType = RenderType::Radio;
2244 nType = ControlType::Radiobutton;
2245 if (nState & ControlState::PRESSED)
2247 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_CHECKED);
2249 break;
2250 case ControlPart::Separator:
2251 context = mpSeparatorMenuItemSeparatorStyle;
2252 flags = GtkStateFlags(GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_INSENSITIVE); //GTK_STATE_FLAG_BACKDROP hack ?
2253 renderType = RenderType::MenuSeparator;
2254 break;
2255 case ControlPart::SubmenuArrow:
2256 if (gtk_check_version(3, 20, 0) == nullptr)
2257 context = mpMenuItemArrowStyle;
2258 else
2260 context = gtk_widget_get_style_context(gCheckMenuItemWidget);
2261 styleClass = GTK_STYLE_CLASS_ARROW;
2263 renderType = RenderType::Arrow;
2264 break;
2265 case ControlPart::Entire:
2266 context = mpMenuStyle;
2267 renderType = RenderType::Background;
2268 break;
2269 default: break;
2271 break;
2272 case ControlType::Toolbar:
2273 switch(nPart)
2275 case ControlPart::DrawBackgroundHorz:
2276 case ControlPart::DrawBackgroundVert:
2277 context = mpToolbarStyle;
2278 break;
2279 case ControlPart::Button:
2280 /* For all checkbuttons in the toolbars */
2281 flags = static_cast<GtkStateFlags>(flags |
2282 ( (rValue.getTristateVal() == ButtonValue::On) ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL));
2283 context = mpToolButtonStyle;
2284 break;
2285 case ControlPart::SeparatorVert:
2286 context = mpToolbarSeperatorStyle;
2287 renderType = RenderType::ToolbarSeparator;
2288 break;
2289 default:
2290 return false;
2292 break;
2293 case ControlType::Radiobutton:
2294 flags = static_cast<GtkStateFlags>(flags |
2295 ( (rValue.getTristateVal() == ButtonValue::On) ? GTK_STATE_FLAG_CHECKED : GTK_STATE_FLAG_NORMAL));
2296 context = mpRadioButtonRadioStyle;
2297 renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::Radio;
2298 break;
2299 case ControlType::Checkbox:
2300 flags = static_cast<GtkStateFlags>(flags |
2301 ( (rValue.getTristateVal() == ButtonValue::On) ? GTK_STATE_FLAG_CHECKED :
2302 (rValue.getTristateVal() == ButtonValue::Mixed) ? GTK_STATE_FLAG_INCONSISTENT :
2303 GTK_STATE_FLAG_NORMAL));
2304 context = mpCheckButtonCheckStyle;
2305 renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::Check;
2306 break;
2307 case ControlType::Pushbutton:
2308 context = mpButtonStyle;
2309 break;
2310 case ControlType::Scrollbar:
2311 switch(nPart)
2313 case ControlPart::DrawBackgroundVert:
2314 case ControlPart::DrawBackgroundHorz:
2315 context = (nPart == ControlPart::DrawBackgroundVert)
2316 ? mpVScrollbarStyle : mpHScrollbarStyle;
2317 renderType = RenderType::Scrollbar;
2318 break;
2319 default: break;
2321 break;
2322 case ControlType::ListNet:
2323 return true;
2324 break;
2325 case ControlType::TabPane:
2326 context = mpNotebookStyle;
2327 break;
2328 case ControlType::TabBody:
2329 context = mpNotebookStackStyle;
2330 break;
2331 case ControlType::TabHeader:
2332 context = mpNotebookHeaderStyle;
2333 break;
2334 case ControlType::TabItem:
2335 context = mpNotebookHeaderTabsTabStyle;
2336 if (nState & ControlState::SELECTED)
2337 flags = static_cast<GtkStateFlags>(flags | ACTIVE_TAB());
2338 renderType = RenderType::TabItem;
2339 break;
2340 case ControlType::WindowBackground:
2341 context = gtk_widget_get_style_context(mpWindow);
2342 break;
2343 case ControlType::Frame:
2345 DrawFrameStyle nStyle = static_cast<DrawFrameStyle>(rValue.getNumericVal() & 0x0f);
2346 if (nStyle == DrawFrameStyle::In)
2347 context = mpFrameOutStyle;
2348 else
2349 context = mpFrameInStyle;
2350 break;
2352 case ControlType::Menubar:
2353 if (nPart == ControlPart::MenuItem)
2355 context = mpMenuBarItemStyle;
2357 flags = (!(nState & ControlState::ENABLED)) ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
2358 if (nState & ControlState::SELECTED)
2359 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_PRELIGHT);
2361 else
2363 context = mpMenuBarStyle;
2365 break;
2366 case ControlType::Fixedline:
2367 context = nPart == ControlPart::SeparatorHorz ? mpFixedHoriLineStyle : mpFixedVertLineStyle;
2368 renderType = RenderType::Separator;
2369 break;
2370 case ControlType::ListNode:
2372 context = mpTreeHeaderButtonStyle;
2373 ButtonValue aButtonValue = rValue.getTristateVal();
2374 if (aButtonValue == ButtonValue::On)
2375 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_CHECKED);
2376 renderType = RenderType::Expander;
2377 break;
2379 case ControlType::ListHeader:
2380 context = mpTreeHeaderButtonStyle;
2381 if (nPart == ControlPart::Arrow)
2383 const char* icon = (rValue.getNumericVal() & 1) ? "pan-down-symbolic" : "pan-up-symbolic";
2384 GtkIconTheme *pIconTheme = gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow));
2385 pixbuf = gtk_icon_theme_load_icon(pIconTheme, icon,
2386 std::max(rControlRegion.GetWidth(), rControlRegion.GetHeight()),
2387 static_cast<GtkIconLookupFlags>(0), nullptr);
2388 flags = GTK_STATE_FLAG_SELECTED;
2389 renderType = RenderType::Icon;
2391 break;
2392 case ControlType::Progress:
2393 context = mpProgressBarProgressStyle;
2394 renderType = RenderType::Progress;
2395 break;
2396 default:
2397 return false;
2400 cairo_t *cr = getCairoContext(false);
2401 clipRegion(cr);
2402 cairo_translate(cr, rControlRegion.Left(), rControlRegion.Top());
2404 long nX = 0;
2405 long nY = 0;
2406 long nWidth = rControlRegion.GetWidth();
2407 long nHeight = rControlRegion.GetHeight();
2409 style_context_set_state(context, flags);
2411 if (styleClass)
2413 gtk_style_context_add_class(context, styleClass);
2416 switch(renderType)
2418 case RenderType::Background:
2419 case RenderType::BackgroundAndFrame:
2420 gtk_render_background(context, cr, nX, nY, nWidth, nHeight);
2421 if (renderType == RenderType::BackgroundAndFrame)
2423 gtk_render_frame(context, cr, nX, nY, nWidth, nHeight);
2425 break;
2426 case RenderType::Check:
2428 PaintCheck(cr, context, rControlRegion, bInMenu);
2429 break;
2431 case RenderType::Radio:
2433 PaintRadio(cr, context, rControlRegion, bInMenu);
2434 break;
2436 case RenderType::MenuSeparator:
2437 gtk_render_line(context, cr,
2438 0, rControlRegion.GetHeight() / 2,
2439 rControlRegion.GetWidth() - 1, rControlRegion.GetHeight() / 2);
2440 break;
2441 case RenderType::ToolbarSeparator:
2443 const bool bNewStyle = gtk_check_version(3, 20, 0) == nullptr;
2445 gint nSeparatorWidth = 1;
2447 if (bNewStyle)
2449 gtk_style_context_get(context,
2450 gtk_style_context_get_state(context),
2451 "min-width", &nSeparatorWidth, nullptr);
2454 gint nHalfSeparatorWidth = nSeparatorWidth / 2;
2455 gint nHalfRegionWidth = rControlRegion.GetWidth() / 2;
2457 nX = nX + nHalfRegionWidth - nHalfSeparatorWidth;
2458 nWidth = nSeparatorWidth;
2459 nY = rControlRegion.GetHeight() * 0.1;
2460 nHeight = rControlRegion.GetHeight() - (2 * nY);
2462 if (bNewStyle)
2464 gtk_render_background(context, cr, nX, nY, nSeparatorWidth, nHeight);
2465 gtk_render_frame(context, cr, nX, nY, nSeparatorWidth, nHeight);
2467 else
2469 gtk_render_line(context, cr, nX, nY, nX, nY + nHeight);
2471 break;
2473 case RenderType::Separator:
2474 if (nPart == ControlPart::SeparatorHorz)
2475 gtk_render_line(context, cr, 0, nHeight / 2, nWidth - 1, nHeight / 2);
2476 else
2477 gtk_render_line(context, cr, nWidth / 2, 0, nWidth / 2, nHeight - 1);
2478 break;
2479 case RenderType::Arrow:
2480 gtk_render_arrow(context, cr,
2481 G_PI / 2, 0, 0,
2482 MIN(rControlRegion.GetWidth(), 1 + rControlRegion.GetHeight()));
2483 break;
2484 case RenderType::Expander:
2485 gtk_render_expander(context, cr, -2, -2, nWidth+4, nHeight+4);
2486 break;
2487 case RenderType::Scrollbar:
2488 PaintScrollbar(context, cr, rControlRegion, nPart, rValue);
2489 break;
2490 case RenderType::Spinbutton:
2491 PaintSpinButton(flags, cr, rControlRegion, nPart, rValue);
2492 break;
2493 case RenderType::Combobox:
2494 PaintCombobox(flags, cr, rControlRegion, nType, nPart);
2495 break;
2496 case RenderType::Icon:
2497 gtk_render_icon(context, cr, pixbuf, nX, nY);
2498 g_object_unref(pixbuf);
2499 break;
2500 case RenderType::Focus:
2502 if (nType != ControlType::Checkbox)
2504 GtkBorder border;
2506 gtk_style_context_get_border(context, flags, &border);
2508 nX += border.left;
2509 nY += border.top;
2510 nWidth -= border.left + border.right;
2511 nHeight -= border.top + border.bottom;
2514 gtk_render_focus(context, cr, nX, nY, nWidth, nHeight);
2516 break;
2518 case RenderType::Progress:
2520 gtk_render_background(mpProgressBarTroughStyle, cr, nX, nY, nWidth, nHeight);
2522 long nProgressWidth = rValue.getNumericVal();
2523 if (nProgressWidth)
2525 GtkBorder padding;
2526 gtk_style_context_get_padding(context, gtk_style_context_get_state(context), &padding);
2528 nX += padding.left;
2529 nY += padding.top;
2530 nHeight -= (padding.top + padding.bottom);
2531 nProgressWidth -= (padding.left + padding.right);
2532 gtk_render_background(context, cr, nX, nY, nProgressWidth, nHeight);
2533 gtk_render_frame(context, cr, nX, nY, nProgressWidth, nHeight);
2536 gtk_render_frame(mpProgressBarTroughStyle, cr, nX, nY, nWidth, nHeight);
2538 break;
2540 case RenderType::TabItem:
2542 if (gtk_check_version(3, 20, 0) != nullptr)
2544 gint initial_gap(0);
2545 gtk_style_context_get_style(mpNotebookStyle,
2546 "initial-gap", &initial_gap,
2547 nullptr);
2549 nX += initial_gap/2;
2550 nWidth -= initial_gap;
2552 tools::Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
2553 render_common(mpNotebookHeaderTabsTabStyle, cr, aRect, flags);
2554 break;
2556 default:
2557 break;
2560 if (styleClass)
2562 gtk_style_context_remove_class(context, styleClass);
2565 cairo_destroy(cr); // unref
2567 if (!rControlRegion.IsEmpty())
2568 mpFrame->damaged(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.GetWidth(), rControlRegion.GetHeight());
2570 return true;
2573 tools::Rectangle GetWidgetSize(const tools::Rectangle& rControlRegion, GtkWidget* widget)
2575 GtkRequisition aReq;
2576 gtk_widget_get_preferred_size(widget, nullptr, &aReq);
2577 long nHeight = std::max<long>(rControlRegion.GetHeight(), aReq.height);
2578 return tools::Rectangle(rControlRegion.TopLeft(), Size(rControlRegion.GetWidth(), nHeight));
2581 tools::Rectangle AdjustRectForTextBordersPadding(GtkStyleContext* pStyle, long nContentWidth, long nContentHeight, const tools::Rectangle& rControlRegion)
2583 GtkBorder border;
2584 gtk_style_context_get_border(pStyle, gtk_style_context_get_state(pStyle), &border);
2586 GtkBorder padding;
2587 gtk_style_context_get_padding(pStyle, gtk_style_context_get_state(pStyle), &padding);
2589 gint nWidgetHeight = nContentHeight + padding.top + padding.bottom + border.top + border.bottom;
2590 nWidgetHeight = std::max(std::max<gint>(nWidgetHeight, rControlRegion.GetHeight()), 34);
2592 gint nWidgetWidth = nContentWidth + padding.left + padding.right + border.left + border.right;
2593 nWidgetWidth = std::max<gint>(nWidgetWidth, rControlRegion.GetWidth());
2595 tools::Rectangle aEditRect(rControlRegion.TopLeft(), Size(nWidgetWidth, nWidgetHeight));
2597 return aEditRect;
2600 bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion, ControlState,
2601 const ImplControlValue& rValue, const OUString&,
2602 tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion )
2604 /* TODO: all this functions needs improvements */
2605 tools::Rectangle aEditRect = rControlRegion;
2606 gint indicator_size, indicator_spacing, point;
2608 if(((nType == ControlType::Checkbox) || (nType == ControlType::Radiobutton)) &&
2609 nPart == ControlPart::Entire)
2611 rNativeBoundingRegion = rControlRegion;
2613 GtkStyleContext *pButtonStyle = (nType == ControlType::Checkbox) ? mpCheckButtonCheckStyle : mpRadioButtonRadioStyle;
2616 gtk_style_context_get_style( pButtonStyle,
2617 "indicator-size", &indicator_size,
2618 "indicator-spacing", &indicator_spacing,
2619 nullptr );
2621 GtkBorder border;
2622 gtk_style_context_get_border(pButtonStyle, gtk_style_context_get_state(pButtonStyle), &border);
2624 GtkBorder padding;
2625 gtk_style_context_get_padding(pButtonStyle, gtk_style_context_get_state(pButtonStyle), &padding);
2628 indicator_size += 2*indicator_spacing + border.left + padding.left + border.right + padding.right;
2629 tools::Rectangle aIndicatorRect( Point( 0,
2630 (rControlRegion.GetHeight()-indicator_size)/2),
2631 Size( indicator_size, indicator_size ) );
2632 rNativeContentRegion = aIndicatorRect;
2634 return true;
2636 else if( nType == ControlType::MenuPopup)
2638 if ((nPart == ControlPart::MenuItemCheckMark) ||
2639 (nPart == ControlPart::MenuItemRadioMark) )
2641 indicator_size = 0;
2643 GtkStyleContext *pMenuItemStyle = (nPart == ControlPart::MenuItemCheckMark ) ? mpCheckMenuItemCheckStyle
2644 : mpRadioMenuItemRadioStyle;
2646 gtk_style_context_get_style( pMenuItemStyle,
2647 "indicator-size", &indicator_size,
2648 nullptr );
2650 point = MAX(0, rControlRegion.GetHeight() - indicator_size);
2651 aEditRect = tools::Rectangle( Point( 0, point / 2),
2652 Size( indicator_size, indicator_size ) );
2654 else if (nPart == ControlPart::Separator)
2656 gint separator_height, separator_width, wide_separators;
2658 gtk_style_context_get_style (mpSeparatorMenuItemSeparatorStyle,
2659 "wide-separators", &wide_separators,
2660 "separator-width", &separator_width,
2661 "separator-height", &separator_height,
2662 nullptr);
2664 aEditRect = tools::Rectangle( aEditRect.TopLeft(),
2665 Size( aEditRect.GetWidth(), wide_separators ? separator_height : 1 ) );
2667 else if (nPart == ControlPart::SubmenuArrow)
2669 gfloat arrow_size = getArrowSize(mpMenuItemArrowStyle);
2670 aEditRect = tools::Rectangle( aEditRect.TopLeft(),
2671 Size( arrow_size, arrow_size ) );
2674 else if ( (nType==ControlType::Scrollbar) &&
2675 ((nPart==ControlPart::ButtonLeft) || (nPart==ControlPart::ButtonRight) ||
2676 (nPart==ControlPart::ButtonUp) || (nPart==ControlPart::ButtonDown) ) )
2678 rNativeBoundingRegion = NWGetScrollButtonRect( nPart, rControlRegion );
2679 rNativeContentRegion = rNativeBoundingRegion;
2681 if (!rNativeContentRegion.GetWidth())
2682 rNativeContentRegion.SetRight( rNativeContentRegion.Left() + 1 );
2683 if (!rNativeContentRegion.GetHeight())
2684 rNativeContentRegion.SetBottom( rNativeContentRegion.Top() + 1 );
2686 return true;
2688 else if ( (nType==ControlType::Spinbox) &&
2689 ((nPart==ControlPart::ButtonUp) || (nPart==ControlPart::ButtonDown) ||
2690 (nPart==ControlPart::SubEdit)) )
2692 tools::Rectangle aControlRegion(GetWidgetSize(rControlRegion, gSpinBox));
2693 aEditRect = NWGetSpinButtonRect(nPart, aControlRegion);
2695 else if ( (nType==ControlType::Combobox) &&
2696 ((nPart==ControlPart::ButtonDown) || (nPart==ControlPart::SubEdit)) )
2698 aEditRect = NWGetComboBoxButtonRect( nPart, rControlRegion );
2700 else if ( (nType==ControlType::Listbox) &&
2701 ((nPart==ControlPart::ButtonDown) || (nPart==ControlPart::SubEdit)) )
2703 aEditRect = NWGetComboBoxButtonRect( nPart, rControlRegion );
2705 else if (nType == ControlType::Editbox && nPart == ControlPart::Entire)
2707 aEditRect = GetWidgetSize(rControlRegion, gEntryBox);
2709 else if (nType == ControlType::Listbox && nPart == ControlPart::Entire)
2711 aEditRect = GetWidgetSize(rControlRegion, gListBox);
2713 else if (nType == ControlType::Combobox && nPart == ControlPart::Entire)
2715 aEditRect = GetWidgetSize(rControlRegion, gComboBox);
2717 else if (nType == ControlType::Spinbox && nPart == ControlPart::Entire)
2719 aEditRect = GetWidgetSize(rControlRegion, gSpinBox);
2721 else if (nType == ControlType::TabItem && nPart == ControlPart::Entire)
2723 const TabitemValue& rTabitemValue = static_cast<const TabitemValue&>(rValue);
2724 const tools::Rectangle& rTabitemRect = rTabitemValue.getContentRect();
2726 aEditRect = AdjustRectForTextBordersPadding(mpNotebookHeaderTabsTabStyle, rTabitemRect.GetWidth(),
2727 rTabitemRect.GetHeight(), rControlRegion);
2729 else if (nType == ControlType::Frame && nPart == ControlPart::Border)
2731 aEditRect = rControlRegion;
2732 DrawFrameFlags nStyle = static_cast<DrawFrameFlags>(rValue.getNumericVal() & 0xfff0);
2733 if (nStyle & DrawFrameFlags::NoDraw)
2735 GtkBorder padding;
2736 gtk_style_context_get_padding(mpFrameInStyle, gtk_style_context_get_state(mpFrameInStyle), &padding);
2738 GtkBorder border;
2739 gtk_style_context_get_border(mpFrameInStyle, gtk_style_context_get_state(mpFrameInStyle), &border);
2741 int x1 = aEditRect.Left();
2742 int y1 = aEditRect.Top();
2743 int x2 = aEditRect.Right();
2744 int y2 = aEditRect.Bottom();
2746 rNativeBoundingRegion = aEditRect;
2747 rNativeContentRegion = tools::Rectangle(x1 + (padding.left + border.left),
2748 y1 + (padding.top + border.top),
2749 x2 - (padding.right + border.right),
2750 y2 - (padding.bottom + border.bottom));
2752 return true;
2754 else
2755 rNativeContentRegion = rControlRegion;
2757 else
2759 return false;
2762 rNativeBoundingRegion = aEditRect;
2763 rNativeContentRegion = rNativeBoundingRegion;
2765 return true;
2767 /************************************************************************
2768 * helper for GtkSalFrame
2769 ************************************************************************/
2770 static inline ::Color getColor( const GdkRGBA& rCol )
2772 return ::Color( static_cast<int>(rCol.red * 0xFFFF) >> 8, static_cast<int>(rCol.green * 0xFFFF) >> 8, static_cast<int>(rCol.blue * 0xFFFF) >> 8 );
2775 static vcl::Font getFont(GtkStyleContext* pStyle, const css::lang::Locale& rLocale)
2777 const PangoFontDescription* font = gtk_style_context_get_font(pStyle, gtk_style_context_get_state(pStyle));
2778 return pango_to_vcl(font, rLocale);
2781 vcl::Font pango_to_vcl(const PangoFontDescription* font, const css::lang::Locale& rLocale)
2783 OString aFamily = pango_font_description_get_family( font );
2784 int nPangoHeight = pango_font_description_get_size( font );
2785 PangoStyle eStyle = pango_font_description_get_style( font );
2786 PangoWeight eWeight = pango_font_description_get_weight( font );
2787 PangoStretch eStretch = pango_font_description_get_stretch( font );
2789 psp::FastPrintFontInfo aInfo;
2790 // set family name
2791 aInfo.m_aFamilyName = OStringToOUString( aFamily, RTL_TEXTENCODING_UTF8 );
2792 // set italic
2793 switch( eStyle )
2795 case PANGO_STYLE_NORMAL: aInfo.m_eItalic = ITALIC_NONE;break;
2796 case PANGO_STYLE_ITALIC: aInfo.m_eItalic = ITALIC_NORMAL;break;
2797 case PANGO_STYLE_OBLIQUE: aInfo.m_eItalic = ITALIC_OBLIQUE;break;
2799 // set weight
2800 if( eWeight <= PANGO_WEIGHT_ULTRALIGHT )
2801 aInfo.m_eWeight = WEIGHT_ULTRALIGHT;
2802 else if( eWeight <= PANGO_WEIGHT_LIGHT )
2803 aInfo.m_eWeight = WEIGHT_LIGHT;
2804 else if( eWeight <= PANGO_WEIGHT_NORMAL )
2805 aInfo.m_eWeight = WEIGHT_NORMAL;
2806 else if( eWeight <= PANGO_WEIGHT_BOLD )
2807 aInfo.m_eWeight = WEIGHT_BOLD;
2808 else
2809 aInfo.m_eWeight = WEIGHT_ULTRABOLD;
2810 // set width
2811 switch( eStretch )
2813 case PANGO_STRETCH_ULTRA_CONDENSED: aInfo.m_eWidth = WIDTH_ULTRA_CONDENSED;break;
2814 case PANGO_STRETCH_EXTRA_CONDENSED: aInfo.m_eWidth = WIDTH_EXTRA_CONDENSED;break;
2815 case PANGO_STRETCH_CONDENSED: aInfo.m_eWidth = WIDTH_CONDENSED;break;
2816 case PANGO_STRETCH_SEMI_CONDENSED: aInfo.m_eWidth = WIDTH_SEMI_CONDENSED;break;
2817 case PANGO_STRETCH_NORMAL: aInfo.m_eWidth = WIDTH_NORMAL;break;
2818 case PANGO_STRETCH_SEMI_EXPANDED: aInfo.m_eWidth = WIDTH_SEMI_EXPANDED;break;
2819 case PANGO_STRETCH_EXPANDED: aInfo.m_eWidth = WIDTH_EXPANDED;break;
2820 case PANGO_STRETCH_EXTRA_EXPANDED: aInfo.m_eWidth = WIDTH_EXTRA_EXPANDED;break;
2821 case PANGO_STRETCH_ULTRA_EXPANDED: aInfo.m_eWidth = WIDTH_ULTRA_EXPANDED;break;
2824 #if OSL_DEBUG_LEVEL > 1
2825 fprintf( stderr, "font name BEFORE system match: \"%s\"\n", aFamily.getStr() );
2826 #endif
2828 // match font to e.g. resolve "Sans"
2829 psp::PrintFontManager::get().matchFont(aInfo, rLocale);
2831 #if OSL_DEBUG_LEVEL > 1
2832 fprintf( stderr, "font match %s, name AFTER: \"%s\"\n",
2833 aInfo.m_nID != 0 ? "succeeded" : "failed",
2834 OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
2835 #endif
2837 int nPointHeight = 0;
2838 nPointHeight = nPangoHeight/PANGO_SCALE;
2840 vcl::Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) );
2841 if( aInfo.m_eWeight != WEIGHT_DONTKNOW )
2842 aFont.SetWeight( aInfo.m_eWeight );
2843 if( aInfo.m_eWidth != WIDTH_DONTKNOW )
2844 aFont.SetWidthType( aInfo.m_eWidth );
2845 if( aInfo.m_eItalic != ITALIC_DONTKNOW )
2846 aFont.SetItalic( aInfo.m_eItalic );
2847 if( aInfo.m_ePitch != PITCH_DONTKNOW )
2848 aFont.SetPitch( aInfo.m_ePitch );
2849 return aFont;
2852 void GtkSalGraphics::updateSettings( AllSettings& rSettings )
2854 GtkStyleContext* pStyle = gtk_widget_get_style_context( mpWindow );
2855 GtkSettings* pSettings = gtk_widget_get_settings( mpWindow );
2856 StyleSettings aStyleSet = rSettings.GetStyleSettings();
2857 GdkRGBA color;
2859 // text colors
2860 GdkRGBA text_color;
2861 style_context_set_state(pStyle, GTK_STATE_FLAG_NORMAL);
2862 gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), &text_color);
2863 ::Color aTextColor = getColor( text_color );
2864 aStyleSet.SetDialogTextColor( aTextColor );
2865 aStyleSet.SetButtonTextColor( aTextColor );
2866 aStyleSet.SetRadioCheckTextColor( aTextColor );
2867 aStyleSet.SetGroupTextColor( aTextColor );
2868 aStyleSet.SetLabelTextColor( aTextColor );
2869 aStyleSet.SetWindowTextColor( aTextColor );
2870 aStyleSet.SetFieldTextColor( aTextColor );
2872 // background colors
2873 GdkRGBA background_color;
2874 gtk_style_context_get_background_color(pStyle, gtk_style_context_get_state(pStyle), &background_color);
2876 ::Color aBackColor = getColor( background_color );
2877 aStyleSet.BatchSetBackgrounds( aBackColor );
2879 // UI font
2880 vcl::Font aFont(getFont(pStyle, rSettings.GetUILanguageTag().getLocale()));
2882 aStyleSet.BatchSetFonts( aFont, aFont);
2884 aFont.SetWeight( WEIGHT_BOLD );
2885 aStyleSet.SetTitleFont( aFont );
2886 aStyleSet.SetFloatTitleFont( aFont );
2888 // mouse over text colors
2889 style_context_set_state(pStyle, GTK_STATE_FLAG_PRELIGHT);
2890 gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), &text_color);
2891 aTextColor = getColor( text_color );
2892 aStyleSet.SetFieldRolloverTextColor( aTextColor );
2894 // button mouse over colors
2896 GdkRGBA normal_button_rollover_text_color, pressed_button_rollover_text_color;
2897 style_context_set_state(mpButtonStyle, GTK_STATE_FLAG_PRELIGHT);
2898 gtk_style_context_get_color(mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &normal_button_rollover_text_color);
2899 aTextColor = getColor(normal_button_rollover_text_color);
2900 aStyleSet.SetButtonRolloverTextColor( aTextColor );
2901 style_context_set_state(mpButtonStyle, static_cast<GtkStateFlags>(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE));
2902 gtk_style_context_get_color(mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &pressed_button_rollover_text_color);
2903 aTextColor = getColor(pressed_button_rollover_text_color);
2904 style_context_set_state(mpButtonStyle, GTK_STATE_FLAG_NORMAL);
2905 aStyleSet.SetButtonPressedRolloverTextColor( aTextColor );
2908 // tooltip colors
2910 GtkStyleContext *pCStyle = gtk_style_context_new();
2911 gtk_style_context_set_screen( pCStyle, gtk_window_get_screen( GTK_WINDOW( mpWindow ) ) );
2912 GtkWidgetPath *pCPath = gtk_widget_path_new();
2913 guint pos = gtk_widget_path_append_type(pCPath, GTK_TYPE_WINDOW);
2914 gtk_widget_path_iter_add_class(pCPath, pos, GTK_STYLE_CLASS_TOOLTIP);
2915 pos = gtk_widget_path_append_type (pCPath, GTK_TYPE_LABEL);
2916 gtk_widget_path_iter_add_class(pCPath, pos, GTK_STYLE_CLASS_LABEL);
2917 pCStyle = gtk_style_context_new();
2918 gtk_style_context_set_path(pCStyle, pCPath);
2919 gtk_widget_path_free(pCPath);
2921 GdkRGBA tooltip_bg_color, tooltip_fg_color;
2922 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
2923 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &tooltip_fg_color);
2924 gtk_style_context_get_background_color(pCStyle, gtk_style_context_get_state(pCStyle), &tooltip_bg_color);
2925 g_object_unref( pCStyle );
2927 aStyleSet.SetHelpColor( getColor( tooltip_bg_color ));
2928 aStyleSet.SetHelpTextColor( getColor( tooltip_fg_color ));
2932 // construct style context for text view
2933 GtkStyleContext *pCStyle = gtk_style_context_new();
2934 gtk_style_context_set_screen( pCStyle, gtk_window_get_screen( GTK_WINDOW( mpWindow ) ) );
2935 GtkWidgetPath *pCPath = gtk_widget_path_new();
2936 gtk_widget_path_append_type( pCPath, GTK_TYPE_TEXT_VIEW );
2937 gtk_widget_path_iter_add_class( pCPath, -1, GTK_STYLE_CLASS_VIEW );
2938 gtk_style_context_set_path( pCStyle, pCPath );
2939 gtk_widget_path_free( pCPath );
2941 // highlighting colors
2942 style_context_set_state(pCStyle, GTK_STATE_FLAG_SELECTED);
2943 gtk_style_context_get_background_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
2944 ::Color aHighlightColor = getColor( text_color );
2945 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
2946 ::Color aHighlightTextColor = getColor( text_color );
2947 aStyleSet.SetHighlightColor( aHighlightColor );
2948 aStyleSet.SetHighlightTextColor( aHighlightTextColor );
2950 // field background color
2951 GdkRGBA field_background_color;
2952 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
2953 gtk_style_context_get_background_color(pCStyle, gtk_style_context_get_state(pCStyle), &field_background_color);
2955 ::Color aBackFieldColor = getColor( field_background_color );
2956 aStyleSet.SetFieldColor( aBackFieldColor );
2957 // This baby is the default page/paper color
2958 aStyleSet.SetWindowColor( aBackFieldColor );
2960 // Cursor width
2961 gfloat caretAspectRatio = 0.04f;
2962 gtk_style_context_get_style( pCStyle, "cursor-aspect-ratio", &caretAspectRatio, nullptr );
2963 // Assume 20px tall for the ratio computation, which should give reasonable results
2964 aStyleSet.SetCursorSize( 20 * caretAspectRatio + 1 );
2966 // Dark shadow color
2967 style_context_set_state(pCStyle, GTK_STATE_FLAG_INSENSITIVE);
2968 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &color);
2969 ::Color aDarkShadowColor = getColor( color );
2970 aStyleSet.SetDarkShadowColor( aDarkShadowColor );
2972 ::Color aShadowColor(aBackColor);
2973 if (aDarkShadowColor.GetLuminance() > aBackColor.GetLuminance())
2974 aShadowColor.IncreaseLuminance(64);
2975 else
2976 aShadowColor.DecreaseLuminance(64);
2977 aStyleSet.SetShadowColor(aShadowColor);
2979 g_object_unref( pCStyle );
2981 // Tab colors
2982 aStyleSet.SetActiveTabColor( aBackFieldColor ); // same as the window color.
2983 aStyleSet.SetInactiveTabColor( aBackColor );
2986 // menu disabled entries handling
2987 aStyleSet.SetSkipDisabledInMenus( true );
2988 aStyleSet.SetPreferredContextMenuShortcuts( false );
2990 // menu colors
2991 style_context_set_state(mpMenuStyle, GTK_STATE_FLAG_NORMAL);
2992 gtk_style_context_get_background_color( mpMenuStyle, gtk_style_context_get_state(mpMenuStyle), &background_color );
2993 aBackColor = getColor( background_color );
2994 aStyleSet.SetMenuColor( aBackColor );
2996 // menu bar
2997 style_context_set_state(mpMenuBarStyle, GTK_STATE_FLAG_NORMAL);
2998 gtk_style_context_get_background_color( mpMenuBarStyle, gtk_style_context_get_state(mpMenuBarStyle), &background_color );
2999 aBackColor = getColor( background_color );
3000 aStyleSet.SetMenuBarColor( aBackColor );
3001 aStyleSet.SetMenuBarRolloverColor( aBackColor );
3003 style_context_set_state(mpMenuBarItemStyle, GTK_STATE_FLAG_NORMAL);
3004 gtk_style_context_get_color( mpMenuBarItemStyle, gtk_style_context_get_state(mpMenuBarItemStyle), &text_color );
3005 aTextColor = aStyleSet.GetPersonaMenuBarTextColor().get_value_or( getColor( text_color ) );
3006 aStyleSet.SetMenuBarTextColor( aTextColor );
3007 aStyleSet.SetMenuBarRolloverTextColor( aTextColor );
3009 style_context_set_state(mpMenuBarItemStyle, GTK_STATE_FLAG_PRELIGHT);
3010 gtk_style_context_get_color( mpMenuBarItemStyle, gtk_style_context_get_state(mpMenuBarItemStyle), &text_color );
3011 aTextColor = aStyleSet.GetPersonaMenuBarTextColor().get_value_or( getColor( text_color ) );
3012 aStyleSet.SetMenuBarHighlightTextColor( aTextColor );
3014 // menu items
3015 style_context_set_state(mpMenuItemLabelStyle, GTK_STATE_FLAG_NORMAL);
3016 gtk_style_context_get_color(mpMenuItemLabelStyle, gtk_style_context_get_state(mpMenuItemLabelStyle), &color);
3017 aTextColor = getColor(color);
3018 aStyleSet.SetMenuTextColor(aTextColor);
3020 style_context_set_state(mpMenuItemLabelStyle, GTK_STATE_FLAG_PRELIGHT);
3021 gtk_style_context_get_background_color( mpMenuItemLabelStyle, gtk_style_context_get_state(mpMenuItemLabelStyle), &background_color );
3022 ::Color aHighlightColor = getColor( background_color );
3023 aStyleSet.SetMenuHighlightColor( aHighlightColor );
3025 gtk_style_context_get_color( mpMenuItemLabelStyle, gtk_style_context_get_state(mpMenuItemLabelStyle), &color );
3026 ::Color aHighlightTextColor = getColor( color );
3027 aStyleSet.SetMenuHighlightTextColor( aHighlightTextColor );
3029 // hyperlink colors
3030 style_context_set_state(mpLinkButtonStyle, GTK_STATE_FLAG_LINK);
3031 gtk_style_context_get_color(mpLinkButtonStyle, gtk_style_context_get_state(mpLinkButtonStyle), &text_color);
3032 aStyleSet.SetLinkColor(getColor(text_color));
3033 style_context_set_state(mpLinkButtonStyle, GTK_STATE_FLAG_VISITED);
3034 gtk_style_context_get_color(mpLinkButtonStyle, gtk_style_context_get_state(mpLinkButtonStyle), &text_color);
3035 aStyleSet.SetVisitedLinkColor(getColor(text_color));
3038 GtkStyleContext *pCStyle = mpNotebookHeaderTabsTabLabelStyle;
3039 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
3040 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3041 aTextColor = getColor( text_color );
3042 aStyleSet.SetTabTextColor(aTextColor);
3043 aStyleSet.SetTabFont(getFont(mpNotebookHeaderTabsTabLabelStyle, rSettings.GetUILanguageTag().getLocale()));
3047 GtkStyleContext *pCStyle = mpToolButtonStyle;
3048 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
3049 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3050 aTextColor = getColor( text_color );
3051 aStyleSet.SetToolTextColor(aTextColor);
3052 aStyleSet.SetToolFont(getFont(mpToolButtonStyle, rSettings.GetUILanguageTag().getLocale()));
3055 // mouse over text colors
3057 GtkStyleContext *pCStyle = mpNotebookHeaderTabsTabHoverLabelStyle;
3058 style_context_set_state(pCStyle, GTK_STATE_FLAG_PRELIGHT);
3059 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3060 aTextColor = getColor( text_color );
3061 aStyleSet.SetTabRolloverTextColor(aTextColor);
3065 GtkStyleContext *pCStyle = mpNotebookHeaderTabsTabActiveLabelStyle;
3066 style_context_set_state(pCStyle, ACTIVE_TAB());
3067 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3068 aTextColor = getColor( text_color );
3069 aStyleSet.SetTabHighlightTextColor(aTextColor);
3072 // get cursor blink time
3073 gboolean blink = false;
3075 g_object_get( pSettings, "gtk-cursor-blink", &blink, nullptr );
3076 if( blink )
3078 gint blink_time = static_cast<gint>(STYLE_CURSOR_NOBLINKTIME);
3079 g_object_get( pSettings, "gtk-cursor-blink-time", &blink_time, nullptr );
3080 // set the blink_time if there is a setting and it is reasonable
3081 // else leave the default value
3082 if( blink_time > 100 && blink_time != gint(STYLE_CURSOR_NOBLINKTIME) )
3083 aStyleSet.SetCursorBlinkTime( blink_time/2 );
3085 else
3086 aStyleSet.SetCursorBlinkTime( STYLE_CURSOR_NOBLINKTIME );
3088 MouseSettings aMouseSettings = rSettings.GetMouseSettings();
3089 int iDoubleClickTime, iDoubleClickDistance, iDragThreshold;
3090 static const int MENU_POPUP_DELAY = 225;
3091 g_object_get( pSettings,
3092 "gtk-double-click-time", &iDoubleClickTime,
3093 "gtk-double-click-distance", &iDoubleClickDistance,
3094 "gtk-dnd-drag-threshold", &iDragThreshold,
3095 nullptr );
3096 aMouseSettings.SetDoubleClickTime( iDoubleClickTime );
3097 aMouseSettings.SetDoubleClickWidth( iDoubleClickDistance );
3098 aMouseSettings.SetDoubleClickHeight( iDoubleClickDistance );
3099 aMouseSettings.SetStartDragWidth( iDragThreshold );
3100 aMouseSettings.SetStartDragHeight( iDragThreshold );
3101 aMouseSettings.SetMenuDelay( MENU_POPUP_DELAY );
3102 rSettings.SetMouseSettings( aMouseSettings );
3104 gboolean primarybuttonwarps = false;
3105 g_object_get( pSettings,
3106 "gtk-primary-button-warps-slider", &primarybuttonwarps,
3107 nullptr );
3108 aStyleSet.SetPreferredUseImagesInMenus(false);
3109 aStyleSet.SetPrimaryButtonWarpsSlider(primarybuttonwarps);
3111 // set scrollbar settings
3112 gint min_slider_length = 21;
3114 // Grab some button style attributes
3115 if (gtk_check_version(3, 20, 0) == nullptr)
3117 Size aSize;
3118 QuerySize(mpHScrollbarStyle, aSize);
3119 QuerySize(mpHScrollbarContentsStyle, aSize);
3120 QuerySize(mpHScrollbarTroughStyle, aSize);
3121 QuerySize(mpHScrollbarSliderStyle, aSize);
3123 gboolean has_forward, has_forward2, has_backward, has_backward2;
3124 gtk_style_context_get_style(mpHScrollbarStyle,
3125 "has-forward-stepper", &has_forward,
3126 "has-secondary-forward-stepper", &has_forward2,
3127 "has-backward-stepper", &has_backward,
3128 "has-secondary-backward-stepper", &has_backward2, nullptr);
3129 if (has_forward || has_backward || has_forward2 || has_backward2)
3130 QuerySize(mpHScrollbarButtonStyle, aSize);
3132 aStyleSet.SetScrollBarSize(aSize.Height());
3134 gtk_style_context_get(mpVScrollbarSliderStyle, gtk_style_context_get_state(mpVScrollbarSliderStyle),
3135 "min-height", &min_slider_length,
3136 nullptr);
3137 aStyleSet.SetMinThumbSize(min_slider_length);
3139 else
3141 gint slider_width = 14;
3142 gint trough_border = 1;
3144 gtk_style_context_get_style(mpVScrollbarStyle,
3145 "slider-width", &slider_width,
3146 "trough-border", &trough_border,
3147 "min-slider-length", &min_slider_length,
3148 nullptr);
3149 aStyleSet.SetScrollBarSize(slider_width + 2*trough_border);
3150 gint magic = trough_border ? 1 : 0;
3151 aStyleSet.SetMinThumbSize(min_slider_length - magic);
3154 // preferred icon style
3155 gchar* pIconThemeName = nullptr;
3156 gboolean bDarkIconTheme = false;
3157 g_object_get(pSettings, "gtk-icon-theme-name", &pIconThemeName,
3158 "gtk-application-prefer-dark-theme", &bDarkIconTheme,
3159 nullptr );
3160 OUString sIconThemeName(OUString::createFromAscii(pIconThemeName));
3161 aStyleSet.SetPreferredIconTheme(sIconThemeName, bDarkIconTheme);
3162 g_free( pIconThemeName );
3164 aStyleSet.SetToolbarIconSize( ToolbarIconSize::Large );
3166 // finally update the collected settings
3167 rSettings.SetStyleSettings( aStyleSet );
3168 #if OSL_DEBUG_LEVEL > 1
3169 gchar* pThemeName = NULL;
3170 g_object_get( pSettings, "gtk-theme-name", &pThemeName, nullptr );
3171 fprintf( stderr, "Theme name is \"%s\"\n", pThemeName );
3172 g_free(pThemeName);
3173 #endif
3176 bool GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
3178 switch(nType)
3180 case ControlType::Pushbutton:
3181 case ControlType::Radiobutton:
3182 case ControlType::Checkbox:
3183 case ControlType::Progress:
3184 case ControlType::ListNode:
3185 case ControlType::ListNet:
3186 if (nPart==ControlPart::Entire || nPart == ControlPart::Focus)
3187 return true;
3188 break;
3190 case ControlType::Scrollbar:
3191 if(nPart==ControlPart::DrawBackgroundHorz || nPart==ControlPart::DrawBackgroundVert ||
3192 nPart==ControlPart::Entire || nPart==ControlPart::HasThreeButtons)
3193 return true;
3194 break;
3196 case ControlType::Editbox:
3197 case ControlType::MultilineEditbox:
3198 if (nPart==ControlPart::Entire || nPart==ControlPart::HasBackgroundTexture)
3199 return true;
3200 break;
3202 case ControlType::Combobox:
3203 if (nPart==ControlPart::Entire || nPart==ControlPart::HasBackgroundTexture || nPart == ControlPart::AllButtons)
3204 return true;
3205 break;
3207 case ControlType::Spinbox:
3208 if (nPart==ControlPart::Entire || nPart==ControlPart::HasBackgroundTexture || nPart == ControlPart::AllButtons || nPart == ControlPart::ButtonUp || nPart == ControlPart::ButtonDown)
3209 return true;
3210 break;
3212 case ControlType::SpinButtons:
3213 if (nPart==ControlPart::Entire || nPart==ControlPart::AllButtons)
3214 return true;
3215 break;
3217 case ControlType::Frame:
3218 case ControlType::WindowBackground:
3219 return true;
3221 case ControlType::TabItem:
3222 case ControlType::TabHeader:
3223 case ControlType::TabPane:
3224 case ControlType::TabBody:
3225 if(nPart==ControlPart::Entire || nPart==ControlPart::TabsDrawRtl)
3226 return true;
3227 break;
3229 case ControlType::Listbox:
3230 if (nPart==ControlPart::Entire || nPart==ControlPart::ListboxWindow || nPart==ControlPart::HasBackgroundTexture || nPart == ControlPart::Focus)
3231 return true;
3232 break;
3234 case ControlType::Toolbar:
3235 if( nPart==ControlPart::Entire
3236 // || nPart==ControlPart::DrawBackgroundHorz
3237 // || nPart==ControlPart::DrawBackgroundVert
3238 // || nPart==ControlPart::ThumbHorz
3239 // || nPart==ControlPart::ThumbVert
3240 || nPart==ControlPart::Button
3241 // || nPart==ControlPart::SeparatorHorz
3242 || nPart==ControlPart::SeparatorVert
3244 return true;
3245 break;
3247 case ControlType::Menubar:
3248 if (nPart==ControlPart::Entire || nPart==ControlPart::MenuItem)
3249 return true;
3250 break;
3252 case ControlType::MenuPopup:
3253 if (nPart==ControlPart::Entire
3254 || nPart==ControlPart::MenuItem
3255 || nPart==ControlPart::MenuItemCheckMark
3256 || nPart==ControlPart::MenuItemRadioMark
3257 || nPart==ControlPart::Separator
3258 || nPart==ControlPart::SubmenuArrow
3260 return true;
3261 break;
3263 // case ControlType::Slider:
3264 // if(nPart == ControlPart::TrackHorzArea || nPart == ControlPart::TrackVertArea)
3265 // return true;
3266 // break;
3268 case ControlType::Fixedline:
3269 if (nPart == ControlPart::SeparatorVert || nPart == ControlPart::SeparatorHorz)
3270 return true;
3271 break;
3273 case ControlType::ListHeader:
3274 if (nPart == ControlPart::Button || nPart == ControlPart::Arrow)
3275 return true;
3276 break;
3277 default: break;
3280 SAL_INFO("vcl.gtk", "Unhandled is native supported for Type:" << static_cast<int>(nType) << ", Part" << static_cast<int>(nPart));
3282 return false;
3285 #if ENABLE_CAIRO_CANVAS
3287 bool GtkSalGraphics::SupportsCairo() const
3289 return true;
3292 cairo::SurfaceSharedPtr GtkSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
3294 return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(rSurface));
3297 cairo::SurfaceSharedPtr GtkSalGraphics::CreateSurface(const OutputDevice& /*rRefDevice*/, int x, int y, int width, int height) const
3299 return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(this, x, y, width, height));
3302 #endif
3304 void GtkSalGraphics::WidgetQueueDraw() const
3306 //request gtk to sync the entire contents
3307 GtkWidget *pWidget = GTK_WIDGET(mpFrame->getFixedContainer());
3308 gtk_widget_queue_draw(pWidget);
3311 namespace {
3313 void getStyleContext(GtkStyleContext** style, GtkWidget* widget)
3315 gtk_container_add(GTK_CONTAINER(gDumbContainer), widget);
3316 *style = gtk_widget_get_style_context(widget);
3317 g_object_ref(*style);
3322 void GtkSalData::initNWF()
3324 ImplSVData* pSVData = ImplGetSVData();
3325 pSVData->maNWFData.mbFlatMenu = true;
3326 pSVData->maNWFData.mbDockingAreaAvoidTBFrames = true;
3327 pSVData->maNWFData.mbCanDrawWidgetAnySize = true;
3328 pSVData->maNWFData.mbDDListBoxNoTextArea = true;
3329 pSVData->maNWFData.mbNoFocusRects = true;
3330 pSVData->maNWFData.mbNoFocusRectsForFlatButtons = true;
3331 pSVData->maNWFData.mbAutoAccel = true;
3332 pSVData->maNWFData.mbEnableAccel = true;
3334 #if defined(GDK_WINDOWING_WAYLAND)
3335 //gnome#768128 for the car crash that is wayland
3336 //and floating dockable toolbars
3337 GdkDisplay *pDisplay = gdk_display_get_default();
3338 if (GDK_IS_WAYLAND_DISPLAY(pDisplay))
3339 pSVData->maNWFData.mbCanDetermineWindowPosition = false;
3340 #endif
3343 void GtkSalData::deInitNWF()
3345 if (gCacheWindow)
3346 gtk_widget_destroy(gCacheWindow);
3349 GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow )
3350 : SvpSalGraphics(),
3351 mpFrame( pFrame ),
3352 mpWindow( pWindow )
3354 if (style_loaded)
3355 return;
3357 style_loaded = true;
3359 /* Load the GtkStyleContexts, it might be a bit slow, but usually,
3360 * gtk apps create a lot of widgets at startup, so, it shouldn't be
3361 * too slow */
3362 gtk_widget_path_iter_set_object_nameFunc set_object_name =
3363 reinterpret_cast<gtk_widget_path_iter_set_object_nameFunc>(osl_getAsciiFunctionSymbol(nullptr,
3364 "gtk_widget_path_iter_set_object_name"));
3366 gCacheWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3367 gDumbContainer = gtk_fixed_new();
3368 gtk_container_add(GTK_CONTAINER(gCacheWindow), gDumbContainer);
3369 gtk_widget_realize(gDumbContainer);
3370 gtk_widget_realize(gCacheWindow);
3372 gEntryBox = gtk_entry_new();
3373 gtk_container_add(GTK_CONTAINER(gDumbContainer), gEntryBox);
3375 mpWindowStyle = createStyleContext(set_object_name, GtkControlPart::ToplevelWindow);
3376 mpEntryStyle = createStyleContext(set_object_name, GtkControlPart::Entry);
3378 getStyleContext(&mpTextViewStyle, gtk_text_view_new());
3380 mpButtonStyle = createStyleContext(set_object_name, GtkControlPart::Button);
3381 mpLinkButtonStyle = createStyleContext(set_object_name, GtkControlPart::LinkButton);
3383 GtkWidget* pToolbar = gtk_toolbar_new();
3384 mpToolbarStyle = gtk_widget_get_style_context(pToolbar);
3385 gtk_style_context_add_class(mpToolbarStyle, GTK_STYLE_CLASS_TOOLBAR);
3387 GtkToolItem *item = gtk_separator_tool_item_new();
3388 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), item, -1);
3389 mpToolbarSeperatorStyle = gtk_widget_get_style_context(GTK_WIDGET(item));
3391 GtkWidget *pButton = gtk_button_new();
3392 item = gtk_tool_button_new(pButton, nullptr);
3393 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), item, -1);
3394 mpToolButtonStyle = gtk_widget_get_style_context(GTK_WIDGET(pButton));
3396 mpVScrollbarStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVertical);
3397 mpVScrollbarContentsStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalContents);
3398 mpVScrollbarTroughStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalTrough);
3399 mpVScrollbarSliderStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalSlider);
3400 mpVScrollbarButtonStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalButton);
3401 mpHScrollbarStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontal);
3402 mpHScrollbarContentsStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalContents);
3403 mpHScrollbarTroughStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalTrough);
3404 mpHScrollbarSliderStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalSlider);
3405 mpHScrollbarButtonStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalButton);
3407 mpCheckButtonStyle = createStyleContext(set_object_name, GtkControlPart::CheckButton);
3408 mpCheckButtonCheckStyle = createStyleContext(set_object_name, GtkControlPart::CheckButtonCheck);
3410 mpRadioButtonStyle = createStyleContext(set_object_name, GtkControlPart::RadioButton);
3411 mpRadioButtonRadioStyle = createStyleContext(set_object_name, GtkControlPart::RadioButtonRadio);
3413 /* Spinbutton */
3414 gSpinBox = gtk_spin_button_new(nullptr, 0, 0);
3415 gtk_container_add(GTK_CONTAINER(gDumbContainer), gSpinBox);
3416 mpSpinStyle = createStyleContext(set_object_name, GtkControlPart::SpinButton);
3417 mpSpinEntryStyle = createStyleContext(set_object_name, GtkControlPart::SpinButtonEntry);
3418 mpSpinUpStyle = createStyleContext(set_object_name, GtkControlPart::SpinButtonUpButton);
3419 mpSpinDownStyle = createStyleContext(set_object_name, GtkControlPart::SpinButtonDownButton);
3421 /* NoteBook */
3422 mpNotebookStyle = createStyleContext(set_object_name, GtkControlPart::Notebook);
3423 mpNotebookStackStyle = createStyleContext(set_object_name, GtkControlPart::NotebookStack);
3424 mpNotebookHeaderStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeader);
3425 mpNotebookHeaderTabsStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabs);
3426 mpNotebookHeaderTabsTabStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTab);
3427 mpNotebookHeaderTabsTabLabelStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTabLabel);
3428 mpNotebookHeaderTabsTabActiveLabelStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTabActiveLabel);
3429 mpNotebookHeaderTabsTabHoverLabelStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTabHoverLabel);
3431 /* Combobox */
3432 gComboBox = gtk_combo_box_text_new_with_entry();
3433 gtk_container_add(GTK_CONTAINER(gDumbContainer), gComboBox);
3434 mpComboboxStyle = createStyleContext(set_object_name, GtkControlPart::Combobox);
3435 mpComboboxBoxStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBox);
3436 mpComboboxEntryStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxEntry);
3437 mpComboboxButtonStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxButton);
3438 mpComboboxButtonBoxStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxButtonBox);
3439 mpComboboxButtonArrowStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxButtonBoxArrow);
3441 /* Listbox */
3442 gListBox = gtk_combo_box_text_new();
3443 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gListBox), "sample");
3444 gtk_container_add(GTK_CONTAINER(gDumbContainer), gListBox);
3445 mpListboxStyle = createStyleContext(set_object_name, GtkControlPart::Listbox);
3446 mpListboxBoxStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBox);
3447 mpListboxButtonStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBoxButton);
3448 mpListboxButtonBoxStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBoxButtonBox);
3449 mpListboxButtonArrowStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBoxButtonBoxArrow);
3451 /* Menu bar */
3452 gMenuBarWidget = gtk_menu_bar_new();
3453 gMenuItemMenuBarWidget = gtk_menu_item_new_with_label( "b" );
3454 gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget), gMenuItemMenuBarWidget);
3455 gtk_container_add(GTK_CONTAINER(gDumbContainer), gMenuBarWidget);
3457 mpMenuBarStyle = createStyleContext(set_object_name, GtkControlPart::MenuBar);
3458 mpMenuBarItemStyle = createStyleContext(set_object_name, GtkControlPart::MenuBarItem);
3460 /* Menu */
3461 mpMenuWindowStyle = createStyleContext(set_object_name, GtkControlPart::MenuWindow);
3462 mpMenuStyle = createStyleContext(set_object_name, GtkControlPart::Menu);
3463 GtkWidget *menu = gtk_menu_new();
3464 gtk_menu_item_set_submenu(GTK_MENU_ITEM(gMenuItemMenuBarWidget), menu);
3466 /* Menu Items */
3467 gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
3468 gtk_menu_shell_append(GTK_MENU_SHELL(menu), gCheckMenuItemWidget);
3470 mpMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::MenuItem);
3471 mpMenuItemLabelStyle = createStyleContext(set_object_name, GtkControlPart::MenuItemLabel);
3472 mpMenuItemArrowStyle = createStyleContext(set_object_name, GtkControlPart::MenuItemArrow);
3473 mpCheckMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::CheckMenuItem);
3474 mpCheckMenuItemCheckStyle = createStyleContext(set_object_name, GtkControlPart::CheckMenuItemCheck);
3475 mpRadioMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::RadioMenuItem);
3476 mpRadioMenuItemRadioStyle = createStyleContext(set_object_name, GtkControlPart::RadioMenuItemRadio);
3477 mpSeparatorMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::SeparatorMenuItem);
3478 mpSeparatorMenuItemSeparatorStyle = createStyleContext(set_object_name, GtkControlPart::SeparatorMenuItemSeparator);
3480 /* Frames */
3481 mpFrameOutStyle = mpFrameInStyle = createStyleContext(set_object_name, GtkControlPart::FrameBorder);
3482 getStyleContext(&mpFixedHoriLineStyle, gtk_separator_new(GTK_ORIENTATION_HORIZONTAL));
3483 getStyleContext(&mpFixedVertLineStyle, gtk_separator_new(GTK_ORIENTATION_VERTICAL));
3486 /* Tree List */
3487 gTreeViewWidget = gtk_tree_view_new();
3488 gtk_container_add(GTK_CONTAINER(gDumbContainer), gTreeViewWidget);
3490 GtkTreeViewColumn* firstTreeViewColumn = gtk_tree_view_column_new();
3491 gtk_tree_view_column_set_title(firstTreeViewColumn, "M");
3492 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), firstTreeViewColumn);
3494 GtkTreeViewColumn* middleTreeViewColumn = gtk_tree_view_column_new();
3495 gtk_tree_view_column_set_title(middleTreeViewColumn, "M");
3496 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), middleTreeViewColumn);
3497 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gTreeViewWidget), middleTreeViewColumn);
3499 GtkTreeViewColumn* lastTreeViewColumn = gtk_tree_view_column_new();
3500 gtk_tree_view_column_set_title(lastTreeViewColumn, "M");
3501 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), lastTreeViewColumn);
3503 /* Use the middle column's header for our button */
3504 GtkWidget* pTreeHeaderCellWidget = gtk_tree_view_column_get_button(middleTreeViewColumn);
3505 mpTreeHeaderButtonStyle = gtk_widget_get_style_context(pTreeHeaderCellWidget);
3507 /* Progress Bar */
3508 mpProgressBarStyle = createStyleContext(set_object_name, GtkControlPart::ProgressBar);
3509 mpProgressBarTroughStyle = createStyleContext(set_object_name, GtkControlPart::ProgressBarTrough);
3510 mpProgressBarProgressStyle = createStyleContext(set_object_name, GtkControlPart::ProgressBarProgress);
3512 gtk_widget_show_all(gDumbContainer);
3515 void GtkSalGraphics::GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY)
3517 char* pForceDpi;
3518 if ((pForceDpi = getenv("SAL_FORCEDPI")))
3520 OString sForceDPI(pForceDpi);
3521 rDPIX = rDPIY = sForceDPI.toInt32();
3522 return;
3525 GdkScreen* pScreen = gtk_widget_get_screen(mpWindow);
3526 double fResolution = -1.0;
3527 g_object_get(pScreen, "resolution", &fResolution, nullptr);
3529 if (fResolution > 0.0)
3530 rDPIX = rDPIY = sal_Int32(fResolution);
3531 else
3532 rDPIX = rDPIY = 96;
3535 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */