Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / unx / gtk3 / gtk3salnativewidgets-gtk.cxx
blob5680ddf71bc2f46da0bbd9e26e6b427af6eccb38
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>
11 #include <sal/log.hxx>
12 #include <osl/module.h>
14 #include <config_cairo_canvas.h>
16 #include <unx/gtk/gtkframe.hxx>
17 #include <unx/gtk/gtkdata.hxx>
18 #include <unx/gtk/gtkinst.hxx>
19 #include <unx/gtk/gtkgdi.hxx>
20 #include <unx/gtk/gtkbackend.hxx>
21 #include <vcl/decoview.hxx>
22 #include <vcl/settings.hxx>
23 #include <unx/fontmanager.hxx>
25 #include "cairo_gtk3_cairo.hxx"
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;
226 GtkStateFlags stateflags = gtk_style_context_get_state (pContext);
228 gtk_style_context_get_margin(pContext, stateflags, &margin);
229 gtk_style_context_get_border(pContext, stateflags, &border);
230 gtk_style_context_get_padding(pContext, stateflags, &padding);
232 int nMinWidth, nMinHeight;
233 gtk_style_context_get(pContext, stateflags,
234 "min-width", &nMinWidth, "min-height", &nMinHeight, nullptr);
236 nMinWidth += margin.left + margin.right + border.left + border.right + padding.left + padding.right;
237 nMinHeight += margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom;
239 rSize = Size(std::max<long>(rSize.Width(), nMinWidth), std::max<long>(rSize.Height(), nMinHeight));
243 tools::Rectangle GtkSalGraphics::NWGetScrollButtonRect( ControlPart nPart, tools::Rectangle aAreaRect )
245 tools::Rectangle buttonRect;
247 gboolean has_forward;
248 gboolean has_forward2;
249 gboolean has_backward;
250 gboolean has_backward2;
252 GtkStyleContext* pScrollbarStyle = nullptr;
253 if ((nPart == ControlPart::ButtonLeft) || (nPart == ControlPart::ButtonRight))
254 pScrollbarStyle = mpHScrollbarStyle;
255 else // (nPart == ControlPart::ButtonUp) || (nPart == ControlPart::ButtonDown)
256 pScrollbarStyle = mpVScrollbarStyle;
258 gtk_style_context_get_style( pScrollbarStyle,
259 "has-forward-stepper", &has_forward,
260 "has-secondary-forward-stepper", &has_forward2,
261 "has-backward-stepper", &has_backward,
262 "has-secondary-backward-stepper", &has_backward2, nullptr );
263 gint buttonWidth;
264 gint buttonHeight;
266 gint nFirst = 0;
267 gint nSecond = 0;
269 if ( has_forward ) nSecond += 1;
270 if ( has_forward2 ) nFirst += 1;
271 if ( has_backward ) nFirst += 1;
272 if ( has_backward2 ) nSecond += 1;
274 if (gtk_check_version(3, 20, 0) == nullptr)
276 Size aSize;
277 if (nPart == ControlPart::ButtonLeft || nPart == ControlPart::ButtonRight)
279 QuerySize(mpHScrollbarStyle, aSize);
280 QuerySize(mpHScrollbarContentsStyle, aSize);
281 QuerySize(mpHScrollbarButtonStyle, aSize);
283 else
285 QuerySize(mpVScrollbarStyle, aSize);
286 QuerySize(mpVScrollbarContentsStyle, aSize);
287 QuerySize(mpVScrollbarButtonStyle, aSize);
290 if (nPart == ControlPart::ButtonUp)
292 aSize.setHeight( aSize.Height() * nFirst );
293 buttonRect.setX(aAreaRect.Left());
294 buttonRect.setY(aAreaRect.Top());
296 else if (nPart == ControlPart::ButtonLeft)
298 aSize.setWidth( aSize.Width() * nFirst );
299 buttonRect.setX(aAreaRect.Left());
300 buttonRect.setY(aAreaRect.Top());
302 else if (nPart == ControlPart::ButtonDown)
304 aSize.setHeight( aSize.Height() * nSecond );
305 buttonRect.setX(aAreaRect.Left());
306 buttonRect.setY(aAreaRect.Top() + aAreaRect.GetHeight() - aSize.Height());
308 else if (nPart == ControlPart::ButtonRight)
310 aSize.setWidth( aSize.Width() * nSecond );
311 buttonRect.setX(aAreaRect.Left() + aAreaRect.GetWidth() - aSize.Width());
312 buttonRect.setY(aAreaRect.Top());
315 buttonRect.SetSize(aSize);
317 return buttonRect;
320 gint slider_width;
321 gint stepper_size;
322 gint stepper_spacing;
323 gint trough_border;
325 // Grab some button style attributes
326 gtk_style_context_get_style( pScrollbarStyle,
327 "slider-width", &slider_width,
328 "stepper-size", &stepper_size,
329 "trough-border", &trough_border,
330 "stepper-spacing", &stepper_spacing, nullptr );
332 if ( ( nPart == ControlPart::ButtonUp ) || ( nPart == ControlPart::ButtonDown ) )
334 buttonWidth = slider_width + 2 * trough_border;
335 buttonHeight = stepper_size + trough_border + stepper_spacing;
337 else
339 buttonWidth = stepper_size + trough_border + stepper_spacing;
340 buttonHeight = slider_width + 2 * trough_border;
343 if ( nPart == ControlPart::ButtonUp )
345 buttonHeight *= nFirst;
346 buttonHeight -= 1;
347 buttonRect.setX( aAreaRect.Left() );
348 buttonRect.setY( aAreaRect.Top() );
350 else if ( nPart == ControlPart::ButtonLeft )
352 buttonWidth *= nFirst;
353 buttonWidth -= 1;
354 buttonRect.setX( aAreaRect.Left() );
355 buttonRect.setY( aAreaRect.Top() );
357 else if ( nPart == ControlPart::ButtonDown )
359 buttonHeight *= nSecond;
360 buttonRect.setX( aAreaRect.Left() );
361 buttonRect.setY( aAreaRect.Top() + aAreaRect.GetHeight() - buttonHeight );
363 else if ( nPart == ControlPart::ButtonRight )
365 buttonWidth *= nSecond;
366 buttonRect.setX( aAreaRect.Left() + aAreaRect.GetWidth() - buttonWidth );
367 buttonRect.setY( aAreaRect.Top() );
370 buttonRect.SetSize( Size( buttonWidth, buttonHeight ) );
372 return buttonRect;
375 static GtkWidget* gCacheWindow;
376 static GtkWidget* gDumbContainer;
377 static GtkWidget* gSpinBox;
378 static GtkWidget* gEntryBox;
379 static GtkWidget* gComboBox;
380 static GtkWidget* gListBox;
381 static GtkWidget* gMenuBarWidget;
382 static GtkWidget* gMenuItemMenuBarWidget;
383 static GtkWidget* gCheckMenuItemWidget;
384 static GtkWidget* gTreeViewWidget;
386 namespace
388 void style_context_set_state(GtkStyleContext* context, GtkStateFlags flags)
392 gtk_style_context_set_state(context, flags);
394 while ((context = gtk_style_context_get_parent(context)));
397 class StyleContextSave
399 private:
400 std::vector<std::pair<GtkStyleContext*, GtkStateFlags>> m_aStates;
401 public:
402 void save(GtkStyleContext* context)
406 m_aStates.emplace_back(context, gtk_style_context_get_state(context));
408 while ((context = gtk_style_context_get_parent(context)));
410 void restore()
412 for (auto a = m_aStates.rbegin(); a != m_aStates.rend(); ++a)
414 gtk_style_context_set_state(a->first, a->second);
416 m_aStates.clear();
420 tools::Rectangle render_common(GtkStyleContext *pContext, cairo_t *cr, const tools::Rectangle &rIn, GtkStateFlags flags)
422 if (!pContext)
423 return rIn;
425 gtk_style_context_set_state(pContext, flags);
427 tools::Rectangle aRect(rIn);
428 GtkBorder margin;
429 gtk_style_context_get_margin(pContext, gtk_style_context_get_state(pContext), &margin);
431 aRect.AdjustLeft(margin.left );
432 aRect.AdjustTop(margin.top );
433 aRect.AdjustRight( -(margin.right) );
434 aRect.AdjustBottom( -(margin.bottom) );
436 gtk_render_background(pContext, cr, aRect.Left(), aRect.Top(),
437 aRect.GetWidth(), aRect.GetHeight());
438 gtk_render_frame(pContext, cr, aRect.Left(), aRect.Top(),
439 aRect.GetWidth(), aRect.GetHeight());
441 GtkBorder border, padding;
442 gtk_style_context_get_border(pContext, gtk_style_context_get_state(pContext), &border);
443 gtk_style_context_get_padding(pContext, gtk_style_context_get_state(pContext), &padding);
445 aRect.AdjustLeft(border.left + padding.left );
446 aRect.AdjustTop(border.top + padding.top );
447 aRect.AdjustRight( -(border.right + padding.right) );
448 aRect.AdjustBottom( -(border.bottom + padding.bottom) );
450 return aRect;
454 void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
455 cairo_t *cr,
456 const tools::Rectangle& rControlRectangle,
457 ControlPart nPart,
458 const ImplControlValue& rValue )
460 if (gtk_check_version(3, 20, 0) == nullptr)
462 assert(rValue.getType() == ControlType::Scrollbar);
463 const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(rValue);
464 tools::Rectangle scrollbarRect;
465 GtkStateFlags stateFlags;
466 GtkOrientation scrollbarOrientation;
467 tools::Rectangle thumbRect = rScrollbarVal.maThumbRect;
468 tools::Rectangle button11BoundRect = rScrollbarVal.maButton1Rect; // backward
469 tools::Rectangle button22BoundRect = rScrollbarVal.maButton2Rect; // forward
470 tools::Rectangle button12BoundRect = rScrollbarVal.maButton1Rect; // secondary forward
471 tools::Rectangle button21BoundRect = rScrollbarVal.maButton2Rect; // secondary backward
472 gdouble arrow1Angle; // backward
473 gdouble arrow2Angle; // forward
474 tools::Rectangle arrowRect;
475 gint slider_width = 0;
476 gint stepper_size = 0;
478 // make controlvalue rectangles relative to area
479 thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
480 button11BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
481 button22BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
482 button12BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
483 button21BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
485 // Find the overall bounding rect of the control
486 scrollbarRect = rControlRectangle;
487 if (scrollbarRect.GetWidth() <= 0 || scrollbarRect.GetHeight() <= 0)
488 return;
490 gint slider_side;
491 Size aSize;
492 if (nPart == ControlPart::DrawBackgroundHorz)
494 QuerySize(mpHScrollbarStyle, aSize);
495 QuerySize(mpHScrollbarContentsStyle, aSize);
496 QuerySize(mpHScrollbarTroughStyle, aSize);
497 QuerySize(mpHScrollbarSliderStyle, aSize);
498 slider_side = aSize.Height();
499 gtk_style_context_get(mpHScrollbarButtonStyle,
500 gtk_style_context_get_state(mpHScrollbarButtonStyle),
501 "min-height", &slider_width,
502 "min-width", &stepper_size, nullptr);
504 else
506 QuerySize(mpVScrollbarStyle, aSize);
507 QuerySize(mpVScrollbarContentsStyle, aSize);
508 QuerySize(mpVScrollbarTroughStyle, aSize);
509 QuerySize(mpVScrollbarSliderStyle, aSize);
510 slider_side = aSize.Width();
511 gtk_style_context_get(mpVScrollbarButtonStyle,
512 gtk_style_context_get_state(mpVScrollbarButtonStyle),
513 "min-width", &slider_width,
514 "min-height", &stepper_size, nullptr);
517 gboolean has_forward;
518 gboolean has_forward2;
519 gboolean has_backward;
520 gboolean has_backward2;
522 gtk_style_context_get_style( context,
523 "has-forward-stepper", &has_forward,
524 "has-secondary-forward-stepper", &has_forward2,
525 "has-backward-stepper", &has_backward,
526 "has-secondary-backward-stepper", &has_backward2, nullptr );
528 if ( nPart == ControlPart::DrawBackgroundHorz )
530 // Center vertically in the track
531 scrollbarRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
532 scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), slider_side ) );
533 thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
534 thumbRect.SetSize( Size( thumbRect.GetWidth(), slider_side ) );
536 scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
537 arrow1Angle = G_PI * 3 / 2;
538 arrow2Angle = G_PI / 2;
540 if ( has_backward )
542 button12BoundRect.Move( stepper_size,
543 (scrollbarRect.GetHeight() - slider_width) / 2 );
546 button11BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
547 button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
548 button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
550 if ( has_backward2 )
552 button22BoundRect.Move( stepper_size, (scrollbarRect.GetHeight() - slider_width) / 2 );
553 button21BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
555 else
557 button22BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
560 button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
561 button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
563 else
565 // Center horizontally in the track
566 scrollbarRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
567 scrollbarRect.SetSize( Size( slider_side, scrollbarRect.GetHeight() ) );
568 thumbRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
569 thumbRect.SetSize( Size( slider_side, thumbRect.GetHeight() ) );
571 scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
572 arrow1Angle = 0;
573 arrow2Angle = G_PI;
575 if ( has_backward )
577 button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
578 stepper_size );
580 button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
581 button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
582 button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
584 if ( has_backward2 )
586 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size );
587 button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
589 else
591 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
594 button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
595 button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
598 bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
600 // ----------------- CONTENTS
601 GtkStyleContext* pScrollbarContentsStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
602 mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
604 gtk_render_background(gtk_widget_get_style_context(gCacheWindow), cr, 0, 0,
605 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
607 gtk_render_background(context, cr, 0, 0,
608 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
609 gtk_render_frame(context, cr, 0, 0,
610 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
612 gtk_render_background(pScrollbarContentsStyle, cr, 0, 0,
613 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
614 gtk_render_frame(pScrollbarContentsStyle, cr, 0, 0,
615 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
617 bool backwardButtonInsensitive =
618 rScrollbarVal.mnCur == rScrollbarVal.mnMin;
619 bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
620 rScrollbarVal.mnCur + rScrollbarVal.mnVisibleSize >= rScrollbarVal.mnMax;
622 // ----------------- BUTTON 1
623 if ( has_backward )
625 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
626 if ( backwardButtonInsensitive )
627 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
629 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
630 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
632 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
634 gtk_render_background(pScrollbarButtonStyle, cr,
635 button11BoundRect.Left(), button11BoundRect.Top(),
636 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
637 gtk_render_frame(pScrollbarButtonStyle, cr,
638 button11BoundRect.Left(), button11BoundRect.Top(),
639 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
641 // ----------------- ARROW 1
642 NWCalcArrowRect( button11BoundRect, arrowRect );
643 gtk_render_arrow(pScrollbarButtonStyle, cr,
644 arrow1Angle,
645 arrowRect.Left(), arrowRect.Top(),
646 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
648 if ( has_forward2 )
650 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
651 if ( forwardButtonInsensitive )
652 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
654 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
655 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
657 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
659 gtk_render_background(pScrollbarButtonStyle, cr,
660 button12BoundRect.Left(), button12BoundRect.Top(),
661 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
662 gtk_render_frame(pScrollbarButtonStyle, cr,
663 button12BoundRect.Left(), button12BoundRect.Top(),
664 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
666 // ----------------- ARROW 1
667 NWCalcArrowRect( button12BoundRect, arrowRect );
668 gtk_render_arrow(pScrollbarButtonStyle, cr,
669 arrow2Angle,
670 arrowRect.Left(), arrowRect.Top(),
671 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
673 // ----------------- BUTTON 2
675 if ( has_forward )
677 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
678 if ( forwardButtonInsensitive )
679 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
681 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
682 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
684 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
686 gtk_render_background(pScrollbarButtonStyle, cr,
687 button22BoundRect.Left(), button22BoundRect.Top(),
688 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
689 gtk_render_frame(pScrollbarButtonStyle, cr,
690 button22BoundRect.Left(), button22BoundRect.Top(),
691 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
693 // ----------------- ARROW 2
694 NWCalcArrowRect( button22BoundRect, arrowRect );
695 gtk_render_arrow(pScrollbarButtonStyle, cr,
696 arrow2Angle,
697 arrowRect.Left(), arrowRect.Top(),
698 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
701 if ( has_backward2 )
703 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
704 if ( backwardButtonInsensitive )
705 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
707 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
708 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
710 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
712 gtk_render_background(pScrollbarButtonStyle, cr,
713 button21BoundRect.Left(), button21BoundRect.Top(),
714 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
715 gtk_render_frame(pScrollbarButtonStyle, cr,
716 button21BoundRect.Left(), button21BoundRect.Top(),
717 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
719 // ----------------- ARROW 2
720 NWCalcArrowRect( button21BoundRect, arrowRect );
721 gtk_render_arrow(pScrollbarButtonStyle, cr,
722 arrow1Angle,
723 arrowRect.Left(), arrowRect.Top(),
724 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
727 // ----------------- TROUGH
728 // trackrect matches that of ScrollBar::ImplCalc
729 tools::Rectangle aTrackRect(Point(0, 0), scrollbarRect.GetSize());
730 if (nPart == ControlPart::DrawBackgroundHorz)
732 tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonLeft, aTrackRect);
733 tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonRight, aTrackRect);
734 if (!aBtn1Rect.IsWidthEmpty())
735 aTrackRect.SetLeft( aBtn1Rect.Right() );
736 if (!aBtn2Rect.IsWidthEmpty())
737 aTrackRect.SetRight( aBtn2Rect.Left() );
739 else
741 tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonUp, aTrackRect);
742 tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonDown, aTrackRect);
743 if (!aBtn1Rect.IsHeightEmpty())
744 aTrackRect.SetTop( aBtn1Rect.Bottom() + 1 );
745 if (!aBtn2Rect.IsHeightEmpty())
746 aTrackRect.SetBottom( aBtn2Rect.Top() );
749 GtkStyleContext* pScrollbarTroughStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
750 mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
751 gtk_render_background(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
752 aTrackRect.GetWidth(), aTrackRect.GetHeight() );
753 gtk_render_frame(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
754 aTrackRect.GetWidth(), aTrackRect.GetHeight() );
756 // ----------------- THUMB
757 if ( has_slider )
759 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnThumbState);
760 if ( rScrollbarVal.mnThumbState & ControlState::PRESSED )
761 stateFlags = static_cast<GtkStateFlags>(stateFlags | GTK_STATE_PRELIGHT);
763 GtkStyleContext* pScrollbarSliderStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
764 mpVScrollbarSliderStyle : mpHScrollbarSliderStyle;
766 gtk_style_context_set_state(pScrollbarSliderStyle, stateFlags);
768 GtkBorder margin;
769 gtk_style_context_get_margin(pScrollbarSliderStyle, stateFlags, &margin);
771 gtk_render_background(pScrollbarSliderStyle, cr,
772 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
773 thumbRect.GetWidth() - margin.left - margin.right,
774 thumbRect.GetHeight() - margin.top - margin.bottom);
776 gtk_render_frame(pScrollbarSliderStyle, cr,
777 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
778 thumbRect.GetWidth() - margin.left - margin.right,
779 thumbRect.GetHeight() - margin.top - margin.bottom);
782 return;
785 OSL_ASSERT( rValue.getType() == ControlType::Scrollbar );
786 const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(rValue);
787 tools::Rectangle scrollbarRect;
788 GtkStateFlags stateFlags;
789 GtkOrientation scrollbarOrientation;
790 tools::Rectangle thumbRect = rScrollbarVal.maThumbRect;
791 tools::Rectangle button11BoundRect = rScrollbarVal.maButton1Rect; // backward
792 tools::Rectangle button22BoundRect = rScrollbarVal.maButton2Rect; // forward
793 tools::Rectangle button12BoundRect = rScrollbarVal.maButton1Rect; // secondary forward
794 tools::Rectangle button21BoundRect = rScrollbarVal.maButton2Rect; // secondary backward
795 gdouble arrow1Angle; // backward
796 gdouble arrow2Angle; // forward
797 tools::Rectangle arrowRect;
798 gint slider_width = 0;
799 gint stepper_size = 0;
800 gint trough_border = 0;
802 // make controlvalue rectangles relative to area
803 thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
804 button11BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
805 button22BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
806 button12BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
807 button21BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
809 // Find the overall bounding rect of the control
810 scrollbarRect = rControlRectangle;
811 scrollbarRect.SetSize( Size( scrollbarRect.GetWidth() + 1,
812 scrollbarRect.GetHeight() + 1 ) );
814 if ( (scrollbarRect.GetWidth() <= 1) || (scrollbarRect.GetHeight() <= 1) )
815 return;
817 // Grab some button style attributes
818 gtk_style_context_get_style( context,
819 "slider_width", &slider_width,
820 "stepper_size", &stepper_size,
821 "trough_border", &trough_border, nullptr );
822 gboolean has_forward;
823 gboolean has_forward2;
824 gboolean has_backward;
825 gboolean has_backward2;
827 gtk_style_context_get_style( context,
828 "has-forward-stepper", &has_forward,
829 "has-secondary-forward-stepper", &has_forward2,
830 "has-backward-stepper", &has_backward,
831 "has-secondary-backward-stepper", &has_backward2, nullptr );
832 gint magic = trough_border ? 1 : 0;
833 gint slider_side = slider_width + (trough_border * 2);
835 if ( nPart == ControlPart::DrawBackgroundHorz )
837 scrollbarRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
838 scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), slider_side ) );
840 scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
841 arrow1Angle = G_PI * 3 / 2;
842 arrow2Angle = G_PI / 2;
844 if ( has_backward )
846 button12BoundRect.Move( stepper_size - trough_border,
847 (scrollbarRect.GetHeight() - slider_width) / 2 );
850 button11BoundRect.Move( trough_border, (scrollbarRect.GetHeight() - slider_width) / 2 );
851 button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
852 button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
854 if ( has_backward2 )
856 button22BoundRect.Move( stepper_size+(trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
857 button21BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
859 else
861 button22BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
864 button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
865 button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
867 thumbRect.SetBottom( thumbRect.Top() + slider_width - 1 );
868 // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
869 // but if the VCL gives us a size smaller than the theme's default thumb size,
870 // honor the VCL size
871 thumbRect.AdjustRight(magic );
872 // Center vertically in the track
873 thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
875 else
877 scrollbarRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
878 scrollbarRect.SetSize( Size( slider_side, scrollbarRect.GetHeight() ) );
880 scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
881 arrow1Angle = 0;
882 arrow2Angle = G_PI;
884 if ( has_backward )
886 button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
887 stepper_size + trough_border );
889 button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, trough_border );
890 button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
891 button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
893 if ( has_backward2 )
895 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size+(trough_border+1)/2 );
896 button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
898 else
900 button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
903 button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
904 button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
906 thumbRect.SetRight( thumbRect.Left() + slider_width - 1 );
908 thumbRect.AdjustBottom(magic );
909 // Center horizontally in the track
910 thumbRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
913 bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
915 // ----------------- CONTENTS
916 GtkStyleContext* pScrollbarContentsStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
917 mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
919 gtk_render_background(gtk_widget_get_style_context(gCacheWindow), cr, 0, 0,
920 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
922 gtk_render_background(context, cr, 0, 0,
923 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
924 gtk_render_frame(context, cr, 0, 0,
925 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
927 gtk_render_background(pScrollbarContentsStyle, cr, 0, 0,
928 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
929 gtk_render_frame(pScrollbarContentsStyle, cr, 0, 0,
930 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
932 // ----------------- TROUGH
933 GtkStyleContext* pScrollbarTroughStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
934 mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
935 gtk_render_background(pScrollbarTroughStyle, cr, 0, 0,
936 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
937 gtk_render_frame(pScrollbarTroughStyle, cr, 0, 0,
938 scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
940 // ----------------- THUMB
941 if ( has_slider )
943 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnThumbState);
944 if ( rScrollbarVal.mnThumbState & ControlState::PRESSED )
945 stateFlags = static_cast<GtkStateFlags>(stateFlags | GTK_STATE_PRELIGHT);
947 GtkStyleContext* pScrollbarSliderStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
948 mpVScrollbarSliderStyle : mpHScrollbarSliderStyle;
950 gtk_style_context_set_state(pScrollbarSliderStyle, stateFlags);
952 GtkBorder margin;
953 gtk_style_context_get_margin(pScrollbarSliderStyle, stateFlags, &margin);
955 gtk_render_background(pScrollbarSliderStyle, cr,
956 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
957 thumbRect.GetWidth() - margin.left - margin.right,
958 thumbRect.GetHeight() - margin.top - margin.bottom);
960 gtk_render_frame(pScrollbarSliderStyle, cr,
961 thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
962 thumbRect.GetWidth() - margin.left - margin.right,
963 thumbRect.GetHeight() - margin.top - margin.bottom);
966 bool backwardButtonInsensitive =
967 rScrollbarVal.mnCur == rScrollbarVal.mnMin;
968 bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
969 rScrollbarVal.mnCur + rScrollbarVal.mnVisibleSize >= rScrollbarVal.mnMax;
971 // ----------------- BUTTON 1
972 if ( has_backward )
974 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
975 if ( backwardButtonInsensitive )
976 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
978 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
979 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
981 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
983 gtk_render_background(pScrollbarButtonStyle, cr,
984 button11BoundRect.Left(), button11BoundRect.Top(),
985 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
986 gtk_render_frame(pScrollbarButtonStyle, cr,
987 button11BoundRect.Left(), button11BoundRect.Top(),
988 button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
990 // ----------------- ARROW 1
991 NWCalcArrowRect( button11BoundRect, arrowRect );
992 gtk_render_arrow(pScrollbarButtonStyle, cr,
993 arrow1Angle,
994 arrowRect.Left(), arrowRect.Top(),
995 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
997 if ( has_forward2 )
999 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
1000 if ( forwardButtonInsensitive )
1001 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
1003 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
1004 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
1006 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
1008 gtk_render_background(pScrollbarButtonStyle, cr,
1009 button12BoundRect.Left(), button12BoundRect.Top(),
1010 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
1011 gtk_render_frame(pScrollbarButtonStyle, cr,
1012 button12BoundRect.Left(), button12BoundRect.Top(),
1013 button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
1015 // ----------------- ARROW 1
1016 NWCalcArrowRect( button12BoundRect, arrowRect );
1017 gtk_render_arrow(pScrollbarButtonStyle, cr,
1018 arrow2Angle,
1019 arrowRect.Left(), arrowRect.Top(),
1020 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
1022 // ----------------- BUTTON 2
1023 if ( has_backward2 )
1025 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
1026 if ( backwardButtonInsensitive )
1027 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
1029 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
1030 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
1032 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
1034 gtk_render_background(pScrollbarButtonStyle, cr,
1035 button21BoundRect.Left(), button21BoundRect.Top(),
1036 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
1037 gtk_render_frame(pScrollbarButtonStyle, cr,
1038 button21BoundRect.Left(), button21BoundRect.Top(),
1039 button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
1041 // ----------------- ARROW 2
1042 NWCalcArrowRect( button21BoundRect, arrowRect );
1043 gtk_render_arrow(pScrollbarButtonStyle, cr,
1044 arrow1Angle,
1045 arrowRect.Left(), arrowRect.Top(),
1046 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
1048 if ( has_forward )
1050 stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
1051 if ( forwardButtonInsensitive )
1052 stateFlags = GTK_STATE_FLAG_INSENSITIVE;
1054 GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
1055 mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
1057 gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
1059 gtk_render_background(pScrollbarButtonStyle, cr,
1060 button22BoundRect.Left(), button22BoundRect.Top(),
1061 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
1062 gtk_render_frame(pScrollbarButtonStyle, cr,
1063 button22BoundRect.Left(), button22BoundRect.Top(),
1064 button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
1066 // ----------------- ARROW 2
1067 NWCalcArrowRect( button22BoundRect, arrowRect );
1068 gtk_render_arrow(pScrollbarButtonStyle, cr,
1069 arrow2Angle,
1070 arrowRect.Left(), arrowRect.Top(),
1071 MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
1075 void GtkSalGraphics::PaintOneSpinButton( GtkStyleContext *context,
1076 cairo_t *cr,
1077 ControlPart nPart,
1078 tools::Rectangle aAreaRect,
1079 ControlState nState )
1081 GtkBorder padding, border;
1083 GtkStateFlags stateFlags = NWConvertVCLStateToGTKState(nState);
1084 tools::Rectangle buttonRect = NWGetSpinButtonRect( nPart, aAreaRect );
1086 gtk_style_context_set_state(context, stateFlags);
1087 stateFlags = gtk_style_context_get_state(context);
1089 gtk_style_context_get_padding(context, stateFlags, &padding);
1090 gtk_style_context_get_border(context, stateFlags, &border);
1092 gtk_render_background(context, cr,
1093 buttonRect.Left(), buttonRect.Top(),
1094 buttonRect.GetWidth(), buttonRect.GetHeight() );
1096 gint iconWidth = buttonRect.GetWidth() - padding.left - padding.right - border.left - border.right;
1097 gint iconHeight = buttonRect.GetHeight() - padding.top - padding.bottom - border.top - border.bottom;
1099 const char* icon = (nPart == ControlPart::ButtonUp) ? "list-add-symbolic" : "list-remove-symbolic";
1100 GtkIconTheme *pIconTheme = gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow));
1102 gint scale = gtk_style_context_get_scale (context);
1103 GtkIconInfo *info = gtk_icon_theme_lookup_icon_for_scale(pIconTheme, icon, std::min(iconWidth, iconHeight), scale,
1104 static_cast<GtkIconLookupFlags>(0));
1106 GdkPixbuf *pixbuf = gtk_icon_info_load_symbolic_for_context(info, context, nullptr, nullptr);
1107 g_object_unref(info);
1109 iconWidth = gdk_pixbuf_get_width(pixbuf)/scale;
1110 iconHeight = gdk_pixbuf_get_height(pixbuf)/scale;
1111 tools::Rectangle arrowRect;
1112 arrowRect.SetSize(Size(iconWidth, iconHeight));
1113 arrowRect.setX( buttonRect.Left() + (buttonRect.GetWidth() - arrowRect.GetWidth()) / 2 );
1114 arrowRect.setY( buttonRect.Top() + (buttonRect.GetHeight() - arrowRect.GetHeight()) / 2 );
1116 gtk_style_context_save (context);
1117 gtk_style_context_set_scale (context, 1);
1118 gtk_render_icon(context, cr, pixbuf, arrowRect.Left(), arrowRect.Top());
1119 gtk_style_context_restore (context);
1120 g_object_unref(pixbuf);
1122 gtk_render_frame(context, cr,
1123 buttonRect.Left(), buttonRect.Top(),
1124 buttonRect.GetWidth(), buttonRect.GetHeight() );
1127 void GtkSalGraphics::PaintSpinButton(GtkStateFlags flags,
1128 cairo_t *cr,
1129 const tools::Rectangle& rControlRectangle,
1130 ControlPart nPart,
1131 const ImplControlValue& rValue )
1133 const SpinbuttonValue *pSpinVal = (rValue.getType() == ControlType::SpinButtons) ? static_cast<const SpinbuttonValue *>(&rValue) : nullptr;
1134 ControlPart upBtnPart = ControlPart::ButtonUp;
1135 ControlState upBtnState = ControlState::NONE;
1136 ControlPart downBtnPart = ControlPart::ButtonDown;
1137 ControlState downBtnState = ControlState::NONE;
1139 if ( pSpinVal )
1141 upBtnPart = pSpinVal->mnUpperPart;
1142 upBtnState = pSpinVal->mnUpperState;
1144 downBtnPart = pSpinVal->mnLowerPart;
1145 downBtnState = pSpinVal->mnLowerState;
1148 if (nPart == ControlPart::Entire)
1150 gtk_style_context_set_state(mpWindowStyle, flags);
1152 gtk_render_background(mpWindowStyle, cr,
1153 0, 0,
1154 rControlRectangle.GetWidth(), rControlRectangle.GetHeight());
1156 gtk_style_context_set_state(mpSpinStyle, flags);
1158 gtk_render_background(mpSpinStyle, cr,
1159 0, 0,
1160 rControlRectangle.GetWidth(), rControlRectangle.GetHeight());
1163 cairo_translate(cr, -rControlRectangle.Left(), -rControlRectangle.Top());
1164 PaintOneSpinButton(mpSpinUpStyle, cr, upBtnPart, rControlRectangle, upBtnState );
1165 PaintOneSpinButton(mpSpinDownStyle, cr, downBtnPart, rControlRectangle, downBtnState );
1166 cairo_translate(cr, rControlRectangle.Left(), rControlRectangle.Top());
1168 if (nPart == ControlPart::Entire)
1170 gtk_render_frame(mpSpinStyle, cr,
1171 0, 0,
1172 rControlRectangle.GetWidth(), rControlRectangle.GetHeight() );
1176 #define FALLBACK_ARROW_SIZE gint(11 * 0.85)
1178 tools::Rectangle GtkSalGraphics::NWGetComboBoxButtonRect(ControlType nType,
1179 ControlPart nPart,
1180 tools::Rectangle aAreaRect )
1182 tools::Rectangle aButtonRect;
1184 GtkBorder padding;
1185 if (nType == ControlType::Listbox)
1186 gtk_style_context_get_padding(mpListboxButtonStyle, gtk_style_context_get_state(mpListboxButtonStyle), &padding);
1187 else
1188 gtk_style_context_get_padding(mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &padding);
1190 gint nArrowWidth = FALLBACK_ARROW_SIZE;
1191 if (gtk_check_version(3, 20, 0) == nullptr)
1193 gtk_style_context_get(mpComboboxButtonArrowStyle,
1194 gtk_style_context_get_state(mpComboboxButtonArrowStyle),
1195 "min-width", &nArrowWidth, nullptr);
1197 else
1199 nArrowWidth = nArrowWidth * gtk_style_context_get_scale (mpComboboxButtonArrowStyle);
1202 gint nButtonWidth = nArrowWidth + padding.left + padding.right;
1203 if( nPart == ControlPart::ButtonDown )
1205 Point aPos(aAreaRect.Left() + aAreaRect.GetWidth() - nButtonWidth, aAreaRect.Top());
1206 if (AllSettings::GetLayoutRTL())
1207 aPos.setX( aAreaRect.Left() );
1208 aButtonRect.SetSize( Size( nButtonWidth, aAreaRect.GetHeight() ) );
1209 aButtonRect.SetPos(aPos);
1211 else if( nPart == ControlPart::SubEdit )
1213 gint adjust_left = padding.left;
1214 gint adjust_top = padding.top;
1215 gint adjust_right = padding.right;
1216 gint adjust_bottom = padding.bottom;
1218 aButtonRect.SetSize( Size( aAreaRect.GetWidth() - nButtonWidth - (adjust_left + adjust_right),
1219 aAreaRect.GetHeight() - (adjust_top + adjust_bottom)) );
1220 Point aEditPos = aAreaRect.TopLeft();
1221 if (AllSettings::GetLayoutRTL())
1222 aEditPos.AdjustX(nButtonWidth );
1223 else
1224 aEditPos.AdjustX(adjust_left );
1225 aEditPos.AdjustY(adjust_top );
1226 aButtonRect.SetPos( aEditPos );
1229 return aButtonRect;
1232 void GtkSalGraphics::PaintCombobox( GtkStateFlags flags, cairo_t *cr,
1233 const tools::Rectangle& rControlRectangle,
1234 ControlType nType,
1235 ControlPart nPart )
1237 tools::Rectangle areaRect;
1238 tools::Rectangle buttonRect;
1239 tools::Rectangle arrowRect;
1241 // Find the overall bounding rect of the buttons's drawing area,
1242 // plus its actual draw rect excluding adornment
1243 areaRect = rControlRectangle;
1245 buttonRect = NWGetComboBoxButtonRect(ControlType::Combobox, ControlPart::ButtonDown, areaRect);
1247 tools::Rectangle aEditBoxRect( areaRect );
1248 aEditBoxRect.SetSize( Size( areaRect.GetWidth() - buttonRect.GetWidth(), aEditBoxRect.GetHeight() ) );
1249 if (AllSettings::GetLayoutRTL())
1250 aEditBoxRect.SetPos( Point( areaRect.Left() + buttonRect.GetWidth(), areaRect.Top() ) );
1252 gint arrow_width = FALLBACK_ARROW_SIZE, arrow_height = FALLBACK_ARROW_SIZE;
1253 if (gtk_check_version(3, 20, 0) == nullptr)
1255 if (nType == ControlType::Combobox)
1257 gtk_style_context_get(mpComboboxButtonArrowStyle,
1258 gtk_style_context_get_state(mpComboboxButtonArrowStyle),
1259 "min-width", &arrow_width, "min-height", &arrow_height, nullptr);
1261 else if (nType == ControlType::Listbox)
1263 gtk_style_context_get(mpListboxButtonArrowStyle,
1264 gtk_style_context_get_state(mpListboxButtonArrowStyle),
1265 "min-width", &arrow_width, "min-height", &arrow_height, nullptr);
1268 else
1270 if (nType == ControlType::Combobox)
1272 arrow_width = arrow_width * gtk_style_context_get_scale (mpComboboxButtonArrowStyle);
1273 arrow_height = arrow_height * gtk_style_context_get_scale (mpComboboxButtonArrowStyle);
1275 else if (nType == ControlType::Listbox)
1277 arrow_width = arrow_width * gtk_style_context_get_scale (mpListboxButtonArrowStyle);
1278 arrow_height = arrow_height * gtk_style_context_get_scale (mpListboxButtonArrowStyle);
1282 arrowRect.SetSize(Size(arrow_width, arrow_height));
1283 arrowRect.SetPos( Point( buttonRect.Left() + static_cast<gint>((buttonRect.GetWidth() - arrowRect.GetWidth()) / 2),
1284 buttonRect.Top() + static_cast<gint>((buttonRect.GetHeight() - arrowRect.GetHeight()) / 2) ) );
1287 tools::Rectangle aRect(Point(0, 0), Size(areaRect.GetWidth(), areaRect.GetHeight()));
1289 if (nType == ControlType::Combobox)
1291 if( nPart == ControlPart::Entire )
1293 render_common(mpComboboxStyle, cr, aRect, flags);
1294 render_common(mpComboboxBoxStyle, cr, aRect, flags);
1295 tools::Rectangle aEntryRect(Point(aEditBoxRect.Left() - areaRect.Left(),
1296 aEditBoxRect.Top() - areaRect.Top()),
1297 Size(aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight()));
1299 GtkJunctionSides eJuncSides = gtk_style_context_get_junction_sides(mpComboboxEntryStyle);
1300 if (AllSettings::GetLayoutRTL())
1301 gtk_style_context_set_junction_sides(mpComboboxEntryStyle, GTK_JUNCTION_LEFT);
1302 else
1303 gtk_style_context_set_junction_sides(mpComboboxEntryStyle, GTK_JUNCTION_RIGHT);
1304 render_common(mpComboboxEntryStyle, cr, aEntryRect, flags);
1305 gtk_style_context_set_junction_sides(mpComboboxEntryStyle, eJuncSides);
1308 tools::Rectangle aButtonRect(Point(buttonRect.Left() - areaRect.Left(), buttonRect.Top() - areaRect.Top()),
1309 Size(buttonRect.GetWidth(), buttonRect.GetHeight()));
1310 GtkJunctionSides eJuncSides = gtk_style_context_get_junction_sides(mpComboboxButtonStyle);
1311 if (AllSettings::GetLayoutRTL())
1312 gtk_style_context_set_junction_sides(mpComboboxButtonStyle, GTK_JUNCTION_RIGHT);
1313 else
1314 gtk_style_context_set_junction_sides(mpComboboxButtonStyle, GTK_JUNCTION_LEFT);
1315 render_common(mpComboboxButtonStyle, cr, aButtonRect, flags);
1316 gtk_style_context_set_junction_sides(mpComboboxButtonStyle, eJuncSides);
1318 gtk_render_arrow(mpComboboxButtonArrowStyle, cr,
1319 G_PI,
1320 (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
1321 arrowRect.GetWidth() );
1323 else if (nType == ControlType::Listbox)
1325 if( nPart == ControlPart::ListboxWindow )
1327 /* render the popup window with the menu style */
1328 gtk_render_frame(mpMenuStyle, cr,
1329 0, 0,
1330 areaRect.GetWidth(), areaRect.GetHeight());
1332 else
1334 render_common(mpListboxStyle, cr, aRect, flags);
1335 render_common(mpListboxBoxStyle, cr, aRect, flags);
1337 render_common(mpListboxButtonStyle, cr, aRect, flags);
1339 gtk_render_arrow(mpListboxButtonArrowStyle, cr,
1340 G_PI,
1341 (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
1342 arrowRect.GetWidth() );
1347 static void appendComboEntry(GtkWidgetPath* pSiblingsPath, gtk_widget_path_iter_set_object_nameFunc set_object_name)
1349 gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_ENTRY);
1350 set_object_name(pSiblingsPath, -1, "entry");
1351 gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
1354 static void appendComboButton(GtkWidgetPath* pSiblingsPath, gtk_widget_path_iter_set_object_nameFunc set_object_name)
1356 gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_BUTTON);
1357 set_object_name(pSiblingsPath, -1, "button");
1358 gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
1361 static GtkWidgetPath* buildLTRComboSiblingsPath(gtk_widget_path_iter_set_object_nameFunc set_object_name)
1363 GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
1365 appendComboEntry(pSiblingsPath, set_object_name);
1366 appendComboButton(pSiblingsPath, set_object_name);
1368 return pSiblingsPath;
1371 static GtkWidgetPath* buildRTLComboSiblingsPath(gtk_widget_path_iter_set_object_nameFunc set_object_name)
1373 GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
1375 appendComboButton(pSiblingsPath, set_object_name);
1376 appendComboEntry(pSiblingsPath, set_object_name);
1378 return pSiblingsPath;
1381 GtkStyleContext* GtkSalGraphics::makeContext(GtkWidgetPath *pPath, GtkStyleContext *pParent)
1383 GtkStyleContext* context = gtk_style_context_new();
1384 gtk_style_context_set_screen(context, gtk_widget_get_screen(mpWindow));
1385 gtk_style_context_set_path(context, pPath);
1386 if (pParent == nullptr)
1388 GtkWidget* pTopLevel = gtk_widget_get_toplevel(mpWindow);
1389 GtkStyleContext* pStyle = gtk_widget_get_style_context(pTopLevel);
1390 gtk_style_context_set_parent(context, pStyle);
1391 gtk_style_context_set_scale (context, gtk_style_context_get_scale (pStyle));
1393 else
1395 gtk_style_context_set_parent(context, pParent);
1396 gtk_style_context_set_scale (context, gtk_style_context_get_scale (pParent));
1398 gtk_widget_path_unref(pPath);
1399 return context;
1402 GtkStyleContext* GtkSalGraphics::createNewContext(GtkControlPart ePart, gtk_widget_path_iter_set_object_nameFunc set_object_name)
1404 switch (ePart)
1406 case GtkControlPart::ToplevelWindow:
1408 GtkWidgetPath *path = gtk_widget_path_new();
1409 gtk_widget_path_append_type(path, G_TYPE_NONE);
1410 set_object_name(path, -1, "window");
1411 gtk_widget_path_iter_add_class(path, -1, "background");
1412 return makeContext(path, nullptr);
1414 case GtkControlPart::Button:
1416 GtkWidgetPath *path = gtk_widget_path_new();
1417 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1418 set_object_name(path, -1, "button");
1419 return makeContext(path, nullptr);
1421 case GtkControlPart::LinkButton:
1423 GtkWidgetPath *path = gtk_widget_path_new();
1424 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1425 set_object_name(path, -1, "button");
1426 gtk_widget_path_iter_add_class(path, -1, "link");
1427 return makeContext(path, nullptr);
1429 case GtkControlPart::CheckButton:
1431 GtkWidgetPath *path = gtk_widget_path_new();
1432 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
1433 set_object_name(path, -1, "checkbutton");
1434 return makeContext(path, nullptr);
1436 case GtkControlPart::CheckButtonCheck:
1438 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckButtonStyle));
1439 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
1440 set_object_name(path, -1, "check");
1441 return makeContext(path, mpCheckButtonStyle);
1443 case GtkControlPart::RadioButton:
1445 GtkWidgetPath *path = gtk_widget_path_new();
1446 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1447 set_object_name(path, -1, "radiobutton");
1448 return makeContext(path, nullptr);
1450 case GtkControlPart::RadioButtonRadio:
1452 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioButtonStyle));
1453 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1454 set_object_name(path, -1, "radio");
1455 return makeContext(path, mpRadioButtonStyle);
1457 case GtkControlPart::ComboboxBoxButtonBoxArrow:
1459 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonBoxStyle));
1460 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1461 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1462 set_object_name(path, -1, "arrow");
1463 return makeContext(path, mpComboboxButtonBoxStyle);
1465 case GtkControlPart::ListboxBoxButtonBoxArrow:
1467 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonBoxStyle));
1468 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1469 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1470 set_object_name(path, -1, "arrow");
1471 return makeContext(path, mpListboxButtonBoxStyle);
1473 case GtkControlPart::Entry:
1475 GtkWidgetPath *path = gtk_widget_path_new();
1476 gtk_widget_path_append_type(path, GTK_TYPE_ENTRY);
1477 set_object_name(path, -1, "entry");
1478 return makeContext(path, nullptr);
1480 case GtkControlPart::Combobox:
1481 case GtkControlPart::Listbox:
1483 GtkWidgetPath *path = gtk_widget_path_new();
1484 gtk_widget_path_append_type(path, G_TYPE_NONE);
1485 set_object_name(path, -1, "combobox");
1486 return makeContext(path, nullptr);
1488 case GtkControlPart::ComboboxBox:
1490 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxStyle));
1491 gtk_widget_path_append_type(path, G_TYPE_NONE);
1492 set_object_name(path, -1, "box");
1493 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1494 gtk_widget_path_iter_add_class(path, -1, "linked");
1495 return makeContext(path, mpComboboxStyle);
1497 case GtkControlPart::ListboxBox:
1499 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxStyle));
1500 gtk_widget_path_append_type(path, G_TYPE_NONE);
1501 set_object_name(path, -1, "box");
1502 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1503 gtk_widget_path_iter_add_class(path, -1, "linked");
1504 return makeContext(path, mpListboxStyle);
1506 case GtkControlPart::ComboboxBoxEntry:
1508 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
1509 GtkWidgetPath* pSiblingsPath;
1510 if (AllSettings::GetLayoutRTL())
1512 pSiblingsPath = buildRTLComboSiblingsPath(set_object_name);
1513 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 1);
1515 else
1517 pSiblingsPath = buildLTRComboSiblingsPath(set_object_name);
1518 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
1520 gtk_widget_path_unref(pSiblingsPath);
1521 return makeContext(path, mpComboboxBoxStyle);
1523 case GtkControlPart::ComboboxBoxButton:
1525 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
1526 GtkWidgetPath* pSiblingsPath;
1527 if (AllSettings::GetLayoutRTL())
1529 pSiblingsPath = buildRTLComboSiblingsPath(set_object_name);
1530 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
1532 else
1534 pSiblingsPath = buildLTRComboSiblingsPath(set_object_name);
1535 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 1);
1537 gtk_widget_path_unref(pSiblingsPath);
1538 return makeContext(path, mpComboboxBoxStyle);
1540 case GtkControlPart::ListboxBoxButton:
1542 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxBoxStyle));
1543 GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
1545 gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_BUTTON);
1546 set_object_name(pSiblingsPath, -1, "button");
1547 gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
1549 gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
1550 gtk_widget_path_unref(pSiblingsPath);
1551 return makeContext(path, mpListboxBoxStyle);
1553 case GtkControlPart::ComboboxBoxButtonBox:
1555 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonStyle));
1556 gtk_widget_path_append_type(path, G_TYPE_NONE);
1557 set_object_name(path, -1, "box");
1558 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1559 return makeContext(path, mpComboboxButtonStyle);
1561 case GtkControlPart::ListboxBoxButtonBox:
1563 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonStyle));
1564 gtk_widget_path_append_type(path, G_TYPE_NONE);
1565 set_object_name(path, -1, "box");
1566 gtk_widget_path_iter_add_class(path, -1, "horizontal");
1567 return makeContext(path, mpListboxButtonStyle);
1569 case GtkControlPart::SpinButton:
1571 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
1572 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1573 set_object_name(path, -1, "spinbutton");
1574 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1575 return makeContext(path, mpWindowStyle);
1577 case GtkControlPart::SpinButtonEntry:
1579 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
1580 gtk_widget_path_append_type(path, G_TYPE_NONE);
1581 set_object_name(path, -1, "entry");
1582 return makeContext(path, mpSpinStyle);
1584 case GtkControlPart::SpinButtonUpButton:
1585 case GtkControlPart::SpinButtonDownButton:
1587 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
1588 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1589 set_object_name(path, -1, "button");
1590 gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::SpinButtonUpButton ? "up" : "down");
1591 return makeContext(path, mpSpinStyle);
1593 case GtkControlPart::ScrollbarVertical:
1594 case GtkControlPart::ScrollbarHorizontal:
1596 GtkWidgetPath *path = gtk_widget_path_new();
1597 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1598 set_object_name(path, -1, "scrollbar");
1599 gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::ScrollbarVertical ? "vertical" : "horizontal");
1600 return makeContext(path, nullptr);
1602 case GtkControlPart::ScrollbarVerticalContents:
1603 case GtkControlPart::ScrollbarHorizontalContents:
1605 GtkStyleContext *pParent =
1606 (ePart == GtkControlPart::ScrollbarVerticalContents) ? mpVScrollbarStyle : mpHScrollbarStyle;
1607 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1608 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1609 set_object_name(path, -1, "contents");
1610 return makeContext(path, pParent);
1612 case GtkControlPart::ScrollbarVerticalTrough:
1613 case GtkControlPart::ScrollbarHorizontalTrough:
1615 GtkStyleContext *pParent =
1616 (ePart == GtkControlPart::ScrollbarVerticalTrough) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
1617 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1618 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1619 set_object_name(path, -1, "trough");
1620 return makeContext(path, pParent);
1622 case GtkControlPart::ScrollbarVerticalSlider:
1623 case GtkControlPart::ScrollbarHorizontalSlider:
1625 GtkStyleContext *pParent =
1626 (ePart == GtkControlPart::ScrollbarVerticalSlider) ? mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
1627 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1628 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1629 set_object_name(path, -1, "slider");
1630 return makeContext(path, pParent);
1632 case GtkControlPart::ScrollbarVerticalButton:
1633 case GtkControlPart::ScrollbarHorizontalButton:
1635 GtkStyleContext *pParent =
1636 (ePart == GtkControlPart::ScrollbarVerticalButton) ? mpVScrollbarStyle : mpHScrollbarStyle;
1637 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1638 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1639 set_object_name(path, -1, "button");
1640 return makeContext(path, pParent);
1642 case GtkControlPart::ProgressBar:
1644 GtkWidgetPath *path = gtk_widget_path_new();
1645 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1646 set_object_name(path, -1, "progressbar");
1647 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1648 return makeContext(path, nullptr);
1650 case GtkControlPart::ProgressBarTrough:
1652 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle));
1653 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1654 set_object_name(path, -1, "trough");
1655 return makeContext(path, mpProgressBarStyle);
1657 case GtkControlPart::ProgressBarProgress:
1659 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarTroughStyle));
1660 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1661 set_object_name(path, -1, "progress");
1662 return makeContext(path, mpProgressBarTroughStyle);
1664 case GtkControlPart::Notebook:
1666 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
1667 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1668 set_object_name(path, -1, "notebook");
1669 return makeContext(path, mpWindowStyle);
1671 case GtkControlPart::NotebookStack:
1673 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
1674 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1675 set_object_name(path, -1, "stack");
1676 return makeContext(path, mpNotebookStyle);
1678 case GtkControlPart::NotebookHeader:
1680 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
1681 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1682 set_object_name(path, -1, "header");
1683 gtk_widget_path_iter_add_class(path, -1, "frame");
1684 gtk_widget_path_iter_add_class(path, -1, "top");
1685 return makeContext(path, mpNotebookStyle);
1687 case GtkControlPart::NotebookHeaderTabs:
1689 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderStyle));
1690 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1691 set_object_name(path, -1, "tabs");
1692 gtk_widget_path_iter_add_class(path, -1, "top");
1693 return makeContext(path, mpNotebookHeaderStyle);
1695 case GtkControlPart::NotebookHeaderTabsTab:
1697 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsStyle));
1698 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
1699 set_object_name(path, -1, "tab");
1700 gtk_widget_path_iter_add_class(path, -1, "top");
1701 return makeContext(path, mpNotebookHeaderTabsStyle);
1703 case GtkControlPart::NotebookHeaderTabsTabLabel:
1705 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
1706 gtk_widget_path_append_type(path, G_TYPE_NONE);
1707 set_object_name(path, -1, "label");
1708 return makeContext(path, mpNotebookHeaderTabsTabStyle);
1710 case GtkControlPart::NotebookHeaderTabsTabActiveLabel:
1711 case GtkControlPart::NotebookHeaderTabsTabHoverLabel:
1712 return mpNotebookHeaderTabsTabLabelStyle;
1713 case GtkControlPart::FrameBorder:
1715 GtkWidgetPath *path = gtk_widget_path_new();
1716 gtk_widget_path_append_type(path, GTK_TYPE_FRAME);
1717 set_object_name(path, -1, "frame");
1718 gtk_widget_path_iter_add_class(path, -1, "frame");
1719 return makeContext(path, nullptr);
1721 case GtkControlPart::MenuBar:
1723 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
1724 gtk_widget_path_append_type(path, GTK_TYPE_MENU_BAR);
1725 set_object_name(path, -1, "menubar");
1726 return makeContext(path, mpWindowStyle);
1728 case GtkControlPart::MenuBarItem:
1730 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarStyle));
1731 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
1732 set_object_name(path, -1, "menuitem");
1733 return makeContext(path, mpMenuBarStyle);
1735 case GtkControlPart::MenuWindow:
1737 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarItemStyle));
1738 gtk_widget_path_append_type(path, G_TYPE_NONE);
1739 set_object_name(path, -1, "window");
1740 gtk_widget_path_iter_add_class(path, -1, "background");
1741 gtk_widget_path_iter_add_class(path, -1, "popup");
1742 return makeContext(path, mpMenuBarItemStyle);
1744 case GtkControlPart::Menu:
1746 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuWindowStyle));
1747 gtk_widget_path_append_type(path, GTK_TYPE_MENU);
1748 set_object_name(path, -1, "menu");
1749 return makeContext(path, mpMenuWindowStyle);
1751 case GtkControlPart::MenuItem:
1753 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1754 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
1755 set_object_name(path, -1, "menuitem");
1756 return makeContext(path, mpMenuStyle);
1758 case GtkControlPart::MenuItemLabel:
1760 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
1761 gtk_widget_path_append_type(path, G_TYPE_NONE);
1762 set_object_name(path, -1, "label");
1763 return makeContext(path, mpMenuItemStyle);
1765 case GtkControlPart::MenuItemArrow:
1767 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
1768 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
1769 set_object_name(path, -1, "arrow");
1770 return makeContext(path, mpMenuItemStyle);
1772 case GtkControlPart::CheckMenuItem:
1774 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1775 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
1776 set_object_name(path, -1, "menuitem");
1777 return makeContext(path, mpMenuStyle);
1779 case GtkControlPart::CheckMenuItemCheck:
1781 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckMenuItemStyle));
1782 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
1783 set_object_name(path, -1, "check");
1784 return makeContext(path, mpCheckMenuItemStyle);
1786 case GtkControlPart::RadioMenuItem:
1788 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1789 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
1790 set_object_name(path, -1, "menuitem");
1791 return makeContext(path, mpMenuStyle);
1793 case GtkControlPart::RadioMenuItemRadio:
1795 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioMenuItemStyle));
1796 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
1797 set_object_name(path, -1, "radio");
1798 return makeContext(path, mpRadioMenuItemStyle);
1800 case GtkControlPart::SeparatorMenuItem:
1802 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
1803 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
1804 set_object_name(path, -1, "menuitem");
1805 return makeContext(path, mpMenuStyle);
1807 case GtkControlPart::SeparatorMenuItemSeparator:
1809 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSeparatorMenuItemStyle));
1810 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
1811 set_object_name(path, -1, "separator");
1812 return makeContext(path, mpSeparatorMenuItemStyle);
1816 return nullptr;
1819 #ifndef GTK_STYLE_CLASS_POPUP
1820 #define GTK_STYLE_CLASS_POPUP "popup"
1821 #endif
1822 #ifndef GTK_STYLE_CLASS_LABEL
1823 #define GTK_STYLE_CLASS_LABEL "label"
1824 #endif
1826 GtkStyleContext* GtkSalGraphics::createOldContext(GtkControlPart ePart)
1828 switch (ePart)
1830 case GtkControlPart::ToplevelWindow:
1832 GtkWidgetPath *path = gtk_widget_path_new();
1833 gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
1834 gtk_widget_path_iter_add_class(path, -1, "background");
1835 return makeContext(path, nullptr);
1837 case GtkControlPart::Button:
1839 GtkWidgetPath *path = gtk_widget_path_new();
1840 gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
1841 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1842 gtk_widget_path_iter_add_class(path, -1, "button");
1843 gtk_widget_path_iter_add_class(path, -1, "text-button");
1844 return makeContext(path, nullptr);
1846 case GtkControlPart::LinkButton:
1848 GtkWidgetPath *path = gtk_widget_path_new();
1849 gtk_widget_path_append_type(path, GTK_TYPE_LINK_BUTTON);
1850 gtk_widget_path_iter_add_class(path, -1, "text-button");
1851 return makeContext(path, nullptr);
1853 case GtkControlPart::CheckButton:
1855 GtkWidgetPath *path = gtk_widget_path_new();
1856 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
1857 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
1858 gtk_widget_path_iter_add_class(path, -1, "text-button");
1859 return makeContext(path, nullptr);
1861 case GtkControlPart::CheckButtonCheck:
1862 return mpCheckButtonStyle;
1863 case GtkControlPart::RadioButton:
1865 GtkWidgetPath *path = gtk_widget_path_new();
1866 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
1867 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
1868 gtk_widget_path_iter_add_class(path, -1, "text-button");
1869 return makeContext(path, nullptr);
1871 case GtkControlPart::RadioButtonRadio:
1872 return mpRadioButtonStyle;
1873 case GtkControlPart::ComboboxBoxButtonBoxArrow:
1874 case GtkControlPart::ListboxBoxButtonBoxArrow:
1876 return (ePart == GtkControlPart::ComboboxBoxButtonBoxArrow)
1877 ? mpComboboxButtonStyle : mpListboxButtonStyle;
1879 case GtkControlPart::Entry:
1880 case GtkControlPart::ComboboxBoxEntry:
1881 case GtkControlPart::SpinButtonEntry:
1883 GtkWidgetPath *path = gtk_widget_path_new();
1884 gtk_widget_path_append_type(path, GTK_TYPE_ENTRY);
1885 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ENTRY);
1886 return makeContext(path, nullptr);
1888 case GtkControlPart::Combobox:
1890 GtkWidgetPath *path = gtk_widget_path_new();
1891 gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX_TEXT);
1892 return makeContext(path, nullptr);
1894 case GtkControlPart::Listbox:
1896 GtkWidgetPath *path = gtk_widget_path_new();
1897 gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX);
1898 return makeContext(path, nullptr);
1900 case GtkControlPart::ComboboxBoxButton:
1901 case GtkControlPart::ListboxBoxButton:
1903 GtkStyleContext *pParent =
1904 (ePart == GtkControlPart::ComboboxBoxButton ) ? mpComboboxStyle : mpListboxStyle;
1905 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1906 gtk_widget_path_append_type(path, GTK_TYPE_TOGGLE_BUTTON);
1907 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1908 gtk_widget_path_iter_add_class(path, -1, "the-button-in-the-combobox");
1909 return makeContext(path, pParent);
1911 case GtkControlPart::SpinButton:
1913 GtkWidgetPath *path = gtk_widget_path_new();
1914 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1915 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ENTRY);
1916 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1917 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
1918 return makeContext(path, nullptr);
1920 case GtkControlPart::SpinButtonUpButton:
1921 case GtkControlPart::SpinButtonDownButton:
1923 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
1924 gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
1925 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
1926 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1927 return makeContext(path, mpSpinStyle);
1929 case GtkControlPart::ScrollbarVertical:
1930 case GtkControlPart::ScrollbarHorizontal:
1932 GtkWidgetPath *path = gtk_widget_path_new();
1933 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1934 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1935 gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::ScrollbarVertical ? "vertical" : "horizontal");
1936 return makeContext(path, nullptr);
1938 case GtkControlPart::ScrollbarVerticalContents:
1939 case GtkControlPart::ScrollbarHorizontalContents:
1941 GtkStyleContext *pParent =
1942 (ePart == GtkControlPart::ScrollbarVerticalContents) ? mpVScrollbarStyle : mpHScrollbarStyle;
1943 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1944 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1945 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1946 gtk_widget_path_iter_add_class(path, -1, "contents");
1947 return makeContext(path, pParent);
1949 case GtkControlPart::ScrollbarHorizontalTrough:
1950 case GtkControlPart::ScrollbarVerticalTrough:
1952 GtkStyleContext *pParent =
1953 (ePart == GtkControlPart::ScrollbarVerticalTrough) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
1954 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1955 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1956 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1957 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_TROUGH);
1958 return makeContext(path, pParent);
1960 case GtkControlPart::ScrollbarHorizontalSlider:
1961 case GtkControlPart::ScrollbarVerticalSlider:
1963 GtkStyleContext *pParent =
1964 (ePart == GtkControlPart::ScrollbarVerticalSlider) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
1965 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1966 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1967 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1968 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SLIDER);
1969 return makeContext(path, pParent);
1971 case GtkControlPart::ScrollbarHorizontalButton:
1972 case GtkControlPart::ScrollbarVerticalButton:
1974 GtkStyleContext *pParent =
1975 (ePart == GtkControlPart::ScrollbarVerticalButton) ? mpVScrollbarStyle : mpHScrollbarStyle;
1976 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
1977 gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
1978 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
1979 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
1980 return makeContext(path, pParent);
1982 case GtkControlPart::ProgressBar:
1984 GtkWidgetPath *path = gtk_widget_path_new();
1985 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1986 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
1987 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
1988 return makeContext(path, nullptr);
1990 case GtkControlPart::ProgressBarTrough:
1992 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle));
1993 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
1994 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_TROUGH);
1995 return makeContext(path, mpProgressBarStyle);
1997 case GtkControlPart::ProgressBarProgress:
1999 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarTroughStyle));
2000 gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
2001 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
2002 return makeContext(path, mpProgressBarTroughStyle);
2004 case GtkControlPart::Notebook:
2006 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
2007 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
2008 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_NOTEBOOK);
2009 gtk_widget_path_iter_add_class(path, -1, "frame");
2010 return makeContext(path, mpWindowStyle);
2012 case GtkControlPart::NotebookStack:
2013 return mpNotebookStyle;
2014 case GtkControlPart::NotebookHeader:
2016 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
2017 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
2018 gtk_widget_path_iter_add_class(path, -1, "top");
2019 return makeContext(path, gtk_style_context_get_parent(mpNotebookStyle));
2021 case GtkControlPart::NotebookHeaderTabs:
2022 return mpNotebookHeaderStyle;
2023 case GtkControlPart::NotebookHeaderTabsTab:
2025 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsStyle));
2026 gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
2027 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
2028 gtk_widget_path_iter_add_class(path, -1, "top");
2029 gtk_widget_path_iter_add_region(path, -1, GTK_STYLE_REGION_TAB, static_cast<GtkRegionFlags>(GTK_REGION_EVEN | GTK_REGION_FIRST));
2030 return makeContext(path, mpNotebookHeaderTabsStyle);
2032 case GtkControlPart::NotebookHeaderTabsTabLabel:
2034 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
2035 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
2036 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
2037 return makeContext(path, mpNotebookHeaderTabsTabStyle);
2039 case GtkControlPart::NotebookHeaderTabsTabActiveLabel:
2041 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
2042 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
2043 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
2044 gtk_widget_path_iter_add_class(path, -1, "active-page");
2045 return makeContext(path, mpNotebookHeaderTabsTabStyle);
2047 case GtkControlPart::NotebookHeaderTabsTabHoverLabel:
2049 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
2050 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
2051 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
2052 gtk_widget_path_iter_add_class(path, -1, "prelight-page");
2053 return makeContext(path, mpNotebookHeaderTabsTabStyle);
2055 case GtkControlPart::FrameBorder:
2057 GtkWidgetPath *path = gtk_widget_path_new();
2058 gtk_widget_path_append_type(path, GTK_TYPE_FRAME);
2059 gtk_widget_path_iter_add_class(path, -1, "frame");
2060 return makeContext(path, nullptr);
2062 case GtkControlPart::MenuBar:
2064 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
2065 gtk_widget_path_append_type(path, GTK_TYPE_MENU_BAR);
2066 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUBAR);
2067 return makeContext(path, mpWindowStyle);
2069 case GtkControlPart::MenuBarItem:
2071 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarStyle));
2072 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
2073 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2074 return makeContext(path, mpMenuBarStyle);
2076 case GtkControlPart::MenuWindow:
2078 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarItemStyle));
2079 gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
2080 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_POPUP);
2081 gtk_widget_path_iter_add_class(path, -1, "background");
2082 return makeContext(path, mpMenuBarItemStyle);
2084 case GtkControlPart::Menu:
2086 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuWindowStyle));
2087 gtk_widget_path_append_type(path, GTK_TYPE_MENU);
2088 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENU);
2089 return makeContext(path, mpMenuWindowStyle);
2091 case GtkControlPart::MenuItem:
2093 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2094 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
2095 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2096 return makeContext(path, mpMenuStyle);
2098 case GtkControlPart::MenuItemLabel:
2100 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
2101 gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
2102 return makeContext(path, mpMenuItemStyle);
2104 case GtkControlPart::MenuItemArrow:
2106 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
2107 gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
2108 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ARROW);
2109 return makeContext(path, mpMenuItemStyle);
2111 case GtkControlPart::CheckMenuItem:
2113 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2114 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
2115 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
2116 return makeContext(path, mpMenuStyle);
2118 case GtkControlPart::CheckMenuItemCheck:
2120 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckMenuItemStyle));
2121 gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
2122 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
2123 return makeContext(path, mpCheckMenuItemStyle);
2125 case GtkControlPart::RadioMenuItem:
2127 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2128 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
2129 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2130 return makeContext(path, mpMenuStyle);
2132 case GtkControlPart::RadioMenuItemRadio:
2134 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioMenuItemStyle));
2135 gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
2136 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
2137 return makeContext(path, mpRadioMenuItemStyle);
2139 case GtkControlPart::SeparatorMenuItem:
2141 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
2142 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
2143 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
2144 return makeContext(path, mpMenuStyle);
2146 case GtkControlPart::SeparatorMenuItemSeparator:
2148 GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSeparatorMenuItemStyle));
2149 gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
2150 gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SEPARATOR);
2151 return makeContext(path, mpSeparatorMenuItemStyle);
2153 case GtkControlPart::ComboboxBox:
2154 case GtkControlPart::ListboxBox:
2155 case GtkControlPart::ComboboxBoxButtonBox:
2156 case GtkControlPart::ListboxBoxButtonBox:
2157 return nullptr;
2158 default:
2159 break;
2162 return mpButtonStyle;
2165 GtkStyleContext* GtkSalGraphics::createStyleContext(gtk_widget_path_iter_set_object_nameFunc set_object_name,
2166 GtkControlPart ePart)
2168 if (set_object_name)
2169 return createNewContext(ePart, set_object_name);
2170 return createOldContext(ePart);
2173 namespace
2175 GtkStateFlags ACTIVE_TAB()
2177 #if GTK_CHECK_VERSION(3,20,0)
2178 if (gtk_check_version(3, 20, 0) == nullptr)
2179 return GTK_STATE_FLAG_CHECKED;
2180 #endif
2181 return GTK_STATE_FLAG_ACTIVE;
2185 void GtkSalGraphics::PaintCheckOrRadio(cairo_t *cr, GtkStyleContext *context,
2186 const tools::Rectangle& rControlRectangle, bool bIsCheck, bool bInMenu)
2188 gint indicator_size;
2189 gtk_style_context_get_style(context, "indicator-size", &indicator_size, nullptr);
2191 gint x = (rControlRectangle.GetWidth() - indicator_size) / 2;
2192 gint y = (rControlRectangle.GetHeight() - indicator_size) / 2;
2194 if (!bInMenu)
2195 gtk_render_background(context, cr, x, y, indicator_size, indicator_size);
2197 if (bIsCheck)
2198 gtk_render_check(context, cr, x, y, indicator_size, indicator_size);
2199 else
2200 gtk_render_option(context, cr, x, y, indicator_size, indicator_size);
2202 gtk_render_frame(context, cr, x, y, indicator_size, indicator_size);
2205 void GtkSalGraphics::PaintCheck(cairo_t *cr, GtkStyleContext *context,
2206 const tools::Rectangle& rControlRectangle, bool bInMenu)
2208 PaintCheckOrRadio(cr, context, rControlRectangle, true, bInMenu);
2211 void GtkSalGraphics::PaintRadio(cairo_t *cr, GtkStyleContext *context,
2212 const tools::Rectangle& rControlRectangle, bool bInMenu)
2214 PaintCheckOrRadio(cr, context, rControlRectangle, false, bInMenu);
2217 static gfloat getArrowSize(GtkStyleContext* context)
2219 if (gtk_check_version(3, 20, 0) == nullptr)
2221 gint min_width, min_weight;
2222 gtk_style_context_get_style(context, "min-width", &min_width, nullptr);
2223 gtk_style_context_get_style(context, "min-height", &min_weight, nullptr);
2224 gfloat arrow_size = 11 * MAX (min_width, min_weight);
2225 return arrow_size;
2227 else
2229 gfloat arrow_scaling = 1.0;
2230 gtk_style_context_get_style(context, "arrow-scaling", &arrow_scaling, nullptr);
2231 gfloat arrow_size = 11 * arrow_scaling;
2232 return arrow_size;
2236 namespace
2238 void draw_vertical_separator(GtkStyleContext *context, cairo_t *cr, const tools::Rectangle& rControlRegion)
2240 long nX = 0;
2241 long nY = 0;
2243 const bool bNewStyle = gtk_check_version(3, 20, 0) == nullptr;
2245 gint nSeparatorWidth = 1;
2247 if (bNewStyle)
2249 gtk_style_context_get(context,
2250 gtk_style_context_get_state(context),
2251 "min-width", &nSeparatorWidth, nullptr);
2254 gint nHalfSeparatorWidth = nSeparatorWidth / 2;
2255 gint nHalfRegionWidth = rControlRegion.GetWidth() / 2;
2257 nX = nX + nHalfRegionWidth - nHalfSeparatorWidth;
2258 nY = rControlRegion.GetHeight() > 5 ? 1 : 0;
2259 int nHeight = rControlRegion.GetHeight() - (2 * nY);
2261 if (bNewStyle)
2263 gtk_render_background(context, cr, nX, nY, nSeparatorWidth, nHeight);
2264 gtk_render_frame(context, cr, nX, nY, nSeparatorWidth, nHeight);
2266 else
2268 gtk_render_line(context, cr, nX, nY, nX, nY + nHeight);
2272 void draw_horizontal_separator(GtkStyleContext *context, cairo_t *cr, const tools::Rectangle& rControlRegion)
2274 long nX = 0;
2275 long nY = 0;
2277 const bool bNewStyle = gtk_check_version(3, 20, 0) == nullptr;
2279 gint nSeparatorHeight = 1;
2281 if (bNewStyle)
2283 gtk_style_context_get(context,
2284 gtk_style_context_get_state(context),
2285 "min-height", &nSeparatorHeight, nullptr);
2288 gint nHalfSeparatorHeight = nSeparatorHeight / 2;
2289 gint nHalfRegionHeight = rControlRegion.GetHeight() / 2;
2291 nY = nY + nHalfRegionHeight - nHalfSeparatorHeight;
2292 nX = rControlRegion.GetWidth() > 5 ? 1 : 0;
2293 int nWidth = rControlRegion.GetWidth() - (2 * nX);
2295 if (bNewStyle)
2297 gtk_render_background(context, cr, nX, nY, nWidth, nSeparatorHeight);
2298 gtk_render_frame(context, cr, nX, nY, nWidth, nSeparatorHeight);
2300 else
2302 gtk_render_line(context, cr, nX, nY, nX + nWidth, nY);
2307 void GtkSalGraphics::handleDamage(const tools::Rectangle& rDamagedRegion)
2309 assert(m_pWidgetDraw);
2310 assert(!rDamagedRegion.IsEmpty());
2311 mpFrame->damaged(rDamagedRegion.Left(), rDamagedRegion.Top(), rDamagedRegion.GetWidth(), rDamagedRegion.GetHeight());
2314 bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
2315 ControlState nState, const ImplControlValue& rValue,
2316 const OUString&)
2318 RenderType renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::BackgroundAndFrame;
2319 GtkStyleContext *context = nullptr;
2320 const gchar *styleClass = nullptr;
2321 GdkPixbuf *pixbuf = nullptr;
2322 bool bInMenu = false;
2324 GtkStateFlags flags = NWConvertVCLStateToGTKState(nState);
2326 switch(nType)
2328 case ControlType::Spinbox:
2329 case ControlType::SpinButtons:
2330 context = mpSpinStyle;
2331 renderType = RenderType::Spinbutton;
2332 break;
2333 case ControlType::Editbox:
2334 context = mpEntryStyle;
2335 break;
2336 case ControlType::MultilineEditbox:
2337 context = mpTextViewStyle;
2338 break;
2339 case ControlType::Combobox:
2340 context = mpComboboxStyle;
2341 renderType = RenderType::Combobox;
2342 break;
2343 case ControlType::Listbox:
2344 if (nPart == ControlPart::Focus)
2346 renderType = RenderType::Focus;
2347 context = mpListboxButtonStyle;
2349 else
2351 renderType = RenderType::Combobox;
2352 context = mpListboxStyle;
2354 break;
2355 case ControlType::MenuPopup:
2356 bInMenu = true;
2358 // map selected menu entries in vcl parlance to gtk prelight
2359 if (nPart >= ControlPart::MenuItem && nPart <= ControlPart::SubmenuArrow && (nState & ControlState::SELECTED))
2360 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_PRELIGHT);
2361 flags = static_cast<GtkStateFlags>(flags & ~GTK_STATE_FLAG_ACTIVE);
2362 switch(nPart)
2364 case ControlPart::MenuItem:
2365 context = mpMenuItemStyle;
2366 renderType = RenderType::BackgroundAndFrame;
2367 break;
2368 case ControlPart::MenuItemCheckMark:
2369 if (gtk_check_version(3, 20, 0) == nullptr)
2370 context = mpCheckMenuItemCheckStyle;
2371 else
2373 context = gtk_widget_get_style_context(gCheckMenuItemWidget);
2374 styleClass = GTK_STYLE_CLASS_CHECK;
2376 renderType = RenderType::Check;
2377 nType = ControlType::Checkbox;
2378 if (nState & ControlState::PRESSED)
2380 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_CHECKED);
2382 break;
2383 case ControlPart::MenuItemRadioMark:
2384 if (gtk_check_version(3, 20, 0) == nullptr)
2385 context = mpRadioMenuItemRadioStyle;
2386 else
2388 context = gtk_widget_get_style_context(gCheckMenuItemWidget);
2389 styleClass = GTK_STYLE_CLASS_RADIO;
2391 renderType = RenderType::Radio;
2392 nType = ControlType::Radiobutton;
2393 if (nState & ControlState::PRESSED)
2395 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_CHECKED);
2397 break;
2398 case ControlPart::Separator:
2399 context = mpSeparatorMenuItemSeparatorStyle;
2400 flags = GtkStateFlags(GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_INSENSITIVE); //GTK_STATE_FLAG_BACKDROP hack ?
2401 renderType = RenderType::MenuSeparator;
2402 break;
2403 case ControlPart::SubmenuArrow:
2404 if (gtk_check_version(3, 20, 0) == nullptr)
2405 context = mpMenuItemArrowStyle;
2406 else
2408 context = gtk_widget_get_style_context(gCheckMenuItemWidget);
2409 styleClass = GTK_STYLE_CLASS_ARROW;
2411 renderType = RenderType::Arrow;
2412 break;
2413 case ControlPart::Entire:
2414 context = mpMenuStyle;
2415 renderType = RenderType::Background;
2416 break;
2417 default: break;
2419 break;
2420 case ControlType::Toolbar:
2421 switch(nPart)
2423 case ControlPart::DrawBackgroundHorz:
2424 case ControlPart::DrawBackgroundVert:
2425 context = mpToolbarStyle;
2426 break;
2427 case ControlPart::Button:
2428 /* For all checkbuttons in the toolbars */
2429 flags = static_cast<GtkStateFlags>(flags |
2430 ( (rValue.getTristateVal() == ButtonValue::On) ? GTK_STATE_FLAG_CHECKED : GTK_STATE_FLAG_NORMAL));
2431 context = mpToolButtonStyle;
2432 break;
2433 case ControlPart::SeparatorVert:
2434 context = mpToolbarSeperatorStyle;
2435 renderType = RenderType::ToolbarSeparator;
2436 break;
2437 default:
2438 return false;
2440 break;
2441 case ControlType::Radiobutton:
2442 flags = static_cast<GtkStateFlags>(flags |
2443 ( (rValue.getTristateVal() == ButtonValue::On) ? GTK_STATE_FLAG_CHECKED : GTK_STATE_FLAG_NORMAL));
2444 context = mpRadioButtonRadioStyle;
2445 renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::Radio;
2446 break;
2447 case ControlType::Checkbox:
2448 flags = static_cast<GtkStateFlags>(flags |
2449 ( (rValue.getTristateVal() == ButtonValue::On) ? GTK_STATE_FLAG_CHECKED :
2450 (rValue.getTristateVal() == ButtonValue::Mixed) ? GTK_STATE_FLAG_INCONSISTENT :
2451 GTK_STATE_FLAG_NORMAL));
2452 context = mpCheckButtonCheckStyle;
2453 renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::Check;
2454 break;
2455 case ControlType::Pushbutton:
2456 context = mpButtonStyle;
2457 break;
2458 case ControlType::Scrollbar:
2459 switch(nPart)
2461 case ControlPart::DrawBackgroundVert:
2462 case ControlPart::DrawBackgroundHorz:
2463 context = (nPart == ControlPart::DrawBackgroundVert)
2464 ? mpVScrollbarStyle : mpHScrollbarStyle;
2465 renderType = RenderType::Scrollbar;
2466 break;
2467 default: break;
2469 break;
2470 case ControlType::ListNet:
2471 return true;
2472 break;
2473 case ControlType::TabPane:
2474 context = mpNotebookStyle;
2475 break;
2476 case ControlType::TabBody:
2477 context = mpNotebookStackStyle;
2478 break;
2479 case ControlType::TabHeader:
2480 context = mpNotebookHeaderStyle;
2481 break;
2482 case ControlType::TabItem:
2483 context = mpNotebookHeaderTabsTabStyle;
2484 if (nState & ControlState::SELECTED)
2485 flags = static_cast<GtkStateFlags>(flags | ACTIVE_TAB());
2486 renderType = RenderType::TabItem;
2487 break;
2488 case ControlType::WindowBackground:
2489 context = gtk_widget_get_style_context(gtk_widget_get_toplevel(mpWindow));
2490 break;
2491 case ControlType::Frame:
2493 DrawFrameStyle nStyle = static_cast<DrawFrameStyle>(rValue.getNumericVal() & 0x0f);
2494 if (nStyle == DrawFrameStyle::In)
2495 context = mpFrameOutStyle;
2496 else
2497 context = mpFrameInStyle;
2498 break;
2500 case ControlType::Menubar:
2501 if (nPart == ControlPart::MenuItem)
2503 context = mpMenuBarItemStyle;
2505 flags = (!(nState & ControlState::ENABLED)) ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
2506 if (nState & ControlState::SELECTED)
2507 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_PRELIGHT);
2509 else
2511 context = mpMenuBarStyle;
2513 break;
2514 case ControlType::Fixedline:
2515 context = nPart == ControlPart::SeparatorHorz ? mpFixedHoriLineStyle : mpFixedVertLineStyle;
2516 renderType = RenderType::Separator;
2517 break;
2518 case ControlType::ListNode:
2520 context = mpTreeHeaderButtonStyle;
2521 ButtonValue aButtonValue = rValue.getTristateVal();
2522 if (aButtonValue == ButtonValue::On)
2523 flags = static_cast<GtkStateFlags>(flags | GTK_STATE_FLAG_CHECKED);
2524 renderType = RenderType::Expander;
2525 break;
2527 case ControlType::ListHeader:
2528 context = mpTreeHeaderButtonStyle;
2529 if (nPart == ControlPart::Arrow)
2531 const char* icon = (rValue.getNumericVal() & 1) ? "pan-down-symbolic" : "pan-up-symbolic";
2532 GtkIconTheme *pIconTheme = gtk_icon_theme_get_for_screen(gtk_widget_get_screen(mpWindow));
2533 pixbuf = gtk_icon_theme_load_icon_for_scale(pIconTheme, icon,
2534 std::max(rControlRegion.GetWidth(), rControlRegion.GetHeight()),
2535 gtk_style_context_get_scale (context),
2536 static_cast<GtkIconLookupFlags>(0), nullptr);
2537 flags = GTK_STATE_FLAG_SELECTED;
2538 renderType = RenderType::Icon;
2540 break;
2541 case ControlType::Progress:
2542 context = mpProgressBarProgressStyle;
2543 renderType = RenderType::Progress;
2544 break;
2545 default:
2546 return false;
2549 cairo_t *cr = getCairoContext(false);
2550 clipRegion(cr);
2551 cairo_translate(cr, rControlRegion.Left(), rControlRegion.Top());
2553 long nX = 0;
2554 long nY = 0;
2555 long nWidth = rControlRegion.GetWidth();
2556 long nHeight = rControlRegion.GetHeight();
2558 StyleContextSave aContextState;
2559 aContextState.save(context);
2560 style_context_set_state(context, flags);
2562 if (styleClass)
2564 gtk_style_context_add_class(context, styleClass);
2567 switch(renderType)
2569 case RenderType::Background:
2570 case RenderType::BackgroundAndFrame:
2571 gtk_render_background(context, cr, nX, nY, nWidth, nHeight);
2572 if (renderType == RenderType::BackgroundAndFrame)
2574 gtk_render_frame(context, cr, nX, nY, nWidth, nHeight);
2576 break;
2577 case RenderType::Check:
2579 PaintCheck(cr, context, rControlRegion, bInMenu);
2580 break;
2582 case RenderType::Radio:
2584 PaintRadio(cr, context, rControlRegion, bInMenu);
2585 break;
2587 case RenderType::MenuSeparator:
2588 gtk_render_line(context, cr,
2589 0, rControlRegion.GetHeight() / 2,
2590 rControlRegion.GetWidth() - 1, rControlRegion.GetHeight() / 2);
2591 break;
2592 case RenderType::ToolbarSeparator:
2594 draw_vertical_separator(context, cr, rControlRegion);
2595 break;
2597 case RenderType::Separator:
2598 if (nPart == ControlPart::SeparatorHorz)
2599 draw_horizontal_separator(context, cr, rControlRegion);
2600 else
2601 draw_vertical_separator(context, cr, rControlRegion);
2602 break;
2603 case RenderType::Arrow:
2604 gtk_render_arrow(context, cr,
2605 G_PI / 2, 0, 0,
2606 MIN(rControlRegion.GetWidth(), 1 + rControlRegion.GetHeight()));
2607 break;
2608 case RenderType::Expander:
2609 gtk_render_expander(context, cr, -2, -2, nWidth+4, nHeight+4);
2610 break;
2611 case RenderType::Scrollbar:
2612 PaintScrollbar(context, cr, rControlRegion, nPart, rValue);
2613 break;
2614 case RenderType::Spinbutton:
2615 PaintSpinButton(flags, cr, rControlRegion, nPart, rValue);
2616 break;
2617 case RenderType::Combobox:
2618 PaintCombobox(flags, cr, rControlRegion, nType, nPart);
2619 break;
2620 case RenderType::Icon:
2621 gtk_style_context_save (context);
2622 gtk_style_context_set_scale (context, 1);
2623 gtk_render_icon(context, cr, pixbuf, nX, nY);
2624 gtk_style_context_restore (context);
2625 g_object_unref(pixbuf);
2626 break;
2627 case RenderType::Focus:
2629 if (nType == ControlType::Checkbox ||
2630 nType == ControlType::Radiobutton)
2632 nX -= 2; nY -=2;
2633 nHeight += 4; nWidth += 4;
2635 else
2637 GtkBorder border;
2639 gtk_style_context_get_border(context, flags, &border);
2641 nX += border.left;
2642 nY += border.top;
2643 nWidth -= border.left + border.right;
2644 nHeight -= border.top + border.bottom;
2647 gtk_render_focus(context, cr, nX, nY, nWidth, nHeight);
2649 break;
2651 case RenderType::Progress:
2653 gtk_render_background(mpProgressBarTroughStyle, cr, nX, nY, nWidth, nHeight);
2655 long nProgressWidth = rValue.getNumericVal();
2656 if (nProgressWidth)
2658 GtkBorder padding;
2659 gtk_style_context_get_padding(context, gtk_style_context_get_state(context), &padding);
2661 nX += padding.left;
2662 nY += padding.top;
2663 nHeight -= (padding.top + padding.bottom);
2664 nProgressWidth -= (padding.left + padding.right);
2665 gtk_render_background(context, cr, nX, nY, nProgressWidth, nHeight);
2666 gtk_render_frame(context, cr, nX, nY, nProgressWidth, nHeight);
2669 gtk_render_frame(mpProgressBarTroughStyle, cr, nX, nY, nWidth, nHeight);
2671 break;
2673 case RenderType::TabItem:
2675 if (gtk_check_version(3, 20, 0) != nullptr)
2677 gint initial_gap(0);
2678 gtk_style_context_get_style(mpNotebookStyle,
2679 "initial-gap", &initial_gap,
2680 nullptr);
2682 nX += initial_gap/2;
2683 nWidth -= initial_gap;
2685 tools::Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
2686 render_common(mpNotebookHeaderTabsTabStyle, cr, aRect, flags);
2687 break;
2689 default:
2690 break;
2693 if (styleClass)
2695 gtk_style_context_remove_class(context, styleClass);
2697 aContextState.restore();
2699 cairo_destroy(cr); // unref
2701 if (!rControlRegion.IsEmpty())
2702 mpFrame->damaged(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.GetWidth(), rControlRegion.GetHeight());
2704 return true;
2707 static tools::Rectangle GetWidgetSize(const tools::Rectangle& rControlRegion, GtkWidget* widget)
2709 GtkRequisition aReq;
2710 gtk_widget_get_preferred_size(widget, nullptr, &aReq);
2711 long nHeight = std::max<long>(rControlRegion.GetHeight(), aReq.height);
2712 return tools::Rectangle(rControlRegion.TopLeft(), Size(rControlRegion.GetWidth(), nHeight));
2715 static tools::Rectangle AdjustRectForTextBordersPadding(GtkStyleContext* pStyle, long nContentWidth, long nContentHeight, const tools::Rectangle& rControlRegion)
2717 GtkBorder border;
2718 gtk_style_context_get_border(pStyle, gtk_style_context_get_state(pStyle), &border);
2720 GtkBorder padding;
2721 gtk_style_context_get_padding(pStyle, gtk_style_context_get_state(pStyle), &padding);
2723 gint nWidgetHeight = nContentHeight + padding.top + padding.bottom + border.top + border.bottom;
2724 nWidgetHeight = std::max(std::max<gint>(nWidgetHeight, rControlRegion.GetHeight()), 34);
2726 gint nWidgetWidth = nContentWidth + padding.left + padding.right + border.left + border.right;
2727 nWidgetWidth = std::max<gint>(nWidgetWidth, rControlRegion.GetWidth());
2729 tools::Rectangle aEditRect(rControlRegion.TopLeft(), Size(nWidgetWidth, nWidgetHeight));
2731 return aEditRect;
2734 bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion, ControlState,
2735 const ImplControlValue& rValue, const OUString&,
2736 tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion )
2738 /* TODO: all this functions needs improvements */
2739 tools::Rectangle aEditRect = rControlRegion;
2740 gint indicator_size, indicator_spacing, point;
2742 if(((nType == ControlType::Checkbox) || (nType == ControlType::Radiobutton)) &&
2743 nPart == ControlPart::Entire)
2745 rNativeBoundingRegion = rControlRegion;
2747 GtkStyleContext *pButtonStyle = (nType == ControlType::Checkbox) ? mpCheckButtonCheckStyle : mpRadioButtonRadioStyle;
2750 gtk_style_context_get_style( pButtonStyle,
2751 "indicator-size", &indicator_size,
2752 "indicator-spacing", &indicator_spacing,
2753 nullptr );
2755 GtkBorder border;
2756 gtk_style_context_get_border(pButtonStyle, gtk_style_context_get_state(pButtonStyle), &border);
2758 GtkBorder padding;
2759 gtk_style_context_get_padding(pButtonStyle, gtk_style_context_get_state(pButtonStyle), &padding);
2762 indicator_size += 2*indicator_spacing + border.left + padding.left + border.right + padding.right;
2763 tools::Rectangle aIndicatorRect( Point( 0,
2764 (rControlRegion.GetHeight()-indicator_size)/2),
2765 Size( indicator_size, indicator_size ) );
2766 rNativeContentRegion = aIndicatorRect;
2768 return true;
2770 else if( nType == ControlType::MenuPopup)
2772 if ((nPart == ControlPart::MenuItemCheckMark) ||
2773 (nPart == ControlPart::MenuItemRadioMark) )
2775 indicator_size = 0;
2777 GtkStyleContext *pMenuItemStyle = (nPart == ControlPart::MenuItemCheckMark ) ? mpCheckMenuItemCheckStyle
2778 : mpRadioMenuItemRadioStyle;
2780 gtk_style_context_get_style( pMenuItemStyle,
2781 "indicator-size", &indicator_size,
2782 nullptr );
2784 point = MAX(0, rControlRegion.GetHeight() - indicator_size);
2785 aEditRect = tools::Rectangle( Point( 0, point / 2),
2786 Size( indicator_size, indicator_size ) );
2788 else if (nPart == ControlPart::Separator)
2790 gint separator_height, separator_width, wide_separators;
2792 gtk_style_context_get_style (mpSeparatorMenuItemSeparatorStyle,
2793 "wide-separators", &wide_separators,
2794 "separator-width", &separator_width,
2795 "separator-height", &separator_height,
2796 nullptr);
2798 aEditRect = tools::Rectangle( aEditRect.TopLeft(),
2799 Size( aEditRect.GetWidth(), wide_separators ? separator_height : 1 ) );
2801 else if (nPart == ControlPart::SubmenuArrow)
2803 gfloat arrow_size = getArrowSize(mpMenuItemArrowStyle);
2804 aEditRect = tools::Rectangle( aEditRect.TopLeft(),
2805 Size( arrow_size, arrow_size ) );
2808 else if ( (nType==ControlType::Scrollbar) &&
2809 ((nPart==ControlPart::ButtonLeft) || (nPart==ControlPart::ButtonRight) ||
2810 (nPart==ControlPart::ButtonUp) || (nPart==ControlPart::ButtonDown) ) )
2812 rNativeBoundingRegion = NWGetScrollButtonRect( nPart, rControlRegion );
2813 rNativeContentRegion = rNativeBoundingRegion;
2815 if (!rNativeContentRegion.GetWidth())
2816 rNativeContentRegion.SetRight( rNativeContentRegion.Left() + 1 );
2817 if (!rNativeContentRegion.GetHeight())
2818 rNativeContentRegion.SetBottom( rNativeContentRegion.Top() + 1 );
2820 return true;
2822 else if ( (nType==ControlType::Spinbox) &&
2823 ((nPart==ControlPart::ButtonUp) || (nPart==ControlPart::ButtonDown) ||
2824 (nPart==ControlPart::SubEdit)) )
2826 tools::Rectangle aControlRegion(GetWidgetSize(rControlRegion, gSpinBox));
2827 aEditRect = NWGetSpinButtonRect(nPart, aControlRegion);
2829 else if ( (nType==ControlType::Combobox) &&
2830 ((nPart==ControlPart::ButtonDown) || (nPart==ControlPart::SubEdit)) )
2832 aEditRect = NWGetComboBoxButtonRect(nType, nPart, rControlRegion);
2834 else if ( (nType==ControlType::Listbox) &&
2835 ((nPart==ControlPart::ButtonDown) || (nPart==ControlPart::SubEdit)) )
2837 aEditRect = NWGetComboBoxButtonRect(nType, nPart, rControlRegion);
2839 else if (nType == ControlType::Editbox && nPart == ControlPart::Entire)
2841 aEditRect = GetWidgetSize(rControlRegion, gEntryBox);
2843 else if (nType == ControlType::Listbox && nPart == ControlPart::Entire)
2845 aEditRect = GetWidgetSize(rControlRegion, gListBox);
2847 else if (nType == ControlType::Combobox && nPart == ControlPart::Entire)
2849 aEditRect = GetWidgetSize(rControlRegion, gComboBox);
2851 else if (nType == ControlType::Spinbox && nPart == ControlPart::Entire)
2853 aEditRect = GetWidgetSize(rControlRegion, gSpinBox);
2855 else if (nType == ControlType::TabItem && nPart == ControlPart::Entire)
2857 const TabitemValue& rTabitemValue = static_cast<const TabitemValue&>(rValue);
2858 const tools::Rectangle& rTabitemRect = rTabitemValue.getContentRect();
2860 aEditRect = AdjustRectForTextBordersPadding(mpNotebookHeaderTabsTabStyle, rTabitemRect.GetWidth(),
2861 rTabitemRect.GetHeight(), rControlRegion);
2863 else if (nType == ControlType::Frame && nPart == ControlPart::Border)
2865 aEditRect = rControlRegion;
2866 DrawFrameFlags nStyle = static_cast<DrawFrameFlags>(rValue.getNumericVal() & 0xfff0);
2867 if (nStyle & DrawFrameFlags::NoDraw)
2869 GtkBorder padding;
2870 gtk_style_context_get_padding(mpFrameInStyle, gtk_style_context_get_state(mpFrameInStyle), &padding);
2872 GtkBorder border;
2873 gtk_style_context_get_border(mpFrameInStyle, gtk_style_context_get_state(mpFrameInStyle), &border);
2875 int x1 = aEditRect.Left();
2876 int y1 = aEditRect.Top();
2877 int x2 = aEditRect.Right();
2878 int y2 = aEditRect.Bottom();
2880 rNativeBoundingRegion = aEditRect;
2881 rNativeContentRegion = tools::Rectangle(x1 + (padding.left + border.left),
2882 y1 + (padding.top + border.top),
2883 x2 - (padding.right + border.right),
2884 y2 - (padding.bottom + border.bottom));
2886 return true;
2888 else
2889 rNativeContentRegion = rControlRegion;
2891 else
2893 return false;
2896 rNativeBoundingRegion = aEditRect;
2897 rNativeContentRegion = rNativeBoundingRegion;
2899 return true;
2901 /************************************************************************
2902 * helper for GtkSalFrame
2903 ************************************************************************/
2904 static ::Color getColor( const GdkRGBA& rCol )
2906 return ::Color( static_cast<int>(rCol.red * 0xFFFF) >> 8, static_cast<int>(rCol.green * 0xFFFF) >> 8, static_cast<int>(rCol.blue * 0xFFFF) >> 8 );
2909 static vcl::Font getFont(GtkStyleContext* pStyle, const css::lang::Locale& rLocale)
2911 const PangoFontDescription* font = gtk_style_context_get_font(pStyle, gtk_style_context_get_state(pStyle));
2912 return pango_to_vcl(font, rLocale);
2915 vcl::Font pango_to_vcl(const PangoFontDescription* font, const css::lang::Locale& rLocale)
2917 OString aFamily = pango_font_description_get_family( font );
2918 int nPangoHeight = pango_font_description_get_size( font );
2919 PangoStyle eStyle = pango_font_description_get_style( font );
2920 PangoWeight eWeight = pango_font_description_get_weight( font );
2921 PangoStretch eStretch = pango_font_description_get_stretch( font );
2923 psp::FastPrintFontInfo aInfo;
2924 // set family name
2925 aInfo.m_aFamilyName = OStringToOUString( aFamily, RTL_TEXTENCODING_UTF8 );
2926 // set italic
2927 switch( eStyle )
2929 case PANGO_STYLE_NORMAL: aInfo.m_eItalic = ITALIC_NONE;break;
2930 case PANGO_STYLE_ITALIC: aInfo.m_eItalic = ITALIC_NORMAL;break;
2931 case PANGO_STYLE_OBLIQUE: aInfo.m_eItalic = ITALIC_OBLIQUE;break;
2933 // set weight
2934 if( eWeight <= PANGO_WEIGHT_ULTRALIGHT )
2935 aInfo.m_eWeight = WEIGHT_ULTRALIGHT;
2936 else if( eWeight <= PANGO_WEIGHT_LIGHT )
2937 aInfo.m_eWeight = WEIGHT_LIGHT;
2938 else if( eWeight <= PANGO_WEIGHT_NORMAL )
2939 aInfo.m_eWeight = WEIGHT_NORMAL;
2940 else if( eWeight <= PANGO_WEIGHT_BOLD )
2941 aInfo.m_eWeight = WEIGHT_BOLD;
2942 else
2943 aInfo.m_eWeight = WEIGHT_ULTRABOLD;
2944 // set width
2945 switch( eStretch )
2947 case PANGO_STRETCH_ULTRA_CONDENSED: aInfo.m_eWidth = WIDTH_ULTRA_CONDENSED;break;
2948 case PANGO_STRETCH_EXTRA_CONDENSED: aInfo.m_eWidth = WIDTH_EXTRA_CONDENSED;break;
2949 case PANGO_STRETCH_CONDENSED: aInfo.m_eWidth = WIDTH_CONDENSED;break;
2950 case PANGO_STRETCH_SEMI_CONDENSED: aInfo.m_eWidth = WIDTH_SEMI_CONDENSED;break;
2951 case PANGO_STRETCH_NORMAL: aInfo.m_eWidth = WIDTH_NORMAL;break;
2952 case PANGO_STRETCH_SEMI_EXPANDED: aInfo.m_eWidth = WIDTH_SEMI_EXPANDED;break;
2953 case PANGO_STRETCH_EXPANDED: aInfo.m_eWidth = WIDTH_EXPANDED;break;
2954 case PANGO_STRETCH_EXTRA_EXPANDED: aInfo.m_eWidth = WIDTH_EXTRA_EXPANDED;break;
2955 case PANGO_STRETCH_ULTRA_EXPANDED: aInfo.m_eWidth = WIDTH_ULTRA_EXPANDED;break;
2958 #if OSL_DEBUG_LEVEL > 1
2959 fprintf( stderr, "font name BEFORE system match: \"%s\"\n", aFamily.getStr() );
2960 #endif
2962 // match font to e.g. resolve "Sans"
2963 psp::PrintFontManager::get().matchFont(aInfo, rLocale);
2965 #if OSL_DEBUG_LEVEL > 1
2966 fprintf( stderr, "font match %s, name AFTER: \"%s\"\n",
2967 aInfo.m_nID != 0 ? "succeeded" : "failed",
2968 OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
2969 #endif
2971 int nPointHeight = nPangoHeight/PANGO_SCALE;
2973 vcl::Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) );
2974 if( aInfo.m_eWeight != WEIGHT_DONTKNOW )
2975 aFont.SetWeight( aInfo.m_eWeight );
2976 if( aInfo.m_eWidth != WIDTH_DONTKNOW )
2977 aFont.SetWidthType( aInfo.m_eWidth );
2978 if( aInfo.m_eItalic != ITALIC_DONTKNOW )
2979 aFont.SetItalic( aInfo.m_eItalic );
2980 if( aInfo.m_ePitch != PITCH_DONTKNOW )
2981 aFont.SetPitch( aInfo.m_ePitch );
2982 return aFont;
2985 bool GtkSalGraphics::updateSettings(AllSettings& rSettings)
2987 GtkWidget* pTopLevel = gtk_widget_get_toplevel(mpWindow);
2988 GtkStyleContext* pStyle = gtk_widget_get_style_context(pTopLevel);
2989 StyleContextSave aContextState;
2990 aContextState.save(pStyle);
2991 GtkSettings* pSettings = gtk_widget_get_settings(pTopLevel);
2992 StyleSettings aStyleSet = rSettings.GetStyleSettings();
2993 GdkRGBA color;
2995 // text colors
2996 GdkRGBA text_color;
2997 style_context_set_state(pStyle, GTK_STATE_FLAG_NORMAL);
2998 gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), &text_color);
2999 ::Color aTextColor = getColor( text_color );
3000 aStyleSet.SetDialogTextColor( aTextColor );
3001 aStyleSet.SetButtonTextColor( aTextColor );
3002 aStyleSet.SetDefaultActionButtonTextColor(aTextColor);
3003 aStyleSet.SetActionButtonTextColor(aTextColor);
3004 aStyleSet.SetRadioCheckTextColor( aTextColor );
3005 aStyleSet.SetGroupTextColor( aTextColor );
3006 aStyleSet.SetLabelTextColor( aTextColor );
3007 aStyleSet.SetWindowTextColor( aTextColor );
3008 aStyleSet.SetFieldTextColor( aTextColor );
3010 // background colors
3011 GdkRGBA background_color;
3012 gtk_style_context_get_background_color(pStyle, gtk_style_context_get_state(pStyle), &background_color);
3014 ::Color aBackColor = getColor( background_color );
3015 aStyleSet.BatchSetBackgrounds( aBackColor );
3017 // UI font
3018 vcl::Font aFont(getFont(pStyle, rSettings.GetUILanguageTag().getLocale()));
3020 aStyleSet.BatchSetFonts( aFont, aFont);
3022 aFont.SetWeight( WEIGHT_BOLD );
3023 aStyleSet.SetTitleFont( aFont );
3024 aStyleSet.SetFloatTitleFont( aFont );
3026 // mouse over text colors
3027 style_context_set_state(pStyle, GTK_STATE_FLAG_PRELIGHT);
3028 gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), &text_color);
3029 aTextColor = getColor( text_color );
3030 aStyleSet.SetButtonRolloverTextColor(aTextColor);
3031 aStyleSet.SetActionButtonRolloverTextColor(aTextColor);
3032 aStyleSet.SetFieldRolloverTextColor( aTextColor );
3034 aContextState.restore();
3036 // button mouse over colors
3038 GdkRGBA normal_button_rollover_text_color, pressed_button_rollover_text_color;
3039 aContextState.save(mpButtonStyle);
3040 style_context_set_state(mpButtonStyle, GTK_STATE_FLAG_PRELIGHT);
3041 gtk_style_context_get_color(mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &normal_button_rollover_text_color);
3042 aTextColor = getColor(normal_button_rollover_text_color);
3043 aStyleSet.SetButtonRolloverTextColor( aTextColor );
3044 style_context_set_state(mpButtonStyle, static_cast<GtkStateFlags>(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE));
3045 gtk_style_context_get_color(mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &pressed_button_rollover_text_color);
3046 aTextColor = getColor(pressed_button_rollover_text_color);
3047 style_context_set_state(mpButtonStyle, GTK_STATE_FLAG_NORMAL);
3048 aStyleSet.SetButtonPressedRolloverTextColor( aTextColor );
3049 aContextState.restore();
3052 // tooltip colors
3054 GtkWidgetPath *pCPath = gtk_widget_path_new();
3055 guint pos = gtk_widget_path_append_type(pCPath, GTK_TYPE_WINDOW);
3056 gtk_widget_path_iter_add_class(pCPath, pos, GTK_STYLE_CLASS_TOOLTIP);
3057 pos = gtk_widget_path_append_type (pCPath, GTK_TYPE_LABEL);
3058 gtk_widget_path_iter_add_class(pCPath, pos, GTK_STYLE_CLASS_LABEL);
3059 GtkStyleContext *pCStyle = makeContext (pCPath, nullptr);
3061 GdkRGBA tooltip_bg_color, tooltip_fg_color;
3062 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
3063 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &tooltip_fg_color);
3064 gtk_style_context_get_background_color(pCStyle, gtk_style_context_get_state(pCStyle), &tooltip_bg_color);
3065 g_object_unref( pCStyle );
3067 aStyleSet.SetHelpColor( getColor( tooltip_bg_color ));
3068 aStyleSet.SetHelpTextColor( getColor( tooltip_fg_color ));
3072 // construct style context for text view
3073 GtkWidgetPath *pCPath = gtk_widget_path_new();
3074 gtk_widget_path_append_type( pCPath, GTK_TYPE_TEXT_VIEW );
3075 gtk_widget_path_iter_add_class( pCPath, -1, GTK_STYLE_CLASS_VIEW );
3076 GtkStyleContext *pCStyle = makeContext( pCPath, nullptr );
3078 // highlighting colors
3079 style_context_set_state(pCStyle, GTK_STATE_FLAG_SELECTED);
3080 gtk_style_context_get_background_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3081 ::Color aHighlightColor = getColor( text_color );
3082 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3083 ::Color aHighlightTextColor = getColor( text_color );
3084 aStyleSet.SetHighlightColor( aHighlightColor );
3085 aStyleSet.SetHighlightTextColor( aHighlightTextColor );
3087 // field background color
3088 GdkRGBA field_background_color;
3089 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
3090 gtk_style_context_get_background_color(pCStyle, gtk_style_context_get_state(pCStyle), &field_background_color);
3092 ::Color aBackFieldColor = getColor( field_background_color );
3093 aStyleSet.SetFieldColor( aBackFieldColor );
3094 // This baby is the default page/paper color
3095 aStyleSet.SetWindowColor( aBackFieldColor );
3097 // Cursor width
3098 gfloat caretAspectRatio = 0.04f;
3099 gtk_style_context_get_style( pCStyle, "cursor-aspect-ratio", &caretAspectRatio, nullptr );
3100 // Assume 20px tall for the ratio computation, which should give reasonable results
3101 aStyleSet.SetCursorSize( 20 * caretAspectRatio + 1 );
3103 // Dark shadow color
3104 style_context_set_state(pCStyle, GTK_STATE_FLAG_INSENSITIVE);
3105 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &color);
3106 ::Color aDarkShadowColor = getColor( color );
3107 aStyleSet.SetDarkShadowColor( aDarkShadowColor );
3109 ::Color aShadowColor(aBackColor);
3110 if (aDarkShadowColor.GetLuminance() > aBackColor.GetLuminance())
3111 aShadowColor.IncreaseLuminance(64);
3112 else
3113 aShadowColor.DecreaseLuminance(64);
3114 aStyleSet.SetShadowColor(aShadowColor);
3116 g_object_unref( pCStyle );
3118 // Tab colors
3119 aStyleSet.SetActiveTabColor( aBackFieldColor ); // same as the window color.
3120 aStyleSet.SetInactiveTabColor( aBackColor );
3123 // menu disabled entries handling
3124 aStyleSet.SetSkipDisabledInMenus( true );
3125 aStyleSet.SetPreferredContextMenuShortcuts( false );
3127 aContextState.save(mpMenuItemLabelStyle);
3129 // menu colors
3130 style_context_set_state(mpMenuStyle, GTK_STATE_FLAG_NORMAL);
3131 gtk_style_context_get_background_color( mpMenuStyle, gtk_style_context_get_state(mpMenuStyle), &background_color );
3132 aBackColor = getColor( background_color );
3133 aStyleSet.SetMenuColor( aBackColor );
3135 // menu bar
3136 style_context_set_state(mpMenuBarStyle, GTK_STATE_FLAG_NORMAL);
3137 gtk_style_context_get_background_color( mpMenuBarStyle, gtk_style_context_get_state(mpMenuBarStyle), &background_color );
3138 aBackColor = getColor( background_color );
3139 aStyleSet.SetMenuBarColor( aBackColor );
3140 aStyleSet.SetMenuBarRolloverColor( aBackColor );
3142 style_context_set_state(mpMenuBarItemStyle, GTK_STATE_FLAG_NORMAL);
3143 gtk_style_context_get_color( mpMenuBarItemStyle, gtk_style_context_get_state(mpMenuBarItemStyle), &text_color );
3144 aTextColor = aStyleSet.GetPersonaMenuBarTextColor().get_value_or( getColor( text_color ) );
3145 aStyleSet.SetMenuBarTextColor( aTextColor );
3146 aStyleSet.SetMenuBarRolloverTextColor( aTextColor );
3148 style_context_set_state(mpMenuBarItemStyle, GTK_STATE_FLAG_PRELIGHT);
3149 gtk_style_context_get_color( mpMenuBarItemStyle, gtk_style_context_get_state(mpMenuBarItemStyle), &text_color );
3150 aTextColor = aStyleSet.GetPersonaMenuBarTextColor().get_value_or( getColor( text_color ) );
3151 aStyleSet.SetMenuBarHighlightTextColor( aTextColor );
3153 // menu items
3154 style_context_set_state(mpMenuItemLabelStyle, GTK_STATE_FLAG_NORMAL);
3155 gtk_style_context_get_color(mpMenuItemLabelStyle, gtk_style_context_get_state(mpMenuItemLabelStyle), &color);
3156 aTextColor = getColor(color);
3157 aStyleSet.SetMenuTextColor(aTextColor);
3159 style_context_set_state(mpMenuItemLabelStyle, GTK_STATE_FLAG_PRELIGHT);
3160 gtk_style_context_get_background_color( mpMenuItemLabelStyle, gtk_style_context_get_state(mpMenuItemLabelStyle), &background_color );
3161 ::Color aHighlightColor = getColor( background_color );
3162 aStyleSet.SetMenuHighlightColor( aHighlightColor );
3164 gtk_style_context_get_color( mpMenuItemLabelStyle, gtk_style_context_get_state(mpMenuItemLabelStyle), &color );
3165 ::Color aHighlightTextColor = getColor( color );
3166 aStyleSet.SetMenuHighlightTextColor( aHighlightTextColor );
3168 aContextState.restore();
3170 // hyperlink colors
3171 aContextState.save(mpLinkButtonStyle);
3172 style_context_set_state(mpLinkButtonStyle, GTK_STATE_FLAG_LINK);
3173 gtk_style_context_get_color(mpLinkButtonStyle, gtk_style_context_get_state(mpLinkButtonStyle), &text_color);
3174 aStyleSet.SetLinkColor(getColor(text_color));
3175 style_context_set_state(mpLinkButtonStyle, GTK_STATE_FLAG_VISITED);
3176 gtk_style_context_get_color(mpLinkButtonStyle, gtk_style_context_get_state(mpLinkButtonStyle), &text_color);
3177 aStyleSet.SetVisitedLinkColor(getColor(text_color));
3178 aContextState.restore();
3181 GtkStyleContext *pCStyle = mpNotebookHeaderTabsTabLabelStyle;
3182 aContextState.save(pCStyle);
3183 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
3184 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3185 aTextColor = getColor( text_color );
3186 aStyleSet.SetTabTextColor(aTextColor);
3187 aStyleSet.SetTabFont(getFont(mpNotebookHeaderTabsTabLabelStyle, rSettings.GetUILanguageTag().getLocale()));
3188 aContextState.restore();
3192 GtkStyleContext *pCStyle = mpToolButtonStyle;
3193 aContextState.save(pCStyle);
3194 style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
3195 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3196 aTextColor = getColor( text_color );
3197 aStyleSet.SetToolTextColor(aTextColor);
3198 aStyleSet.SetToolFont(getFont(mpToolButtonStyle, rSettings.GetUILanguageTag().getLocale()));
3199 aContextState.restore();
3202 // mouse over text colors
3204 GtkStyleContext *pCStyle = mpNotebookHeaderTabsTabHoverLabelStyle;
3205 aContextState.save(pCStyle);
3206 style_context_set_state(pCStyle, GTK_STATE_FLAG_PRELIGHT);
3207 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3208 aTextColor = getColor( text_color );
3209 aStyleSet.SetTabRolloverTextColor(aTextColor);
3210 aContextState.restore();
3214 GtkStyleContext *pCStyle = mpNotebookHeaderTabsTabActiveLabelStyle;
3215 aContextState.save(pCStyle);
3216 style_context_set_state(pCStyle, ACTIVE_TAB());
3217 gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &text_color);
3218 aTextColor = getColor( text_color );
3219 aStyleSet.SetTabHighlightTextColor(aTextColor);
3220 aContextState.restore();
3223 // get cursor blink time
3224 gboolean blink = false;
3226 g_object_get( pSettings, "gtk-cursor-blink", &blink, nullptr );
3227 if( blink )
3229 gint blink_time = static_cast<gint>(STYLE_CURSOR_NOBLINKTIME);
3230 g_object_get( pSettings, "gtk-cursor-blink-time", &blink_time, nullptr );
3231 // set the blink_time if there is a setting and it is reasonable
3232 // else leave the default value
3233 if( blink_time > 100 )
3234 aStyleSet.SetCursorBlinkTime( blink_time/2 );
3236 else
3237 aStyleSet.SetCursorBlinkTime( STYLE_CURSOR_NOBLINKTIME );
3239 MouseSettings aMouseSettings = rSettings.GetMouseSettings();
3240 int iDoubleClickTime, iDoubleClickDistance, iDragThreshold;
3241 static const int MENU_POPUP_DELAY = 225;
3242 g_object_get( pSettings,
3243 "gtk-double-click-time", &iDoubleClickTime,
3244 "gtk-double-click-distance", &iDoubleClickDistance,
3245 "gtk-dnd-drag-threshold", &iDragThreshold,
3246 nullptr );
3247 aMouseSettings.SetDoubleClickTime( iDoubleClickTime );
3248 aMouseSettings.SetDoubleClickWidth( iDoubleClickDistance );
3249 aMouseSettings.SetDoubleClickHeight( iDoubleClickDistance );
3250 aMouseSettings.SetStartDragWidth( iDragThreshold );
3251 aMouseSettings.SetStartDragHeight( iDragThreshold );
3252 aMouseSettings.SetMenuDelay( MENU_POPUP_DELAY );
3253 rSettings.SetMouseSettings( aMouseSettings );
3255 gboolean primarybuttonwarps = false;
3256 g_object_get( pSettings,
3257 "gtk-primary-button-warps-slider", &primarybuttonwarps,
3258 nullptr );
3259 aStyleSet.SetPreferredUseImagesInMenus(false);
3260 aStyleSet.SetPrimaryButtonWarpsSlider(primarybuttonwarps);
3262 // set scrollbar settings
3263 gint min_slider_length = 21;
3265 // Grab some button style attributes
3266 if (gtk_check_version(3, 20, 0) == nullptr)
3268 Size aSize;
3269 QuerySize(mpHScrollbarStyle, aSize);
3270 QuerySize(mpHScrollbarContentsStyle, aSize);
3271 QuerySize(mpHScrollbarTroughStyle, aSize);
3272 QuerySize(mpHScrollbarSliderStyle, aSize);
3274 gboolean has_forward, has_forward2, has_backward, has_backward2;
3275 gtk_style_context_get_style(mpHScrollbarStyle,
3276 "has-forward-stepper", &has_forward,
3277 "has-secondary-forward-stepper", &has_forward2,
3278 "has-backward-stepper", &has_backward,
3279 "has-secondary-backward-stepper", &has_backward2, nullptr);
3280 if (has_forward || has_backward || has_forward2 || has_backward2)
3281 QuerySize(mpHScrollbarButtonStyle, aSize);
3283 aStyleSet.SetScrollBarSize(aSize.Height());
3285 gtk_style_context_get(mpVScrollbarSliderStyle, gtk_style_context_get_state(mpVScrollbarSliderStyle),
3286 "min-height", &min_slider_length,
3287 nullptr);
3288 aStyleSet.SetMinThumbSize(min_slider_length);
3290 else
3292 gint slider_width = 14;
3293 gint trough_border = 1;
3295 gtk_style_context_get_style(mpVScrollbarStyle,
3296 "slider-width", &slider_width,
3297 "trough-border", &trough_border,
3298 "min-slider-length", &min_slider_length,
3299 nullptr);
3300 aStyleSet.SetScrollBarSize(slider_width + 2*trough_border);
3301 gint magic = trough_border ? 1 : 0;
3302 aStyleSet.SetMinThumbSize(min_slider_length - magic);
3305 // preferred icon style
3306 gchar* pIconThemeName = nullptr;
3307 gboolean bDarkIconTheme = false;
3308 g_object_get(pSettings, "gtk-icon-theme-name", &pIconThemeName,
3309 "gtk-application-prefer-dark-theme", &bDarkIconTheme,
3310 nullptr );
3311 OUString sIconThemeName(OUString::createFromAscii(pIconThemeName));
3312 aStyleSet.SetPreferredIconTheme(sIconThemeName, bDarkIconTheme);
3313 g_free( pIconThemeName );
3315 aStyleSet.SetToolbarIconSize( ToolbarIconSize::Large );
3317 // finally update the collected settings
3318 rSettings.SetStyleSettings( aStyleSet );
3319 #if OSL_DEBUG_LEVEL > 1
3320 gchar* pThemeName = NULL;
3321 g_object_get( pSettings, "gtk-theme-name", &pThemeName, nullptr );
3322 fprintf( stderr, "Theme name is \"%s\"\n", pThemeName );
3323 g_free(pThemeName);
3324 #endif
3326 return true;
3329 bool GtkSalGraphics::isNativeControlSupported( ControlType nType, ControlPart nPart )
3331 switch(nType)
3333 case ControlType::Pushbutton:
3334 case ControlType::Radiobutton:
3335 case ControlType::Checkbox:
3336 case ControlType::Progress:
3337 case ControlType::ListNode:
3338 case ControlType::ListNet:
3339 if (nPart==ControlPart::Entire || nPart == ControlPart::Focus)
3340 return true;
3341 break;
3343 case ControlType::Scrollbar:
3344 if(nPart==ControlPart::DrawBackgroundHorz || nPart==ControlPart::DrawBackgroundVert ||
3345 nPart==ControlPart::Entire || nPart==ControlPart::HasThreeButtons)
3346 return true;
3347 break;
3349 case ControlType::Editbox:
3350 case ControlType::MultilineEditbox:
3351 if (nPart==ControlPart::Entire || nPart==ControlPart::HasBackgroundTexture)
3352 return true;
3353 break;
3355 case ControlType::Combobox:
3356 if (nPart==ControlPart::Entire || nPart==ControlPart::HasBackgroundTexture || nPart == ControlPart::AllButtons)
3357 return true;
3358 break;
3360 case ControlType::Spinbox:
3361 if (nPart==ControlPart::Entire || nPart==ControlPart::HasBackgroundTexture || nPart == ControlPart::AllButtons || nPart == ControlPart::ButtonUp || nPart == ControlPart::ButtonDown)
3362 return true;
3363 break;
3365 case ControlType::SpinButtons:
3366 if (nPart==ControlPart::Entire || nPart==ControlPart::AllButtons)
3367 return true;
3368 break;
3370 case ControlType::Frame:
3371 case ControlType::WindowBackground:
3372 return true;
3374 case ControlType::TabItem:
3375 case ControlType::TabHeader:
3376 case ControlType::TabPane:
3377 case ControlType::TabBody:
3378 if(nPart==ControlPart::Entire || nPart==ControlPart::TabsDrawRtl)
3379 return true;
3380 break;
3382 case ControlType::Listbox:
3383 if (nPart==ControlPart::Entire || nPart==ControlPart::ListboxWindow || nPart==ControlPart::HasBackgroundTexture || nPart == ControlPart::Focus)
3384 return true;
3385 break;
3387 case ControlType::Toolbar:
3388 if( nPart==ControlPart::Entire
3389 // || nPart==ControlPart::DrawBackgroundHorz
3390 // || nPart==ControlPart::DrawBackgroundVert
3391 // || nPart==ControlPart::ThumbHorz
3392 // || nPart==ControlPart::ThumbVert
3393 || nPart==ControlPart::Button
3394 // || nPart==ControlPart::SeparatorHorz
3395 || nPart==ControlPart::SeparatorVert
3397 return true;
3398 break;
3400 case ControlType::Menubar:
3401 if (nPart==ControlPart::Entire || nPart==ControlPart::MenuItem)
3402 return true;
3403 break;
3405 case ControlType::MenuPopup:
3406 if (nPart==ControlPart::Entire
3407 || nPart==ControlPart::MenuItem
3408 || nPart==ControlPart::MenuItemCheckMark
3409 || nPart==ControlPart::MenuItemRadioMark
3410 || nPart==ControlPart::Separator
3411 || nPart==ControlPart::SubmenuArrow
3413 return true;
3414 break;
3416 // case ControlType::Slider:
3417 // if(nPart == ControlPart::TrackHorzArea || nPart == ControlPart::TrackVertArea)
3418 // return true;
3419 // break;
3421 case ControlType::Fixedline:
3422 if (nPart == ControlPart::SeparatorVert || nPart == ControlPart::SeparatorHorz)
3423 return true;
3424 break;
3426 case ControlType::ListHeader:
3427 if (nPart == ControlPart::Button || nPart == ControlPart::Arrow)
3428 return true;
3429 break;
3430 default: break;
3433 SAL_INFO("vcl.gtk", "Unhandled is native supported for Type:" << static_cast<int>(nType) << ", Part" << static_cast<int>(nPart));
3435 return false;
3438 #if ENABLE_CAIRO_CANVAS
3440 bool GtkSalGraphics::SupportsCairo() const
3442 return true;
3445 cairo::SurfaceSharedPtr GtkSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
3447 return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(rSurface));
3450 cairo::SurfaceSharedPtr GtkSalGraphics::CreateSurface(const OutputDevice& /*rRefDevice*/, int x, int y, int width, int height) const
3452 return cairo::SurfaceSharedPtr(new cairo::Gtk3Surface(this, x, y, width, height));
3455 #endif
3457 void GtkSalGraphics::WidgetQueueDraw() const
3459 //request gtk to sync the entire contents
3460 GtkWidget *pWidget = GTK_WIDGET(mpFrame->getFixedContainer());
3461 gtk_widget_queue_draw(pWidget);
3464 namespace {
3466 void getStyleContext(GtkStyleContext** style, GtkWidget* widget)
3468 gtk_container_add(GTK_CONTAINER(gDumbContainer), widget);
3469 *style = gtk_widget_get_style_context(widget);
3470 g_object_ref(*style);
3475 void GtkSalData::initNWF()
3477 ImplSVData* pSVData = ImplGetSVData();
3478 pSVData->maNWFData.mbFlatMenu = true;
3479 pSVData->maNWFData.mbDockingAreaAvoidTBFrames = true;
3480 pSVData->maNWFData.mbCanDrawWidgetAnySize = true;
3481 pSVData->maNWFData.mbDDListBoxNoTextArea = true;
3482 pSVData->maNWFData.mbNoFocusRects = true;
3483 pSVData->maNWFData.mbNoFocusRectsForFlatButtons = true;
3484 pSVData->maNWFData.mbAutoAccel = true;
3486 #if defined(GDK_WINDOWING_WAYLAND)
3487 //gnome#768128 for the car crash that is wayland
3488 //and floating dockable toolbars
3489 GdkDisplay *pDisplay = gdk_display_get_default();
3490 if (DLSYM_GDK_IS_WAYLAND_DISPLAY(pDisplay))
3491 pSVData->maNWFData.mbCanDetermineWindowPosition = false;
3492 #endif
3495 void GtkSalData::deInitNWF()
3497 if (gCacheWindow)
3498 gtk_widget_destroy(gCacheWindow);
3501 GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow )
3502 : SvpSalGraphics(),
3503 mpFrame( pFrame ),
3504 mpWindow( pWindow )
3506 if (style_loaded)
3507 return;
3509 style_loaded = true;
3511 /* Load the GtkStyleContexts, it might be a bit slow, but usually,
3512 * gtk apps create a lot of widgets at startup, so, it shouldn't be
3513 * too slow */
3514 gtk_widget_path_iter_set_object_nameFunc set_object_name =
3515 reinterpret_cast<gtk_widget_path_iter_set_object_nameFunc>(osl_getAsciiFunctionSymbol(nullptr,
3516 "gtk_widget_path_iter_set_object_name"));
3518 gCacheWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
3519 gDumbContainer = gtk_fixed_new();
3520 gtk_container_add(GTK_CONTAINER(gCacheWindow), gDumbContainer);
3521 gtk_widget_realize(gDumbContainer);
3522 gtk_widget_realize(gCacheWindow);
3524 gEntryBox = gtk_entry_new();
3525 gtk_container_add(GTK_CONTAINER(gDumbContainer), gEntryBox);
3527 mpWindowStyle = createStyleContext(set_object_name, GtkControlPart::ToplevelWindow);
3528 mpEntryStyle = createStyleContext(set_object_name, GtkControlPart::Entry);
3530 getStyleContext(&mpTextViewStyle, gtk_text_view_new());
3532 mpButtonStyle = createStyleContext(set_object_name, GtkControlPart::Button);
3533 mpLinkButtonStyle = createStyleContext(set_object_name, GtkControlPart::LinkButton);
3535 GtkWidget* pToolbar = gtk_toolbar_new();
3536 mpToolbarStyle = gtk_widget_get_style_context(pToolbar);
3537 gtk_style_context_add_class(mpToolbarStyle, GTK_STYLE_CLASS_TOOLBAR);
3539 GtkToolItem *item = gtk_separator_tool_item_new();
3540 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), item, -1);
3541 mpToolbarSeperatorStyle = gtk_widget_get_style_context(GTK_WIDGET(item));
3543 GtkWidget *pButton = gtk_button_new();
3544 item = gtk_tool_button_new(pButton, nullptr);
3545 gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), item, -1);
3546 mpToolButtonStyle = gtk_widget_get_style_context(GTK_WIDGET(pButton));
3548 mpVScrollbarStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVertical);
3549 mpVScrollbarContentsStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalContents);
3550 mpVScrollbarTroughStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalTrough);
3551 mpVScrollbarSliderStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalSlider);
3552 mpVScrollbarButtonStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarVerticalButton);
3553 mpHScrollbarStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontal);
3554 mpHScrollbarContentsStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalContents);
3555 mpHScrollbarTroughStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalTrough);
3556 mpHScrollbarSliderStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalSlider);
3557 mpHScrollbarButtonStyle = createStyleContext(set_object_name, GtkControlPart::ScrollbarHorizontalButton);
3559 mpCheckButtonStyle = createStyleContext(set_object_name, GtkControlPart::CheckButton);
3560 mpCheckButtonCheckStyle = createStyleContext(set_object_name, GtkControlPart::CheckButtonCheck);
3562 mpRadioButtonStyle = createStyleContext(set_object_name, GtkControlPart::RadioButton);
3563 mpRadioButtonRadioStyle = createStyleContext(set_object_name, GtkControlPart::RadioButtonRadio);
3565 /* Spinbutton */
3566 gSpinBox = gtk_spin_button_new(nullptr, 0, 0);
3567 gtk_container_add(GTK_CONTAINER(gDumbContainer), gSpinBox);
3568 mpSpinStyle = createStyleContext(set_object_name, GtkControlPart::SpinButton);
3569 mpSpinEntryStyle = createStyleContext(set_object_name, GtkControlPart::SpinButtonEntry);
3570 mpSpinUpStyle = createStyleContext(set_object_name, GtkControlPart::SpinButtonUpButton);
3571 mpSpinDownStyle = createStyleContext(set_object_name, GtkControlPart::SpinButtonDownButton);
3573 /* NoteBook */
3574 mpNotebookStyle = createStyleContext(set_object_name, GtkControlPart::Notebook);
3575 mpNotebookStackStyle = createStyleContext(set_object_name, GtkControlPart::NotebookStack);
3576 mpNotebookHeaderStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeader);
3577 mpNotebookHeaderTabsStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabs);
3578 mpNotebookHeaderTabsTabStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTab);
3579 mpNotebookHeaderTabsTabLabelStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTabLabel);
3580 mpNotebookHeaderTabsTabActiveLabelStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTabActiveLabel);
3581 mpNotebookHeaderTabsTabHoverLabelStyle = createStyleContext(set_object_name, GtkControlPart::NotebookHeaderTabsTabHoverLabel);
3583 /* Combobox */
3584 gComboBox = gtk_combo_box_text_new_with_entry();
3585 gtk_container_add(GTK_CONTAINER(gDumbContainer), gComboBox);
3586 mpComboboxStyle = createStyleContext(set_object_name, GtkControlPart::Combobox);
3587 mpComboboxBoxStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBox);
3588 mpComboboxEntryStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxEntry);
3589 mpComboboxButtonStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxButton);
3590 mpComboboxButtonBoxStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxButtonBox);
3591 mpComboboxButtonArrowStyle = createStyleContext(set_object_name, GtkControlPart::ComboboxBoxButtonBoxArrow);
3593 /* Listbox */
3594 gListBox = gtk_combo_box_text_new();
3595 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(gListBox), "sample");
3596 gtk_container_add(GTK_CONTAINER(gDumbContainer), gListBox);
3597 mpListboxStyle = createStyleContext(set_object_name, GtkControlPart::Listbox);
3598 mpListboxBoxStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBox);
3599 mpListboxButtonStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBoxButton);
3600 mpListboxButtonBoxStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBoxButtonBox);
3601 mpListboxButtonArrowStyle = createStyleContext(set_object_name, GtkControlPart::ListboxBoxButtonBoxArrow);
3603 /* Menu bar */
3604 gMenuBarWidget = gtk_menu_bar_new();
3605 gMenuItemMenuBarWidget = gtk_menu_item_new_with_label( "b" );
3606 gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget), gMenuItemMenuBarWidget);
3607 gtk_container_add(GTK_CONTAINER(gDumbContainer), gMenuBarWidget);
3609 mpMenuBarStyle = createStyleContext(set_object_name, GtkControlPart::MenuBar);
3610 mpMenuBarItemStyle = createStyleContext(set_object_name, GtkControlPart::MenuBarItem);
3612 /* Menu */
3613 mpMenuWindowStyle = createStyleContext(set_object_name, GtkControlPart::MenuWindow);
3614 mpMenuStyle = createStyleContext(set_object_name, GtkControlPart::Menu);
3615 GtkWidget *menu = gtk_menu_new();
3616 gtk_menu_item_set_submenu(GTK_MENU_ITEM(gMenuItemMenuBarWidget), menu);
3618 /* Menu Items */
3619 gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
3620 gtk_menu_shell_append(GTK_MENU_SHELL(menu), gCheckMenuItemWidget);
3622 mpMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::MenuItem);
3623 mpMenuItemLabelStyle = createStyleContext(set_object_name, GtkControlPart::MenuItemLabel);
3624 mpMenuItemArrowStyle = createStyleContext(set_object_name, GtkControlPart::MenuItemArrow);
3625 mpCheckMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::CheckMenuItem);
3626 mpCheckMenuItemCheckStyle = createStyleContext(set_object_name, GtkControlPart::CheckMenuItemCheck);
3627 mpRadioMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::RadioMenuItem);
3628 mpRadioMenuItemRadioStyle = createStyleContext(set_object_name, GtkControlPart::RadioMenuItemRadio);
3629 mpSeparatorMenuItemStyle = createStyleContext(set_object_name, GtkControlPart::SeparatorMenuItem);
3630 mpSeparatorMenuItemSeparatorStyle = createStyleContext(set_object_name, GtkControlPart::SeparatorMenuItemSeparator);
3632 /* Frames */
3633 mpFrameOutStyle = mpFrameInStyle = createStyleContext(set_object_name, GtkControlPart::FrameBorder);
3634 getStyleContext(&mpFixedHoriLineStyle, gtk_separator_new(GTK_ORIENTATION_HORIZONTAL));
3635 getStyleContext(&mpFixedVertLineStyle, gtk_separator_new(GTK_ORIENTATION_VERTICAL));
3638 /* Tree List */
3639 gTreeViewWidget = gtk_tree_view_new();
3640 gtk_container_add(GTK_CONTAINER(gDumbContainer), gTreeViewWidget);
3642 GtkTreeViewColumn* firstTreeViewColumn = gtk_tree_view_column_new();
3643 gtk_tree_view_column_set_title(firstTreeViewColumn, "M");
3644 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), firstTreeViewColumn);
3646 GtkTreeViewColumn* middleTreeViewColumn = gtk_tree_view_column_new();
3647 gtk_tree_view_column_set_title(middleTreeViewColumn, "M");
3648 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), middleTreeViewColumn);
3649 gtk_tree_view_set_expander_column(GTK_TREE_VIEW(gTreeViewWidget), middleTreeViewColumn);
3651 GtkTreeViewColumn* lastTreeViewColumn = gtk_tree_view_column_new();
3652 gtk_tree_view_column_set_title(lastTreeViewColumn, "M");
3653 gtk_tree_view_append_column(GTK_TREE_VIEW(gTreeViewWidget), lastTreeViewColumn);
3655 /* Use the middle column's header for our button */
3656 GtkWidget* pTreeHeaderCellWidget = gtk_tree_view_column_get_button(middleTreeViewColumn);
3657 mpTreeHeaderButtonStyle = gtk_widget_get_style_context(pTreeHeaderCellWidget);
3659 /* Progress Bar */
3660 mpProgressBarStyle = createStyleContext(set_object_name, GtkControlPart::ProgressBar);
3661 mpProgressBarTroughStyle = createStyleContext(set_object_name, GtkControlPart::ProgressBarTrough);
3662 mpProgressBarProgressStyle = createStyleContext(set_object_name, GtkControlPart::ProgressBarProgress);
3664 gtk_widget_show_all(gDumbContainer);
3667 void GtkSalGraphics::GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY)
3669 char* pForceDpi;
3670 if ((pForceDpi = getenv("SAL_FORCEDPI")))
3672 OString sForceDPI(pForceDpi);
3673 rDPIX = rDPIY = sForceDPI.toInt32();
3674 return;
3677 GdkScreen* pScreen = gtk_widget_get_screen(mpWindow);
3678 double fResolution = -1.0;
3679 g_object_get(pScreen, "resolution", &fResolution, nullptr);
3681 if (fResolution > 0.0)
3682 rDPIX = rDPIY = sal_Int32(fResolution);
3683 else
3684 rDPIX = rDPIY = 96;
3687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */