1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 // http://msdn.microsoft.com/en-us/library/windows/desktop/hh270423%28v=vs.85%29.aspx
22 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb773178%28v=vs.85%29.aspx
24 // Useful tool to explore the themes & their rendering:
25 // http://privat.rejbrand.se/UxExplore.exe
26 // (found at http://stackoverflow.com/questions/4009701/windows-visual-themes-gallery-of-parts-and-states/4009712#4009712)
29 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb773218%28v=vs.85%29.aspx
31 // Drawing in non-client area (general DWM-related info):
32 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb688195%28v=vs.85%29.aspx
34 #include "rtl/ustring.h"
36 #include "osl/module.h"
38 #include "vcl/svapp.hxx"
40 #include "win/svsys.h"
41 #include "win/salgdi.h"
42 #include "win/saldata.hxx"
53 typedef map
< wstring
, HTHEME
> ThemeMap
;
54 static ThemeMap aThemeMap
;
57 /****************************************************
58 wrap visual styles API to avoid linking against it
59 it is not available on all Windows platforms
60 *****************************************************/
65 typedef HTHEME (WINAPI
* OpenThemeData_Proc_T
) ( HWND hwnd
, LPCWSTR pszClassList
);
66 typedef HRESULT (WINAPI
* CloseThemeData_Proc_T
) ( HTHEME hTheme
);
67 typedef HRESULT (WINAPI
* GetThemeBackgroundContentRect_Proc_T
) ( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pBoundingRect
, RECT
*pContentRect
);
68 typedef HRESULT (WINAPI
* DrawThemeBackground_Proc_T
) ( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pRect
, const RECT
*pClipRect
);
69 typedef HRESULT (WINAPI
* DrawThemeText_Proc_T
) ( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, LPCWSTR pszText
, int iCharCount
, DWORD dwTextFlags
, DWORD dwTextFlags2
, const RECT
*pRect
);
70 typedef HRESULT (WINAPI
* GetThemePartSize_Proc_T
) ( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, RECT
*prc
, THEMESIZE eSize
, SIZE
*psz
);
71 typedef BOOL (WINAPI
* IsThemeActive_Proc_T
) ( void );
73 OpenThemeData_Proc_T lpfnOpenThemeData
;
74 CloseThemeData_Proc_T lpfnCloseThemeData
;
75 GetThemeBackgroundContentRect_Proc_T lpfnGetThemeBackgroundContentRect
;
76 DrawThemeBackground_Proc_T lpfnDrawThemeBackground
;
77 DrawThemeText_Proc_T lpfnDrawThemeText
;
78 GetThemePartSize_Proc_T lpfnGetThemePartSize
;
79 IsThemeActive_Proc_T lpfnIsThemeActive
;
86 sal_Bool
IsAvailable() { return (mhModule
!= NULL
); }
88 HTHEME
OpenThemeData( HWND hwnd
, LPCWSTR pszClassList
);
89 HRESULT
CloseThemeData( HTHEME hTheme
);
90 HRESULT
GetThemeBackgroundContentRect( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pBoundingRect
, RECT
*pContentRect
);
91 HRESULT
DrawThemeBackground( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pRect
, const RECT
*pClipRect
);
92 HRESULT
DrawThemeText( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, LPCWSTR pszText
, int iCharCount
, DWORD dwTextFlags
, DWORD dwTextFlags2
, const RECT
*pRect
);
93 HRESULT
GetThemePartSize( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, RECT
*prc
, THEMESIZE eSize
, SIZE
*psz
);
94 BOOL
IsThemeActive( void );
97 static VisualStylesAPI vsAPI
;
99 VisualStylesAPI::VisualStylesAPI()
100 : lpfnOpenThemeData( NULL
),
101 lpfnCloseThemeData( NULL
),
102 lpfnGetThemeBackgroundContentRect( NULL
),
103 lpfnDrawThemeBackground( NULL
),
104 lpfnDrawThemeText( NULL
),
105 lpfnGetThemePartSize( NULL
),
106 lpfnIsThemeActive( NULL
)
108 OUString
aLibraryName( "uxtheme.dll" );
109 mhModule
= osl_loadModule( aLibraryName
.pData
, SAL_LOADMODULE_DEFAULT
);
113 lpfnOpenThemeData
= (OpenThemeData_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "OpenThemeData" );
114 lpfnCloseThemeData
= (CloseThemeData_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "CloseThemeData" );
115 lpfnGetThemeBackgroundContentRect
= (GetThemeBackgroundContentRect_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "GetThemeBackgroundContentRect" );
116 lpfnDrawThemeBackground
= (DrawThemeBackground_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "DrawThemeBackground" );
117 lpfnDrawThemeText
= (DrawThemeText_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "DrawThemeText" );
118 lpfnGetThemePartSize
= (GetThemePartSize_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "GetThemePartSize" );
119 lpfnIsThemeActive
= (IsThemeActive_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "IsThemeActive" );
123 VisualStylesAPI::~VisualStylesAPI()
126 osl_unloadModule( mhModule
);
129 HTHEME
VisualStylesAPI::OpenThemeData( HWND hwnd
, LPCWSTR pszClassList
)
131 if(lpfnOpenThemeData
)
132 return (*lpfnOpenThemeData
) (hwnd
, pszClassList
);
137 HRESULT
VisualStylesAPI::CloseThemeData( HTHEME hTheme
)
139 if(lpfnCloseThemeData
)
140 return (*lpfnCloseThemeData
) (hTheme
);
145 HRESULT
VisualStylesAPI::GetThemeBackgroundContentRect( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pBoundingRect
, RECT
*pContentRect
)
147 if(lpfnGetThemeBackgroundContentRect
)
148 return (*lpfnGetThemeBackgroundContentRect
) ( hTheme
, hdc
, iPartId
, iStateId
, pBoundingRect
, pContentRect
);
153 HRESULT
VisualStylesAPI::DrawThemeBackground( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pRect
, const RECT
*pClipRect
)
155 if(lpfnDrawThemeBackground
)
156 return (*lpfnDrawThemeBackground
) (hTheme
, hdc
, iPartId
, iStateId
, pRect
, pClipRect
);
161 HRESULT
VisualStylesAPI::DrawThemeText( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, LPCWSTR pszText
, int iCharCount
, DWORD dwTextFlags
, DWORD dwTextFlags2
, const RECT
*pRect
)
163 if(lpfnDrawThemeText
)
164 return (*lpfnDrawThemeText
) (hTheme
, hdc
, iPartId
, iStateId
, pszText
, iCharCount
, dwTextFlags
, dwTextFlags2
, pRect
);
169 HRESULT
VisualStylesAPI::GetThemePartSize( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, RECT
*prc
, THEMESIZE eSize
, SIZE
*psz
)
171 if(lpfnGetThemePartSize
)
172 return (*lpfnGetThemePartSize
) (hTheme
, hdc
, iPartId
, iStateId
, prc
, eSize
, psz
);
177 BOOL
VisualStylesAPI::IsThemeActive( void )
179 if(lpfnIsThemeActive
)
180 return (*lpfnIsThemeActive
) ();
185 /*********************************************************
186 * Initialize XP theming and local stuff
187 *********************************************************/
188 void SalData::initNWF( void )
190 ImplSVData
* pSVData
= ImplGetSVData();
192 // the menu bar and the top docking area should have a common background (gradient)
193 pSVData
->maNWFData
.mbMenuBarDockingAreaCommonBG
= true;
197 // *********************************************************
198 // * Release theming handles
199 // ********************************************************
200 void SalData::deInitNWF( void )
202 ThemeMap::iterator iter
= aThemeMap
.begin();
203 while( iter
!= aThemeMap
.end() )
205 vsAPI
.CloseThemeData(iter
->second
);
210 osl_unloadModule( maDwmLib
);
213 static HTHEME
getThemeHandle( HWND hWnd
, LPCWSTR name
)
215 if( GetSalData()->mbThemeChanged
)
217 // throw away invalid theme handles
218 GetSalData()->deInitNWF();
219 GetSalData()->mbThemeChanged
= FALSE
;
222 ThemeMap::iterator iter
;
223 if( (iter
= aThemeMap
.find( name
)) != aThemeMap
.end() )
225 // theme not found -> add it to map
226 HTHEME hTheme
= vsAPI
.OpenThemeData( hWnd
, name
);
228 aThemeMap
[name
] = hTheme
;
233 * IsNativeControlSupported()
235 * Returns TRUE if the platform supports native
236 * drawing of the control defined by nPart
238 sal_Bool
WinSalGraphics::IsNativeControlSupported( ControlType nType
, ControlPart nPart
)
240 HTHEME hTheme
= NULL
;
244 case CTRL_PUSHBUTTON
:
245 case CTRL_RADIOBUTTON
:
247 if( nPart
== PART_ENTIRE_CONTROL
)
248 hTheme
= getThemeHandle( mhWnd
, L
"Button");
251 if( nPart
== PART_DRAW_BACKGROUND_HORZ
|| nPart
== PART_DRAW_BACKGROUND_VERT
)
252 return FALSE
; // no background painting needed
253 if( nPart
== PART_ENTIRE_CONTROL
)
254 hTheme
= getThemeHandle( mhWnd
, L
"Scrollbar");
257 if( nPart
== HAS_BACKGROUND_TEXTURE
)
258 return FALSE
; // we do not paint the inner part (ie the selection background/focus indication)
259 if( nPart
== PART_ENTIRE_CONTROL
)
260 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
261 else if( nPart
== PART_BUTTON_DOWN
)
262 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
265 if( nPart
== PART_ENTIRE_CONTROL
)
266 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
267 else if( nPart
== PART_ALL_BUTTONS
||
268 nPart
== PART_BUTTON_UP
|| nPart
== PART_BUTTON_DOWN
||
269 nPart
== PART_BUTTON_LEFT
|| nPart
== PART_BUTTON_RIGHT
)
270 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
272 case CTRL_SPINBUTTONS
:
273 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_ALL_BUTTONS
)
274 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
277 case CTRL_MULTILINE_EDITBOX
:
278 if( nPart
== HAS_BACKGROUND_TEXTURE
)
279 return FALSE
; // we do not paint the inner part (ie the selection background/focus indication)
281 if( nPart
== PART_ENTIRE_CONTROL
)
282 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
285 if( nPart
== HAS_BACKGROUND_TEXTURE
)
286 return FALSE
; // we do not paint the inner part (ie the selection background/focus indication)
287 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_WINDOW
)
288 hTheme
= getThemeHandle( mhWnd
, L
"Listview");
289 else if( nPart
== PART_BUTTON_DOWN
)
290 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
295 if( nPart
== PART_ENTIRE_CONTROL
)
296 hTheme
= getThemeHandle( mhWnd
, L
"Tab");
299 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_BUTTON
)
300 hTheme
= getThemeHandle( mhWnd
, L
"Toolbar");
302 // use rebar theme for grip and background
303 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
306 if( nPart
== PART_ENTIRE_CONTROL
)
307 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
308 else if( GetSalData()->mbThemeMenuSupport
)
310 if( nPart
== PART_MENU_ITEM
)
311 hTheme
= getThemeHandle( mhWnd
, L
"Menu" );
314 case CTRL_MENU_POPUP
:
315 if( GetSalData()->mbThemeMenuSupport
)
317 if( nPart
== PART_ENTIRE_CONTROL
||
318 nPart
== PART_MENU_ITEM
||
319 nPart
== PART_MENU_ITEM_CHECK_MARK
||
320 nPart
== PART_MENU_ITEM_RADIO_MARK
||
321 nPart
== PART_MENU_SEPARATOR
)
322 hTheme
= getThemeHandle( mhWnd
, L
"Menu" );
326 if( nPart
== PART_ENTIRE_CONTROL
)
327 hTheme
= getThemeHandle( mhWnd
, L
"Progress");
330 if( nPart
== PART_TRACK_HORZ_AREA
|| nPart
== PART_TRACK_VERT_AREA
)
331 hTheme
= getThemeHandle( mhWnd
, L
"Trackbar" );
334 if( nPart
== PART_ENTIRE_CONTROL
)
335 hTheme
= getThemeHandle( mhWnd
, L
"TreeView" );
342 return (hTheme
!= NULL
);
347 * HitTestNativeControl()
349 * If the return value is TRUE, bIsInside contains information whether
350 * aPos was or was not inside the native widget specified by the
351 * nType/nPart combination.
353 sal_Bool
WinSalGraphics::hitTestNativeControl( ControlType
,
362 sal_Bool
ImplDrawTheme( HTHEME hTheme
, HDC hDC
, int iPart
, int iState
, RECT rc
, const OUString
& aStr
)
364 HRESULT hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
366 if( aStr
.getLength() )
369 hr
= vsAPI
.GetThemeBackgroundContentRect( hTheme
, hDC
, iPart
, iState
, &rc
, &rcContent
);
370 hr
= vsAPI
.DrawThemeText( hTheme
, hDC
, iPart
, iState
,
371 reinterpret_cast<LPCWSTR
>(aStr
.getStr()), -1,
372 DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
,
379 Rectangle
ImplGetThemeRect( HTHEME hTheme
, HDC hDC
, int iPart
, int iState
, const Rectangle
& /* aRect */, THEMESIZE eTS
= TS_TRUE
)
382 HRESULT hr
= vsAPI
.GetThemePartSize( hTheme
, hDC
, iPart
, iState
, NULL
, eTS
, &aSz
); // TS_TRUE returns optimal size
384 return Rectangle( 0, 0, aSz
.cx
, aSz
.cy
);
392 void ImplConvertSpinbuttonValues( int nControlPart
, const ControlState
& rState
, const Rectangle
& rRect
,
393 int* pLunaPart
, int *pLunaState
, RECT
*pRect
)
395 if( nControlPart
== PART_BUTTON_DOWN
)
397 *pLunaPart
= SPNP_DOWN
;
398 if( rState
& CTRL_STATE_PRESSED
)
399 *pLunaState
= DNS_PRESSED
;
400 else if( !(rState
& CTRL_STATE_ENABLED
) )
401 *pLunaState
= DNS_DISABLED
;
402 else if( rState
& CTRL_STATE_ROLLOVER
)
403 *pLunaState
= DNS_HOT
;
405 *pLunaState
= DNS_NORMAL
;
407 if( nControlPart
== PART_BUTTON_UP
)
409 *pLunaPart
= SPNP_UP
;
410 if( rState
& CTRL_STATE_PRESSED
)
411 *pLunaState
= UPS_PRESSED
;
412 else if( !(rState
& CTRL_STATE_ENABLED
) )
413 *pLunaState
= UPS_DISABLED
;
414 else if( rState
& CTRL_STATE_ROLLOVER
)
415 *pLunaState
= UPS_HOT
;
417 *pLunaState
= UPS_NORMAL
;
419 if( nControlPart
== PART_BUTTON_RIGHT
)
421 *pLunaPart
= SPNP_UPHORZ
;
422 if( rState
& CTRL_STATE_PRESSED
)
423 *pLunaState
= DNHZS_PRESSED
;
424 else if( !(rState
& CTRL_STATE_ENABLED
) )
425 *pLunaState
= DNHZS_DISABLED
;
426 else if( rState
& CTRL_STATE_ROLLOVER
)
427 *pLunaState
= DNHZS_HOT
;
429 *pLunaState
= DNHZS_NORMAL
;
431 if( nControlPart
== PART_BUTTON_LEFT
)
433 *pLunaPart
= SPNP_DOWNHORZ
;
434 if( rState
& CTRL_STATE_PRESSED
)
435 *pLunaState
= UPHZS_PRESSED
;
436 else if( !(rState
& CTRL_STATE_ENABLED
) )
437 *pLunaState
= UPHZS_DISABLED
;
438 else if( rState
& CTRL_STATE_ROLLOVER
)
439 *pLunaState
= UPHZS_HOT
;
441 *pLunaState
= UPHZS_NORMAL
;
444 pRect
->left
= rRect
.Left();
445 pRect
->right
= rRect
.Right()+1;
446 pRect
->top
= rRect
.Top();
447 pRect
->bottom
= rRect
.Bottom()+1;
450 /// Draw an own toolbar style on Windows Vista or later, looks better there
451 static void impl_drawAeroToolbar( HDC hDC
, RECT rc
, bool bHorizontal
)
453 if ( rc
.top
== 0 && bHorizontal
)
455 const long GRADIENT_HEIGHT
= 32;
457 long gradient_break
= rc
.top
;
458 long gradient_bottom
= rc
.bottom
- 1;
459 GRADIENT_RECT g_rect
[1] = { { 0, 1 } };
461 // very slow gradient at the top (if we have space for that)
462 if ( gradient_bottom
- rc
.top
> GRADIENT_HEIGHT
)
464 gradient_break
= gradient_bottom
- GRADIENT_HEIGHT
;
466 TRIVERTEX vert
[2] = {
467 { rc
.left
, rc
.top
, 0xff00, 0xff00, 0xff00, 0xff00 },
468 { rc
.right
, gradient_break
, 0xfa00, 0xfa00, 0xfa00, 0xff00 },
470 GradientFill( hDC
, vert
, 2, g_rect
, 1, GRADIENT_FILL_RECT_V
);
473 // gradient at the bottom
474 TRIVERTEX vert
[2] = {
475 { rc
.left
, gradient_break
, 0xfa00, 0xfa00, 0xfa00, 0xff00 },
476 { rc
.right
, gradient_bottom
, 0xf000, 0xf000, 0xf000, 0xff00 }
478 GradientFill( hDC
, vert
, 2, g_rect
, 1, GRADIENT_FILL_RECT_V
);
480 // and a darker horizontal line under that
481 HPEN hpen
= CreatePen( PS_SOLID
, 1, RGB( 0xa0, 0xa0, 0xa0 ) );
482 SelectObject( hDC
, hpen
);
484 MoveToEx( hDC
, rc
.left
, gradient_bottom
, NULL
);
485 LineTo( hDC
, rc
.right
, gradient_bottom
);
487 DeleteObject( hpen
);
491 HBRUSH hbrush
= CreateSolidBrush( RGB( 0xf0, 0xf0, 0xf0 ) );
492 FillRect( hDC
, &rc
, hbrush
);
493 DeleteObject( hbrush
);
495 // darker line to distinguish the toolbar and viewshell
496 // it is drawn only for the horizontal toolbars; it did not look well
497 // when done for the vertical ones too
500 long from_x
, from_y
, to_x
, to_y
;
504 from_y
= to_y
= rc
.top
;
506 HPEN hpen
= CreatePen( PS_SOLID
, 1, RGB( 0xa0, 0xa0, 0xa0 ) );
507 SelectObject( hDC
, hpen
);
509 MoveToEx( hDC
, from_x
, from_y
, NULL
);
510 LineTo( hDC
, to_x
, to_y
);
512 DeleteObject( hpen
);
517 sal_Bool
ImplDrawNativeControl( HDC hDC
, HTHEME hTheme
, RECT rc
,
521 const ImplControlValue
& aValue
,
524 // a listbox dropdown is actually a combobox dropdown
525 if( nType
== CTRL_LISTBOX
)
526 if( nPart
== PART_BUTTON_DOWN
)
527 nType
= CTRL_COMBOBOX
;
529 // draw entire combobox as a large edit box
530 if( nType
== CTRL_COMBOBOX
)
531 if( nPart
== PART_ENTIRE_CONTROL
)
532 nType
= CTRL_EDITBOX
;
534 // draw entire spinbox as a large edit box
535 if( nType
== CTRL_SPINBOX
)
536 if( nPart
== PART_ENTIRE_CONTROL
)
537 nType
= CTRL_EDITBOX
;
539 int iPart(0), iState(0);
540 if( nType
== CTRL_SCROLLBAR
)
543 if( nPart
== PART_BUTTON_UP
)
545 iPart
= SBP_ARROWBTN
;
546 if( nState
& CTRL_STATE_PRESSED
)
547 iState
= ABS_UPPRESSED
;
548 else if( !(nState
& CTRL_STATE_ENABLED
) )
549 iState
= ABS_UPDISABLED
;
550 else if( nState
& CTRL_STATE_ROLLOVER
)
553 iState
= ABS_UPNORMAL
;
554 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
557 if( nPart
== PART_BUTTON_DOWN
)
559 iPart
= SBP_ARROWBTN
;
560 if( nState
& CTRL_STATE_PRESSED
)
561 iState
= ABS_DOWNPRESSED
;
562 else if( !(nState
& CTRL_STATE_ENABLED
) )
563 iState
= ABS_DOWNDISABLED
;
564 else if( nState
& CTRL_STATE_ROLLOVER
)
565 iState
= ABS_DOWNHOT
;
567 iState
= ABS_DOWNNORMAL
;
568 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
571 if( nPart
== PART_BUTTON_LEFT
)
573 iPart
= SBP_ARROWBTN
;
574 if( nState
& CTRL_STATE_PRESSED
)
575 iState
= ABS_LEFTPRESSED
;
576 else if( !(nState
& CTRL_STATE_ENABLED
) )
577 iState
= ABS_LEFTDISABLED
;
578 else if( nState
& CTRL_STATE_ROLLOVER
)
579 iState
= ABS_LEFTHOT
;
581 iState
= ABS_LEFTNORMAL
;
582 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
585 if( nPart
== PART_BUTTON_RIGHT
)
587 iPart
= SBP_ARROWBTN
;
588 if( nState
& CTRL_STATE_PRESSED
)
589 iState
= ABS_RIGHTPRESSED
;
590 else if( !(nState
& CTRL_STATE_ENABLED
) )
591 iState
= ABS_RIGHTDISABLED
;
592 else if( nState
& CTRL_STATE_ROLLOVER
)
593 iState
= ABS_RIGHTHOT
;
595 iState
= ABS_RIGHTNORMAL
;
596 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
599 if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
601 iPart
= (nPart
== PART_THUMB_HORZ
) ? SBP_THUMBBTNHORZ
: SBP_THUMBBTNVERT
;
602 if( nState
& CTRL_STATE_PRESSED
)
603 iState
= SCRBS_PRESSED
;
604 else if( !(nState
& CTRL_STATE_ENABLED
) )
605 iState
= SCRBS_DISABLED
;
606 else if( nState
& CTRL_STATE_ROLLOVER
)
609 iState
= SCRBS_NORMAL
;
612 vsAPI
.GetThemePartSize(hTheme
, hDC
, iPart
, iState
, NULL
, TS_MIN
, &sz
);
613 vsAPI
.GetThemePartSize(hTheme
, hDC
, iPart
, iState
, NULL
, TS_TRUE
, &sz
);
614 vsAPI
.GetThemePartSize(hTheme
, hDC
, iPart
, iState
, NULL
, TS_DRAW
, &sz
);
616 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
617 // paint gripper on thumb if enough space
618 if( ( (nPart
== PART_THUMB_VERT
) && (rc
.bottom
-rc
.top
> 12) ) ||
619 ( (nPart
== PART_THUMB_HORZ
) && (rc
.right
-rc
.left
> 12) ) )
621 iPart
= (nPart
== PART_THUMB_HORZ
) ? SBP_GRIPPERHORZ
: SBP_GRIPPERVERT
;
623 vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
627 if( nPart
== PART_TRACK_HORZ_LEFT
|| nPart
== PART_TRACK_HORZ_RIGHT
|| nPart
== PART_TRACK_VERT_UPPER
|| nPart
== PART_TRACK_VERT_LOWER
)
631 case PART_TRACK_HORZ_LEFT
: iPart
= SBP_UPPERTRACKHORZ
; break;
632 case PART_TRACK_HORZ_RIGHT
: iPart
= SBP_LOWERTRACKHORZ
; break;
633 case PART_TRACK_VERT_UPPER
: iPart
= SBP_UPPERTRACKVERT
; break;
634 case PART_TRACK_VERT_LOWER
: iPart
= SBP_LOWERTRACKVERT
; break;
637 if( nState
& CTRL_STATE_PRESSED
)
638 iState
= SCRBS_PRESSED
;
639 else if( !(nState
& CTRL_STATE_ENABLED
) )
640 iState
= SCRBS_DISABLED
;
641 else if( nState
& CTRL_STATE_ROLLOVER
)
644 iState
= SCRBS_NORMAL
;
645 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
649 if( nType
== CTRL_SPINBUTTONS
&& nPart
== PART_ALL_BUTTONS
)
651 if( aValue
.getType() == CTRL_SPINBUTTONS
)
653 const SpinbuttonValue
* pValue
= (aValue
.getType() == CTRL_SPINBUTTONS
) ? static_cast<const SpinbuttonValue
*>(&aValue
) : NULL
;
654 sal_Bool bOk
= sal_False
;
657 ImplConvertSpinbuttonValues( pValue
->mnUpperPart
, pValue
->mnUpperState
, pValue
->maUpperRect
, &iPart
, &iState
, &rect
);
658 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
662 ImplConvertSpinbuttonValues( pValue
->mnLowerPart
, pValue
->mnLowerState
, pValue
->maLowerRect
, &iPart
, &iState
, &rect
);
663 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
669 if( nType
== CTRL_SPINBOX
)
671 // decrease spinbutton rects a little
674 if( nPart
== PART_ALL_BUTTONS
)
676 if( aValue
.getType() == CTRL_SPINBUTTONS
)
678 const SpinbuttonValue
*pValue
= static_cast<const SpinbuttonValue
*>(&aValue
);
679 sal_Bool bOk
= sal_False
;
682 ImplConvertSpinbuttonValues( pValue
->mnUpperPart
, pValue
->mnUpperState
, pValue
->maUpperRect
, &iPart
, &iState
, &rect
);
683 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
687 ImplConvertSpinbuttonValues( pValue
->mnLowerPart
, pValue
->mnLowerState
, pValue
->maLowerRect
, &iPart
, &iState
, &rect
);
688 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
695 if( nPart
== PART_BUTTON_DOWN
)
698 if( nState
& CTRL_STATE_PRESSED
)
699 iState
= DNS_PRESSED
;
700 else if( !(nState
& CTRL_STATE_ENABLED
) )
701 iState
= DNS_DISABLED
;
702 else if( nState
& CTRL_STATE_ROLLOVER
)
707 if( nPart
== PART_BUTTON_UP
)
710 if( nState
& CTRL_STATE_PRESSED
)
711 iState
= UPS_PRESSED
;
712 else if( !(nState
& CTRL_STATE_ENABLED
) )
713 iState
= UPS_DISABLED
;
714 else if( nState
& CTRL_STATE_ROLLOVER
)
719 if( nPart
== PART_BUTTON_RIGHT
)
721 iPart
= SPNP_DOWNHORZ
;
722 if( nState
& CTRL_STATE_PRESSED
)
723 iState
= DNHZS_PRESSED
;
724 else if( !(nState
& CTRL_STATE_ENABLED
) )
725 iState
= DNHZS_DISABLED
;
726 else if( nState
& CTRL_STATE_ROLLOVER
)
729 iState
= DNHZS_NORMAL
;
731 if( nPart
== PART_BUTTON_LEFT
)
734 if( nState
& CTRL_STATE_PRESSED
)
735 iState
= UPHZS_PRESSED
;
736 else if( !(nState
& CTRL_STATE_ENABLED
) )
737 iState
= UPHZS_DISABLED
;
738 else if( nState
& CTRL_STATE_ROLLOVER
)
741 iState
= UPHZS_NORMAL
;
743 if( nPart
== PART_BUTTON_LEFT
|| nPart
== PART_BUTTON_RIGHT
|| nPart
== PART_BUTTON_UP
|| nPart
== PART_BUTTON_DOWN
)
744 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
746 if( nType
== CTRL_COMBOBOX
)
748 if( nPart
== PART_BUTTON_DOWN
)
750 iPart
= CP_DROPDOWNBUTTON
;
751 if( nState
& CTRL_STATE_PRESSED
)
752 iState
= CBXS_PRESSED
;
753 else if( !(nState
& CTRL_STATE_ENABLED
) )
754 iState
= CBXS_DISABLED
;
755 else if( nState
& CTRL_STATE_ROLLOVER
)
758 iState
= CBXS_NORMAL
;
759 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
762 if( nType
== CTRL_PUSHBUTTON
)
764 iPart
= BP_PUSHBUTTON
;
765 if( nState
& CTRL_STATE_PRESSED
)
766 iState
= PBS_PRESSED
;
767 else if( !(nState
& CTRL_STATE_ENABLED
) )
768 iState
= PBS_DISABLED
;
769 else if( nState
& CTRL_STATE_ROLLOVER
)
771 else if( nState
& CTRL_STATE_DEFAULT
)
772 iState
= PBS_DEFAULTED
;
773 //else if( nState & CTRL_STATE_FOCUSED )
774 // iState = PBS_DEFAULTED; // may need to draw focus rect
778 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
781 if( nType
== CTRL_RADIOBUTTON
)
783 iPart
= BP_RADIOBUTTON
;
784 sal_Bool bChecked
= ( aValue
.getTristateVal() == BUTTONVALUE_ON
);
786 if( nState
& CTRL_STATE_PRESSED
)
787 iState
= bChecked
? RBS_CHECKEDPRESSED
: RBS_UNCHECKEDPRESSED
;
788 else if( !(nState
& CTRL_STATE_ENABLED
) )
789 iState
= bChecked
? RBS_CHECKEDDISABLED
: RBS_UNCHECKEDDISABLED
;
790 else if( nState
& CTRL_STATE_ROLLOVER
)
791 iState
= bChecked
? RBS_CHECKEDHOT
: RBS_UNCHECKEDHOT
;
793 iState
= bChecked
? RBS_CHECKEDNORMAL
: RBS_UNCHECKEDNORMAL
;
795 //if( nState & CTRL_STATE_FOCUSED )
796 // iState |= PBS_DEFAULTED; // may need to draw focus rect
798 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
801 if( nType
== CTRL_CHECKBOX
)
804 ButtonValue v
= aValue
.getTristateVal();
806 if( nState
& CTRL_STATE_PRESSED
)
807 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDPRESSED
:
808 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDPRESSED
: CBS_MIXEDPRESSED
);
809 else if( !(nState
& CTRL_STATE_ENABLED
) )
810 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDDISABLED
:
811 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDDISABLED
: CBS_MIXEDDISABLED
);
812 else if( nState
& CTRL_STATE_ROLLOVER
)
813 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDHOT
:
814 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDHOT
: CBS_MIXEDHOT
);
816 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDNORMAL
:
817 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDNORMAL
: CBS_MIXEDNORMAL
);
819 //if( nState & CTRL_STATE_FOCUSED )
820 // iState |= PBS_DEFAULTED; // may need to draw focus rect
823 //THEMESIZE eSize = TS_DRAW; // TS_MIN, TS_TRUE, TS_DRAW
824 //vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, &rc, eSize, &sz);
826 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
829 if( ( nType
== CTRL_EDITBOX
) || ( nType
== CTRL_MULTILINE_EDITBOX
) )
832 if( !(nState
& CTRL_STATE_ENABLED
) )
833 iState
= ETS_DISABLED
;
834 else if( nState
& CTRL_STATE_FOCUSED
)
835 iState
= ETS_FOCUSED
;
836 else if( nState
& CTRL_STATE_ROLLOVER
)
841 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
844 if( nType
== CTRL_LISTBOX
)
846 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_WINDOW
)
848 iPart
= LVP_EMPTYTEXT
; // ??? no idea which part to choose here
849 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
853 if( nType
== CTRL_TAB_PANE
)
856 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
859 if( nType
== CTRL_TAB_BODY
)
862 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
865 if( nType
== CTRL_TAB_ITEM
)
867 iPart
= TABP_TABITEMLEFTEDGE
;
870 OSL_ASSERT( aValue
.getType() == CTRL_TAB_ITEM
);
872 const TabitemValue
*pValue
= static_cast<const TabitemValue
*>(&aValue
);
873 if( pValue
->isBothAligned() )
875 iPart
= TABP_TABITEMLEFTEDGE
;
878 else if( pValue
->isLeftAligned() )
879 iPart
= TABP_TABITEMLEFTEDGE
;
880 else if( pValue
->isRightAligned() )
881 iPart
= TABP_TABITEMRIGHTEDGE
;
882 else iPart
= TABP_TABITEM
;
884 if( !(nState
& CTRL_STATE_ENABLED
) )
885 iState
= TILES_DISABLED
;
886 else if( nState
& CTRL_STATE_SELECTED
)
888 iState
= TILES_SELECTED
;
889 // increase the selected tab
891 if( pValue
&& !pValue
->isBothAligned() )
893 if( pValue
->isLeftAligned() || pValue
->isNotAligned() )
895 if( pValue
->isRightAligned() )
901 else if( nState
& CTRL_STATE_ROLLOVER
)
903 else if( nState
& CTRL_STATE_FOCUSED
)
904 iState
= TILES_FOCUSED
; // may need to draw focus rect
906 iState
= TILES_NORMAL
;
907 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
910 if( nType
== CTRL_TOOLBAR
)
912 if( nPart
== PART_BUTTON
)
915 sal_Bool bChecked
= ( aValue
.getTristateVal() == BUTTONVALUE_ON
);
916 if( !(nState
& CTRL_STATE_ENABLED
) )
917 //iState = TS_DISABLED;
918 // disabled buttons are typically not painted at all but we need visual
919 // feedback when travelling by keyboard over disabled entries
921 else if( nState
& CTRL_STATE_PRESSED
)
923 else if( nState
& CTRL_STATE_ROLLOVER
)
924 iState
= bChecked
? TS_HOTCHECKED
: TS_HOT
;
926 iState
= bChecked
? TS_CHECKED
: TS_NORMAL
;
927 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
929 else if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
931 // the vertical gripper is not supported in most themes and it makes no
932 // sense to only support horizontal gripper
933 //iPart = (nPart == PART_THUMB_HORZ) ? RP_GRIPPERVERT : RP_GRIPPER;
934 //return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
936 else if( nPart
== PART_DRAW_BACKGROUND_HORZ
|| nPart
== PART_DRAW_BACKGROUND_VERT
)
938 if( aValue
.getType() == CTRL_TOOLBAR
)
940 const ToolbarValue
*pValue
= static_cast<const ToolbarValue
*>(&aValue
);
941 if( pValue
->mbIsTopDockingArea
)
942 rc
.top
= 0; // extend potential gradient to cover menu bar as well
945 // make it more compatible with Aero
946 if( ImplGetSVData()->maNWFData
.mbDockingAreaAvoidTBFrames
)
948 impl_drawAeroToolbar( hDC
, rc
, nPart
== PART_DRAW_BACKGROUND_HORZ
);
952 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
956 if( nType
== CTRL_MENUBAR
)
958 if( nPart
== PART_ENTIRE_CONTROL
)
960 if( aValue
.getType() == CTRL_MENUBAR
)
962 const MenubarValue
*pValue
= static_cast<const MenubarValue
*>(&aValue
);
963 rc
.bottom
+= pValue
->maTopDockingAreaHeight
; // extend potential gradient to cover docking area as well
965 // make it more compatible with Aero
966 if( ImplGetSVData()->maNWFData
.mbDockingAreaAvoidTBFrames
)
968 impl_drawAeroToolbar( hDC
, rc
, true );
972 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
974 else if( nPart
== PART_MENU_ITEM
)
976 if( nState
& CTRL_STATE_ENABLED
)
978 if( nState
& CTRL_STATE_SELECTED
)
980 else if( nState
& CTRL_STATE_ROLLOVER
)
987 if( nState
& CTRL_STATE_SELECTED
)
988 iState
= MBI_DISABLEDPUSHED
;
989 else if( nState
& CTRL_STATE_ROLLOVER
)
990 iState
= MBI_DISABLEDHOT
;
992 iState
= MBI_DISABLED
;
994 return ImplDrawTheme( hTheme
, hDC
, MENU_BARITEM
, iState
, rc
, aCaption
);
998 if( nType
== CTRL_PROGRESS
)
1000 if( nPart
!= PART_ENTIRE_CONTROL
)
1003 if( ! ImplDrawTheme( hTheme
, hDC
, PP_BAR
, iState
, rc
, aCaption
) )
1005 RECT aProgressRect
= rc
;
1006 if( vsAPI
.GetThemeBackgroundContentRect( hTheme
, hDC
, PP_BAR
, iState
, &rc
, &aProgressRect
) != S_OK
)
1009 long nProgressWidth
= aValue
.getNumericVal();
1010 nProgressWidth
*= (aProgressRect
.right
- aProgressRect
.left
);
1011 nProgressWidth
/= (rc
.right
- rc
.left
);
1012 if( Application::GetSettings().GetLayoutRTL() )
1013 aProgressRect
.left
= aProgressRect
.right
- nProgressWidth
;
1015 aProgressRect
.right
= aProgressRect
.left
+ nProgressWidth
;
1017 return ImplDrawTheme( hTheme
, hDC
, PP_CHUNK
, iState
, aProgressRect
, aCaption
);
1020 if( nType
== CTRL_SLIDER
)
1022 iPart
= (nPart
== PART_TRACK_HORZ_AREA
) ? TKP_TRACK
: TKP_TRACKVERT
;
1023 iState
= (nPart
== PART_TRACK_HORZ_AREA
) ? static_cast<int>(TRS_NORMAL
) : static_cast<int>(TRVS_NORMAL
);
1025 Rectangle aTrackRect
= ImplGetThemeRect( hTheme
, hDC
, iPart
, iState
, Rectangle() );
1027 if( nPart
== PART_TRACK_HORZ_AREA
)
1029 long nH
= aTrackRect
.GetHeight();
1030 aTRect
.top
+= (rc
.bottom
- rc
.top
- nH
)/2;
1031 aTRect
.bottom
= aTRect
.top
+ nH
;
1035 long nW
= aTrackRect
.GetWidth();
1036 aTRect
.left
+= (rc
.right
- rc
.left
- nW
)/2;
1037 aTRect
.right
= aTRect
.left
+ nW
;
1039 ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, aTRect
, aCaption
);
1042 OSL_ASSERT( aValue
.getType() == CTRL_SLIDER
);
1043 const SliderValue
* pVal
= static_cast<const SliderValue
*>(&aValue
);
1044 aThumbRect
.left
= pVal
->maThumbRect
.Left();
1045 aThumbRect
.top
= pVal
->maThumbRect
.Top();
1046 aThumbRect
.right
= pVal
->maThumbRect
.Right();
1047 aThumbRect
.bottom
= pVal
->maThumbRect
.Bottom();
1048 iPart
= (nPart
== PART_TRACK_HORZ_AREA
) ? TKP_THUMB
: TKP_THUMBVERT
;
1049 iState
= (nState
& CTRL_STATE_ENABLED
) ? TUS_NORMAL
: TUS_DISABLED
;
1050 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, aThumbRect
, aCaption
);
1053 if( nType
== CTRL_LISTNODE
)
1055 if( nPart
!= PART_ENTIRE_CONTROL
)
1058 ButtonValue aButtonValue
= aValue
.getTristateVal();
1060 switch( aButtonValue
)
1062 case BUTTONVALUE_ON
:
1063 iState
= GLPS_OPENED
;
1065 case BUTTONVALUE_OFF
:
1066 iState
= GLPS_CLOSED
;
1071 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
1074 if( GetSalData()->mbThemeMenuSupport
)
1076 if( nType
== CTRL_MENU_POPUP
)
1078 if( nPart
== PART_ENTIRE_CONTROL
)
1080 RECT aGutterRC
= rc
;
1081 if( Application::GetSettings().GetLayoutRTL() )
1083 aGutterRC
.right
-= aValue
.getNumericVal()+1;
1084 aGutterRC
.left
= aGutterRC
.right
-3;
1088 aGutterRC
.left
+= aValue
.getNumericVal();
1089 aGutterRC
.right
= aGutterRC
.left
+3;
1092 ImplDrawTheme( hTheme
, hDC
, MENU_POPUPBACKGROUND
, 0, rc
, aCaption
) &&
1093 ImplDrawTheme( hTheme
, hDC
, MENU_POPUPGUTTER
, 0, aGutterRC
, aCaption
)
1096 else if( nPart
== PART_MENU_ITEM
)
1098 if( (nState
& CTRL_STATE_ENABLED
) )
1099 iState
= (nState
& CTRL_STATE_SELECTED
) ? MPI_HOT
: MPI_NORMAL
;
1101 iState
= (nState
& CTRL_STATE_SELECTED
) ? MPI_DISABLEDHOT
: MPI_DISABLED
;
1102 return ImplDrawTheme( hTheme
, hDC
, MENU_POPUPITEM
, iState
, rc
, aCaption
);
1104 else if( nPart
== PART_MENU_ITEM_CHECK_MARK
|| nPart
== PART_MENU_ITEM_RADIO_MARK
)
1106 if( (nState
& CTRL_STATE_PRESSED
) )
1109 if( aValue
.getType() == CTRL_MENU_POPUP
)
1111 const MenupopupValue
& rMVal( static_cast<const MenupopupValue
&>(aValue
) );
1112 aBGRect
.top
= rMVal
.maItemRect
.Top();
1113 aBGRect
.bottom
= rMVal
.maItemRect
.Bottom()+1; // see below in drawNativeControl
1114 if( Application::GetSettings().GetLayoutRTL() )
1116 aBGRect
.right
= rMVal
.maItemRect
.Right()+1;
1117 aBGRect
.left
= aBGRect
.right
- (rMVal
.getNumericVal()-rMVal
.maItemRect
.Left());
1121 aBGRect
.right
= rMVal
.getNumericVal();
1122 aBGRect
.left
= rMVal
.maItemRect
.Left();
1126 iState
= (nState
& CTRL_STATE_ENABLED
) ? MCB_NORMAL
: MCB_DISABLED
;
1127 ImplDrawTheme( hTheme
, hDC
, MENU_POPUPCHECKBACKGROUND
, iState
, aBGRect
, aCaption
);
1128 if( nPart
== PART_MENU_ITEM_CHECK_MARK
)
1129 iState
= (nState
& CTRL_STATE_ENABLED
) ? MC_CHECKMARKNORMAL
: MC_CHECKMARKDISABLED
;
1131 iState
= (nState
& CTRL_STATE_ENABLED
) ? MC_BULLETNORMAL
: MC_BULLETDISABLED
;
1132 return ImplDrawTheme( hTheme
, hDC
, MENU_POPUPCHECK
, iState
, rc
, aCaption
);
1135 return true; // unchecked: do nothing
1137 else if( nPart
== PART_MENU_SEPARATOR
)
1139 // adjust for gutter position
1140 if( Application::GetSettings().GetLayoutRTL() )
1141 rc
.right
-= aValue
.getNumericVal()+1;
1143 rc
.left
+= aValue
.getNumericVal()+1;
1144 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
,
1145 MENU_POPUPSEPARATOR
, 0, Rectangle( rc
.left
, rc
.top
, rc
.right
, rc
.bottom
) ) );
1146 // center the separator inside the passed rectangle
1147 long nDY
= ((rc
.bottom
- rc
.top
+ 1) - aRect
.GetHeight()) / 2;
1149 rc
.bottom
= rc
.top
+aRect
.GetHeight()-1;
1150 return ImplDrawTheme( hTheme
, hDC
, MENU_POPUPSEPARATOR
, 0, rc
, aCaption
);
1159 * DrawNativeControl()
1161 * Draws the requested control described by nPart/nState.
1163 * rControlRegion: The bounding region of the complete control in VCL frame coordinates.
1164 * aValue: An optional value (tristate/numerical/string)
1165 * aCaption: A caption or title string (like button text etc)
1167 sal_Bool
WinSalGraphics::drawNativeControl( ControlType nType
,
1169 const Rectangle
& rControlRegion
,
1170 ControlState nState
,
1171 const ImplControlValue
& aValue
,
1172 const OUString
& aCaption
)
1174 sal_Bool bOk
= false;
1175 HTHEME hTheme
= NULL
;
1179 case CTRL_PUSHBUTTON
:
1180 case CTRL_RADIOBUTTON
:
1182 hTheme
= getThemeHandle( mhWnd
, L
"Button");
1184 case CTRL_SCROLLBAR
:
1185 hTheme
= getThemeHandle( mhWnd
, L
"Scrollbar");
1188 if( nPart
== PART_ENTIRE_CONTROL
)
1189 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
1190 else if( nPart
== PART_BUTTON_DOWN
)
1191 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
1194 if( nPart
== PART_ENTIRE_CONTROL
)
1195 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
1197 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
1199 case CTRL_SPINBUTTONS
:
1200 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
1203 case CTRL_MULTILINE_EDITBOX
:
1204 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
1207 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_WINDOW
)
1208 hTheme
= getThemeHandle( mhWnd
, L
"Listview");
1209 else if( nPart
== PART_BUTTON_DOWN
)
1210 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
1215 hTheme
= getThemeHandle( mhWnd
, L
"Tab");
1218 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_BUTTON
)
1219 hTheme
= getThemeHandle( mhWnd
, L
"Toolbar");
1221 // use rebar for grip and background
1222 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
1225 if( nPart
== PART_ENTIRE_CONTROL
)
1226 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
1227 else if( GetSalData()->mbThemeMenuSupport
)
1229 if( nPart
== PART_MENU_ITEM
)
1230 hTheme
= getThemeHandle( mhWnd
, L
"Menu" );
1234 if( nPart
== PART_ENTIRE_CONTROL
)
1235 hTheme
= getThemeHandle( mhWnd
, L
"Progress");
1238 if( nPart
== PART_ENTIRE_CONTROL
)
1239 hTheme
= getThemeHandle( mhWnd
, L
"TreeView");
1242 if( nPart
== PART_TRACK_HORZ_AREA
|| nPart
== PART_TRACK_VERT_AREA
)
1243 hTheme
= getThemeHandle( mhWnd
, L
"Trackbar" );
1245 case CTRL_MENU_POPUP
:
1246 if( GetSalData()->mbThemeMenuSupport
)
1248 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_MENU_ITEM
||
1249 nPart
== PART_MENU_ITEM_CHECK_MARK
|| nPart
== PART_MENU_ITEM_RADIO_MARK
||
1250 nPart
== PART_MENU_SEPARATOR
1252 hTheme
= getThemeHandle( mhWnd
, L
"Menu" );
1263 Rectangle buttonRect
= rControlRegion
;
1265 rc
.left
= buttonRect
.Left();
1266 rc
.right
= buttonRect
.Right()+1;
1267 rc
.top
= buttonRect
.Top();
1268 rc
.bottom
= buttonRect
.Bottom()+1;
1270 // set default text alignment
1271 int ta
= SetTextAlign( mhDC
, TA_LEFT
|TA_TOP
|TA_NOUPDATECP
);
1273 OUString
aCaptionStr( aCaption
.replace('~', '&') ); // translate mnemonics
1274 bOk
= ImplDrawNativeControl(mhDC
, hTheme
, rc
,
1275 nType
, nPart
, nState
, aValue
,
1278 // restore alignment
1279 SetTextAlign( mhDC
, ta
);
1288 * GetNativeControlRegion()
1290 * If the return value is TRUE, rNativeBoundingRegion
1291 * contains the true bounding region covered by the control
1292 * including any adornment, while rNativeContentRegion contains the area
1293 * within the control that can be safely drawn into without drawing over
1294 * the borders of the control.
1296 * rControlRegion: The bounding region of the control in VCL frame coordinates.
1297 * aValue: An optional value (tristate/numerical/string)
1298 * aCaption: A caption or title string (like button text etc)
1300 sal_Bool
WinSalGraphics::getNativeControlRegion( ControlType nType
,
1302 const Rectangle
& rControlRegion
,
1303 ControlState nState
,
1304 const ImplControlValue
& rControlValue
,
1306 Rectangle
&rNativeBoundingRegion
,
1307 Rectangle
&rNativeContentRegion
)
1309 sal_Bool bRet
= FALSE
;
1311 HDC hDC
= GetDC( mhWnd
);
1312 if( nType
== CTRL_TOOLBAR
)
1314 if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
1317 // the vertical gripper is not supported in most themes and it makes no
1318 // sense to only support horizontal gripper
1320 HTHEME hTheme = getThemeHandle( mhWnd, L"Rebar");
1323 Rectangle aRect( ImplGetThemeRect( hTheme, hDC, nPart == PART_THUMB_HORZ ? RP_GRIPPERVERT : RP_GRIPPER,
1324 0, rControlRegion.GetBoundRect() ) );
1325 if( nPart == PART_THUMB_HORZ && !aRect.IsEmpty() )
1327 Rectangle aVertRect( 0, 0, aRect.getHeight(), aRect.getWidth() );
1328 rNativeContentRegion = aVertRect;
1331 rNativeContentRegion = aRect;
1332 rNativeBoundingRegion = rNativeContentRegion;
1333 if( !rNativeContentRegion.IsEmpty() )
1338 if( nPart
== PART_BUTTON
)
1340 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Toolbar");
1343 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
, TP_SPLITBUTTONDROPDOWN
,
1344 TS_HOT
, rControlRegion
) );
1345 rNativeContentRegion
= aRect
;
1346 rNativeBoundingRegion
= rNativeContentRegion
;
1347 if( !rNativeContentRegion
.IsEmpty() )
1352 if( nType
== CTRL_PROGRESS
&& nPart
== PART_ENTIRE_CONTROL
)
1354 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Progress");
1357 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
, PP_BAR
,
1358 0, rControlRegion
) );
1359 rNativeContentRegion
= aRect
;
1360 rNativeBoundingRegion
= rNativeContentRegion
;
1361 if( !rNativeContentRegion
.IsEmpty() )
1365 if( (nType
== CTRL_LISTBOX
|| nType
== CTRL_COMBOBOX
) && nPart
== PART_ENTIRE_CONTROL
)
1367 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
1370 Rectangle
aBoxRect( rControlRegion
);
1371 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
, CP_DROPDOWNBUTTON
,
1372 CBXS_NORMAL
, aBoxRect
) );
1373 if( aRect
.GetHeight() > aBoxRect
.GetHeight() )
1374 aBoxRect
.Bottom() = aBoxRect
.Top() + aRect
.GetHeight();
1375 if( aRect
.GetWidth() > aBoxRect
.GetWidth() )
1376 aBoxRect
.Right() = aBoxRect
.Left() + aRect
.GetWidth();
1377 rNativeContentRegion
= aBoxRect
;
1378 rNativeBoundingRegion
= rNativeContentRegion
;
1379 if( !aRect
.IsEmpty() )
1384 if( (nType
== CTRL_EDITBOX
|| nType
== CTRL_SPINBOX
) && nPart
== PART_ENTIRE_CONTROL
)
1386 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Edit");
1390 Rectangle
aBoxRect( rControlRegion
);
1391 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
, EP_BACKGROUNDWITHBORDER
,
1392 EBWBS_HOT
, aBoxRect
) );
1393 // ad app font height
1394 NONCLIENTMETRICSW aNonClientMetrics
;
1395 aNonClientMetrics
.cbSize
= sizeof( aNonClientMetrics
);
1396 if ( SystemParametersInfoW( SPI_GETNONCLIENTMETRICS
, sizeof( aNonClientMetrics
), &aNonClientMetrics
, 0 ) )
1398 long nFontHeight
= aNonClientMetrics
.lfMessageFont
.lfHeight
;
1399 if( nFontHeight
< 0 )
1400 nFontHeight
= -nFontHeight
;
1402 if( aRect
.GetHeight() && nFontHeight
)
1404 aRect
.Bottom() += aRect
.GetHeight();
1405 aRect
.Bottom() += nFontHeight
;
1406 if( aRect
.GetHeight() > aBoxRect
.GetHeight() )
1407 aBoxRect
.Bottom() = aBoxRect
.Top() + aRect
.GetHeight();
1408 if( aRect
.GetWidth() > aBoxRect
.GetWidth() )
1409 aBoxRect
.Right() = aBoxRect
.Left() + aRect
.GetWidth();
1410 rNativeContentRegion
= aBoxRect
;
1411 rNativeBoundingRegion
= rNativeContentRegion
;
1418 if( GetSalData()->mbThemeMenuSupport
)
1420 if( nType
== CTRL_MENU_POPUP
)
1422 if( nPart
== PART_MENU_ITEM_CHECK_MARK
||
1423 nPart
== PART_MENU_ITEM_RADIO_MARK
)
1425 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Menu");
1426 Rectangle
aBoxRect( rControlRegion
);
1427 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
,
1431 if( aBoxRect
.GetWidth() && aBoxRect
.GetHeight() )
1433 rNativeContentRegion
= aRect
;
1434 rNativeBoundingRegion
= rNativeContentRegion
;
1441 if( nType
== CTRL_SLIDER
&& ( (nPart
== PART_THUMB_HORZ
) || (nPart
== PART_THUMB_VERT
) ) )
1443 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Trackbar");
1446 int iPart
= (nPart
== PART_THUMB_HORZ
) ? TKP_THUMB
: TKP_THUMBVERT
;
1447 int iState
= (nPart
== PART_THUMB_HORZ
) ? static_cast<int>(TUS_NORMAL
) : static_cast<int>(TUVS_NORMAL
);
1448 Rectangle aThumbRect
= ImplGetThemeRect( hTheme
, hDC
, iPart
, iState
, Rectangle() );
1449 if( nPart
== PART_THUMB_HORZ
)
1451 long nW
= aThumbRect
.GetWidth();
1452 Rectangle
aRect( rControlRegion
);
1453 aRect
.Right() = aRect
.Left() + nW
- 1;
1454 rNativeContentRegion
= aRect
;
1455 rNativeBoundingRegion
= rNativeContentRegion
;
1459 long nH
= aThumbRect
.GetHeight();
1460 Rectangle
aRect( rControlRegion
);
1461 aRect
.Bottom() = aRect
.Top() + nH
- 1;
1462 rNativeContentRegion
= aRect
;
1463 rNativeBoundingRegion
= rNativeContentRegion
;
1469 if ( ( nType
== CTRL_TAB_ITEM
) && ( nPart
== PART_ENTIRE_CONTROL
) )
1471 Rectangle
aControlRect( rControlRegion
);
1472 rNativeContentRegion
= aControlRect
;
1474 --aControlRect
.Bottom();
1476 if( rControlValue
.getType() == CTRL_TAB_ITEM
)
1478 const TabitemValue
*pValue
= static_cast<const TabitemValue
*>(&rControlValue
);
1479 if ( pValue
->isBothAligned() )
1480 --aControlRect
.Right();
1482 if ( nState
& CTRL_STATE_SELECTED
)
1484 aControlRect
.Left() -= 2;
1485 if ( pValue
&& !pValue
->isBothAligned() )
1487 if ( pValue
->isLeftAligned() || pValue
->isNotAligned() )
1488 aControlRect
.Right() += 2;
1489 if ( pValue
->isRightAligned() )
1490 aControlRect
.Right() += 1;
1492 aControlRect
.Top() -= 2;
1493 aControlRect
.Bottom() += 2;
1496 rNativeBoundingRegion
= aControlRect
;
1500 ReleaseDC( mhWnd
, hDC
);
1504 void WinSalGraphics::updateSettingsNative( AllSettings
& rSettings
)
1506 if ( !vsAPI
.IsThemeActive() )
1509 StyleSettings aStyleSettings
= rSettings
.GetStyleSettings();
1510 ImplSVData
* pSVData
= ImplGetSVData();
1512 // don't draw frame around each and every toolbar
1513 pSVData
->maNWFData
.mbDockingAreaAvoidTBFrames
= true;
1515 // check if vista or newer runs
1516 // in Aero theme (and similar ?) the menu text color does not change
1517 // for selected items; also on WinXP and earlier menus are not themed
1518 // FIXME get the color directly from the theme, not from the settings
1519 if( aSalShlData
.maVersionInfo
.dwMajorVersion
>= 6 )
1521 // in aero menuitem highlight text is drawn in the same color as normal
1522 aStyleSettings
.SetMenuHighlightTextColor( aStyleSettings
.GetMenuTextColor() );
1523 aStyleSettings
.SetMenuBarRolloverTextColor( aStyleSettings
.GetMenuTextColor() );
1524 pSVData
->maNWFData
.mnMenuFormatBorderX
= 2;
1525 pSVData
->maNWFData
.mnMenuFormatBorderY
= 2;
1526 pSVData
->maNWFData
.maMenuBarHighlightTextColor
= aStyleSettings
.GetMenuTextColor();
1527 GetSalData()->mbThemeMenuSupport
= TRUE
;
1530 rSettings
.SetStyleSettings( aStyleSettings
);
1533 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */