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