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