Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_version.h>
21 :
22 : #include "vcl/svapp.hxx"
23 :
24 : #include "unx/gtk/gtkframe.hxx"
25 : #include "unx/gtk/gtkdata.hxx"
26 : #include "unx/gtk/gtkinst.hxx"
27 : #include "unx/gtk/gtkgdi.hxx"
28 :
29 : #include "unx/saldata.hxx"
30 : #include "unx/saldisp.hxx"
31 :
32 : #include <cstdio>
33 : #include <cmath>
34 : #include <vector>
35 : #include <algorithm>
36 : #include <boost/unordered_map.hpp>
37 :
38 : #include "vcl/vclenum.hxx"
39 : #include <vcl/settings.hxx>
40 : #include "fontmanager.hxx"
41 : #include <vcl/decoview.hxx>
42 :
43 : typedef struct _cairo_font_options cairo_font_options_t;
44 : const char* const tabPrelitDataName="libreoffice-tab-is-prelit";
45 :
46 : // initialize statics
47 : bool GtkSalGraphics::bThemeChanged = true;
48 : bool GtkSalGraphics::bNeedPixmapPaint = false;
49 :
50 0 : GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow )
51 : : X11SalGraphics(),
52 : m_pWindow( pWindow ),
53 0 : m_aClipRegion(true)
54 : {
55 : Init( pFrame, GDK_WINDOW_XID( widget_get_window( pWindow ) ),
56 : SalX11Screen( gdk_x11_screen_get_screen_number(
57 0 : gtk_widget_get_screen( pWindow ) ) ) );
58 0 : }
59 :
60 0 : GtkSalGraphics::~GtkSalGraphics()
61 : {
62 0 : }
63 :
64 : /*************************************
65 : * Cached native widget objects
66 : *************************************/
67 : class NWPixmapCacheList;
68 : class NWPixmapCache;
69 : struct NWFWidgetData
70 : {
71 : GtkWidget * gCacheWindow;
72 : GtkWidget * gDumbContainer;
73 :
74 : GtkWidget * gBtnWidget;
75 : GtkWidget * gRadioWidget;
76 : GtkWidget * gRadioWidgetSibling;
77 : GtkWidget * gCheckWidget;
78 : GtkWidget * gScrollHorizWidget;
79 : GtkWidget * gScrollVertWidget;
80 : GtkWidget * gArrowWidget;
81 : GtkWidget * gDropdownWidget;
82 : GtkWidget * gEditBoxWidget;
83 : GtkWidget * gSpinButtonWidget;
84 : GtkWidget * gNotebookWidget;
85 : GtkWidget * gOptionMenuWidget;
86 : GtkWidget * gComboWidget;
87 : GtkWidget * gScrolledWindowWidget;
88 : GtkWidget * gToolbarWidget;
89 : GtkWidget * gToolbarButtonWidget;
90 : GtkWidget * gHandleBoxWidget;
91 : GtkWidget * gMenubarWidget;
92 : GtkWidget * gMenuItemMenubarWidget;
93 : GtkWidget * gMenuWidget;
94 : GtkWidget * gMenuItemMenuWidget;
95 : GtkWidget * gMenuItemCheckMenuWidget;
96 : GtkWidget * gMenuItemRadioMenuWidget;
97 : GtkWidget * gMenuItemSeparatorMenuWidget;
98 : GtkWidget * gImageMenuItem;
99 : GtkWidget * gTooltipPopup;
100 : GtkWidget * gProgressBar;
101 : GtkWidget * gTreeView;
102 : GtkWidget * gHScale;
103 : GtkWidget * gVScale;
104 : GtkWidget * gSeparator;
105 : GtkWidget * gDialog;
106 : GtkWidget * gFrame;
107 :
108 : NWPixmapCacheList* gNWPixmapCacheList;
109 : NWPixmapCache* gCacheTabItems;
110 : NWPixmapCache* gCacheTabPages;
111 :
112 0 : NWFWidgetData() :
113 : gCacheWindow( NULL ),
114 : gDumbContainer( NULL ),
115 : gBtnWidget( NULL ),
116 : gRadioWidget( NULL ),
117 : gRadioWidgetSibling( NULL ),
118 : gCheckWidget( NULL ),
119 : gScrollHorizWidget( NULL ),
120 : gScrollVertWidget( NULL ),
121 : gArrowWidget( NULL ),
122 : gDropdownWidget( NULL ),
123 : gEditBoxWidget( NULL ),
124 : gSpinButtonWidget( NULL ),
125 : gNotebookWidget( NULL ),
126 : gOptionMenuWidget( NULL ),
127 : gComboWidget( NULL ),
128 : gScrolledWindowWidget( NULL ),
129 : gToolbarWidget( NULL ),
130 : gToolbarButtonWidget( NULL ),
131 : gHandleBoxWidget( NULL ),
132 : gMenubarWidget( NULL ),
133 : gMenuItemMenubarWidget( NULL ),
134 : gMenuWidget( NULL ),
135 : gMenuItemMenuWidget( NULL ),
136 : gMenuItemCheckMenuWidget( NULL ),
137 : gMenuItemRadioMenuWidget( NULL ),
138 : gMenuItemSeparatorMenuWidget( NULL ),
139 : gImageMenuItem( NULL ),
140 : gTooltipPopup( NULL ),
141 : gProgressBar( NULL ),
142 : gTreeView( NULL ),
143 : gHScale( NULL ),
144 : gVScale( NULL ),
145 : gSeparator( NULL ),
146 : gDialog( NULL ),
147 : gFrame( NULL ),
148 : gNWPixmapCacheList( NULL ),
149 : gCacheTabItems( NULL ),
150 0 : gCacheTabPages( NULL )
151 0 : {}
152 : };
153 :
154 : // Keep a hash table of Widgets->default flags so that we can
155 : // easily and quickly reset each to a default state before using
156 : // them
157 0 : static boost::unordered_map<long, guint> gWidgetDefaultFlags;
158 0 : class WidgetDataVector : public std::vector<NWFWidgetData>
159 : {
160 : public:
161 0 : WidgetDataVector(size_t nElems = 0) : std::vector<NWFWidgetData>( nElems ) {}
162 0 : NWFWidgetData &operator [](size_t i) { return at(i); }
163 0 : NWFWidgetData &operator [](const SalX11Screen &s) { return at(s.getXScreen()); }
164 : };
165 0 : static WidgetDataVector gWidgetData;
166 :
167 : static const GtkBorder aDefDefBorder = { 1, 1, 1, 1 };
168 :
169 : // Some GTK defaults
170 : #define MIN_ARROW_SIZE 11
171 : #define BTN_CHILD_SPACING 1
172 : #define MIN_SPIN_ARROW_WIDTH 6
173 :
174 : static void NWEnsureGTKRadio ( SalX11Screen nScreen );
175 : static void NWEnsureGTKButton ( SalX11Screen nScreen );
176 : static void NWEnsureGTKCheck ( SalX11Screen nScreen );
177 : static void NWEnsureGTKScrollbars ( SalX11Screen nScreen );
178 : static void NWEnsureGTKArrow ( SalX11Screen nScreen );
179 : static void NWEnsureGTKEditBox ( SalX11Screen nScreen );
180 : static void NWEnsureGTKSpinButton ( SalX11Screen nScreen );
181 : static void NWEnsureGTKNotebook ( SalX11Screen nScreen );
182 : static void NWEnsureGTKOptionMenu ( SalX11Screen nScreen );
183 : static void NWEnsureGTKCombo ( SalX11Screen nScreen );
184 : static void NWEnsureGTKScrolledWindow ( SalX11Screen nScreen );
185 : static void NWEnsureGTKToolbar ( SalX11Screen nScreen );
186 : static void NWEnsureGTKMenubar ( SalX11Screen nScreen );
187 : static void NWEnsureGTKMenu ( SalX11Screen nScreen );
188 : static void NWEnsureGTKTooltip ( SalX11Screen nScreen );
189 : static void NWEnsureGTKDialog ( SalX11Screen nScreen );
190 : static void NWEnsureGTKFrame ( SalX11Screen nScreen );
191 : static void NWEnsureGTKProgressBar ( SalX11Screen nScreen );
192 : static void NWEnsureGTKTreeView ( SalX11Screen nScreen );
193 : static void NWEnsureGTKSlider ( SalX11Screen nScreen );
194 :
195 : static void NWConvertVCLStateToGTKState( ControlState nVCLState, GtkStateType* nGTKState, GtkShadowType* nGTKShadow );
196 : static void NWAddWidgetToCacheWindow( GtkWidget* widget, SalX11Screen nScreen );
197 : static void NWSetWidgetState( GtkWidget* widget, ControlState nState, GtkStateType nGtkState );
198 :
199 : static void NWCalcArrowRect( const Rectangle& rButton, Rectangle& rArrow );
200 :
201 : /*
202 : * Individual helper functions
203 : *
204 : */
205 :
206 : static Rectangle NWGetButtonArea( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
207 : const ImplControlValue& aValue, const OUString& rCaption );
208 :
209 : static Rectangle NWGetTabItemRect( SalX11Screen nScreen, Rectangle aAreaRect );
210 :
211 : static Rectangle NWGetEditBoxPixmapRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
212 : const ImplControlValue& aValue, const OUString& rCaption );
213 :
214 : static void NWPaintOneEditBox( SalX11Screen nScreen, GdkDrawable * gdkDrawable, GdkRectangle *gdkRect,
215 : ControlType nType, ControlPart nPart, Rectangle aEditBoxRect,
216 : ControlState nState, const ImplControlValue& aValue,
217 : const OUString& rCaption );
218 :
219 : static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
220 : const ImplControlValue& aValue, const OUString& rCaption );
221 :
222 : static void NWPaintOneSpinButton( SalX11Screen nScreen, GdkPixmap * pixmap, ControlType nType, ControlPart nPart, Rectangle aAreaRect,
223 : ControlState nState, const ImplControlValue& aValue,
224 : const OUString& rCaption );
225 :
226 : static Rectangle NWGetComboBoxButtonRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
227 : const ImplControlValue& aValue, const OUString& rCaption );
228 :
229 : static Rectangle NWGetListBoxButtonRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
230 : const ImplControlValue& aValue, const OUString& rCaption );
231 :
232 : static Rectangle NWGetListBoxIndicatorRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
233 : const ImplControlValue& aValue, const OUString& rCaption );
234 :
235 : static Rectangle NWGetToolbarRect( SalX11Screen nScreen,
236 : ControlType nType,
237 : ControlPart nPart,
238 : Rectangle aAreaRect,
239 : ControlState nState,
240 : const ImplControlValue& aValue,
241 : const OUString& rCaption );
242 :
243 : static int getFrameWidth(GtkWidget* widget);
244 :
245 : static Rectangle NWGetScrollButtonRect( SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect );
246 :
247 : /*********************************************************
248 : * PixmapCache
249 : *********************************************************/
250 :
251 : // as some native widget drawing operations are pretty slow
252 : // with certain themes (eg tabpages)
253 : // this cache can be used to cache the corresponding pixmap
254 : // see NWPaintGTKTabItem
255 :
256 : class NWPixmapCacheData
257 : {
258 : public:
259 : ControlType m_nType;
260 : ControlState m_nState;
261 : Rectangle m_pixmapRect;
262 : GdkPixmap* m_pixmap;
263 :
264 0 : NWPixmapCacheData() : m_nType(0), m_nState(0), m_pixmap(0) {}
265 0 : ~NWPixmapCacheData()
266 0 : { SetPixmap( NULL ); };
267 : void SetPixmap( GdkPixmap* pPixmap );
268 : };
269 :
270 : class NWPixmapCache
271 : {
272 : int m_size;
273 : int m_idx;
274 : int m_screen;
275 : NWPixmapCacheData* pData;
276 : public:
277 : NWPixmapCache( SalX11Screen nScreen );
278 : ~NWPixmapCache();
279 :
280 0 : void SetSize( int n)
281 0 : { delete [] pData; m_idx = 0; m_size = n; pData = new NWPixmapCacheData[m_size]; }
282 0 : int GetSize() const { return m_size; }
283 :
284 : bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap );
285 : void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap );
286 :
287 : void ThemeChanged();
288 : };
289 :
290 0 : class NWPixmapCacheList
291 : {
292 : public:
293 : ::std::vector< NWPixmapCache* > mCaches;
294 :
295 : void AddCache( NWPixmapCache *pCache );
296 : void RemoveCache( NWPixmapCache *pCache );
297 : void ThemeChanged();
298 : };
299 :
300 : // --- implementation ---
301 :
302 0 : void NWPixmapCacheData::SetPixmap( GdkPixmap* pPixmap )
303 : {
304 0 : if( m_pixmap )
305 0 : g_object_unref( m_pixmap );
306 :
307 0 : m_pixmap = pPixmap;
308 :
309 0 : if( m_pixmap )
310 0 : g_object_ref( m_pixmap );
311 0 : }
312 :
313 0 : NWPixmapCache::NWPixmapCache( SalX11Screen nScreen )
314 : {
315 0 : m_idx = 0;
316 0 : m_size = 0;
317 0 : m_screen = nScreen.getXScreen();
318 0 : pData = NULL;
319 0 : if( gWidgetData[m_screen].gNWPixmapCacheList )
320 0 : gWidgetData[m_screen].gNWPixmapCacheList->AddCache(this);
321 0 : }
322 0 : NWPixmapCache::~NWPixmapCache()
323 : {
324 0 : if( gWidgetData[m_screen].gNWPixmapCacheList )
325 0 : gWidgetData[m_screen].gNWPixmapCacheList->RemoveCache(this);
326 0 : delete[] pData;
327 0 : }
328 0 : void NWPixmapCache::ThemeChanged()
329 : {
330 : // throw away cached pixmaps
331 : int i;
332 0 : for(i=0; i<m_size; i++)
333 0 : pData[i].SetPixmap( NULL );
334 0 : }
335 :
336 0 : bool NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap )
337 : {
338 0 : aState &= ~CTRL_CACHING_ALLOWED; // mask clipping flag
339 : int i;
340 0 : for(i=0; i<m_size; i++)
341 : {
342 0 : if( pData[i].m_nType == aType &&
343 0 : pData[i].m_nState == aState &&
344 0 : pData[i].m_pixmapRect.GetWidth() == r_pixmapRect.GetWidth() &&
345 0 : pData[i].m_pixmapRect.GetHeight() == r_pixmapRect.GetHeight() &&
346 0 : pData[i].m_pixmap != NULL )
347 : {
348 0 : *pPixmap = pData[i].m_pixmap;
349 0 : return true;
350 : }
351 : }
352 0 : return false;
353 : }
354 :
355 0 : void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap )
356 : {
357 0 : if( !(aState & CTRL_CACHING_ALLOWED) )
358 0 : return;
359 :
360 0 : aState &= ~CTRL_CACHING_ALLOWED; // mask clipping flag
361 0 : m_idx = (m_idx+1) % m_size; // just wrap
362 0 : pData[m_idx].m_nType = aType;
363 0 : pData[m_idx].m_nState = aState;
364 0 : pData[m_idx].m_pixmapRect = r_pixmapRect;
365 0 : pData[m_idx].SetPixmap( pPixmap );
366 : }
367 :
368 0 : void NWPixmapCacheList::AddCache( NWPixmapCache* pCache )
369 : {
370 0 : mCaches.push_back( pCache );
371 0 : }
372 0 : void NWPixmapCacheList::RemoveCache( NWPixmapCache* pCache )
373 : {
374 0 : ::std::vector< NWPixmapCache* >::iterator p;
375 0 : p = ::std::find( mCaches.begin(), mCaches.end(), pCache );
376 0 : if( p != mCaches.end() )
377 0 : mCaches.erase( p );
378 0 : }
379 0 : void NWPixmapCacheList::ThemeChanged( )
380 : {
381 0 : ::std::vector< NWPixmapCache* >::iterator p = mCaches.begin();
382 0 : while( p != mCaches.end() )
383 : {
384 0 : (*p)->ThemeChanged();
385 0 : ++p;
386 : }
387 0 : }
388 :
389 : /*********************************************************
390 : * Make border manipulation easier
391 : *********************************************************/
392 0 : inline void NW_gtk_border_set_from_border( GtkBorder& aDst, const GtkBorder * pSrc )
393 : {
394 0 : aDst.left = pSrc->left;
395 0 : aDst.top = pSrc->top;
396 0 : aDst.right = pSrc->right;
397 0 : aDst.bottom = pSrc->bottom;
398 0 : }
399 :
400 : /*********************************************************
401 : * Initialize GTK and local stuff
402 : *********************************************************/
403 0 : void GtkData::initNWF( void )
404 : {
405 0 : ImplSVData* pSVData = ImplGetSVData();
406 :
407 : // draw no border for popup menus (NWF draws its own)
408 0 : pSVData->maNWFData.mbFlatMenu = true;
409 :
410 : // draw separate buttons for toolbox dropdown items
411 0 : pSVData->maNWFData.mbToolboxDropDownSeparate = true;
412 :
413 : // draw toolbars in separate lines
414 0 : pSVData->maNWFData.mbDockingAreaSeparateTB = true;
415 :
416 : // open first menu on F10
417 0 : pSVData->maNWFData.mbOpenMenuOnF10 = true;
418 :
419 : // omit GetNativeControl while painting (see brdwin.cxx)
420 0 : pSVData->maNWFData.mbCanDrawWidgetAnySize = true;
421 :
422 0 : pSVData->maNWFData.mbDDListBoxNoTextArea = true;
423 :
424 0 : int nScreens = GetGtkSalData()->GetGtkDisplay()->GetXScreenCount();
425 0 : gWidgetData = WidgetDataVector( nScreens );
426 0 : for( int i = 0; i < nScreens; i++ )
427 0 : gWidgetData[i].gNWPixmapCacheList = new NWPixmapCacheList;
428 :
429 : // small extra border around menu items
430 0 : NWEnsureGTKMenu( SalX11Screen( 0 ) );
431 0 : gint horizontal_padding = 1;
432 0 : gint vertical_padding = 1;
433 0 : gtk_widget_style_get( gWidgetData[0].gMenuWidget,
434 : "horizontal-padding", &horizontal_padding,
435 0 : (char *)NULL);
436 0 : gtk_widget_style_get( gWidgetData[0].gMenuWidget,
437 : "vertical-padding", &vertical_padding,
438 0 : (char *)NULL);
439 0 : gint xthickness = gWidgetData[0].gMenuWidget->style->xthickness;
440 0 : gint ythickness = gWidgetData[0].gMenuWidget->style->ythickness;
441 0 : pSVData->maNWFData.mnMenuFormatBorderX = xthickness + horizontal_padding;
442 0 : pSVData->maNWFData.mnMenuFormatBorderY = ythickness + vertical_padding;
443 :
444 0 : if( SalGetDesktopEnvironment() == "KDE" )
445 : {
446 : // #i97196# ensure a widget exists and the style engine was loaded
447 0 : NWEnsureGTKButton( SalX11Screen( 0 ) );
448 0 : if( g_type_from_name( "QtEngineStyle" ) )
449 : {
450 : // KDE 3.3 invented a bug in the qt<->gtk theme engine
451 : // that makes direct rendering impossible: they totally
452 : // ignore the clip rectangle passed to the paint methods
453 0 : GtkSalGraphics::bNeedPixmapPaint = true;
454 : }
455 : }
456 0 : static const char* pEnv = getenv( "SAL_GTK_USE_PIXMAPPAINT" );
457 0 : if( pEnv && *pEnv )
458 0 : GtkSalGraphics::bNeedPixmapPaint = true;
459 :
460 : #if OSL_DEBUG_LEVEL > 1
461 : std::fprintf( stderr, "GtkPlugin: using %s NWF\n",
462 : GtkSalGraphics::bNeedPixmapPaint ? "offscreen" : "direct" );
463 : #endif
464 0 : }
465 :
466 : /*********************************************************
467 : * Release GTK and local stuff
468 : *********************************************************/
469 0 : void GtkData::deInitNWF( void )
470 : {
471 0 : for( unsigned int i = 0; i < gWidgetData.size(); i++ )
472 : {
473 : // free up global widgets
474 : // gtk_widget_destroy will in turn destroy the child hierarchy
475 : // so only destroy disjunct hierachies
476 0 : if( gWidgetData[i].gCacheWindow )
477 0 : gtk_widget_destroy( gWidgetData[i].gCacheWindow );
478 0 : if( gWidgetData[i].gMenuWidget )
479 0 : gtk_widget_destroy( gWidgetData[i].gMenuWidget );
480 0 : if( gWidgetData[i].gTooltipPopup )
481 0 : gtk_widget_destroy( gWidgetData[i].gTooltipPopup );
482 0 : if( gWidgetData[i].gDialog )
483 0 : gtk_widget_destroy( gWidgetData[i].gDialog );
484 0 : delete gWidgetData[i].gCacheTabPages;
485 0 : gWidgetData[i].gCacheTabPages = NULL;
486 0 : delete gWidgetData[i].gCacheTabItems;
487 0 : gWidgetData[i].gCacheTabItems = NULL;
488 0 : delete gWidgetData[i].gNWPixmapCacheList;
489 0 : gWidgetData[i].gNWPixmapCacheList = NULL;
490 : }
491 0 : }
492 :
493 : /**********************************************************
494 : * track clip region
495 : **********************************************************/
496 0 : void GtkSalGraphics::ResetClipRegion()
497 : {
498 0 : m_aClipRegion.SetNull();
499 0 : X11SalGraphics::ResetClipRegion();
500 0 : }
501 :
502 0 : bool GtkSalGraphics::setClipRegion( const Region& i_rClip )
503 : {
504 0 : m_aClipRegion = i_rClip;
505 0 : bool bRet = X11SalGraphics::setClipRegion( m_aClipRegion );
506 0 : if( m_aClipRegion.IsEmpty() )
507 0 : m_aClipRegion.SetNull();
508 0 : return bRet;
509 : }
510 :
511 0 : void GtkSalGraphics::copyBits( const SalTwoRect& rPosAry,
512 : SalGraphics* pSrcGraphics )
513 : {
514 0 : GtkSalFrame* pFrame = GetGtkFrame();
515 0 : XLIB_Window aWin = None;
516 0 : if( pFrame && m_pWindow )
517 : {
518 : /* #i64117# some themes set the background pixmap VERY frequently */
519 0 : GdkWindow* pWin = GTK_WIDGET(m_pWindow)->window;
520 0 : if( pWin )
521 : {
522 0 : aWin = GDK_WINDOW_XWINDOW(pWin);
523 0 : if( aWin != None )
524 0 : XSetWindowBackgroundPixmap( pFrame->getDisplay()->GetDisplay(),
525 : aWin,
526 0 : None );
527 : }
528 : }
529 0 : X11SalGraphics::copyBits( rPosAry, pSrcGraphics );
530 0 : if( pFrame && pFrame->getBackgroundPixmap() != None )
531 0 : XSetWindowBackgroundPixmap( pFrame->getDisplay()->GetDisplay(),
532 : aWin,
533 0 : pFrame->getBackgroundPixmap() );
534 0 : }
535 :
536 : /*
537 : * IsNativeControlSupported()
538 : *
539 : * Returns true if the platform supports native
540 : * drawing of the control defined by nPart
541 : */
542 0 : bool GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
543 : {
544 0 : switch(nType)
545 : {
546 : case CTRL_PUSHBUTTON:
547 : case CTRL_RADIOBUTTON:
548 : case CTRL_CHECKBOX:
549 : case CTRL_TOOLTIP:
550 : case CTRL_PROGRESS:
551 : case CTRL_LISTNODE:
552 : case CTRL_LISTNET:
553 0 : if(nPart==PART_ENTIRE_CONTROL)
554 0 : return true;
555 0 : break;
556 :
557 : case CTRL_SCROLLBAR:
558 0 : if(nPart==PART_DRAW_BACKGROUND_HORZ || nPart==PART_DRAW_BACKGROUND_VERT ||
559 0 : nPart==PART_ENTIRE_CONTROL || nPart==HAS_THREE_BUTTONS)
560 0 : return true;
561 0 : break;
562 :
563 : case CTRL_EDITBOX:
564 : case CTRL_MULTILINE_EDITBOX:
565 : case CTRL_COMBOBOX:
566 0 : if(nPart==PART_ENTIRE_CONTROL || nPart==HAS_BACKGROUND_TEXTURE)
567 0 : return true;
568 0 : break;
569 :
570 : case CTRL_SPINBOX:
571 0 : if(nPart==PART_ENTIRE_CONTROL || nPart==PART_ALL_BUTTONS || nPart==HAS_BACKGROUND_TEXTURE)
572 0 : return true;
573 0 : break;
574 :
575 : case CTRL_SPINBUTTONS:
576 0 : if(nPart==PART_ENTIRE_CONTROL || nPart==PART_ALL_BUTTONS)
577 0 : return true;
578 0 : break;
579 :
580 : case CTRL_FRAME:
581 : case CTRL_WINDOW_BACKGROUND:
582 0 : return true;
583 :
584 : case CTRL_TAB_ITEM:
585 : case CTRL_TAB_PANE:
586 : case CTRL_TAB_BODY:
587 0 : if(nPart==PART_ENTIRE_CONTROL || nPart==PART_TABS_DRAW_RTL)
588 0 : return true;
589 0 : break;
590 :
591 : case CTRL_LISTBOX:
592 0 : if(nPart==PART_ENTIRE_CONTROL || nPart==PART_WINDOW || nPart==HAS_BACKGROUND_TEXTURE)
593 0 : return true;
594 0 : break;
595 :
596 : case CTRL_TOOLBAR:
597 0 : if( nPart==PART_ENTIRE_CONTROL
598 0 : || nPart==PART_DRAW_BACKGROUND_HORZ
599 0 : || nPart==PART_DRAW_BACKGROUND_VERT
600 0 : || nPart==PART_THUMB_HORZ
601 0 : || nPart==PART_THUMB_VERT
602 0 : || nPart==PART_BUTTON
603 0 : || nPart==PART_SEPARATOR_HORZ
604 0 : || nPart==PART_SEPARATOR_VERT
605 : )
606 0 : return true;
607 0 : break;
608 :
609 : case CTRL_MENUBAR:
610 0 : if(nPart==PART_ENTIRE_CONTROL || nPart==PART_MENU_ITEM)
611 0 : return true;
612 0 : break;
613 :
614 : case CTRL_MENU_POPUP:
615 0 : if (nPart==PART_ENTIRE_CONTROL
616 0 : || nPart==PART_MENU_ITEM
617 0 : || nPart==PART_MENU_ITEM_CHECK_MARK
618 0 : || nPart==PART_MENU_ITEM_RADIO_MARK
619 0 : || nPart==PART_MENU_SEPARATOR
620 0 : || nPart==PART_MENU_SUBMENU_ARROW
621 : )
622 0 : return true;
623 0 : break;
624 :
625 : case CTRL_SLIDER:
626 0 : if(nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA)
627 0 : return true;
628 0 : break;
629 :
630 : case CTRL_FIXEDLINE:
631 0 : if(nPart == PART_SEPARATOR_VERT || nPart == PART_SEPARATOR_HORZ)
632 0 : return true;
633 0 : break;
634 :
635 : case CTRL_LISTHEADER:
636 0 : if(nPart == PART_BUTTON || nPart == PART_ARROW)
637 0 : return true;
638 0 : break;
639 : }
640 :
641 0 : return false;
642 : }
643 :
644 : /*
645 : * HitTestNativeControl()
646 : *
647 : * bIsInside is set to true if aPos is contained within the
648 : * given part of the control, whose bounding region is
649 : * given by rControlRegion (in VCL frame coordinates).
650 : *
651 : * returns whether bIsInside was really set.
652 : */
653 0 : bool GtkSalGraphics::hitTestNativeControl( ControlType nType,
654 : ControlPart nPart,
655 : const Rectangle& rControlRegion,
656 : const Point& aPos,
657 : bool& rIsInside )
658 : {
659 0 : if ( ( nType == CTRL_SCROLLBAR ) &&
660 0 : ( ( nPart == PART_BUTTON_UP ) ||
661 0 : ( nPart == PART_BUTTON_DOWN ) ||
662 0 : ( nPart == PART_BUTTON_LEFT ) ||
663 : ( nPart == PART_BUTTON_RIGHT ) ) )
664 : {
665 0 : NWEnsureGTKScrollbars( m_nXScreen );
666 :
667 : // Grab some button style attributes
668 : gboolean has_forward;
669 : gboolean has_forward2;
670 : gboolean has_backward;
671 : gboolean has_backward2;
672 :
673 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget,
674 : "has-forward-stepper", &has_forward,
675 : "has-secondary-forward-stepper", &has_forward2,
676 : "has-backward-stepper", &has_backward,
677 : "has-secondary-backward-stepper", &has_backward2,
678 0 : (char *)NULL );
679 0 : Rectangle aForward;
680 0 : Rectangle aBackward;
681 :
682 0 : rIsInside = false;
683 :
684 0 : ControlPart nCounterPart = 0;
685 0 : if ( nPart == PART_BUTTON_UP )
686 0 : nCounterPart = PART_BUTTON_DOWN;
687 0 : else if ( nPart == PART_BUTTON_DOWN )
688 0 : nCounterPart = PART_BUTTON_UP;
689 0 : else if ( nPart == PART_BUTTON_LEFT )
690 0 : nCounterPart = PART_BUTTON_RIGHT;
691 0 : else if ( nPart == PART_BUTTON_RIGHT )
692 0 : nCounterPart = PART_BUTTON_LEFT;
693 :
694 0 : aBackward = NWGetScrollButtonRect( m_nXScreen, nPart, rControlRegion );
695 0 : aForward = NWGetScrollButtonRect( m_nXScreen, nCounterPart, rControlRegion );
696 :
697 0 : if ( has_backward && has_forward2 )
698 : {
699 0 : Size aSize( aBackward.GetSize() );
700 0 : if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_DOWN ) )
701 0 : aSize.setHeight( aBackward.GetHeight() / 2 );
702 : else
703 0 : aSize.setWidth( aBackward.GetWidth() / 2 );
704 0 : aBackward.SetSize( aSize );
705 :
706 0 : if ( nPart == PART_BUTTON_DOWN )
707 0 : aBackward.Move( 0, aBackward.GetHeight() / 2 );
708 0 : else if ( nPart == PART_BUTTON_RIGHT )
709 0 : aBackward.Move( aBackward.GetWidth() / 2, 0 );
710 : }
711 :
712 0 : if ( has_backward2 && has_forward )
713 : {
714 0 : Size aSize( aForward.GetSize() );
715 0 : if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_DOWN ) )
716 0 : aSize.setHeight( aForward.GetHeight() / 2 );
717 : else
718 0 : aSize.setWidth( aForward.GetWidth() / 2 );
719 0 : aForward.SetSize( aSize );
720 :
721 0 : if ( nPart == PART_BUTTON_DOWN )
722 0 : aForward.Move( 0, aForward.GetHeight() / 2 );
723 0 : else if ( nPart == PART_BUTTON_RIGHT )
724 0 : aForward.Move( aForward.GetWidth() / 2, 0 );
725 : }
726 :
727 0 : if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_LEFT ) )
728 : {
729 0 : if ( has_backward )
730 0 : rIsInside |= aBackward.IsInside( aPos );
731 0 : if ( has_backward2 )
732 0 : rIsInside |= aForward.IsInside( aPos );
733 : }
734 : else
735 : {
736 0 : if ( has_forward )
737 0 : rIsInside |= aBackward.IsInside( aPos );
738 0 : if ( has_forward2 )
739 0 : rIsInside |= aForward.IsInside( aPos );
740 : }
741 0 : return true;
742 : }
743 :
744 0 : if( IsNativeControlSupported(nType, nPart) )
745 : {
746 0 : rIsInside = rControlRegion.IsInside( aPos );
747 0 : return true;
748 : }
749 : else
750 : {
751 0 : return false;
752 : }
753 : }
754 :
755 : /*
756 : * DrawNativeControl()
757 : *
758 : * Draws the requested control described by nPart/nState.
759 : *
760 : * rControlRegion: The bounding region of the complete control in VCL frame coordinates.
761 : * aValue: An optional value (tristate/numerical/string)
762 : * rCaption: A caption or title string (like button text etc)
763 : */
764 0 : bool GtkSalGraphics::drawNativeControl( ControlType nType,
765 : ControlPart nPart,
766 : const Rectangle& rControlRegion,
767 : ControlState nState,
768 : const ImplControlValue& aValue,
769 : const OUString& rCaption )
770 : {
771 : // get a GC with current clipping region set
772 0 : GetFontGC();
773 :
774 : // theme changed ?
775 0 : if( GtkSalGraphics::bThemeChanged )
776 : {
777 : // invalidate caches
778 0 : for( unsigned int i = 0; i < gWidgetData.size(); i++ )
779 0 : if( gWidgetData[i].gNWPixmapCacheList )
780 0 : gWidgetData[i].gNWPixmapCacheList->ThemeChanged();
781 0 : GtkSalGraphics::bThemeChanged = false;
782 : }
783 :
784 0 : Rectangle aCtrlRect( rControlRegion );
785 0 : Region aClipRegion( m_aClipRegion );
786 0 : if( aClipRegion.IsNull() )
787 0 : aClipRegion = aCtrlRect;
788 :
789 0 : clipList aClip;
790 0 : GdkDrawable* gdkDrawable = GDK_DRAWABLE( GetGdkWindow() );
791 0 : GdkPixmap* pixmap = NULL;
792 0 : Rectangle aPixmapRect;
793 0 : if( ( bNeedPixmapPaint )
794 0 : && nType != CTRL_SCROLLBAR
795 0 : && nType != CTRL_SPINBOX
796 0 : && nType != CTRL_TAB_ITEM
797 0 : && nType != CTRL_TAB_PANE
798 0 : && nType != CTRL_PROGRESS
799 0 : && ! (nType == CTRL_TOOLBAR && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) )
800 : )
801 : {
802 : // make pixmap a little larger since some themes draw decoration
803 : // outside the rectangle, see e.g. checkbox
804 0 : aPixmapRect = Rectangle( Point( aCtrlRect.Left()-1, aCtrlRect.Top()-1 ),
805 0 : Size( aCtrlRect.GetWidth()+2, aCtrlRect.GetHeight()+2) );
806 0 : pixmap = NWGetPixmapFromScreen( aPixmapRect );
807 0 : if( ! pixmap )
808 0 : return false;
809 0 : gdkDrawable = GDK_DRAWABLE( pixmap );
810 0 : aCtrlRect = Rectangle( Point(1,1), aCtrlRect.GetSize() );
811 0 : aClip.push_back( aCtrlRect );
812 : }
813 : else
814 : {
815 0 : RectangleVector aRectangles;
816 0 : aClipRegion.GetRegionRectangles(aRectangles);
817 :
818 0 : for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
819 : {
820 0 : Rectangle aPaintRect = aCtrlRect.GetIntersection(*aRectIter);
821 0 : if( aPaintRect.IsEmpty() )
822 0 : continue;
823 0 : aClip.push_back( aPaintRect );
824 0 : }
825 : }
826 :
827 : assert(gdkDrawable); //rhbz#1050162
828 0 : if (gdkDrawable == 0)
829 0 : return false;
830 :
831 0 : bool returnVal = false;
832 0 : if ( (nType==CTRL_PUSHBUTTON) && (nPart==PART_ENTIRE_CONTROL) )
833 : {
834 0 : returnVal = NWPaintGTKButton( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
835 : }
836 0 : else if ( (nType==CTRL_RADIOBUTTON) && (nPart==PART_ENTIRE_CONTROL) )
837 : {
838 0 : returnVal = NWPaintGTKRadio( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
839 : }
840 0 : else if ( (nType==CTRL_CHECKBOX) && (nPart==PART_ENTIRE_CONTROL) )
841 : {
842 0 : returnVal = NWPaintGTKCheck( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
843 : }
844 0 : else if ( (nType==CTRL_SCROLLBAR) && ((nPart==PART_DRAW_BACKGROUND_HORZ) || (nPart==PART_DRAW_BACKGROUND_VERT)) )
845 : {
846 0 : returnVal = NWPaintGTKScrollbar( nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
847 : }
848 0 : else if ( ((nType==CTRL_EDITBOX) && ((nPart==PART_ENTIRE_CONTROL) || (nPart==HAS_BACKGROUND_TEXTURE)) )
849 0 : || ((nType==CTRL_SPINBOX) && (nPart==HAS_BACKGROUND_TEXTURE))
850 0 : || ((nType==CTRL_COMBOBOX) && (nPart==HAS_BACKGROUND_TEXTURE))
851 0 : || ((nType==CTRL_LISTBOX) && (nPart==HAS_BACKGROUND_TEXTURE)) )
852 : {
853 0 : returnVal = NWPaintGTKEditBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
854 : }
855 0 : else if ( ((nType==CTRL_MULTILINE_EDITBOX) && ((nPart==PART_ENTIRE_CONTROL) || (nPart==HAS_BACKGROUND_TEXTURE)) ) )
856 : {
857 0 : returnVal = NWPaintGTKEditBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
858 : }
859 0 : else if ( ((nType==CTRL_SPINBOX) || (nType==CTRL_SPINBUTTONS))
860 0 : && ((nPart==PART_ENTIRE_CONTROL) || (nPart==PART_ALL_BUTTONS)) )
861 : {
862 0 : returnVal = NWPaintGTKSpinBox( nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
863 : }
864 0 : else if ( (nType == CTRL_COMBOBOX) &&
865 : ( (nPart==PART_ENTIRE_CONTROL)
866 0 : ||(nPart==PART_BUTTON_DOWN)
867 : ) )
868 : {
869 0 : returnVal = NWPaintGTKComboBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
870 : }
871 0 : else if ( (nType==CTRL_TAB_ITEM) || (nType==CTRL_TAB_PANE) || (nType==CTRL_TAB_BODY) )
872 : {
873 0 : if ( nType == CTRL_TAB_BODY )
874 0 : returnVal = true;
875 : else
876 0 : returnVal = NWPaintGTKTabItem( nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption);
877 : }
878 0 : else if ( (nType==CTRL_LISTBOX) && ((nPart==PART_ENTIRE_CONTROL) || (nPart==PART_WINDOW)) )
879 : {
880 0 : returnVal = NWPaintGTKListBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
881 : }
882 0 : else if ( nType== CTRL_TOOLBAR )
883 : {
884 0 : returnVal = NWPaintGTKToolbar( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
885 : }
886 0 : else if ( nType== CTRL_MENUBAR )
887 : {
888 0 : returnVal = NWPaintGTKMenubar( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
889 : }
890 0 : else if( (nType == CTRL_MENU_POPUP)
891 0 : && ( (nPart == PART_ENTIRE_CONTROL)
892 0 : || (nPart == PART_MENU_ITEM)
893 0 : || (nPart == PART_MENU_ITEM_CHECK_MARK)
894 0 : || (nPart == PART_MENU_ITEM_RADIO_MARK)
895 0 : || (nPart == PART_MENU_SEPARATOR)
896 0 : || (nPart == PART_MENU_SUBMENU_ARROW)
897 : )
898 : )
899 : {
900 0 : returnVal = NWPaintGTKPopupMenu( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
901 : }
902 0 : else if( (nType == CTRL_TOOLTIP) && (nPart == PART_ENTIRE_CONTROL) )
903 : {
904 0 : returnVal = NWPaintGTKTooltip( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
905 : }
906 0 : else if( (nType == CTRL_PROGRESS) && (nPart == PART_ENTIRE_CONTROL) )
907 : {
908 0 : returnVal = NWPaintGTKProgress( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
909 : }
910 0 : else if( (nType == CTRL_LISTNODE) && (nPart == PART_ENTIRE_CONTROL) )
911 : {
912 0 : returnVal = NWPaintGTKListNode( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
913 : }
914 0 : else if( (nType == CTRL_LISTNET) && (nPart == PART_ENTIRE_CONTROL) )
915 : {
916 : // don't actually draw anything; gtk treeviews do not draw lines
917 0 : returnVal = TRUE;
918 : }
919 0 : else if( nType == CTRL_SLIDER )
920 : {
921 0 : returnVal = NWPaintGTKSlider( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
922 : }
923 0 : else if( nType == CTRL_WINDOW_BACKGROUND )
924 : {
925 0 : returnVal = NWPaintGTKWindowBackground( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
926 : }
927 0 : else if( nType == CTRL_FIXEDLINE )
928 : {
929 0 : returnVal = NWPaintGTKFixedLine( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
930 : }
931 0 : else if(nType==CTRL_FRAME)
932 : {
933 0 : returnVal = NWPaintGTKFrame( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption);
934 : }
935 0 : else if(nType==CTRL_LISTHEADER)
936 : {
937 0 : if(nPart == PART_BUTTON)
938 0 : returnVal = NWPaintGTKListHeader( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
939 0 : else if(nPart == PART_ARROW)
940 0 : returnVal = NWPaintGTKArrow( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
941 : }
942 :
943 0 : if( pixmap )
944 : {
945 0 : returnVal = NWRenderPixmapToScreen( pixmap, aPixmapRect ) && returnVal;
946 0 : g_object_unref( pixmap );
947 : }
948 :
949 0 : return( returnVal );
950 : }
951 :
952 : /*
953 : * GetNativeControlRegion()
954 : *
955 : * If the return value is true, rNativeBoundingRegion
956 : * contains the true bounding region covered by the control
957 : * including any adornment, while rNativeContentRegion contains the area
958 : * within the control that can be safely drawn into without drawing over
959 : * the borders of the control.
960 : *
961 : * rControlRegion: The bounding region of the control in VCL frame coordinates.
962 : * aValue: An optional value (tristate/numerical/string)
963 : * rCaption: A caption or title string (like button text etc)
964 : */
965 0 : bool GtkSalGraphics::getNativeControlRegion( ControlType nType,
966 : ControlPart nPart,
967 : const Rectangle& rControlRegion,
968 : ControlState nState,
969 : const ImplControlValue& aValue,
970 : const OUString& rCaption,
971 : Rectangle &rNativeBoundingRegion,
972 : Rectangle &rNativeContentRegion )
973 : {
974 0 : bool returnVal = false;
975 :
976 0 : if ( (nType==CTRL_PUSHBUTTON) && (nPart==PART_ENTIRE_CONTROL)
977 0 : && (rControlRegion.GetWidth() > 16)
978 0 : && (rControlRegion.GetHeight() > 16) )
979 : {
980 : rNativeBoundingRegion = NWGetButtonArea( m_nXScreen, nType, nPart, rControlRegion,
981 0 : nState, aValue, rCaption );
982 0 : rNativeContentRegion = rControlRegion;
983 :
984 0 : returnVal = true;
985 : }
986 0 : if (nType == CTRL_TAB_ITEM && nPart == PART_ENTIRE_CONTROL)
987 : {
988 0 : rNativeBoundingRegion = NWGetTabItemRect(m_nXScreen, rControlRegion);
989 0 : rNativeContentRegion = rNativeBoundingRegion;
990 0 : returnVal = true;
991 : }
992 0 : if ( (nType==CTRL_COMBOBOX) && ((nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) )
993 : {
994 : rNativeBoundingRegion = NWGetComboBoxButtonRect( m_nXScreen, nType, nPart, rControlRegion, nState,
995 0 : aValue, rCaption );
996 0 : rNativeContentRegion = rNativeBoundingRegion;
997 :
998 0 : returnVal = true;
999 : }
1000 0 : if ( (nType==CTRL_SPINBOX) && ((nPart==PART_BUTTON_UP) || (nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) )
1001 : {
1002 :
1003 : rNativeBoundingRegion = NWGetSpinButtonRect( m_nXScreen, nType, nPart, rControlRegion, nState,
1004 0 : aValue, rCaption );
1005 0 : rNativeContentRegion = rNativeBoundingRegion;
1006 :
1007 0 : returnVal = true;
1008 : }
1009 0 : if ( (nType==CTRL_LISTBOX) && ((nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) )
1010 : {
1011 : rNativeBoundingRegion = NWGetListBoxButtonRect( m_nXScreen, nType, nPart, rControlRegion, nState,
1012 0 : aValue, rCaption );
1013 0 : rNativeContentRegion = rNativeBoundingRegion;
1014 :
1015 0 : returnVal = true;
1016 : }
1017 0 : if ( (nType==CTRL_TOOLBAR) &&
1018 0 : ((nPart==PART_DRAW_BACKGROUND_HORZ) ||
1019 0 : (nPart==PART_DRAW_BACKGROUND_VERT) ||
1020 0 : (nPart==PART_THUMB_HORZ) ||
1021 0 : (nPart==PART_THUMB_VERT) ||
1022 : (nPart==PART_BUTTON)
1023 : ))
1024 : {
1025 0 : rNativeBoundingRegion = NWGetToolbarRect( m_nXScreen, nType, nPart, rControlRegion, nState, aValue, rCaption );
1026 0 : rNativeContentRegion = rNativeBoundingRegion;
1027 0 : returnVal = true;
1028 : }
1029 0 : if ( (nType==CTRL_SCROLLBAR) && ((nPart==PART_BUTTON_LEFT) || (nPart==PART_BUTTON_RIGHT) ||
1030 0 : (nPart==PART_BUTTON_UP) || (nPart==PART_BUTTON_DOWN) ) )
1031 : {
1032 0 : rNativeBoundingRegion = NWGetScrollButtonRect( m_nXScreen, nPart, rControlRegion );
1033 0 : rNativeContentRegion = rNativeBoundingRegion;
1034 :
1035 : //See fdo#33523, possibly makes sense to do this test for all return values
1036 0 : if (!rNativeContentRegion.GetWidth())
1037 0 : rNativeContentRegion.Right() = rNativeContentRegion.Left() + 1;
1038 0 : if (!rNativeContentRegion.GetHeight())
1039 0 : rNativeContentRegion.Bottom() = rNativeContentRegion.Top() + 1;
1040 0 : returnVal = true;
1041 : }
1042 0 : if( (nType == CTRL_MENUBAR) && (nPart == PART_ENTIRE_CONTROL) )
1043 : {
1044 0 : NWEnsureGTKMenubar( m_nXScreen );
1045 : GtkRequisition aReq;
1046 0 : gtk_widget_size_request( gWidgetData[m_nXScreen].gMenubarWidget, &aReq );
1047 0 : Rectangle aMenuBarRect = rControlRegion;
1048 : aMenuBarRect = Rectangle( aMenuBarRect.TopLeft(),
1049 0 : Size( aMenuBarRect.GetWidth(), aReq.height+1 ) );
1050 0 : rNativeBoundingRegion = aMenuBarRect;
1051 0 : rNativeContentRegion = rNativeBoundingRegion;
1052 0 : returnVal = true;
1053 : }
1054 0 : if( nType == CTRL_MENU_POPUP )
1055 : {
1056 0 : if( (nPart == PART_MENU_ITEM_CHECK_MARK) ||
1057 : (nPart == PART_MENU_ITEM_RADIO_MARK) )
1058 : {
1059 0 : NWEnsureGTKMenu( m_nXScreen );
1060 :
1061 0 : gint indicator_size = 0;
1062 : GtkWidget* pWidget = (nPart == PART_MENU_ITEM_CHECK_MARK) ?
1063 0 : gWidgetData[m_nXScreen].gMenuItemCheckMenuWidget : gWidgetData[m_nXScreen].gMenuItemRadioMenuWidget;
1064 : gtk_widget_style_get( pWidget,
1065 : "indicator_size", &indicator_size,
1066 0 : (char *)NULL );
1067 0 : rNativeBoundingRegion = rControlRegion;
1068 : Rectangle aIndicatorRect( Point( 0,
1069 0 : (rControlRegion.GetHeight()-indicator_size)/2),
1070 0 : Size( indicator_size, indicator_size ) );
1071 0 : rNativeContentRegion = aIndicatorRect;
1072 0 : returnVal = true;
1073 : }
1074 0 : else if( nPart == PART_MENU_SUBMENU_ARROW )
1075 : {
1076 0 : GtkWidget* widget = gWidgetData[m_nXScreen].gMenuItemMenuWidget;
1077 : GtkWidget* child;
1078 : PangoContext *context;
1079 : PangoFontMetrics *metrics;
1080 : gint arrow_size;
1081 : gint arrow_extent;
1082 : guint horizontal_padding;
1083 0 : gfloat arrow_scaling = 0.4; // Default for early GTK versions
1084 :
1085 : gtk_widget_style_get( widget,
1086 : "horizontal-padding", &horizontal_padding,
1087 0 : NULL );
1088 :
1089 : // Use arrow-scaling property if available (2.15+), avoid warning otherwise
1090 0 : if ( gtk_widget_class_find_style_property( GTK_WIDGET_GET_CLASS( widget ),
1091 0 : "arrow-scaling" ) )
1092 : {
1093 : gtk_widget_style_get( widget,
1094 : "arrow-scaling", &arrow_scaling,
1095 0 : NULL );
1096 : }
1097 :
1098 0 : child = GTK_BIN( widget )->child;
1099 :
1100 0 : context = gtk_widget_get_pango_context( child );
1101 : metrics = pango_context_get_metrics( context,
1102 : child->style->font_desc,
1103 0 : pango_context_get_language( context ) );
1104 :
1105 0 : arrow_size = ( PANGO_PIXELS( pango_font_metrics_get_ascent( metrics ) +
1106 0 : pango_font_metrics_get_descent( metrics ) ));
1107 :
1108 0 : pango_font_metrics_unref( metrics );
1109 :
1110 0 : arrow_extent = static_cast<gint>(arrow_size * arrow_scaling);
1111 :
1112 : rNativeContentRegion = Rectangle( Point( 0, 0 ),
1113 0 : Size( arrow_extent, arrow_extent ));
1114 : rNativeBoundingRegion = Rectangle( Point( 0, 0 ),
1115 0 : Size( arrow_extent + horizontal_padding, arrow_extent ));
1116 0 : returnVal = true;
1117 : }
1118 : }
1119 0 : if( (nType == CTRL_RADIOBUTTON || nType == CTRL_CHECKBOX) )
1120 : {
1121 0 : NWEnsureGTKRadio( m_nXScreen );
1122 0 : NWEnsureGTKCheck( m_nXScreen );
1123 0 : GtkWidget* widget = (nType == CTRL_RADIOBUTTON) ? gWidgetData[m_nXScreen].gRadioWidget : gWidgetData[m_nXScreen].gCheckWidget;
1124 : gint indicator_size, indicator_spacing, focusPad, focusWidth;
1125 : gtk_widget_style_get( widget,
1126 : "indicator_size", &indicator_size,
1127 : "indicator_spacing", &indicator_spacing,
1128 : "focus-line-width", &focusWidth,
1129 : "focus-padding", &focusPad,
1130 0 : (char *)NULL);
1131 0 : indicator_size += 2*indicator_spacing + 2*(focusWidth + focusWidth);
1132 0 : rNativeBoundingRegion = rControlRegion;
1133 : Rectangle aIndicatorRect( Point( 0,
1134 0 : (rControlRegion.GetHeight()-indicator_size)/2),
1135 0 : Size( indicator_size, indicator_size ) );
1136 0 : rNativeContentRegion = aIndicatorRect;
1137 0 : returnVal = true;
1138 : }
1139 0 : if( (nType == CTRL_EDITBOX || nType == CTRL_SPINBOX || nType == CTRL_COMBOBOX) && nPart == PART_ENTIRE_CONTROL )
1140 : {
1141 0 : NWEnsureGTKEditBox( m_nXScreen );
1142 0 : GtkWidget* widget = gWidgetData[m_nXScreen].gEditBoxWidget;
1143 : GtkRequisition aReq;
1144 0 : gtk_widget_size_request( widget, &aReq );
1145 0 : Rectangle aEditRect = rControlRegion;
1146 0 : long nHeight = (aEditRect.GetHeight() > aReq.height) ? aEditRect.GetHeight() : aReq.height;
1147 : aEditRect = Rectangle( aEditRect.TopLeft(),
1148 0 : Size( aEditRect.GetWidth(), nHeight ) );
1149 0 : rNativeBoundingRegion = aEditRect;
1150 0 : rNativeContentRegion = rNativeBoundingRegion;
1151 0 : returnVal = true;
1152 : }
1153 0 : if( (nType == CTRL_SLIDER) && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) )
1154 : {
1155 0 : NWEnsureGTKSlider( m_nXScreen );
1156 0 : GtkWidget* widget = (nPart == PART_THUMB_HORZ) ? gWidgetData[m_nXScreen].gHScale : gWidgetData[m_nXScreen].gVScale;
1157 0 : gint slider_length = 10;
1158 0 : gint slider_width = 10;
1159 : gtk_widget_style_get( widget,
1160 : "slider-width", &slider_width,
1161 : "slider-length", &slider_length,
1162 0 : (char *)NULL);
1163 0 : Rectangle aRect( rControlRegion );
1164 0 : if( nPart == PART_THUMB_HORZ )
1165 : {
1166 0 : aRect.Right() = aRect.Left() + slider_length - 1;
1167 0 : aRect.Bottom() = aRect.Top() + slider_width - 1;
1168 : }
1169 : else
1170 : {
1171 0 : aRect.Bottom() = aRect.Top() + slider_length - 1;
1172 0 : aRect.Right() = aRect.Left() + slider_width - 1;
1173 : }
1174 0 : rNativeBoundingRegion = rNativeContentRegion = aRect;
1175 0 : returnVal = true;
1176 : }
1177 0 : if( nType == CTRL_FRAME && nPart == PART_BORDER )
1178 : {
1179 0 : int frameWidth = getFrameWidth(gWidgetData[m_nXScreen].gFrame);
1180 0 : rNativeBoundingRegion = rControlRegion;
1181 0 : sal_uInt16 nStyle = aValue.getNumericVal();
1182 0 : int x1=rControlRegion.Left();
1183 0 : int y1=rControlRegion.Top();
1184 0 : int x2=rControlRegion.Right();
1185 0 : int y2=rControlRegion.Bottom();
1186 :
1187 0 : if( nStyle & FRAME_DRAW_NODRAW )
1188 : {
1189 0 : rNativeContentRegion = Rectangle(x1+frameWidth,
1190 0 : y1+frameWidth,
1191 0 : x2-frameWidth,
1192 0 : y2-frameWidth);
1193 : }
1194 : else
1195 0 : rNativeContentRegion = rControlRegion;
1196 0 : returnVal=true;
1197 : }
1198 :
1199 0 : return( returnVal );
1200 : }
1201 :
1202 : /************************************************************************
1203 : * Individual control drawing functions
1204 : ************************************************************************/
1205 0 : bool GtkSalGraphics::NWPaintGTKArrow(
1206 : GdkDrawable* gdkDrawable,
1207 : ControlType, ControlPart,
1208 : const Rectangle& rControlRectangle,
1209 : const clipList& rClipList,
1210 : ControlState nState, const ImplControlValue& aValue,
1211 : const OUString& )
1212 : {
1213 0 : GtkArrowType arrowType(aValue.getNumericVal()&1?GTK_ARROW_DOWN:GTK_ARROW_UP);
1214 0 : GtkStateType stateType(nState&CTRL_STATE_PRESSED?GTK_STATE_ACTIVE:GTK_STATE_NORMAL);
1215 :
1216 : GdkRectangle clipRect;
1217 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
1218 : {
1219 0 : clipRect.x = it->Left();
1220 0 : clipRect.y = it->Top();
1221 0 : clipRect.width = it->GetWidth();
1222 0 : clipRect.height = it->GetHeight();
1223 :
1224 : gtk_paint_arrow(m_pWindow->style,gdkDrawable,stateType,GTK_SHADOW_NONE,&clipRect,
1225 : m_pWindow,"arrow",arrowType,true,
1226 0 : rControlRectangle.Left(),
1227 0 : rControlRectangle.Top(),
1228 0 : rControlRectangle.GetWidth(),
1229 0 : rControlRectangle.GetHeight());
1230 : }
1231 0 : return true;
1232 : }
1233 :
1234 0 : bool GtkSalGraphics::NWPaintGTKListHeader(
1235 : GdkDrawable* gdkDrawable,
1236 : ControlType, ControlPart,
1237 : const Rectangle& rControlRectangle,
1238 : const clipList& rClipList,
1239 : ControlState nState, const ImplControlValue&,
1240 : const OUString& )
1241 : {
1242 : GtkStateType stateType;
1243 : GtkShadowType shadowType;
1244 0 : NWEnsureGTKTreeView( m_nXScreen );
1245 0 : GtkWidget* &treeview(gWidgetData[m_nXScreen].gTreeView);
1246 0 : GtkTreeViewColumn* column=gtk_tree_view_get_column(GTK_TREE_VIEW(treeview),0);
1247 0 : GtkWidget* button=gtk_tree_view_column_get_widget(column);
1248 0 : while(button && !GTK_IS_BUTTON(button))
1249 0 : button=gtk_widget_get_parent(button);
1250 0 : if(!button)
1251 : // Shouldn't ever happen
1252 0 : return false;
1253 0 : gtk_widget_realize(button);
1254 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
1255 0 : NWSetWidgetState( button, nState, stateType );
1256 :
1257 : GdkRectangle clipRect;
1258 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
1259 : {
1260 0 : clipRect.x = it->Left();
1261 0 : clipRect.y = it->Top();
1262 0 : clipRect.width = it->GetWidth();
1263 0 : clipRect.height = it->GetHeight();
1264 :
1265 : gtk_paint_box(button->style,gdkDrawable,stateType,shadowType,&clipRect,
1266 : button,"button",
1267 0 : rControlRectangle.Left()-1,
1268 0 : rControlRectangle.Top(),
1269 0 : rControlRectangle.GetWidth()+1,
1270 0 : rControlRectangle.GetHeight());
1271 : }
1272 0 : return true;
1273 : }
1274 :
1275 0 : bool GtkSalGraphics::NWPaintGTKFixedLine(
1276 : GdkDrawable* gdkDrawable,
1277 : ControlType, ControlPart nPart,
1278 : const Rectangle& rControlRectangle,
1279 : const clipList&,
1280 : ControlState, const ImplControlValue&,
1281 : const OUString& )
1282 : {
1283 0 : if(nPart == PART_SEPARATOR_HORZ)
1284 0 : gtk_paint_hline(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,NULL,m_pWindow,"hseparator",rControlRectangle.Left(),rControlRectangle.Right(),rControlRectangle.Top());
1285 : else
1286 0 : gtk_paint_vline(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,NULL,m_pWindow,"vseparator",rControlRectangle.Top(),rControlRectangle.Bottom(),rControlRectangle.Left());
1287 :
1288 0 : return true;
1289 : }
1290 :
1291 0 : bool GtkSalGraphics::NWPaintGTKFrame(
1292 : GdkDrawable* gdkDrawable,
1293 : ControlType, ControlPart,
1294 : const Rectangle& rControlRectangle,
1295 : const clipList& rClipList,
1296 : ControlState /* nState */, const ImplControlValue& aValue,
1297 : const OUString& )
1298 : {
1299 : GdkRectangle clipRect;
1300 0 : int frameWidth=getFrameWidth(gWidgetData[m_nXScreen].gFrame);
1301 0 : GtkShadowType shadowType=GTK_SHADOW_IN;
1302 0 : sal_uInt16 nStyle = aValue.getNumericVal();
1303 0 : if( nStyle & FRAME_DRAW_IN )
1304 0 : shadowType=GTK_SHADOW_OUT;
1305 0 : if( nStyle & FRAME_DRAW_OUT )
1306 0 : shadowType=GTK_SHADOW_IN;
1307 :
1308 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
1309 : {
1310 0 : clipRect.x = it->Left();
1311 0 : clipRect.y = it->Top();
1312 0 : clipRect.width = it->GetWidth();
1313 0 : clipRect.height = it->GetHeight();
1314 :
1315 : // Draw background first
1316 :
1317 : // Top
1318 : gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
1319 : m_pWindow,"base",
1320 0 : rControlRectangle.Left(),
1321 0 : rControlRectangle.Top(),
1322 0 : rControlRectangle.GetWidth(),
1323 0 : frameWidth);
1324 : // Bottom
1325 : gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
1326 : m_pWindow,"base",
1327 0 : rControlRectangle.Left(),
1328 0 : rControlRectangle.Top()+rControlRectangle.GetHeight()-frameWidth,
1329 0 : rControlRectangle.GetWidth(),
1330 0 : frameWidth);
1331 : // Left
1332 : gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
1333 : m_pWindow,"base",
1334 0 : rControlRectangle.Left(),
1335 0 : rControlRectangle.Top(),
1336 : 2*frameWidth,
1337 0 : rControlRectangle.GetHeight());
1338 : // Right
1339 : gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
1340 : m_pWindow,"base",
1341 0 : rControlRectangle.Left()+rControlRectangle.GetWidth()-frameWidth,
1342 0 : rControlRectangle.Top(),
1343 : 2*frameWidth,
1344 0 : rControlRectangle.GetHeight());
1345 :
1346 : // Now render the frame
1347 0 : gtk_paint_shadow(gWidgetData[m_nXScreen].gFrame->style,gdkDrawable,GTK_STATE_NORMAL,shadowType,&clipRect,
1348 0 : gWidgetData[m_nXScreen].gFrame,"base",
1349 0 : rControlRectangle.Left(),
1350 0 : rControlRectangle.Top(),
1351 0 : rControlRectangle.GetWidth(),
1352 0 : rControlRectangle.GetHeight());
1353 : }
1354 :
1355 0 : return true;
1356 : }
1357 :
1358 0 : bool GtkSalGraphics::NWPaintGTKWindowBackground(
1359 : GdkDrawable* gdkDrawable,
1360 : ControlType, ControlPart,
1361 : const Rectangle& /* rControlRectangle */,
1362 : const clipList& rClipList,
1363 : ControlState /* nState */, const ImplControlValue&,
1364 : const OUString& )
1365 : {
1366 : int w,h;
1367 0 : gtk_window_get_size(GTK_WINDOW(m_pWindow),&w,&h);
1368 : GdkRectangle clipRect;
1369 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
1370 : {
1371 0 : clipRect.x = it->Left();
1372 0 : clipRect.y = it->Top();
1373 0 : clipRect.width = it->GetWidth();
1374 0 : clipRect.height = it->GetHeight();
1375 :
1376 0 : gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_NONE,&clipRect,m_pWindow,"base",0,0,w,h);
1377 : }
1378 :
1379 0 : return true;
1380 : }
1381 :
1382 0 : bool GtkSalGraphics::NWPaintGTKButtonReal(
1383 : GtkWidget* button,
1384 : GdkDrawable* gdkDrawable,
1385 : ControlType, ControlPart,
1386 : const Rectangle& rControlRectangle,
1387 : const clipList& rClipList,
1388 : ControlState nState, const ImplControlValue&,
1389 : const OUString& )
1390 : {
1391 : GtkStateType stateType;
1392 : GtkShadowType shadowType;
1393 : gboolean interiorFocus;
1394 : gint focusWidth;
1395 : gint focusPad;
1396 0 : bool bDrawFocus = true;
1397 : gint x, y, w, h;
1398 : GtkBorder aDefBorder;
1399 : GtkBorder* pBorder;
1400 : GdkRectangle clipRect;
1401 :
1402 0 : NWEnsureGTKButton( m_nXScreen );
1403 0 : NWEnsureGTKToolbar( m_nXScreen );
1404 :
1405 : // Flat toolbutton has a bit bigger variety of states than normal buttons, so handle it differently
1406 0 : if(GTK_IS_TOGGLE_BUTTON(button))
1407 : {
1408 0 : if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
1409 0 : shadowType=GTK_SHADOW_IN;
1410 : else
1411 0 : shadowType=GTK_SHADOW_OUT;
1412 :
1413 0 : if(nState & CTRL_STATE_ROLLOVER)
1414 0 : stateType=GTK_STATE_PRELIGHT;
1415 : else
1416 0 : stateType=GTK_STATE_NORMAL;
1417 :
1418 0 : if(nState & CTRL_STATE_PRESSED)
1419 : {
1420 0 : stateType=GTK_STATE_ACTIVE;
1421 0 : shadowType=GTK_SHADOW_IN;
1422 : }
1423 : }
1424 : else
1425 : {
1426 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
1427 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
1428 : }
1429 :
1430 0 : x = rControlRectangle.Left();
1431 0 : y = rControlRectangle.Top();
1432 0 : w = rControlRectangle.GetWidth();
1433 0 : h = rControlRectangle.GetHeight();
1434 :
1435 0 : gint internal_padding = 0;
1436 0 : if(GTK_IS_TOOL_ITEM(button))
1437 : {
1438 0 : gtk_widget_style_get (GTK_WIDGET (gWidgetData[m_nXScreen].gToolbarWidget),
1439 : "internal-padding", &internal_padding,
1440 0 : NULL);
1441 0 : x += internal_padding/2;
1442 0 : w -= internal_padding;
1443 0 : stateType = GTK_STATE_PRELIGHT;
1444 : }
1445 :
1446 : // Grab some button style attributes
1447 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gBtnWidget, "focus-line-width", &focusWidth,
1448 : "focus-padding", &focusPad,
1449 : "interior_focus", &interiorFocus,
1450 0 : (char *)NULL );
1451 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gBtnWidget,
1452 : "default_border", &pBorder,
1453 0 : (char *)NULL );
1454 :
1455 : // Make sure the border values exist, otherwise use some defaults
1456 0 : if ( pBorder )
1457 : {
1458 0 : NW_gtk_border_set_from_border( aDefBorder, pBorder );
1459 0 : gtk_border_free( pBorder );
1460 : }
1461 0 : else NW_gtk_border_set_from_border( aDefBorder, &aDefDefBorder );
1462 :
1463 : // If the button is too small, don't ever draw focus or grab more space
1464 0 : if ( (w < 16) || (h < 16) )
1465 0 : bDrawFocus = false;
1466 :
1467 0 : gint xi = x, yi = y, wi = w, hi = h;
1468 0 : if ( (nState & CTRL_STATE_DEFAULT) && bDrawFocus )
1469 : {
1470 0 : xi += aDefBorder.left;
1471 0 : yi += aDefBorder.top;
1472 0 : wi -= aDefBorder.left + aDefBorder.right;
1473 0 : hi -= aDefBorder.top + aDefBorder.bottom;
1474 : }
1475 :
1476 0 : if ( !interiorFocus && bDrawFocus )
1477 : {
1478 0 : xi += focusWidth + focusPad;
1479 0 : yi += focusWidth + focusPad;
1480 0 : wi -= 2 * (focusWidth + focusPad);
1481 0 : hi -= 2 * (focusWidth + focusPad);
1482 : }
1483 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it)
1484 : {
1485 0 : clipRect.x = it->Left();
1486 0 : clipRect.y = it->Top();
1487 0 : clipRect.width = it->GetWidth();
1488 0 : clipRect.height = it->GetHeight();
1489 :
1490 : // Buttons must paint opaque since some themes have alpha-channel enabled buttons
1491 0 : if(button == gWidgetData[m_nXScreen].gToolbarButtonWidget)
1492 : {
1493 0 : gtk_paint_box( gWidgetData[m_nXScreen].gToolbarWidget->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
1494 0 : &clipRect, gWidgetData[m_nXScreen].gToolbarWidget, "toolbar", x, y, w, h );
1495 : }
1496 : else
1497 : {
1498 : gtk_paint_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
1499 0 : &clipRect, m_pWindow, "base", x, y, w, h );
1500 : }
1501 :
1502 0 : if ( GTK_IS_BUTTON(button) )
1503 : {
1504 0 : if ( (nState & CTRL_STATE_DEFAULT) )
1505 : gtk_paint_box( button->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
1506 0 : &clipRect, button, "buttondefault", x, y, w, h );
1507 :
1508 : /* don't draw "button", because it can be a tool_button, and
1509 : * it causes some weird things, so, the default button is
1510 : * just fine */
1511 : gtk_paint_box( button->style, gdkDrawable, stateType, shadowType,
1512 0 : &clipRect, button, "button", xi, yi, wi, hi );
1513 : }
1514 : }
1515 :
1516 0 : return true;
1517 : }
1518 :
1519 0 : bool GtkSalGraphics::NWPaintGTKButton(
1520 : GdkDrawable* gdkDrawable,
1521 : ControlType type, ControlPart part,
1522 : const Rectangle& rControlRectangle,
1523 : const clipList& rClipList,
1524 : ControlState nState, const ImplControlValue& value,
1525 : const OUString& string)
1526 : {
1527 : return NWPaintGTKButtonReal(
1528 0 : gWidgetData[m_nXScreen].gBtnWidget,
1529 : gdkDrawable,
1530 : type, part,
1531 : rControlRectangle,
1532 : rClipList,
1533 : nState, value,
1534 0 : string );
1535 : }
1536 :
1537 0 : static Rectangle NWGetButtonArea( SalX11Screen nScreen,
1538 : ControlType, ControlPart, Rectangle aAreaRect, ControlState nState,
1539 : const ImplControlValue&, const OUString& )
1540 : {
1541 : gboolean interiorFocus;
1542 : gint focusWidth;
1543 : gint focusPad;
1544 : GtkBorder aDefBorder;
1545 : GtkBorder * pBorder;
1546 0 : bool bDrawFocus = true;
1547 0 : Rectangle aRect;
1548 : gint x, y, w, h;
1549 :
1550 0 : NWEnsureGTKButton( nScreen );
1551 0 : gtk_widget_style_get( gWidgetData[nScreen].gBtnWidget,
1552 : "focus-line-width", &focusWidth,
1553 : "focus-padding", &focusPad,
1554 : "interior_focus", &interiorFocus,
1555 : "default_border", &pBorder,
1556 0 : (char *)NULL );
1557 :
1558 : // Make sure the border values exist, otherwise use some defaults
1559 0 : if ( pBorder )
1560 : {
1561 0 : NW_gtk_border_set_from_border( aDefBorder, pBorder );
1562 0 : gtk_border_free( pBorder );
1563 : }
1564 0 : else NW_gtk_border_set_from_border( aDefBorder, &aDefDefBorder );
1565 :
1566 0 : x = aAreaRect.Left();
1567 0 : y = aAreaRect.Top();
1568 0 : w = aAreaRect.GetWidth();
1569 0 : h = aAreaRect.GetHeight();
1570 :
1571 : // If the button is too small, don't ever draw focus or grab more space
1572 0 : if ( (w < 16) || (h < 16) )
1573 0 : bDrawFocus = false;
1574 :
1575 0 : if ( (nState & CTRL_STATE_DEFAULT) && bDrawFocus )
1576 : {
1577 0 : x -= aDefBorder.left;
1578 0 : y -= aDefBorder.top;
1579 0 : w += aDefBorder.left + aDefBorder.right;
1580 0 : h += aDefBorder.top + aDefBorder.bottom;
1581 : }
1582 :
1583 0 : aRect = Rectangle( Point( x, y ), Size( w, h ) );
1584 :
1585 0 : return( aRect );
1586 : }
1587 :
1588 0 : static Rectangle NWGetTabItemRect( SalX11Screen nScreen, Rectangle aAreaRect )
1589 : {
1590 0 : NWEnsureGTKNotebook( nScreen );
1591 :
1592 : gint x, y, w, h;
1593 :
1594 0 : x = aAreaRect.Left();
1595 0 : y = aAreaRect.Top();
1596 0 : w = aAreaRect.GetWidth();
1597 0 : h = aAreaRect.GetHeight();
1598 :
1599 0 : gint xthickness = gWidgetData[nScreen].gNotebookWidget->style->xthickness;
1600 0 : gint ythickness = gWidgetData[nScreen].gNotebookWidget->style->ythickness;
1601 :
1602 0 : x -= xthickness;
1603 0 : y -= ythickness;
1604 0 : w += xthickness*2;
1605 0 : h += ythickness*2;
1606 :
1607 0 : return Rectangle( Point( x, y ), Size( w, h ) );
1608 : }
1609 :
1610 0 : bool GtkSalGraphics::NWPaintGTKRadio( GdkDrawable* gdkDrawable,
1611 : ControlType, ControlPart,
1612 : const Rectangle& rControlRectangle,
1613 : const clipList& rClipList,
1614 : ControlState nState,
1615 : const ImplControlValue& aValue,
1616 : const OUString& )
1617 : {
1618 : GtkStateType stateType;
1619 : GtkShadowType shadowType;
1620 0 : bool isChecked = (aValue.getTristateVal()==BUTTONVALUE_ON);
1621 : gint x, y;
1622 : GdkRectangle clipRect;
1623 :
1624 0 : NWEnsureGTKButton( m_nXScreen );
1625 0 : NWEnsureGTKRadio( m_nXScreen );
1626 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
1627 :
1628 : gint indicator_size;
1629 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gRadioWidget, "indicator_size", &indicator_size, (char *)NULL);
1630 :
1631 0 : x = rControlRectangle.Left() + (rControlRectangle.GetWidth()-indicator_size)/2;
1632 0 : y = rControlRectangle.Top() + (rControlRectangle.GetHeight()-indicator_size)/2;
1633 :
1634 : // Set the shadow based on if checked or not so we get a freakin checkmark.
1635 0 : shadowType = isChecked ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
1636 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gRadioWidget, nState, stateType );
1637 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gRadioWidgetSibling, nState, stateType );
1638 :
1639 : // GTK enforces radio groups, so that if we don't have 2 buttons in the group,
1640 : // the single button will always be active. So we have to have 2 buttons.
1641 :
1642 : // #i59666# set the members directly where we should use
1643 : // gtk_toggle_button_set_active. reason: there are animated themes
1644 : // which are in active state only after a while leading to painting
1645 : // intermediate states between active/inactive. Let's hope that
1646 : // GtkToggleButtone stays binary compatible.
1647 0 : if (!isChecked)
1648 0 : GTK_TOGGLE_BUTTON(gWidgetData[m_nXScreen].gRadioWidgetSibling)->active = true;
1649 0 : GTK_TOGGLE_BUTTON(gWidgetData[m_nXScreen].gRadioWidget)->active = isChecked;
1650 :
1651 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
1652 : {
1653 0 : clipRect.x = it->Left();
1654 0 : clipRect.y = it->Top();
1655 0 : clipRect.width = it->GetWidth();
1656 0 : clipRect.height = it->GetHeight();
1657 :
1658 0 : gtk_paint_option( gWidgetData[m_nXScreen].gRadioWidget->style, gdkDrawable, stateType, shadowType,
1659 0 : &clipRect, gWidgetData[m_nXScreen].gRadioWidget, "radiobutton",
1660 0 : x, y, indicator_size, indicator_size );
1661 : }
1662 :
1663 0 : return true;
1664 : }
1665 :
1666 0 : bool GtkSalGraphics::NWPaintGTKCheck( GdkDrawable* gdkDrawable,
1667 : ControlType, ControlPart,
1668 : const Rectangle& rControlRectangle,
1669 : const clipList& rClipList,
1670 : ControlState nState,
1671 : const ImplControlValue& aValue,
1672 : const OUString& )
1673 : {
1674 : GtkStateType stateType;
1675 : GtkShadowType shadowType;
1676 0 : bool isChecked = (aValue.getTristateVal() == BUTTONVALUE_ON);
1677 0 : bool isInconsistent = (aValue.getTristateVal() == BUTTONVALUE_MIXED);
1678 : GdkRectangle clipRect;
1679 : gint x,y;
1680 :
1681 0 : NWEnsureGTKButton( m_nXScreen );
1682 0 : NWEnsureGTKCheck( m_nXScreen );
1683 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
1684 :
1685 : gint indicator_size;
1686 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gCheckWidget, "indicator_size", &indicator_size, (char *)NULL);
1687 :
1688 0 : x = rControlRectangle.Left() + (rControlRectangle.GetWidth()-indicator_size)/2;
1689 0 : y = rControlRectangle.Top() + (rControlRectangle.GetHeight()-indicator_size)/2;
1690 :
1691 : // Set the shadow based on if checked or not so we get a checkmark.
1692 0 : shadowType = isChecked ? GTK_SHADOW_IN : isInconsistent ? GTK_SHADOW_ETCHED_IN : GTK_SHADOW_OUT;
1693 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gCheckWidget, nState, stateType );
1694 0 : GTK_TOGGLE_BUTTON(gWidgetData[m_nXScreen].gCheckWidget)->active = isChecked;
1695 :
1696 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
1697 : {
1698 0 : clipRect.x = it->Left();
1699 0 : clipRect.y = it->Top();
1700 0 : clipRect.width = it->GetWidth();
1701 0 : clipRect.height = it->GetHeight();
1702 :
1703 0 : gtk_paint_check( gWidgetData[m_nXScreen].gCheckWidget->style, gdkDrawable, stateType, shadowType,
1704 0 : &clipRect, gWidgetData[m_nXScreen].gCheckWidget, "checkbutton",
1705 0 : x, y, indicator_size, indicator_size );
1706 : }
1707 :
1708 0 : return true;
1709 : }
1710 :
1711 0 : static void NWCalcArrowRect( const Rectangle& rButton, Rectangle& rArrow )
1712 : {
1713 : // Size the arrow appropriately
1714 0 : Size aSize( rButton.GetWidth()/2, rButton.GetHeight()/2 );
1715 0 : rArrow.SetSize( aSize );
1716 :
1717 : rArrow.SetPos( Point(
1718 0 : rButton.Left() + ( rButton.GetWidth() - rArrow.GetWidth() ) / 2,
1719 0 : rButton.Top() + ( rButton.GetHeight() - rArrow.GetHeight() ) / 2
1720 0 : ) );
1721 0 : }
1722 :
1723 0 : bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
1724 : const Rectangle& rControlRectangle,
1725 : const clipList&,
1726 : ControlState nState,
1727 : const ImplControlValue& aValue,
1728 : const OUString& )
1729 : {
1730 : assert(aValue.getType() == CTRL_SCROLLBAR);
1731 0 : const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(aValue);
1732 0 : GdkPixmap* pixmap = NULL;
1733 0 : Rectangle pixmapRect, scrollbarRect;
1734 : GtkStateType stateType;
1735 : GtkShadowType shadowType;
1736 : GtkScrollbar * scrollbarWidget;
1737 : GtkStyle * style;
1738 0 : GtkAdjustment* scrollbarValues = NULL;
1739 : GtkOrientation scrollbarOrientation;
1740 0 : Rectangle thumbRect = rScrollbarVal.maThumbRect;
1741 0 : Rectangle button11BoundRect = rScrollbarVal.maButton1Rect; // backward
1742 0 : Rectangle button22BoundRect = rScrollbarVal.maButton2Rect; // forward
1743 0 : Rectangle button12BoundRect = rScrollbarVal.maButton1Rect; // secondary forward
1744 0 : Rectangle button21BoundRect = rScrollbarVal.maButton2Rect; // secondary backward
1745 : GtkArrowType button1Type; // backward
1746 : GtkArrowType button2Type; // forward
1747 0 : gchar * scrollbarTagH = (gchar *) "hscrollbar";
1748 0 : gchar * scrollbarTagV = (gchar *) "vscrollbar";
1749 0 : gchar * scrollbarTag = NULL;
1750 0 : Rectangle arrowRect;
1751 0 : gint slider_width = 0;
1752 0 : gint stepper_size = 0;
1753 0 : gint stepper_spacing = 0;
1754 0 : gint trough_border = 0;
1755 0 : gint min_slider_length = 0;
1756 0 : gint vShim = 0;
1757 0 : gint hShim = 0;
1758 : gint x,y,w,h;
1759 :
1760 : // make controlvalue rectangles relative to area
1761 0 : thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
1762 0 : button11BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
1763 0 : button22BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
1764 0 : button12BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
1765 0 : button21BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
1766 :
1767 0 : NWEnsureGTKButton( m_nXScreen );
1768 0 : NWEnsureGTKScrollbars( m_nXScreen );
1769 0 : NWEnsureGTKArrow( m_nXScreen );
1770 :
1771 : // Find the overall bounding rect of the control
1772 0 : pixmapRect = rControlRectangle;
1773 0 : scrollbarRect = pixmapRect;
1774 :
1775 0 : if ( (scrollbarRect.GetWidth() <= 1) || (scrollbarRect.GetHeight() <= 1) )
1776 0 : return true;
1777 :
1778 : // Grab some button style attributes
1779 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget,
1780 : "slider_width", &slider_width,
1781 : "stepper_size", &stepper_size,
1782 : "trough_border", &trough_border,
1783 : "stepper_spacing", &stepper_spacing,
1784 0 : "min_slider_length", &min_slider_length, (char *)NULL );
1785 : gboolean has_forward;
1786 : gboolean has_forward2;
1787 : gboolean has_backward;
1788 : gboolean has_backward2;
1789 :
1790 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget, "has-forward-stepper", &has_forward,
1791 : "has-secondary-forward-stepper", &has_forward2,
1792 : "has-backward-stepper", &has_backward,
1793 0 : "has-secondary-backward-stepper", &has_backward2, (char *)NULL );
1794 0 : gint magic = trough_border ? 1 : 0;
1795 0 : gint nFirst = 0;
1796 :
1797 0 : if ( has_backward ) nFirst += 1;
1798 0 : if ( has_forward2 ) nFirst += 1;
1799 :
1800 0 : if ( nPart == PART_DRAW_BACKGROUND_HORZ )
1801 : {
1802 0 : unsigned int sliderHeight = slider_width + (trough_border * 2);
1803 0 : vShim = (pixmapRect.GetHeight() - sliderHeight) / 2;
1804 0 : bool bRTLSwap = button11BoundRect.Left() > button22BoundRect.Left();
1805 :
1806 0 : scrollbarRect.Move( 0, vShim );
1807 0 : scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), sliderHeight ) );
1808 :
1809 0 : scrollbarWidget = GTK_SCROLLBAR( gWidgetData[m_nXScreen].gScrollHorizWidget );
1810 0 : scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
1811 0 : scrollbarTag = scrollbarTagH;
1812 0 : button1Type = bRTLSwap? GTK_ARROW_RIGHT: GTK_ARROW_LEFT;
1813 0 : button2Type = bRTLSwap? GTK_ARROW_LEFT: GTK_ARROW_RIGHT;
1814 :
1815 0 : if ( has_backward )
1816 : {
1817 0 : button12BoundRect.Move( stepper_size - trough_border,
1818 0 : (scrollbarRect.GetHeight() - slider_width) / 2 );
1819 : }
1820 :
1821 0 : button11BoundRect.Move( trough_border, (scrollbarRect.GetHeight() - slider_width) / 2 );
1822 0 : button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
1823 0 : button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
1824 :
1825 0 : if ( has_backward2 )
1826 : {
1827 0 : button22BoundRect.Move( stepper_size+(trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
1828 0 : button21BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
1829 : }
1830 : else
1831 : {
1832 0 : button22BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
1833 : }
1834 :
1835 0 : button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
1836 0 : button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
1837 :
1838 0 : thumbRect.Bottom() = thumbRect.Top() + slider_width - 1;
1839 : // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
1840 : // but if the VCL gives us a size smaller than the theme's default thumb size,
1841 : // honor the VCL size
1842 0 : thumbRect.Right() += magic;
1843 : // Center vertically in the track
1844 0 : thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
1845 : }
1846 : else
1847 : {
1848 0 : unsigned int sliderWidth = slider_width + (trough_border * 2);
1849 0 : hShim = (pixmapRect.GetWidth() - sliderWidth) / 2;
1850 :
1851 0 : scrollbarRect.Move( hShim, 0 );
1852 0 : scrollbarRect.SetSize( Size( sliderWidth, scrollbarRect.GetHeight() ) );
1853 :
1854 0 : scrollbarWidget = GTK_SCROLLBAR( gWidgetData[m_nXScreen].gScrollVertWidget );
1855 0 : scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
1856 0 : scrollbarTag = scrollbarTagV;
1857 0 : button1Type = GTK_ARROW_UP;
1858 0 : button2Type = GTK_ARROW_DOWN;
1859 :
1860 0 : if ( has_backward )
1861 : {
1862 0 : button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
1863 0 : stepper_size + trough_border );
1864 : }
1865 0 : button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, trough_border );
1866 0 : button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
1867 0 : button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
1868 :
1869 0 : if ( has_backward2 )
1870 : {
1871 0 : button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size+(trough_border+1)/2 );
1872 0 : button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
1873 : }
1874 : else
1875 : {
1876 0 : button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
1877 : }
1878 :
1879 0 : button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
1880 0 : button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
1881 :
1882 0 : thumbRect.Right() = thumbRect.Left() + slider_width - 1;
1883 :
1884 0 : thumbRect.Bottom() += magic;
1885 : // Center horizontally in the track
1886 0 : thumbRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
1887 : }
1888 :
1889 0 : bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
1890 :
1891 0 : scrollbarValues = gtk_range_get_adjustment( GTK_RANGE(scrollbarWidget) );
1892 0 : if ( scrollbarValues == NULL )
1893 0 : scrollbarValues = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
1894 0 : if ( nPart == PART_DRAW_BACKGROUND_HORZ )
1895 : {
1896 0 : scrollbarValues->lower = rScrollbarVal.mnMin;
1897 0 : scrollbarValues->upper = rScrollbarVal.mnMax;
1898 0 : scrollbarValues->value = rScrollbarVal.mnCur;
1899 0 : scrollbarValues->page_size = scrollbarRect.GetWidth() / 2;
1900 : }
1901 : else
1902 : {
1903 0 : scrollbarValues->lower = rScrollbarVal.mnMin;
1904 0 : scrollbarValues->upper = rScrollbarVal.mnMax;
1905 0 : scrollbarValues->value = rScrollbarVal.mnCur;
1906 0 : scrollbarValues->page_size = scrollbarRect.GetHeight() / 2;
1907 : }
1908 0 : gtk_adjustment_changed( scrollbarValues );
1909 :
1910 : // as multiple paints are required for the scrollbar
1911 : // painting them directly to the window flickers
1912 0 : pixmap = NWGetPixmapFromScreen( pixmapRect );
1913 0 : if( ! pixmap )
1914 0 : return false;
1915 0 : x = y = 0;
1916 :
1917 0 : w = pixmapRect.GetWidth();
1918 0 : h = pixmapRect.GetHeight();
1919 :
1920 0 : GdkDrawable* const &gdkDrawable = GDK_DRAWABLE( pixmap );
1921 0 : GdkRectangle* gdkRect = NULL;
1922 :
1923 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
1924 0 : NWSetWidgetState( GTK_WIDGET(scrollbarWidget), nState, stateType );
1925 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
1926 0 : style = GTK_WIDGET( scrollbarWidget )->style;
1927 :
1928 : gtk_style_apply_default_background( m_pWindow->style, gdkDrawable, TRUE,
1929 : GTK_STATE_NORMAL, gdkRect,
1930 0 : x, y, w, h );
1931 :
1932 : // ----------------- TROUGH
1933 : // Pass coordinates of draw rect: window(0,0) -> widget(bottom-right) (coords relative to widget)
1934 : gtk_paint_flat_box(m_pWindow->style, gdkDrawable,
1935 : GTK_STATE_NORMAL, GTK_SHADOW_NONE, gdkRect,
1936 0 : m_pWindow, "base", x-pixmapRect.Left(),y-pixmapRect.Top(),x+pixmapRect.Right(),y+pixmapRect.Bottom());
1937 :
1938 : gtk_paint_box( style, gdkDrawable, GTK_STATE_ACTIVE, GTK_SHADOW_IN,
1939 0 : gdkRect, GTK_WIDGET(scrollbarWidget), "trough",
1940 : x, y,
1941 0 : scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
1942 :
1943 0 : if ( nState & CTRL_STATE_FOCUSED )
1944 : {
1945 : gtk_paint_focus( style, gdkDrawable, GTK_STATE_ACTIVE,
1946 0 : gdkRect, GTK_WIDGET(scrollbarWidget), "trough",
1947 : x, y,
1948 0 : scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
1949 : }
1950 :
1951 : // ----------------- THUMB
1952 0 : if ( has_slider )
1953 : {
1954 0 : NWConvertVCLStateToGTKState( rScrollbarVal.mnThumbState, &stateType, &shadowType );
1955 : gtk_paint_slider( style, gdkDrawable, stateType, GTK_SHADOW_OUT,
1956 0 : gdkRect, GTK_WIDGET(scrollbarWidget), "slider",
1957 0 : x+hShim+thumbRect.Left(), y+vShim+thumbRect.Top(),
1958 0 : thumbRect.GetWidth(), thumbRect.GetHeight(), scrollbarOrientation );
1959 : }
1960 :
1961 : // Some engines require allocation, e.g. Clearlooks uses it to identify
1962 : // positions of the buttons, whereupon the first and the last button will
1963 : // have rounded corners.
1964 0 : GTK_WIDGET(scrollbarWidget)->allocation.x = x;
1965 0 : GTK_WIDGET(scrollbarWidget)->allocation.y = y;
1966 0 : GTK_WIDGET(scrollbarWidget)->allocation.width = w;
1967 0 : GTK_WIDGET(scrollbarWidget)->allocation.height = h;
1968 :
1969 : bool backwardButtonInsensitive =
1970 0 : rScrollbarVal.mnCur == rScrollbarVal.mnMin;
1971 0 : bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
1972 0 : rScrollbarVal.mnCur + rScrollbarVal.mnVisibleSize >= rScrollbarVal.mnMax;
1973 :
1974 : // ----------------- BUTTON 1
1975 0 : if ( has_backward )
1976 : {
1977 0 : NWConvertVCLStateToGTKState( rScrollbarVal.mnButton1State, &stateType, &shadowType );
1978 0 : if ( backwardButtonInsensitive )
1979 0 : stateType = GTK_STATE_INSENSITIVE;
1980 : gtk_paint_box( style, gdkDrawable, stateType, shadowType,
1981 0 : gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag,
1982 0 : x+hShim+button11BoundRect.Left(), y+vShim+button11BoundRect.Top(),
1983 0 : button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
1984 : // ----------------- ARROW 1
1985 0 : NWCalcArrowRect( button11BoundRect, arrowRect );
1986 : gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
1987 0 : gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button1Type, true,
1988 0 : x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
1989 0 : arrowRect.GetWidth(), arrowRect.GetHeight() );
1990 : }
1991 0 : if ( has_forward2 )
1992 : {
1993 0 : NWConvertVCLStateToGTKState( rScrollbarVal.mnButton2State, &stateType, &shadowType );
1994 0 : if ( forwardButtonInsensitive )
1995 0 : stateType = GTK_STATE_INSENSITIVE;
1996 : gtk_paint_box( style, gdkDrawable, stateType, shadowType,
1997 0 : gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag,
1998 0 : x+hShim+button12BoundRect.Left(), y+vShim+button12BoundRect.Top(),
1999 0 : button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
2000 : // ----------------- ARROW 1
2001 0 : NWCalcArrowRect( button12BoundRect, arrowRect );
2002 : gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
2003 0 : gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button2Type, true,
2004 0 : x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
2005 0 : arrowRect.GetWidth(), arrowRect.GetHeight() );
2006 : }
2007 : // ----------------- BUTTON 2
2008 0 : if ( has_backward2 )
2009 : {
2010 0 : NWConvertVCLStateToGTKState( rScrollbarVal.mnButton1State, &stateType, &shadowType );
2011 0 : if ( backwardButtonInsensitive )
2012 0 : stateType = GTK_STATE_INSENSITIVE;
2013 : gtk_paint_box( style, gdkDrawable, stateType, shadowType, gdkRect,
2014 0 : GTK_WIDGET(scrollbarWidget), scrollbarTag,
2015 0 : x+hShim+button21BoundRect.Left(), y+vShim+button21BoundRect.Top(),
2016 0 : button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
2017 : // ----------------- ARROW 2
2018 0 : NWCalcArrowRect( button21BoundRect, arrowRect );
2019 : gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
2020 0 : gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button1Type, true,
2021 0 : x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
2022 0 : arrowRect.GetWidth(), arrowRect.GetHeight() );
2023 : }
2024 0 : if ( has_forward )
2025 : {
2026 0 : NWConvertVCLStateToGTKState( rScrollbarVal.mnButton2State, &stateType, &shadowType );
2027 0 : if ( forwardButtonInsensitive )
2028 0 : stateType = GTK_STATE_INSENSITIVE;
2029 : gtk_paint_box( style, gdkDrawable, stateType, shadowType, gdkRect,
2030 0 : GTK_WIDGET(scrollbarWidget), scrollbarTag,
2031 0 : x+hShim+button22BoundRect.Left(), y+vShim+button22BoundRect.Top(),
2032 0 : button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
2033 : // ----------------- ARROW 2
2034 0 : NWCalcArrowRect( button22BoundRect, arrowRect );
2035 : gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
2036 0 : gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button2Type, true,
2037 0 : x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
2038 0 : arrowRect.GetWidth(), arrowRect.GetHeight() );
2039 : }
2040 :
2041 0 : if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
2042 : {
2043 0 : g_object_unref( pixmap );
2044 0 : return false;
2045 : }
2046 0 : g_object_unref( pixmap );
2047 :
2048 0 : return true;
2049 : }
2050 :
2051 0 : static Rectangle NWGetScrollButtonRect( SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect )
2052 : {
2053 : gint slider_width;
2054 : gint stepper_size;
2055 : gint stepper_spacing;
2056 : gint trough_border;
2057 :
2058 0 : NWEnsureGTKScrollbars( nScreen );
2059 :
2060 : // Grab some button style attributes
2061 0 : gtk_widget_style_get( gWidgetData[nScreen].gScrollHorizWidget,
2062 : "slider-width", &slider_width,
2063 : "stepper-size", &stepper_size,
2064 : "trough-border", &trough_border,
2065 0 : "stepper-spacing", &stepper_spacing, (char *)NULL );
2066 :
2067 : gboolean has_forward;
2068 : gboolean has_forward2;
2069 : gboolean has_backward;
2070 : gboolean has_backward2;
2071 :
2072 0 : gtk_widget_style_get( gWidgetData[nScreen].gScrollHorizWidget,
2073 : "has-forward-stepper", &has_forward,
2074 : "has-secondary-forward-stepper", &has_forward2,
2075 : "has-backward-stepper", &has_backward,
2076 0 : "has-secondary-backward-stepper", &has_backward2, (char *)NULL );
2077 : gint buttonWidth;
2078 : gint buttonHeight;
2079 0 : Rectangle buttonRect;
2080 :
2081 0 : gint nFirst = 0;
2082 0 : gint nSecond = 0;
2083 :
2084 0 : if ( has_forward ) nSecond += 1;
2085 0 : if ( has_forward2 ) nFirst += 1;
2086 0 : if ( has_backward ) nFirst += 1;
2087 0 : if ( has_backward2 ) nSecond += 1;
2088 :
2089 0 : if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_DOWN ) )
2090 : {
2091 0 : buttonWidth = slider_width + 2 * trough_border;
2092 0 : buttonHeight = stepper_size + trough_border + stepper_spacing;
2093 : }
2094 : else
2095 : {
2096 0 : buttonWidth = stepper_size + trough_border + stepper_spacing;
2097 0 : buttonHeight = slider_width + 2 * trough_border;
2098 : }
2099 :
2100 0 : if ( nPart == PART_BUTTON_UP )
2101 : {
2102 0 : buttonHeight *= nFirst;
2103 0 : buttonHeight -= 1;
2104 0 : buttonRect.setX( aAreaRect.Left() );
2105 0 : buttonRect.setY( aAreaRect.Top() );
2106 : }
2107 0 : else if ( nPart == PART_BUTTON_LEFT )
2108 : {
2109 0 : buttonWidth *= nFirst;
2110 0 : buttonWidth -= 1;
2111 0 : buttonRect.setX( aAreaRect.Left() );
2112 0 : buttonRect.setY( aAreaRect.Top() );
2113 : }
2114 0 : else if ( nPart == PART_BUTTON_DOWN )
2115 : {
2116 0 : buttonHeight *= nSecond;
2117 0 : buttonRect.setX( aAreaRect.Left() );
2118 0 : buttonRect.setY( aAreaRect.Top() + aAreaRect.GetHeight() - buttonHeight );
2119 : }
2120 0 : else if ( nPart == PART_BUTTON_RIGHT )
2121 : {
2122 0 : buttonWidth *= nSecond;
2123 0 : buttonRect.setX( aAreaRect.Left() + aAreaRect.GetWidth() - buttonWidth );
2124 0 : buttonRect.setY( aAreaRect.Top() );
2125 : }
2126 :
2127 0 : buttonRect.SetSize( Size( buttonWidth, buttonHeight ) );
2128 :
2129 0 : return( buttonRect );
2130 : }
2131 :
2132 0 : bool GtkSalGraphics::NWPaintGTKEditBox( GdkDrawable* gdkDrawable,
2133 : ControlType nType, ControlPart nPart,
2134 : const Rectangle& rControlRectangle,
2135 : const clipList& rClipList,
2136 : ControlState nState,
2137 : const ImplControlValue& aValue,
2138 : const OUString& rCaption )
2139 : {
2140 0 : Rectangle pixmapRect;
2141 : GdkRectangle clipRect;
2142 :
2143 : // Find the overall bounding rect of the buttons's drawing area,
2144 : // plus its actual draw rect excluding adornment
2145 : pixmapRect = NWGetEditBoxPixmapRect( m_nXScreen, nType, nPart, rControlRectangle,
2146 0 : nState, aValue, rCaption );
2147 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
2148 : {
2149 0 : clipRect.x = it->Left();
2150 0 : clipRect.y = it->Top();
2151 0 : clipRect.width = it->GetWidth();
2152 0 : clipRect.height = it->GetHeight();
2153 :
2154 0 : NWPaintOneEditBox( m_nXScreen, gdkDrawable, &clipRect, nType, nPart, pixmapRect, nState, aValue, rCaption );
2155 : }
2156 :
2157 0 : return true;
2158 : }
2159 :
2160 : /* Take interior/exterior focus into account and return
2161 : * the bounding rectangle of the edit box including
2162 : * any focus requirements.
2163 : */
2164 0 : static Rectangle NWGetEditBoxPixmapRect(SalX11Screen nScreen,
2165 : ControlType,
2166 : ControlPart,
2167 : Rectangle aAreaRect,
2168 : ControlState,
2169 : const ImplControlValue&,
2170 : const OUString& )
2171 : {
2172 0 : Rectangle pixmapRect = aAreaRect;
2173 : gboolean interiorFocus;
2174 : gint focusWidth;
2175 :
2176 0 : NWEnsureGTKEditBox( nScreen );
2177 :
2178 : // Grab some entry style attributes
2179 0 : gtk_widget_style_get( gWidgetData[nScreen].gEditBoxWidget,
2180 : "focus-line-width", &focusWidth,
2181 0 : "interior-focus", &interiorFocus, (char *)NULL );
2182 :
2183 0 : if ( !interiorFocus )
2184 : {
2185 0 : pixmapRect.Move( -(focusWidth), -(focusWidth) );
2186 0 : pixmapRect.SetSize( Size( pixmapRect.GetWidth() + (2*(focusWidth)),
2187 0 : pixmapRect.GetHeight() + (2*(focusWidth)) ) );
2188 : }
2189 :
2190 0 : return( pixmapRect );
2191 : }
2192 :
2193 : /* Paint a GTK Entry widget into the specified GdkPixmap.
2194 : * All coordinates should be local to the Pixmap, NOT
2195 : * screen/window coordinates.
2196 : */
2197 0 : static void NWPaintOneEditBox( SalX11Screen nScreen,
2198 : GdkDrawable * gdkDrawable,
2199 : GdkRectangle * gdkRect,
2200 : ControlType nType,
2201 : ControlPart,
2202 : Rectangle aEditBoxRect,
2203 : ControlState nState,
2204 : const ImplControlValue&,
2205 : const OUString& )
2206 : {
2207 : GtkStateType stateType;
2208 : GtkShadowType shadowType;
2209 : GtkWidget *widget;
2210 :
2211 0 : NWEnsureGTKButton( nScreen );
2212 0 : NWEnsureGTKEditBox( nScreen );
2213 0 : NWEnsureGTKSpinButton( nScreen );
2214 0 : NWEnsureGTKCombo( nScreen );
2215 0 : NWEnsureGTKScrolledWindow( nScreen );
2216 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
2217 :
2218 0 : switch ( nType )
2219 : {
2220 : case CTRL_SPINBOX:
2221 0 : widget = gWidgetData[nScreen].gSpinButtonWidget;
2222 0 : break;
2223 :
2224 : case CTRL_MULTILINE_EDITBOX:
2225 0 : widget = gWidgetData[nScreen].gScrolledWindowWidget;
2226 0 : break;
2227 : case CTRL_COMBOBOX:
2228 0 : widget = GTK_COMBO(gWidgetData[nScreen].gComboWidget)->entry;
2229 0 : break;
2230 :
2231 : default:
2232 0 : widget = gWidgetData[nScreen].gEditBoxWidget;
2233 0 : break;
2234 : }
2235 :
2236 0 : if ( stateType == GTK_STATE_PRELIGHT )
2237 0 : stateType = GTK_STATE_NORMAL;
2238 :
2239 0 : NWSetWidgetState( widget, nState, stateType );
2240 :
2241 0 : gint xborder = widget->style->xthickness;
2242 0 : gint yborder = widget->style->ythickness;
2243 : gint bInteriorFocus, nFocusLineWidth;
2244 : gtk_widget_style_get( widget,
2245 : "interior-focus", &bInteriorFocus,
2246 : "focus-line-width", &nFocusLineWidth,
2247 0 : (char *)NULL);
2248 0 : if ( !bInteriorFocus )
2249 : {
2250 0 : xborder += nFocusLineWidth;
2251 0 : yborder += nFocusLineWidth;
2252 : }
2253 :
2254 : gtk_paint_flat_box( widget->style, gdkDrawable, stateType, GTK_SHADOW_NONE,
2255 : gdkRect, widget, "entry_bg",
2256 0 : aEditBoxRect.Left() + xborder, aEditBoxRect.Top() + yborder,
2257 0 : aEditBoxRect.GetWidth() - 2*xborder, aEditBoxRect.GetHeight() - 2*yborder );
2258 : gtk_paint_shadow( widget->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
2259 : gdkRect, widget, "entry",
2260 0 : aEditBoxRect.Left(), aEditBoxRect.Top(),
2261 0 : aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight() );
2262 :
2263 0 : }
2264 :
2265 0 : bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
2266 : const Rectangle& rControlRectangle,
2267 : const clipList&,
2268 : ControlState nState,
2269 : const ImplControlValue& aValue,
2270 : const OUString& rCaption )
2271 : {
2272 : GdkPixmap * pixmap;
2273 0 : Rectangle pixmapRect;
2274 : GtkStateType stateType;
2275 : GtkShadowType shadowType;
2276 0 : const SpinbuttonValue * pSpinVal = (aValue.getType() == CTRL_SPINBUTTONS) ? static_cast<const SpinbuttonValue *>(&aValue) : NULL;
2277 0 : Rectangle upBtnRect;
2278 0 : ControlPart upBtnPart = PART_BUTTON_UP;
2279 0 : ControlState upBtnState = CTRL_STATE_ENABLED;
2280 0 : Rectangle downBtnRect;
2281 0 : ControlPart downBtnPart = PART_BUTTON_DOWN;
2282 0 : ControlState downBtnState = CTRL_STATE_ENABLED;
2283 :
2284 0 : NWEnsureGTKButton( m_nXScreen );
2285 0 : NWEnsureGTKSpinButton( m_nXScreen );
2286 0 : NWEnsureGTKArrow( m_nXScreen );
2287 :
2288 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
2289 :
2290 0 : if ( pSpinVal )
2291 : {
2292 0 : upBtnPart = pSpinVal->mnUpperPart;
2293 0 : upBtnState = pSpinVal->mnUpperState;
2294 :
2295 0 : downBtnPart = pSpinVal->mnLowerPart;
2296 0 : downBtnState = pSpinVal->mnLowerState;
2297 : }
2298 :
2299 : // CTRL_SPINBUTTONS pass their area in pSpinVal, not in rControlRectangle
2300 0 : if ( nType == CTRL_SPINBUTTONS )
2301 : {
2302 0 : if ( !pSpinVal )
2303 : {
2304 0 : std::fprintf( stderr, "Tried to draw CTRL_SPINBUTTONS, but the SpinButtons data structure didn't exist!\n" );
2305 0 : return( false );
2306 : }
2307 0 : pixmapRect = pSpinVal->maUpperRect;
2308 0 : pixmapRect.Union( pSpinVal->maLowerRect );
2309 : }
2310 : else
2311 0 : pixmapRect = rControlRectangle;
2312 :
2313 0 : pixmap = NWGetPixmapFromScreen( pixmapRect );
2314 0 : if ( !pixmap )
2315 0 : return false;
2316 :
2317 : // First render background
2318 : gtk_paint_flat_box(m_pWindow->style,pixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base",
2319 0 : -pixmapRect.Left(),
2320 0 : -pixmapRect.Top(),
2321 0 : pixmapRect.Right(),
2322 0 : pixmapRect.Bottom() );
2323 :
2324 0 : upBtnRect = NWGetSpinButtonRect( m_nXScreen, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
2325 0 : downBtnRect = NWGetSpinButtonRect( m_nXScreen, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
2326 :
2327 0 : if ( (nType==CTRL_SPINBOX) && (nPart!=PART_ALL_BUTTONS) )
2328 : {
2329 : // Draw an edit field for SpinBoxes and ComboBoxes
2330 0 : Rectangle aEditBoxRect( pixmapRect );
2331 0 : aEditBoxRect.SetSize( Size( pixmapRect.GetWidth() - upBtnRect.GetWidth(), aEditBoxRect.GetHeight() ) );
2332 0 : if( Application::GetSettings().GetLayoutRTL() )
2333 0 : aEditBoxRect.setX( upBtnRect.GetWidth() );
2334 : else
2335 0 : aEditBoxRect.setX( 0 );
2336 0 : aEditBoxRect.setY( 0 );
2337 :
2338 0 : NWPaintOneEditBox( m_nXScreen, pixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption );
2339 : }
2340 :
2341 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gSpinButtonWidget, nState, stateType );
2342 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gSpinButtonWidget, "shadow_type", &shadowType, (char *)NULL );
2343 :
2344 0 : if ( shadowType != GTK_SHADOW_NONE )
2345 : {
2346 0 : Rectangle shadowRect( upBtnRect );
2347 :
2348 0 : shadowRect.Union( downBtnRect );
2349 0 : gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, pixmap, GTK_STATE_NORMAL, shadowType, NULL,
2350 0 : gWidgetData[m_nXScreen].gSpinButtonWidget, "spinbutton",
2351 0 : (shadowRect.Left() - pixmapRect.Left()), (shadowRect.Top() - pixmapRect.Top()),
2352 0 : shadowRect.GetWidth(), shadowRect.GetHeight() );
2353 : }
2354 :
2355 0 : NWPaintOneSpinButton( m_nXScreen, pixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
2356 0 : NWPaintOneSpinButton( m_nXScreen, pixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
2357 :
2358 0 : if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
2359 : {
2360 0 : g_object_unref( pixmap );
2361 0 : return false;
2362 : }
2363 :
2364 0 : g_object_unref( pixmap );
2365 0 : return true;
2366 : }
2367 :
2368 0 : static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen,
2369 : ControlType,
2370 : ControlPart nPart,
2371 : Rectangle aAreaRect,
2372 : ControlState,
2373 : const ImplControlValue&,
2374 : const OUString& )
2375 : {
2376 : gint buttonSize;
2377 0 : Rectangle buttonRect;
2378 :
2379 0 : NWEnsureGTKSpinButton( nScreen );
2380 :
2381 0 : buttonSize = MAX( PANGO_PIXELS( pango_font_description_get_size(GTK_WIDGET(gWidgetData[nScreen].gSpinButtonWidget)->style->font_desc) ),
2382 0 : MIN_SPIN_ARROW_WIDTH );
2383 0 : buttonSize -= buttonSize % 2 - 1; /* force odd */
2384 0 : buttonRect.SetSize( Size( buttonSize + 2 * gWidgetData[nScreen].gSpinButtonWidget->style->xthickness,
2385 0 : buttonRect.GetHeight() ) );
2386 0 : if( Application::GetSettings().GetLayoutRTL() )
2387 0 : buttonRect.setX( aAreaRect.Left() );
2388 : else
2389 0 : buttonRect.setX( aAreaRect.Left() + (aAreaRect.GetWidth() - buttonRect.GetWidth()) );
2390 0 : if ( nPart == PART_BUTTON_UP )
2391 : {
2392 0 : buttonRect.setY( aAreaRect.Top() );
2393 0 : buttonRect.Bottom() = buttonRect.Top() + (aAreaRect.GetHeight() / 2);
2394 : }
2395 0 : else if( nPart == PART_BUTTON_DOWN )
2396 : {
2397 0 : buttonRect.setY( aAreaRect.Top() + (aAreaRect.GetHeight() / 2) );
2398 0 : buttonRect.Bottom() = aAreaRect.Bottom(); // cover area completely
2399 : }
2400 : else
2401 : {
2402 0 : if( Application::GetSettings().GetLayoutRTL() ) {
2403 0 : buttonRect.Left() = buttonRect.Right()+1;
2404 0 : buttonRect.Right() = aAreaRect.Right();
2405 : } else {
2406 0 : buttonRect.Right() = buttonRect.Left()-1;
2407 0 : buttonRect.Left() = aAreaRect.Left();
2408 : }
2409 0 : buttonRect.Top() = aAreaRect.Top();
2410 0 : buttonRect.Bottom() = aAreaRect.Bottom();
2411 : }
2412 :
2413 0 : return( buttonRect );
2414 : }
2415 :
2416 0 : static void NWPaintOneSpinButton( SalX11Screen nScreen,
2417 : GdkPixmap* pixmap,
2418 : ControlType nType,
2419 : ControlPart nPart,
2420 : Rectangle aAreaRect,
2421 : ControlState nState,
2422 : const ImplControlValue& aValue,
2423 : const OUString& rCaption )
2424 : {
2425 0 : Rectangle buttonRect;
2426 : GtkStateType stateType;
2427 : GtkShadowType shadowType;
2428 0 : Rectangle arrowRect;
2429 : gint arrowSize;
2430 :
2431 0 : NWEnsureGTKSpinButton( nScreen );
2432 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
2433 :
2434 0 : buttonRect = NWGetSpinButtonRect( nScreen, nType, nPart, aAreaRect, nState, aValue, rCaption );
2435 :
2436 0 : NWSetWidgetState( gWidgetData[nScreen].gSpinButtonWidget, nState, stateType );
2437 0 : gtk_paint_box( gWidgetData[nScreen].gSpinButtonWidget->style, pixmap, stateType, shadowType, NULL, gWidgetData[nScreen].gSpinButtonWidget,
2438 : (nPart == PART_BUTTON_UP) ? "spinbutton_up" : "spinbutton_down",
2439 0 : (buttonRect.Left() - aAreaRect.Left()), (buttonRect.Top() - aAreaRect.Top()),
2440 0 : buttonRect.GetWidth(), buttonRect.GetHeight() );
2441 :
2442 0 : arrowSize = (buttonRect.GetWidth() - (2 * gWidgetData[nScreen].gSpinButtonWidget->style->xthickness)) - 4;
2443 0 : arrowSize -= arrowSize % 2 - 1; /* force odd */
2444 0 : arrowRect.SetSize( Size( arrowSize, arrowSize ) );
2445 0 : arrowRect.setX( buttonRect.Left() + (buttonRect.GetWidth() - arrowRect.GetWidth()) / 2 );
2446 0 : if ( nPart == PART_BUTTON_UP )
2447 0 : arrowRect.setY( buttonRect.Top() + (buttonRect.GetHeight() - arrowRect.GetHeight()) / 2 + 1);
2448 : else
2449 0 : arrowRect.setY( buttonRect.Top() + (buttonRect.GetHeight() - arrowRect.GetHeight()) / 2 - 1);
2450 :
2451 0 : gtk_paint_arrow( gWidgetData[nScreen].gSpinButtonWidget->style, pixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[nScreen].gSpinButtonWidget,
2452 : "spinbutton", (nPart == PART_BUTTON_UP) ? GTK_ARROW_UP : GTK_ARROW_DOWN, true,
2453 0 : (arrowRect.Left() - aAreaRect.Left()), (arrowRect.Top() - aAreaRect.Top()),
2454 0 : arrowRect.GetWidth(), arrowRect.GetHeight() );
2455 0 : }
2456 :
2457 0 : bool GtkSalGraphics::NWPaintGTKComboBox( GdkDrawable* gdkDrawable,
2458 : ControlType nType, ControlPart nPart,
2459 : const Rectangle& rControlRectangle,
2460 : const clipList& rClipList,
2461 : ControlState nState,
2462 : const ImplControlValue& aValue,
2463 : const OUString& rCaption )
2464 : {
2465 0 : Rectangle pixmapRect;
2466 0 : Rectangle buttonRect;
2467 : GtkStateType stateType;
2468 : GtkShadowType shadowType;
2469 0 : Rectangle arrowRect;
2470 : gint x,y;
2471 : GdkRectangle clipRect;
2472 :
2473 0 : NWEnsureGTKButton( m_nXScreen );
2474 0 : NWEnsureGTKArrow( m_nXScreen );
2475 0 : NWEnsureGTKCombo( m_nXScreen );
2476 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
2477 :
2478 : // Find the overall bounding rect of the buttons's drawing area,
2479 : // plus its actual draw rect excluding adornment
2480 0 : pixmapRect = rControlRectangle;
2481 0 : x = rControlRectangle.Left();
2482 0 : y = rControlRectangle.Top();
2483 :
2484 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
2485 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gComboWidget, nState, stateType );
2486 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gArrowWidget, nState, stateType );
2487 :
2488 0 : buttonRect = NWGetComboBoxButtonRect( m_nXScreen, nType, PART_BUTTON_DOWN, pixmapRect, nState, aValue, rCaption );
2489 0 : if( nPart == PART_BUTTON_DOWN )
2490 0 : buttonRect.Left() += 1;
2491 :
2492 0 : Rectangle aEditBoxRect( pixmapRect );
2493 0 : aEditBoxRect.SetSize( Size( pixmapRect.GetWidth() - buttonRect.GetWidth(), aEditBoxRect.GetHeight() ) );
2494 0 : if( Application::GetSettings().GetLayoutRTL() )
2495 0 : aEditBoxRect.SetPos( Point( x + buttonRect.GetWidth() , y ) );
2496 :
2497 : #define ARROW_EXTENT 0.7
2498 : arrowRect.SetSize( Size( (gint)(MIN_ARROW_SIZE * ARROW_EXTENT),
2499 0 : (gint)(MIN_ARROW_SIZE * ARROW_EXTENT) ) );
2500 0 : arrowRect.SetPos( Point( buttonRect.Left() + (gint)((buttonRect.GetWidth() - arrowRect.GetWidth()) / 2),
2501 0 : buttonRect.Top() + (gint)((buttonRect.GetHeight() - arrowRect.GetHeight()) / 2) ) );
2502 :
2503 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
2504 : {
2505 0 : clipRect.x = it->Left();
2506 0 : clipRect.y = it->Top();
2507 0 : clipRect.width = it->GetWidth();
2508 0 : clipRect.height = it->GetHeight();
2509 :
2510 0 : if( nPart == PART_ENTIRE_CONTROL )
2511 : NWPaintOneEditBox( m_nXScreen, gdkDrawable, &clipRect, nType, nPart, aEditBoxRect,
2512 0 : nState, aValue, rCaption );
2513 :
2514 : // Buttons must paint opaque since some themes have alpha-channel enabled buttons
2515 : gtk_paint_flat_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
2516 : &clipRect, m_pWindow, "base",
2517 0 : x+(buttonRect.Left() - pixmapRect.Left()),
2518 0 : y+(buttonRect.Top() - pixmapRect.Top()),
2519 0 : buttonRect.GetWidth(), buttonRect.GetHeight() );
2520 0 : gtk_paint_box( GTK_COMBO(gWidgetData[m_nXScreen].gComboWidget)->button->style, gdkDrawable, stateType, shadowType,
2521 0 : &clipRect, GTK_COMBO(gWidgetData[m_nXScreen].gComboWidget)->button, "button",
2522 0 : x+(buttonRect.Left() - pixmapRect.Left()),
2523 0 : y+(buttonRect.Top() - pixmapRect.Top()),
2524 0 : buttonRect.GetWidth(), buttonRect.GetHeight() );
2525 :
2526 0 : gtk_paint_arrow( gWidgetData[m_nXScreen].gArrowWidget->style, gdkDrawable, stateType, shadowType,
2527 0 : &clipRect, gWidgetData[m_nXScreen].gArrowWidget, "arrow", GTK_ARROW_DOWN, true,
2528 0 : x+(arrowRect.Left() - pixmapRect.Left()), y+(arrowRect.Top() - pixmapRect.Top()),
2529 0 : arrowRect.GetWidth(), arrowRect.GetHeight() );
2530 : }
2531 :
2532 0 : return true;
2533 : }
2534 :
2535 0 : static Rectangle NWGetComboBoxButtonRect( SalX11Screen nScreen,
2536 : ControlType,
2537 : ControlPart nPart,
2538 : Rectangle aAreaRect,
2539 : ControlState,
2540 : const ImplControlValue&,
2541 : const OUString& )
2542 : {
2543 0 : Rectangle aButtonRect;
2544 : gint nArrowWidth;
2545 : gint nButtonWidth;
2546 : gint nFocusWidth;
2547 : gint nFocusPad;
2548 :
2549 0 : NWEnsureGTKArrow( nScreen );
2550 :
2551 : // Grab some button style attributes
2552 0 : gtk_widget_style_get( gWidgetData[nScreen].gDropdownWidget,
2553 : "focus-line-width", &nFocusWidth,
2554 0 : "focus-padding", &nFocusPad, (char *)NULL );
2555 :
2556 0 : nArrowWidth = MIN_ARROW_SIZE + (GTK_MISC(gWidgetData[nScreen].gArrowWidget)->xpad * 2);
2557 0 : nButtonWidth = nArrowWidth +
2558 0 : ((BTN_CHILD_SPACING + gWidgetData[nScreen].gDropdownWidget->style->xthickness) * 2)
2559 0 : + (2 * (nFocusWidth+nFocusPad));
2560 0 : if( nPart == PART_BUTTON_DOWN )
2561 : {
2562 0 : aButtonRect.SetSize( Size( nButtonWidth, aAreaRect.GetHeight() ) );
2563 0 : if( Application::GetSettings().GetLayoutRTL() )
2564 0 : aButtonRect.SetPos( Point( aAreaRect.Left(), aAreaRect.Top() ) );
2565 : else
2566 0 : aButtonRect.SetPos( Point( aAreaRect.Left() + aAreaRect.GetWidth() - nButtonWidth,
2567 0 : aAreaRect.Top() ) );
2568 : }
2569 0 : else if( nPart == PART_SUB_EDIT )
2570 : {
2571 0 : NWEnsureGTKCombo( nScreen );
2572 :
2573 0 : gint adjust_x = GTK_CONTAINER(gWidgetData[nScreen].gComboWidget)->border_width +
2574 0 : nFocusWidth +
2575 0 : nFocusPad;
2576 0 : gint adjust_y = adjust_x + gWidgetData[nScreen].gComboWidget->style->ythickness;
2577 0 : adjust_x += gWidgetData[nScreen].gComboWidget->style->xthickness;
2578 0 : aButtonRect.SetSize( Size( aAreaRect.GetWidth() - nButtonWidth - 2 * adjust_x,
2579 0 : aAreaRect.GetHeight() - 2 * adjust_y ) );
2580 0 : Point aEditPos = aAreaRect.TopLeft();
2581 0 : aEditPos.X() += adjust_x;
2582 0 : aEditPos.Y() += adjust_y;
2583 0 : if( Application::GetSettings().GetLayoutRTL() )
2584 0 : aEditPos.X() += nButtonWidth;
2585 0 : aButtonRect.SetPos( aEditPos );
2586 : }
2587 :
2588 0 : return( aButtonRect );
2589 : }
2590 :
2591 0 : bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
2592 : const Rectangle& rControlRectangle,
2593 : const clipList&,
2594 : ControlState nState,
2595 : const ImplControlValue& aValue,
2596 : const OUString& )
2597 : {
2598 : OSL_ASSERT( nType != CTRL_TAB_ITEM || aValue.getType() == CTRL_TAB_ITEM );
2599 : GdkPixmap * pixmap;
2600 0 : Rectangle pixmapRect;
2601 0 : Rectangle tabRect;
2602 : GtkStateType stateType;
2603 : GtkShadowType shadowType;
2604 0 : if( ! gWidgetData[ m_nXScreen ].gCacheTabItems )
2605 : {
2606 0 : gWidgetData[ m_nXScreen ].gCacheTabItems = new NWPixmapCache( m_nXScreen );
2607 0 : gWidgetData[ m_nXScreen ].gCacheTabPages = new NWPixmapCache( m_nXScreen );
2608 : }
2609 0 : NWPixmapCache& aCacheItems = *gWidgetData[ m_nXScreen ].gCacheTabItems;
2610 0 : NWPixmapCache& aCachePage = *gWidgetData[ m_nXScreen ].gCacheTabPages;
2611 :
2612 0 : if( !aCacheItems.GetSize() )
2613 0 : aCacheItems.SetSize( 20 );
2614 0 : if( !aCachePage.GetSize() )
2615 0 : aCachePage.SetSize( 1 );
2616 :
2617 0 : if ( (nType == CTRL_TAB_ITEM) && (aValue.getType() != CTRL_TAB_ITEM) )
2618 : {
2619 0 : return( false );
2620 : }
2621 :
2622 0 : NWEnsureGTKButton( m_nXScreen );
2623 0 : NWEnsureGTKNotebook( m_nXScreen );
2624 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
2625 :
2626 : // Find the overall bounding rect of the buttons's drawing area,
2627 : // plus its actual draw rect excluding adornment
2628 0 : pixmapRect = rControlRectangle;
2629 0 : if ( nType == CTRL_TAB_ITEM )
2630 : {
2631 0 : const TabitemValue * pTabitemValue = static_cast<const TabitemValue *>(&aValue);
2632 0 : if ( !pTabitemValue->isFirst() )
2633 : {
2634 : // GTK+ tabs overlap on the right edge (the top tab obscures the
2635 : // left edge of the tab right "below" it, so adjust the rectangle
2636 : // to draw tabs slightly large so the overlap happens
2637 0 : pixmapRect.Move( -2, 0 );
2638 0 : pixmapRect.SetSize( Size( pixmapRect.GetWidth() + 2, pixmapRect.GetHeight() ) );
2639 : }
2640 0 : if ( nState & CTRL_STATE_SELECTED )
2641 : {
2642 : // In GTK+, the selected tab is 2px taller than all other tabs
2643 0 : pixmapRect.Move( 0, -2 );
2644 0 : pixmapRect.Bottom() += 2;
2645 0 : tabRect = pixmapRect;
2646 : // Only draw over 1 pixel of the tab pane that this tab is drawn on top of.
2647 0 : tabRect.Bottom() -= 1;
2648 : }
2649 : else
2650 0 : tabRect = pixmapRect;
2651 :
2652 : // Allow the tab to draw a right border if needed
2653 0 : tabRect.Right() -= 1;
2654 :
2655 : // avoid degenerate cases which might lead to crashes
2656 0 : if( tabRect.GetWidth() <= 1 || tabRect.GetHeight() <= 1 )
2657 0 : return false;
2658 : }
2659 :
2660 0 : if( nType == CTRL_TAB_ITEM )
2661 : {
2662 0 : if( aCacheItems.Find( nType, nState, pixmapRect, &pixmap ) )
2663 0 : return NWRenderPixmapToScreen( pixmap, pixmapRect );
2664 : }
2665 : else
2666 : {
2667 0 : if( aCachePage.Find( nType, nState, pixmapRect, &pixmap ) )
2668 0 : return NWRenderPixmapToScreen( pixmap, pixmapRect );
2669 : }
2670 :
2671 0 : pixmap = gdk_pixmap_new( NULL, pixmapRect.GetWidth(), pixmapRect.GetHeight(),
2672 0 : GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() );
2673 : GdkRectangle paintRect;
2674 0 : paintRect.x = paintRect.y = 0;
2675 0 : paintRect.width = pixmapRect.GetWidth();
2676 0 : paintRect.height = pixmapRect.GetHeight();
2677 :
2678 : gtk_paint_flat_box( m_pWindow->style, pixmap, GTK_STATE_NORMAL,
2679 : GTK_SHADOW_NONE, &paintRect, m_pWindow, "base",
2680 0 : -rControlRectangle.Left(),
2681 0 : -rControlRectangle.Top(),
2682 0 : pixmapRect.GetWidth()+rControlRectangle.Left(),
2683 0 : pixmapRect.GetHeight()+rControlRectangle.Top());
2684 :
2685 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gNotebookWidget, nState, stateType );
2686 :
2687 0 : switch( nType )
2688 : {
2689 : case CTRL_TAB_BODY:
2690 0 : break;
2691 :
2692 : case CTRL_TAB_PANE:
2693 0 : gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
2694 0 : (char *)"notebook", 0, 0, pixmapRect.GetWidth(), pixmapRect.GetHeight(), GTK_POS_TOP, 0, 0 );
2695 0 : break;
2696 :
2697 : case CTRL_TAB_ITEM:
2698 : {
2699 0 : stateType = ( nState & CTRL_STATE_SELECTED ) ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE;
2700 :
2701 : // First draw the background
2702 0 : gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap,
2703 : GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base",
2704 0 : -rControlRectangle.Left(),
2705 0 : -rControlRectangle.Top(),
2706 0 : pixmapRect.GetWidth()+rControlRectangle.Left(),
2707 0 : pixmapRect.GetHeight()+rControlRectangle.Top());
2708 :
2709 : // Now the tab itself
2710 0 : if( nState & CTRL_STATE_ROLLOVER )
2711 0 : g_object_set_data(G_OBJECT(pixmap),tabPrelitDataName,(gpointer)TRUE);
2712 :
2713 0 : gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
2714 0 : (char *)"tab", (tabRect.Left() - pixmapRect.Left()), (tabRect.Top() - pixmapRect.Top()),
2715 0 : tabRect.GetWidth(), tabRect.GetHeight(), GTK_POS_BOTTOM );
2716 :
2717 0 : g_object_steal_data(G_OBJECT(pixmap),tabPrelitDataName);
2718 :
2719 0 : if ( nState & CTRL_STATE_SELECTED )
2720 : {
2721 : gtk_paint_flat_box( m_pWindow->style, pixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow,
2722 0 : "base", 0, (pixmapRect.GetHeight() - 1), pixmapRect.GetWidth(), 1 );
2723 : }
2724 0 : break;
2725 : }
2726 :
2727 : default:
2728 0 : break;
2729 : }
2730 :
2731 : // cache data
2732 0 : if( nType == CTRL_TAB_ITEM )
2733 0 : aCacheItems.Fill( nType, nState, pixmapRect, pixmap );
2734 : else
2735 0 : aCachePage.Fill( nType, nState, pixmapRect, pixmap );
2736 :
2737 0 : bool bSuccess = NWRenderPixmapToScreen(pixmap, pixmapRect);
2738 0 : g_object_unref( pixmap );
2739 0 : return bSuccess;
2740 : }
2741 :
2742 0 : bool GtkSalGraphics::NWPaintGTKListBox( GdkDrawable* gdkDrawable,
2743 : ControlType nType, ControlPart nPart,
2744 : const Rectangle& rControlRectangle,
2745 : const clipList& rClipList,
2746 : ControlState nState,
2747 : const ImplControlValue& aValue,
2748 : const OUString& rCaption )
2749 : {
2750 0 : Rectangle aIndicatorRect;
2751 : GtkStateType stateType;
2752 : GtkShadowType shadowType;
2753 : gint bInteriorFocus;
2754 : gint nFocusLineWidth;
2755 : gint nFocusPadding;
2756 : gint x,y,w,h;
2757 : GdkRectangle clipRect;
2758 :
2759 0 : NWEnsureGTKButton( m_nXScreen );
2760 0 : NWEnsureGTKOptionMenu( m_nXScreen );
2761 0 : NWEnsureGTKScrolledWindow( m_nXScreen );
2762 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
2763 :
2764 : // set up references to correct drawable and cliprect
2765 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
2766 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gOptionMenuWidget, nState, stateType );
2767 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gScrolledWindowWidget, nState, stateType );
2768 :
2769 0 : x = rControlRectangle.Left();
2770 0 : y = rControlRectangle.Top();
2771 0 : w = rControlRectangle.GetWidth();
2772 0 : h = rControlRectangle.GetHeight();
2773 :
2774 0 : if ( nPart != PART_WINDOW )
2775 : {
2776 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gOptionMenuWidget,
2777 : "interior_focus", &bInteriorFocus,
2778 : "focus_line_width", &nFocusLineWidth,
2779 : "focus_padding", &nFocusPadding,
2780 0 : (char *)NULL);
2781 : }
2782 :
2783 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
2784 : {
2785 0 : clipRect.x = it->Left();
2786 0 : clipRect.y = it->Top();
2787 0 : clipRect.width = it->GetWidth();
2788 0 : clipRect.height = it->GetHeight();
2789 :
2790 0 : if ( nPart != PART_WINDOW )
2791 : {
2792 : // Listboxes must paint opaque since some themes have alpha-channel enabled bodies
2793 : gtk_paint_flat_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
2794 0 : &clipRect, m_pWindow, "base", x, y, w, h);
2795 0 : gtk_paint_box( gWidgetData[m_nXScreen].gOptionMenuWidget->style, gdkDrawable, stateType, shadowType, &clipRect,
2796 0 : gWidgetData[m_nXScreen].gOptionMenuWidget, "optionmenu",
2797 0 : x, y, w, h);
2798 : aIndicatorRect = NWGetListBoxIndicatorRect( m_nXScreen, nType, nPart, rControlRectangle, nState,
2799 0 : aValue, rCaption );
2800 0 : gtk_paint_tab( gWidgetData[m_nXScreen].gOptionMenuWidget->style, gdkDrawable, stateType, shadowType, &clipRect,
2801 0 : gWidgetData[m_nXScreen].gOptionMenuWidget, "optionmenutab",
2802 0 : aIndicatorRect.Left(), aIndicatorRect.Top(),
2803 0 : aIndicatorRect.GetWidth(), aIndicatorRect.GetHeight() );
2804 : }
2805 : else
2806 : {
2807 0 : shadowType = GTK_SHADOW_IN;
2808 :
2809 0 : gtk_paint_shadow( gWidgetData[m_nXScreen].gScrolledWindowWidget->style, gdkDrawable, GTK_STATE_NORMAL, shadowType,
2810 0 : &clipRect, gWidgetData[m_nXScreen].gScrolledWindowWidget, "scrolled_window",
2811 0 : x, y, w, h );
2812 : }
2813 : }
2814 :
2815 0 : return true;
2816 : }
2817 :
2818 0 : bool GtkSalGraphics::NWPaintGTKToolbar(
2819 : GdkDrawable* gdkDrawable,
2820 : ControlType, ControlPart nPart,
2821 : const Rectangle& rControlRectangle,
2822 : const clipList& rClipList,
2823 : ControlState nState, const ImplControlValue& aValue,
2824 : const OUString& string)
2825 : {
2826 : GtkStateType stateType;
2827 : GtkShadowType shadowType;
2828 : gint x, y, w, h;
2829 0 : gint g_x=0, g_y=0, g_w=10, g_h=10;
2830 0 : GtkWidget* pButtonWidget = gWidgetData[m_nXScreen].gToolbarButtonWidget;
2831 : GdkRectangle clipRect;
2832 :
2833 0 : NWEnsureGTKToolbar( m_nXScreen );
2834 0 : if( nPart == PART_BUTTON ) // toolbar buttons cannot focus in gtk
2835 0 : nState &= ~CTRL_STATE_FOCUSED;
2836 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
2837 :
2838 0 : x = rControlRectangle.Left();
2839 0 : y = rControlRectangle.Top();
2840 0 : w = rControlRectangle.GetWidth();
2841 0 : h = rControlRectangle.GetHeight();
2842 :
2843 : // handle toolbar
2844 0 : if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
2845 : {
2846 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gToolbarWidget, nState, stateType );
2847 :
2848 0 : GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gToolbarWidget, GTK_SENSITIVE );
2849 0 : if ( nState & CTRL_STATE_ENABLED )
2850 0 : GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gToolbarWidget, GTK_SENSITIVE );
2851 :
2852 0 : if( nPart == PART_DRAW_BACKGROUND_HORZ )
2853 0 : gtk_toolbar_set_orientation( GTK_TOOLBAR(gWidgetData[m_nXScreen].gToolbarWidget), GTK_ORIENTATION_HORIZONTAL );
2854 : else
2855 0 : gtk_toolbar_set_orientation( GTK_TOOLBAR(gWidgetData[m_nXScreen].gToolbarWidget), GTK_ORIENTATION_VERTICAL );
2856 : }
2857 : // handle grip
2858 0 : else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
2859 : {
2860 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gHandleBoxWidget, nState, stateType );
2861 :
2862 0 : GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gHandleBoxWidget, GTK_SENSITIVE );
2863 0 : if ( nState & CTRL_STATE_ENABLED )
2864 0 : GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gHandleBoxWidget, GTK_SENSITIVE );
2865 :
2866 0 : gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(gWidgetData[m_nXScreen].gHandleBoxWidget), shadowType );
2867 :
2868 : // evaluate grip rect
2869 0 : if( aValue.getType() == CTRL_TOOLBAR )
2870 : {
2871 0 : const ToolbarValue* pVal = static_cast<const ToolbarValue*>(&aValue);
2872 0 : g_x = pVal->maGripRect.Left();
2873 0 : g_y = pVal->maGripRect.Top();
2874 0 : g_w = pVal->maGripRect.GetWidth();
2875 0 : g_h = pVal->maGripRect.GetHeight();
2876 0 : }
2877 : }
2878 : // handle button
2879 0 : else if( nPart == PART_BUTTON )
2880 : {
2881 0 : bool bPaintButton = (nState & CTRL_STATE_PRESSED)
2882 0 : || (nState & CTRL_STATE_ROLLOVER);
2883 0 : if( aValue.getTristateVal() == BUTTONVALUE_ON )
2884 : {
2885 0 : gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pButtonWidget),TRUE);
2886 0 : bPaintButton = true;
2887 : }
2888 : else
2889 0 : gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pButtonWidget),FALSE);
2890 :
2891 0 : NWSetWidgetState( pButtonWidget, nState, stateType );
2892 0 : gtk_widget_ensure_style( pButtonWidget );
2893 0 : if(bPaintButton)
2894 0 : NWPaintGTKButtonReal(pButtonWidget, gdkDrawable, 0, 0, rControlRectangle, rClipList, nState, aValue, string);
2895 : }
2896 :
2897 0 : if( nPart != PART_BUTTON )
2898 : {
2899 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
2900 : {
2901 0 : clipRect.x = it->Left();
2902 0 : clipRect.y = it->Top();
2903 0 : clipRect.width = it->GetWidth();
2904 0 : clipRect.height = it->GetHeight();
2905 :
2906 : // draw toolbar
2907 0 : if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
2908 : {
2909 0 : gtk_paint_flat_box( gWidgetData[m_nXScreen].gToolbarWidget->style,
2910 : gdkDrawable,
2911 : (GtkStateType)GTK_STATE_NORMAL,
2912 : GTK_SHADOW_NONE,
2913 : &clipRect,
2914 0 : gWidgetData[m_nXScreen].gToolbarWidget,
2915 : "base",
2916 0 : x, y, w, h );
2917 0 : gtk_paint_box( gWidgetData[m_nXScreen].gToolbarWidget->style,
2918 : gdkDrawable,
2919 : stateType,
2920 : shadowType,
2921 : &clipRect,
2922 0 : gWidgetData[m_nXScreen].gToolbarWidget,
2923 : "toolbar",
2924 0 : x, y, w, h );
2925 : }
2926 : // draw grip
2927 0 : else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
2928 : {
2929 0 : gtk_paint_handle( gWidgetData[m_nXScreen].gHandleBoxWidget->style,
2930 : gdkDrawable,
2931 : GTK_STATE_NORMAL,
2932 : GTK_SHADOW_OUT,
2933 : &clipRect,
2934 0 : gWidgetData[m_nXScreen].gHandleBoxWidget,
2935 : "handlebox",
2936 : g_x, g_y, g_w, g_h,
2937 : nPart == PART_THUMB_HORZ ?
2938 : GTK_ORIENTATION_HORIZONTAL :
2939 : GTK_ORIENTATION_VERTICAL
2940 0 : );
2941 : }
2942 0 : else if( nPart == PART_SEPARATOR_HORZ || nPart == PART_SEPARATOR_VERT )
2943 : {
2944 0 : const double shim = 0.2;
2945 :
2946 : #if GTK_CHECK_VERSION(2,10,0)
2947 0 : gint separator_height, separator_width, wide_separators = 0;
2948 :
2949 0 : gtk_widget_style_get (gWidgetData[m_nXScreen].gSeparator,
2950 : "wide-separators", &wide_separators,
2951 : "separator-width", &separator_width,
2952 : "separator-height", &separator_height,
2953 0 : NULL);
2954 :
2955 0 : if (wide_separators)
2956 : {
2957 0 : if (nPart == PART_SEPARATOR_VERT)
2958 0 : gtk_paint_box (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
2959 : GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
2960 0 : &clipRect, gWidgetData[m_nXScreen].gSeparator, "vseparator",
2961 0 : x + (w - separator_width) / 2, y + h * shim,
2962 0 : separator_width, h * (1 - 2*shim));
2963 : else
2964 0 : gtk_paint_box (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
2965 : GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
2966 0 : &clipRect, gWidgetData[m_nXScreen].gSeparator, "hseparator",
2967 0 : x + w * shim, y + (h - separator_width) / 2,
2968 0 : w * (1 - 2*shim), separator_width);
2969 : }
2970 : else
2971 : #endif
2972 : {
2973 0 : if (nPart == PART_SEPARATOR_VERT)
2974 0 : gtk_paint_vline (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
2975 : GTK_STATE_NORMAL,
2976 0 : &clipRect, gWidgetData[m_nXScreen].gSeparator, "vseparator",
2977 0 : y + h * shim, y + h * (1 - shim), x + w/2 - 1);
2978 : else
2979 0 : gtk_paint_hline (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
2980 : GTK_STATE_NORMAL,
2981 0 : &clipRect, gWidgetData[m_nXScreen].gSeparator, "hseparator",
2982 0 : x + w * shim, x + w * (1 - shim), y + h/2 - 1);
2983 : }
2984 : }
2985 : }
2986 : }
2987 :
2988 0 : return true;
2989 : }
2990 :
2991 0 : bool GtkSalGraphics::NWPaintGTKMenubar(
2992 : GdkDrawable* gdkDrawable,
2993 : ControlType, ControlPart nPart,
2994 : const Rectangle& rControlRectangle,
2995 : const clipList& rClipList,
2996 : ControlState nState, const ImplControlValue&,
2997 : const OUString& )
2998 : {
2999 : GtkStateType stateType;
3000 : GtkShadowType shadowType;
3001 0 : GtkShadowType selected_shadow_type = GTK_SHADOW_OUT;
3002 : gint x, y, w, h;
3003 : GdkRectangle clipRect;
3004 :
3005 0 : NWEnsureGTKMenubar( m_nXScreen );
3006 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
3007 :
3008 0 : x = rControlRectangle.Left();
3009 0 : y = rControlRectangle.Top();
3010 0 : w = rControlRectangle.GetWidth();
3011 0 : h = rControlRectangle.GetHeight();
3012 :
3013 0 : if( nPart == PART_MENU_ITEM )
3014 : {
3015 0 : if( nState & CTRL_STATE_SELECTED )
3016 : {
3017 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gMenuItemMenubarWidget,
3018 : "selected_shadow_type", &selected_shadow_type,
3019 0 : (char *)NULL);
3020 : }
3021 : }
3022 :
3023 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
3024 : {
3025 0 : clipRect.x = it->Left();
3026 0 : clipRect.y = it->Top();
3027 0 : clipRect.width = it->GetWidth();
3028 0 : clipRect.height = it->GetHeight();
3029 :
3030 : // handle Menubar
3031 0 : if( nPart == PART_ENTIRE_CONTROL )
3032 : {
3033 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gMenubarWidget, nState, stateType );
3034 :
3035 0 : GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gMenubarWidget, GTK_SENSITIVE );
3036 0 : if ( nState & CTRL_STATE_ENABLED )
3037 0 : GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gMenubarWidget, GTK_SENSITIVE );
3038 :
3039 : // for translucent menubar styles paint background first
3040 0 : gtk_paint_flat_box( gWidgetData[m_nXScreen].gMenubarWidget->style,
3041 : gdkDrawable,
3042 : GTK_STATE_NORMAL,
3043 : GTK_SHADOW_NONE,
3044 : &clipRect,
3045 0 : GTK_WIDGET(m_pWindow),
3046 : "base",
3047 0 : x, y, w, h );
3048 0 : gtk_paint_box( gWidgetData[m_nXScreen].gMenubarWidget->style,
3049 : gdkDrawable,
3050 : stateType,
3051 : shadowType,
3052 : &clipRect,
3053 0 : gWidgetData[m_nXScreen].gMenubarWidget,
3054 : "menubar",
3055 0 : x, y, w, h );
3056 : }
3057 :
3058 0 : else if( nPart == PART_MENU_ITEM )
3059 : {
3060 0 : if( nState & CTRL_STATE_SELECTED )
3061 : {
3062 0 : gtk_paint_box( gWidgetData[m_nXScreen].gMenuItemMenubarWidget->style,
3063 : gdkDrawable,
3064 : GTK_STATE_PRELIGHT,
3065 : selected_shadow_type,
3066 : &clipRect,
3067 0 : gWidgetData[m_nXScreen].gMenuItemMenubarWidget,
3068 : "menuitem",
3069 0 : x, y, w, h);
3070 : }
3071 : }
3072 : }
3073 :
3074 0 : return true;
3075 : }
3076 :
3077 0 : bool GtkSalGraphics::NWPaintGTKPopupMenu(
3078 : GdkDrawable* gdkDrawable,
3079 : ControlType, ControlPart nPart,
3080 : const Rectangle& rControlRectangle,
3081 : const clipList& rClipList,
3082 : ControlState nState, const ImplControlValue&,
3083 : const OUString& )
3084 : {
3085 : // #i50745# gtk does not draw disabled menu entries (and crux theme
3086 : // even crashes) in very old (Fedora Core 4 vintage) gtk's
3087 0 : if (gtk_major_version <= 2 && gtk_minor_version <= 8 &&
3088 0 : nPart == PART_MENU_ITEM && ! (nState & CTRL_STATE_ENABLED) )
3089 0 : return true;
3090 :
3091 : GtkStateType stateType;
3092 : GtkShadowType shadowType;
3093 0 : GtkShadowType selected_shadow_type = GTK_SHADOW_OUT;
3094 : gint x, y, w, h;
3095 : GdkRectangle clipRect;
3096 :
3097 0 : NWEnsureGTKMenu( m_nXScreen );
3098 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
3099 :
3100 0 : x = rControlRectangle.Left();
3101 0 : y = rControlRectangle.Top();
3102 0 : w = rControlRectangle.GetWidth();
3103 0 : h = rControlRectangle.GetHeight();
3104 :
3105 0 : if( nPart == PART_MENU_ITEM &&
3106 0 : ( nState & (CTRL_STATE_SELECTED|CTRL_STATE_ROLLOVER) ) )
3107 : {
3108 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gMenuItemMenuWidget,
3109 : "selected_shadow_type", &selected_shadow_type,
3110 0 : (char *)NULL);
3111 : }
3112 :
3113 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gMenuWidget, nState, stateType );
3114 :
3115 0 : GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gMenuWidget, GTK_SENSITIVE );
3116 0 : if ( nState & CTRL_STATE_ENABLED )
3117 0 : GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gMenuWidget, GTK_SENSITIVE );
3118 :
3119 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
3120 : {
3121 0 : clipRect.x = it->Left();
3122 0 : clipRect.y = it->Top();
3123 0 : clipRect.width = it->GetWidth();
3124 0 : clipRect.height = it->GetHeight();
3125 :
3126 0 : if( nPart == PART_ENTIRE_CONTROL )
3127 : {
3128 : // for translucent menubar styles paint background first
3129 0 : gtk_paint_flat_box( gWidgetData[m_nXScreen].gMenuWidget->style,
3130 : gdkDrawable,
3131 : GTK_STATE_NORMAL,
3132 : GTK_SHADOW_NONE,
3133 : &clipRect,
3134 0 : GTK_WIDGET(m_pWindow),
3135 : "base",
3136 0 : x, y, w, h );
3137 0 : gtk_paint_box( gWidgetData[m_nXScreen].gMenuWidget->style,
3138 : gdkDrawable,
3139 : GTK_STATE_NORMAL,
3140 : GTK_SHADOW_OUT,
3141 : &clipRect,
3142 0 : gWidgetData[m_nXScreen].gMenuWidget,
3143 : "menu",
3144 0 : x, y, w, h );
3145 : }
3146 0 : else if( nPart == PART_MENU_ITEM )
3147 : {
3148 0 : if( nState & (CTRL_STATE_SELECTED|CTRL_STATE_ROLLOVER) )
3149 : {
3150 0 : if( nState & CTRL_STATE_ENABLED )
3151 0 : gtk_paint_box( gWidgetData[m_nXScreen].gMenuItemMenuWidget->style,
3152 : gdkDrawable,
3153 : GTK_STATE_PRELIGHT,
3154 : selected_shadow_type,
3155 : &clipRect,
3156 0 : gWidgetData[m_nXScreen].gMenuItemMenuWidget,
3157 : "menuitem",
3158 0 : x, y, w, h);
3159 : }
3160 : }
3161 0 : else if( nPart == PART_MENU_ITEM_CHECK_MARK || nPart == PART_MENU_ITEM_RADIO_MARK )
3162 : {
3163 : GtkWidget* pWidget = (nPart == PART_MENU_ITEM_CHECK_MARK) ?
3164 0 : gWidgetData[m_nXScreen].gMenuItemCheckMenuWidget :
3165 0 : gWidgetData[m_nXScreen].gMenuItemRadioMenuWidget;
3166 :
3167 : GtkStateType nStateType;
3168 : GtkShadowType nShadowType;
3169 0 : NWConvertVCLStateToGTKState( nState, &nStateType, &nShadowType );
3170 :
3171 0 : if ( (nState & CTRL_STATE_SELECTED) && (nState & CTRL_STATE_ENABLED) )
3172 0 : nStateType = GTK_STATE_PRELIGHT;
3173 :
3174 0 : NWSetWidgetState( pWidget, nState, nStateType );
3175 :
3176 0 : if ( nPart == PART_MENU_ITEM_CHECK_MARK )
3177 : {
3178 : gtk_paint_check( pWidget->style,
3179 : gdkDrawable,
3180 : nStateType,
3181 : nShadowType,
3182 : &clipRect,
3183 0 : gWidgetData[m_nXScreen].gMenuItemMenuWidget,
3184 : "check",
3185 0 : x, y, w, h );
3186 : }
3187 : else
3188 : {
3189 : gtk_paint_option( pWidget->style,
3190 : gdkDrawable,
3191 : nStateType,
3192 : nShadowType,
3193 : &clipRect,
3194 0 : gWidgetData[m_nXScreen].gMenuItemMenuWidget,
3195 : "option",
3196 0 : x, y, w, h );
3197 0 : }
3198 : }
3199 0 : else if( nPart == PART_MENU_SEPARATOR )
3200 : {
3201 0 : gtk_paint_hline( gWidgetData[m_nXScreen].gMenuItemSeparatorMenuWidget->style,
3202 : gdkDrawable,
3203 : GTK_STATE_NORMAL,
3204 : &clipRect,
3205 0 : gWidgetData[m_nXScreen].gMenuItemSeparatorMenuWidget,
3206 : "menuitem",
3207 0 : x, x + w, y + h / 2);
3208 : }
3209 0 : else if( nPart == PART_MENU_SUBMENU_ARROW )
3210 : {
3211 : GtkStateType nStateType;
3212 : GtkShadowType nShadowType;
3213 0 : NWConvertVCLStateToGTKState( nState, &nStateType, &nShadowType );
3214 :
3215 0 : if ( (nState & CTRL_STATE_SELECTED) && (nState & CTRL_STATE_ENABLED) )
3216 0 : nStateType = GTK_STATE_PRELIGHT;
3217 :
3218 0 : NWSetWidgetState( gWidgetData[m_nXScreen].gMenuItemMenuWidget,
3219 0 : nState, nStateType );
3220 :
3221 : GtkArrowType eArrow;
3222 0 : if( Application::GetSettings().GetLayoutRTL() )
3223 0 : eArrow = GTK_ARROW_LEFT;
3224 : else
3225 0 : eArrow = GTK_ARROW_RIGHT;
3226 :
3227 0 : gtk_paint_arrow( gWidgetData[m_nXScreen].gMenuItemMenuWidget->style,
3228 : gdkDrawable,
3229 : nStateType,
3230 : nShadowType,
3231 : &clipRect,
3232 0 : gWidgetData[m_nXScreen].gMenuItemMenuWidget,
3233 : "menuitem",
3234 : eArrow, TRUE,
3235 0 : x, y, w, h);
3236 : }
3237 : }
3238 :
3239 0 : return true;
3240 : }
3241 :
3242 0 : bool GtkSalGraphics::NWPaintGTKTooltip(
3243 : GdkDrawable* gdkDrawable,
3244 : ControlType, ControlPart,
3245 : const Rectangle& rControlRectangle,
3246 : const clipList& rClipList,
3247 : ControlState, const ImplControlValue&,
3248 : const OUString& )
3249 : {
3250 0 : NWEnsureGTKTooltip( m_nXScreen );
3251 :
3252 : gint x, y, w, h;
3253 : GdkRectangle clipRect;
3254 :
3255 0 : x = rControlRectangle.Left();
3256 0 : y = rControlRectangle.Top();
3257 0 : w = rControlRectangle.GetWidth();
3258 0 : h = rControlRectangle.GetHeight();
3259 :
3260 0 : for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
3261 : {
3262 0 : clipRect.x = it->Left();
3263 0 : clipRect.y = it->Top();
3264 0 : clipRect.width = it->GetWidth();
3265 0 : clipRect.height = it->GetHeight();
3266 :
3267 0 : gtk_paint_flat_box( gWidgetData[m_nXScreen].gTooltipPopup->style,
3268 : gdkDrawable,
3269 : GTK_STATE_NORMAL,
3270 : GTK_SHADOW_OUT,
3271 : &clipRect,
3272 0 : gWidgetData[m_nXScreen].gTooltipPopup,
3273 : "tooltip",
3274 0 : x, y, w, h );
3275 : }
3276 :
3277 0 : return true;
3278 : }
3279 :
3280 0 : bool GtkSalGraphics::NWPaintGTKListNode(
3281 : GdkDrawable*,
3282 : ControlType, ControlPart,
3283 : const Rectangle& rControlRectangle,
3284 : const clipList&,
3285 : ControlState nState, const ImplControlValue& rValue,
3286 : const OUString& )
3287 : {
3288 0 : NWEnsureGTKTreeView( m_nXScreen );
3289 :
3290 0 : Rectangle aRect( rControlRectangle );
3291 0 : aRect.Left() -= 2;
3292 0 : aRect.Right() += 2;
3293 0 : aRect.Top() -= 2;
3294 0 : aRect.Bottom() += 2;
3295 : gint w, h;
3296 0 : w = aRect.GetWidth();
3297 0 : h = aRect.GetHeight();
3298 :
3299 : GtkStateType stateType;
3300 : GtkShadowType shadowType;
3301 0 : NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
3302 :
3303 0 : ButtonValue aButtonValue = rValue.getTristateVal();
3304 0 : GtkExpanderStyle eStyle = GTK_EXPANDER_EXPANDED;
3305 :
3306 0 : switch( aButtonValue )
3307 : {
3308 0 : case BUTTONVALUE_ON: eStyle = GTK_EXPANDER_EXPANDED;break;
3309 0 : case BUTTONVALUE_OFF: eStyle = GTK_EXPANDER_COLLAPSED; break;
3310 : default:
3311 0 : break;
3312 : }
3313 :
3314 0 : GdkPixmap* pixmap = NWGetPixmapFromScreen( aRect );
3315 0 : if( ! pixmap )
3316 0 : return false;
3317 :
3318 0 : GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
3319 0 : gtk_paint_expander( gWidgetData[m_nXScreen].gTreeView->style,
3320 : pixDrawable,
3321 : stateType,
3322 : NULL,
3323 0 : gWidgetData[m_nXScreen].gTreeView,
3324 : "treeview",
3325 : w/2, h/2,
3326 0 : eStyle );
3327 :
3328 0 : bool bRet = NWRenderPixmapToScreen( pixmap, aRect );
3329 0 : g_object_unref( pixmap );
3330 :
3331 0 : return bRet;
3332 : }
3333 :
3334 0 : bool GtkSalGraphics::NWPaintGTKProgress(
3335 : GdkDrawable*,
3336 : ControlType, ControlPart,
3337 : const Rectangle& rControlRectangle,
3338 : const clipList&,
3339 : ControlState, const ImplControlValue& rValue,
3340 : const OUString& )
3341 : {
3342 0 : NWEnsureGTKProgressBar( m_nXScreen );
3343 :
3344 : gint w, h;
3345 0 : w = rControlRectangle.GetWidth();
3346 0 : h = rControlRectangle.GetHeight();
3347 :
3348 0 : long nProgressWidth = rValue.getNumericVal();
3349 :
3350 0 : GdkPixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) );
3351 0 : if( ! pixmap )
3352 0 : return false;
3353 :
3354 0 : GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
3355 :
3356 : // paint background
3357 0 : gtk_paint_flat_box(gWidgetData[m_nXScreen].gProgressBar->style, pixDrawable,
3358 : GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base",
3359 0 : -rControlRectangle.Left(),-rControlRectangle.Top(),
3360 0 : rControlRectangle.Left()+w,rControlRectangle.Top()+h);
3361 :
3362 0 : gtk_paint_flat_box( gWidgetData[m_nXScreen].gProgressBar->style,
3363 : pixDrawable,
3364 : GTK_STATE_NORMAL,
3365 : GTK_SHADOW_NONE,
3366 : NULL,
3367 0 : gWidgetData[m_nXScreen].gProgressBar,
3368 : "trough",
3369 0 : 0, 0, w, h );
3370 0 : if( nProgressWidth > 0 )
3371 : {
3372 : // paint progress
3373 0 : if( Application::GetSettings().GetLayoutRTL() )
3374 : {
3375 0 : gtk_paint_box( gWidgetData[m_nXScreen].gProgressBar->style,
3376 : pixDrawable,
3377 : GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
3378 : NULL,
3379 0 : gWidgetData[m_nXScreen].gProgressBar,
3380 : "bar",
3381 0 : w-nProgressWidth, 0, nProgressWidth, h
3382 0 : );
3383 : }
3384 : else
3385 : {
3386 0 : gtk_paint_box( gWidgetData[m_nXScreen].gProgressBar->style,
3387 : pixDrawable,
3388 : GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
3389 : NULL,
3390 0 : gWidgetData[m_nXScreen].gProgressBar,
3391 : "bar",
3392 : 0, 0, nProgressWidth, h
3393 0 : );
3394 : }
3395 : }
3396 :
3397 0 : bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
3398 0 : g_object_unref( pixmap );
3399 :
3400 0 : return bRet;
3401 : }
3402 :
3403 0 : bool GtkSalGraphics::NWPaintGTKSlider(
3404 : GdkDrawable*,
3405 : ControlType, ControlPart nPart,
3406 : const Rectangle& rControlRectangle,
3407 : const clipList&,
3408 : ControlState nState, const ImplControlValue& rValue,
3409 : const OUString& )
3410 : {
3411 : OSL_ASSERT( rValue.getType() == CTRL_SLIDER );
3412 0 : NWEnsureGTKSlider( m_nXScreen );
3413 :
3414 : gint w, h;
3415 0 : w = rControlRectangle.GetWidth();
3416 0 : h = rControlRectangle.GetHeight();
3417 :
3418 0 : const SliderValue* pVal = static_cast<const SliderValue*>(&rValue);
3419 :
3420 0 : GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle );
3421 0 : if( ! pixmap )
3422 0 : return false;
3423 :
3424 0 : GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
3425 : GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA)
3426 0 : ? GTK_WIDGET(gWidgetData[m_nXScreen].gHScale)
3427 0 : : GTK_WIDGET(gWidgetData[m_nXScreen].gVScale);
3428 0 : const gchar* pDetail = (nPart == PART_TRACK_HORZ_AREA) ? "hscale" : "vscale";
3429 0 : GtkOrientation eOri = (nPart == PART_TRACK_HORZ_AREA) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
3430 0 : gint slider_width = 10;
3431 0 : gint slider_length = 10;
3432 0 : gint trough_border = 0;
3433 : gtk_widget_style_get( pWidget,
3434 : "slider-width", &slider_width,
3435 : "slider-length", &slider_length,
3436 : "trough-border", &trough_border,
3437 0 : NULL);
3438 :
3439 0 : GtkStateType eState = (nState & CTRL_STATE_ENABLED) ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE;
3440 0 : if( nPart == PART_TRACK_HORZ_AREA )
3441 : {
3442 : gtk_paint_box( pWidget->style,
3443 : pixDrawable,
3444 : eState,
3445 : GTK_SHADOW_IN,
3446 : NULL,
3447 : pWidget,
3448 : "trough",
3449 0 : 0, (h-slider_width-2*trough_border)/2, w, slider_width + 2*trough_border);
3450 0 : gint x = (w - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin);
3451 : gtk_paint_slider( pWidget->style,
3452 : pixDrawable,
3453 : eState,
3454 : GTK_SHADOW_OUT,
3455 : NULL,
3456 : pWidget,
3457 : pDetail,
3458 0 : x, (h-slider_width)/2,
3459 : slider_length, slider_width,
3460 0 : eOri );
3461 : }
3462 : else
3463 : {
3464 : gtk_paint_box( pWidget->style,
3465 : pixDrawable,
3466 : eState,
3467 : GTK_SHADOW_IN,
3468 : NULL,
3469 : pWidget,
3470 : "trough",
3471 0 : (w-slider_width-2*trough_border)/2, 0, slider_width + 2*trough_border, h);
3472 0 : gint y = (h - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin);
3473 : gtk_paint_slider( pWidget->style,
3474 : pixDrawable,
3475 : eState,
3476 : GTK_SHADOW_OUT,
3477 : NULL,
3478 : pWidget,
3479 : pDetail,
3480 0 : (w-slider_width)/2, y,
3481 : slider_width, slider_length,
3482 0 : eOri );
3483 : }
3484 :
3485 0 : bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
3486 0 : g_object_unref( pixmap );
3487 :
3488 0 : return bRet;
3489 : }
3490 :
3491 0 : static int getFrameWidth(GtkWidget* widget)
3492 : {
3493 0 : return widget->style->xthickness;
3494 : }
3495 :
3496 0 : static Rectangle NWGetListBoxButtonRect( SalX11Screen nScreen,
3497 : ControlType,
3498 : ControlPart nPart,
3499 : Rectangle aAreaRect,
3500 : ControlState,
3501 : const ImplControlValue&,
3502 : const OUString& )
3503 : {
3504 0 : Rectangle aPartRect;
3505 0 : GtkRequisition *pIndicatorSize = NULL;
3506 0 : GtkBorder *pIndicatorSpacing = NULL;
3507 0 : gint width = 13; // GTK+ default
3508 0 : gint right = 5; // GTK+ default
3509 0 : gint nButtonAreaWidth = 0;
3510 0 : gint xthickness = 0;
3511 :
3512 0 : NWEnsureGTKOptionMenu( nScreen );
3513 :
3514 0 : gtk_widget_style_get( gWidgetData[nScreen].gOptionMenuWidget,
3515 : "indicator_size", &pIndicatorSize,
3516 0 : "indicator_spacing",&pIndicatorSpacing, (char *)NULL);
3517 :
3518 0 : if ( pIndicatorSize )
3519 0 : width = pIndicatorSize->width;
3520 :
3521 0 : if ( pIndicatorSpacing )
3522 0 : right = pIndicatorSpacing->right;
3523 :
3524 0 : Size aPartSize( 0, aAreaRect.GetHeight() );
3525 0 : Point aPartPos ( 0, aAreaRect.Top() );
3526 :
3527 0 : xthickness = gWidgetData[nScreen].gOptionMenuWidget->style->xthickness;
3528 0 : nButtonAreaWidth = width + right + (xthickness * 2);
3529 0 : switch( nPart )
3530 : {
3531 : case PART_BUTTON_DOWN:
3532 0 : aPartSize.Width() = nButtonAreaWidth;
3533 0 : aPartPos.X() = aAreaRect.Left() + aAreaRect.GetWidth() - aPartSize.Width();
3534 0 : break;
3535 :
3536 : case PART_SUB_EDIT:
3537 0 : aPartSize.Width() = aAreaRect.GetWidth() - nButtonAreaWidth - xthickness;
3538 0 : if( Application::GetSettings().GetLayoutRTL() )
3539 0 : aPartPos.X() = aAreaRect.Left() + nButtonAreaWidth;
3540 : else
3541 0 : aPartPos.X() = aAreaRect.Left() + xthickness;
3542 0 : break;
3543 :
3544 : default:
3545 0 : aPartSize.Width() = aAreaRect.GetWidth();
3546 0 : aPartPos.X() = aAreaRect.Left();
3547 0 : break;
3548 : }
3549 0 : aPartRect = Rectangle( aPartPos, aPartSize );
3550 :
3551 0 : if ( pIndicatorSize )
3552 0 : gtk_requisition_free( pIndicatorSize );
3553 0 : if ( pIndicatorSpacing )
3554 0 : gtk_border_free( pIndicatorSpacing );
3555 :
3556 0 : return( aPartRect );
3557 : }
3558 :
3559 0 : static Rectangle NWGetListBoxIndicatorRect( SalX11Screen nScreen,
3560 : ControlType,
3561 : ControlPart,
3562 : Rectangle aAreaRect,
3563 : ControlState,
3564 : const ImplControlValue&,
3565 : const OUString& )
3566 : {
3567 0 : Rectangle aIndicatorRect;
3568 0 : GtkRequisition *pIndicatorSize = NULL;
3569 0 : GtkBorder *pIndicatorSpacing = NULL;
3570 0 : gint width = 13; // GTK+ default
3571 0 : gint height = 13; // GTK+ default
3572 0 : gint right = 5; // GTK+ default
3573 : gint x;
3574 :
3575 0 : NWEnsureGTKOptionMenu( nScreen );
3576 :
3577 0 : gtk_widget_style_get( gWidgetData[nScreen].gOptionMenuWidget,
3578 : "indicator_size", &pIndicatorSize,
3579 0 : "indicator_spacing",&pIndicatorSpacing, (char *)NULL);
3580 :
3581 0 : if ( pIndicatorSize )
3582 : {
3583 0 : width = pIndicatorSize->width;
3584 0 : height = pIndicatorSize->height;
3585 : }
3586 :
3587 0 : if ( pIndicatorSpacing )
3588 0 : right = pIndicatorSpacing->right;
3589 :
3590 0 : aIndicatorRect.SetSize( Size( width, height ) );
3591 0 : if( Application::GetSettings().GetLayoutRTL() )
3592 0 : x = aAreaRect.Left() + right;
3593 : else
3594 0 : x = aAreaRect.Left() + aAreaRect.GetWidth() - width - right - gWidgetData[nScreen].gOptionMenuWidget->style->xthickness;
3595 0 : aIndicatorRect.SetPos( Point( x, aAreaRect.Top() + ((aAreaRect.GetHeight() - height) / 2) ) );
3596 :
3597 : // If height is odd, move the indicator down 1 pixel
3598 0 : if ( aIndicatorRect.GetHeight() % 2 )
3599 0 : aIndicatorRect.Move( 0, 1 );
3600 :
3601 0 : if ( pIndicatorSize )
3602 0 : gtk_requisition_free( pIndicatorSize );
3603 0 : if ( pIndicatorSpacing )
3604 0 : gtk_border_free( pIndicatorSpacing );
3605 :
3606 0 : return( aIndicatorRect );
3607 : }
3608 :
3609 0 : static Rectangle NWGetToolbarRect( SalX11Screen nScreen,
3610 : ControlType,
3611 : ControlPart nPart,
3612 : Rectangle aAreaRect,
3613 : ControlState,
3614 : const ImplControlValue&,
3615 : const OUString& )
3616 : {
3617 0 : Rectangle aRet;
3618 :
3619 0 : if( nPart == PART_DRAW_BACKGROUND_HORZ ||
3620 : nPart == PART_DRAW_BACKGROUND_VERT )
3621 0 : aRet = aAreaRect;
3622 0 : else if( nPart == PART_THUMB_HORZ )
3623 0 : aRet = Rectangle( Point( 0, 0 ), Size( aAreaRect.GetWidth(), 10 ) );
3624 0 : else if( nPart == PART_THUMB_VERT )
3625 0 : aRet = Rectangle( Point( 0, 0 ), Size( 10, aAreaRect.GetHeight() ) );
3626 0 : else if( nPart == PART_BUTTON )
3627 : {
3628 0 : aRet = aAreaRect;
3629 :
3630 0 : NWEnsureGTKToolbar( nScreen );
3631 :
3632 : gint nMinWidth =
3633 0 : 2*gWidgetData[nScreen].gToolbarButtonWidget->style->xthickness
3634 0 : + 1 // CHILD_SPACING constant, found in gtk_button.c
3635 0 : + 3*gWidgetData[nScreen].gToolbarButtonWidget->style->xthickness; // Murphy factor
3636 : gint nMinHeight =
3637 0 : 2*gWidgetData[nScreen].gToolbarButtonWidget->style->ythickness
3638 0 : + 1 // CHILD_SPACING constant, found in gtk_button.c
3639 0 : + 3*gWidgetData[nScreen].gToolbarButtonWidget->style->ythickness; // Murphy factor
3640 :
3641 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gToolbarButtonWidget );
3642 0 : if( aAreaRect.GetWidth() < nMinWidth )
3643 0 : aRet.Right() = aRet.Left() + nMinWidth;
3644 0 : if( aAreaRect.GetHeight() < nMinHeight )
3645 0 : aRet.Bottom() = aRet.Top() + nMinHeight;
3646 : }
3647 :
3648 0 : return aRet;
3649 : }
3650 :
3651 : /************************************************************************
3652 : * helper for GtkSalFrame
3653 : ************************************************************************/
3654 0 : static inline Color getColor( const GdkColor& rCol )
3655 : {
3656 0 : return Color( rCol.red >> 8, rCol.green >> 8, rCol.blue >> 8 );
3657 : }
3658 :
3659 : #if OSL_DEBUG_LEVEL > 1
3660 :
3661 : void printColor( const char* name, const GdkColor& rCol )
3662 : {
3663 : std::fprintf( stderr, " %s = 0x%2x 0x%2x 0x%2x\n",
3664 : name,
3665 : rCol.red >> 8, rCol.green >> 8, rCol.blue >> 8 );
3666 : }
3667 :
3668 : void printStyleColors( GtkStyle* pStyle )
3669 : {
3670 : static const char* pStates[] = { "NORMAL", "ACTIVE", "PRELIGHT", "SELECTED", "INSENSITIVE" };
3671 :
3672 : for( int i = 0; i < 5; i++ )
3673 : {
3674 : std::fprintf( stderr, "state %s colors:\n", pStates[i] );
3675 : printColor( "bg ", pStyle->bg[i] );
3676 : printColor( "fg ", pStyle->fg[i] );
3677 : printColor( "light ", pStyle->light[i] );
3678 : printColor( "dark ", pStyle->dark[i] );
3679 : printColor( "mid ", pStyle->mid[i] );
3680 : printColor( "text ", pStyle->text[i] );
3681 : printColor( "base ", pStyle->base[i] );
3682 : printColor( "text_aa", pStyle->text_aa[i] );
3683 : }
3684 : }
3685 : #endif
3686 :
3687 0 : void GtkSalGraphics::signalSettingsNotify( GObject *pSettings, GParamSpec *pSpec, gpointer )
3688 : {
3689 0 : g_return_if_fail( pSpec != NULL );
3690 :
3691 0 : if( !strcmp( pSpec->name, "gtk-fontconfig-timestamp" ) )
3692 0 : GtkSalGraphics::refreshFontconfig( GTK_SETTINGS( pSettings ) );
3693 : }
3694 :
3695 0 : void GtkSalGraphics::refreshFontconfig( GtkSettings *pSettings )
3696 : {
3697 0 : guint latest_fontconfig_timestamp = 0;
3698 : static guint our_fontconfig_timestamp = 0;
3699 0 : g_object_get( pSettings, "gtk-fontconfig-timestamp", &latest_fontconfig_timestamp, (char *)NULL );
3700 0 : if (latest_fontconfig_timestamp != our_fontconfig_timestamp)
3701 : {
3702 0 : bool bFirstTime = our_fontconfig_timestamp == 0;
3703 0 : our_fontconfig_timestamp = latest_fontconfig_timestamp;
3704 0 : if (!bFirstTime)
3705 : {
3706 0 : psp::PrintFontManager::get().initialize();
3707 : }
3708 : }
3709 0 : }
3710 :
3711 0 : void GtkSalGraphics::updateSettings( AllSettings& rSettings )
3712 : {
3713 0 : GdkScreen* pScreen = gtk_widget_get_screen( m_pWindow );
3714 0 : gtk_widget_ensure_style( m_pWindow );
3715 0 : GtkStyle* pStyle = gtk_widget_get_style( m_pWindow );
3716 0 : GtkSettings* pSettings = gtk_widget_get_settings( m_pWindow );
3717 0 : StyleSettings aStyleSet = rSettings.GetStyleSettings();
3718 :
3719 : // Listen for font changes
3720 0 : if( !g_object_get_data( G_OBJECT( pSettings ), "libo:listening" ) )
3721 : {
3722 0 : g_object_set_data( G_OBJECT( pSettings ), "libo:listening",
3723 0 : GUINT_TO_POINTER( 1 ) );
3724 0 : g_signal_connect_data( G_OBJECT( pSettings ), "notify",
3725 : G_CALLBACK( signalSettingsNotify ),
3726 0 : NULL, NULL, G_CONNECT_AFTER );
3727 : }
3728 :
3729 0 : refreshFontconfig( pSettings );
3730 :
3731 : // get the widgets in place
3732 0 : NWEnsureGTKMenu( m_nXScreen );
3733 0 : NWEnsureGTKMenubar( m_nXScreen );
3734 0 : NWEnsureGTKScrollbars( m_nXScreen );
3735 0 : NWEnsureGTKEditBox( m_nXScreen );
3736 0 : NWEnsureGTKTooltip( m_nXScreen );
3737 0 : NWEnsureGTKDialog( m_nXScreen );
3738 0 : NWEnsureGTKFrame( m_nXScreen );
3739 :
3740 : #if OSL_DEBUG_LEVEL > 2
3741 : printStyleColors( pStyle );
3742 : #endif
3743 :
3744 : // text colors
3745 0 : Color aTextColor = getColor( pStyle->text[GTK_STATE_NORMAL] );
3746 0 : aStyleSet.SetDialogTextColor( aTextColor );
3747 0 : aStyleSet.SetWindowTextColor( aTextColor );
3748 0 : aStyleSet.SetFieldTextColor( aTextColor );
3749 0 : aTextColor = getColor( pStyle->fg[GTK_STATE_NORMAL] );
3750 0 : aStyleSet.SetButtonTextColor( aTextColor );
3751 0 : aStyleSet.SetRadioCheckTextColor( aTextColor );
3752 0 : aStyleSet.SetGroupTextColor( aTextColor );
3753 0 : aStyleSet.SetLabelTextColor( aTextColor );
3754 0 : aStyleSet.SetInfoTextColor( aTextColor );
3755 :
3756 : // Tooltip colors
3757 0 : GtkStyle* pTooltipStyle = gtk_widget_get_style( gWidgetData[m_nXScreen].gTooltipPopup );
3758 0 : aTextColor = getColor( pTooltipStyle->fg[ GTK_STATE_NORMAL ] );
3759 0 : aStyleSet.SetHelpTextColor( aTextColor );
3760 :
3761 0 : DialogStyle aDialogStyle(aStyleSet.GetDialogStyle());
3762 0 : gtk_widget_style_get (gWidgetData[m_nXScreen].gDialog,
3763 : "content-area-border", &aDialogStyle.content_area_border,
3764 : "content-area-spacing", &aDialogStyle.content_area_spacing,
3765 : "button-spacing", &aDialogStyle.button_spacing,
3766 : "action-area-border", &aDialogStyle.action_area_border,
3767 0 : NULL);
3768 0 : aStyleSet.SetDialogStyle(aDialogStyle);
3769 :
3770 0 : FrameStyle aFrameStyle(aStyleSet.GetFrameStyle());
3771 : aFrameStyle.left = aFrameStyle.right =
3772 0 : gWidgetData[m_nXScreen].gFrame->style->xthickness;
3773 : aFrameStyle.top = aFrameStyle.bottom =
3774 0 : gWidgetData[m_nXScreen].gFrame->style->ythickness;
3775 0 : aStyleSet.SetFrameStyle(aFrameStyle);
3776 :
3777 : // mouse over text colors
3778 0 : aTextColor = getColor( pStyle->fg[ GTK_STATE_PRELIGHT ] );
3779 0 : aStyleSet.SetButtonRolloverTextColor( aTextColor );
3780 0 : aStyleSet.SetFieldRolloverTextColor( aTextColor );
3781 :
3782 : // background colors
3783 0 : Color aBackColor = getColor( pStyle->bg[GTK_STATE_NORMAL] );
3784 0 : Color aBackFieldColor = getColor( pStyle->base[ GTK_STATE_NORMAL ] );
3785 0 : aStyleSet.Set3DColors( aBackColor );
3786 0 : aStyleSet.SetFaceColor( aBackColor );
3787 0 : aStyleSet.SetDialogColor( aBackColor );
3788 0 : aStyleSet.SetWorkspaceColor( aBackColor );
3789 0 : aStyleSet.SetFieldColor( aBackFieldColor );
3790 0 : aStyleSet.SetWindowColor( aBackFieldColor );
3791 0 : aStyleSet.SetCheckedColorSpecialCase( );
3792 :
3793 : // highlighting colors
3794 0 : Color aHighlightColor = getColor( pStyle->base[GTK_STATE_SELECTED] );
3795 0 : Color aHighlightTextColor = getColor( pStyle->text[GTK_STATE_SELECTED] );
3796 0 : aStyleSet.SetHighlightColor( aHighlightColor );
3797 0 : aStyleSet.SetHighlightTextColor( aHighlightTextColor );
3798 :
3799 0 : if( ! gtk_check_version( 2, 10, 0 ) ) // link colors came in with 2.10, avoid an assertion
3800 : {
3801 : // hyperlink colors
3802 0 : GdkColor *link_color = NULL;
3803 0 : gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL);
3804 0 : if (link_color)
3805 : {
3806 0 : aStyleSet.SetLinkColor(getColor(*link_color));
3807 0 : gdk_color_free (link_color);
3808 0 : link_color = NULL;
3809 : }
3810 0 : gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL);
3811 0 : if (link_color)
3812 : {
3813 0 : aStyleSet.SetVisitedLinkColor(getColor(*link_color));
3814 0 : gdk_color_free (link_color);
3815 : }
3816 : }
3817 :
3818 : // Tab colors
3819 0 : aStyleSet.SetActiveTabColor( aBackFieldColor ); // same as the window color.
3820 0 : Color aSelectedBackColor = getColor( pStyle->bg[GTK_STATE_ACTIVE] );
3821 0 : aStyleSet.SetInactiveTabColor( aSelectedBackColor );
3822 :
3823 : // menu disabled entries handling
3824 0 : aStyleSet.SetSkipDisabledInMenus( true );
3825 0 : aStyleSet.SetAcceleratorsInContextMenus( false );
3826 : // menu colors
3827 0 : GtkStyle* pMenuStyle = gtk_widget_get_style( gWidgetData[m_nXScreen].gMenuWidget );
3828 0 : GtkStyle* pMenuItemStyle = gtk_rc_get_style( gWidgetData[m_nXScreen].gMenuItemMenuWidget );
3829 0 : GtkStyle* pMenubarStyle = gtk_rc_get_style( gWidgetData[m_nXScreen].gMenubarWidget );
3830 0 : GtkStyle* pMenuTextStyle = gtk_rc_get_style( gtk_bin_get_child( GTK_BIN(gWidgetData[m_nXScreen].gMenuItemMenuWidget) ) );
3831 :
3832 0 : aBackColor = getColor( pMenubarStyle->bg[GTK_STATE_NORMAL] );
3833 0 : aStyleSet.SetMenuBarColor( aBackColor );
3834 0 : aStyleSet.SetMenuBarRolloverColor( aBackColor );
3835 0 : aBackColor = getColor( pMenuStyle->bg[GTK_STATE_NORMAL] );
3836 0 : aTextColor = getColor( pMenuTextStyle->fg[GTK_STATE_NORMAL] );
3837 0 : aStyleSet.SetMenuColor( aBackColor );
3838 0 : aStyleSet.SetMenuTextColor( aTextColor );
3839 :
3840 0 : aTextColor = aStyleSet.GetPersonaMenuBarTextColor().get_value_or( getColor( pMenubarStyle->fg[GTK_STATE_NORMAL] ) );
3841 0 : aStyleSet.SetMenuBarTextColor( aTextColor );
3842 0 : aStyleSet.SetMenuBarRolloverTextColor( aTextColor );
3843 :
3844 : #if OSL_DEBUG_LEVEL > 1
3845 : std::fprintf( stderr, "==\n" );
3846 : std::fprintf( stderr, "MenuColor = %x (%d)\n", (int)aStyleSet.GetMenuColor().GetColor(), aStyleSet.GetMenuColor().GetLuminance() );
3847 : std::fprintf( stderr, "MenuTextColor = %x (%d)\n", (int)aStyleSet.GetMenuTextColor().GetColor(), aStyleSet.GetMenuTextColor().GetLuminance() );
3848 : std::fprintf( stderr, "MenuBarColor = %x (%d)\n", (int)aStyleSet.GetMenuBarColor().GetColor(), aStyleSet.GetMenuBarColor().GetLuminance() );
3849 : std::fprintf( stderr, "MenuBarRolloverColor = %x (%d)\n", (int)aStyleSet.GetMenuBarRolloverColor().GetColor(), aStyleSet.GetMenuBarRolloverColor().GetLuminance() );
3850 : std::fprintf( stderr, "MenuBarTextColor = %x (%d)\n", (int)aStyleSet.GetMenuBarTextColor().GetColor(), aStyleSet.GetMenuBarTextColor().GetLuminance() );
3851 : std::fprintf( stderr, "MenuBarRolloverTextColor = %x (%d)\n", (int)aStyleSet.GetMenuBarRolloverTextColor().GetColor(), aStyleSet.GetMenuBarRolloverTextColor().GetLuminance() );
3852 : std::fprintf( stderr, "LightColor = %x (%d)\n", (int)aStyleSet.GetLightColor().GetColor(), aStyleSet.GetLightColor().GetLuminance() );
3853 : std::fprintf( stderr, "ShadowColor = %x (%d)\n", (int)aStyleSet.GetShadowColor().GetColor(), aStyleSet.GetShadowColor().GetLuminance() );
3854 : std::fprintf( stderr, "DarkShadowColor = %x (%d)\n", (int)aStyleSet.GetDarkShadowColor().GetColor(), aStyleSet.GetDarkShadowColor().GetLuminance() );
3855 : #endif
3856 :
3857 : // Awful hack for menu separators in the Sonar and similar themes.
3858 : // If the menu color is not too dark, and the menu text color is lighter,
3859 : // make the "light" color lighter than the menu color and the "shadow"
3860 : // color darker than it.
3861 0 : if ( aStyleSet.GetMenuColor().GetLuminance() >= 32 &&
3862 0 : aStyleSet.GetMenuColor().GetLuminance() <= aStyleSet.GetMenuTextColor().GetLuminance() )
3863 : {
3864 0 : Color temp = aStyleSet.GetMenuColor();
3865 0 : temp.IncreaseLuminance( 8 );
3866 0 : aStyleSet.SetLightColor( temp );
3867 0 : temp = aStyleSet.GetMenuColor();
3868 0 : temp.DecreaseLuminance( 16 );
3869 0 : aStyleSet.SetShadowColor( temp );
3870 : }
3871 :
3872 0 : aHighlightColor = getColor( pMenuItemStyle->bg[ GTK_STATE_SELECTED ] );
3873 0 : aHighlightTextColor = getColor( pMenuTextStyle->fg[ GTK_STATE_PRELIGHT ] );
3874 0 : if( aHighlightColor == aHighlightTextColor )
3875 0 : aHighlightTextColor = (aHighlightColor.GetLuminance() < 128) ? Color( COL_WHITE ) : Color( COL_BLACK );
3876 0 : aStyleSet.SetMenuHighlightColor( aHighlightColor );
3877 0 : aStyleSet.SetMenuHighlightTextColor( aHighlightTextColor );
3878 :
3879 : // UI font
3880 0 : OString aFamily = pango_font_description_get_family( pStyle->font_desc );
3881 0 : int nPangoHeight = pango_font_description_get_size( pStyle->font_desc );
3882 0 : PangoStyle eStyle = pango_font_description_get_style( pStyle->font_desc );
3883 0 : PangoWeight eWeight = pango_font_description_get_weight( pStyle->font_desc );
3884 0 : PangoStretch eStretch = pango_font_description_get_stretch( pStyle->font_desc );
3885 :
3886 0 : psp::FastPrintFontInfo aInfo;
3887 : // set family name
3888 0 : aInfo.m_aFamilyName = OStringToOUString( aFamily, RTL_TEXTENCODING_UTF8 );
3889 : // set italic
3890 0 : switch( eStyle )
3891 : {
3892 0 : case PANGO_STYLE_NORMAL: aInfo.m_eItalic = ITALIC_NONE;break;
3893 0 : case PANGO_STYLE_ITALIC: aInfo.m_eItalic = ITALIC_NORMAL;break;
3894 0 : case PANGO_STYLE_OBLIQUE: aInfo.m_eItalic = ITALIC_OBLIQUE;break;
3895 : }
3896 : // set weight
3897 0 : if( eWeight <= PANGO_WEIGHT_ULTRALIGHT )
3898 0 : aInfo.m_eWeight = WEIGHT_ULTRALIGHT;
3899 0 : else if( eWeight <= PANGO_WEIGHT_LIGHT )
3900 0 : aInfo.m_eWeight = WEIGHT_LIGHT;
3901 0 : else if( eWeight <= PANGO_WEIGHT_NORMAL )
3902 0 : aInfo.m_eWeight = WEIGHT_NORMAL;
3903 0 : else if( eWeight <= PANGO_WEIGHT_BOLD )
3904 0 : aInfo.m_eWeight = WEIGHT_BOLD;
3905 : else
3906 0 : aInfo.m_eWeight = WEIGHT_ULTRABOLD;
3907 : // set width
3908 0 : switch( eStretch )
3909 : {
3910 0 : case PANGO_STRETCH_ULTRA_CONDENSED: aInfo.m_eWidth = WIDTH_ULTRA_CONDENSED;break;
3911 0 : case PANGO_STRETCH_EXTRA_CONDENSED: aInfo.m_eWidth = WIDTH_EXTRA_CONDENSED;break;
3912 0 : case PANGO_STRETCH_CONDENSED: aInfo.m_eWidth = WIDTH_CONDENSED;break;
3913 0 : case PANGO_STRETCH_SEMI_CONDENSED: aInfo.m_eWidth = WIDTH_SEMI_CONDENSED;break;
3914 0 : case PANGO_STRETCH_NORMAL: aInfo.m_eWidth = WIDTH_NORMAL;break;
3915 0 : case PANGO_STRETCH_SEMI_EXPANDED: aInfo.m_eWidth = WIDTH_SEMI_EXPANDED;break;
3916 0 : case PANGO_STRETCH_EXPANDED: aInfo.m_eWidth = WIDTH_EXPANDED;break;
3917 0 : case PANGO_STRETCH_EXTRA_EXPANDED: aInfo.m_eWidth = WIDTH_EXTRA_EXPANDED;break;
3918 0 : case PANGO_STRETCH_ULTRA_EXPANDED: aInfo.m_eWidth = WIDTH_ULTRA_EXPANDED;break;
3919 : }
3920 :
3921 : #if OSL_DEBUG_LEVEL > 1
3922 : std::fprintf( stderr, "font name BEFORE system match: \"%s\"\n", aFamily.getStr() );
3923 : #endif
3924 :
3925 : // match font to e.g. resolve "Sans"
3926 0 : psp::PrintFontManager::get().matchFont( aInfo, rSettings.GetUILanguageTag().getLocale() );
3927 :
3928 : #if OSL_DEBUG_LEVEL > 1
3929 : std::fprintf( stderr, "font match %s, name AFTER: \"%s\"\n",
3930 : aInfo.m_nID != 0 ? "succeeded" : "failed",
3931 : OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
3932 : #endif
3933 :
3934 0 : sal_Int32 nDispDPIY = GetDisplay()->GetResolution().B();
3935 0 : int nPointHeight = 0;
3936 : static gboolean(*pAbso)(const PangoFontDescription*) =
3937 0 : (gboolean(*)(const PangoFontDescription*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "pango_font_description_get_size_is_absolute" );
3938 :
3939 0 : if( pAbso && pAbso( pStyle->font_desc ) )
3940 0 : nPointHeight = (nPangoHeight * 72 + nDispDPIY*PANGO_SCALE/2) / (nDispDPIY * PANGO_SCALE);
3941 : else
3942 0 : nPointHeight = nPangoHeight/PANGO_SCALE;
3943 :
3944 0 : Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) );
3945 0 : if( aInfo.m_eWeight != WEIGHT_DONTKNOW )
3946 0 : aFont.SetWeight( aInfo.m_eWeight );
3947 0 : if( aInfo.m_eWidth != WIDTH_DONTKNOW )
3948 0 : aFont.SetWidthType( aInfo.m_eWidth );
3949 0 : if( aInfo.m_eItalic != ITALIC_DONTKNOW )
3950 0 : aFont.SetItalic( aInfo.m_eItalic );
3951 0 : if( aInfo.m_ePitch != PITCH_DONTKNOW )
3952 0 : aFont.SetPitch( aInfo.m_ePitch );
3953 :
3954 0 : aStyleSet.SetAppFont( aFont );
3955 0 : aStyleSet.SetHelpFont( aFont );
3956 0 : aStyleSet.SetMenuFont( aFont );
3957 0 : aStyleSet.SetToolFont( aFont );
3958 0 : aStyleSet.SetLabelFont( aFont );
3959 0 : aStyleSet.SetInfoFont( aFont );
3960 0 : aStyleSet.SetRadioCheckFont( aFont );
3961 0 : aStyleSet.SetPushButtonFont( aFont );
3962 0 : aStyleSet.SetFieldFont( aFont );
3963 0 : aStyleSet.SetIconFont( aFont );
3964 0 : aStyleSet.SetGroupFont( aFont );
3965 :
3966 0 : aFont.SetWeight( WEIGHT_BOLD );
3967 0 : aStyleSet.SetTitleFont( aFont );
3968 0 : aStyleSet.SetFloatTitleFont( aFont );
3969 :
3970 : // get cursor blink time
3971 0 : gboolean blink = false;
3972 :
3973 0 : g_object_get( pSettings, "gtk-cursor-blink", &blink, (char *)NULL );
3974 0 : if( blink )
3975 : {
3976 0 : gint blink_time = STYLE_CURSOR_NOBLINKTIME;
3977 0 : g_object_get( pSettings, "gtk-cursor-blink-time", &blink_time, (char *)NULL );
3978 : // set the blink_time if there is a setting and it is reasonable
3979 : // else leave the default value
3980 0 : if( blink_time > 100 && blink_time != gint(STYLE_CURSOR_NOBLINKTIME) )
3981 0 : aStyleSet.SetCursorBlinkTime( blink_time/2 );
3982 : }
3983 : else
3984 0 : aStyleSet.SetCursorBlinkTime( STYLE_CURSOR_NOBLINKTIME );
3985 :
3986 0 : MouseSettings aMouseSettings = rSettings.GetMouseSettings();
3987 : int iDoubleClickTime, iDoubleClickDistance, iDragThreshold, iMenuPopupDelay;
3988 : g_object_get( pSettings,
3989 : "gtk-double-click-time", &iDoubleClickTime,
3990 : "gtk-double-click-distance", &iDoubleClickDistance,
3991 : "gtk-dnd-drag-threshold", &iDragThreshold,
3992 : "gtk-menu-popup-delay", &iMenuPopupDelay,
3993 0 : (char *)NULL );
3994 0 : aMouseSettings.SetDoubleClickTime( iDoubleClickTime );
3995 0 : aMouseSettings.SetDoubleClickWidth( iDoubleClickDistance );
3996 0 : aMouseSettings.SetDoubleClickHeight( iDoubleClickDistance );
3997 0 : aMouseSettings.SetStartDragWidth( iDragThreshold );
3998 0 : aMouseSettings.SetStartDragHeight( iDragThreshold );
3999 0 : aMouseSettings.SetMenuDelay( iMenuPopupDelay );
4000 0 : rSettings.SetMouseSettings( aMouseSettings );
4001 :
4002 0 : gboolean showmenuicons = true, primarybuttonwarps = false;
4003 : g_object_get( pSettings,
4004 : "gtk-menu-images", &showmenuicons,
4005 0 : (char *)NULL );
4006 0 : if( g_object_class_find_property(
4007 0 : G_OBJECT_GET_CLASS(pSettings), "gtk-primary-button-warps-slider") )
4008 : {
4009 : g_object_get( pSettings,
4010 : "gtk-primary-button-warps-slider", &primarybuttonwarps,
4011 0 : (char *)NULL );
4012 : }
4013 0 : aStyleSet.SetPreferredUseImagesInMenus(showmenuicons);
4014 0 : aStyleSet.SetPrimaryButtonWarpsSlider(primarybuttonwarps);
4015 :
4016 : // set scrollbar settings
4017 0 : gint slider_width = 14;
4018 0 : gint trough_border = 1;
4019 0 : gint min_slider_length = 21;
4020 :
4021 : // Grab some button style attributes
4022 0 : gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget,
4023 : "slider-width", &slider_width,
4024 : "trough-border", &trough_border,
4025 : "min-slider-length", &min_slider_length,
4026 0 : (char *)NULL );
4027 0 : gint magic = trough_border ? 1 : 0;
4028 0 : aStyleSet.SetScrollBarSize( slider_width + 2*trough_border );
4029 0 : aStyleSet.SetMinThumbSize( min_slider_length - magic );
4030 :
4031 : // preferred icon style
4032 0 : gchar* pIconThemeName = NULL;
4033 0 : g_object_get( pSettings, "gtk-icon-theme-name", &pIconThemeName, (char *)NULL );
4034 0 : aStyleSet.SetPreferredIconTheme( OUString::createFromAscii( pIconThemeName ) );
4035 0 : g_free( pIconThemeName );
4036 :
4037 0 : aStyleSet.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_LARGE );
4038 :
4039 : #if !GTK_CHECK_VERSION(2,9,0)
4040 : static cairo_font_options_t* (*gdk_screen_get_font_options)(GdkScreen*) =
4041 : (cairo_font_options_t*(*)(GdkScreen*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_screen_get_font_options" );
4042 : if( gdk_screen_get_font_options != NULL )
4043 : {
4044 : const cairo_font_options_t* pNewOptions = gdk_screen_get_font_options( pScreen );
4045 : aStyleSet.SetCairoFontOptions( pNewOptions );
4046 : }
4047 : #else
4048 0 : const cairo_font_options_t* pNewOptions = gdk_screen_get_font_options( pScreen );
4049 0 : aStyleSet.SetCairoFontOptions( pNewOptions );
4050 : #endif
4051 :
4052 : // finally update the collected settings
4053 0 : rSettings.SetStyleSettings( aStyleSet );
4054 0 : }
4055 :
4056 : /************************************************************************
4057 : * Create a GdkPixmap filled with the contents of an area of an Xlib window
4058 : ************************************************************************/
4059 :
4060 0 : GdkPixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect )
4061 : {
4062 : // Create a new pixmap to hold the composite of the window background and the control
4063 0 : GdkPixmap * pPixmap = gdk_pixmap_new( GDK_DRAWABLE(GetGdkWindow()), srcRect.GetWidth(), srcRect.GetHeight(), -1 );
4064 0 : GdkGC * pPixmapGC = gdk_gc_new( pPixmap );
4065 :
4066 0 : if( !pPixmap || !pPixmapGC )
4067 : {
4068 0 : if ( pPixmap )
4069 0 : g_object_unref( pPixmap );
4070 0 : if ( pPixmapGC )
4071 0 : g_object_unref( pPixmapGC );
4072 0 : std::fprintf( stderr, "salnativewidgets-gtk.cxx: could not get valid pixmap from screen\n" );
4073 0 : return( NULL );
4074 : }
4075 :
4076 : // Copy the background of the screen into a composite pixmap
4077 : CopyScreenArea( GetXDisplay(),
4078 0 : GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
4079 : gdk_x11_drawable_get_xid(pPixmap),
4080 0 : SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
4081 0 : gdk_drawable_get_depth( GDK_DRAWABLE( pPixmap ) ),
4082 : gdk_x11_gc_get_xgc(pPixmapGC),
4083 0 : srcRect.Left(), srcRect.Top(), srcRect.GetWidth(), srcRect.GetHeight(), 0, 0 );
4084 :
4085 0 : g_object_unref( pPixmapGC );
4086 0 : return( pPixmap );
4087 : }
4088 :
4089 : /************************************************************************
4090 : * Copy an alpha pixmap to screen using a gc with clipping
4091 : ************************************************************************/
4092 :
4093 0 : bool GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect )
4094 : {
4095 : // The GC can't be null, otherwise we'd have no clip region
4096 0 : GC aFontGC = GetFontGC();
4097 0 : if( aFontGC == NULL )
4098 : {
4099 0 : std::fprintf(stderr, "salnativewidgets.cxx: no valid GC\n" );
4100 0 : return false;
4101 : }
4102 :
4103 0 : if ( !pPixmap )
4104 0 : return false;
4105 :
4106 : // Copy the background of the screen into a composite pixmap
4107 : CopyScreenArea( GetXDisplay(),
4108 : GDK_DRAWABLE_XID(pPixmap),
4109 0 : SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
4110 0 : gdk_drawable_get_depth( GDK_DRAWABLE(pPixmap) ),
4111 0 : GetDrawable(), m_nXScreen, GetVisual().GetDepth(),
4112 : aFontGC,
4113 0 : 0, 0, dstRect.GetWidth(), dstRect.GetHeight(), dstRect.Left(), dstRect.Top() );
4114 :
4115 0 : return true;
4116 : }
4117 :
4118 : /************************************************************************
4119 : * State conversion
4120 : ************************************************************************/
4121 0 : static void NWConvertVCLStateToGTKState( ControlState nVCLState,
4122 : GtkStateType* nGTKState, GtkShadowType* nGTKShadow )
4123 : {
4124 0 : *nGTKShadow = GTK_SHADOW_OUT;
4125 0 : *nGTKState = GTK_STATE_INSENSITIVE;
4126 :
4127 0 : if ( nVCLState & CTRL_STATE_ENABLED )
4128 : {
4129 0 : if ( nVCLState & CTRL_STATE_PRESSED )
4130 : {
4131 0 : *nGTKState = GTK_STATE_ACTIVE;
4132 0 : *nGTKShadow = GTK_SHADOW_IN;
4133 : }
4134 0 : else if ( nVCLState & CTRL_STATE_ROLLOVER )
4135 : {
4136 0 : *nGTKState = GTK_STATE_PRELIGHT;
4137 0 : *nGTKShadow = GTK_SHADOW_OUT;
4138 : }
4139 : else
4140 : {
4141 0 : *nGTKState = GTK_STATE_NORMAL;
4142 0 : *nGTKShadow = GTK_SHADOW_OUT;
4143 : }
4144 : }
4145 0 : }
4146 :
4147 : /************************************************************************
4148 : * Set widget flags
4149 : ************************************************************************/
4150 0 : static void NWSetWidgetState( GtkWidget* widget, ControlState nState, GtkStateType nGtkState )
4151 : {
4152 : // Set to default state, then build up from there
4153 0 : GTK_WIDGET_UNSET_FLAGS( widget, GTK_HAS_DEFAULT );
4154 0 : GTK_WIDGET_UNSET_FLAGS( widget, GTK_HAS_FOCUS );
4155 0 : GTK_WIDGET_UNSET_FLAGS( widget, GTK_SENSITIVE );
4156 0 : GTK_WIDGET_SET_FLAGS( widget, gWidgetDefaultFlags[(long)widget] );
4157 :
4158 0 : if ( nState & CTRL_STATE_DEFAULT )
4159 0 : GTK_WIDGET_SET_FLAGS( widget, GTK_HAS_DEFAULT );
4160 0 : if ( !GTK_IS_TOGGLE_BUTTON(widget) && (nState & CTRL_STATE_FOCUSED) )
4161 0 : GTK_WIDGET_SET_FLAGS( widget, GTK_HAS_FOCUS );
4162 0 : if ( nState & CTRL_STATE_ENABLED )
4163 0 : GTK_WIDGET_SET_FLAGS( widget, GTK_SENSITIVE );
4164 0 : gtk_widget_set_state( widget, nGtkState );
4165 0 : }
4166 :
4167 : /************************************************************************
4168 : * Widget ensure functions - make sure cached objects are valid
4169 : ************************************************************************/
4170 :
4171 0 : static void NWAddWidgetToCacheWindow( GtkWidget* widget, SalX11Screen nScreen )
4172 : {
4173 0 : NWFWidgetData& rData = gWidgetData[nScreen];
4174 0 : if ( !rData.gCacheWindow || !rData.gDumbContainer )
4175 : {
4176 0 : if ( !rData.gCacheWindow )
4177 : {
4178 0 : rData.gCacheWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
4179 0 : g_object_set_data( G_OBJECT( rData.gCacheWindow ), "libo-version",
4180 0 : (gpointer)LIBO_VERSION_DOTTED );
4181 :
4182 : GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(),
4183 0 : nScreen.getXScreen() );
4184 0 : if( pScreen )
4185 0 : gtk_window_set_screen( GTK_WINDOW(rData.gCacheWindow), pScreen );
4186 : }
4187 0 : if ( !rData.gDumbContainer )
4188 0 : rData.gDumbContainer = gtk_fixed_new();
4189 0 : gtk_container_add( GTK_CONTAINER(rData.gCacheWindow), rData.gDumbContainer );
4190 0 : gtk_widget_realize( rData.gDumbContainer );
4191 0 : gtk_widget_realize( rData.gCacheWindow );
4192 : }
4193 :
4194 0 : gtk_container_add( GTK_CONTAINER(rData.gDumbContainer), widget );
4195 0 : gtk_widget_realize( widget );
4196 0 : gtk_widget_ensure_style( widget );
4197 :
4198 : // Store widget's default flags
4199 0 : gWidgetDefaultFlags[ (long)widget ] = GTK_WIDGET_FLAGS( widget );
4200 0 : }
4201 :
4202 0 : static void NWEnsureGTKButton( SalX11Screen nScreen )
4203 : {
4204 0 : if ( !gWidgetData[nScreen].gBtnWidget )
4205 : {
4206 0 : gWidgetData[nScreen].gBtnWidget = gtk_button_new_with_label( "" );
4207 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gBtnWidget, nScreen );
4208 : }
4209 0 : }
4210 :
4211 0 : static void NWEnsureGTKRadio( SalX11Screen nScreen )
4212 : {
4213 0 : if ( !gWidgetData[nScreen].gRadioWidget || !gWidgetData[nScreen].gRadioWidgetSibling )
4214 : {
4215 0 : gWidgetData[nScreen].gRadioWidget = gtk_radio_button_new( NULL );
4216 0 : gWidgetData[nScreen].gRadioWidgetSibling = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON(gWidgetData[nScreen].gRadioWidget) );
4217 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gRadioWidget, nScreen );
4218 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gRadioWidgetSibling, nScreen );
4219 : }
4220 0 : }
4221 :
4222 0 : static void NWEnsureGTKCheck( SalX11Screen nScreen )
4223 : {
4224 0 : if ( !gWidgetData[nScreen].gCheckWidget )
4225 : {
4226 0 : gWidgetData[nScreen].gCheckWidget = gtk_check_button_new();
4227 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gCheckWidget, nScreen );
4228 : }
4229 0 : }
4230 :
4231 0 : static void NWEnsureGTKScrollbars( SalX11Screen nScreen )
4232 : {
4233 0 : if ( !gWidgetData[nScreen].gScrollHorizWidget )
4234 : {
4235 0 : gWidgetData[nScreen].gScrollHorizWidget = gtk_hscrollbar_new( NULL );
4236 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gScrollHorizWidget, nScreen );
4237 : }
4238 :
4239 0 : if ( !gWidgetData[nScreen].gScrollVertWidget )
4240 : {
4241 0 : gWidgetData[nScreen].gScrollVertWidget = gtk_vscrollbar_new( NULL );
4242 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gScrollVertWidget, nScreen );
4243 : }
4244 0 : }
4245 :
4246 0 : static void NWEnsureGTKArrow( SalX11Screen nScreen )
4247 : {
4248 0 : if ( !gWidgetData[nScreen].gArrowWidget || !gWidgetData[nScreen].gDropdownWidget )
4249 : {
4250 0 : gWidgetData[nScreen].gDropdownWidget = gtk_toggle_button_new();
4251 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gDropdownWidget, nScreen );
4252 0 : gWidgetData[nScreen].gArrowWidget = gtk_arrow_new( GTK_ARROW_DOWN, GTK_SHADOW_OUT );
4253 0 : gtk_container_add( GTK_CONTAINER(gWidgetData[nScreen].gDropdownWidget), gWidgetData[nScreen].gArrowWidget );
4254 0 : gtk_widget_set_rc_style( gWidgetData[nScreen].gArrowWidget );
4255 0 : gtk_widget_realize( gWidgetData[nScreen].gArrowWidget );
4256 : }
4257 0 : }
4258 :
4259 0 : static void NWEnsureGTKEditBox( SalX11Screen nScreen )
4260 : {
4261 0 : if ( !gWidgetData[nScreen].gEditBoxWidget )
4262 : {
4263 0 : gWidgetData[nScreen].gEditBoxWidget = gtk_entry_new();
4264 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gEditBoxWidget, nScreen );
4265 : }
4266 0 : }
4267 :
4268 0 : static void NWEnsureGTKSpinButton( SalX11Screen nScreen )
4269 : {
4270 0 : if ( !gWidgetData[nScreen].gSpinButtonWidget )
4271 : {
4272 0 : GtkAdjustment *adj = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 1, 1, 1, 0) );
4273 0 : gWidgetData[nScreen].gSpinButtonWidget = gtk_spin_button_new( adj, 1, 2 );
4274 :
4275 : //Setting non-editable means it doesn't blink, so there's no timeouts
4276 : //running around to nobble us
4277 0 : gtk_editable_set_editable(GTK_EDITABLE(gWidgetData[nScreen].gSpinButtonWidget), false);
4278 :
4279 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gSpinButtonWidget, nScreen );
4280 : }
4281 0 : }
4282 :
4283 0 : static void NWEnsureGTKNotebook( SalX11Screen nScreen )
4284 : {
4285 0 : if ( !gWidgetData[nScreen].gNotebookWidget )
4286 : {
4287 0 : gWidgetData[nScreen].gNotebookWidget = gtk_notebook_new();
4288 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gNotebookWidget, nScreen );
4289 : }
4290 0 : }
4291 :
4292 0 : static void NWEnsureGTKOptionMenu( SalX11Screen nScreen )
4293 : {
4294 0 : if ( !gWidgetData[nScreen].gOptionMenuWidget )
4295 : {
4296 0 : gWidgetData[nScreen].gOptionMenuWidget = gtk_option_menu_new();
4297 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gOptionMenuWidget, nScreen );
4298 : }
4299 0 : }
4300 :
4301 0 : static void NWEnsureGTKCombo( SalX11Screen nScreen )
4302 : {
4303 0 : if ( !gWidgetData[nScreen].gComboWidget )
4304 : {
4305 0 : gWidgetData[nScreen].gComboWidget = gtk_combo_new();
4306 :
4307 : // #i59129# Setting non-editable means it doesn't blink, so
4308 : // there are no timeouts running around to nobble us
4309 0 : gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(gWidgetData[nScreen].gComboWidget)->entry), false);
4310 :
4311 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gComboWidget, nScreen );
4312 : // Must realize the ComboBox's children, since GTK
4313 : // does not do this for us in GtkCombo::gtk_widget_realize()
4314 0 : gtk_widget_realize( GTK_COMBO(gWidgetData[nScreen].gComboWidget)->button );
4315 0 : gtk_widget_realize( GTK_COMBO(gWidgetData[nScreen].gComboWidget)->entry );
4316 : }
4317 0 : }
4318 :
4319 0 : static void NWEnsureGTKScrolledWindow( SalX11Screen nScreen )
4320 : {
4321 0 : if ( !gWidgetData[nScreen].gScrolledWindowWidget )
4322 : {
4323 0 : GtkAdjustment *hadj = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
4324 0 : GtkAdjustment *vadj = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
4325 :
4326 0 : gWidgetData[nScreen].gScrolledWindowWidget = gtk_scrolled_window_new( hadj, vadj );
4327 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gScrolledWindowWidget, nScreen );
4328 : }
4329 0 : }
4330 :
4331 0 : static void NWEnsureGTKToolbar( SalX11Screen nScreen )
4332 : {
4333 0 : if( !gWidgetData[nScreen].gToolbarWidget )
4334 : {
4335 0 : gWidgetData[nScreen].gToolbarWidget = gtk_toolbar_new();
4336 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gToolbarWidget, nScreen );
4337 0 : gWidgetData[nScreen].gToolbarButtonWidget = GTK_WIDGET(gtk_toggle_button_new());
4338 0 : gWidgetData[nScreen].gSeparator = GTK_WIDGET(gtk_separator_tool_item_new());
4339 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gSeparator, nScreen );
4340 :
4341 0 : GtkReliefStyle aRelief = GTK_RELIEF_NORMAL;
4342 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gToolbarWidget );
4343 0 : gtk_widget_style_get( gWidgetData[nScreen].gToolbarWidget,
4344 : "button_relief", &aRelief,
4345 0 : (char *)NULL);
4346 :
4347 0 : gtk_button_set_relief( GTK_BUTTON(gWidgetData[nScreen].gToolbarButtonWidget), aRelief );
4348 0 : GTK_WIDGET_UNSET_FLAGS( gWidgetData[nScreen].gToolbarButtonWidget, GTK_CAN_FOCUS );
4349 0 : GTK_WIDGET_UNSET_FLAGS( gWidgetData[nScreen].gToolbarButtonWidget, GTK_CAN_DEFAULT );
4350 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gToolbarButtonWidget, nScreen );
4351 :
4352 : }
4353 0 : if( ! gWidgetData[nScreen].gHandleBoxWidget )
4354 : {
4355 0 : gWidgetData[nScreen].gHandleBoxWidget = gtk_handle_box_new();
4356 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gHandleBoxWidget, nScreen );
4357 : }
4358 0 : }
4359 :
4360 0 : static void NWEnsureGTKMenubar( SalX11Screen nScreen )
4361 : {
4362 0 : if( !gWidgetData[nScreen].gMenubarWidget )
4363 : {
4364 0 : gWidgetData[nScreen].gMenubarWidget = gtk_menu_bar_new();
4365 0 : gWidgetData[nScreen].gMenuItemMenubarWidget = gtk_menu_item_new_with_label( "b" );
4366 0 : gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenubarWidget ), gWidgetData[nScreen].gMenuItemMenubarWidget );
4367 0 : gtk_widget_show( gWidgetData[nScreen].gMenuItemMenubarWidget );
4368 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gMenubarWidget, nScreen );
4369 0 : gtk_widget_show( gWidgetData[nScreen].gMenubarWidget );
4370 :
4371 : // do what NWAddWidgetToCacheWindow does except adding to def container
4372 0 : gtk_widget_realize( gWidgetData[nScreen].gMenuItemMenubarWidget );
4373 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemMenubarWidget );
4374 :
4375 0 : gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemMenubarWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemMenubarWidget );
4376 : }
4377 0 : }
4378 :
4379 0 : static void NWEnsureGTKMenu( SalX11Screen nScreen )
4380 : {
4381 0 : if( !gWidgetData[nScreen].gMenuWidget )
4382 : {
4383 0 : gWidgetData[nScreen].gMenuWidget = gtk_menu_new();
4384 0 : gWidgetData[nScreen].gMenuItemMenuWidget = gtk_menu_item_new_with_label( "b" );
4385 0 : gWidgetData[nScreen].gMenuItemCheckMenuWidget = gtk_check_menu_item_new_with_label( "b" );
4386 0 : gWidgetData[nScreen].gMenuItemRadioMenuWidget = gtk_radio_menu_item_new_with_label( NULL, "b" );
4387 0 : gWidgetData[nScreen].gMenuItemSeparatorMenuWidget = gtk_menu_item_new();
4388 0 : gWidgetData[nScreen].gImageMenuItem = gtk_image_menu_item_new();
4389 :
4390 0 : gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemMenuWidget );
4391 0 : gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemCheckMenuWidget );
4392 0 : gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemRadioMenuWidget );
4393 0 : gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
4394 0 : gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gImageMenuItem );
4395 :
4396 : // do what NWAddWidgetToCacheWindow does except adding to def container
4397 0 : gtk_widget_realize( gWidgetData[nScreen].gMenuWidget );
4398 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gMenuWidget );
4399 :
4400 0 : gtk_widget_realize( gWidgetData[nScreen].gMenuItemMenuWidget );
4401 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemMenuWidget );
4402 :
4403 0 : gtk_widget_realize( gWidgetData[nScreen].gMenuItemCheckMenuWidget );
4404 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemCheckMenuWidget );
4405 :
4406 0 : gtk_widget_realize( gWidgetData[nScreen].gMenuItemRadioMenuWidget );
4407 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemRadioMenuWidget );
4408 :
4409 0 : gtk_widget_realize( gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
4410 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
4411 :
4412 0 : gtk_widget_realize( gWidgetData[nScreen].gImageMenuItem );
4413 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gImageMenuItem );
4414 :
4415 0 : gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuWidget );
4416 0 : gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemMenuWidget );
4417 0 : gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemCheckMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemCheckMenuWidget );
4418 0 : gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemRadioMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemRadioMenuWidget );
4419 0 : gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemSeparatorMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
4420 0 : gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gImageMenuItem ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gImageMenuItem );
4421 : }
4422 0 : }
4423 :
4424 0 : static void NWEnsureGTKTooltip( SalX11Screen nScreen )
4425 : {
4426 0 : if( !gWidgetData[nScreen].gTooltipPopup )
4427 : {
4428 0 : gWidgetData[nScreen].gTooltipPopup = gtk_window_new (GTK_WINDOW_POPUP);
4429 : GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(),
4430 0 : nScreen.getXScreen() );
4431 0 : if( pScreen )
4432 0 : gtk_window_set_screen( GTK_WINDOW(gWidgetData[nScreen].gTooltipPopup), pScreen );
4433 0 : gtk_widget_set_name( gWidgetData[nScreen].gTooltipPopup, "gtk-tooltips");
4434 0 : gtk_widget_realize( gWidgetData[nScreen].gTooltipPopup );
4435 0 : gtk_widget_ensure_style( gWidgetData[nScreen].gTooltipPopup );
4436 : }
4437 0 : }
4438 :
4439 0 : static void NWEnsureGTKDialog( SalX11Screen nScreen )
4440 : {
4441 0 : if( !gWidgetData[nScreen].gDialog )
4442 : {
4443 0 : gWidgetData[nScreen].gDialog = gtk_dialog_new();
4444 : GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(),
4445 0 : nScreen.getXScreen() );
4446 0 : if( pScreen )
4447 0 : gtk_window_set_screen( GTK_WINDOW(gWidgetData[nScreen].gDialog), pScreen );
4448 0 : gtk_widget_realize(gWidgetData[nScreen].gDialog);
4449 0 : gtk_widget_ensure_style(gWidgetData[nScreen].gDialog);
4450 : }
4451 0 : }
4452 :
4453 0 : static void NWEnsureGTKFrame( SalX11Screen nScreen )
4454 : {
4455 0 : if( !gWidgetData[nScreen].gFrame )
4456 : {
4457 0 : gWidgetData[nScreen].gFrame = gtk_frame_new(NULL);
4458 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gFrame, nScreen );
4459 : }
4460 0 : }
4461 :
4462 0 : static void NWEnsureGTKProgressBar( SalX11Screen nScreen )
4463 : {
4464 0 : if( !gWidgetData[nScreen].gProgressBar )
4465 : {
4466 0 : gWidgetData[nScreen].gProgressBar = gtk_progress_bar_new ();
4467 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gProgressBar, nScreen );
4468 : }
4469 0 : }
4470 :
4471 0 : static void NWEnsureGTKTreeView( SalX11Screen nScreen )
4472 : {
4473 0 : if( !gWidgetData[nScreen].gTreeView )
4474 : {
4475 0 : gWidgetData[nScreen].gTreeView = gtk_tree_view_new ();
4476 :
4477 : // Columns will be used for tree header rendering
4478 0 : GtkCellRenderer* renderer=gtk_cell_renderer_text_new();
4479 0 : GtkTreeViewColumn* column=gtk_tree_view_column_new_with_attributes("",renderer,"text",0,NULL);
4480 0 : gtk_tree_view_column_set_widget(column,gtk_label_new(""));
4481 0 : gtk_tree_view_append_column(GTK_TREE_VIEW(gWidgetData[nScreen].gTreeView), column);
4482 :
4483 : // Add one more column so that some engines like clearlooks did render separators between columns
4484 0 : column=gtk_tree_view_column_new_with_attributes("",renderer,"text",0,NULL);
4485 0 : gtk_tree_view_append_column(GTK_TREE_VIEW(gWidgetData[nScreen].gTreeView), column);
4486 :
4487 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gTreeView, nScreen );
4488 : }
4489 0 : }
4490 :
4491 0 : static void NWEnsureGTKSlider( SalX11Screen nScreen )
4492 : {
4493 0 : if( !gWidgetData[nScreen].gHScale )
4494 : {
4495 0 : gWidgetData[nScreen].gHScale = gtk_hscale_new_with_range(0, 10, 1);
4496 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gHScale, nScreen );
4497 : }
4498 0 : if( !gWidgetData[nScreen].gVScale )
4499 : {
4500 0 : gWidgetData[nScreen].gVScale = gtk_vscale_new_with_range(0, 10, 1);
4501 0 : NWAddWidgetToCacheWindow( gWidgetData[nScreen].gVScale, nScreen );
4502 : }
4503 0 : }
4504 :
4505 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|