1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salnativewidgets-gtk.cxx,v $
10 * $Revision: 1.47.32.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include "plugins/gtk/gtkframe.hxx"
35 #include "plugins/gtk/gtkdata.hxx"
36 #include "plugins/gtk/gtkinst.hxx"
37 #include "plugins/gtk/gtkgdi.hxx"
39 #include "pspgraphics.h"
47 #include "saldata.hxx"
48 #include "saldisp.hxx"
49 #include "vcl/svapp.hxx"
52 BOOL
GtkSalGraphics::bThemeChanged
= TRUE
;
53 BOOL
GtkSalGraphics::bNeedPixmapPaint
= FALSE
;
54 BOOL
GtkSalGraphics::bGlobalNeedPixmapPaint
= FALSE
;
55 BOOL
GtkSalGraphics::bToolbarGripWorkaround
= FALSE
;
56 BOOL
GtkSalGraphics::bNeedButtonStyleAsEditBackgroundWorkaround
= FALSE
;
58 GtkSalGraphics::~GtkSalGraphics()
65 /*************************************
66 * Cached native widget objects
67 *************************************/
68 class NWPixmapCacheList
;
72 GtkWidget
* gCacheWindow
;
73 GtkWidget
* gDumbContainer
;
75 GtkWidget
* gBtnWidget
;
76 GtkWidget
* gRadioWidget
;
77 GtkWidget
* gRadioWidgetSibling
;
78 GtkWidget
* gCheckWidget
;
79 GtkWidget
* gScrollHorizWidget
;
80 GtkWidget
* gScrollVertWidget
;
81 GtkWidget
* gArrowWidget
;
82 GtkWidget
* gDropdownWidget
;
83 GtkWidget
* gEditBoxWidget
;
84 GtkWidget
* gSpinButtonWidget
;
85 GtkWidget
* gNotebookWidget
;
86 GtkWidget
* gOptionMenuWidget
;
87 GtkWidget
* gComboWidget
;
88 GtkWidget
* gScrolledWindowWidget
;
89 GtkWidget
* gToolbarWidget
;
90 GtkWidget
* gToolbarButtonWidget
;
91 GtkWidget
* gToolbarToggleWidget
;
92 GtkWidget
* gHandleBoxWidget
;
93 GtkWidget
* gMenubarWidget
;
94 GtkWidget
* gMenuItemMenubarWidget
;
95 GtkWidget
* gMenuWidget
;
96 GtkWidget
* gMenuItemMenuWidget
;
97 GtkWidget
* gMenuItemCheckMenuWidget
;
98 GtkWidget
* gMenuItemRadioMenuWidget
;
99 GtkWidget
* gImageMenuItem
;
100 GtkWidget
* gTooltipPopup
;
101 GtkWidget
* gProgressBar
;
102 GtkWidget
* gTreeView
;
104 NWPixmapCacheList
* gNWPixmapCacheList
;
105 NWPixmapCache
* gCacheTabItems
;
106 NWPixmapCache
* gCacheTabPages
;
109 gCacheWindow( NULL
),
110 gDumbContainer( NULL
),
112 gRadioWidget( NULL
),
113 gRadioWidgetSibling( NULL
),
114 gCheckWidget( NULL
),
115 gScrollHorizWidget( NULL
),
116 gScrollVertWidget( NULL
),
117 gArrowWidget( NULL
),
118 gDropdownWidget( NULL
),
119 gEditBoxWidget( NULL
),
120 gSpinButtonWidget( NULL
),
121 gNotebookWidget( NULL
),
122 gOptionMenuWidget( NULL
),
123 gComboWidget( NULL
),
124 gScrolledWindowWidget( NULL
),
125 gToolbarWidget( NULL
),
126 gToolbarButtonWidget( NULL
),
127 gToolbarToggleWidget( NULL
),
128 gHandleBoxWidget( NULL
),
129 gMenubarWidget( NULL
),
130 gMenuItemMenubarWidget( NULL
),
132 gMenuItemMenuWidget( NULL
),
133 gMenuItemCheckMenuWidget( NULL
),
134 gMenuItemRadioMenuWidget( NULL
),
135 gImageMenuItem( NULL
),
136 gTooltipPopup( NULL
),
137 gProgressBar( NULL
),
139 gNWPixmapCacheList( NULL
),
140 gCacheTabItems( NULL
),
141 gCacheTabPages( NULL
)
145 // Keep a hash table of Widgets->default flags so that we can
146 // easily and quickly reset each to a default state before using
148 static std::hash_map
<long, guint
> gWidgetDefaultFlags
;
149 static std::vector
<NWFWidgetData
> gWidgetData
;
151 static const GtkBorder aDefDefBorder
= { 1, 1, 1, 1 };
154 #define MIN_ARROW_SIZE 11
155 #define BTN_CHILD_SPACING 1
156 #define MIN_SPIN_ARROW_WIDTH 6
159 static void NWEnsureGTKRadio ( int nScreen
);
160 static void NWEnsureGTKButton ( int nScreen
);
161 static void NWEnsureGTKCheck ( int nScreen
);
162 static void NWEnsureGTKScrollbars ( int nScreen
);
163 static void NWEnsureGTKArrow ( int nScreen
);
164 static void NWEnsureGTKEditBox ( int nScreen
);
165 static void NWEnsureGTKSpinButton ( int nScreen
);
166 static void NWEnsureGTKNotebook ( int nScreen
);
167 static void NWEnsureGTKOptionMenu ( int nScreen
);
168 static void NWEnsureGTKCombo ( int nScreen
);
169 static void NWEnsureGTKScrolledWindow ( int nScreen
);
170 static void NWEnsureGTKToolbar ( int nScreen
);
171 static void NWEnsureGTKMenubar ( int nScreen
);
172 static void NWEnsureGTKMenu ( int nScreen
);
173 static void NWEnsureGTKTooltip ( int nScreen
);
174 static void NWEnsureGTKProgressBar ( int nScreen
);
175 static void NWEnsureGTKTreeView ( int nScreen
);
177 static void NWConvertVCLStateToGTKState( ControlState nVCLState
, GtkStateType
* nGTKState
, GtkShadowType
* nGTKShadow
);
178 static void NWAddWidgetToCacheWindow( GtkWidget
* widget
, int nScreen
);
179 static void NWSetWidgetState( GtkWidget
* widget
, ControlState nState
, GtkStateType nGtkState
);
181 static void NWCalcArrowRect( const Rectangle
& rButton
, Rectangle
& rArrow
);
184 * Individual helper functions
189 static Rectangle
NWGetButtonArea( int nScreen
, ControlType nType
, ControlPart nPart
, Rectangle aAreaRect
, ControlState nState
,
190 const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
, const OUString
& rCaption
);
193 static Rectangle
NWGetEditBoxPixmapRect( int nScreen
, ControlType nType
, ControlPart nPart
, Rectangle aAreaRect
, ControlState nState
,
194 const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
, const OUString
& rCaption
);
196 static void NWPaintOneEditBox( int nScreen
, GdkDrawable
* gdkDrawable
, GdkRectangle
*gdkRect
,
197 ControlType nType
, ControlPart nPart
, Rectangle aEditBoxRect
,
198 ControlState nState
, const ImplControlValue
& aValue
,
199 SalControlHandle
& rControlHandle
, const OUString
& rCaption
);
202 static Rectangle
NWGetSpinButtonRect( int nScreen
, ControlType nType
, ControlPart nPart
, Rectangle aAreaRect
, ControlState nState
,
203 const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
, const OUString
& rCaption
);
205 static void NWPaintOneSpinButton( int nScreen
, GdkPixmap
* pixmap
, ControlType nType
, ControlPart nPart
, Rectangle aAreaRect
,
206 ControlState nState
, const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
,
207 const OUString
& rCaption
);
209 static Rectangle
NWGetComboBoxButtonRect( int nScreen
, ControlType nType
, ControlPart nPart
, Rectangle aAreaRect
, ControlState nState
,
210 const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
, const OUString
& rCaption
);
213 static Rectangle
NWGetListBoxButtonRect( int nScreen
, ControlType nType
, ControlPart nPart
, Rectangle aAreaRect
, ControlState nState
,
214 const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
, const OUString
& rCaption
);
216 static Rectangle
NWGetListBoxIndicatorRect( int nScreen
, ControlType nType
, ControlPart nPart
, Rectangle aAreaRect
, ControlState nState
,
217 const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
, const OUString
& rCaption
);
219 static Rectangle
NWGetToolbarRect( int nScreen
,
224 const ImplControlValue
& aValue
,
225 SalControlHandle
& rControlHandle
,
226 const OUString
& rCaption
);
229 static Rectangle
NWGetScrollButtonRect( int nScreen
, ControlPart nPart
, Rectangle aAreaRect
);
232 /*********************************************************
234 *********************************************************/
236 // as some native widget drawing operations are pretty slow
237 // with certain themes (eg tabpages)
238 // this cache can be used to cache the corresponding pixmap
239 // see NWPaintGTKTabItem
241 class NWPixmapCacheData
245 ControlState m_nState
;
246 Rectangle m_pixmapRect
;
249 NWPixmapCacheData() : m_nType(0), m_nState(0), m_pixmap(0) {}
251 { SetPixmap( NULL
); };
252 void SetPixmap( GdkPixmap
* pPixmap
);
260 NWPixmapCacheData
* pData
;
262 NWPixmapCache( int nScreen
);
266 { delete [] pData
; m_idx
= 0; m_size
= n
; pData
= new NWPixmapCacheData
[m_size
]; }
267 int GetSize() { return m_size
; }
269 BOOL
Find( ControlType aType
, ControlState aState
, const Rectangle
& r_pixmapRect
, GdkPixmap
** pPixmap
);
270 void Fill( ControlType aType
, ControlState aState
, const Rectangle
& r_pixmapRect
, GdkPixmap
* pPixmap
);
275 class NWPixmapCacheList
278 ::std::vector
< NWPixmapCache
* > mCaches
;
280 void AddCache( NWPixmapCache
*pCache
);
281 void RemoveCache( NWPixmapCache
*pCache
);
285 // --- implementation ---
287 void NWPixmapCacheData::SetPixmap( GdkPixmap
* pPixmap
)
290 g_object_unref( m_pixmap
);
295 g_object_ref( m_pixmap
);
299 NWPixmapCache::NWPixmapCache( int nScreen
)
305 if( gWidgetData
[m_screen
].gNWPixmapCacheList
)
306 gWidgetData
[m_screen
].gNWPixmapCacheList
->AddCache(this);
308 NWPixmapCache::~NWPixmapCache()
310 if( gWidgetData
[m_screen
].gNWPixmapCacheList
)
311 gWidgetData
[m_screen
].gNWPixmapCacheList
->RemoveCache(this);
314 void NWPixmapCache::ThemeChanged()
316 // throw away cached pixmaps
318 for(i
=0; i
<m_size
; i
++)
319 pData
[i
].SetPixmap( NULL
);
322 BOOL
NWPixmapCache::Find( ControlType aType
, ControlState aState
, const Rectangle
& r_pixmapRect
, GdkPixmap
** pPixmap
)
324 aState
&= ~CTRL_CACHING_ALLOWED
; // mask clipping flag
326 for(i
=0; i
<m_size
; i
++)
328 if( pData
[i
].m_nType
== aType
&&
329 pData
[i
].m_nState
== aState
&&
330 pData
[i
].m_pixmapRect
.GetWidth() == r_pixmapRect
.GetWidth() &&
331 pData
[i
].m_pixmapRect
.GetHeight() == r_pixmapRect
.GetHeight() &&
332 pData
[i
].m_pixmap
!= NULL
)
334 *pPixmap
= pData
[i
].m_pixmap
;
341 void NWPixmapCache::Fill( ControlType aType
, ControlState aState
, const Rectangle
& r_pixmapRect
, GdkPixmap
* pPixmap
)
343 if( !(aState
& CTRL_CACHING_ALLOWED
) )
346 aState
&= ~CTRL_CACHING_ALLOWED
; // mask clipping flag
347 m_idx
= (m_idx
+1) % m_size
; // just wrap
348 pData
[m_idx
].m_nType
= aType
;
349 pData
[m_idx
].m_nState
= aState
;
350 pData
[m_idx
].m_pixmapRect
= r_pixmapRect
;
351 pData
[m_idx
].SetPixmap( pPixmap
);
355 void NWPixmapCacheList::AddCache( NWPixmapCache
* pCache
)
357 mCaches
.push_back( pCache
);
359 void NWPixmapCacheList::RemoveCache( NWPixmapCache
* pCache
)
361 ::std::vector
< NWPixmapCache
* >::iterator p
;
362 p
= ::std::find( mCaches
.begin(), mCaches
.end(), pCache
);
363 if( p
!= mCaches
.end() )
366 void NWPixmapCacheList::ThemeChanged( )
368 ::std::vector
< NWPixmapCache
* >::iterator p
= mCaches
.begin();
369 while( p
!= mCaches
.end() )
371 (*p
)->ThemeChanged();
377 /*********************************************************
378 * Make border manipulation easier
379 *********************************************************/
380 inline void NW_gtk_border_set_from_border( GtkBorder
& aDst
, const GtkBorder
* pSrc
)
382 aDst
.left
= pSrc
->left
;
383 aDst
.top
= pSrc
->top
;
384 aDst
.right
= pSrc
->right
;
385 aDst
.bottom
= pSrc
->bottom
;
389 /*********************************************************
390 * Initialize GTK and local stuff
391 *********************************************************/
392 void GtkData::initNWF( void )
394 ImplSVData
* pSVData
= ImplGetSVData();
396 // draw no border for popup menus (NWF draws its own)
397 pSVData
->maNWFData
.mbFlatMenu
= true;
399 // draw separate buttons for toolbox dropdown items
400 pSVData
->maNWFData
.mbToolboxDropDownSeparate
= true;
402 // small extra border around menu items
403 pSVData
->maNWFData
.mnMenuFormatExtraBorder
= 1;
405 // draw toolbars in separate lines
406 pSVData
->maNWFData
.mbDockingAreaSeparateTB
= true;
408 // open first menu on F10
409 pSVData
->maNWFData
.mbOpenMenuOnF10
= true;
411 int nScreens
= GetX11SalData()->GetDisplay()->GetScreenCount();
412 gWidgetData
= std::vector
<NWFWidgetData
>( nScreens
);
413 for( int i
= 0; i
< nScreens
; i
++ )
414 gWidgetData
[i
].gNWPixmapCacheList
= new NWPixmapCacheList
;
417 if( SalGetDesktopEnvironment().equalsAscii( "KDE" ) )
419 // #i97196# ensure a widget exists and the style engine was loaded
420 NWEnsureGTKButton( 0 );
421 if( g_type_from_name( "QtEngineStyle" ) )
423 // KDE 3.3 invented a bug in the qt<->gtk theme engine
424 // that makes direct rendering impossible: they totally
425 // ignore the clip rectangle passed to the paint methods
426 GtkSalGraphics::bNeedPixmapPaint
= GtkSalGraphics::bGlobalNeedPixmapPaint
= true;
429 static const char* pEnv
= getenv( "SAL_GTK_USE_PIXMAPPAINT" );
431 GtkSalGraphics::bNeedPixmapPaint
= GtkSalGraphics::bGlobalNeedPixmapPaint
= true;
433 #if OSL_DEBUG_LEVEL > 1
434 std::fprintf( stderr
, "GtkPlugin: using %s NWF\n",
435 GtkSalGraphics::bNeedPixmapPaint
? "offscreen" : "direct" );
440 /*********************************************************
441 * Release GTK and local stuff
442 *********************************************************/
443 void GtkData::deInitNWF( void )
446 for( unsigned int i
= 0; i
< gWidgetData
.size(); i
++ )
448 // free up global widgets
449 // gtk_widget_destroy will in turn destroy the child hierarchy
450 // so only destroy disjunct hierachies
451 if( gWidgetData
[i
].gCacheWindow
)
452 gtk_widget_destroy( gWidgetData
[i
].gCacheWindow
);
453 if( gWidgetData
[i
].gMenuWidget
)
454 gtk_widget_destroy( gWidgetData
[i
].gMenuWidget
);
455 if( gWidgetData
[i
].gTooltipPopup
)
456 gtk_widget_destroy( gWidgetData
[i
].gTooltipPopup
);
457 delete gWidgetData
[i
].gCacheTabPages
;
458 gWidgetData
[i
].gCacheTabPages
= NULL
;
459 delete gWidgetData
[i
].gCacheTabItems
;
460 gWidgetData
[i
].gCacheTabItems
= NULL
;
461 delete gWidgetData
[i
].gNWPixmapCacheList
;
462 gWidgetData
[i
].gNWPixmapCacheList
= NULL
;
467 /**********************************************************
469 **********************************************************/
470 void GtkSalGraphics::ResetClipRegion()
472 m_aClipRegion
.SetNull();
473 X11SalGraphics::ResetClipRegion();
476 void GtkSalGraphics::BeginSetClipRegion( ULONG nCount
)
478 m_aClipRegion
.SetNull();
479 X11SalGraphics::BeginSetClipRegion( nCount
);
482 BOOL
GtkSalGraphics::unionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
484 Rectangle
aRect( Point( nX
, nY
), Size( nWidth
, nHeight
) );
485 m_aClipRegion
.Union( aRect
);
486 return X11SalGraphics::unionClipRegion( nX
, nY
, nWidth
, nHeight
);
489 bool GtkSalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon
& )
491 // TODO: implement and advertise OutDevSupport_B2DClip support
495 void GtkSalGraphics::EndSetClipRegion()
497 if( m_aClipRegion
.IsEmpty() )
498 m_aClipRegion
.SetNull();
499 X11SalGraphics::EndSetClipRegion();
502 void GtkSalGraphics::copyBits( const SalTwoRect
* pPosAry
,
503 SalGraphics
* pSrcGraphics
)
505 GtkSalFrame
* pFrame
= GetGtkFrame();
506 XLIB_Window aWin
= None
;
507 if( pFrame
&& m_pWindow
)
509 /* #i64117# some themes set the background pixmap VERY frequently */
510 GdkWindow
* pWin
= GTK_WIDGET(m_pWindow
)->window
;
513 aWin
= GDK_WINDOW_XWINDOW(pWin
);
515 XSetWindowBackgroundPixmap( pFrame
->getDisplay()->GetDisplay(),
520 X11SalGraphics::copyBits( pPosAry
, pSrcGraphics
);
521 if( pFrame
&& pFrame
->getBackgroundPixmap() != None
)
522 XSetWindowBackgroundPixmap( pFrame
->getDisplay()->GetDisplay(),
524 pFrame
->getBackgroundPixmap() );
528 * IsNativeControlSupported()
530 * Returns TRUE if the platform supports native
531 * drawing of the control defined by nPart
533 BOOL
GtkSalGraphics::IsNativeControlSupported( ControlType nType
, ControlPart nPart
)
536 ((nType
==CTRL_PUSHBUTTON
) && (nPart
==PART_ENTIRE_CONTROL
)) ||
537 ((nType
==CTRL_RADIOBUTTON
) && (nPart
==PART_ENTIRE_CONTROL
)) ||
538 ((nType
==CTRL_CHECKBOX
) && (nPart
==PART_ENTIRE_CONTROL
)) ||
539 ((nType
==CTRL_SCROLLBAR
) &&
540 ( (nPart
==PART_DRAW_BACKGROUND_HORZ
)
541 || (nPart
==PART_DRAW_BACKGROUND_VERT
)
542 || (nPart
==PART_ENTIRE_CONTROL
)
543 || (nPart
==HAS_THREE_BUTTONS
) ) ) ||
544 ((nType
==CTRL_EDITBOX
) &&
545 ( (nPart
==PART_ENTIRE_CONTROL
)
546 || (nPart
==HAS_BACKGROUND_TEXTURE
) ) ) ||
547 ((nType
==CTRL_MULTILINE_EDITBOX
) &&
548 ( (nPart
==PART_ENTIRE_CONTROL
)
549 || (nPart
==HAS_BACKGROUND_TEXTURE
) ) ) ||
550 ((nType
==CTRL_SPINBOX
) &&
551 ( (nPart
==PART_ENTIRE_CONTROL
)
552 || (nPart
==PART_ALL_BUTTONS
)
553 || (nPart
==HAS_BACKGROUND_TEXTURE
) ) ) ||
554 ((nType
==CTRL_SPINBUTTONS
) &&
555 ( (nPart
==PART_ENTIRE_CONTROL
)
556 || (nPart
==PART_ALL_BUTTONS
) ) ) ||
557 ((nType
==CTRL_COMBOBOX
) &&
558 ( (nPart
==PART_ENTIRE_CONTROL
)
559 || (nPart
==HAS_BACKGROUND_TEXTURE
) ) ) ||
560 (((nType
==CTRL_TAB_ITEM
) || (nType
==CTRL_TAB_PANE
) ||
561 (nType
==CTRL_TAB_BODY
) || (nType
==CTRL_FIXEDBORDER
)) &&
562 ( (nPart
==PART_ENTIRE_CONTROL
)
563 || (nPart
==PART_TABS_DRAW_RTL
) ) ) ||
564 ((nType
==CTRL_LISTBOX
) &&
565 ( (nPart
==PART_ENTIRE_CONTROL
)
566 || (nPart
==PART_WINDOW
)
567 || (nPart
==HAS_BACKGROUND_TEXTURE
) ) ) ||
568 ((nType
== CTRL_TOOLBAR
) &&
569 ( (nPart
==PART_ENTIRE_CONTROL
)
570 || (nPart
==PART_DRAW_BACKGROUND_HORZ
)
571 || (nPart
==PART_DRAW_BACKGROUND_VERT
)
572 || (nPart
==PART_THUMB_HORZ
)
573 || (nPart
==PART_THUMB_VERT
)
574 || (nPart
==PART_BUTTON
)
577 ((nType
== CTRL_MENUBAR
) &&
578 ( (nPart
==PART_ENTIRE_CONTROL
) ) ) ||
579 ((nType
== CTRL_TOOLTIP
) &&
580 ( (nPart
==PART_ENTIRE_CONTROL
) ) ) ||
581 ((nType
== CTRL_MENU_POPUP
) &&
582 ( (nPart
==PART_ENTIRE_CONTROL
)
583 || (nPart
==PART_MENU_ITEM
)
584 || (nPart
==PART_MENU_ITEM_CHECK_MARK
)
585 || (nPart
==PART_MENU_ITEM_RADIO_MARK
)
588 ((nType
== CTRL_PROGRESS
) &&
589 ( (nPart
== PART_ENTIRE_CONTROL
) )
591 ((nType
== CTRL_LISTNODE
|| nType
== CTRL_LISTNET
) &&
592 ( (nPart
== PART_ENTIRE_CONTROL
) )
602 * HitTestNativeControl()
604 * bIsInside is set to TRUE if aPos is contained within the
605 * given part of the control, whose bounding region is
606 * given by rControlRegion (in VCL frame coordinates).
608 * returns whether bIsInside was really set.
610 BOOL
GtkSalGraphics::hitTestNativeControl( ControlType nType
,
612 const Region
& rControlRegion
,
617 if ( ( nType
== CTRL_SCROLLBAR
) &&
618 ( ( nPart
== PART_BUTTON_UP
) ||
619 ( nPart
== PART_BUTTON_DOWN
) ||
620 ( nPart
== PART_BUTTON_LEFT
) ||
621 ( nPart
== PART_BUTTON_RIGHT
) ) )
623 NWEnsureGTKScrollbars( m_nScreen
);
625 // Grab some button style attributes
626 gboolean has_forward
;
627 gboolean has_forward2
;
628 gboolean has_backward
;
629 gboolean has_backward2
;
631 gtk_widget_style_get( gWidgetData
[m_nScreen
].gScrollHorizWidget
, "has-forward-stepper", &has_forward
,
632 "has-secondary-forward-stepper", &has_forward2
,
633 "has-backward-stepper", &has_backward
,
634 "has-secondary-backward-stepper", &has_backward2
, (char *)NULL
);
640 ControlPart nCounterPart
= 0;
641 if ( nPart
== PART_BUTTON_UP
)
642 nCounterPart
= PART_BUTTON_DOWN
;
643 else if ( nPart
== PART_BUTTON_DOWN
)
644 nCounterPart
= PART_BUTTON_UP
;
645 else if ( nPart
== PART_BUTTON_LEFT
)
646 nCounterPart
= PART_BUTTON_RIGHT
;
647 else if ( nPart
== PART_BUTTON_RIGHT
)
648 nCounterPart
= PART_BUTTON_LEFT
;
650 aBackward
= NWGetScrollButtonRect( m_nScreen
, nPart
, rControlRegion
.GetBoundRect() );
651 aForward
= NWGetScrollButtonRect( m_nScreen
, nCounterPart
, rControlRegion
.GetBoundRect() );
653 if ( has_backward
&& has_forward2
)
655 Size
aSize( aBackward
.GetSize() );
656 if ( ( nPart
== PART_BUTTON_UP
) || ( nPart
== PART_BUTTON_DOWN
) )
657 aSize
.setHeight( aBackward
.GetHeight() / 2 );
659 aSize
.setWidth( aBackward
.GetWidth() / 2 );
660 aBackward
.SetSize( aSize
);
662 if ( nPart
== PART_BUTTON_DOWN
)
663 aBackward
.Move( 0, aBackward
.GetHeight() / 2 );
664 else if ( nPart
== PART_BUTTON_RIGHT
)
665 aBackward
.Move( aBackward
.GetWidth() / 2, 0 );
668 if ( has_backward2
&& has_forward
)
670 Size
aSize( aForward
.GetSize() );
671 if ( ( nPart
== PART_BUTTON_UP
) || ( nPart
== PART_BUTTON_DOWN
) )
672 aSize
.setHeight( aForward
.GetHeight() / 2 );
674 aSize
.setWidth( aForward
.GetWidth() / 2 );
675 aForward
.SetSize( aSize
);
677 if ( nPart
== PART_BUTTON_DOWN
)
678 aForward
.Move( 0, aForward
.GetHeight() / 2 );
679 else if ( nPart
== PART_BUTTON_RIGHT
)
680 aForward
.Move( aForward
.GetWidth() / 2, 0 );
683 if ( ( nPart
== PART_BUTTON_UP
) || ( nPart
== PART_BUTTON_LEFT
) )
686 rIsInside
|= aBackward
.IsInside( aPos
);
688 rIsInside
|= aForward
.IsInside( aPos
);
693 rIsInside
|= aBackward
.IsInside( aPos
);
695 rIsInside
|= aForward
.IsInside( aPos
);
700 if( IsNativeControlSupported(nType
, nPart
) )
702 rIsInside
= rControlRegion
.IsInside( aPos
);
713 * DrawNativeControl()
715 * Draws the requested control described by nPart/nState.
717 * rControlRegion: The bounding region of the complete control in VCL frame coordinates.
718 * aValue: An optional value (tristate/numerical/string)
719 * rControlHandle: Carries platform dependent data and is maintained by the SalFrame implementation.
720 * rCaption: A caption or title string (like button text etc)
722 BOOL
GtkSalGraphics::drawNativeControl( ControlType nType
,
724 const Region
& rControlRegion
,
726 const ImplControlValue
& aValue
,
727 SalControlHandle
& rControlHandle
,
728 const OUString
& rCaption
)
730 if( (nType
==CTRL_CHECKBOX
) && (nPart
==PART_ENTIRE_CONTROL
) &&
731 aValue
.getTristateVal() == BUTTONVALUE_MIXED
)
733 return drawNativeMixedStateCheck( nType
, nPart
, rControlRegion
, nState
, aValue
, rControlHandle
, rCaption
);
736 BOOL returnVal
= FALSE
;
737 // get a GC with current clipping region set
742 if( GtkSalGraphics::bThemeChanged
)
745 for( unsigned int i
= 0; i
< gWidgetData
.size(); i
++ )
746 if( gWidgetData
[i
].gNWPixmapCacheList
)
747 gWidgetData
[i
].gNWPixmapCacheList
->ThemeChanged();
748 GtkSalGraphics::bThemeChanged
= FALSE
;
751 Rectangle aCtrlRect
= rControlRegion
.GetBoundRect();
752 Region
aClipRegion( m_aClipRegion
);
753 if( aClipRegion
.IsNull() )
754 aClipRegion
= aCtrlRect
;
757 GdkDrawable
* gdkDrawable
= GDK_DRAWABLE( GetGdkWindow() );
758 GdkPixmap
* pixmap
= NULL
;
759 Rectangle aPixmapRect
;
760 if( ( bNeedPixmapPaint
)
761 && nType
!= CTRL_SCROLLBAR
762 && nType
!= CTRL_SPINBOX
763 && nType
!= CTRL_TAB_ITEM
764 && nType
!= CTRL_TAB_PANE
765 && nType
!= CTRL_PROGRESS
766 && ! (bToolbarGripWorkaround
&& nType
== CTRL_TOOLBAR
&& (nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
) )
769 // make pixmap a little larger since some themes draw decoration
770 // outside the rectangle, see e.g. checkbox
771 aPixmapRect
= Rectangle( Point( aCtrlRect
.Left()-1, aCtrlRect
.Top()-1 ),
772 Size( aCtrlRect
.GetWidth()+2, aCtrlRect
.GetHeight()+2) );
773 pixmap
= NWGetPixmapFromScreen( aPixmapRect
);
776 gdkDrawable
= GDK_DRAWABLE( pixmap
);
777 aCtrlRect
= Rectangle( Point(1,1), aCtrlRect
.GetSize() );
778 aClip
.push_back( aCtrlRect
);
782 RegionHandle aHdl
= aClipRegion
.BeginEnumRects();
783 Rectangle aPaintRect
;
784 while( aClipRegion
.GetNextEnumRect( aHdl
, aPaintRect
) )
786 aPaintRect
= aCtrlRect
.GetIntersection( aPaintRect
);
787 if( aPaintRect
.IsEmpty() )
789 aClip
.push_back( aPaintRect
);
791 aClipRegion
.EndEnumRects( aHdl
);
794 if ( (nType
==CTRL_PUSHBUTTON
) && (nPart
==PART_ENTIRE_CONTROL
) )
796 returnVal
= NWPaintGTKButton( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
798 else if ( (nType
==CTRL_RADIOBUTTON
) && (nPart
==PART_ENTIRE_CONTROL
) )
800 returnVal
= NWPaintGTKRadio( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
802 else if ( (nType
==CTRL_CHECKBOX
) && (nPart
==PART_ENTIRE_CONTROL
) )
804 returnVal
= NWPaintGTKCheck( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
806 else if ( (nType
==CTRL_SCROLLBAR
) && ((nPart
==PART_DRAW_BACKGROUND_HORZ
) || (nPart
==PART_DRAW_BACKGROUND_VERT
)) )
808 returnVal
= NWPaintGTKScrollbar( nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
810 else if ( ((nType
==CTRL_EDITBOX
) && ((nPart
==PART_ENTIRE_CONTROL
) || (nPart
==HAS_BACKGROUND_TEXTURE
)) )
811 || ((nType
==CTRL_SPINBOX
) && (nPart
==HAS_BACKGROUND_TEXTURE
))
812 || ((nType
==CTRL_COMBOBOX
) && (nPart
==HAS_BACKGROUND_TEXTURE
))
813 || ((nType
==CTRL_LISTBOX
) && (nPart
==HAS_BACKGROUND_TEXTURE
)) )
815 returnVal
= NWPaintGTKEditBox( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
817 else if ( ((nType
==CTRL_MULTILINE_EDITBOX
) && ((nPart
==PART_ENTIRE_CONTROL
) || (nPart
==HAS_BACKGROUND_TEXTURE
)) ) )
819 returnVal
= NWPaintGTKEditBox( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
821 else if ( ((nType
==CTRL_SPINBOX
) || (nType
==CTRL_SPINBUTTONS
))
822 && ((nPart
==PART_ENTIRE_CONTROL
) || (nPart
==PART_ALL_BUTTONS
)) )
824 returnVal
= NWPaintGTKSpinBox( nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
826 else if ( (nType
== CTRL_COMBOBOX
) &&
827 ( (nPart
==PART_ENTIRE_CONTROL
)
828 ||(nPart
==PART_BUTTON_DOWN
)
831 returnVal
= NWPaintGTKComboBox( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
833 else if ( (nType
==CTRL_TAB_ITEM
) || (nType
==CTRL_TAB_PANE
) || (nType
==CTRL_TAB_BODY
) || (nType
==CTRL_FIXEDBORDER
) )
835 if ( nType
== CTRL_TAB_BODY
)
838 returnVal
= NWPaintGTKTabItem( nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
840 else if ( (nType
==CTRL_LISTBOX
) && ((nPart
==PART_ENTIRE_CONTROL
) || (nPart
==PART_WINDOW
)) )
842 returnVal
= NWPaintGTKListBox( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
844 else if ( (nType
== CTRL_TOOLBAR
) )
846 returnVal
= NWPaintGTKToolbar( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
848 else if ( (nType
== CTRL_MENUBAR
) )
850 returnVal
= NWPaintGTKMenubar( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
852 else if( (nType
== CTRL_MENU_POPUP
)
853 && ( (nPart
== PART_ENTIRE_CONTROL
)
854 || (nPart
== PART_MENU_ITEM
)
855 || (nPart
== PART_MENU_ITEM_CHECK_MARK
)
856 || (nPart
== PART_MENU_ITEM_RADIO_MARK
)
860 returnVal
= NWPaintGTKPopupMenu( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
862 else if( (nType
== CTRL_TOOLTIP
) && (nPart
== PART_ENTIRE_CONTROL
) )
864 returnVal
= NWPaintGTKTooltip( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
866 else if( (nType
== CTRL_PROGRESS
) && (nPart
== PART_ENTIRE_CONTROL
) )
868 returnVal
= NWPaintGTKProgress( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
870 else if( (nType
== CTRL_LISTNODE
) && (nPart
== PART_ENTIRE_CONTROL
) )
872 returnVal
= NWPaintGTKListNode( gdkDrawable
, nType
, nPart
, aCtrlRect
, aClip
, nState
, aValue
, rControlHandle
, rCaption
);
874 else if( (nType
== CTRL_LISTNET
) && (nPart
== PART_ENTIRE_CONTROL
) )
876 // don't actually draw anything; gtk treeviews do not draw lines
882 returnVal
= NWRenderPixmapToScreen( pixmap
, aPixmapRect
) && returnVal
;
883 g_object_unref( pixmap
);
889 BOOL
GtkSalGraphics::drawNativeMixedStateCheck( ControlType nType
,
891 const Region
& rControlRegion
,
893 const ImplControlValue
& aValue
,
894 SalControlHandle
& rControlHandle
,
895 const OUString
& rCaption
)
897 // need to emulate something for mixed state
899 // do this via pixmap since some themes don't care for regions
900 bool bOldNeedPixmapPaint
= bNeedPixmapPaint
;
901 bNeedPixmapPaint
= true;
903 Rectangle aCtrlRect
= rControlRegion
.GetBoundRect();
904 BOOL returnVal
= FALSE
;
907 // draw upper half in off state
908 const_cast<ImplControlValue
&>(aValue
).setTristateVal( BUTTONVALUE_OFF
);
909 XLIB_Region aRegion
= XCreateRegion();
910 XRectangle aXRect
= { aCtrlRect
.Left(), aCtrlRect
.Top(), aCtrlRect
.GetWidth(), aCtrlRect
.GetHeight() };
911 const unsigned short nH
= aXRect
.height
/2;
913 XUnionRectWithRegion( &aXRect
, aRegion
, aRegion
);
914 SetClipRegion( pFontGC_
, aRegion
);
915 XDestroyRegion( aRegion
);
917 returnVal
= drawNativeControl( nType
, nPart
, rControlRegion
, nState
, aValue
, rControlHandle
, rCaption
);
921 // draw lower half in on state
922 const_cast<ImplControlValue
&>(aValue
).setTristateVal( BUTTONVALUE_ON
);
924 aRegion
= XCreateRegion();
925 XUnionRectWithRegion( &aXRect
, aRegion
, aRegion
);
926 SetClipRegion( pFontGC_
, aRegion
);
927 XDestroyRegion( aRegion
);
928 returnVal
= drawNativeControl( nType
, nPart
, rControlRegion
, nState
, aValue
, rControlHandle
, rCaption
);
932 bNeedPixmapPaint
= bOldNeedPixmapPaint
;
933 const_cast<ImplControlValue
&>(aValue
).setTristateVal( BUTTONVALUE_MIXED
);
934 SetClipRegion( pFontGC_
);
940 * DrawNativeControlText()
942 * OPTIONAL. Draws the requested text for the control described by nPart/nState.
943 * Used if text not drawn by DrawNativeControl().
945 * rControlRegion: The bounding region of the complete control in VCL frame coordinates.
946 * aValue: An optional value (tristate/numerical/string)
947 * rControlHandle: Carries platform dependent data and is maintained by the SalFrame implementation.
948 * rCaption: A caption or title string (like button text etc)
950 BOOL
GtkSalGraphics::drawNativeControlText( ControlType
,
954 const ImplControlValue
&,
963 * GetNativeControlRegion()
965 * If the return value is TRUE, rNativeBoundingRegion
966 * contains the TRUE bounding region covered by the control
967 * including any adornment, while rNativeContentRegion contains the area
968 * within the control that can be safely drawn into without drawing over
969 * the borders of the control.
971 * rControlRegion: The bounding region of the control in VCL frame coordinates.
972 * aValue: An optional value (tristate/numerical/string)
973 * rControlHandle: Carries platform dependent data and is maintained by the SalFrame implementation.
974 * rCaption: A caption or title string (like button text etc)
976 BOOL
GtkSalGraphics::getNativeControlRegion( ControlType nType
,
978 const Region
& rControlRegion
,
980 const ImplControlValue
& aValue
,
981 SalControlHandle
& rControlHandle
,
982 const OUString
& rCaption
,
983 Region
&rNativeBoundingRegion
,
984 Region
&rNativeContentRegion
)
986 BOOL returnVal
= FALSE
;
988 if ( (nType
==CTRL_PUSHBUTTON
) && (nPart
==PART_ENTIRE_CONTROL
)
989 && (rControlRegion
.GetBoundRect().GetWidth() > 16)
990 && (rControlRegion
.GetBoundRect().GetHeight() > 16) )
992 rNativeBoundingRegion
= NWGetButtonArea( m_nScreen
, nType
, nPart
, rControlRegion
.GetBoundRect(),
993 nState
, aValue
, rControlHandle
, rCaption
);
994 rNativeContentRegion
= rControlRegion
;
998 if ( (nType
==CTRL_COMBOBOX
) && ((nPart
==PART_BUTTON_DOWN
) || (nPart
==PART_SUB_EDIT
)) )
1000 rNativeBoundingRegion
= NWGetComboBoxButtonRect( m_nScreen
, nType
, nPart
, rControlRegion
.GetBoundRect(), nState
,
1001 aValue
, rControlHandle
, rCaption
);
1002 rNativeContentRegion
= rNativeBoundingRegion
;
1006 if ( (nType
==CTRL_SPINBOX
) && ((nPart
==PART_BUTTON_UP
) || (nPart
==PART_BUTTON_DOWN
) || (nPart
==PART_SUB_EDIT
)) )
1009 rNativeBoundingRegion
= NWGetSpinButtonRect( m_nScreen
, nType
, nPart
, rControlRegion
.GetBoundRect(), nState
,
1010 aValue
, rControlHandle
, rCaption
);
1011 rNativeContentRegion
= rNativeBoundingRegion
;
1015 if ( (nType
==CTRL_LISTBOX
) && ((nPart
==PART_BUTTON_DOWN
) || (nPart
==PART_SUB_EDIT
)) )
1017 rNativeBoundingRegion
= NWGetListBoxButtonRect( m_nScreen
, nType
, nPart
, rControlRegion
.GetBoundRect(), nState
,
1018 aValue
, rControlHandle
, rCaption
);
1019 rNativeContentRegion
= rNativeBoundingRegion
;
1023 if ( (nType
==CTRL_TOOLBAR
) &&
1024 ((nPart
==PART_DRAW_BACKGROUND_HORZ
) ||
1025 (nPart
==PART_DRAW_BACKGROUND_VERT
) ||
1026 (nPart
==PART_THUMB_HORZ
) ||
1027 (nPart
==PART_THUMB_VERT
) ||
1028 (nPart
==PART_BUTTON
)
1031 rNativeBoundingRegion
= NWGetToolbarRect( m_nScreen
, nType
, nPart
, rControlRegion
.GetBoundRect(), nState
, aValue
, rControlHandle
, rCaption
);
1032 rNativeContentRegion
= rNativeBoundingRegion
;
1035 if ( (nType
==CTRL_SCROLLBAR
) && ((nPart
==PART_BUTTON_LEFT
) || (nPart
==PART_BUTTON_RIGHT
) ||
1036 (nPart
==PART_BUTTON_UP
) || (nPart
==PART_BUTTON_DOWN
) ) )
1038 rNativeBoundingRegion
= NWGetScrollButtonRect( m_nScreen
, nPart
, rControlRegion
.GetBoundRect() );
1039 rNativeContentRegion
= rNativeBoundingRegion
;
1043 if( (nType
== CTRL_MENUBAR
) && (nPart
== PART_ENTIRE_CONTROL
) )
1045 NWEnsureGTKMenubar( m_nScreen
);
1046 GtkRequisition aReq
;
1047 gtk_widget_size_request( gWidgetData
[m_nScreen
].gMenubarWidget
, &aReq
);
1048 Rectangle aMenuBarRect
= rControlRegion
.GetBoundRect();
1049 aMenuBarRect
= Rectangle( aMenuBarRect
.TopLeft(),
1050 Size( aMenuBarRect
.GetWidth(), aReq
.height
+1 ) );
1051 rNativeBoundingRegion
= Region( aMenuBarRect
);
1052 rNativeContentRegion
= rNativeBoundingRegion
;
1055 if( (nType
== CTRL_MENU_POPUP
) )
1057 if( (nPart
== PART_MENU_ITEM_CHECK_MARK
) ||
1058 (nPart
== PART_MENU_ITEM_RADIO_MARK
) )
1060 NWEnsureGTKMenu( m_nScreen
);
1062 gint indicator_size
= 0;
1063 GtkWidget
* pWidget
= (nPart
== PART_MENU_ITEM_CHECK_MARK
) ?
1064 gWidgetData
[m_nScreen
].gMenuItemCheckMenuWidget
: gWidgetData
[m_nScreen
].gMenuItemRadioMenuWidget
;
1065 gtk_widget_style_get( pWidget
,
1066 "indicator_size", &indicator_size
,
1068 rNativeBoundingRegion
= rControlRegion
;
1069 Rectangle
aIndicatorRect( Point( 0,
1070 (rControlRegion
.GetBoundRect().GetHeight()-indicator_size
)/2),
1071 Size( indicator_size
, indicator_size
) );
1072 rNativeContentRegion
= Region( aIndicatorRect
);
1076 if( (nType
== CTRL_RADIOBUTTON
|| nType
== CTRL_CHECKBOX
) )
1078 NWEnsureGTKRadio( m_nScreen
);
1079 NWEnsureGTKCheck( m_nScreen
);
1080 GtkWidget
* widget
= (nType
== CTRL_RADIOBUTTON
) ? gWidgetData
[m_nScreen
].gRadioWidget
: gWidgetData
[m_nScreen
].gCheckWidget
;
1081 gint indicator_size
, indicator_spacing
;
1082 gtk_widget_style_get( widget
,
1083 "indicator_size", &indicator_size
,
1084 "indicator_spacing", &indicator_spacing
,
1086 indicator_size
+= 2*indicator_spacing
; // guess overpaint of theme
1087 rNativeBoundingRegion
= rControlRegion
;
1088 Rectangle
aIndicatorRect( Point( 0,
1089 (rControlRegion
.GetBoundRect().GetHeight()-indicator_size
)/2),
1090 Size( indicator_size
, indicator_size
) );
1091 rNativeContentRegion
= Region( aIndicatorRect
);
1095 return( returnVal
);
1099 /************************************************************************
1100 * Individual control drawing functions
1101 ************************************************************************/
1102 BOOL
GtkSalGraphics::NWPaintGTKButton(
1103 GdkDrawable
* gdkDrawable
,
1104 ControlType
, ControlPart
,
1105 const Rectangle
& rControlRectangle
,
1106 const clipList
& rClipList
,
1107 ControlState nState
, const ImplControlValue
&,
1108 SalControlHandle
&, const OUString
& )
1110 GtkStateType stateType
;
1111 GtkShadowType shadowType
;
1112 gboolean interiorFocus
;
1115 BOOL bDrawFocus
= TRUE
;
1117 GtkBorder aDefBorder
;
1119 GdkRectangle clipRect
;
1121 NWEnsureGTKButton( m_nScreen
);
1122 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
1124 x
= rControlRectangle
.Left();
1125 y
= rControlRectangle
.Top();
1126 w
= rControlRectangle
.GetWidth();
1127 h
= rControlRectangle
.GetHeight();
1129 // Grab some button style attributes
1130 gtk_widget_style_get( gWidgetData
[m_nScreen
].gBtnWidget
, "focus-line-width", &focusWidth
,
1131 "focus-padding", &focusPad
,
1132 "interior_focus", &interiorFocus
,
1133 "default_border", &pBorder
,
1136 // Make sure the border values exist, otherwise use some defaults
1139 NW_gtk_border_set_from_border( aDefBorder
, pBorder
);
1140 gtk_border_free( pBorder
);
1142 else NW_gtk_border_set_from_border( aDefBorder
, &aDefDefBorder
);
1144 // If the button is too small, don't ever draw focus or grab more space
1145 if ( (w
< 16) || (h
< 16) )
1148 NWSetWidgetState( gWidgetData
[m_nScreen
].gBtnWidget
, nState
, stateType
);
1150 gint xi
= x
, yi
= y
, wi
= w
, hi
= h
;
1151 if ( (nState
& CTRL_STATE_DEFAULT
) && bDrawFocus
)
1153 xi
+= aDefBorder
.left
;
1154 yi
+= aDefBorder
.top
;
1155 wi
-= aDefBorder
.left
+ aDefBorder
.right
;
1156 hi
-= aDefBorder
.top
+ aDefBorder
.bottom
;
1159 if ( !interiorFocus
&& bDrawFocus
)
1161 xi
+= focusWidth
+ focusPad
;
1162 yi
+= focusWidth
+ focusPad
;
1163 wi
-= 2 * (focusWidth
+ focusPad
);
1164 hi
-= 2 * (focusWidth
+ focusPad
);
1167 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
1169 clipRect
.x
= it
->Left();
1170 clipRect
.y
= it
->Top();
1171 clipRect
.width
= it
->GetWidth();
1172 clipRect
.height
= it
->GetHeight();
1174 // Buttons must paint opaque since some themes have alpha-channel enabled buttons
1175 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gBtnWidget
->style
, gdkDrawable
, GTK_STATE_NORMAL
, GTK_SHADOW_NONE
,
1176 &clipRect
, m_pWindow
, "base", x
, y
, w
, h
);
1178 if ( (nState
& CTRL_STATE_DEFAULT
) && (GTK_BUTTON(gWidgetData
[m_nScreen
].gBtnWidget
)->relief
== GTK_RELIEF_NORMAL
) )
1180 gtk_paint_box( gWidgetData
[m_nScreen
].gBtnWidget
->style
, gdkDrawable
, GTK_STATE_NORMAL
, GTK_SHADOW_IN
,
1181 &clipRect
, gWidgetData
[m_nScreen
].gBtnWidget
, "buttondefault", x
, y
, w
, h
);
1184 if ( (GTK_BUTTON(gWidgetData
[m_nScreen
].gBtnWidget
)->relief
!= GTK_RELIEF_NONE
)
1185 || (nState
& CTRL_STATE_PRESSED
)
1186 || (nState
& CTRL_STATE_ROLLOVER
) )
1188 gtk_paint_box( gWidgetData
[m_nScreen
].gBtnWidget
->style
, gdkDrawable
, stateType
, shadowType
,
1189 &clipRect
, gWidgetData
[m_nScreen
].gBtnWidget
, "button", xi
, yi
, wi
, hi
);
1192 #if 0 // VCL draws focus rects
1194 if ( (nState
& CTRL_STATE_FOCUSED
) && (nState
& CTRL_STATE_ENABLED
) && bDrawFocus
)
1198 x
+= gWidgetData
[m_nScreen
].gBtnWidget
->style
->xthickness
+ focusPad
;
1199 y
+= gWidgetData
[m_nScreen
].gBtnWidget
->style
->ythickness
+ focusPad
;
1200 w
-= 2 * (gWidgetData
[m_nScreen
].gBtnWidget
->style
->xthickness
+ focusPad
);
1201 h
-= 2 * (gWidgetData
[m_nScreen
].gBtnWidget
->style
->xthickness
+ focusPad
);
1205 x
-= focusWidth
+ focusPad
;
1206 y
-= focusWidth
+ focusPad
;
1207 w
+= 2 * (focusWidth
+ focusPad
);
1208 h
+= 2 * (focusWidth
+ focusPad
);
1210 if ( !interiorFocus
)
1211 gtk_paint_focus( gWidgetData
[m_nScreen
].gBtnWidget
->style
, gdkDrawable
, stateType
, &clipRect
,
1212 gWidgetData
[m_nScreen
].gBtnWidget
, "button", x
, y
, w
, h
);
1219 static Rectangle
NWGetButtonArea( int nScreen
,
1220 ControlType
, ControlPart
, Rectangle aAreaRect
, ControlState nState
,
1221 const ImplControlValue
&, SalControlHandle
&, const OUString
& )
1223 gboolean interiorFocus
;
1226 GtkBorder aDefBorder
;
1227 GtkBorder
* pBorder
;
1228 BOOL bDrawFocus
= TRUE
;
1232 NWEnsureGTKButton( nScreen
);
1233 gtk_widget_style_get( gWidgetData
[nScreen
].gBtnWidget
,
1234 "focus-line-width", &focusWidth
,
1235 "focus-padding", &focusPad
,
1236 "interior_focus", &interiorFocus
,
1237 "default_border", &pBorder
,
1240 // Make sure the border values exist, otherwise use some defaults
1243 NW_gtk_border_set_from_border( aDefBorder
, pBorder
);
1244 gtk_border_free( pBorder
);
1246 else NW_gtk_border_set_from_border( aDefBorder
, &aDefDefBorder
);
1248 x
= aAreaRect
.Left();
1249 y
= aAreaRect
.Top();
1250 w
= aAreaRect
.GetWidth();
1251 h
= aAreaRect
.GetHeight();
1253 // If the button is too small, don't ever draw focus or grab more space
1254 if ( (w
< 16) || (h
< 16) )
1257 if ( (nState
& CTRL_STATE_DEFAULT
) && bDrawFocus
)
1259 x
-= aDefBorder
.left
;
1260 y
-= aDefBorder
.top
;
1261 w
+= aDefBorder
.left
+ aDefBorder
.right
;
1262 h
+= aDefBorder
.top
+ aDefBorder
.bottom
;
1265 aRect
= Rectangle( Point( x
, y
), Size( w
, h
) );
1270 //-------------------------------------
1272 BOOL
GtkSalGraphics::NWPaintGTKRadio( GdkDrawable
* gdkDrawable
,
1273 ControlType
, ControlPart
,
1274 const Rectangle
& rControlRectangle
,
1275 const clipList
& rClipList
,
1276 ControlState nState
,
1277 const ImplControlValue
& aValue
, SalControlHandle
&,
1280 GtkStateType stateType
;
1281 GtkShadowType shadowType
;
1282 BOOL isChecked
= (aValue
.getTristateVal()==BUTTONVALUE_ON
);
1284 GdkRectangle clipRect
;
1286 NWEnsureGTKButton( m_nScreen
);
1287 NWEnsureGTKRadio( m_nScreen
);
1288 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
1290 gint indicator_size
;
1291 gtk_widget_style_get( gWidgetData
[m_nScreen
].gRadioWidget
, "indicator_size", &indicator_size
, (char *)NULL
);
1293 x
= rControlRectangle
.Left() + (rControlRectangle
.GetWidth()-indicator_size
)/2;
1294 y
= rControlRectangle
.Top() + (rControlRectangle
.GetHeight()-indicator_size
)/2;
1296 // Set the shadow based on if checked or not so we get a freakin checkmark.
1297 shadowType
= isChecked
? GTK_SHADOW_IN
: GTK_SHADOW_OUT
;
1298 NWSetWidgetState( gWidgetData
[m_nScreen
].gRadioWidget
, nState
, stateType
);
1299 NWSetWidgetState( gWidgetData
[m_nScreen
].gRadioWidgetSibling
, nState
, stateType
);
1301 // GTK enforces radio groups, so that if we don't have 2 buttons in the group,
1302 // the single button will always be active. So we have to have 2 buttons.
1304 // #i59666# set the members directly where we should use
1305 // gtk_toggle_button_set_active. reason: there are animated themes
1306 // which are in active state only after a while leading to painting
1307 // intermediate states between active/inactive. Let's hope that
1308 // GtkToggleButtone stays binary compatible.
1310 GTK_TOGGLE_BUTTON(gWidgetData
[m_nScreen
].gRadioWidgetSibling
)->active
= TRUE
;
1311 GTK_TOGGLE_BUTTON(gWidgetData
[m_nScreen
].gRadioWidget
)->active
= isChecked
;
1313 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
1315 clipRect
.x
= it
->Left();
1316 clipRect
.y
= it
->Top();
1317 clipRect
.width
= it
->GetWidth();
1318 clipRect
.height
= it
->GetHeight();
1320 gtk_paint_option( gWidgetData
[m_nScreen
].gRadioWidget
->style
, gdkDrawable
, stateType
, shadowType
,
1321 &clipRect
, gWidgetData
[m_nScreen
].gRadioWidget
, "radiobutton",
1322 x
, y
, indicator_size
, indicator_size
);
1328 //-------------------------------------
1330 BOOL
GtkSalGraphics::NWPaintGTKCheck( GdkDrawable
* gdkDrawable
,
1331 ControlType
, ControlPart
,
1332 const Rectangle
& rControlRectangle
,
1333 const clipList
& rClipList
,
1334 ControlState nState
,
1335 const ImplControlValue
& aValue
,
1336 SalControlHandle
&, const OUString
& )
1338 GtkStateType stateType
;
1339 GtkShadowType shadowType
;
1340 BOOL isChecked
= (aValue
.getTristateVal()==BUTTONVALUE_ON
) ? TRUE
: FALSE
;
1341 GdkRectangle clipRect
;
1344 NWEnsureGTKButton( m_nScreen
);
1345 NWEnsureGTKCheck( m_nScreen
);
1346 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
1348 gint indicator_size
;
1349 gtk_widget_style_get( gWidgetData
[m_nScreen
].gCheckWidget
, "indicator_size", &indicator_size
, (char *)NULL
);
1351 x
= rControlRectangle
.Left() + (rControlRectangle
.GetWidth()-indicator_size
)/2;
1352 y
= rControlRectangle
.Top() + (rControlRectangle
.GetHeight()-indicator_size
)/2;
1354 // Set the shadow based on if checked or not so we get a checkmark.
1355 shadowType
= isChecked
? GTK_SHADOW_IN
: GTK_SHADOW_OUT
;
1356 NWSetWidgetState( gWidgetData
[m_nScreen
].gCheckWidget
, nState
, stateType
);
1357 GTK_TOGGLE_BUTTON(gWidgetData
[m_nScreen
].gCheckWidget
)->active
= isChecked
;
1359 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
1361 clipRect
.x
= it
->Left();
1362 clipRect
.y
= it
->Top();
1363 clipRect
.width
= it
->GetWidth();
1364 clipRect
.height
= it
->GetHeight();
1366 gtk_paint_check( gWidgetData
[m_nScreen
].gCheckWidget
->style
, gdkDrawable
, stateType
, shadowType
,
1367 &clipRect
, gWidgetData
[m_nScreen
].gCheckWidget
, "checkbutton",
1368 x
, y
, indicator_size
, indicator_size
);
1374 //-------------------------------------
1375 static void NWCalcArrowRect( const Rectangle
& rButton
, Rectangle
& rArrow
)
1377 // Size the arrow appropriately
1378 Size
aSize( rButton
.GetWidth()/2, rButton
.GetHeight()/2 );
1379 rArrow
.SetSize( aSize
);
1381 rArrow
.SetPos( Point(
1382 rButton
.Left() + ( rButton
.GetWidth() - rArrow
.GetWidth() ) / 2,
1383 rButton
.Top() + ( rButton
.GetHeight() - rArrow
.GetHeight() ) / 2
1387 BOOL
GtkSalGraphics::NWPaintGTKScrollbar( ControlType
, ControlPart nPart
,
1388 const Rectangle
& rControlRectangle
,
1390 ControlState nState
,
1391 const ImplControlValue
& aValue
, SalControlHandle
&,
1394 ScrollbarValue
* pScrollbarVal
= (ScrollbarValue
*)(aValue
.getOptionalVal());
1395 GdkPixmap
* pixmap
= NULL
;
1396 Rectangle pixmapRect
, scrollbarRect
;
1397 GtkStateType stateType
;
1398 GtkShadowType shadowType
;
1399 GtkScrollbar
* scrollbarWidget
;
1401 GtkAdjustment
* scrollbarValues
= NULL
;
1402 GtkOrientation scrollbarOrientation
;
1403 Rectangle thumbRect
= pScrollbarVal
->maThumbRect
;
1404 Rectangle button11BoundRect
= pScrollbarVal
->maButton1Rect
; // backward
1405 Rectangle button22BoundRect
= pScrollbarVal
->maButton2Rect
; // forward
1406 Rectangle button12BoundRect
= pScrollbarVal
->maButton1Rect
; // secondary forward
1407 Rectangle button21BoundRect
= pScrollbarVal
->maButton2Rect
; // secondary backward
1408 GtkArrowType button1Type
; // backward
1409 GtkArrowType button2Type
; // forward
1410 gchar
* scrollbarTagH
= (gchar
*) "hscrollbar";
1411 gchar
* scrollbarTagV
= (gchar
*) "vscrollbar";
1412 gchar
* scrollbarTag
= NULL
;
1413 Rectangle arrowRect
;
1414 gint slider_width
= 0;
1415 gint stepper_size
= 0;
1416 gint stepper_spacing
= 0;
1417 gint trough_border
= 0;
1418 gint min_slider_length
= 0;
1423 // make controlvalue rectangles relative to area
1424 thumbRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
1425 button11BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
1426 button22BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
1427 button12BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
1428 button21BoundRect
.Move( -rControlRectangle
.Left(), -rControlRectangle
.Top() );
1430 NWEnsureGTKButton( m_nScreen
);
1431 NWEnsureGTKScrollbars( m_nScreen
);
1432 NWEnsureGTKArrow( m_nScreen
);
1434 // Find the overall bounding rect of the control
1435 pixmapRect
= rControlRectangle
;
1436 pixmapRect
.SetSize( Size( pixmapRect
.GetWidth() + 1,
1437 pixmapRect
.GetHeight() + 1 ) );
1438 scrollbarRect
= pixmapRect
;
1440 if ( (scrollbarRect
.GetWidth() <= 1) || (scrollbarRect
.GetHeight() <= 1) )
1443 // Grab some button style attributes
1444 gtk_widget_style_get( gWidgetData
[m_nScreen
].gScrollHorizWidget
,
1445 "slider_width", &slider_width
,
1446 "stepper_size", &stepper_size
,
1447 "trough_border", &trough_border
,
1448 "stepper_spacing", &stepper_spacing
,
1449 "min_slider_length", &min_slider_length
, (char *)NULL
);
1450 gboolean has_forward
;
1451 gboolean has_forward2
;
1452 gboolean has_backward
;
1453 gboolean has_backward2
;
1455 gtk_widget_style_get( gWidgetData
[m_nScreen
].gScrollHorizWidget
, "has-forward-stepper", &has_forward
,
1456 "has-secondary-forward-stepper", &has_forward2
,
1457 "has-backward-stepper", &has_backward
,
1458 "has-secondary-backward-stepper", &has_backward2
, (char *)NULL
);
1459 gint magic
= trough_border
? 1 : 0;
1462 if ( has_backward
) nFirst
+= 1;
1463 if ( has_forward2
) nFirst
+= 1;
1465 if ( nPart
== PART_DRAW_BACKGROUND_HORZ
)
1467 unsigned int sliderHeight
= slider_width
+ (trough_border
* 2);
1468 vShim
= (pixmapRect
.GetHeight() - sliderHeight
) / 2;
1470 scrollbarRect
.Move( 0, vShim
);
1471 scrollbarRect
.SetSize( Size( scrollbarRect
.GetWidth(), sliderHeight
) );
1473 scrollbarWidget
= GTK_SCROLLBAR( gWidgetData
[m_nScreen
].gScrollHorizWidget
);
1474 scrollbarOrientation
= GTK_ORIENTATION_HORIZONTAL
;
1475 scrollbarTag
= scrollbarTagH
;
1476 button1Type
= GTK_ARROW_LEFT
;
1477 button2Type
= GTK_ARROW_RIGHT
;
1481 button12BoundRect
.Move( stepper_size
- trough_border
,
1482 (scrollbarRect
.GetHeight() - slider_width
) / 2 );
1485 button11BoundRect
.Move( trough_border
, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
1486 button11BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
1487 button12BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
1489 if ( has_backward2
)
1491 button22BoundRect
.Move( stepper_size
+(trough_border
+1)/2, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
1492 button21BoundRect
.Move( (trough_border
+1)/2, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
1496 button22BoundRect
.Move( (trough_border
+1)/2, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
1499 button21BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
1500 button22BoundRect
.SetSize( Size( stepper_size
, slider_width
) );
1502 thumbRect
.Bottom() = thumbRect
.Top() + slider_width
- 1;
1503 // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
1504 // but if the VCL gives us a size smaller than the theme's default thumb size,
1505 // honor the VCL size
1507 if ( (thumbRect
.GetWidth() < min_slider_length
)
1508 && ((scrollbarRect
.GetWidth()-button1BoundRect
.GetWidth()-button2BoundRect
.GetWidth()) > min_slider_length
) )
1509 thumbRect
.SetSize( Size( min_slider_length
, thumbRect
.GetHeight() ) );
1512 thumbRect
.Right() += magic
;
1513 // Center vertically in the track
1514 thumbRect
.Move( 0, (scrollbarRect
.GetHeight() - slider_width
) / 2 );
1518 unsigned int sliderWidth
= slider_width
+ (trough_border
* 2);
1519 hShim
= (pixmapRect
.GetWidth() - sliderWidth
) / 2;
1521 scrollbarRect
.Move( hShim
, 0 );
1522 scrollbarRect
.SetSize( Size( sliderWidth
, scrollbarRect
.GetHeight() ) );
1524 scrollbarWidget
= GTK_SCROLLBAR( gWidgetData
[m_nScreen
].gScrollVertWidget
);
1525 scrollbarOrientation
= GTK_ORIENTATION_VERTICAL
;
1526 scrollbarTag
= scrollbarTagV
;
1527 button1Type
= GTK_ARROW_UP
;
1528 button2Type
= GTK_ARROW_DOWN
;
1532 button12BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2,
1533 stepper_size
+ trough_border
);
1535 button11BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, trough_border
);
1536 button11BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
1537 button12BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
1539 if ( has_backward2
)
1541 button22BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, stepper_size
+(trough_border
+1)/2 );
1542 button21BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, (trough_border
+1)/2 );
1546 button22BoundRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, (trough_border
+1)/2 );
1549 button21BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
1550 button22BoundRect
.SetSize( Size( slider_width
, stepper_size
) );
1552 thumbRect
.Right() = thumbRect
.Left() + slider_width
- 1;
1554 // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
1555 // but if the VCL gives us a size smaller than the theme's default thumb size,
1556 // honor the VCL size
1557 if ( (thumbRect
.GetHeight() < min_slider_length
)
1558 && ((scrollbarRect
.GetHeight()-button1BoundRect
.GetHeight()-button2BoundRect
.GetHeight()) > min_slider_length
) )
1559 thumbRect
.SetSize( Size( thumbRect
.GetWidth(), min_slider_length
) );
1562 thumbRect
.Bottom() += magic
;
1563 // Center horizontally in the track
1564 thumbRect
.Move( (scrollbarRect
.GetWidth() - slider_width
) / 2, 0 );
1567 BOOL has_slider
= ( thumbRect
.GetWidth() > 0 && thumbRect
.GetHeight() > 0 );
1569 scrollbarValues
= gtk_range_get_adjustment( GTK_RANGE(scrollbarWidget
) );
1570 if ( scrollbarValues
== NULL
)
1571 scrollbarValues
= GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
1572 if ( nPart
== PART_DRAW_BACKGROUND_HORZ
)
1574 scrollbarValues
->lower
= pScrollbarVal
->mnMin
;
1575 scrollbarValues
->upper
= pScrollbarVal
->mnMax
;
1576 scrollbarValues
->value
= pScrollbarVal
->mnCur
;
1577 scrollbarValues
->page_size
= scrollbarRect
.GetWidth() / 2;
1581 scrollbarValues
->lower
= pScrollbarVal
->mnMin
;
1582 scrollbarValues
->upper
= pScrollbarVal
->mnMax
;
1583 scrollbarValues
->value
= pScrollbarVal
->mnCur
;
1584 scrollbarValues
->page_size
= scrollbarRect
.GetHeight() / 2;
1586 gtk_adjustment_changed( scrollbarValues
);
1588 // as multiple paints are required for the scrollbar
1589 // painting them directly to the window flickers
1590 pixmap
= NWGetPixmapFromScreen( pixmapRect
);
1595 w
= pixmapRect
.GetWidth();
1596 h
= pixmapRect
.GetHeight();
1598 GdkDrawable
* const &gdkDrawable
= GDK_DRAWABLE( pixmap
);
1599 GdkRectangle
* gdkRect
= NULL
;
1601 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
1602 NWSetWidgetState( GTK_WIDGET(scrollbarWidget
), nState
, stateType
);
1603 NWSetWidgetState( gWidgetData
[m_nScreen
].gBtnWidget
, nState
, stateType
);
1604 style
= GTK_WIDGET( scrollbarWidget
)->style
;
1606 // ----------------- TROUGH
1607 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gBtnWidget
->style
, gdkDrawable
,
1608 GTK_STATE_NORMAL
, GTK_SHADOW_NONE
, gdkRect
,
1609 m_pWindow
, "base", x
, y
,
1611 gtk_paint_box( style
, gdkDrawable
, GTK_STATE_ACTIVE
, GTK_SHADOW_IN
,
1612 gdkRect
, GTK_WIDGET(scrollbarWidget
), "trough",
1614 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
1616 if ( nState
& CTRL_STATE_FOCUSED
)
1618 gtk_paint_focus( style
, gdkDrawable
, GTK_STATE_ACTIVE
,
1619 gdkRect
, GTK_WIDGET(scrollbarWidget
), "trough",
1621 scrollbarRect
.GetWidth(), scrollbarRect
.GetHeight() );
1624 // ----------------- THUMB
1627 NWConvertVCLStateToGTKState( pScrollbarVal
->mnThumbState
, &stateType
, &shadowType
);
1628 if ( pScrollbarVal
->mnThumbState
& CTRL_STATE_PRESSED
) stateType
= GTK_STATE_PRELIGHT
;
1629 gtk_paint_slider( style
, gdkDrawable
, stateType
, GTK_SHADOW_OUT
,
1630 gdkRect
, GTK_WIDGET(scrollbarWidget
), "slider",
1631 x
+hShim
+thumbRect
.Left(), y
+vShim
+thumbRect
.Top(),
1632 thumbRect
.GetWidth(), thumbRect
.GetHeight(), scrollbarOrientation
);
1634 // ----------------- BUTTON 1 //
1637 NWConvertVCLStateToGTKState( pScrollbarVal
->mnButton1State
, &stateType
, &shadowType
);
1638 if ( stateType
== GTK_STATE_INSENSITIVE
) stateType
= GTK_STATE_NORMAL
;
1639 gtk_paint_box( style
, gdkDrawable
, stateType
, shadowType
,
1640 gdkRect
, GTK_WIDGET(scrollbarWidget
), "stepper",
1641 x
+hShim
+button11BoundRect
.Left(), y
+vShim
+button11BoundRect
.Top(),
1642 button11BoundRect
.GetWidth(), button11BoundRect
.GetHeight() );
1643 // ----------------- ARROW 1
1644 NWCalcArrowRect( button11BoundRect
, arrowRect
);
1645 gtk_paint_arrow( style
, gdkDrawable
, stateType
, shadowType
,
1646 gdkRect
, GTK_WIDGET(scrollbarWidget
), scrollbarTag
, button1Type
, TRUE
,
1647 x
+hShim
+arrowRect
.Left(), y
+vShim
+arrowRect
.Top(),
1648 arrowRect
.GetWidth(), arrowRect
.GetHeight() );
1652 NWConvertVCLStateToGTKState( pScrollbarVal
->mnButton2State
, &stateType
, &shadowType
);
1653 if ( stateType
== GTK_STATE_INSENSITIVE
) stateType
= GTK_STATE_NORMAL
;
1654 gtk_paint_box( style
, gdkDrawable
, stateType
, shadowType
,
1655 gdkRect
, GTK_WIDGET(scrollbarWidget
), "stepper",
1656 x
+hShim
+button12BoundRect
.Left(), y
+vShim
+button12BoundRect
.Top(),
1657 button12BoundRect
.GetWidth(), button12BoundRect
.GetHeight() );
1658 // ----------------- ARROW 1
1659 NWCalcArrowRect( button12BoundRect
, arrowRect
);
1660 gtk_paint_arrow( style
, gdkDrawable
, stateType
, shadowType
,
1661 gdkRect
, GTK_WIDGET(scrollbarWidget
), scrollbarTag
, button2Type
, TRUE
,
1662 x
+hShim
+arrowRect
.Left(), y
+vShim
+arrowRect
.Top(),
1663 arrowRect
.GetWidth(), arrowRect
.GetHeight() );
1665 // ----------------- BUTTON 2
1666 if ( has_backward2
)
1668 NWConvertVCLStateToGTKState( pScrollbarVal
->mnButton1State
, &stateType
, &shadowType
);
1669 if ( stateType
== GTK_STATE_INSENSITIVE
) stateType
= GTK_STATE_NORMAL
;
1670 gtk_paint_box( style
, gdkDrawable
, stateType
, shadowType
, gdkRect
,
1671 GTK_WIDGET(scrollbarWidget
), "stepper",
1672 x
+hShim
+button21BoundRect
.Left(), y
+vShim
+button21BoundRect
.Top(),
1673 button21BoundRect
.GetWidth(), button21BoundRect
.GetHeight() );
1674 // ----------------- ARROW 2
1675 NWCalcArrowRect( button21BoundRect
, arrowRect
);
1676 gtk_paint_arrow( style
, gdkDrawable
, stateType
, shadowType
,
1677 gdkRect
, GTK_WIDGET(scrollbarWidget
), scrollbarTag
, button1Type
, TRUE
,
1678 x
+hShim
+arrowRect
.Left(), y
+vShim
+arrowRect
.Top(),
1679 arrowRect
.GetWidth(), arrowRect
.GetHeight() );
1683 NWConvertVCLStateToGTKState( pScrollbarVal
->mnButton2State
, &stateType
, &shadowType
);
1684 if ( stateType
== GTK_STATE_INSENSITIVE
) stateType
= GTK_STATE_NORMAL
;
1685 gtk_paint_box( style
, gdkDrawable
, stateType
, shadowType
, gdkRect
,
1686 GTK_WIDGET(scrollbarWidget
), "stepper",
1687 x
+hShim
+button22BoundRect
.Left(), y
+vShim
+button22BoundRect
.Top(),
1688 button22BoundRect
.GetWidth(), button22BoundRect
.GetHeight() );
1689 // ----------------- ARROW 2
1690 NWCalcArrowRect( button22BoundRect
, arrowRect
);
1691 gtk_paint_arrow( style
, gdkDrawable
, stateType
, shadowType
,
1692 gdkRect
, GTK_WIDGET(scrollbarWidget
), scrollbarTag
, button2Type
, TRUE
,
1693 x
+hShim
+arrowRect
.Left(), y
+vShim
+arrowRect
.Top(),
1694 arrowRect
.GetWidth(), arrowRect
.GetHeight() );
1697 if( !NWRenderPixmapToScreen(pixmap
, pixmapRect
) )
1699 g_object_unref( pixmap
);
1702 g_object_unref( pixmap
);
1709 static Rectangle
NWGetScrollButtonRect( int nScreen
, ControlPart nPart
, Rectangle aAreaRect
)
1713 gint stepper_spacing
;
1716 NWEnsureGTKScrollbars( nScreen
);
1718 // Grab some button style attributes
1719 gtk_widget_style_get( gWidgetData
[nScreen
].gScrollHorizWidget
,
1720 "slider-width", &slider_width
,
1721 "stepper-size", &stepper_size
,
1722 "trough-border", &trough_border
,
1723 "stepper-spacing", &stepper_spacing
, (char *)NULL
);
1725 gboolean has_forward
;
1726 gboolean has_forward2
;
1727 gboolean has_backward
;
1728 gboolean has_backward2
;
1730 gtk_widget_style_get( gWidgetData
[nScreen
].gScrollHorizWidget
,
1731 "has-forward-stepper", &has_forward
,
1732 "has-secondary-forward-stepper", &has_forward2
,
1733 "has-backward-stepper", &has_backward
,
1734 "has-secondary-backward-stepper", &has_backward2
, (char *)NULL
);
1737 Rectangle buttonRect
;
1742 if ( has_forward
) nSecond
+= 1;
1743 if ( has_forward2
) nFirst
+= 1;
1744 if ( has_backward
) nFirst
+= 1;
1745 if ( has_backward2
) nSecond
+= 1;
1747 if ( ( nPart
== PART_BUTTON_UP
) || ( nPart
== PART_BUTTON_DOWN
) )
1749 buttonWidth
= slider_width
+ 2 * trough_border
;
1750 buttonHeight
= stepper_size
+ trough_border
+ stepper_spacing
;
1754 buttonWidth
= stepper_size
+ trough_border
+ stepper_spacing
;
1755 buttonHeight
= slider_width
+ 2 * trough_border
;
1758 if ( nPart
== PART_BUTTON_UP
)
1760 buttonHeight
*= nFirst
;
1762 buttonRect
.setX( aAreaRect
.Left() );
1763 buttonRect
.setY( aAreaRect
.Top() );
1765 else if ( nPart
== PART_BUTTON_LEFT
)
1767 buttonWidth
*= nFirst
;
1769 buttonRect
.setX( aAreaRect
.Left() );
1770 buttonRect
.setY( aAreaRect
.Top() );
1772 else if ( nPart
== PART_BUTTON_DOWN
)
1774 buttonHeight
*= nSecond
;
1775 buttonRect
.setX( aAreaRect
.Left() );
1776 buttonRect
.setY( aAreaRect
.Top() + aAreaRect
.GetHeight() - buttonHeight
);
1778 else if ( nPart
== PART_BUTTON_RIGHT
)
1780 buttonWidth
*= nSecond
;
1781 buttonRect
.setX( aAreaRect
.Left() + aAreaRect
.GetWidth() - buttonWidth
);
1782 buttonRect
.setY( aAreaRect
.Top() );
1785 buttonRect
.SetSize( Size( buttonWidth
, buttonHeight
) );
1787 return( buttonRect
);
1790 //-------------------------------------
1792 BOOL
GtkSalGraphics::NWPaintGTKEditBox( GdkDrawable
* gdkDrawable
,
1793 ControlType nType
, ControlPart nPart
,
1794 const Rectangle
& rControlRectangle
,
1795 const clipList
& rClipList
,
1796 ControlState nState
,
1797 const ImplControlValue
& aValue
, SalControlHandle
& rControlHandle
,
1798 const OUString
& rCaption
)
1800 Rectangle pixmapRect
;
1801 GdkRectangle clipRect
;
1803 // Find the overall bounding rect of the buttons's drawing area,
1804 // plus its actual draw rect excluding adornment
1805 pixmapRect
= NWGetEditBoxPixmapRect( m_nScreen
, nType
, nPart
, rControlRectangle
,
1806 nState
, aValue
, rControlHandle
, rCaption
);
1807 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
1809 clipRect
.x
= it
->Left();
1810 clipRect
.y
= it
->Top();
1811 clipRect
.width
= it
->GetWidth();
1812 clipRect
.height
= it
->GetHeight();
1814 NWPaintOneEditBox( m_nScreen
, gdkDrawable
, &clipRect
, nType
, nPart
, pixmapRect
, nState
, aValue
, rControlHandle
, rCaption
);
1821 /* Take interior/exterior focus into account and return
1822 * the bounding rectangle of the edit box including
1823 * any focus requirements.
1825 static Rectangle
NWGetEditBoxPixmapRect(int nScreen
,
1828 Rectangle aAreaRect
,
1830 const ImplControlValue
&,
1834 Rectangle pixmapRect
= aAreaRect
;
1835 gboolean interiorFocus
;
1838 NWEnsureGTKEditBox( nScreen
);
1840 // Grab some entry style attributes
1841 gtk_widget_style_get( gWidgetData
[nScreen
].gEditBoxWidget
,
1842 "focus-line-width", &focusWidth
,
1843 "interior-focus", &interiorFocus
, (char *)NULL
);
1845 if ( !interiorFocus
)
1847 pixmapRect
.Move( -(focusWidth
), -(focusWidth
) );
1848 pixmapRect
.SetSize( Size( pixmapRect
.GetWidth() + (2*(focusWidth
)),
1849 pixmapRect
.GetHeight() + (2*(focusWidth
)) ) );
1852 return( pixmapRect
);
1856 /* Paint a GTK Entry widget into the specified GdkPixmap.
1857 * All coordinates should be local to the Pixmap, NOT
1858 * screen/window coordinates.
1860 static void NWPaintOneEditBox( int nScreen
,
1861 GdkDrawable
* gdkDrawable
,
1862 GdkRectangle
* gdkRect
,
1865 Rectangle aEditBoxRect
,
1866 ControlState nState
,
1867 const ImplControlValue
&,
1871 GtkStateType stateType
;
1872 GtkShadowType shadowType
;
1875 NWEnsureGTKButton( nScreen
);
1876 NWEnsureGTKEditBox( nScreen
);
1877 NWEnsureGTKSpinButton( nScreen
);
1878 NWEnsureGTKCombo( nScreen
);
1879 NWEnsureGTKScrolledWindow( nScreen
);
1880 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
1882 /* border's shadowType for gtk entries is always GTK_SHADOW_IN (see gtkentry.c)
1883 shadowType = GTK_SHADOW_IN;
1889 widget
= gWidgetData
[nScreen
].gSpinButtonWidget
;
1892 case CTRL_MULTILINE_EDITBOX
:
1893 widget
= gWidgetData
[nScreen
].gScrolledWindowWidget
;
1896 widget
= GTK_COMBO(gWidgetData
[nScreen
].gComboWidget
)->entry
;
1900 widget
= gWidgetData
[nScreen
].gEditBoxWidget
;
1904 if ( stateType
== GTK_STATE_PRELIGHT
)
1905 stateType
= GTK_STATE_NORMAL
;
1907 // Blueprint needs to paint entry_bg with a Button widget, not an Entry widget to get
1908 // a nice white (or whatever default color) background
1909 GtkWidget
* pBGWidget
= widget
;
1910 if( GtkSalGraphics::bNeedButtonStyleAsEditBackgroundWorkaround
)
1912 NWSetWidgetState( gWidgetData
[nScreen
].gBtnWidget
, nState
, stateType
);
1913 pBGWidget
= gWidgetData
[nScreen
].gBtnWidget
;
1915 NWSetWidgetState( widget
, nState
, stateType
);
1917 gtk_paint_flat_box( pBGWidget
->style
, gdkDrawable
, stateType
, GTK_SHADOW_NONE
,
1918 gdkRect
, pBGWidget
, "entry_bg",
1919 aEditBoxRect
.Left(), aEditBoxRect
.Top(),
1920 aEditBoxRect
.GetWidth(), aEditBoxRect
.GetHeight() );
1921 gtk_paint_shadow( widget
->style
, gdkDrawable
, GTK_STATE_NORMAL
, GTK_SHADOW_IN
,
1922 gdkRect
, widget
, "entry",
1923 aEditBoxRect
.Left(), aEditBoxRect
.Top(),
1924 aEditBoxRect
.GetWidth(), aEditBoxRect
.GetHeight() );
1930 //-------------------------------------
1932 BOOL
GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType
, ControlPart nPart
,
1933 const Rectangle
& rControlRectangle
,
1935 ControlState nState
,
1936 const ImplControlValue
& aValue
,
1937 SalControlHandle
& rControlHandle
, const OUString
& rCaption
)
1940 Rectangle pixmapRect
;
1941 GtkStateType stateType
;
1942 GtkShadowType shadowType
;
1943 SpinbuttonValue
* pSpinVal
= (SpinbuttonValue
*)(aValue
.getOptionalVal());
1944 Rectangle upBtnRect
;
1945 ControlPart upBtnPart
= PART_BUTTON_UP
;
1946 ControlState upBtnState
= CTRL_STATE_ENABLED
;
1947 Rectangle downBtnRect
;
1948 ControlPart downBtnPart
= PART_BUTTON_DOWN
;
1949 ControlState downBtnState
= CTRL_STATE_ENABLED
;
1951 NWEnsureGTKButton( m_nScreen
);
1952 NWEnsureGTKSpinButton( m_nScreen
);
1953 NWEnsureGTKArrow( m_nScreen
);
1955 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
1959 upBtnPart
= pSpinVal
->mnUpperPart
;
1960 upBtnState
= pSpinVal
->mnUpperState
;
1962 downBtnPart
= pSpinVal
->mnLowerPart
;
1963 downBtnState
= pSpinVal
->mnLowerState
;
1966 // CTRL_SPINBUTTONS pass their area in pSpinVal, not in rControlRectangle
1967 if ( nType
== CTRL_SPINBUTTONS
)
1971 std::fprintf( stderr
, "Tried to draw CTRL_SPINBUTTONS, but the SpinButtons data structure didn't exist!\n" );
1974 pixmapRect
= pSpinVal
->maUpperRect
;
1975 pixmapRect
.Union( pSpinVal
->maLowerRect
);
1978 pixmapRect
= rControlRectangle
;
1981 pixmap
= NWGetPixmapFromScreen( pixmapRect
);
1985 upBtnRect
= NWGetSpinButtonRect( m_nScreen
, nType
, upBtnPart
, pixmapRect
, upBtnState
, aValue
, rControlHandle
, rCaption
);
1986 downBtnRect
= NWGetSpinButtonRect( m_nScreen
, nType
, downBtnPart
, pixmapRect
, downBtnState
, aValue
, rControlHandle
, rCaption
);
1988 if ( (nType
==CTRL_SPINBOX
) && (nPart
!=PART_ALL_BUTTONS
) )
1990 // Draw an edit field for SpinBoxes and ComboBoxes
1991 Rectangle
aEditBoxRect( pixmapRect
);
1992 aEditBoxRect
.SetSize( Size( upBtnRect
.Left() - pixmapRect
.Left(), aEditBoxRect
.GetHeight() ) );
1993 aEditBoxRect
.setX( 0 );
1994 aEditBoxRect
.setY( 0 );
1996 NWPaintOneEditBox( m_nScreen
, pixmap
, NULL
, nType
, nPart
, aEditBoxRect
, nState
, aValue
, rControlHandle
, rCaption
);
1999 NWSetWidgetState( gWidgetData
[m_nScreen
].gSpinButtonWidget
, nState
, stateType
);
2000 gtk_widget_style_get( gWidgetData
[m_nScreen
].gSpinButtonWidget
, "shadow_type", &shadowType
, (char *)NULL
);
2002 if ( shadowType
!= GTK_SHADOW_NONE
)
2004 Rectangle
shadowRect( upBtnRect
);
2006 shadowRect
.Union( downBtnRect
);
2007 gtk_paint_box( gWidgetData
[m_nScreen
].gSpinButtonWidget
->style
, pixmap
, GTK_STATE_NORMAL
, shadowType
, NULL
,
2008 gWidgetData
[m_nScreen
].gSpinButtonWidget
, "spinbutton",
2009 (shadowRect
.Left() - pixmapRect
.Left()), (shadowRect
.Top() - pixmapRect
.Top()),
2010 shadowRect
.GetWidth(), shadowRect
.GetHeight() );
2013 NWPaintOneSpinButton( m_nScreen
, pixmap
, nType
, upBtnPart
, pixmapRect
, upBtnState
, aValue
, rControlHandle
, rCaption
);
2014 NWPaintOneSpinButton( m_nScreen
, pixmap
, nType
, downBtnPart
, pixmapRect
, downBtnState
, aValue
, rControlHandle
, rCaption
);
2016 if( !NWRenderPixmapToScreen(pixmap
, pixmapRect
) )
2018 g_object_unref( pixmap
);
2022 g_object_unref( pixmap
);
2028 static Rectangle
NWGetSpinButtonRect( int nScreen
,
2031 Rectangle aAreaRect
,
2033 const ImplControlValue
&,
2038 Rectangle buttonRect
;
2040 NWEnsureGTKSpinButton( nScreen
);
2042 buttonSize
= MAX( PANGO_PIXELS( pango_font_description_get_size(GTK_WIDGET(gWidgetData
[nScreen
].gSpinButtonWidget
)->style
->font_desc
) ),
2043 MIN_SPIN_ARROW_WIDTH
);
2044 buttonSize
-= buttonSize
% 2 - 1; /* force odd */
2045 buttonRect
.SetSize( Size( buttonSize
+ 2 * gWidgetData
[nScreen
].gSpinButtonWidget
->style
->xthickness
,
2046 buttonRect
.GetHeight() ) );
2047 buttonRect
.setX( aAreaRect
.Left() + (aAreaRect
.GetWidth() - buttonRect
.GetWidth()) );
2048 if ( nPart
== PART_BUTTON_UP
)
2050 buttonRect
.setY( aAreaRect
.Top() );
2051 buttonRect
.Bottom() = buttonRect
.Top() + (aAreaRect
.GetHeight() / 2);
2053 else if( nPart
== PART_BUTTON_DOWN
)
2055 buttonRect
.setY( aAreaRect
.Top() + (aAreaRect
.GetHeight() / 2) );
2056 buttonRect
.Bottom() = aAreaRect
.Bottom(); // cover area completely
2060 buttonRect
.Right() = buttonRect
.Left()-1;
2061 buttonRect
.Left() = aAreaRect
.Left();
2062 buttonRect
.Top() = aAreaRect
.Top();
2063 buttonRect
.Bottom() = aAreaRect
.Bottom();
2066 return( buttonRect
);
2071 static void NWPaintOneSpinButton( int nScreen
,
2075 Rectangle aAreaRect
,
2076 ControlState nState
,
2077 const ImplControlValue
& aValue
,
2078 SalControlHandle
& rControlHandle
,
2079 const OUString
& rCaption
)
2081 Rectangle buttonRect
;
2082 GtkStateType stateType
;
2083 GtkShadowType shadowType
;
2084 Rectangle arrowRect
;
2087 NWEnsureGTKSpinButton( nScreen
);
2088 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2090 buttonRect
= NWGetSpinButtonRect( nScreen
, nType
, nPart
, aAreaRect
, nState
, aValue
, rControlHandle
, rCaption
);
2092 NWSetWidgetState( gWidgetData
[nScreen
].gSpinButtonWidget
, nState
, stateType
);
2093 gtk_paint_box( gWidgetData
[nScreen
].gSpinButtonWidget
->style
, pixmap
, stateType
, shadowType
, NULL
, gWidgetData
[nScreen
].gSpinButtonWidget
,
2094 (nPart
== PART_BUTTON_UP
) ? "spinbutton_up" : "spinbutton_down",
2095 (buttonRect
.Left() - aAreaRect
.Left()), (buttonRect
.Top() - aAreaRect
.Top()),
2096 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
2098 arrowSize
= (buttonRect
.GetWidth() - (2 * gWidgetData
[nScreen
].gSpinButtonWidget
->style
->xthickness
)) - 4;
2099 arrowSize
-= arrowSize
% 2 - 1; /* force odd */
2100 arrowRect
.SetSize( Size( arrowSize
, arrowSize
) );
2101 arrowRect
.setX( buttonRect
.Left() + (buttonRect
.GetWidth() - arrowRect
.GetWidth()) / 2 );
2102 if ( nPart
== PART_BUTTON_UP
)
2103 arrowRect
.setY( buttonRect
.Top() + (buttonRect
.GetHeight() - arrowRect
.GetHeight()) / 2 + 1);
2105 arrowRect
.setY( buttonRect
.Top() + (buttonRect
.GetHeight() - arrowRect
.GetHeight()) / 2 - 1);
2107 gtk_paint_arrow( gWidgetData
[nScreen
].gSpinButtonWidget
->style
, pixmap
, stateType
, GTK_SHADOW_OUT
, NULL
, gWidgetData
[nScreen
].gSpinButtonWidget
,
2108 "spinbutton", (nPart
== PART_BUTTON_UP
) ? GTK_ARROW_UP
: GTK_ARROW_DOWN
, TRUE
,
2109 (arrowRect
.Left() - aAreaRect
.Left()), (arrowRect
.Top() - aAreaRect
.Top()),
2110 arrowRect
.GetWidth(), arrowRect
.GetHeight() );
2114 //-------------------------------------
2116 BOOL
GtkSalGraphics::NWPaintGTKComboBox( GdkDrawable
* gdkDrawable
,
2117 ControlType nType
, ControlPart nPart
,
2118 const Rectangle
& rControlRectangle
,
2119 const clipList
& rClipList
,
2120 ControlState nState
,
2121 const ImplControlValue
& aValue
,
2122 SalControlHandle
& rControlHandle
, const OUString
& rCaption
)
2124 Rectangle pixmapRect
;
2125 Rectangle buttonRect
;
2126 GtkStateType stateType
;
2127 GtkShadowType shadowType
;
2128 Rectangle arrowRect
;
2130 GdkRectangle clipRect
;
2132 NWEnsureGTKButton( m_nScreen
);
2133 NWEnsureGTKArrow( m_nScreen
);
2134 NWEnsureGTKCombo( m_nScreen
);
2135 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2137 // Find the overall bounding rect of the buttons's drawing area,
2138 // plus its actual draw rect excluding adornment
2139 pixmapRect
= rControlRectangle
;
2140 x
= rControlRectangle
.Left();
2141 y
= rControlRectangle
.Top();
2143 NWSetWidgetState( gWidgetData
[m_nScreen
].gBtnWidget
, nState
, stateType
);
2144 NWSetWidgetState( gWidgetData
[m_nScreen
].gComboWidget
, nState
, stateType
);
2145 NWSetWidgetState( gWidgetData
[m_nScreen
].gArrowWidget
, nState
, stateType
);
2147 buttonRect
= NWGetComboBoxButtonRect( m_nScreen
, nType
, PART_BUTTON_DOWN
, pixmapRect
, nState
, aValue
, rControlHandle
, rCaption
);
2148 if( nPart
== PART_BUTTON_DOWN
)
2149 buttonRect
.Left() += 1;
2151 Rectangle
aEditBoxRect( pixmapRect
);
2152 aEditBoxRect
.SetSize( Size( pixmapRect
.GetWidth() - buttonRect
.GetWidth(), aEditBoxRect
.GetHeight() ) );
2154 #define ARROW_EXTENT 0.7
2155 arrowRect
.SetSize( Size( (gint
)(MIN_ARROW_SIZE
* ARROW_EXTENT
),
2156 (gint
)(MIN_ARROW_SIZE
* ARROW_EXTENT
) ) );
2157 arrowRect
.SetPos( Point( buttonRect
.Left() + (gint
)((buttonRect
.GetWidth() - arrowRect
.GetWidth()) / 2),
2158 buttonRect
.Top() + (gint
)((buttonRect
.GetHeight() - arrowRect
.GetHeight()) / 2) ) );
2160 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
2162 clipRect
.x
= it
->Left();
2163 clipRect
.y
= it
->Top();
2164 clipRect
.width
= it
->GetWidth();
2165 clipRect
.height
= it
->GetHeight();
2167 if( nPart
== PART_ENTIRE_CONTROL
)
2168 NWPaintOneEditBox( m_nScreen
, gdkDrawable
, &clipRect
, nType
, nPart
, aEditBoxRect
,
2169 nState
, aValue
, rControlHandle
, rCaption
);
2171 // Buttons must paint opaque since some themes have alpha-channel enabled buttons
2172 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gBtnWidget
->style
, gdkDrawable
, GTK_STATE_NORMAL
, GTK_SHADOW_NONE
,
2173 &clipRect
, m_pWindow
, "base",
2174 x
+(buttonRect
.Left() - pixmapRect
.Left()),
2175 y
+(buttonRect
.Top() - pixmapRect
.Top()),
2176 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
2177 gtk_paint_box( GTK_COMBO(gWidgetData
[m_nScreen
].gComboWidget
)->button
->style
, gdkDrawable
, stateType
, shadowType
,
2178 &clipRect
, GTK_COMBO(gWidgetData
[m_nScreen
].gComboWidget
)->button
, "button",
2179 x
+(buttonRect
.Left() - pixmapRect
.Left()),
2180 y
+(buttonRect
.Top() - pixmapRect
.Top()),
2181 buttonRect
.GetWidth(), buttonRect
.GetHeight() );
2183 gtk_paint_arrow( gWidgetData
[m_nScreen
].gArrowWidget
->style
, gdkDrawable
, stateType
, shadowType
,
2184 &clipRect
, gWidgetData
[m_nScreen
].gArrowWidget
, "arrow", GTK_ARROW_DOWN
, TRUE
,
2185 x
+(arrowRect
.Left() - pixmapRect
.Left()), y
+(arrowRect
.Top() - pixmapRect
.Top()),
2186 arrowRect
.GetWidth(), arrowRect
.GetHeight() );
2194 static Rectangle
NWGetComboBoxButtonRect( int nScreen
,
2197 Rectangle aAreaRect
,
2199 const ImplControlValue
&,
2203 Rectangle aButtonRect
;
2209 NWEnsureGTKArrow( nScreen
);
2211 // Grab some button style attributes
2212 gtk_widget_style_get( gWidgetData
[nScreen
].gDropdownWidget
,
2213 "focus-line-width", &nFocusWidth
,
2214 "focus-padding", &nFocusPad
, (char *)NULL
);
2216 nArrowWidth
= MIN_ARROW_SIZE
+ (GTK_MISC(gWidgetData
[nScreen
].gArrowWidget
)->xpad
* 2);
2217 nButtonWidth
= nArrowWidth
+
2218 ((BTN_CHILD_SPACING
+ gWidgetData
[nScreen
].gDropdownWidget
->style
->xthickness
) * 2)
2219 + (2 * (nFocusWidth
+nFocusPad
));
2220 if( nPart
== PART_BUTTON_DOWN
)
2222 aButtonRect
.SetSize( Size( nButtonWidth
, aAreaRect
.GetHeight() ) );
2223 aButtonRect
.SetPos( Point( aAreaRect
.Left() + aAreaRect
.GetWidth() - nButtonWidth
,
2224 aAreaRect
.Top() ) );
2226 else if( nPart
== PART_SUB_EDIT
)
2228 NWEnsureGTKCombo( nScreen
);
2230 gint adjust_x
= GTK_CONTAINER(gWidgetData
[nScreen
].gComboWidget
)->border_width
+
2233 gint adjust_y
= adjust_x
+ gWidgetData
[nScreen
].gComboWidget
->style
->ythickness
;
2234 adjust_x
+= gWidgetData
[nScreen
].gComboWidget
->style
->xthickness
;
2235 aButtonRect
.SetSize( Size( aAreaRect
.GetWidth() - nButtonWidth
- 2 * adjust_x
,
2236 aAreaRect
.GetHeight() - 2 * adjust_y
) );
2237 Point aEditPos
= aAreaRect
.TopLeft();
2238 aEditPos
.X() += adjust_x
;
2239 aEditPos
.Y() += adjust_y
;
2240 aButtonRect
.SetPos( aEditPos
);
2243 return( aButtonRect
);
2246 //-------------------------------------
2250 BOOL
GtkSalGraphics::NWPaintGTKTabItem( ControlType nType
, ControlPart
,
2251 const Rectangle
& rControlRectangle
,
2253 ControlState nState
,
2254 const ImplControlValue
& aValue
,
2255 SalControlHandle
&, const OUString
& )
2258 Rectangle pixmapRect
;
2260 TabitemValue
* pTabitemValue
= (TabitemValue
*)(aValue
.getOptionalVal());
2261 GtkStateType stateType
;
2262 GtkShadowType shadowType
;
2263 if( ! gWidgetData
[ m_nScreen
].gCacheTabItems
)
2265 gWidgetData
[ m_nScreen
].gCacheTabItems
= new NWPixmapCache( m_nScreen
);
2266 gWidgetData
[ m_nScreen
].gCacheTabPages
= new NWPixmapCache( m_nScreen
);
2268 NWPixmapCache
& aCacheItems
= *gWidgetData
[ m_nScreen
].gCacheTabItems
;
2269 NWPixmapCache
& aCachePage
= *gWidgetData
[ m_nScreen
].gCacheTabPages
;
2271 if( !aCacheItems
.GetSize() )
2272 aCacheItems
.SetSize( 20 );
2273 if( !aCachePage
.GetSize() )
2274 aCachePage
.SetSize( 1 );
2276 if ( !pTabitemValue
&& (nType
==CTRL_TAB_ITEM
) )
2278 std::fprintf( stderr
, "NWPaintGTKTabItem() received a NULL TabitemValue. Cannot draw native tab\n" );
2282 NWEnsureGTKButton( m_nScreen
);
2283 NWEnsureGTKNotebook( m_nScreen
);
2284 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2286 // Find the overall bounding rect of the buttons's drawing area,
2287 // plus its actual draw rect excluding adornment
2288 pixmapRect
= rControlRectangle
;
2289 if ( nType
== CTRL_TAB_ITEM
)
2291 if ( !pTabitemValue
->isFirst() )
2293 // GTK+ tabs overlap on the right edge (the top tab obscures the
2294 // left edge of the tab right "below" it, so adjust the rectangle
2295 // to draw tabs slightly large so the overlap happens
2296 pixmapRect
.Move( -2, 0 );
2297 pixmapRect
.SetSize( Size( pixmapRect
.GetWidth() + 2, pixmapRect
.GetHeight() ) );
2299 if ( nState
& CTRL_STATE_SELECTED
)
2301 // In GTK+, the selected tab is 2px taller than all other tabs
2302 pixmapRect
.Move( 0, -2 );
2303 pixmapRect
.Bottom() += 2;
2304 tabRect
= pixmapRect
;
2305 // Only draw over 1 pixel of the tab pane that this tab is drawn on top of.
2306 tabRect
.Bottom() -= 1;
2309 tabRect
= pixmapRect
;
2311 // Allow the tab to draw a right border if needed
2312 tabRect
.Right() -= 1;
2314 // #129732# avoid degenerate cases which might lead to crashes
2315 if( tabRect
.GetWidth() <= 1 || tabRect
.GetHeight() <= 1 )
2319 if( nType
== CTRL_TAB_ITEM
)
2321 if( aCacheItems
.Find( nType
, nState
, pixmapRect
, &pixmap
) )
2322 return NWRenderPixmapToScreen( pixmap
, pixmapRect
);
2326 if( aCachePage
.Find( nType
, nState
, pixmapRect
, &pixmap
) )
2327 return NWRenderPixmapToScreen( pixmap
, pixmapRect
);
2331 // gtk_widget_set_state( gWidgetData[m_nScreen].gNotebookWidget, stateType );
2333 pixmap
= gdk_pixmap_new( NULL
, pixmapRect
.GetWidth(), pixmapRect
.GetHeight(),
2334 GetX11SalData()->GetDisplay()->GetVisual( m_nScreen
).GetDepth() );
2335 GdkRectangle paintRect
;
2336 paintRect
.x
= paintRect
.y
= 0;
2337 paintRect
.width
= pixmapRect
.GetWidth();
2338 paintRect
.height
= pixmapRect
.GetHeight();
2340 gtk_paint_flat_box( m_pWindow
->style
, pixmap
, GTK_STATE_NORMAL
,
2341 GTK_SHADOW_NONE
, &paintRect
, m_pWindow
, "base", 0, 0, -1, -1);
2343 NWSetWidgetState( gWidgetData
[m_nScreen
].gNotebookWidget
, nState
, stateType
);
2350 case CTRL_FIXEDBORDER
:
2352 gtk_paint_box_gap( gWidgetData
[m_nScreen
].gNotebookWidget
->style
, pixmap
, GTK_STATE_NORMAL
, GTK_SHADOW_OUT
, NULL
, gWidgetData
[m_nScreen
].gNotebookWidget
,
2353 (char *)"notebook", 0, 0, pixmapRect
.GetWidth(), pixmapRect
.GetHeight(), GTK_POS_TOP
, 0, 0 );
2357 stateType
= ( nState
& CTRL_STATE_SELECTED
) ? GTK_STATE_NORMAL
: GTK_STATE_ACTIVE
;
2359 gtk_paint_extension( gWidgetData
[m_nScreen
].gNotebookWidget
->style
, pixmap
, stateType
, GTK_SHADOW_OUT
, NULL
, gWidgetData
[m_nScreen
].gNotebookWidget
,
2360 (char *)"tab", (tabRect
.Left() - pixmapRect
.Left()), (tabRect
.Top() - pixmapRect
.Top()),
2361 tabRect
.GetWidth(), tabRect
.GetHeight(), GTK_POS_BOTTOM
);
2363 if ( nState
& CTRL_STATE_SELECTED
)
2365 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gNotebookWidget
->style
, pixmap
, stateType
, GTK_SHADOW_NONE
, NULL
, m_pWindow
,
2366 (char *)"base", 0, (pixmapRect
.GetHeight() - 1), pixmapRect
.GetWidth(), 1 );
2374 // Crux seems to think it can make the pane without a left edge
2375 if ( nType
== CTRL_FIXEDBORDER
)
2376 pixmapRect
.Move( 1, 0 );
2379 if( nType
== CTRL_TAB_ITEM
)
2380 aCacheItems
.Fill( nType
, nState
, pixmapRect
, pixmap
);
2382 aCachePage
.Fill( nType
, nState
, pixmapRect
, pixmap
);
2384 BOOL bSuccess
= NWRenderPixmapToScreen(pixmap
, pixmapRect
);
2385 g_object_unref( pixmap
);
2389 //-------------------------------------
2391 BOOL
GtkSalGraphics::NWPaintGTKListBox( GdkDrawable
* gdkDrawable
,
2392 ControlType nType
, ControlPart nPart
,
2393 const Rectangle
& rControlRectangle
,
2394 const clipList
& rClipList
,
2395 ControlState nState
,
2396 const ImplControlValue
& aValue
,
2397 SalControlHandle
& rControlHandle
, const OUString
& rCaption
)
2399 Rectangle pixmapRect
;
2400 Rectangle widgetRect
;
2401 Rectangle aIndicatorRect
;
2402 GtkStateType stateType
;
2403 GtkShadowType shadowType
;
2404 gint bInteriorFocus
;
2405 gint nFocusLineWidth
;
2408 GdkRectangle clipRect
;
2410 NWEnsureGTKButton( m_nScreen
);
2411 NWEnsureGTKOptionMenu( m_nScreen
);
2412 NWEnsureGTKScrolledWindow( m_nScreen
);
2413 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2415 // Find the overall bounding rect of the buttons's drawing area,
2416 // plus its actual draw rect excluding adornment
2417 pixmapRect
= rControlRectangle
;
2418 if ( nPart
== PART_WINDOW
)
2420 // Make the widget a _bit_ bigger
2421 pixmapRect
.SetPos( Point( pixmapRect
.Left() - 1,
2422 pixmapRect
.Top() - 1 ) );
2423 pixmapRect
.SetSize( Size( pixmapRect
.GetWidth() + 2,
2424 pixmapRect
.GetHeight() + 2 ) );
2427 widgetRect
= pixmapRect
;
2428 x
= pixmapRect
.Left();
2429 y
= pixmapRect
.Top();
2431 // set up references to correct drawable and cliprect
2432 NWSetWidgetState( gWidgetData
[m_nScreen
].gBtnWidget
, nState
, stateType
);
2433 NWSetWidgetState( gWidgetData
[m_nScreen
].gOptionMenuWidget
, nState
, stateType
);
2434 NWSetWidgetState( gWidgetData
[m_nScreen
].gScrolledWindowWidget
, nState
, stateType
);
2436 if ( nPart
!= PART_WINDOW
)
2438 gtk_widget_style_get( gWidgetData
[m_nScreen
].gOptionMenuWidget
,
2439 "interior_focus", &bInteriorFocus
,
2440 "focus_line_width", &nFocusLineWidth
,
2441 "focus_padding", &nFocusPadding
,
2445 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
2447 clipRect
.x
= it
->Left();
2448 clipRect
.y
= it
->Top();
2449 clipRect
.width
= it
->GetWidth();
2450 clipRect
.height
= it
->GetHeight();
2452 if ( nPart
!= PART_WINDOW
)
2454 // Listboxes must paint opaque since some themes have alpha-channel enabled bodies
2455 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gBtnWidget
->style
, gdkDrawable
, GTK_STATE_NORMAL
, GTK_SHADOW_NONE
,
2456 &clipRect
, m_pWindow
, "base", x
, y
,
2457 pixmapRect
.GetWidth(), pixmapRect
.GetHeight() );
2458 gtk_paint_box( gWidgetData
[m_nScreen
].gOptionMenuWidget
->style
, gdkDrawable
, stateType
, shadowType
, &clipRect
,
2459 gWidgetData
[m_nScreen
].gOptionMenuWidget
, "optionmenu",
2460 x
+(widgetRect
.Left() - pixmapRect
.Left()),
2461 y
+(widgetRect
.Top() - pixmapRect
.Top()),
2462 widgetRect
.GetWidth(), widgetRect
.GetHeight() );
2463 aIndicatorRect
= NWGetListBoxIndicatorRect( m_nScreen
, nType
, nPart
, widgetRect
, nState
,
2464 aValue
, rControlHandle
, rCaption
);
2465 gtk_paint_tab( gWidgetData
[m_nScreen
].gOptionMenuWidget
->style
, gdkDrawable
, stateType
, shadowType
, &clipRect
,
2466 gWidgetData
[m_nScreen
].gOptionMenuWidget
, "optionmenutab",
2467 x
+(aIndicatorRect
.Left() - pixmapRect
.Left()),
2468 y
+(aIndicatorRect
.Top() - pixmapRect
.Top()),
2469 aIndicatorRect
.GetWidth(), aIndicatorRect
.GetHeight() );
2473 shadowType
= GTK_SHADOW_IN
;
2475 gtk_paint_shadow( gWidgetData
[m_nScreen
].gScrolledWindowWidget
->style
, gdkDrawable
, GTK_STATE_NORMAL
, shadowType
,
2476 &clipRect
, gWidgetData
[m_nScreen
].gScrolledWindowWidget
, "scrolled_window",
2477 x
+(widgetRect
.Left() - pixmapRect
.Left()), y
+(widgetRect
.Top() - pixmapRect
.Top()),
2478 widgetRect
.GetWidth(), widgetRect
.GetHeight() );
2485 BOOL
GtkSalGraphics::NWPaintGTKToolbar(
2486 GdkDrawable
* gdkDrawable
,
2487 ControlType
, ControlPart nPart
,
2488 const Rectangle
& rControlRectangle
,
2489 const clipList
& rClipList
,
2490 ControlState nState
, const ImplControlValue
& aValue
,
2491 SalControlHandle
&, const OUString
& )
2493 GtkStateType stateType
;
2494 GtkShadowType shadowType
;
2496 gint g_x
=0, g_y
=0, g_w
=10, g_h
=10;
2497 bool bPaintButton
= true;
2498 GtkWidget
* pButtonWidget
= gWidgetData
[m_nScreen
].gToolbarButtonWidget
;
2499 const gchar
* pButtonDetail
= "button";
2500 GdkRectangle clipRect
;
2502 NWEnsureGTKToolbar( m_nScreen
);
2503 if( nPart
== PART_BUTTON
) // toolbar buttons cannot focus in gtk
2504 nState
&= ~CTRL_STATE_FOCUSED
;
2505 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2507 x
= rControlRectangle
.Left();
2508 y
= rControlRectangle
.Top();
2509 w
= rControlRectangle
.GetWidth();
2510 h
= rControlRectangle
.GetHeight();
2513 if( nPart
== PART_DRAW_BACKGROUND_HORZ
|| nPart
== PART_DRAW_BACKGROUND_VERT
)
2515 NWSetWidgetState( gWidgetData
[m_nScreen
].gToolbarWidget
, nState
, stateType
);
2517 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[m_nScreen
].gToolbarWidget
, GTK_SENSITIVE
);
2518 if ( nState
& CTRL_STATE_ENABLED
)
2519 GTK_WIDGET_SET_FLAGS( gWidgetData
[m_nScreen
].gToolbarWidget
, GTK_SENSITIVE
);
2521 if( nPart
== PART_DRAW_BACKGROUND_HORZ
)
2522 gtk_toolbar_set_orientation( GTK_TOOLBAR(gWidgetData
[m_nScreen
].gToolbarWidget
), GTK_ORIENTATION_HORIZONTAL
);
2524 gtk_toolbar_set_orientation( GTK_TOOLBAR(gWidgetData
[m_nScreen
].gToolbarWidget
), GTK_ORIENTATION_VERTICAL
);
2527 else if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
2529 NWSetWidgetState( gWidgetData
[m_nScreen
].gHandleBoxWidget
, nState
, stateType
);
2531 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[m_nScreen
].gHandleBoxWidget
, GTK_SENSITIVE
);
2532 if ( nState
& CTRL_STATE_ENABLED
)
2533 GTK_WIDGET_SET_FLAGS( gWidgetData
[m_nScreen
].gHandleBoxWidget
, GTK_SENSITIVE
);
2535 gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(gWidgetData
[m_nScreen
].gHandleBoxWidget
), shadowType
);
2537 // evaluate grip rect
2538 ToolbarValue
* pVal
= (ToolbarValue
*)aValue
.getOptionalVal();
2541 g_x
= pVal
->maGripRect
.Left();
2542 g_y
= pVal
->maGripRect
.Top();
2543 g_w
= pVal
->maGripRect
.GetWidth();
2544 g_h
= pVal
->maGripRect
.GetHeight();
2548 else if( nPart
== PART_BUTTON
)
2551 (GTK_BUTTON(pButtonWidget
)->relief
!= GTK_RELIEF_NONE
)
2552 || (nState
& CTRL_STATE_PRESSED
)
2553 || (nState
& CTRL_STATE_ROLLOVER
);
2554 if( aValue
.getTristateVal() == BUTTONVALUE_ON
)
2556 pButtonWidget
= gWidgetData
[m_nScreen
].gToolbarToggleWidget
;
2557 shadowType
= GTK_SHADOW_IN
;
2558 // special case stateType value for depressed toggle buttons
2559 // cf. gtk+/gtk/gtktogglebutton.c (gtk_toggle_button_update_state)
2560 if( ! (nState
& (CTRL_STATE_PRESSED
|CTRL_STATE_ROLLOVER
)) )
2561 stateType
= GTK_STATE_ACTIVE
;
2562 pButtonDetail
= "togglebutton";
2563 bPaintButton
= true;
2566 NWSetWidgetState( pButtonWidget
, nState
, stateType
);
2567 gtk_widget_ensure_style( pButtonWidget
);
2570 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
2572 clipRect
.x
= it
->Left();
2573 clipRect
.y
= it
->Top();
2574 clipRect
.width
= it
->GetWidth();
2575 clipRect
.height
= it
->GetHeight();
2578 if( nPart
== PART_DRAW_BACKGROUND_HORZ
|| nPart
== PART_DRAW_BACKGROUND_VERT
)
2580 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gToolbarWidget
->style
,
2582 (GtkStateType
)GTK_STATE_NORMAL
,
2585 gWidgetData
[m_nScreen
].gToolbarWidget
,
2588 gtk_paint_box( gWidgetData
[m_nScreen
].gToolbarWidget
->style
,
2593 gWidgetData
[m_nScreen
].gToolbarWidget
,
2598 else if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
2600 gtk_paint_handle( gWidgetData
[m_nScreen
].gHandleBoxWidget
->style
,
2605 gWidgetData
[m_nScreen
].gHandleBoxWidget
,
2608 nPart
== PART_THUMB_HORZ
?
2609 GTK_ORIENTATION_HORIZONTAL
:
2610 GTK_ORIENTATION_VERTICAL
2614 else if( nPart
== PART_BUTTON
)
2618 gtk_paint_box( pButtonWidget
->style
, gdkDrawable
,
2622 pButtonWidget
, pButtonDetail
, x
, y
, w
, h
);
2632 BOOL
GtkSalGraphics::NWPaintGTKMenubar(
2633 GdkDrawable
* gdkDrawable
,
2634 ControlType
, ControlPart nPart
,
2635 const Rectangle
& rControlRectangle
,
2636 const clipList
& rClipList
,
2637 ControlState nState
, const ImplControlValue
&,
2638 SalControlHandle
&, const OUString
& )
2640 GtkStateType stateType
;
2641 GtkShadowType shadowType
;
2642 GtkShadowType selected_shadow_type
= GTK_SHADOW_OUT
;
2644 GdkRectangle clipRect
;
2646 NWEnsureGTKMenubar( m_nScreen
);
2647 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2649 x
= rControlRectangle
.Left();
2650 y
= rControlRectangle
.Top();
2651 w
= rControlRectangle
.GetWidth();
2652 h
= rControlRectangle
.GetHeight();
2654 if( nPart
== PART_MENU_ITEM
)
2656 if( nState
& (CTRL_STATE_SELECTED
|CTRL_STATE_ROLLOVER
) )
2658 gtk_widget_style_get( gWidgetData
[m_nScreen
].gMenuItemMenubarWidget
,
2659 "selected_shadow_type", &selected_shadow_type
,
2664 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
2666 clipRect
.x
= it
->Left();
2667 clipRect
.y
= it
->Top();
2668 clipRect
.width
= it
->GetWidth();
2669 clipRect
.height
= it
->GetHeight();
2672 if( nPart
== PART_ENTIRE_CONTROL
)
2674 NWSetWidgetState( gWidgetData
[m_nScreen
].gMenubarWidget
, nState
, stateType
);
2676 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[m_nScreen
].gMenubarWidget
, GTK_SENSITIVE
);
2677 if ( nState
& CTRL_STATE_ENABLED
)
2678 GTK_WIDGET_SET_FLAGS( gWidgetData
[m_nScreen
].gMenubarWidget
, GTK_SENSITIVE
);
2680 // #118704# for translucent menubar styles paint background first
2681 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gMenubarWidget
->style
,
2686 GTK_WIDGET(m_pWindow
),
2689 gtk_paint_box( gWidgetData
[m_nScreen
].gMenubarWidget
->style
,
2694 gWidgetData
[m_nScreen
].gMenubarWidget
,
2698 else if( nPart
== PART_MENU_ITEM
)
2700 if( nState
& (CTRL_STATE_SELECTED
|CTRL_STATE_ROLLOVER
) )
2702 gtk_paint_box( gWidgetData
[m_nScreen
].gMenuItemMenubarWidget
->style
,
2705 selected_shadow_type
,
2707 gWidgetData
[m_nScreen
].gMenuItemMenubarWidget
,
2717 BOOL
GtkSalGraphics::NWPaintGTKPopupMenu(
2718 GdkDrawable
* gdkDrawable
,
2719 ControlType
, ControlPart nPart
,
2720 const Rectangle
& rControlRectangle
,
2721 const clipList
& rClipList
,
2722 ControlState nState
, const ImplControlValue
&,
2723 SalControlHandle
&, const OUString
& )
2725 // #i50745# gtk does not draw disabled menu entries (and crux theme
2726 // even crashes), draw them using vcl functionality.
2727 if( nPart
== PART_MENU_ITEM
&& ! (nState
& CTRL_STATE_ENABLED
) )
2730 GtkStateType stateType
;
2731 GtkShadowType shadowType
;
2732 GtkShadowType selected_shadow_type
= GTK_SHADOW_OUT
;
2734 GdkRectangle clipRect
;
2736 NWEnsureGTKMenu( m_nScreen
);
2737 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2739 x
= rControlRectangle
.Left();
2740 y
= rControlRectangle
.Top();
2741 w
= rControlRectangle
.GetWidth();
2742 h
= rControlRectangle
.GetHeight();
2744 if( nPart
== PART_MENU_ITEM
&&
2745 ( nState
& (CTRL_STATE_SELECTED
|CTRL_STATE_ROLLOVER
) ) )
2747 gtk_widget_style_get( gWidgetData
[m_nScreen
].gMenuItemMenuWidget
,
2748 "selected_shadow_type", &selected_shadow_type
,
2752 NWSetWidgetState( gWidgetData
[m_nScreen
].gMenuWidget
, nState
, stateType
);
2754 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[m_nScreen
].gMenuWidget
, GTK_SENSITIVE
);
2755 if ( nState
& CTRL_STATE_ENABLED
)
2756 GTK_WIDGET_SET_FLAGS( gWidgetData
[m_nScreen
].gMenuWidget
, GTK_SENSITIVE
);
2758 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
2760 clipRect
.x
= it
->Left();
2761 clipRect
.y
= it
->Top();
2762 clipRect
.width
= it
->GetWidth();
2763 clipRect
.height
= it
->GetHeight();
2765 if( nPart
== PART_ENTIRE_CONTROL
)
2767 // #118704# for translucent menubar styles paint background first
2768 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gMenuWidget
->style
,
2773 GTK_WIDGET(m_pWindow
),
2776 gtk_paint_box( gWidgetData
[m_nScreen
].gMenuWidget
->style
,
2781 gWidgetData
[m_nScreen
].gMenuWidget
,
2785 else if( nPart
== PART_MENU_ITEM
)
2787 if( nState
& (CTRL_STATE_SELECTED
|CTRL_STATE_ROLLOVER
) )
2789 if( nState
& CTRL_STATE_ENABLED
)
2790 gtk_paint_box( gWidgetData
[m_nScreen
].gMenuItemMenuWidget
->style
,
2793 selected_shadow_type
,
2795 gWidgetData
[m_nScreen
].gMenuItemMenuWidget
,
2800 else if( nPart
== PART_MENU_ITEM_CHECK_MARK
|| nPart
== PART_MENU_ITEM_RADIO_MARK
)
2802 GtkWidget
* pWidget
= (nPart
== PART_MENU_ITEM_CHECK_MARK
) ?
2803 gWidgetData
[m_nScreen
].gMenuItemCheckMenuWidget
:
2804 gWidgetData
[m_nScreen
].gMenuItemRadioMenuWidget
;
2806 GtkStateType nStateType
= GTK_STATE_NORMAL
;
2807 GtkShadowType nShadowType
;
2809 if ( nState
& CTRL_STATE_SELECTED
)
2810 nStateType
= GTK_STATE_PRELIGHT
;
2812 NWSetWidgetState( pWidget
, nState
, nStateType
);
2814 if ( nState
& CTRL_STATE_PRESSED
)
2815 nShadowType
= GTK_SHADOW_IN
;
2817 nShadowType
= GTK_SHADOW_OUT
;
2819 if ( nPart
== PART_MENU_ITEM_CHECK_MARK
)
2821 gtk_paint_check( pWidget
->style
,
2826 gWidgetData
[m_nScreen
].gMenuItemMenuWidget
,
2832 gtk_paint_option( pWidget
->style
,
2837 gWidgetData
[m_nScreen
].gMenuItemMenuWidget
,
2847 BOOL
GtkSalGraphics::NWPaintGTKTooltip(
2848 GdkDrawable
* gdkDrawable
,
2849 ControlType
, ControlPart
,
2850 const Rectangle
& rControlRectangle
,
2851 const clipList
& rClipList
,
2852 ControlState
, const ImplControlValue
&,
2853 SalControlHandle
&, const OUString
& )
2855 NWEnsureGTKTooltip( m_nScreen
);
2858 GdkRectangle clipRect
;
2860 x
= rControlRectangle
.Left();
2861 y
= rControlRectangle
.Top();
2862 w
= rControlRectangle
.GetWidth();
2863 h
= rControlRectangle
.GetHeight();
2865 for( clipList::const_iterator it
= rClipList
.begin(); it
!= rClipList
.end(); ++it
)
2867 clipRect
.x
= it
->Left();
2868 clipRect
.y
= it
->Top();
2869 clipRect
.width
= it
->GetWidth();
2870 clipRect
.height
= it
->GetHeight();
2872 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gTooltipPopup
->style
,
2877 gWidgetData
[m_nScreen
].gTooltipPopup
,
2885 BOOL
GtkSalGraphics::NWPaintGTKListNode(
2887 ControlType
, ControlPart
,
2888 const Rectangle
& rControlRectangle
,
2890 ControlState nState
, const ImplControlValue
& rValue
,
2891 SalControlHandle
&, const OUString
& )
2893 NWEnsureGTKTreeView( m_nScreen
);
2895 Rectangle
aRect( rControlRectangle
);
2899 aRect
.Bottom() += 2;
2901 w
= aRect
.GetWidth();
2902 h
= aRect
.GetHeight();
2904 GtkStateType stateType
;
2905 GtkShadowType shadowType
;
2906 NWConvertVCLStateToGTKState( nState
, &stateType
, &shadowType
);
2908 ButtonValue aButtonValue
= rValue
.getTristateVal();
2909 GtkExpanderStyle eStyle
= GTK_EXPANDER_EXPANDED
;
2911 switch( aButtonValue
)
2913 case BUTTONVALUE_ON
: eStyle
= GTK_EXPANDER_EXPANDED
;break;
2914 case BUTTONVALUE_OFF
: eStyle
= GTK_EXPANDER_COLLAPSED
; break;
2919 GdkPixmap
* pixmap
= NWGetPixmapFromScreen( aRect
);
2923 GdkDrawable
* const &pixDrawable
= GDK_DRAWABLE( pixmap
);
2924 gtk_paint_expander( gWidgetData
[m_nScreen
].gTreeView
->style
,
2928 gWidgetData
[m_nScreen
].gTreeView
,
2933 BOOL bRet
= NWRenderPixmapToScreen( pixmap
, aRect
);
2934 g_object_unref( pixmap
);
2939 BOOL
GtkSalGraphics::NWPaintGTKProgress(
2941 ControlType
, ControlPart
,
2942 const Rectangle
& rControlRectangle
,
2944 ControlState
, const ImplControlValue
& rValue
,
2945 SalControlHandle
&, const OUString
& )
2947 NWEnsureGTKProgressBar( m_nScreen
);
2950 w
= rControlRectangle
.GetWidth();
2951 h
= rControlRectangle
.GetHeight();
2953 long nProgressWidth
= rValue
.getNumericVal();
2955 GdkPixmap
* pixmap
= NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w
, h
) ) );
2959 GdkDrawable
* const &pixDrawable
= GDK_DRAWABLE( pixmap
);
2962 gtk_paint_flat_box( gWidgetData
[m_nScreen
].gProgressBar
->style
,
2967 gWidgetData
[m_nScreen
].gProgressBar
,
2970 if( nProgressWidth
> 0 )
2973 if( Application::GetSettings().GetLayoutRTL() )
2975 gtk_paint_box( gWidgetData
[m_nScreen
].gProgressBar
->style
,
2977 GTK_STATE_PRELIGHT
, GTK_SHADOW_OUT
,
2979 gWidgetData
[m_nScreen
].gProgressBar
,
2981 w
-nProgressWidth
, 0, nProgressWidth
, h
2986 gtk_paint_box( gWidgetData
[m_nScreen
].gProgressBar
->style
,
2988 GTK_STATE_PRELIGHT
, GTK_SHADOW_OUT
,
2990 gWidgetData
[m_nScreen
].gProgressBar
,
2992 0, 0, nProgressWidth
, h
2997 BOOL bRet
= NWRenderPixmapToScreen( pixmap
, rControlRectangle
);
2998 g_object_unref( pixmap
);
3005 static Rectangle
NWGetListBoxButtonRect( int nScreen
,
3008 Rectangle aAreaRect
,
3010 const ImplControlValue
&,
3014 Rectangle aPartRect
;
3015 GtkRequisition
*pIndicatorSize
= NULL
;
3016 GtkBorder
*pIndicatorSpacing
= NULL
;
3017 gint width
= 13; // GTK+ default
3018 gint right
= 5; // GTK+ default
3019 gint nButtonAreaWidth
= 0;
3020 gint xthickness
= 0;
3022 NWEnsureGTKOptionMenu( nScreen
);
3024 gtk_widget_style_get( gWidgetData
[nScreen
].gOptionMenuWidget
,
3025 "indicator_size", &pIndicatorSize
,
3026 "indicator_spacing",&pIndicatorSpacing
, (char *)NULL
);
3028 if ( pIndicatorSize
)
3029 width
= pIndicatorSize
->width
;
3031 if ( pIndicatorSpacing
)
3032 right
= pIndicatorSpacing
->right
;
3034 Size
aPartSize( 0, aAreaRect
.GetHeight() );
3035 Point
aPartPos ( 0, aAreaRect
.Top() );
3037 xthickness
= gWidgetData
[nScreen
].gOptionMenuWidget
->style
->xthickness
;
3038 nButtonAreaWidth
= width
+ right
+ (xthickness
* 2);
3041 case PART_BUTTON_DOWN
:
3042 aPartSize
.Width() = nButtonAreaWidth
;
3043 aPartPos
.X() = aAreaRect
.Left() + aAreaRect
.GetWidth() - aPartSize
.Width();
3047 aPartSize
.Width() = aAreaRect
.GetWidth() - nButtonAreaWidth
- xthickness
;
3048 aPartPos
.X() = aAreaRect
.Left() + xthickness
;
3052 aPartSize
.Width() = aAreaRect
.GetWidth();
3053 aPartPos
.X() = aAreaRect
.Left();
3056 aPartRect
= Rectangle( aPartPos
, aPartSize
);
3058 if ( pIndicatorSize
)
3059 gtk_requisition_free( pIndicatorSize
);
3060 if ( pIndicatorSpacing
)
3061 gtk_border_free( pIndicatorSpacing
);
3063 return( aPartRect
);
3068 static Rectangle
NWGetListBoxIndicatorRect( int nScreen
,
3071 Rectangle aAreaRect
,
3073 const ImplControlValue
&,
3077 Rectangle aIndicatorRect
;
3078 GtkRequisition
*pIndicatorSize
= NULL
;
3079 GtkBorder
*pIndicatorSpacing
= NULL
;
3080 gint width
= 13; // GTK+ default
3081 gint height
= 13; // GTK+ default
3082 gint right
= 5; // GTK+ default
3084 NWEnsureGTKOptionMenu( nScreen
);
3086 gtk_widget_style_get( gWidgetData
[nScreen
].gOptionMenuWidget
,
3087 "indicator_size", &pIndicatorSize
,
3088 "indicator_spacing",&pIndicatorSpacing
, (char *)NULL
);
3090 if ( pIndicatorSize
)
3092 width
= pIndicatorSize
->width
;
3093 height
= pIndicatorSize
->height
;
3096 if ( pIndicatorSpacing
)
3097 right
= pIndicatorSpacing
->right
;
3099 aIndicatorRect
.SetSize( Size( width
, height
) );
3100 aIndicatorRect
.SetPos( Point( aAreaRect
.Left() + aAreaRect
.GetWidth() - width
- right
- gWidgetData
[nScreen
].gOptionMenuWidget
->style
->xthickness
,
3101 aAreaRect
.Top() + ((aAreaRect
.GetHeight() - height
) / 2) ) );
3103 // If height is odd, move the indicator down 1 pixel
3104 if ( aIndicatorRect
.GetHeight() % 2 )
3105 aIndicatorRect
.Move( 0, 1 );
3107 if ( pIndicatorSize
)
3108 gtk_requisition_free( pIndicatorSize
);
3109 if ( pIndicatorSpacing
)
3110 gtk_border_free( pIndicatorSpacing
);
3112 return( aIndicatorRect
);
3115 static Rectangle
NWGetToolbarRect( int nScreen
,
3118 Rectangle aAreaRect
,
3120 const ImplControlValue
&,
3126 if( nPart
== PART_DRAW_BACKGROUND_HORZ
||
3127 nPart
== PART_DRAW_BACKGROUND_VERT
)
3129 else if( nPart
== PART_THUMB_HORZ
)
3130 aRet
= Rectangle( Point( 0, 0 ), Size( aAreaRect
.GetWidth(), 10 ) );
3131 else if( nPart
== PART_THUMB_VERT
)
3132 aRet
= Rectangle( Point( 0, 0 ), Size( 10, aAreaRect
.GetHeight() ) );
3133 else if( nPart
== PART_BUTTON
)
3137 NWEnsureGTKToolbar( nScreen
);
3140 2*gWidgetData
[nScreen
].gToolbarButtonWidget
->style
->xthickness
3141 + 1 // CHILD_SPACING constant, found in gtk_button.c
3142 + 3*gWidgetData
[nScreen
].gToolbarButtonWidget
->style
->xthickness
; // Murphy factor
3144 2*gWidgetData
[nScreen
].gToolbarButtonWidget
->style
->ythickness
3145 + 1 // CHILD_SPACING constant, found in gtk_button.c
3146 + 3*gWidgetData
[nScreen
].gToolbarButtonWidget
->style
->ythickness
; // Murphy factor
3148 gtk_widget_ensure_style( gWidgetData
[nScreen
].gToolbarButtonWidget
);
3149 if( aAreaRect
.GetWidth() < nMinWidth
)
3150 aRet
.Right() = aRet
.Left() + nMinWidth
;
3151 if( aAreaRect
.GetHeight() < nMinHeight
)
3152 aRet
.Bottom() = aRet
.Top() + nMinHeight
;
3158 /************************************************************************
3159 * helper for GtkSalFrame
3160 ************************************************************************/
3161 static inline Color
getColor( const GdkColor
& rCol
)
3163 return Color( rCol
.red
>> 8, rCol
.green
>> 8, rCol
.blue
>> 8 );
3166 #if OSL_DEBUG_LEVEL > 1
3168 void printColor( const char* name
, const GdkColor
& rCol
)
3170 std::fprintf( stderr
, " %s = 0x%2x 0x%2x 0x%2x\n",
3172 rCol
.red
>> 8, rCol
.green
>> 8, rCol
.blue
>> 8 );
3175 void printStyleColors( GtkStyle
* pStyle
)
3177 static const char* pStates
[] = { "NORMAL", "ACTIVE", "PRELIGHT", "SELECTED", "INSENSITIVE" };
3179 for( int i
= 0; i
< 5; i
++ )
3181 std::fprintf( stderr
, "state %s colors:\n", pStates
[i
] );
3182 printColor( "bg ", pStyle
->bg
[i
] );
3183 printColor( "fg ", pStyle
->fg
[i
] );
3184 printColor( "light ", pStyle
->light
[i
] );
3185 printColor( "dark ", pStyle
->dark
[i
] );
3186 printColor( "mid ", pStyle
->mid
[i
] );
3187 printColor( "text ", pStyle
->text
[i
] );
3188 printColor( "base ", pStyle
->base
[i
] );
3189 printColor( "text_aa", pStyle
->text_aa
[i
] );
3194 void GtkSalGraphics::updateSettings( AllSettings
& rSettings
)
3196 // get the widgets in place
3197 NWEnsureGTKMenu( m_nScreen
);
3198 NWEnsureGTKMenubar( m_nScreen
);
3199 NWEnsureGTKScrollbars( m_nScreen
);
3200 NWEnsureGTKEditBox( m_nScreen
);
3201 NWEnsureGTKTooltip( m_nScreen
);
3203 gtk_widget_ensure_style( m_pWindow
);
3204 GtkStyle
* pStyle
= gtk_widget_get_style( m_pWindow
);
3206 StyleSettings aStyleSet
= rSettings
.GetStyleSettings();
3208 #if OSL_DEBUG_LEVEL > 2
3209 printStyleColors( pStyle
);
3213 Color aTextColor
= getColor( pStyle
->text
[GTK_STATE_NORMAL
] );
3214 aStyleSet
.SetDialogTextColor( aTextColor
);
3215 aStyleSet
.SetButtonTextColor( aTextColor
);
3216 aStyleSet
.SetRadioCheckTextColor( aTextColor
);
3217 aStyleSet
.SetGroupTextColor( aTextColor
);
3218 aStyleSet
.SetLabelTextColor( aTextColor
);
3219 aStyleSet
.SetInfoTextColor( aTextColor
);
3220 aStyleSet
.SetWindowTextColor( aTextColor
);
3221 aStyleSet
.SetFieldTextColor( aTextColor
);
3224 GtkStyle
* pTooltipStyle
= gtk_widget_get_style( gWidgetData
[m_nScreen
].gTooltipPopup
);
3225 aTextColor
= getColor( pTooltipStyle
->fg
[ GTK_STATE_NORMAL
] );
3226 aStyleSet
.SetHelpTextColor( aTextColor
);
3228 // mouse over text colors
3229 aTextColor
= getColor( pStyle
->fg
[ GTK_STATE_PRELIGHT
] );
3230 aStyleSet
.SetButtonRolloverTextColor( aTextColor
);
3231 aStyleSet
.SetFieldRolloverTextColor( aTextColor
);
3233 // background colors
3234 Color aBackColor
= getColor( pStyle
->bg
[GTK_STATE_NORMAL
] );
3235 Color aBackFieldColor
= getColor( pStyle
->base
[ GTK_STATE_NORMAL
] );
3236 aStyleSet
.Set3DColors( aBackColor
);
3237 aStyleSet
.SetFaceColor( aBackColor
);
3238 aStyleSet
.SetDialogColor( aBackColor
);
3239 aStyleSet
.SetWorkspaceColor( aBackColor
);
3240 aStyleSet
.SetFieldColor( aBackFieldColor
);
3241 aStyleSet
.SetWindowColor( aBackFieldColor
);
3242 // aStyleSet.SetHelpColor( aBackColor );
3243 // ancient wisdom tells us a mystic algorithm how to set checked color
3244 if( aBackColor
== COL_LIGHTGRAY
)
3245 aStyleSet
.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) );
3248 Color aColor2
= aStyleSet
.GetLightColor();
3249 Color
aCheck( (BYTE
)(((USHORT
)aBackColor
.GetRed()+(USHORT
)aColor2
.GetRed())/2),
3250 (BYTE
)(((USHORT
)aBackColor
.GetGreen()+(USHORT
)aColor2
.GetGreen())/2),
3251 (BYTE
)(((USHORT
)aBackColor
.GetBlue()+(USHORT
)aColor2
.GetBlue())/2)
3253 aStyleSet
.SetCheckedColor( aCheck
);
3256 // highlighting colors
3257 Color aHighlightColor
= getColor( pStyle
->base
[GTK_STATE_SELECTED
] );
3258 Color aHighlightTextColor
= getColor( pStyle
->text
[GTK_STATE_SELECTED
] );
3259 aStyleSet
.SetHighlightColor( aHighlightColor
);
3260 aStyleSet
.SetHighlightTextColor( aHighlightTextColor
);
3263 GdkColor
*link_color
= NULL
;
3264 gtk_widget_style_get (m_pWindow
, "link-color", &link_color
, NULL
);
3267 aStyleSet
.SetLinkColor(getColor(*link_color
));
3268 gdk_color_free (link_color
);
3271 gtk_widget_style_get (m_pWindow
, "visited-link-color", &link_color
, NULL
);
3274 aStyleSet
.SetVisitedLinkColor(getColor(*link_color
));
3275 gdk_color_free (link_color
);
3279 aStyleSet
.SetActiveTabColor( aBackFieldColor
); // same as the window color.
3280 Color aSelectedBackColor
= getColor( pStyle
->bg
[GTK_STATE_ACTIVE
] );
3281 aStyleSet
.SetInactiveTabColor( aSelectedBackColor
);
3283 // menu disabled entries handling
3284 aStyleSet
.SetSkipDisabledInMenus( TRUE
);
3286 GtkStyle
* pMenuStyle
= gtk_widget_get_style( gWidgetData
[m_nScreen
].gMenuWidget
);
3287 GtkStyle
* pMenuItemStyle
= gtk_rc_get_style( gWidgetData
[m_nScreen
].gMenuItemMenuWidget
);
3288 GtkStyle
* pMenubarStyle
= gtk_rc_get_style( gWidgetData
[m_nScreen
].gMenubarWidget
);
3289 GtkStyle
* pMenuTextStyle
= gtk_rc_get_style( gtk_bin_get_child( GTK_BIN(gWidgetData
[m_nScreen
].gMenuItemMenuWidget
) ) );
3291 aBackColor
= getColor( pMenubarStyle
->bg
[GTK_STATE_NORMAL
] );
3292 aStyleSet
.SetMenuBarColor( aBackColor
);
3293 aBackColor
= getColor( pMenuStyle
->bg
[GTK_STATE_NORMAL
] );
3294 aTextColor
= getColor( pMenuTextStyle
->text
[GTK_STATE_NORMAL
] );
3295 aStyleSet
.SetMenuColor( aBackColor
);
3296 aStyleSet
.SetMenuTextColor( aTextColor
);
3298 aTextColor
= getColor( pMenubarStyle
->text
[GTK_STATE_NORMAL
] );
3299 aStyleSet
.SetMenuBarTextColor( aTextColor
);
3301 #if OSL_DEBUG_LEVEL > 1
3302 std::fprintf( stderr
, "==\n" );
3303 std::fprintf( stderr
, "MenuColor = %x (%d)\n", (int)aStyleSet
.GetMenuColor().GetColor(), aStyleSet
.GetMenuColor().GetLuminance() );
3304 std::fprintf( stderr
, "MenuTextColor = %x (%d)\n", (int)aStyleSet
.GetMenuTextColor().GetColor(), aStyleSet
.GetMenuTextColor().GetLuminance() );
3305 std::fprintf( stderr
, "MenuBarColor = %x (%d)\n", (int)aStyleSet
.GetMenuBarColor().GetColor(), aStyleSet
.GetMenuBarColor().GetLuminance() );
3306 std::fprintf( stderr
, "MenuBarTextColor = %x (%d)\n", (int)aStyleSet
.GetMenuBarTextColor().GetColor(), aStyleSet
.GetMenuBarTextColor().GetLuminance() );
3307 std::fprintf( stderr
, "LightColor = %x (%d)\n", (int)aStyleSet
.GetLightColor().GetColor(), aStyleSet
.GetLightColor().GetLuminance() );
3308 std::fprintf( stderr
, "ShadowColor = %x (%d)\n", (int)aStyleSet
.GetShadowColor().GetColor(), aStyleSet
.GetShadowColor().GetLuminance() );
3311 // Awful hack for menu separators in the Sonar and similar themes.
3312 // If the menu color is not too dark, and the menu text color is lighter,
3313 // make the "light" color lighter than the menu color and the "shadow"
3314 // color darker than it.
3315 if ( aStyleSet
.GetMenuColor().GetLuminance() >= 32 &&
3316 aStyleSet
.GetMenuColor().GetLuminance() <= aStyleSet
.GetMenuTextColor().GetLuminance() )
3318 Color temp
= aStyleSet
.GetMenuColor();
3319 temp
.IncreaseLuminance( 8 );
3320 aStyleSet
.SetLightColor( temp
);
3321 temp
= aStyleSet
.GetMenuColor();
3322 temp
.DecreaseLuminance( 16 );
3323 aStyleSet
.SetShadowColor( temp
);
3326 aHighlightColor
= getColor( pMenuItemStyle
->bg
[ GTK_STATE_SELECTED
] );
3327 aHighlightTextColor
= getColor( pMenuTextStyle
->fg
[ GTK_STATE_PRELIGHT
] );
3328 if( aHighlightColor
== aHighlightTextColor
)
3329 aHighlightTextColor
= (aHighlightColor
.GetLuminance() < 128) ? Color( COL_WHITE
) : Color( COL_BLACK
);
3330 aStyleSet
.SetMenuHighlightColor( aHighlightColor
);
3331 aStyleSet
.SetMenuHighlightTextColor( aHighlightTextColor
);
3334 OString aFamily
= pango_font_description_get_family( pStyle
->font_desc
);
3335 int nPangoHeight
= pango_font_description_get_size( pStyle
->font_desc
);
3336 PangoStyle eStyle
= pango_font_description_get_style( pStyle
->font_desc
);
3337 PangoWeight eWeight
= pango_font_description_get_weight( pStyle
->font_desc
);
3338 PangoStretch eStretch
= pango_font_description_get_stretch( pStyle
->font_desc
);
3340 psp::FastPrintFontInfo aInfo
;
3342 aInfo
.m_aFamilyName
= OStringToOUString( aFamily
, RTL_TEXTENCODING_UTF8
);
3346 case PANGO_STYLE_NORMAL
: aInfo
.m_eItalic
= psp::italic::Upright
;break;
3347 case PANGO_STYLE_ITALIC
: aInfo
.m_eItalic
= psp::italic::Italic
;break;
3348 case PANGO_STYLE_OBLIQUE
: aInfo
.m_eItalic
= psp::italic::Oblique
;break;
3351 if( eWeight
<= PANGO_WEIGHT_ULTRALIGHT
)
3352 aInfo
.m_eWeight
= psp::weight::UltraLight
;
3353 else if( eWeight
<= PANGO_WEIGHT_LIGHT
)
3354 aInfo
.m_eWeight
= psp::weight::Light
;
3355 else if( eWeight
<= PANGO_WEIGHT_NORMAL
)
3356 aInfo
.m_eWeight
= psp::weight::Normal
;
3357 else if( eWeight
<= PANGO_WEIGHT_BOLD
)
3358 aInfo
.m_eWeight
= psp::weight::Bold
;
3360 aInfo
.m_eWeight
= psp::weight::UltraBold
;
3364 case PANGO_STRETCH_ULTRA_CONDENSED
: aInfo
.m_eWidth
= psp::width::UltraCondensed
;break;
3365 case PANGO_STRETCH_EXTRA_CONDENSED
: aInfo
.m_eWidth
= psp::width::ExtraCondensed
;break;
3366 case PANGO_STRETCH_CONDENSED
: aInfo
.m_eWidth
= psp::width::Condensed
;break;
3367 case PANGO_STRETCH_SEMI_CONDENSED
: aInfo
.m_eWidth
= psp::width::SemiCondensed
;break;
3368 case PANGO_STRETCH_NORMAL
: aInfo
.m_eWidth
= psp::width::Normal
;break;
3369 case PANGO_STRETCH_SEMI_EXPANDED
: aInfo
.m_eWidth
= psp::width::SemiExpanded
;break;
3370 case PANGO_STRETCH_EXPANDED
: aInfo
.m_eWidth
= psp::width::Expanded
;break;
3371 case PANGO_STRETCH_EXTRA_EXPANDED
: aInfo
.m_eWidth
= psp::width::ExtraExpanded
;break;
3372 case PANGO_STRETCH_ULTRA_EXPANDED
: aInfo
.m_eWidth
= psp::width::UltraExpanded
;break;
3375 #if OSL_DEBUG_LEVEL > 1
3376 std::fprintf( stderr
, "font name BEFORE system match: \"%s\"\n", aFamily
.getStr() );
3379 // match font to e.g. resolve "Sans"
3380 psp::PrintFontManager::get().matchFont( aInfo
, rSettings
.GetUILocale() );
3382 #if OSL_DEBUG_LEVEL > 1
3383 std::fprintf( stderr
, "font match %s, name AFTER: \"%s\"\n",
3384 aInfo
.m_nID
!= 0 ? "succeeded" : "failed",
3385 OUStringToOString( aInfo
.m_aFamilyName
, RTL_TEXTENCODING_ISO_8859_1
).getStr() );
3388 sal_Int32 nDispDPIY
= GetDisplay()->GetResolution().B();
3389 int nPointHeight
= 0;
3390 static gboolean(*pAbso
)(const PangoFontDescription
*) =
3391 (gboolean(*)(const PangoFontDescription
*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin
, "pango_font_description_get_size_is_absolute" );
3393 if( pAbso
&& pAbso( pStyle
->font_desc
) )
3394 nPointHeight
= (nPangoHeight
* 72 + nDispDPIY
*PANGO_SCALE
/2) / (nDispDPIY
* PANGO_SCALE
);
3396 nPointHeight
= nPangoHeight
/PANGO_SCALE
;
3398 Font
aFont( aInfo
.m_aFamilyName
, Size( 0, nPointHeight
) );
3399 if( aInfo
.m_eWeight
!= psp::weight::Unknown
)
3400 aFont
.SetWeight( PspGraphics::ToFontWeight( aInfo
.m_eWeight
) );
3401 if( aInfo
.m_eWidth
!= psp::width::Unknown
)
3402 aFont
.SetWidthType( PspGraphics::ToFontWidth( aInfo
.m_eWidth
) );
3403 if( aInfo
.m_eItalic
!= psp::italic::Unknown
)
3404 aFont
.SetItalic( PspGraphics::ToFontItalic( aInfo
.m_eItalic
) );
3405 if( aInfo
.m_ePitch
!= psp::pitch::Unknown
)
3406 aFont
.SetPitch( PspGraphics::ToFontPitch( aInfo
.m_ePitch
) );
3408 aStyleSet
.SetAppFont( aFont
);
3409 aStyleSet
.SetHelpFont( aFont
);
3410 aStyleSet
.SetTitleFont( aFont
);
3411 aStyleSet
.SetFloatTitleFont( aFont
);
3412 aStyleSet
.SetMenuFont( aFont
);
3413 aStyleSet
.SetToolFont( aFont
);
3414 aStyleSet
.SetLabelFont( aFont
);
3415 aStyleSet
.SetInfoFont( aFont
);
3416 aStyleSet
.SetRadioCheckFont( aFont
);
3417 aStyleSet
.SetPushButtonFont( aFont
);
3418 aStyleSet
.SetFieldFont( aFont
);
3419 aStyleSet
.SetIconFont( aFont
);
3420 aStyleSet
.SetGroupFont( aFont
);
3422 // get cursor blink time
3423 GtkSettings
*pSettings
= gtk_widget_get_settings( gWidgetData
[m_nScreen
].gEditBoxWidget
);
3424 gboolean blink
= false;
3426 g_object_get( pSettings
, "gtk-cursor-blink", &blink
, (char *)NULL
);
3429 gint blink_time
= STYLE_CURSOR_NOBLINKTIME
;
3430 g_object_get( pSettings
, "gtk-cursor-blink-time", &blink_time
, (char *)NULL
);
3431 // set the blink_time if there is a setting and it is reasonable
3432 // else leave the default value
3433 if( blink_time
> 100 && blink_time
!= gint(STYLE_CURSOR_NOBLINKTIME
) )
3434 aStyleSet
.SetCursorBlinkTime( blink_time
/2 );
3437 aStyleSet
.SetCursorBlinkTime( STYLE_CURSOR_NOBLINKTIME
);
3439 gboolean showmenuicons
= true;
3440 pSettings
= gtk_widget_get_settings( gWidgetData
[m_nScreen
].gImageMenuItem
);
3441 g_object_get( pSettings
, "gtk-menu-images", &showmenuicons
, (char *)NULL
);
3442 aStyleSet
.SetUseImagesInMenus( showmenuicons
);
3444 // set scrollbar settings
3445 gint slider_width
= 14;
3446 gint trough_border
= 1;
3447 gint min_slider_length
= 21;
3449 // Grab some button style attributes
3450 gtk_widget_style_get( gWidgetData
[m_nScreen
].gScrollHorizWidget
,
3451 "slider-width", &slider_width
,
3452 "trough-border", &trough_border
,
3453 "min-slider-length", &min_slider_length
,
3455 gint magic
= trough_border
? 1 : 0;
3456 aStyleSet
.SetScrollBarSize( slider_width
+ 2*trough_border
);
3457 aStyleSet
.SetMinThumbSize( min_slider_length
- magic
);
3459 // preferred icon style
3460 gchar
* pIconThemeName
= NULL
;
3461 g_object_get( gtk_settings_get_default(), "gtk-icon-theme-name", &pIconThemeName
, (char *)NULL
);
3462 aStyleSet
.SetPreferredSymbolsStyleName( OUString::createFromAscii(pIconThemeName
) );
3463 g_free (pIconThemeName
);
3465 // FIXME: need some way of fetching toolbar icon size.
3466 // aStyleSet.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_SMALL );
3468 /* #i35482# do not override HC mode per force
3469 // #i59364# high contrast mode
3470 bool bHC = ( aStyleSet.GetFaceColor().IsDark() ||
3471 aStyleSet.GetWindowColor().IsDark() );
3472 aStyleSet.SetHighContrastMode( bHC );
3475 // finally update the collected settings
3476 rSettings
.SetStyleSettings( aStyleSet
);
3478 #if OSL_DEBUG_LEVEL > 1
3480 GtkSettings
* pGtkSettings
= gtk_settings_get_default();
3482 memset( &aValue
, 0, sizeof(GValue
) );
3483 g_value_init( &aValue
, G_TYPE_STRING
);
3484 g_object_get_property( G_OBJECT(pGtkSettings
), "gtk-theme-name", &aValue
);
3485 const gchar
* pThemeName
= g_value_get_string( &aValue
);
3486 std::fprintf( stderr
, "Theme name is \"%s\"\n", pThemeName
);
3487 g_value_unset( &aValue
);
3490 GtkSettings
* pGtkSettings
= gtk_settings_get_default();
3492 memset( &aValue
, 0, sizeof(GValue
) );
3493 g_value_init( &aValue
, G_TYPE_STRING
);
3494 g_object_get_property( G_OBJECT(pGtkSettings
), "gtk-theme-name", &aValue
);
3495 const gchar
* pThemeName
= g_value_get_string( &aValue
);
3497 // default behaviour
3498 bNeedPixmapPaint
= bGlobalNeedPixmapPaint
;
3499 bToolbarGripWorkaround
= false;
3500 bNeedButtonStyleAsEditBackgroundWorkaround
= false;
3502 // setup some workarounds for "blueprint" theme
3503 if( pThemeName
&& strncasecmp( pThemeName
, "blueprint", 9 ) == 0 )
3505 bNeedButtonStyleAsEditBackgroundWorkaround
= true;
3506 if( GetX11SalData()->GetDisplay()->GetServerVendor() == vendor_sun
)
3508 // #i52570#, #i61532# workaround a weird paint issue;
3509 // on a Sunray Xserver sometimes painting buttons and edits
3510 // won't work when using the blueprint theme
3511 // not reproducible with simpler programs or other themes
3512 if( pThemeName
&& strncasecmp( pThemeName
, "blueprint", 9 ) == 0 )
3514 bNeedPixmapPaint
= true;
3515 bToolbarGripWorkaround
= true;
3520 g_value_unset( &aValue
);
3524 /************************************************************************
3525 * Create a GdkPixmap filled with the contents of an area of an Xlib window
3526 ************************************************************************/
3528 GdkPixmap
* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect
)
3530 // Create a new pixmap to hold the composite of the window background and the control
3531 GdkPixmap
* pPixmap
= gdk_pixmap_new( GDK_DRAWABLE(GetGdkWindow()), srcRect
.GetWidth(), srcRect
.GetHeight(), -1 );
3532 GdkGC
* pPixmapGC
= gdk_gc_new( pPixmap
);
3534 if( !pPixmap
|| !pPixmapGC
)
3537 g_object_unref( pPixmap
);
3539 g_object_unref( pPixmapGC
);
3540 std::fprintf( stderr
, "salnativewidgets-gtk.cxx: could not get valid pixmap from screen\n" );
3544 // Copy the background of the screen into a composite pixmap
3545 CopyScreenArea( GetXDisplay(),
3546 GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
3547 gdk_x11_drawable_get_xid(pPixmap
),
3548 gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap
) ) ),
3549 gdk_drawable_get_depth( GDK_DRAWABLE( pPixmap
) ),
3550 gdk_x11_gc_get_xgc(pPixmapGC
),
3551 srcRect
.Left(), srcRect
.Top(), srcRect
.GetWidth(), srcRect
.GetHeight(), 0, 0 );
3553 g_object_unref( pPixmapGC
);
3560 /************************************************************************
3561 * Copy an alpha pixmap to screen using a gc with clipping
3562 ************************************************************************/
3564 BOOL
GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap
* pPixmap
, Rectangle dstRect
)
3566 // The GC can't be null, otherwise we'd have no clip region
3567 if( SelectFont() == NULL
)
3569 std::fprintf(stderr
, "salnativewidgets.cxx: no valid GC\n" );
3576 // Copy the background of the screen into a composite pixmap
3577 CopyScreenArea( GetXDisplay(),
3578 GDK_DRAWABLE_XID(pPixmap
),
3579 gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap
) ) ),
3580 gdk_drawable_get_depth( GDK_DRAWABLE(pPixmap
) ),
3581 GetDrawable(), m_nScreen
, GetVisual().GetDepth(),
3583 0, 0, dstRect
.GetWidth(), dstRect
.GetHeight(), dstRect
.Left(), dstRect
.Top() );
3589 /************************************************************************
3591 ************************************************************************/
3592 static void NWConvertVCLStateToGTKState( ControlState nVCLState
,
3593 GtkStateType
* nGTKState
, GtkShadowType
* nGTKShadow
)
3595 *nGTKShadow
= GTK_SHADOW_OUT
;
3596 *nGTKState
= GTK_STATE_INSENSITIVE
;
3598 if ( nVCLState
& CTRL_STATE_ENABLED
)
3600 if ( nVCLState
& CTRL_STATE_PRESSED
)
3602 *nGTKState
= GTK_STATE_ACTIVE
;
3603 *nGTKShadow
= GTK_SHADOW_IN
;
3605 else if ( nVCLState
& CTRL_STATE_ROLLOVER
)
3607 *nGTKState
= GTK_STATE_PRELIGHT
;
3608 *nGTKShadow
= GTK_SHADOW_OUT
;
3612 *nGTKState
= GTK_STATE_NORMAL
;
3613 *nGTKShadow
= GTK_SHADOW_OUT
;
3618 /************************************************************************
3620 ************************************************************************/
3621 static void NWSetWidgetState( GtkWidget
* widget
, ControlState nState
, GtkStateType nGtkState
)
3623 // Set to default state, then build up from there
3624 GTK_WIDGET_UNSET_FLAGS( widget
, GTK_HAS_DEFAULT
);
3625 GTK_WIDGET_UNSET_FLAGS( widget
, GTK_HAS_FOCUS
);
3626 GTK_WIDGET_UNSET_FLAGS( widget
, GTK_SENSITIVE
);
3627 GTK_WIDGET_SET_FLAGS( widget
, gWidgetDefaultFlags
[(long)widget
] );
3629 if ( nState
& CTRL_STATE_DEFAULT
)
3630 GTK_WIDGET_SET_FLAGS( widget
, GTK_HAS_DEFAULT
);
3631 if ( !GTK_IS_TOGGLE_BUTTON(widget
) && (nState
& CTRL_STATE_FOCUSED
) )
3632 GTK_WIDGET_SET_FLAGS( widget
, GTK_HAS_FOCUS
);
3633 if ( nState
& CTRL_STATE_ENABLED
)
3634 GTK_WIDGET_SET_FLAGS( widget
, GTK_SENSITIVE
);
3635 gtk_widget_set_state( widget
, nGtkState
);
3638 /************************************************************************
3639 * Widget ensure functions - make sure cached objects are valid
3640 ************************************************************************/
3642 //-------------------------------------
3644 static void NWAddWidgetToCacheWindow( GtkWidget
* widget
, int nScreen
)
3646 NWFWidgetData
& rData
= gWidgetData
[nScreen
];
3647 if ( !rData
.gCacheWindow
|| !rData
.gDumbContainer
)
3649 if ( !rData
.gCacheWindow
)
3651 rData
.gCacheWindow
= gtk_window_new( GTK_WINDOW_TOPLEVEL
);
3652 GdkScreen
* pScreen
= gdk_display_get_screen( gdk_display_get_default(), nScreen
);
3654 gtk_window_set_screen( GTK_WINDOW(rData
.gCacheWindow
), pScreen
);
3656 if ( !rData
.gDumbContainer
)
3657 rData
.gDumbContainer
= gtk_fixed_new();
3658 gtk_container_add( GTK_CONTAINER(rData
.gCacheWindow
), rData
.gDumbContainer
);
3659 gtk_widget_realize( rData
.gDumbContainer
);
3660 gtk_widget_realize( rData
.gCacheWindow
);
3663 gtk_container_add( GTK_CONTAINER(rData
.gDumbContainer
), widget
);
3664 gtk_widget_realize( widget
);
3665 gtk_widget_ensure_style( widget
);
3667 // Store widget's default flags
3668 gWidgetDefaultFlags
[ (long)widget
] = GTK_WIDGET_FLAGS( widget
);
3671 //-------------------------------------
3673 static void NWEnsureGTKButton( int nScreen
)
3675 if ( !gWidgetData
[nScreen
].gBtnWidget
)
3677 gWidgetData
[nScreen
].gBtnWidget
= gtk_button_new_with_label( "" );
3678 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gBtnWidget
, nScreen
);
3682 //-------------------------------------
3684 static void NWEnsureGTKRadio( int nScreen
)
3686 if ( !gWidgetData
[nScreen
].gRadioWidget
|| !gWidgetData
[nScreen
].gRadioWidgetSibling
)
3688 gWidgetData
[nScreen
].gRadioWidget
= gtk_radio_button_new( NULL
);
3689 gWidgetData
[nScreen
].gRadioWidgetSibling
= gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON(gWidgetData
[nScreen
].gRadioWidget
) );
3690 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gRadioWidget
, nScreen
);
3691 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gRadioWidgetSibling
, nScreen
);
3695 //-------------------------------------
3697 static void NWEnsureGTKCheck( int nScreen
)
3699 if ( !gWidgetData
[nScreen
].gCheckWidget
)
3701 gWidgetData
[nScreen
].gCheckWidget
= gtk_check_button_new();
3702 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gCheckWidget
, nScreen
);
3706 //-------------------------------------
3708 static void NWEnsureGTKScrollbars( int nScreen
)
3710 if ( !gWidgetData
[nScreen
].gScrollHorizWidget
)
3712 gWidgetData
[nScreen
].gScrollHorizWidget
= gtk_hscrollbar_new( NULL
);
3713 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gScrollHorizWidget
, nScreen
);
3716 if ( !gWidgetData
[nScreen
].gScrollVertWidget
)
3718 gWidgetData
[nScreen
].gScrollVertWidget
= gtk_vscrollbar_new( NULL
);
3719 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gScrollVertWidget
, nScreen
);
3723 //-------------------------------------
3725 static void NWEnsureGTKArrow( int nScreen
)
3727 if ( !gWidgetData
[nScreen
].gArrowWidget
|| !gWidgetData
[nScreen
].gDropdownWidget
)
3729 gWidgetData
[nScreen
].gDropdownWidget
= gtk_toggle_button_new();
3730 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gDropdownWidget
, nScreen
);
3731 gWidgetData
[nScreen
].gArrowWidget
= gtk_arrow_new( GTK_ARROW_DOWN
, GTK_SHADOW_OUT
);
3732 gtk_container_add( GTK_CONTAINER(gWidgetData
[nScreen
].gDropdownWidget
), gWidgetData
[nScreen
].gArrowWidget
);
3733 gtk_widget_set_rc_style( gWidgetData
[nScreen
].gArrowWidget
);
3734 gtk_widget_realize( gWidgetData
[nScreen
].gArrowWidget
);
3738 //-------------------------------------
3740 static void NWEnsureGTKEditBox( int nScreen
)
3742 if ( !gWidgetData
[nScreen
].gEditBoxWidget
)
3744 gWidgetData
[nScreen
].gEditBoxWidget
= gtk_entry_new();
3745 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gEditBoxWidget
, nScreen
);
3749 //-------------------------------------
3751 static void NWEnsureGTKSpinButton( int nScreen
)
3753 if ( !gWidgetData
[nScreen
].gSpinButtonWidget
)
3755 GtkAdjustment
*adj
= GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 1, 1, 1, 0) );
3756 gWidgetData
[nScreen
].gSpinButtonWidget
= gtk_spin_button_new( adj
, 1, 2 );
3758 //Setting non-editable means it doesn't blink, so there's no timeouts
3759 //running around to nobble us
3760 gtk_editable_set_editable(GTK_EDITABLE(gWidgetData
[nScreen
].gSpinButtonWidget
), false);
3762 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gSpinButtonWidget
, nScreen
);
3766 //-------------------------------------
3768 static void NWEnsureGTKNotebook( int nScreen
)
3770 if ( !gWidgetData
[nScreen
].gNotebookWidget
)
3772 gWidgetData
[nScreen
].gNotebookWidget
= gtk_notebook_new();
3773 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gNotebookWidget
, nScreen
);
3777 //-------------------------------------
3779 static void NWEnsureGTKOptionMenu( int nScreen
)
3781 if ( !gWidgetData
[nScreen
].gOptionMenuWidget
)
3783 gWidgetData
[nScreen
].gOptionMenuWidget
= gtk_option_menu_new();
3784 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gOptionMenuWidget
, nScreen
);
3788 //-------------------------------------
3790 static void NWEnsureGTKCombo( int nScreen
)
3792 if ( !gWidgetData
[nScreen
].gComboWidget
)
3794 gWidgetData
[nScreen
].gComboWidget
= gtk_combo_new();
3796 // #i59129# Setting non-editable means it doesn't blink, so
3797 // there are no timeouts running around to nobble us
3798 gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(gWidgetData
[nScreen
].gComboWidget
)->entry
), false);
3800 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gComboWidget
, nScreen
);
3801 // Must realize the ComboBox's children, since GTK
3802 // does not do this for us in GtkCombo::gtk_widget_realize()
3803 gtk_widget_realize( GTK_COMBO(gWidgetData
[nScreen
].gComboWidget
)->button
);
3804 gtk_widget_realize( GTK_COMBO(gWidgetData
[nScreen
].gComboWidget
)->entry
);
3808 //-------------------------------------
3810 static void NWEnsureGTKScrolledWindow( int nScreen
)
3812 if ( !gWidgetData
[nScreen
].gScrolledWindowWidget
)
3814 GtkAdjustment
*hadj
= GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
3815 GtkAdjustment
*vadj
= GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
3817 gWidgetData
[nScreen
].gScrolledWindowWidget
= gtk_scrolled_window_new( hadj
, vadj
);
3818 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gScrolledWindowWidget
, nScreen
);
3822 //-------------------------------------
3824 static void NWEnsureGTKToolbar( int nScreen
)
3826 if( !gWidgetData
[nScreen
].gToolbarWidget
)
3828 gWidgetData
[nScreen
].gToolbarWidget
= gtk_toolbar_new();
3829 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gToolbarWidget
, nScreen
);
3830 gWidgetData
[nScreen
].gToolbarButtonWidget
= gtk_button_new();
3831 gWidgetData
[nScreen
].gToolbarToggleWidget
= gtk_toggle_button_new();
3833 GtkReliefStyle aRelief
= GTK_RELIEF_NORMAL
;
3834 gtk_widget_ensure_style( gWidgetData
[nScreen
].gToolbarWidget
);
3835 gtk_widget_style_get( gWidgetData
[nScreen
].gToolbarWidget
,
3836 "button_relief", &aRelief
,
3839 gtk_button_set_relief( GTK_BUTTON(gWidgetData
[nScreen
].gToolbarButtonWidget
), aRelief
);
3840 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[nScreen
].gToolbarButtonWidget
, GTK_CAN_FOCUS
);
3841 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[nScreen
].gToolbarButtonWidget
, GTK_CAN_DEFAULT
);
3842 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gToolbarButtonWidget
, nScreen
);
3844 gtk_button_set_relief( GTK_BUTTON(gWidgetData
[nScreen
].gToolbarToggleWidget
), aRelief
);
3845 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[nScreen
].gToolbarToggleWidget
, GTK_CAN_FOCUS
);
3846 GTK_WIDGET_UNSET_FLAGS( gWidgetData
[nScreen
].gToolbarToggleWidget
, GTK_CAN_DEFAULT
);
3847 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gToolbarToggleWidget
, nScreen
);
3849 if( ! gWidgetData
[nScreen
].gHandleBoxWidget
)
3851 gWidgetData
[nScreen
].gHandleBoxWidget
= gtk_handle_box_new();
3852 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gHandleBoxWidget
, nScreen
);
3856 //-------------------------------------
3858 static void NWEnsureGTKMenubar( int nScreen
)
3860 if( !gWidgetData
[nScreen
].gMenubarWidget
)
3862 gWidgetData
[nScreen
].gMenubarWidget
= gtk_menu_bar_new();
3863 gWidgetData
[nScreen
].gMenuItemMenubarWidget
= gtk_menu_item_new_with_label( "b" );
3864 gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData
[nScreen
].gMenubarWidget
), gWidgetData
[nScreen
].gMenuItemMenubarWidget
);
3865 gtk_widget_show( gWidgetData
[nScreen
].gMenuItemMenubarWidget
);
3866 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gMenubarWidget
, nScreen
);
3867 gtk_widget_show( gWidgetData
[nScreen
].gMenubarWidget
);
3869 // do what NWAddWidgetToCacheWindow does except adding to def container
3870 gtk_widget_realize( gWidgetData
[nScreen
].gMenuItemMenubarWidget
);
3871 gtk_widget_ensure_style( gWidgetData
[nScreen
].gMenuItemMenubarWidget
);
3873 gWidgetDefaultFlags
[ (long)gWidgetData
[nScreen
].gMenuItemMenubarWidget
] = GTK_WIDGET_FLAGS( gWidgetData
[nScreen
].gMenuItemMenubarWidget
);
3877 static void NWEnsureGTKMenu( int nScreen
)
3879 if( !gWidgetData
[nScreen
].gMenuWidget
)
3881 gWidgetData
[nScreen
].gMenuWidget
= gtk_menu_new();
3882 gWidgetData
[nScreen
].gMenuItemMenuWidget
= gtk_menu_item_new_with_label( "b" );
3883 gWidgetData
[nScreen
].gMenuItemCheckMenuWidget
= gtk_check_menu_item_new_with_label( "b" );
3884 gWidgetData
[nScreen
].gMenuItemRadioMenuWidget
= gtk_radio_menu_item_new_with_label( NULL
, "b" );
3885 gWidgetData
[nScreen
].gImageMenuItem
= gtk_image_menu_item_new();
3887 gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData
[nScreen
].gMenuWidget
), gWidgetData
[nScreen
].gMenuItemMenuWidget
);
3888 gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData
[nScreen
].gMenuWidget
), gWidgetData
[nScreen
].gMenuItemCheckMenuWidget
);
3889 gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData
[nScreen
].gMenuWidget
), gWidgetData
[nScreen
].gMenuItemRadioMenuWidget
);
3890 gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData
[nScreen
].gMenuWidget
), gWidgetData
[nScreen
].gImageMenuItem
);
3892 // do what NWAddWidgetToCacheWindow does except adding to def container
3893 gtk_widget_realize( gWidgetData
[nScreen
].gMenuWidget
);
3894 gtk_widget_ensure_style( gWidgetData
[nScreen
].gMenuWidget
);
3896 gtk_widget_realize( gWidgetData
[nScreen
].gMenuItemMenuWidget
);
3897 gtk_widget_ensure_style( gWidgetData
[nScreen
].gMenuItemMenuWidget
);
3899 gtk_widget_realize( gWidgetData
[nScreen
].gMenuItemCheckMenuWidget
);
3900 gtk_widget_ensure_style( gWidgetData
[nScreen
].gMenuItemCheckMenuWidget
);
3902 gtk_widget_realize( gWidgetData
[nScreen
].gMenuItemRadioMenuWidget
);
3903 gtk_widget_ensure_style( gWidgetData
[nScreen
].gMenuItemRadioMenuWidget
);
3905 gtk_widget_realize( gWidgetData
[nScreen
].gImageMenuItem
);
3906 gtk_widget_ensure_style( gWidgetData
[nScreen
].gImageMenuItem
);
3908 gWidgetDefaultFlags
[ (long)gWidgetData
[nScreen
].gMenuWidget
] = GTK_WIDGET_FLAGS( gWidgetData
[nScreen
].gMenuWidget
);
3909 gWidgetDefaultFlags
[ (long)gWidgetData
[nScreen
].gMenuItemMenuWidget
] = GTK_WIDGET_FLAGS( gWidgetData
[nScreen
].gMenuItemMenuWidget
);
3910 gWidgetDefaultFlags
[ (long)gWidgetData
[nScreen
].gMenuItemCheckMenuWidget
] = GTK_WIDGET_FLAGS( gWidgetData
[nScreen
].gMenuItemCheckMenuWidget
);
3911 gWidgetDefaultFlags
[ (long)gWidgetData
[nScreen
].gMenuItemRadioMenuWidget
] = GTK_WIDGET_FLAGS( gWidgetData
[nScreen
].gMenuItemRadioMenuWidget
);
3912 gWidgetDefaultFlags
[ (long)gWidgetData
[nScreen
].gImageMenuItem
] = GTK_WIDGET_FLAGS( gWidgetData
[nScreen
].gImageMenuItem
);
3916 static void NWEnsureGTKTooltip( int nScreen
)
3918 if( !gWidgetData
[nScreen
].gTooltipPopup
)
3920 gWidgetData
[nScreen
].gTooltipPopup
= gtk_window_new (GTK_WINDOW_POPUP
);
3921 GdkScreen
* pScreen
= gdk_display_get_screen( gdk_display_get_default(), nScreen
);
3923 gtk_window_set_screen( GTK_WINDOW(gWidgetData
[nScreen
].gTooltipPopup
), pScreen
);
3924 gtk_widget_set_name( gWidgetData
[nScreen
].gTooltipPopup
, "gtk-tooltips");
3925 gtk_widget_realize( gWidgetData
[nScreen
].gTooltipPopup
);
3926 gtk_widget_ensure_style( gWidgetData
[nScreen
].gTooltipPopup
);
3930 static void NWEnsureGTKProgressBar( int nScreen
)
3932 if( !gWidgetData
[nScreen
].gProgressBar
)
3934 gWidgetData
[nScreen
].gProgressBar
= gtk_progress_bar_new ();
3935 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gProgressBar
, nScreen
);
3939 static void NWEnsureGTKTreeView( int nScreen
)
3941 if( !gWidgetData
[nScreen
].gTreeView
)
3943 gWidgetData
[nScreen
].gTreeView
= gtk_tree_view_new ();
3944 NWAddWidgetToCacheWindow( gWidgetData
[nScreen
].gTreeView
, nScreen
);