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-luna.cxx,v $
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 #define _SV_SALNATIVEWIDGETS_CXX
38 #include "saldata.hxx"
39 #include "vcl/svapp.hxx"
41 #include "rtl/ustring.h"
42 #include "osl/module.h"
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
);
72 OpenThemeData_Proc_T lpfnOpenThemeData
;
73 CloseThemeData_Proc_T lpfnCloseThemeData
;
74 GetThemeBackgroundContentRect_Proc_T lpfnGetThemeBackgroundContentRect
;
75 DrawThemeBackground_Proc_T lpfnDrawThemeBackground
;
76 DrawThemeText_Proc_T lpfnDrawThemeText
;
77 GetThemePartSize_Proc_T lpfnGetThemePartSize
;
84 BOOL
IsAvailable() { return (mhModule
!= NULL
); }
86 HTHEME
OpenThemeData( HWND hwnd
, LPCWSTR pszClassList
);
87 HRESULT
CloseThemeData( HTHEME hTheme
);
88 HRESULT
GetThemeBackgroundContentRect( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pBoundingRect
, RECT
*pContentRect
);
89 HRESULT
DrawThemeBackground( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pRect
, const RECT
*pClipRect
);
90 HRESULT
DrawThemeText( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, LPCWSTR pszText
, int iCharCount
, DWORD dwTextFlags
, DWORD dwTextFlags2
, const RECT
*pRect
);
91 HRESULT
GetThemePartSize( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, RECT
*prc
, THEMESIZE eSize
, SIZE
*psz
);
94 static VisualStylesAPI vsAPI
;
96 VisualStylesAPI::VisualStylesAPI()
98 OUString
aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "uxtheme.dll" ) );
99 mhModule
= osl_loadModule( aLibraryName
.pData
, SAL_LOADMODULE_DEFAULT
);
103 lpfnOpenThemeData
= (OpenThemeData_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "OpenThemeData" );
104 lpfnCloseThemeData
= (CloseThemeData_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "CloseThemeData" );
105 lpfnGetThemeBackgroundContentRect
= (GetThemeBackgroundContentRect_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "GetThemeBackgroundContentRect" );
106 lpfnDrawThemeBackground
= (DrawThemeBackground_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "DrawThemeBackground" );
107 lpfnDrawThemeText
= (DrawThemeText_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "DrawThemeText" );
108 lpfnGetThemePartSize
= (GetThemePartSize_Proc_T
)osl_getAsciiFunctionSymbol( mhModule
, "GetThemePartSize" );
112 lpfnOpenThemeData
= NULL
;
113 lpfnCloseThemeData
= NULL
;
114 lpfnGetThemeBackgroundContentRect
= NULL
;
115 lpfnDrawThemeBackground
= NULL
;
116 lpfnDrawThemeText
= NULL
;
117 lpfnGetThemePartSize
= NULL
;
120 VisualStylesAPI::~VisualStylesAPI()
123 osl_unloadModule( mhModule
);
125 HTHEME
VisualStylesAPI::OpenThemeData( HWND hwnd
, LPCWSTR pszClassList
)
127 if(lpfnOpenThemeData
)
128 return (*lpfnOpenThemeData
) (hwnd
, pszClassList
);
133 HRESULT
VisualStylesAPI::CloseThemeData( HTHEME hTheme
)
135 if(lpfnCloseThemeData
)
136 return (*lpfnCloseThemeData
) (hTheme
);
140 HRESULT
VisualStylesAPI::GetThemeBackgroundContentRect( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pBoundingRect
, RECT
*pContentRect
)
142 if(lpfnGetThemeBackgroundContentRect
)
143 return (*lpfnGetThemeBackgroundContentRect
) ( hTheme
, hdc
, iPartId
, iStateId
, pBoundingRect
, pContentRect
);
147 HRESULT
VisualStylesAPI::DrawThemeBackground( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, const RECT
*pRect
, const RECT
*pClipRect
)
149 if(lpfnDrawThemeBackground
)
150 return (*lpfnDrawThemeBackground
) (hTheme
, hdc
, iPartId
, iStateId
, pRect
, pClipRect
);
154 HRESULT
VisualStylesAPI::DrawThemeText( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, LPCWSTR pszText
, int iCharCount
, DWORD dwTextFlags
, DWORD dwTextFlags2
, const RECT
*pRect
)
156 if(lpfnDrawThemeText
)
157 return (*lpfnDrawThemeText
) (hTheme
, hdc
, iPartId
, iStateId
, pszText
, iCharCount
, dwTextFlags
, dwTextFlags2
, pRect
);
161 HRESULT
VisualStylesAPI::GetThemePartSize( HTHEME hTheme
, HDC hdc
, int iPartId
, int iStateId
, RECT
*prc
, THEMESIZE eSize
, SIZE
*psz
)
163 if(lpfnGetThemePartSize
)
164 return (*lpfnGetThemePartSize
) (hTheme
, hdc
, iPartId
, iStateId
, prc
, eSize
, psz
);
170 /*********************************************************
171 * Initialize XP theming and local stuff
172 *********************************************************/
173 void SalData::initNWF( void )
175 ImplSVData
* pSVData
= ImplGetSVData();
177 // the menu bar and the top docking area should have a common background (gradient)
178 pSVData
->maNWFData
.mbMenuBarDockingAreaCommonBG
= true;
182 // *********************************************************
183 // * Release theming handles
184 // ********************************************************
185 void SalData::deInitNWF( void )
187 ThemeMap::iterator iter
= aThemeMap
.begin();
188 while( iter
!= aThemeMap
.end() )
190 vsAPI
.CloseThemeData(iter
->second
);
196 static HTHEME
getThemeHandle( HWND hWnd
, LPCWSTR name
)
198 if( GetSalData()->mbThemeChanged
)
200 // throw away invalid theme handles
201 GetSalData()->deInitNWF();
202 GetSalData()->mbThemeChanged
= FALSE
;
205 ThemeMap::iterator iter
;
206 if( (iter
= aThemeMap
.find( name
)) != aThemeMap
.end() )
208 // theme not found -> add it to map
209 HTHEME hTheme
= vsAPI
.OpenThemeData( hWnd
, name
);
211 aThemeMap
[name
] = hTheme
;
216 * IsNativeControlSupported()
218 * Returns TRUE if the platform supports native
219 * drawing of the control defined by nPart
221 BOOL
WinSalGraphics::IsNativeControlSupported( ControlType nType
, ControlPart nPart
)
223 HTHEME hTheme
= NULL
;
227 case CTRL_PUSHBUTTON
:
228 case CTRL_RADIOBUTTON
:
230 if( nPart
== PART_ENTIRE_CONTROL
)
231 hTheme
= getThemeHandle( mhWnd
, L
"Button");
234 if( nPart
== PART_DRAW_BACKGROUND_HORZ
|| nPart
== PART_DRAW_BACKGROUND_VERT
)
235 return FALSE
; // no background painting needed
236 if( nPart
== PART_ENTIRE_CONTROL
)
237 hTheme
= getThemeHandle( mhWnd
, L
"Scrollbar");
240 if( nPart
== HAS_BACKGROUND_TEXTURE
)
241 return FALSE
; // we do not paint the inner part (ie the selection background/focus indication)
242 if( nPart
== PART_ENTIRE_CONTROL
)
243 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
244 else if( nPart
== PART_BUTTON_DOWN
)
245 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
248 if( nPart
== PART_ENTIRE_CONTROL
)
249 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
250 else if( nPart
== PART_ALL_BUTTONS
||
251 nPart
== PART_BUTTON_UP
|| nPart
== PART_BUTTON_DOWN
||
252 nPart
== PART_BUTTON_LEFT
|| nPart
== PART_BUTTON_RIGHT
)
253 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
255 case CTRL_SPINBUTTONS
:
256 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_ALL_BUTTONS
)
257 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
260 case CTRL_MULTILINE_EDITBOX
:
261 if( nPart
== HAS_BACKGROUND_TEXTURE
)
262 return FALSE
; // we do not paint the inner part (ie the selection background/focus indication)
264 if( nPart
== PART_ENTIRE_CONTROL
)
265 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
268 if( nPart
== HAS_BACKGROUND_TEXTURE
)
269 return FALSE
; // we do not paint the inner part (ie the selection background/focus indication)
270 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_WINDOW
)
271 hTheme
= getThemeHandle( mhWnd
, L
"Listview");
272 else if( nPart
== PART_BUTTON_DOWN
)
273 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
278 case CTRL_FIXEDBORDER
:
279 if( nPart
== PART_ENTIRE_CONTROL
)
280 hTheme
= getThemeHandle( mhWnd
, L
"Tab");
283 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_BUTTON
)
284 hTheme
= getThemeHandle( mhWnd
, L
"Toolbar");
286 // use rebar theme for grip and background
287 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
290 if( nPart
== PART_ENTIRE_CONTROL
)
291 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
294 if( nPart
== PART_ENTIRE_CONTROL
)
295 hTheme
= getThemeHandle( mhWnd
, L
"Progress");
302 return (hTheme
!= NULL
);
307 * HitTestNativeControl()
309 * If the return value is TRUE, bIsInside contains information whether
310 * aPos was or was not inside the native widget specified by the
311 * nType/nPart combination.
313 BOOL
WinSalGraphics::hitTestNativeControl( ControlType
,
323 BOOL
ImplDrawTheme( HTHEME hTheme
, HDC hDC
, int iPart
, int iState
, RECT rc
, const OUString
& aStr
)
325 HRESULT hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
327 if( aStr
.getLength() )
330 hr
= vsAPI
.GetThemeBackgroundContentRect( hTheme
, hDC
, iPart
, iState
, &rc
, &rcContent
);
331 hr
= vsAPI
.DrawThemeText( hTheme
, hDC
, iPart
, iState
,
332 reinterpret_cast<LPCWSTR
>(aStr
.getStr()), -1,
333 DT_CENTER
| DT_VCENTER
| DT_SINGLELINE
,
340 Rectangle
ImplGetThemeRect( HTHEME hTheme
, HDC hDC
, int iPart
, int iState
, const Rectangle
& aRect
)
344 rc
.left
= aRect
.nLeft
;
345 rc
.right
= aRect
.nRight
;
347 rc
.bottom
= aRect
.nBottom
;
348 HRESULT hr
= vsAPI
.GetThemePartSize( hTheme
, hDC
, iPart
, iState
, NULL
, TS_TRUE
, &aSz
); // TS_TRUE returns optimal size
350 return Rectangle( 0, 0, aSz
.cx
, aSz
.cy
);
358 void ImplConvertSpinbuttonValues( int nControlPart
, const ControlState
& rState
, const Rectangle
& rRect
,
359 int* pLunaPart
, int *pLunaState
, RECT
*pRect
)
361 if( nControlPart
== PART_BUTTON_DOWN
)
363 *pLunaPart
= SPNP_DOWN
;
364 if( rState
& CTRL_STATE_PRESSED
)
365 *pLunaState
= DNS_PRESSED
;
366 else if( !(rState
& CTRL_STATE_ENABLED
) )
367 *pLunaState
= DNS_DISABLED
;
368 else if( rState
& CTRL_STATE_ROLLOVER
)
369 *pLunaState
= DNS_HOT
;
371 *pLunaState
= DNS_NORMAL
;
373 if( nControlPart
== PART_BUTTON_UP
)
375 *pLunaPart
= SPNP_UP
;
376 if( rState
& CTRL_STATE_PRESSED
)
377 *pLunaState
= UPS_PRESSED
;
378 else if( !(rState
& CTRL_STATE_ENABLED
) )
379 *pLunaState
= UPS_DISABLED
;
380 else if( rState
& CTRL_STATE_ROLLOVER
)
381 *pLunaState
= UPS_HOT
;
383 *pLunaState
= UPS_NORMAL
;
385 if( nControlPart
== PART_BUTTON_RIGHT
)
387 *pLunaPart
= SPNP_UPHORZ
;
388 if( rState
& CTRL_STATE_PRESSED
)
389 *pLunaState
= DNHZS_PRESSED
;
390 else if( !(rState
& CTRL_STATE_ENABLED
) )
391 *pLunaState
= DNHZS_DISABLED
;
392 else if( rState
& CTRL_STATE_ROLLOVER
)
393 *pLunaState
= DNHZS_HOT
;
395 *pLunaState
= DNHZS_NORMAL
;
397 if( nControlPart
== PART_BUTTON_LEFT
)
399 *pLunaPart
= SPNP_DOWNHORZ
;
400 if( rState
& CTRL_STATE_PRESSED
)
401 *pLunaState
= UPHZS_PRESSED
;
402 else if( !(rState
& CTRL_STATE_ENABLED
) )
403 *pLunaState
= UPHZS_DISABLED
;
404 else if( rState
& CTRL_STATE_ROLLOVER
)
405 *pLunaState
= UPHZS_HOT
;
407 *pLunaState
= UPHZS_NORMAL
;
410 pRect
->left
= rRect
.Left();
411 pRect
->right
= rRect
.Right()+1;
412 pRect
->top
= rRect
.Top();
413 pRect
->bottom
= rRect
.Bottom()+1;
418 BOOL
ImplDrawNativeControl( HDC hDC
, HTHEME hTheme
, RECT rc
,
422 const ImplControlValue
& aValue
,
426 // a listbox dropdown is actually a combobox dropdown
427 if( nType
== CTRL_LISTBOX
)
428 if( nPart
== PART_BUTTON_DOWN
)
429 nType
= CTRL_COMBOBOX
;
431 // draw entire combobox as a large edit box
432 if( nType
== CTRL_COMBOBOX
)
433 if( nPart
== PART_ENTIRE_CONTROL
)
434 nType
= CTRL_EDITBOX
;
436 // draw entire spinbox as a large edit box
437 if( nType
== CTRL_SPINBOX
)
438 if( nPart
== PART_ENTIRE_CONTROL
)
439 nType
= CTRL_EDITBOX
;
441 int iPart(0), iState(0);
442 if( nType
== CTRL_SCROLLBAR
)
445 if( nPart
== PART_BUTTON_UP
)
447 iPart
= SBP_ARROWBTN
;
448 if( nState
& CTRL_STATE_PRESSED
)
449 iState
= ABS_UPPRESSED
;
450 else if( !(nState
& CTRL_STATE_ENABLED
) )
451 iState
= ABS_UPDISABLED
;
452 else if( nState
& CTRL_STATE_ROLLOVER
)
455 iState
= ABS_UPNORMAL
;
456 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
459 if( nPart
== PART_BUTTON_DOWN
)
461 iPart
= SBP_ARROWBTN
;
462 if( nState
& CTRL_STATE_PRESSED
)
463 iState
= ABS_DOWNPRESSED
;
464 else if( !(nState
& CTRL_STATE_ENABLED
) )
465 iState
= ABS_DOWNDISABLED
;
466 else if( nState
& CTRL_STATE_ROLLOVER
)
467 iState
= ABS_DOWNHOT
;
469 iState
= ABS_DOWNNORMAL
;
470 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
473 if( nPart
== PART_BUTTON_LEFT
)
475 iPart
= SBP_ARROWBTN
;
476 if( nState
& CTRL_STATE_PRESSED
)
477 iState
= ABS_LEFTPRESSED
;
478 else if( !(nState
& CTRL_STATE_ENABLED
) )
479 iState
= ABS_LEFTDISABLED
;
480 else if( nState
& CTRL_STATE_ROLLOVER
)
481 iState
= ABS_LEFTHOT
;
483 iState
= ABS_LEFTNORMAL
;
484 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
487 if( nPart
== PART_BUTTON_RIGHT
)
489 iPart
= SBP_ARROWBTN
;
490 if( nState
& CTRL_STATE_PRESSED
)
491 iState
= ABS_RIGHTPRESSED
;
492 else if( !(nState
& CTRL_STATE_ENABLED
) )
493 iState
= ABS_RIGHTDISABLED
;
494 else if( nState
& CTRL_STATE_ROLLOVER
)
495 iState
= ABS_RIGHTHOT
;
497 iState
= ABS_RIGHTNORMAL
;
498 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
501 if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
503 iPart
= (nPart
== PART_THUMB_HORZ
) ? SBP_THUMBBTNHORZ
: SBP_THUMBBTNVERT
;
504 if( nState
& CTRL_STATE_PRESSED
)
505 iState
= SCRBS_PRESSED
;
506 else if( !(nState
& CTRL_STATE_ENABLED
) )
507 iState
= SCRBS_DISABLED
;
508 else if( nState
& CTRL_STATE_ROLLOVER
)
511 iState
= SCRBS_NORMAL
;
514 vsAPI
.GetThemePartSize(hTheme
, hDC
, iPart
, iState
, NULL
, TS_MIN
, &sz
);
515 vsAPI
.GetThemePartSize(hTheme
, hDC
, iPart
, iState
, NULL
, TS_TRUE
, &sz
);
516 vsAPI
.GetThemePartSize(hTheme
, hDC
, iPart
, iState
, NULL
, TS_DRAW
, &sz
);
518 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
519 // paint gripper on thumb if enough space
520 if( ( (nPart
== PART_THUMB_VERT
) && (rc
.bottom
-rc
.top
> 12) ) ||
521 ( (nPart
== PART_THUMB_HORZ
) && (rc
.right
-rc
.left
> 12) ) )
523 iPart
= (nPart
== PART_THUMB_HORZ
) ? SBP_GRIPPERHORZ
: SBP_GRIPPERVERT
;
525 vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
529 if( nPart
== PART_TRACK_HORZ_LEFT
|| nPart
== PART_TRACK_HORZ_RIGHT
|| nPart
== PART_TRACK_VERT_UPPER
|| nPart
== PART_TRACK_VERT_LOWER
)
533 case PART_TRACK_HORZ_LEFT
: iPart
= SBP_UPPERTRACKHORZ
; break;
534 case PART_TRACK_HORZ_RIGHT
: iPart
= SBP_LOWERTRACKHORZ
; break;
535 case PART_TRACK_VERT_UPPER
: iPart
= SBP_UPPERTRACKVERT
; break;
536 case PART_TRACK_VERT_LOWER
: iPart
= SBP_LOWERTRACKVERT
; break;
539 if( nState
& CTRL_STATE_PRESSED
)
540 iState
= SCRBS_PRESSED
;
541 else if( !(nState
& CTRL_STATE_ENABLED
) )
542 iState
= SCRBS_DISABLED
;
543 else if( nState
& CTRL_STATE_ROLLOVER
)
546 iState
= SCRBS_NORMAL
;
547 hr
= vsAPI
.DrawThemeBackground( hTheme
, hDC
, iPart
, iState
, &rc
, 0);
551 if( nType
== CTRL_SPINBUTTONS
&& nPart
== PART_ALL_BUTTONS
)
553 SpinbuttonValue
*pValue
= (SpinbuttonValue
*) aValue
.getOptionalVal();
559 ImplConvertSpinbuttonValues( pValue
->mnUpperPart
, pValue
->mnUpperState
, pValue
->maUpperRect
, &iPart
, &iState
, &rect
);
560 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
564 ImplConvertSpinbuttonValues( pValue
->mnLowerPart
, pValue
->mnLowerState
, pValue
->maLowerRect
, &iPart
, &iState
, &rect
);
565 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
571 if( nType
== CTRL_SPINBOX
)
573 // decrease spinbutton rects a little
576 if( nPart
== PART_ALL_BUTTONS
)
578 SpinbuttonValue
*pValue
= (SpinbuttonValue
*) aValue
.getOptionalVal();
584 ImplConvertSpinbuttonValues( pValue
->mnUpperPart
, pValue
->mnUpperState
, pValue
->maUpperRect
, &iPart
, &iState
, &rect
);
585 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
589 ImplConvertSpinbuttonValues( pValue
->mnLowerPart
, pValue
->mnLowerState
, pValue
->maLowerRect
, &iPart
, &iState
, &rect
);
590 bOk
= ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rect
, aCaption
);
597 if( nPart
== PART_BUTTON_DOWN
)
600 if( nState
& CTRL_STATE_PRESSED
)
601 iState
= DNS_PRESSED
;
602 else if( !(nState
& CTRL_STATE_ENABLED
) )
603 iState
= DNS_DISABLED
;
604 else if( nState
& CTRL_STATE_ROLLOVER
)
609 if( nPart
== PART_BUTTON_UP
)
612 if( nState
& CTRL_STATE_PRESSED
)
613 iState
= UPS_PRESSED
;
614 else if( !(nState
& CTRL_STATE_ENABLED
) )
615 iState
= UPS_DISABLED
;
616 else if( nState
& CTRL_STATE_ROLLOVER
)
621 if( nPart
== PART_BUTTON_RIGHT
)
623 iPart
= SPNP_DOWNHORZ
;
624 if( nState
& CTRL_STATE_PRESSED
)
625 iState
= DNHZS_PRESSED
;
626 else if( !(nState
& CTRL_STATE_ENABLED
) )
627 iState
= DNHZS_DISABLED
;
628 else if( nState
& CTRL_STATE_ROLLOVER
)
631 iState
= DNHZS_NORMAL
;
633 if( nPart
== PART_BUTTON_LEFT
)
636 if( nState
& CTRL_STATE_PRESSED
)
637 iState
= UPHZS_PRESSED
;
638 else if( !(nState
& CTRL_STATE_ENABLED
) )
639 iState
= UPHZS_DISABLED
;
640 else if( nState
& CTRL_STATE_ROLLOVER
)
643 iState
= UPHZS_NORMAL
;
645 if( nPart
== PART_BUTTON_LEFT
|| nPart
== PART_BUTTON_RIGHT
|| nPart
== PART_BUTTON_UP
|| nPart
== PART_BUTTON_DOWN
)
646 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
648 if( nType
== CTRL_COMBOBOX
)
650 if( nPart
== PART_BUTTON_DOWN
)
652 iPart
= CP_DROPDOWNBUTTON
;
653 if( nState
& CTRL_STATE_PRESSED
)
654 iState
= CBXS_PRESSED
;
655 else if( !(nState
& CTRL_STATE_ENABLED
) )
656 iState
= CBXS_DISABLED
;
657 else if( nState
& CTRL_STATE_ROLLOVER
)
660 iState
= CBXS_NORMAL
;
661 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
664 if( nType
== CTRL_PUSHBUTTON
)
666 iPart
= BP_PUSHBUTTON
;
667 if( nState
& CTRL_STATE_PRESSED
)
668 iState
= PBS_PRESSED
;
669 else if( !(nState
& CTRL_STATE_ENABLED
) )
670 iState
= PBS_DISABLED
;
671 else if( nState
& CTRL_STATE_ROLLOVER
)
673 else if( nState
& CTRL_STATE_DEFAULT
)
674 iState
= PBS_DEFAULTED
;
675 //else if( nState & CTRL_STATE_FOCUSED )
676 // iState = PBS_DEFAULTED; // may need to draw focus rect
680 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
683 if( nType
== CTRL_RADIOBUTTON
)
685 iPart
= BP_RADIOBUTTON
;
686 BOOL bChecked
= ( aValue
.getTristateVal() == BUTTONVALUE_ON
);
688 if( nState
& CTRL_STATE_PRESSED
)
689 iState
= bChecked
? RBS_CHECKEDPRESSED
: RBS_UNCHECKEDPRESSED
;
690 else if( !(nState
& CTRL_STATE_ENABLED
) )
691 iState
= bChecked
? RBS_CHECKEDDISABLED
: RBS_UNCHECKEDDISABLED
;
692 else if( nState
& CTRL_STATE_ROLLOVER
)
693 iState
= bChecked
? RBS_CHECKEDHOT
: RBS_UNCHECKEDHOT
;
695 iState
= bChecked
? RBS_CHECKEDNORMAL
: RBS_UNCHECKEDNORMAL
;
697 //if( nState & CTRL_STATE_FOCUSED )
698 // iState |= PBS_DEFAULTED; // may need to draw focus rect
700 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
703 if( nType
== CTRL_CHECKBOX
)
706 ButtonValue v
= aValue
.getTristateVal();
708 if( nState
& CTRL_STATE_PRESSED
)
709 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDPRESSED
:
710 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDPRESSED
: CBS_MIXEDPRESSED
);
711 else if( !(nState
& CTRL_STATE_ENABLED
) )
712 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDDISABLED
:
713 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDDISABLED
: CBS_MIXEDDISABLED
);
714 else if( nState
& CTRL_STATE_ROLLOVER
)
715 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDHOT
:
716 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDHOT
: CBS_MIXEDHOT
);
718 iState
= (v
== BUTTONVALUE_ON
) ? CBS_CHECKEDNORMAL
:
719 ( (v
== BUTTONVALUE_OFF
) ? CBS_UNCHECKEDNORMAL
: CBS_MIXEDNORMAL
);
721 //if( nState & CTRL_STATE_FOCUSED )
722 // iState |= PBS_DEFAULTED; // may need to draw focus rect
725 //THEMESIZE eSize = TS_DRAW; // TS_MIN, TS_TRUE, TS_DRAW
726 //vsAPI.GetThemePartSize( hTheme, hDC, iPart, iState, &rc, eSize, &sz);
728 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
731 if( ( nType
== CTRL_EDITBOX
) || ( nType
== CTRL_MULTILINE_EDITBOX
) )
734 if( !(nState
& CTRL_STATE_ENABLED
) )
735 iState
= ETS_DISABLED
;
736 else if( nState
& CTRL_STATE_FOCUSED
)
737 iState
= ETS_FOCUSED
;
738 else if( nState
& CTRL_STATE_ROLLOVER
)
743 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
746 if( nType
== CTRL_LISTBOX
)
748 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_WINDOW
)
750 iPart
= LVP_EMPTYTEXT
; // ??? no idea which part to choose here
751 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
755 if( nType
== CTRL_TAB_PANE
)
758 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
761 if( nType
== CTRL_FIXEDBORDER
)
765 if( !(nState & CTRL_STATE_ENABLED) )
766 iState = GBS_DISABLED;
770 // The fixed border is only used around the tools->options tabpage where
771 // TABP_PANE fits best
773 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
776 if( nType
== CTRL_TAB_BODY
)
779 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
782 if( nType
== CTRL_TAB_ITEM
)
784 iPart
= TABP_TABITEMLEFTEDGE
;
787 TabitemValue
*pValue
= (TabitemValue
*) aValue
.getOptionalVal();
790 if( pValue
->isBothAligned() )
792 iPart
= TABP_TABITEMLEFTEDGE
;
795 else if( pValue
->isLeftAligned() )
796 iPart
= TABP_TABITEMLEFTEDGE
;
797 else if( pValue
->isRightAligned() )
798 iPart
= TABP_TABITEMRIGHTEDGE
;
799 else iPart
= TABP_TABITEM
;
802 if( !(nState
& CTRL_STATE_ENABLED
) )
803 iState
= TILES_DISABLED
;
804 else if( nState
& CTRL_STATE_SELECTED
)
806 iState
= TILES_SELECTED
;
807 // increase the selected tab
809 if( pValue
&& !pValue
->isBothAligned() )
811 if( pValue
->isLeftAligned() || pValue
->isNotAligned() )
813 if( pValue
->isRightAligned() )
819 else if( nState
& CTRL_STATE_ROLLOVER
)
821 else if( nState
& CTRL_STATE_FOCUSED
)
822 iState
= TILES_FOCUSED
; // may need to draw focus rect
824 iState
= TILES_NORMAL
;
825 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
828 if( nType
== CTRL_TOOLBAR
)
830 if( nPart
== PART_BUTTON
)
833 BOOL bChecked
= ( aValue
.getTristateVal() == BUTTONVALUE_ON
);
834 if( !(nState
& CTRL_STATE_ENABLED
) )
835 //iState = TS_DISABLED;
836 // disabled buttons are typically not painted at all but we need visual
837 // feedback when travelling by keyboard over disabled entries
839 else if( nState
& CTRL_STATE_PRESSED
)
841 else if( nState
& CTRL_STATE_ROLLOVER
)
842 iState
= bChecked
? TS_HOTCHECKED
: TS_HOT
;
844 iState
= bChecked
? TS_CHECKED
: TS_NORMAL
;
845 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
847 else if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
849 // the vertical gripper is not supported in most themes and it makes no
850 // sense to only support horizontal gripper
851 //iPart = (nPart == PART_THUMB_HORZ) ? RP_GRIPPERVERT : RP_GRIPPER;
852 //return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption);
854 else if( nPart
== PART_DRAW_BACKGROUND_HORZ
|| nPart
== PART_DRAW_BACKGROUND_VERT
)
856 ToolbarValue
*pValue
= (ToolbarValue
*) aValue
.getOptionalVal();
857 if( pValue
&& pValue
->mbIsTopDockingArea
)
858 rc
.top
= 0; // extend potential gradient to cover menu bar as well
859 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
863 if( nType
== CTRL_MENUBAR
)
865 if( nPart
!= PART_ENTIRE_CONTROL
)
868 MenubarValue
*pValue
= (MenubarValue
*) aValue
.getOptionalVal();
870 rc
.bottom
+= pValue
->maTopDockingAreaHeight
; // extend potential gradient to cover docking area as well
871 return ImplDrawTheme( hTheme
, hDC
, iPart
, iState
, rc
, aCaption
);
874 if( nType
== CTRL_PROGRESS
)
876 if( nPart
!= PART_ENTIRE_CONTROL
)
879 if( ! ImplDrawTheme( hTheme
, hDC
, PP_BAR
, iState
, rc
, aCaption
) )
881 RECT aProgressRect
= rc
;
882 if( vsAPI
.GetThemeBackgroundContentRect( hTheme
, hDC
, PP_BAR
, iState
, &rc
, &aProgressRect
) != S_OK
)
885 long nProgressWidth
= aValue
.getNumericVal();
886 nProgressWidth
*= (aProgressRect
.right
- aProgressRect
.left
);
887 nProgressWidth
/= (rc
.right
- rc
.left
);
888 if( Application::GetSettings().GetLayoutRTL() )
889 aProgressRect
.left
= aProgressRect
.right
- nProgressWidth
;
891 aProgressRect
.right
= aProgressRect
.left
+ nProgressWidth
;
893 return ImplDrawTheme( hTheme
, hDC
, PP_CHUNK
, iState
, aProgressRect
, aCaption
);
900 * DrawNativeControl()
902 * Draws the requested control described by nPart/nState.
904 * rControlRegion: The bounding region of the complete control in VCL frame coordinates.
905 * aValue: An optional value (tristate/numerical/string)
906 * rControlHandle: Carries platform dependent data and is maintained by the WinSalGraphics implementation.
907 * aCaption: A caption or title string (like button text etc)
909 BOOL
WinSalGraphics::drawNativeControl( ControlType nType
,
911 const Region
& rControlRegion
,
913 const ImplControlValue
& aValue
,
914 SalControlHandle
& rControlHandle
,
915 const OUString
& aCaption
)
918 HTHEME hTheme
= NULL
;
922 case CTRL_PUSHBUTTON
:
923 case CTRL_RADIOBUTTON
:
925 hTheme
= getThemeHandle( mhWnd
, L
"Button");
928 hTheme
= getThemeHandle( mhWnd
, L
"Scrollbar");
931 if( nPart
== PART_ENTIRE_CONTROL
)
932 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
933 else if( nPart
== PART_BUTTON_DOWN
)
934 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
937 if( nPart
== PART_ENTIRE_CONTROL
)
938 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
940 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
942 case CTRL_SPINBUTTONS
:
943 hTheme
= getThemeHandle( mhWnd
, L
"Spin");
946 case CTRL_MULTILINE_EDITBOX
:
947 hTheme
= getThemeHandle( mhWnd
, L
"Edit");
950 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_WINDOW
)
951 hTheme
= getThemeHandle( mhWnd
, L
"Listview");
952 else if( nPart
== PART_BUTTON_DOWN
)
953 hTheme
= getThemeHandle( mhWnd
, L
"Combobox");
958 case CTRL_FIXEDBORDER
:
959 hTheme
= getThemeHandle( mhWnd
, L
"Tab");
962 if( nPart
== PART_ENTIRE_CONTROL
|| nPart
== PART_BUTTON
)
963 hTheme
= getThemeHandle( mhWnd
, L
"Toolbar");
965 // use rebar for grip and background
966 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
969 if( nPart
== PART_ENTIRE_CONTROL
)
970 hTheme
= getThemeHandle( mhWnd
, L
"Rebar");
973 if( nPart
== PART_ENTIRE_CONTROL
)
974 hTheme
= getThemeHandle( mhWnd
, L
"Progress");
984 Rectangle buttonRect
= rControlRegion
.GetBoundRect();
986 rc
.left
= buttonRect
.Left();
987 rc
.right
= buttonRect
.Right()+1;
988 rc
.top
= buttonRect
.Top();
989 rc
.bottom
= buttonRect
.Bottom()+1;
991 // set default text alignment
992 int ta
= SetTextAlign( mhDC
, TA_LEFT
|TA_TOP
|TA_NOUPDATECP
);
994 OUString
aCaptionStr( aCaption
.replace('~', '&') ); // translate mnemonics
995 bOk
= ImplDrawNativeControl(mhDC
, hTheme
, rc
,
996 nType
, nPart
, nState
, aValue
,
997 rControlHandle
, aCaptionStr
);
1000 SetTextAlign( mhDC
, ta
);
1010 * DrawNativeControlText()
1012 * OPTIONAL. Draws the requested text for the control described by nPart/nState.
1013 * Used if text not drawn by DrawNativeControl().
1015 * rControlRegion: The bounding region of the complete control in VCL frame coordinates.
1016 * aValue: An optional value (tristate/numerical/string)
1017 * rControlHandle: Carries platform dependent data and is maintained by the WinSalGraphics implementation.
1018 * aCaption: A caption or title string (like button text etc)
1020 BOOL
WinSalGraphics::drawNativeControlText( ControlType
,
1024 const ImplControlValue
&,
1033 * GetNativeControlRegion()
1035 * If the return value is TRUE, rNativeBoundingRegion
1036 * contains the true bounding region covered by the control
1037 * including any adornment, while rNativeContentRegion contains the area
1038 * within the control that can be safely drawn into without drawing over
1039 * the borders of the control.
1041 * rControlRegion: The bounding region of the control in VCL frame coordinates.
1042 * aValue: An optional value (tristate/numerical/string)
1043 * rControlHandle: Carries platform dependent data and is maintained by the WinSalGraphics implementation.
1044 * aCaption: A caption or title string (like button text etc)
1046 BOOL
WinSalGraphics::getNativeControlRegion( ControlType nType
,
1048 const Region
& rControlRegion
,
1050 const ImplControlValue
&,
1053 Region
&rNativeBoundingRegion
,
1054 Region
&rNativeContentRegion
)
1058 HDC hDC
= GetDC( mhWnd
);
1059 if( nType
== CTRL_TOOLBAR
)
1061 if( nPart
== PART_THUMB_HORZ
|| nPart
== PART_THUMB_VERT
)
1064 // the vertical gripper is not supported in most themes and it makes no
1065 // sense to only support horizontal gripper
1067 HTHEME hTheme = getThemeHandle( mhWnd, L"Rebar");
1070 Rectangle aRect( ImplGetThemeRect( hTheme, hDC, nPart == PART_THUMB_HORZ ? RP_GRIPPERVERT : RP_GRIPPER,
1071 0, rControlRegion.GetBoundRect() ) );
1072 if( nPart == PART_THUMB_HORZ && !aRect.IsEmpty() )
1074 Rectangle aVertRect( 0, 0, aRect.getHeight(), aRect.getWidth() );
1075 rNativeContentRegion = aVertRect;
1078 rNativeContentRegion = aRect;
1079 rNativeBoundingRegion = rNativeContentRegion;
1080 if( !rNativeContentRegion.IsEmpty() )
1085 if( nPart
== PART_BUTTON
)
1087 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Toolbar");
1090 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
, TP_SPLITBUTTONDROPDOWN
,
1091 TS_HOT
, rControlRegion
.GetBoundRect() ) );
1092 rNativeContentRegion
= aRect
;
1093 rNativeBoundingRegion
= rNativeContentRegion
;
1094 if( !rNativeContentRegion
.IsEmpty() )
1099 if( nType
== CTRL_PROGRESS
&& nPart
== PART_ENTIRE_CONTROL
)
1101 HTHEME hTheme
= getThemeHandle( mhWnd
, L
"Progress");
1104 Rectangle
aRect( ImplGetThemeRect( hTheme
, hDC
, PP_BAR
,
1105 0, rControlRegion
.GetBoundRect() ) );
1106 rNativeContentRegion
= aRect
;
1107 rNativeBoundingRegion
= rNativeContentRegion
;
1108 if( !rNativeContentRegion
.IsEmpty() )
1112 ReleaseDC( mhWnd
, hDC
);