1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "vcl/salnativewidgets.hxx"
29*cdf0e10cSrcweir #include "vcl/decoview.hxx"
30*cdf0e10cSrcweir #include "vcl/svapp.hxx"
31*cdf0e10cSrcweir #include "vcl/timer.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "aqua/salconst.h"
34*cdf0e10cSrcweir #include "aqua/salgdi.h"
35*cdf0e10cSrcweir #include "aqua/salnativewidgets.h"
36*cdf0e10cSrcweir #include "aqua/saldata.hxx"
37*cdf0e10cSrcweir #include "aqua/salframe.h"
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include "premac.h"
40*cdf0e10cSrcweir #include <Carbon/Carbon.h>
41*cdf0e10cSrcweir #include "postmac.h"
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir class AquaBlinker : public Timer
44*cdf0e10cSrcweir {
45*cdf0e10cSrcweir     AquaSalFrame*       mpFrame;
46*cdf0e10cSrcweir     Rectangle           maInvalidateRect;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir     AquaBlinker( AquaSalFrame* pFrame, const Rectangle& rRect )
49*cdf0e10cSrcweir     : mpFrame( pFrame ), maInvalidateRect( rRect )
50*cdf0e10cSrcweir     {
51*cdf0e10cSrcweir         mpFrame->maBlinkers.push_back( this );
52*cdf0e10cSrcweir     }
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir     public:
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir     static void Blink( AquaSalFrame*, const Rectangle&, int nTimeout = 80 );
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir     virtual void Timeout()
59*cdf0e10cSrcweir     {
60*cdf0e10cSrcweir         Stop();
61*cdf0e10cSrcweir         if( AquaSalFrame::isAlive( mpFrame ) && mpFrame->mbShown )
62*cdf0e10cSrcweir         {
63*cdf0e10cSrcweir             mpFrame->maBlinkers.remove( this );
64*cdf0e10cSrcweir             mpFrame->SendPaintEvent( &maInvalidateRect );
65*cdf0e10cSrcweir         }
66*cdf0e10cSrcweir         delete this;
67*cdf0e10cSrcweir     }
68*cdf0e10cSrcweir };
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir void AquaBlinker::Blink( AquaSalFrame* pFrame, const Rectangle& rRect, int nTimeout )
71*cdf0e10cSrcweir {
72*cdf0e10cSrcweir     // prevent repeated paints from triggering themselves all the time
73*cdf0e10cSrcweir     for( std::list< AquaBlinker* >::const_iterator it = pFrame->maBlinkers.begin();
74*cdf0e10cSrcweir          it != pFrame->maBlinkers.end(); ++it )
75*cdf0e10cSrcweir     {
76*cdf0e10cSrcweir         if( (*it)->maInvalidateRect == rRect )
77*cdf0e10cSrcweir             return;
78*cdf0e10cSrcweir     }
79*cdf0e10cSrcweir     AquaBlinker* pNew = new AquaBlinker( pFrame, rRect );
80*cdf0e10cSrcweir     pNew->SetTimeout( nTimeout );
81*cdf0e10cSrcweir     pNew->Start();
82*cdf0e10cSrcweir }
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir ControlPart ImplgetCounterPart( ControlPart nPart )
85*cdf0e10cSrcweir {
86*cdf0e10cSrcweir     ControlPart nCounterPart = 0;
87*cdf0e10cSrcweir     switch (nPart)
88*cdf0e10cSrcweir     {
89*cdf0e10cSrcweir         case PART_BUTTON_UP:
90*cdf0e10cSrcweir             nCounterPart = PART_BUTTON_DOWN;
91*cdf0e10cSrcweir             break;
92*cdf0e10cSrcweir         case PART_BUTTON_DOWN:
93*cdf0e10cSrcweir             nCounterPart = PART_BUTTON_UP;
94*cdf0e10cSrcweir             break;
95*cdf0e10cSrcweir         case PART_BUTTON_LEFT:
96*cdf0e10cSrcweir             nCounterPart = PART_BUTTON_RIGHT;
97*cdf0e10cSrcweir             break;
98*cdf0e10cSrcweir         case PART_BUTTON_RIGHT:
99*cdf0e10cSrcweir             nCounterPart = PART_BUTTON_LEFT;
100*cdf0e10cSrcweir             break;
101*cdf0e10cSrcweir     }
102*cdf0e10cSrcweir     return nCounterPart;
103*cdf0e10cSrcweir }
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir // Helper returns an HIRect
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir static HIRect ImplGetHIRectFromRectangle(Rectangle aRect)
109*cdf0e10cSrcweir {
110*cdf0e10cSrcweir     HIRect aHIRect;
111*cdf0e10cSrcweir     aHIRect.origin.x = static_cast<float>(aRect.Left());
112*cdf0e10cSrcweir     aHIRect.origin.y = static_cast<float>(aRect.Top());
113*cdf0e10cSrcweir     aHIRect.size.width = static_cast<float>(aRect.GetWidth());
114*cdf0e10cSrcweir     aHIRect.size.height = static_cast<float>(aRect.GetHeight());
115*cdf0e10cSrcweir 	return aHIRect;
116*cdf0e10cSrcweir }
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir static ThemeButtonValue ImplGetButtonValue( ButtonValue aButtonValue )
119*cdf0e10cSrcweir {
120*cdf0e10cSrcweir     switch( aButtonValue )
121*cdf0e10cSrcweir     {
122*cdf0e10cSrcweir         case BUTTONVALUE_ON:
123*cdf0e10cSrcweir             return kThemeButtonOn;
124*cdf0e10cSrcweir             break;
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir         case BUTTONVALUE_OFF:
127*cdf0e10cSrcweir             return kThemeButtonOff;
128*cdf0e10cSrcweir             break;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir         case BUTTONVALUE_MIXED:
131*cdf0e10cSrcweir         case BUTTONVALUE_DONTKNOW:
132*cdf0e10cSrcweir         default:
133*cdf0e10cSrcweir             return kThemeButtonMixed;
134*cdf0e10cSrcweir             break;
135*cdf0e10cSrcweir     }
136*cdf0e10cSrcweir }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir static bool AquaGetScrollRect( /* TODO: int nScreen, */  ControlPart nPart,
139*cdf0e10cSrcweir 	const Rectangle& rControlRect, Rectangle& rResultRect )
140*cdf0e10cSrcweir {
141*cdf0e10cSrcweir 	bool bRetVal = true;
142*cdf0e10cSrcweir     rResultRect = rControlRect;
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir     switch( nPart )
145*cdf0e10cSrcweir     {
146*cdf0e10cSrcweir         case PART_BUTTON_UP:
147*cdf0e10cSrcweir 			if( GetSalData()->mbIsScrollbarDoubleMax )
148*cdf0e10cSrcweir 				rResultRect.Top() = rControlRect.Bottom() - 2*BUTTON_HEIGHT;
149*cdf0e10cSrcweir             rResultRect.Bottom() = rResultRect.Top() + BUTTON_HEIGHT;
150*cdf0e10cSrcweir             break;
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir         case PART_BUTTON_DOWN:
153*cdf0e10cSrcweir             rResultRect.Top() = rControlRect.Bottom() - BUTTON_HEIGHT;
154*cdf0e10cSrcweir             break;
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir         case PART_BUTTON_LEFT:
157*cdf0e10cSrcweir 			if( GetSalData()->mbIsScrollbarDoubleMax )
158*cdf0e10cSrcweir 				rResultRect.Left() = rControlRect.Right() - 2*BUTTON_WIDTH;
159*cdf0e10cSrcweir 			rResultRect.Right() = rResultRect.Left() + BUTTON_WIDTH;
160*cdf0e10cSrcweir 			break;
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir         case PART_BUTTON_RIGHT:
163*cdf0e10cSrcweir 			rResultRect.Left() = rControlRect.Right() - BUTTON_WIDTH;
164*cdf0e10cSrcweir             break;
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir         case PART_TRACK_HORZ_AREA:
167*cdf0e10cSrcweir             rResultRect.Right() -= BUTTON_WIDTH + 1;
168*cdf0e10cSrcweir 			if( GetSalData()->mbIsScrollbarDoubleMax )
169*cdf0e10cSrcweir 				rResultRect.Right() -= BUTTON_WIDTH;
170*cdf0e10cSrcweir 			else
171*cdf0e10cSrcweir 				rResultRect.Left() += BUTTON_WIDTH + 1;
172*cdf0e10cSrcweir             break;
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir         case PART_TRACK_VERT_AREA:
175*cdf0e10cSrcweir             rResultRect.Bottom() -= BUTTON_HEIGHT + 1;
176*cdf0e10cSrcweir 			if( GetSalData()->mbIsScrollbarDoubleMax )
177*cdf0e10cSrcweir 				rResultRect.Bottom() -= BUTTON_HEIGHT;
178*cdf0e10cSrcweir 			else
179*cdf0e10cSrcweir 				rResultRect.Top() += BUTTON_HEIGHT + 1;
180*cdf0e10cSrcweir             break;
181*cdf0e10cSrcweir         case PART_THUMB_HORZ:
182*cdf0e10cSrcweir             if( GetSalData()->mbIsScrollbarDoubleMax )
183*cdf0e10cSrcweir             {
184*cdf0e10cSrcweir                 rResultRect.Left() += 8;
185*cdf0e10cSrcweir                 rResultRect.Right() += 6;
186*cdf0e10cSrcweir             }
187*cdf0e10cSrcweir             else
188*cdf0e10cSrcweir             {
189*cdf0e10cSrcweir                 rResultRect.Left() += 4;
190*cdf0e10cSrcweir                 rResultRect.Right() += 4;
191*cdf0e10cSrcweir             }
192*cdf0e10cSrcweir             break;
193*cdf0e10cSrcweir         case PART_THUMB_VERT:
194*cdf0e10cSrcweir             if( GetSalData()->mbIsScrollbarDoubleMax )
195*cdf0e10cSrcweir             {
196*cdf0e10cSrcweir                 rResultRect.Top() += 8;
197*cdf0e10cSrcweir                 rResultRect.Bottom() += 8;
198*cdf0e10cSrcweir             }
199*cdf0e10cSrcweir             else
200*cdf0e10cSrcweir             {
201*cdf0e10cSrcweir                 rResultRect.Top() += 4;
202*cdf0e10cSrcweir                 rResultRect.Bottom() += 4;
203*cdf0e10cSrcweir             }
204*cdf0e10cSrcweir             break;
205*cdf0e10cSrcweir         case PART_TRACK_HORZ_LEFT:
206*cdf0e10cSrcweir             if( GetSalData()->mbIsScrollbarDoubleMax )
207*cdf0e10cSrcweir                 rResultRect.Right() += 8;
208*cdf0e10cSrcweir             else
209*cdf0e10cSrcweir                 rResultRect.Right() += 4;
210*cdf0e10cSrcweir             break;
211*cdf0e10cSrcweir         case PART_TRACK_HORZ_RIGHT:
212*cdf0e10cSrcweir             if( GetSalData()->mbIsScrollbarDoubleMax )
213*cdf0e10cSrcweir                 rResultRect.Left() += 6;
214*cdf0e10cSrcweir             else
215*cdf0e10cSrcweir                 rResultRect.Left() += 4;
216*cdf0e10cSrcweir             break;
217*cdf0e10cSrcweir         case PART_TRACK_VERT_UPPER:
218*cdf0e10cSrcweir             if( GetSalData()->mbIsScrollbarDoubleMax )
219*cdf0e10cSrcweir                 rResultRect.Bottom() += 8;
220*cdf0e10cSrcweir             else
221*cdf0e10cSrcweir                 rResultRect.Bottom() += 4;
222*cdf0e10cSrcweir             break;
223*cdf0e10cSrcweir         case PART_TRACK_VERT_LOWER:
224*cdf0e10cSrcweir             if( GetSalData()->mbIsScrollbarDoubleMax )
225*cdf0e10cSrcweir                 rResultRect.Top() += 8;
226*cdf0e10cSrcweir             else
227*cdf0e10cSrcweir                 rResultRect.Top() += 4;
228*cdf0e10cSrcweir             break;
229*cdf0e10cSrcweir 		default:
230*cdf0e10cSrcweir 			bRetVal = false;
231*cdf0e10cSrcweir     }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 	return bRetVal;
234*cdf0e10cSrcweir }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir /*
237*cdf0e10cSrcweir  * IsNativeControlSupported()
238*cdf0e10cSrcweir  * --------------------------
239*cdf0e10cSrcweir  * Returns sal_True if the platform supports native
240*cdf0e10cSrcweir  * drawing of the control defined by nPart.
241*cdf0e10cSrcweir  *
242*cdf0e10cSrcweir  */
243*cdf0e10cSrcweir sal_Bool AquaSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
244*cdf0e10cSrcweir {
245*cdf0e10cSrcweir     bool bOk = sal_False;
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir     // Native controls are now defaults
248*cdf0e10cSrcweir     // If you want to disable experimental native controls code,
249*cdf0e10cSrcweir     // just set the environment variable SAL_NO_NWF to something
250*cdf0e10cSrcweir     // and vcl controls will be used as default again.
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir     switch( nType )
253*cdf0e10cSrcweir     {
254*cdf0e10cSrcweir         case CTRL_PUSHBUTTON:
255*cdf0e10cSrcweir         case CTRL_RADIOBUTTON:
256*cdf0e10cSrcweir         case CTRL_CHECKBOX:
257*cdf0e10cSrcweir         case CTRL_LISTNODE:
258*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
259*cdf0e10cSrcweir                 return true;
260*cdf0e10cSrcweir             break;
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir         case CTRL_SCROLLBAR:
263*cdf0e10cSrcweir             if( nPart == PART_DRAW_BACKGROUND_HORZ ||
264*cdf0e10cSrcweir                 nPart == PART_DRAW_BACKGROUND_VERT ||
265*cdf0e10cSrcweir                 nPart == PART_ENTIRE_CONTROL       ||
266*cdf0e10cSrcweir                 nPart == HAS_THREE_BUTTONS )
267*cdf0e10cSrcweir                 return true;
268*cdf0e10cSrcweir             break;
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir         case CTRL_SLIDER:
271*cdf0e10cSrcweir             if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA )
272*cdf0e10cSrcweir                 return true;
273*cdf0e10cSrcweir             break;
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir         case CTRL_EDITBOX:
276*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL ||
277*cdf0e10cSrcweir                 nPart == HAS_BACKGROUND_TEXTURE )
278*cdf0e10cSrcweir                 return true;
279*cdf0e10cSrcweir             break;
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir         case CTRL_MULTILINE_EDITBOX:
282*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL ||
283*cdf0e10cSrcweir                 nPart == HAS_BACKGROUND_TEXTURE )
284*cdf0e10cSrcweir                 return true;
285*cdf0e10cSrcweir             break;
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir         case CTRL_SPINBOX:
288*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL ||
289*cdf0e10cSrcweir                 nPart == PART_ALL_BUTTONS    ||
290*cdf0e10cSrcweir                 nPart == HAS_BACKGROUND_TEXTURE )
291*cdf0e10cSrcweir                 return true;
292*cdf0e10cSrcweir             break;
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir         case CTRL_SPINBUTTONS:
295*cdf0e10cSrcweir                 return false;
296*cdf0e10cSrcweir             break;
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir 		case CTRL_COMBOBOX:
299*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL ||
300*cdf0e10cSrcweir                 nPart == HAS_BACKGROUND_TEXTURE )
301*cdf0e10cSrcweir                 return true;
302*cdf0e10cSrcweir             break;
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir         case CTRL_LISTBOX:
305*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL    ||
306*cdf0e10cSrcweir                 nPart == PART_WINDOW            ||
307*cdf0e10cSrcweir                 nPart == HAS_BACKGROUND_TEXTURE ||
308*cdf0e10cSrcweir                 nPart == PART_SUB_EDIT
309*cdf0e10cSrcweir                 )
310*cdf0e10cSrcweir                 return true;
311*cdf0e10cSrcweir             break;
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir         case CTRL_TAB_ITEM:
314*cdf0e10cSrcweir         case CTRL_TAB_PANE:
315*cdf0e10cSrcweir         case CTRL_TAB_BODY:  // see vcl/source/window/tabpage.cxx
316*cdf0e10cSrcweir         case CTRL_FIXEDBORDER:
317*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL ||
318*cdf0e10cSrcweir                 nPart == PART_TABS_DRAW_RTL ||
319*cdf0e10cSrcweir                 nPart == HAS_BACKGROUND_TEXTURE )
320*cdf0e10cSrcweir                 return true;
321*cdf0e10cSrcweir             break;
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir         // when PART_BUTTON is used, toolbar icons are not highlighted when mouse rolls over.
324*cdf0e10cSrcweir         // More Aqua compliant
325*cdf0e10cSrcweir         case CTRL_TOOLBAR:
326*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL       ||
327*cdf0e10cSrcweir                 nPart == PART_DRAW_BACKGROUND_HORZ ||
328*cdf0e10cSrcweir                 nPart == PART_DRAW_BACKGROUND_VERT)
329*cdf0e10cSrcweir                 return true;
330*cdf0e10cSrcweir             break;
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir         case  CTRL_WINDOW_BACKGROUND:
333*cdf0e10cSrcweir             if ( nPart == PART_BACKGROUND_WINDOW ||
334*cdf0e10cSrcweir                  nPart == PART_BACKGROUND_DIALOG )
335*cdf0e10cSrcweir                  return true;
336*cdf0e10cSrcweir             break;
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir         case CTRL_MENUBAR:
339*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
340*cdf0e10cSrcweir                 return true;
341*cdf0e10cSrcweir             break;
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir         case CTRL_TOOLTIP: // ** TO DO
344*cdf0e10cSrcweir             #if 0
345*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL ) // we don't currently support the tooltip
346*cdf0e10cSrcweir                 return true;
347*cdf0e10cSrcweir             #endif
348*cdf0e10cSrcweir             break;
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir         case CTRL_MENU_POPUP:
351*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL       ||
352*cdf0e10cSrcweir                 nPart == PART_MENU_ITEM            ||
353*cdf0e10cSrcweir                 nPart == PART_MENU_ITEM_CHECK_MARK ||
354*cdf0e10cSrcweir                 nPart == PART_MENU_ITEM_RADIO_MARK)
355*cdf0e10cSrcweir                 return true;
356*cdf0e10cSrcweir             break;
357*cdf0e10cSrcweir         case CTRL_PROGRESS:
358*cdf0e10cSrcweir         case CTRL_INTROPROGRESS:
359*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
360*cdf0e10cSrcweir                 return true;
361*cdf0e10cSrcweir             break;
362*cdf0e10cSrcweir         case CTRL_FRAME:
363*cdf0e10cSrcweir             if( nPart == PART_BORDER )
364*cdf0e10cSrcweir                 return true;
365*cdf0e10cSrcweir             break;
366*cdf0e10cSrcweir         case CTRL_LISTNET:
367*cdf0e10cSrcweir             if( nPart == PART_ENTIRE_CONTROL )
368*cdf0e10cSrcweir                 return true;
369*cdf0e10cSrcweir             break;
370*cdf0e10cSrcweir     }
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir     return bOk;
373*cdf0e10cSrcweir }
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir /*
376*cdf0e10cSrcweir  * HitTestNativeControl()
377*cdf0e10cSrcweir  *
378*cdf0e10cSrcweir  *  If the return value is sal_True, bIsInside contains information whether
379*cdf0e10cSrcweir  *  aPos was or was not inside the native widget specified by the
380*cdf0e10cSrcweir  *  nType/nPart combination.
381*cdf0e10cSrcweir  */
382*cdf0e10cSrcweir sal_Bool AquaSalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
383*cdf0e10cSrcweir 					    const Point& rPos, sal_Bool& rIsInside )
384*cdf0e10cSrcweir {
385*cdf0e10cSrcweir     if ( nType == CTRL_SCROLLBAR )
386*cdf0e10cSrcweir     {
387*cdf0e10cSrcweir 		Rectangle aRect;
388*cdf0e10cSrcweir 		bool bValid = AquaGetScrollRect( /* TODO: m_nScreen */ nPart, rControlRegion, aRect );
389*cdf0e10cSrcweir 		rIsInside = bValid ? aRect.IsInside( rPos ) : sal_False;
390*cdf0e10cSrcweir         if( GetSalData()->mbIsScrollbarDoubleMax )
391*cdf0e10cSrcweir         {
392*cdf0e10cSrcweir             // in double max mode the actual trough is a little smaller than the track
393*cdf0e10cSrcweir             // there is some visual filler that is not sensitive
394*cdf0e10cSrcweir             if( bValid && rIsInside )
395*cdf0e10cSrcweir             {
396*cdf0e10cSrcweir                 if( nPart == PART_TRACK_HORZ_AREA )
397*cdf0e10cSrcweir                 {
398*cdf0e10cSrcweir                     // the left 4 pixels are not hit sensitive
399*cdf0e10cSrcweir                     if( rPos.X() - aRect.Left() < 4 )
400*cdf0e10cSrcweir                         rIsInside = sal_False;
401*cdf0e10cSrcweir                 }
402*cdf0e10cSrcweir                 else if( nPart == PART_TRACK_VERT_AREA )
403*cdf0e10cSrcweir                 {
404*cdf0e10cSrcweir                     // the top 4 pixels are not hit sensitive
405*cdf0e10cSrcweir                     if( rPos.Y() - aRect.Top() < 4 )
406*cdf0e10cSrcweir                         rIsInside = sal_False;
407*cdf0e10cSrcweir                 }
408*cdf0e10cSrcweir             }
409*cdf0e10cSrcweir         }
410*cdf0e10cSrcweir 		return bValid;
411*cdf0e10cSrcweir     }  //  CTRL_SCROLLBAR
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir     return sal_False;
414*cdf0e10cSrcweir }
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir /*
417*cdf0e10cSrcweir   kThemeStateInactive = 0,
418*cdf0e10cSrcweir    kThemeStateActive = 1,
419*cdf0e10cSrcweir    kThemeStatePressed = 2,
420*cdf0e10cSrcweir    kThemeStateRollover = 6,
421*cdf0e10cSrcweir    kThemeStateUnavailable = 7,
422*cdf0e10cSrcweir    kThemeStateUnavailableInactive = 8
423*cdf0e10cSrcweir    kThemeStatePressedUp = 2,
424*cdf0e10cSrcweir    kThemeStatePressedDown = 3
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir #define CTRL_STATE_ENABLED		0x0001
427*cdf0e10cSrcweir #define CTRL_STATE_FOCUSED		0x0002
428*cdf0e10cSrcweir #define CTRL_STATE_PRESSED		0x0004
429*cdf0e10cSrcweir #define CTRL_STATE_ROLLOVER		0x0008
430*cdf0e10cSrcweir #define CTRL_STATE_HIDDEN		0x0010
431*cdf0e10cSrcweir #define CTRL_STATE_DEFAULT		0x0020
432*cdf0e10cSrcweir #define CTRL_STATE_SELECTED		0x0040
433*cdf0e10cSrcweir #define CTRL_CACHING_ALLOWED	0x8000  // set when the control is completely visible (i.e. not clipped)
434*cdf0e10cSrcweir */
435*cdf0e10cSrcweir UInt32 AquaSalGraphics::getState( ControlState nState )
436*cdf0e10cSrcweir {
437*cdf0e10cSrcweir     bool bDrawActive = mpFrame ? ([mpFrame->getWindow() isKeyWindow] ? true : false) : true;
438*cdf0e10cSrcweir     if( (nState & CTRL_STATE_ENABLED) == 0 || ! bDrawActive )
439*cdf0e10cSrcweir     {
440*cdf0e10cSrcweir         if( (nState & CTRL_STATE_HIDDEN) == 0 )
441*cdf0e10cSrcweir             return kThemeStateInactive;
442*cdf0e10cSrcweir         else
443*cdf0e10cSrcweir             return kThemeStateUnavailableInactive;
444*cdf0e10cSrcweir     }
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir     if( (nState & CTRL_STATE_HIDDEN) != 0 )
447*cdf0e10cSrcweir         return kThemeStateUnavailable;
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir     if( (nState & CTRL_STATE_PRESSED) != 0 )
450*cdf0e10cSrcweir         return kThemeStatePressed;
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir     return kThemeStateActive;
453*cdf0e10cSrcweir }
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir UInt32 AquaSalGraphics::getTrackState( ControlState nState )
456*cdf0e10cSrcweir {
457*cdf0e10cSrcweir     bool bDrawActive = mpFrame ? ([mpFrame->getWindow() isKeyWindow] ? true : false) : true;
458*cdf0e10cSrcweir     if( (nState & CTRL_STATE_ENABLED) == 0 || ! bDrawActive )
459*cdf0e10cSrcweir             return kThemeTrackInactive;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir     return kThemeTrackActive;
462*cdf0e10cSrcweir }
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir /*
465*cdf0e10cSrcweir  * DrawNativeControl()
466*cdf0e10cSrcweir  *
467*cdf0e10cSrcweir  *  Draws the requested control described by nPart/nState.
468*cdf0e10cSrcweir  *
469*cdf0e10cSrcweir  *  rControlRegion:	The bounding region of the complete control in VCL frame coordinates.
470*cdf0e10cSrcweir  *  aValue:		An optional value (tristate/numerical/string)
471*cdf0e10cSrcweir  *  aCaption:	A caption or title string (like button text etc)
472*cdf0e10cSrcweir  */
473*cdf0e10cSrcweir sal_Bool AquaSalGraphics::drawNativeControl(ControlType nType,
474*cdf0e10cSrcweir 					ControlPart nPart,
475*cdf0e10cSrcweir 					const Rectangle& rControlRegion,
476*cdf0e10cSrcweir 					ControlState nState,
477*cdf0e10cSrcweir 					const ImplControlValue& aValue,
478*cdf0e10cSrcweir 					const rtl::OUString& )
479*cdf0e10cSrcweir {
480*cdf0e10cSrcweir     sal_Bool bOK = sal_False;
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir     if( ! CheckContext() )
483*cdf0e10cSrcweir         return false;
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir     CGContextSaveGState( mrContext );
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir     Rectangle buttonRect = rControlRegion;
488*cdf0e10cSrcweir 	HIRect rc = ImplGetHIRectFromRectangle(buttonRect);
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir     /** Scrollbar parts code equivalent **
491*cdf0e10cSrcweir     PART_BUTTON_UP 101
492*cdf0e10cSrcweir     PART_BUTTON_DOWN 102
493*cdf0e10cSrcweir 	PART_THUMB_VERT 211
494*cdf0e10cSrcweir 	PART_TRACK_VERT_UPPER 201
495*cdf0e10cSrcweir 	PART_TRACK_VERT_LOWER 203
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir 	PART_DRAW_BACKGROUND_HORZ 1000
498*cdf0e10cSrcweir 	PART_DRAW_BACKGROUND_VERT 1001
499*cdf0e10cSrcweir     **/
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir     switch( nType )
502*cdf0e10cSrcweir     {
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir     case  CTRL_COMBOBOX:
505*cdf0e10cSrcweir         if ( nPart == HAS_BACKGROUND_TEXTURE ||
506*cdf0e10cSrcweir              nPart == PART_ENTIRE_CONTROL )
507*cdf0e10cSrcweir         {
508*cdf0e10cSrcweir             HIThemeButtonDrawInfo aComboInfo;
509*cdf0e10cSrcweir             aComboInfo.version = 0;
510*cdf0e10cSrcweir             aComboInfo.kind = kThemeComboBox;
511*cdf0e10cSrcweir             aComboInfo.state = getState( nState );
512*cdf0e10cSrcweir             aComboInfo.value = kThemeButtonOn;
513*cdf0e10cSrcweir             aComboInfo.adornment = kThemeAdornmentNone;
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir             if( (nState & CTRL_STATE_FOCUSED) != 0 )
516*cdf0e10cSrcweir                 aComboInfo.adornment |= kThemeAdornmentFocus;
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir             HIThemeDrawButton(&rc, &aComboInfo, mrContext, kHIThemeOrientationNormal,&rc);
519*cdf0e10cSrcweir             bOK = true;
520*cdf0e10cSrcweir         }
521*cdf0e10cSrcweir         break;
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir     case CTRL_FIXEDBORDER:
524*cdf0e10cSrcweir     case CTRL_TOOLBAR:
525*cdf0e10cSrcweir         {
526*cdf0e10cSrcweir             HIThemeMenuItemDrawInfo aMenuItemDrawInfo;
527*cdf0e10cSrcweir             aMenuItemDrawInfo.version = 0;
528*cdf0e10cSrcweir             aMenuItemDrawInfo.state = kThemeMenuActive;
529*cdf0e10cSrcweir             aMenuItemDrawInfo.itemType = kThemeMenuItemHierBackground;
530*cdf0e10cSrcweir             HIThemeDrawMenuItem(&rc,&rc,&aMenuItemDrawInfo,mrContext,kHIThemeOrientationNormal,NULL);
531*cdf0e10cSrcweir             bOK = true;
532*cdf0e10cSrcweir         }
533*cdf0e10cSrcweir         break;
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir         case CTRL_WINDOW_BACKGROUND:
536*cdf0e10cSrcweir         {
537*cdf0e10cSrcweir             HIThemeBackgroundDrawInfo aThemeBackgroundInfo;
538*cdf0e10cSrcweir             aThemeBackgroundInfo.version = 0;
539*cdf0e10cSrcweir             aThemeBackgroundInfo.state = getState( nState );
540*cdf0e10cSrcweir             aThemeBackgroundInfo.kind = kThemeBrushDialogBackgroundInactive;
541*cdf0e10cSrcweir             // FIXME: without this magical offset there is a 2 pixel black border on the right and bottom
542*cdf0e10cSrcweir             rc.size.width += 2;
543*cdf0e10cSrcweir             rc.size.height += 2;
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir             HIThemeApplyBackground( &rc, &aThemeBackgroundInfo, mrContext, kHIThemeOrientationNormal);
546*cdf0e10cSrcweir             CGContextFillRect( mrContext, rc );
547*cdf0e10cSrcweir             bOK = true;
548*cdf0e10cSrcweir         }
549*cdf0e10cSrcweir         break;
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir     case CTRL_MENUBAR:
552*cdf0e10cSrcweir     case CTRL_MENU_POPUP:
553*cdf0e10cSrcweir         {
554*cdf0e10cSrcweir             if ((nPart == PART_ENTIRE_CONTROL) || (nPart == PART_MENU_ITEM )|| (nPart == HAS_BACKGROUND_TEXTURE ))
555*cdf0e10cSrcweir             {
556*cdf0e10cSrcweir                 // FIXME: without this magical offset there is a 2 pixel black border on the right
557*cdf0e10cSrcweir                 rc.size.width += 2;
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir                 HIThemeMenuDrawInfo aMenuInfo;
560*cdf0e10cSrcweir                 aMenuInfo.version = 0;
561*cdf0e10cSrcweir                 aMenuInfo.menuType = kThemeMenuTypePullDown;
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir                 HIThemeMenuItemDrawInfo aMenuItemDrawInfo;
564*cdf0e10cSrcweir                 // the Aqua grey theme when the item is selected is drawn here.
565*cdf0e10cSrcweir                 aMenuItemDrawInfo.itemType = kThemeMenuItemPlain;
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir                 if ((nPart == PART_MENU_ITEM ) && (nState & CTRL_STATE_SELECTED))
568*cdf0e10cSrcweir                 {
569*cdf0e10cSrcweir                     // the blue theme when the item is selected is drawn here.
570*cdf0e10cSrcweir                     aMenuItemDrawInfo.state = kThemeMenuSelected;
571*cdf0e10cSrcweir                 }
572*cdf0e10cSrcweir                 else
573*cdf0e10cSrcweir                 {
574*cdf0e10cSrcweir                     // normal color for non selected item
575*cdf0e10cSrcweir                     aMenuItemDrawInfo.state = kThemeMenuActive;
576*cdf0e10cSrcweir                 }
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir                 // repaints the background of the pull down menu
579*cdf0e10cSrcweir                 HIThemeDrawMenuBackground(&rc,&aMenuInfo,mrContext,kHIThemeOrientationNormal);
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir                 // repaints the item either blue (selected) and/or Aqua grey (active only)
582*cdf0e10cSrcweir                 HIThemeDrawMenuItem(&rc,&rc,&aMenuItemDrawInfo,mrContext,kHIThemeOrientationNormal,&rc);
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir                 bOK = true;
585*cdf0e10cSrcweir             }
586*cdf0e10cSrcweir             else if(( nPart == PART_MENU_ITEM_CHECK_MARK )||( nPart == PART_MENU_ITEM_RADIO_MARK )) {
587*cdf0e10cSrcweir                 if( nState & CTRL_STATE_PRESSED ) {//checked, else it is not displayed (see vcl/source/window/menu.cxx)
588*cdf0e10cSrcweir                     HIThemeTextInfo aTextInfo;
589*cdf0e10cSrcweir                     aTextInfo.version = 0;
590*cdf0e10cSrcweir                     aTextInfo.state = ((nState & CTRL_STATE_ENABLED)==0) ? kThemeStateInactive: kThemeStateActive;
591*cdf0e10cSrcweir                     aTextInfo.fontID = kThemeMenuItemMarkFont;
592*cdf0e10cSrcweir                     aTextInfo.horizontalFlushness=kHIThemeTextHorizontalFlushCenter;
593*cdf0e10cSrcweir                     aTextInfo.verticalFlushness=kHIThemeTextVerticalFlushTop;
594*cdf0e10cSrcweir                     aTextInfo.options=kHIThemeTextBoxOptionNone;
595*cdf0e10cSrcweir                     aTextInfo.truncationPosition=kHIThemeTextTruncationNone;
596*cdf0e10cSrcweir                     //aTextInfo.truncationMaxLines unused because of kHIThemeTextTruncationNone
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir                     if( nState & CTRL_STATE_SELECTED) aTextInfo.state = kThemeStatePressed; //item highlighted
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir                     UniChar mark=( nPart == PART_MENU_ITEM_CHECK_MARK ) ? kCheckUnicode: kBulletUnicode;//0x2713;
601*cdf0e10cSrcweir                     CFStringRef cfString = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &mark, 1, kCFAllocatorNull);
602*cdf0e10cSrcweir                     HIThemeDrawTextBox(cfString, &rc, &aTextInfo, mrContext, kHIThemeOrientationNormal);
603*cdf0e10cSrcweir 					if (cfString)
604*cdf0e10cSrcweir 						CFRelease(cfString);
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir                     bOK = true;
607*cdf0e10cSrcweir                 }
608*cdf0e10cSrcweir             }
609*cdf0e10cSrcweir         }
610*cdf0e10cSrcweir         break;
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir     case CTRL_PUSHBUTTON:
613*cdf0e10cSrcweir         {
614*cdf0e10cSrcweir             // [ FIXME] : instead of use a value, vcl can retrieve corect values on the fly (to be implemented)
615*cdf0e10cSrcweir             const int PB_Mini_Height = 15;
616*cdf0e10cSrcweir             const int PB_Norm_Height = 21;
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir             HIThemeButtonDrawInfo aPushInfo;
619*cdf0e10cSrcweir             aPushInfo.version = 0;
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir             // no animation
622*cdf0e10cSrcweir             aPushInfo.animation.time.start = 0;
623*cdf0e10cSrcweir             aPushInfo.animation.time.current = 0;
624*cdf0e10cSrcweir             PushButtonValue* pPBVal = aValue.getType() == CTRL_PUSHBUTTON ? (PushButtonValue*)&aValue : NULL;
625*cdf0e10cSrcweir             int nPaintHeight = static_cast<int>(rc.size.height);
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir             if( pPBVal && pPBVal->mbBevelButton )
628*cdf0e10cSrcweir             {
629*cdf0e10cSrcweir                 aPushInfo.kind = kThemeRoundedBevelButton;
630*cdf0e10cSrcweir             }
631*cdf0e10cSrcweir             else if( rc.size.height <= PB_Norm_Height )
632*cdf0e10cSrcweir             {
633*cdf0e10cSrcweir                 aPushInfo.kind = kThemePushButtonMini;
634*cdf0e10cSrcweir                 nPaintHeight = PB_Mini_Height;
635*cdf0e10cSrcweir             }
636*cdf0e10cSrcweir             else if( pPBVal->mbSingleLine || rc.size.height < (PB_Norm_Height + PB_Norm_Height/2) )
637*cdf0e10cSrcweir             {
638*cdf0e10cSrcweir                 aPushInfo.kind = kThemePushButtonNormal;
639*cdf0e10cSrcweir                 nPaintHeight = PB_Norm_Height;
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir                 // avoid clipping when focused
642*cdf0e10cSrcweir                 rc.origin.x += FOCUS_RING_WIDTH/2;
643*cdf0e10cSrcweir                 rc.size.width -= FOCUS_RING_WIDTH;
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir                 if( (nState & CTRL_STATE_DEFAULT) != 0 )
646*cdf0e10cSrcweir                 {
647*cdf0e10cSrcweir                     AquaBlinker::Blink( mpFrame, buttonRect );
648*cdf0e10cSrcweir                     // show correct animation phase
649*cdf0e10cSrcweir                     aPushInfo.animation.time.current = CFAbsoluteTimeGetCurrent();
650*cdf0e10cSrcweir                 }
651*cdf0e10cSrcweir             }
652*cdf0e10cSrcweir             else
653*cdf0e10cSrcweir                 aPushInfo.kind = kThemeBevelButton;
654*cdf0e10cSrcweir 
655*cdf0e10cSrcweir             // translate the origin for controls with fixed paint height
656*cdf0e10cSrcweir             // so content ends up somewhere sensible
657*cdf0e10cSrcweir             int delta_y = static_cast<int>(rc.size.height) - nPaintHeight;
658*cdf0e10cSrcweir             rc.origin.y += delta_y/2;
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir             aPushInfo.state = getState( nState );
661*cdf0e10cSrcweir             aPushInfo.value = ImplGetButtonValue( aValue.getTristateVal() );
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir             aPushInfo.adornment = (( nState & CTRL_STATE_DEFAULT ) != 0) ?
664*cdf0e10cSrcweir             kThemeAdornmentDefault :
665*cdf0e10cSrcweir             kThemeAdornmentNone;
666*cdf0e10cSrcweir             if( (nState & CTRL_STATE_FOCUSED) != 0 )
667*cdf0e10cSrcweir                 aPushInfo.adornment |= kThemeAdornmentFocus;
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir             HIThemeDrawButton( &rc, &aPushInfo, mrContext, kHIThemeOrientationNormal, NULL );
670*cdf0e10cSrcweir             bOK = true;
671*cdf0e10cSrcweir         }
672*cdf0e10cSrcweir         break;
673*cdf0e10cSrcweir 
674*cdf0e10cSrcweir     case CTRL_RADIOBUTTON:
675*cdf0e10cSrcweir     case CTRL_CHECKBOX:
676*cdf0e10cSrcweir         {
677*cdf0e10cSrcweir             HIThemeButtonDrawInfo aInfo;
678*cdf0e10cSrcweir             aInfo.version = 0;
679*cdf0e10cSrcweir             switch( nType )
680*cdf0e10cSrcweir             {
681*cdf0e10cSrcweir             case CTRL_RADIOBUTTON: if(rc.size.width >= BUTTON_HEIGHT) aInfo.kind = kThemeRadioButton;
682*cdf0e10cSrcweir                                     else aInfo.kind = kThemeSmallRadioButton;
683*cdf0e10cSrcweir                 break;
684*cdf0e10cSrcweir             case CTRL_CHECKBOX:   if(rc.size.width >= BUTTON_HEIGHT) aInfo.kind = kThemeCheckBox;
685*cdf0e10cSrcweir                                     else aInfo.kind = kThemeSmallCheckBox;
686*cdf0e10cSrcweir                 break;
687*cdf0e10cSrcweir             }
688*cdf0e10cSrcweir 
689*cdf0e10cSrcweir             aInfo.state = getState( nState );
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir             ButtonValue aButtonValue = aValue.getTristateVal();
692*cdf0e10cSrcweir             aInfo.value = ImplGetButtonValue( aButtonValue );
693*cdf0e10cSrcweir 
694*cdf0e10cSrcweir             aInfo.adornment = (( nState & CTRL_STATE_DEFAULT ) != 0) ?
695*cdf0e10cSrcweir             kThemeAdornmentDefault :
696*cdf0e10cSrcweir             kThemeAdornmentNone;
697*cdf0e10cSrcweir             if( (nState & CTRL_STATE_FOCUSED) != 0 )
698*cdf0e10cSrcweir                 aInfo.adornment |= kThemeAdornmentFocus;
699*cdf0e10cSrcweir             HIThemeDrawButton( &rc, &aInfo, mrContext, kHIThemeOrientationNormal, NULL );
700*cdf0e10cSrcweir             bOK = true;
701*cdf0e10cSrcweir         }
702*cdf0e10cSrcweir         break;
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir     case CTRL_LISTNODE:
705*cdf0e10cSrcweir         {
706*cdf0e10cSrcweir             ButtonValue aButtonValue = aValue.getTristateVal();
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir             if( Application::GetSettings().GetLayoutRTL() && aButtonValue == BUTTONVALUE_OFF )
709*cdf0e10cSrcweir             {
710*cdf0e10cSrcweir                 // FIXME: a value of kThemeDisclosureLeft
711*cdf0e10cSrcweir                 // should draw a theme compliant left disclosure triangle
712*cdf0e10cSrcweir                 // sadly this does not seem to work, so we'll draw a left
713*cdf0e10cSrcweir                 // grey equilateral triangle here ourselves.
714*cdf0e10cSrcweir                 // Perhaps some other HIThemeButtonDrawInfo setting would do the trick ?
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir                 CGContextSetShouldAntialias( mrContext, true );
717*cdf0e10cSrcweir                 float aGrey[] = { 0.45, 0.45, 0.45, 1.0 };
718*cdf0e10cSrcweir                 CGContextSetFillColor( mrContext, aGrey );
719*cdf0e10cSrcweir                 CGContextBeginPath( mrContext );
720*cdf0e10cSrcweir                 float x = rc.origin.x + rc.size.width;
721*cdf0e10cSrcweir                 float y = rc.origin.y;
722*cdf0e10cSrcweir                 CGContextMoveToPoint( mrContext, x, y );
723*cdf0e10cSrcweir                 y += rc.size.height;
724*cdf0e10cSrcweir                 CGContextAddLineToPoint( mrContext, x, y );
725*cdf0e10cSrcweir                 x -= rc.size.height * 0.866; // cos( 30 degree ) is approx. 0.866
726*cdf0e10cSrcweir                 y -= rc.size.height/2;
727*cdf0e10cSrcweir                 CGContextAddLineToPoint( mrContext, x, y );
728*cdf0e10cSrcweir                 CGContextDrawPath( mrContext, kCGPathEOFill );
729*cdf0e10cSrcweir             }
730*cdf0e10cSrcweir             else
731*cdf0e10cSrcweir             {
732*cdf0e10cSrcweir                 HIThemeButtonDrawInfo aInfo;
733*cdf0e10cSrcweir                 aInfo.version = 0;
734*cdf0e10cSrcweir                 aInfo.kind = kThemeDisclosureTriangle;
735*cdf0e10cSrcweir                 aInfo.value = kThemeDisclosureRight;
736*cdf0e10cSrcweir                 aInfo.state = getState( nState );
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir                 aInfo.adornment = kThemeAdornmentNone;
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir                 switch( aButtonValue ) {
741*cdf0e10cSrcweir                     case BUTTONVALUE_ON: aInfo.value = kThemeDisclosureDown;//expanded
742*cdf0e10cSrcweir                         break;
743*cdf0e10cSrcweir                     case BUTTONVALUE_OFF:
744*cdf0e10cSrcweir                         // FIXME: this should have drawn a theme compliant disclosure triangle
745*cdf0e10cSrcweir                         // (see above)
746*cdf0e10cSrcweir                         if( Application::GetSettings().GetLayoutRTL() )
747*cdf0e10cSrcweir                         {
748*cdf0e10cSrcweir                             aInfo.value = kThemeDisclosureLeft;//collapsed, RTL
749*cdf0e10cSrcweir                         }
750*cdf0e10cSrcweir                         break;
751*cdf0e10cSrcweir                     case BUTTONVALUE_DONTKNOW: //what to do?
752*cdf0e10cSrcweir                     default:
753*cdf0e10cSrcweir                         break;
754*cdf0e10cSrcweir                 }
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir                 HIThemeDrawButton( &rc, &aInfo, mrContext, kHIThemeOrientationNormal, NULL );
757*cdf0e10cSrcweir             }
758*cdf0e10cSrcweir             bOK = true;
759*cdf0e10cSrcweir         }
760*cdf0e10cSrcweir         break;
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir     case CTRL_PROGRESS:
763*cdf0e10cSrcweir     case CTRL_INTROPROGRESS:
764*cdf0e10cSrcweir         {
765*cdf0e10cSrcweir             long nProgressWidth = aValue.getNumericVal();
766*cdf0e10cSrcweir             HIThemeTrackDrawInfo aTrackInfo;
767*cdf0e10cSrcweir             aTrackInfo.version              = 0;
768*cdf0e10cSrcweir             aTrackInfo.kind                 = (rc.size.height > 10) ? kThemeProgressBarLarge : kThemeProgressBarMedium;
769*cdf0e10cSrcweir             aTrackInfo.bounds               = rc;
770*cdf0e10cSrcweir             aTrackInfo.min                  = 0;
771*cdf0e10cSrcweir             aTrackInfo.max                  = static_cast<SInt32>(rc.size.width);
772*cdf0e10cSrcweir             aTrackInfo.value                = nProgressWidth;
773*cdf0e10cSrcweir             aTrackInfo.reserved             = 0;
774*cdf0e10cSrcweir             aTrackInfo.bounds.origin.y     -= 2; // FIXME: magic for shadow
775*cdf0e10cSrcweir             aTrackInfo.bounds.size.width   -= 2; // FIXME: magic for shadow
776*cdf0e10cSrcweir             aTrackInfo.attributes           = kThemeTrackHorizontal;
777*cdf0e10cSrcweir             if( Application::GetSettings().GetLayoutRTL() )
778*cdf0e10cSrcweir                 aTrackInfo.attributes      |= kThemeTrackRightToLeft;
779*cdf0e10cSrcweir             aTrackInfo.enableState          = getTrackState( nState );
780*cdf0e10cSrcweir             // the intro bitmap never gets key anyway; we want to draw that enabled
781*cdf0e10cSrcweir             if( nType == CTRL_INTROPROGRESS )
782*cdf0e10cSrcweir                 aTrackInfo.enableState          = kThemeTrackActive;
783*cdf0e10cSrcweir             aTrackInfo.filler1              = 0;
784*cdf0e10cSrcweir             aTrackInfo.trackInfo.progress.phase   = static_cast<UInt8>(CFAbsoluteTimeGetCurrent()*10.0);
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir             HIThemeDrawTrack( &aTrackInfo, NULL, mrContext, kHIThemeOrientationNormal );
787*cdf0e10cSrcweir             bOK = true;
788*cdf0e10cSrcweir         }
789*cdf0e10cSrcweir         break;
790*cdf0e10cSrcweir 
791*cdf0e10cSrcweir     case CTRL_SLIDER:
792*cdf0e10cSrcweir         {
793*cdf0e10cSrcweir             SliderValue* pSLVal = (SliderValue*)&aValue;
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir             HIThemeTrackDrawInfo aTrackDraw;
796*cdf0e10cSrcweir             aTrackDraw.kind = kThemeSliderMedium;
797*cdf0e10cSrcweir             if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA )
798*cdf0e10cSrcweir             {
799*cdf0e10cSrcweir                 aTrackDraw.bounds = rc;
800*cdf0e10cSrcweir                 aTrackDraw.min   = pSLVal->mnMin;
801*cdf0e10cSrcweir                 aTrackDraw.max   = pSLVal->mnMax;;
802*cdf0e10cSrcweir                 aTrackDraw.value = pSLVal->mnCur;
803*cdf0e10cSrcweir                 aTrackDraw.reserved = 0;
804*cdf0e10cSrcweir                 aTrackDraw.attributes = kThemeTrackShowThumb;
805*cdf0e10cSrcweir                 if( nPart == PART_TRACK_HORZ_AREA )
806*cdf0e10cSrcweir                     aTrackDraw.attributes |= kThemeTrackHorizontal;
807*cdf0e10cSrcweir                 aTrackDraw.enableState = (nState & CTRL_STATE_ENABLED)
808*cdf0e10cSrcweir                                          ? kThemeTrackActive : kThemeTrackInactive;
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir                 SliderTrackInfo aSlideInfo;
811*cdf0e10cSrcweir                 aSlideInfo.thumbDir = kThemeThumbUpward;
812*cdf0e10cSrcweir                 aSlideInfo.pressState = 0;
813*cdf0e10cSrcweir                 aTrackDraw.trackInfo.slider = aSlideInfo;
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir                 HIThemeDrawTrack( &aTrackDraw, NULL, mrContext, kHIThemeOrientationNormal );
816*cdf0e10cSrcweir                 bOK = true;
817*cdf0e10cSrcweir             }
818*cdf0e10cSrcweir         }
819*cdf0e10cSrcweir         break;
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir     case CTRL_SCROLLBAR:
822*cdf0e10cSrcweir         {
823*cdf0e10cSrcweir             ScrollbarValue* pScrollbarVal = (ScrollbarValue *)&aValue;
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir             if( nPart == PART_DRAW_BACKGROUND_VERT ||
826*cdf0e10cSrcweir                 nPart == PART_DRAW_BACKGROUND_HORZ )
827*cdf0e10cSrcweir             {
828*cdf0e10cSrcweir                 HIThemeTrackDrawInfo aTrackDraw;
829*cdf0e10cSrcweir                 aTrackDraw.kind = kThemeMediumScrollBar;
830*cdf0e10cSrcweir                 // FIXME: the scrollbar length must be adjusted
831*cdf0e10cSrcweir                 if (nPart == PART_DRAW_BACKGROUND_VERT)
832*cdf0e10cSrcweir                     rc.size.height += 2;
833*cdf0e10cSrcweir                 else
834*cdf0e10cSrcweir                     rc.size.width += 2;
835*cdf0e10cSrcweir 
836*cdf0e10cSrcweir                 aTrackDraw.bounds = rc;
837*cdf0e10cSrcweir                 aTrackDraw.min = pScrollbarVal->mnMin;
838*cdf0e10cSrcweir                 aTrackDraw.max = pScrollbarVal->mnMax - pScrollbarVal->mnVisibleSize;
839*cdf0e10cSrcweir                 aTrackDraw.value = pScrollbarVal->mnCur;
840*cdf0e10cSrcweir                 aTrackDraw.reserved = 0;
841*cdf0e10cSrcweir                 aTrackDraw.attributes = kThemeTrackShowThumb;
842*cdf0e10cSrcweir                 if( nPart == PART_DRAW_BACKGROUND_HORZ )
843*cdf0e10cSrcweir                     aTrackDraw.attributes |= kThemeTrackHorizontal;
844*cdf0e10cSrcweir                 aTrackDraw.enableState = getTrackState( nState );
845*cdf0e10cSrcweir 
846*cdf0e10cSrcweir                 ScrollBarTrackInfo aScrollInfo;
847*cdf0e10cSrcweir                 aScrollInfo.viewsize = pScrollbarVal->mnVisibleSize;
848*cdf0e10cSrcweir                 aScrollInfo.pressState = 0;
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir                 if ( pScrollbarVal->mnButton1State & CTRL_STATE_ENABLED )
851*cdf0e10cSrcweir                 {
852*cdf0e10cSrcweir                     if ( pScrollbarVal->mnButton1State & CTRL_STATE_PRESSED )
853*cdf0e10cSrcweir                         aScrollInfo.pressState = kThemeTopOutsideArrowPressed;
854*cdf0e10cSrcweir                 }
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir                 if ( pScrollbarVal->mnButton2State & CTRL_STATE_ENABLED )
857*cdf0e10cSrcweir                 {
858*cdf0e10cSrcweir                     if ( pScrollbarVal->mnButton2State & CTRL_STATE_PRESSED )
859*cdf0e10cSrcweir                         aScrollInfo.pressState = kThemeBottomOutsideArrowPressed;
860*cdf0e10cSrcweir                 }
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir                 if ( pScrollbarVal->mnThumbState & CTRL_STATE_ENABLED )
863*cdf0e10cSrcweir                 {
864*cdf0e10cSrcweir                     if ( pScrollbarVal->mnThumbState & CTRL_STATE_PRESSED )
865*cdf0e10cSrcweir                         aScrollInfo.pressState = kThemeThumbPressed;
866*cdf0e10cSrcweir                 }
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir                 aTrackDraw.trackInfo.scrollbar = aScrollInfo;
869*cdf0e10cSrcweir 
870*cdf0e10cSrcweir                 HIThemeDrawTrack( &aTrackDraw, NULL, mrContext, kHIThemeOrientationNormal );
871*cdf0e10cSrcweir                 bOK = true;
872*cdf0e10cSrcweir             }
873*cdf0e10cSrcweir         }
874*cdf0e10cSrcweir         break;
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir //#define OLD_TAB_STYLE
877*cdf0e10cSrcweir #ifdef OLD_TAB_STYLE
878*cdf0e10cSrcweir     case CTRL_TAB_PANE:
879*cdf0e10cSrcweir         {
880*cdf0e10cSrcweir             HIThemeTabPaneDrawInfo aTabPaneDrawInfo;
881*cdf0e10cSrcweir             aTabPaneDrawInfo.version = 0;
882*cdf0e10cSrcweir             aTabPaneDrawInfo.state = kThemeStateActive;
883*cdf0e10cSrcweir             aTabPaneDrawInfo.direction=kThemeTabNorth;
884*cdf0e10cSrcweir             aTabPaneDrawInfo.size=kHIThemeTabSizeNormal;
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir             //the border is outside the rect rc for Carbon
887*cdf0e10cSrcweir             //but for VCL it should be inside
888*cdf0e10cSrcweir             rc.origin.x+=1;
889*cdf0e10cSrcweir             rc.size.width-=2;
890*cdf0e10cSrcweir 
891*cdf0e10cSrcweir             HIThemeDrawTabPane(&rc, &aTabPaneDrawInfo, mrContext, kHIThemeOrientationNormal);
892*cdf0e10cSrcweir             bOK = true;
893*cdf0e10cSrcweir         }
894*cdf0e10cSrcweir         break;
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir     case CTRL_TAB_ITEM:
897*cdf0e10cSrcweir         {
898*cdf0e10cSrcweir             HIThemeTabDrawInfo aTabItemDrawInfo;
899*cdf0e10cSrcweir             aTabItemDrawInfo.version=0;
900*cdf0e10cSrcweir             aTabItemDrawInfo.style=kThemeTabNonFront;
901*cdf0e10cSrcweir             aTabItemDrawInfo.direction=kThemeTabNorth;
902*cdf0e10cSrcweir             aTabItemDrawInfo.size=kHIThemeTabSizeNormal;
903*cdf0e10cSrcweir             aTabItemDrawInfo.adornment=kHIThemeTabAdornmentNone;
904*cdf0e10cSrcweir 
905*cdf0e10cSrcweir             if(nState & CTRL_STATE_SELECTED) {
906*cdf0e10cSrcweir                 aTabItemDrawInfo.style=kThemeTabFront;
907*cdf0e10cSrcweir             }
908*cdf0e10cSrcweir             if(nState & CTRL_STATE_FOCUSED) {
909*cdf0e10cSrcweir                 aTabItemDrawInfo.adornment=kHIThemeTabAdornmentFocus;
910*cdf0e10cSrcweir             }
911*cdf0e10cSrcweir 
912*cdf0e10cSrcweir             /*if(rc.size.height>=TAB_HEIGHT_NORMAL) rc.size.height=TAB_HEIGHT_NORMAL;
913*cdf0e10cSrcweir             else if(rc.size.height>=TAB_HEIGHT_SMALL) rc.size.height=TAB_HEIGHT_SMALL;
914*cdf0e10cSrcweir             else rc.size.height=TAB_HEIGHT_MINI;*/
915*cdf0e10cSrcweir             //now we only use the default size
916*cdf0e10cSrcweir             rc.size.height=TAB_HEIGHT_NORMAL;
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir             HIThemeDrawTab(&rc, &aTabItemDrawInfo, mrContext, kHIThemeOrientationNormal, &rc );
919*cdf0e10cSrcweir 
920*cdf0e10cSrcweir             bOK=true;
921*cdf0e10cSrcweir         }
922*cdf0e10cSrcweir         break;
923*cdf0e10cSrcweir #else
924*cdf0e10cSrcweir     case CTRL_TAB_PANE:
925*cdf0e10cSrcweir         {
926*cdf0e10cSrcweir             HIThemeTabPaneDrawInfo aTabPaneDrawInfo;
927*cdf0e10cSrcweir             aTabPaneDrawInfo.version = 1;
928*cdf0e10cSrcweir             aTabPaneDrawInfo.state = kThemeStateActive;
929*cdf0e10cSrcweir             aTabPaneDrawInfo.direction=kThemeTabNorth;
930*cdf0e10cSrcweir             aTabPaneDrawInfo.size=kHIThemeTabSizeNormal;
931*cdf0e10cSrcweir             aTabPaneDrawInfo.kind=kHIThemeTabKindNormal;
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir             //the border is outside the rect rc for Carbon
934*cdf0e10cSrcweir             //but for VCL it should be inside
935*cdf0e10cSrcweir             rc.origin.x+=1;
936*cdf0e10cSrcweir             rc.origin.y-=TAB_HEIGHT_NORMAL/2;
937*cdf0e10cSrcweir             rc.size.height+=TAB_HEIGHT_NORMAL/2;
938*cdf0e10cSrcweir             rc.size.width-=2;
939*cdf0e10cSrcweir 
940*cdf0e10cSrcweir             HIThemeDrawTabPane(&rc, &aTabPaneDrawInfo, mrContext, kHIThemeOrientationNormal);
941*cdf0e10cSrcweir 
942*cdf0e10cSrcweir             bOK = true;
943*cdf0e10cSrcweir         }
944*cdf0e10cSrcweir         break;
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir     case CTRL_TAB_ITEM:
947*cdf0e10cSrcweir         {
948*cdf0e10cSrcweir             HIThemeTabDrawInfo aTabItemDrawInfo;
949*cdf0e10cSrcweir             aTabItemDrawInfo.version=1;
950*cdf0e10cSrcweir             aTabItemDrawInfo.style=kThemeTabNonFront;
951*cdf0e10cSrcweir             aTabItemDrawInfo.direction=kThemeTabNorth;
952*cdf0e10cSrcweir             aTabItemDrawInfo.size=kHIThemeTabSizeNormal;
953*cdf0e10cSrcweir             aTabItemDrawInfo.adornment=kHIThemeTabAdornmentTrailingSeparator;
954*cdf0e10cSrcweir             //State
955*cdf0e10cSrcweir             if(nState & CTRL_STATE_SELECTED) {
956*cdf0e10cSrcweir                 aTabItemDrawInfo.style=kThemeTabFront;
957*cdf0e10cSrcweir             }
958*cdf0e10cSrcweir             if(nState & CTRL_STATE_FOCUSED) {
959*cdf0e10cSrcweir                 aTabItemDrawInfo.adornment|=kHIThemeTabAdornmentFocus;
960*cdf0e10cSrcweir             }
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir             //first, last or middle tab
963*cdf0e10cSrcweir             aTabItemDrawInfo.position=kHIThemeTabPositionMiddle;
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir             TabitemValue* pTabValue = (TabitemValue *) &aValue;
966*cdf0e10cSrcweir             unsigned int nAlignment = pTabValue->mnAlignment;
967*cdf0e10cSrcweir             //TABITEM_LEFTALIGNED (and TABITEM_RIGHTALIGNED) for the leftmost (or rightmost) tab
968*cdf0e10cSrcweir             //when there are several lines of tabs because there is only one first tab and one
969*cdf0e10cSrcweir             //last tab and TABITEM_FIRST_IN_GROUP (and TABITEM_LAST_IN_GROUP) because when the
970*cdf0e10cSrcweir             //line width is different from window width, there may not be TABITEM_RIGHTALIGNED
971*cdf0e10cSrcweir             if( ( (nAlignment & TABITEM_LEFTALIGNED)&&(nAlignment & TABITEM_RIGHTALIGNED) ) ||
972*cdf0e10cSrcweir                 ( (nAlignment & TABITEM_FIRST_IN_GROUP)&&(nAlignment & TABITEM_LAST_IN_GROUP) )
973*cdf0e10cSrcweir                ) //tab alone
974*cdf0e10cSrcweir                 aTabItemDrawInfo.position=kHIThemeTabPositionOnly;
975*cdf0e10cSrcweir             else if((nAlignment & TABITEM_LEFTALIGNED)||(nAlignment & TABITEM_FIRST_IN_GROUP))
976*cdf0e10cSrcweir                 aTabItemDrawInfo.position=kHIThemeTabPositionFirst;
977*cdf0e10cSrcweir             else if((nAlignment & TABITEM_RIGHTALIGNED)||(nAlignment & TABITEM_LAST_IN_GROUP))
978*cdf0e10cSrcweir                 aTabItemDrawInfo.position=kHIThemeTabPositionLast;
979*cdf0e10cSrcweir 
980*cdf0e10cSrcweir             //support for RTL
981*cdf0e10cSrcweir             //see issue 79748
982*cdf0e10cSrcweir             if( Application::GetSettings().GetLayoutRTL() ) {
983*cdf0e10cSrcweir                 if( aTabItemDrawInfo.position == kHIThemeTabPositionFirst )
984*cdf0e10cSrcweir                         aTabItemDrawInfo.position = kHIThemeTabPositionLast;
985*cdf0e10cSrcweir                 else if( aTabItemDrawInfo.position == kHIThemeTabPositionLast )
986*cdf0e10cSrcweir                         aTabItemDrawInfo.position = kHIThemeTabPositionFirst;
987*cdf0e10cSrcweir             }
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir             rc.size.width+=2;//because VCL has 2 empty pixels between 2 tabs
990*cdf0e10cSrcweir             rc.origin.x-=1;
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir             HIThemeDrawTab(&rc, &aTabItemDrawInfo, mrContext, kHIThemeOrientationNormal, &rc );
993*cdf0e10cSrcweir 
994*cdf0e10cSrcweir             bOK=true;
995*cdf0e10cSrcweir         }
996*cdf0e10cSrcweir         break;
997*cdf0e10cSrcweir #endif
998*cdf0e10cSrcweir 
999*cdf0e10cSrcweir     case  CTRL_LISTBOX:
1000*cdf0e10cSrcweir         switch( nPart)
1001*cdf0e10cSrcweir         {
1002*cdf0e10cSrcweir             case PART_ENTIRE_CONTROL:
1003*cdf0e10cSrcweir             case PART_BUTTON_DOWN:
1004*cdf0e10cSrcweir             {
1005*cdf0e10cSrcweir                 HIThemeButtonDrawInfo aListInfo;
1006*cdf0e10cSrcweir                 aListInfo.version = 0;
1007*cdf0e10cSrcweir                 aListInfo.kind = kThemePopupButton;
1008*cdf0e10cSrcweir                 aListInfo.state = getState( nState );//kThemeStateInactive -> greyed
1009*cdf0e10cSrcweir                 aListInfo.value = kThemeButtonOn;
1010*cdf0e10cSrcweir 
1011*cdf0e10cSrcweir                 aListInfo.adornment = kThemeAdornmentDefault;
1012*cdf0e10cSrcweir                 if( (nState & CTRL_STATE_FOCUSED) != 0 )
1013*cdf0e10cSrcweir                     aListInfo.adornment |= kThemeAdornmentFocus;
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir                 HIThemeDrawButton(&rc, &aListInfo, mrContext, kHIThemeOrientationNormal,&rc);
1016*cdf0e10cSrcweir                 bOK = true;
1017*cdf0e10cSrcweir                 break;
1018*cdf0e10cSrcweir             }
1019*cdf0e10cSrcweir             case PART_WINDOW:
1020*cdf0e10cSrcweir             {
1021*cdf0e10cSrcweir                 HIThemeFrameDrawInfo aTextDrawInfo;
1022*cdf0e10cSrcweir                 aTextDrawInfo.version=0;
1023*cdf0e10cSrcweir                 aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare;
1024*cdf0e10cSrcweir                 aTextDrawInfo.state=getState( nState );
1025*cdf0e10cSrcweir                 aTextDrawInfo.isFocused=false;
1026*cdf0e10cSrcweir 
1027*cdf0e10cSrcweir                 rc.size.width+=1;//else there's a white space because aqua theme hasn't a 3D border
1028*cdf0e10cSrcweir                 rc.size.height+=1;
1029*cdf0e10cSrcweir                 HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir                 if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal);
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir                 bOK=true;
1034*cdf0e10cSrcweir                 break;
1035*cdf0e10cSrcweir             }
1036*cdf0e10cSrcweir         }
1037*cdf0e10cSrcweir         break;
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir     case CTRL_EDITBOX:
1040*cdf0e10cSrcweir     case CTRL_MULTILINE_EDITBOX:
1041*cdf0e10cSrcweir         {
1042*cdf0e10cSrcweir             HIThemeFrameDrawInfo aTextDrawInfo;
1043*cdf0e10cSrcweir             aTextDrawInfo.version=0;
1044*cdf0e10cSrcweir             aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare;
1045*cdf0e10cSrcweir             aTextDrawInfo.state=getState( nState );
1046*cdf0e10cSrcweir             aTextDrawInfo.isFocused=false;
1047*cdf0e10cSrcweir 
1048*cdf0e10cSrcweir             rc.size.width  += 1; // else there may be a white space because aqua theme hasn't a 3D border
1049*cdf0e10cSrcweir             // change rc so that the frame will encompass only the content region
1050*cdf0e10cSrcweir             // see counterpart in GetNativeControlRegion
1051*cdf0e10cSrcweir             rc.size.width  += 2;
1052*cdf0e10cSrcweir             rc.size.height += 2;
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir             //CGContextSetFillColorWithColor
1055*cdf0e10cSrcweir             CGContextFillRect (mrContext, CGRectMake(rc.origin.x, rc.origin.y, rc.size.width, rc.size.height));
1056*cdf0e10cSrcweir             //fill a white background, because drawFrame only draws the border
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir             HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir             if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal);
1061*cdf0e10cSrcweir 
1062*cdf0e10cSrcweir             bOK=true;
1063*cdf0e10cSrcweir         }
1064*cdf0e10cSrcweir         break;
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir     case CTRL_SPINBOX:
1067*cdf0e10cSrcweir         {
1068*cdf0e10cSrcweir             if(nPart == PART_ENTIRE_CONTROL)
1069*cdf0e10cSrcweir             {
1070*cdf0e10cSrcweir                 //text field:
1071*cdf0e10cSrcweir                 HIThemeFrameDrawInfo aTextDrawInfo;
1072*cdf0e10cSrcweir                 aTextDrawInfo.version=0;
1073*cdf0e10cSrcweir                 aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare;
1074*cdf0e10cSrcweir                 aTextDrawInfo.state=getState( nState );
1075*cdf0e10cSrcweir                 aTextDrawInfo.isFocused=false;
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir                 //rc.size.width contains the full size of the spinbox ie textfield + button
1078*cdf0e10cSrcweir                 //so we remove the button width and the space between the button and the textfield
1079*cdf0e10cSrcweir                 rc.size.width -= SPIN_BUTTON_SPACE + SPIN_BUTTON_WIDTH + 2*FOCUS_RING_WIDTH;
1080*cdf0e10cSrcweir                 rc.origin.x += FOCUS_RING_WIDTH;
1081*cdf0e10cSrcweir                 rc.origin.y += FOCUS_RING_WIDTH;
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir                 //CGContextSetFillColorWithColor
1084*cdf0e10cSrcweir                 CGContextFillRect (mrContext, CGRectMake(rc.origin.x, rc.origin.y, rc.size.width, rc.size.height));
1085*cdf0e10cSrcweir                 //fill a white background, because drawFrame only draws the border
1086*cdf0e10cSrcweir 
1087*cdf0e10cSrcweir                 HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);
1088*cdf0e10cSrcweir 
1089*cdf0e10cSrcweir                 if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal);
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir                 //buttons:
1092*cdf0e10cSrcweir                 SpinbuttonValue* pSpinButtonVal = (SpinbuttonValue *)&aValue;
1093*cdf0e10cSrcweir                 ControlState nUpperState = CTRL_STATE_ENABLED;//state of the upper button
1094*cdf0e10cSrcweir                 ControlState nLowerState = CTRL_STATE_ENABLED;//and of the lower button
1095*cdf0e10cSrcweir                 if(pSpinButtonVal) {//pSpinButtonVal is sometimes null
1096*cdf0e10cSrcweir                     nUpperState = (ControlState) pSpinButtonVal->mnUpperState;
1097*cdf0e10cSrcweir                     nLowerState = (ControlState) pSpinButtonVal->mnLowerState;
1098*cdf0e10cSrcweir                 }
1099*cdf0e10cSrcweir 
1100*cdf0e10cSrcweir                 if( pSpinButtonVal )
1101*cdf0e10cSrcweir                 {
1102*cdf0e10cSrcweir                     HIThemeButtonDrawInfo aSpinInfo;
1103*cdf0e10cSrcweir                     aSpinInfo.kind = kThemeIncDecButton;
1104*cdf0e10cSrcweir                     aSpinInfo.state = kThemeStateActive;
1105*cdf0e10cSrcweir                     if(nUpperState & CTRL_STATE_PRESSED)
1106*cdf0e10cSrcweir                         aSpinInfo.state = kThemeStatePressedUp;
1107*cdf0e10cSrcweir                     else if(nLowerState & CTRL_STATE_PRESSED)
1108*cdf0e10cSrcweir                         aSpinInfo.state = kThemeStatePressedDown;
1109*cdf0e10cSrcweir                     else if((nUpperState & ~CTRL_STATE_ENABLED)||(nLowerState & ~CTRL_STATE_ENABLED))
1110*cdf0e10cSrcweir                         aSpinInfo.state = kThemeStateInactive;
1111*cdf0e10cSrcweir                     else if((nUpperState & CTRL_STATE_ROLLOVER)||(nLowerState & CTRL_STATE_ROLLOVER))
1112*cdf0e10cSrcweir                         aSpinInfo.state = kThemeStateRollover;
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir                     Rectangle aSpinRect( pSpinButtonVal->maUpperRect );
1115*cdf0e10cSrcweir                     aSpinRect.Union( pSpinButtonVal->maLowerRect );
1116*cdf0e10cSrcweir                     HIRect buttonRc = ImplGetHIRectFromRectangle(aSpinRect);
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir                     // FIXME: without this fuzz factor there is some unwanted clipping
1119*cdf0e10cSrcweir                     if( Application::GetSettings().GetLayoutRTL() )
1120*cdf0e10cSrcweir                         buttonRc.origin.x -= FOCUS_RING_WIDTH - CLIP_FUZZ;
1121*cdf0e10cSrcweir                     else
1122*cdf0e10cSrcweir                         buttonRc.origin.x += FOCUS_RING_WIDTH + CLIP_FUZZ;
1123*cdf0e10cSrcweir 
1124*cdf0e10cSrcweir                     switch( aValue.getTristateVal() )
1125*cdf0e10cSrcweir                     {
1126*cdf0e10cSrcweir                         case BUTTONVALUE_ON:        aSpinInfo.value = kThemeButtonOn;
1127*cdf0e10cSrcweir                                                     break;
1128*cdf0e10cSrcweir                         case BUTTONVALUE_OFF:       aSpinInfo.value = kThemeButtonOff;
1129*cdf0e10cSrcweir                                                     break;
1130*cdf0e10cSrcweir                         case BUTTONVALUE_MIXED:
1131*cdf0e10cSrcweir                         case BUTTONVALUE_DONTKNOW:
1132*cdf0e10cSrcweir                         default:                    aSpinInfo.value = kThemeButtonMixed;
1133*cdf0e10cSrcweir                                                     break;
1134*cdf0e10cSrcweir                     }
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir                     aSpinInfo.adornment = ( ((nUpperState & CTRL_STATE_DEFAULT) != 0 ) ||
1137*cdf0e10cSrcweir                                             ((nLowerState & CTRL_STATE_DEFAULT) != 0 )) ?
1138*cdf0e10cSrcweir                                        kThemeAdornmentDefault :
1139*cdf0e10cSrcweir                                        kThemeAdornmentNone;
1140*cdf0e10cSrcweir                     if( ((nUpperState & CTRL_STATE_FOCUSED) != 0 ) || ((nLowerState & CTRL_STATE_FOCUSED) != 0 ))
1141*cdf0e10cSrcweir                         aSpinInfo.adornment |= kThemeAdornmentFocus;
1142*cdf0e10cSrcweir 
1143*cdf0e10cSrcweir                     HIThemeDrawButton( &buttonRc, &aSpinInfo, mrContext, kHIThemeOrientationNormal, NULL );
1144*cdf0e10cSrcweir                 }
1145*cdf0e10cSrcweir 
1146*cdf0e10cSrcweir                 bOK=true;
1147*cdf0e10cSrcweir             }
1148*cdf0e10cSrcweir 
1149*cdf0e10cSrcweir         }
1150*cdf0e10cSrcweir         break;
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir     case CTRL_FRAME:
1153*cdf0e10cSrcweir         {
1154*cdf0e10cSrcweir             sal_uInt16 nStyle = aValue.getNumericVal();
1155*cdf0e10cSrcweir             if( nPart == PART_BORDER ) {
1156*cdf0e10cSrcweir                 if(!( nStyle & FRAME_DRAW_MENU ) && !(nStyle & FRAME_DRAW_WINDOWBORDER) )
1157*cdf0e10cSrcweir                 {
1158*cdf0e10cSrcweir                     // #i84756# strange effects start to happen when HIThemeDrawFrame
1159*cdf0e10cSrcweir                     // meets the border of the window. These can be avoided by clipping
1160*cdf0e10cSrcweir                     // to the boundary of the frame
1161*cdf0e10cSrcweir                     if( rc.origin.y + rc.size.height >= mpFrame->maGeometry.nHeight-3 )
1162*cdf0e10cSrcweir                     {
1163*cdf0e10cSrcweir                         CGMutablePathRef rPath = CGPathCreateMutable();
1164*cdf0e10cSrcweir                         CGPathAddRect( rPath, NULL, CGRectMake( 0, 0, mpFrame->maGeometry.nWidth-1, mpFrame->maGeometry.nHeight-1 ) );
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir                         CGContextBeginPath( mrContext );
1167*cdf0e10cSrcweir                         CGContextAddPath( mrContext, rPath );
1168*cdf0e10cSrcweir                         CGContextClip( mrContext );
1169*cdf0e10cSrcweir                         CGPathRelease( rPath );
1170*cdf0e10cSrcweir                     }
1171*cdf0e10cSrcweir 
1172*cdf0e10cSrcweir                     HIThemeFrameDrawInfo aTextDrawInfo;
1173*cdf0e10cSrcweir                     aTextDrawInfo.version=0;
1174*cdf0e10cSrcweir                     aTextDrawInfo.kind=kHIThemeFrameListBox;
1175*cdf0e10cSrcweir                     aTextDrawInfo.state=kThemeStateActive;
1176*cdf0e10cSrcweir                     aTextDrawInfo.isFocused=false;
1177*cdf0e10cSrcweir 
1178*cdf0e10cSrcweir                     HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir                     bOK=true;
1181*cdf0e10cSrcweir                 }
1182*cdf0e10cSrcweir             }
1183*cdf0e10cSrcweir         }
1184*cdf0e10cSrcweir         break;
1185*cdf0e10cSrcweir 
1186*cdf0e10cSrcweir     case CTRL_LISTNET:
1187*cdf0e10cSrcweir         {
1188*cdf0e10cSrcweir            //do nothing as there isn't net for listviews on macos
1189*cdf0e10cSrcweir             bOK=true;
1190*cdf0e10cSrcweir         }
1191*cdf0e10cSrcweir         break;
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir     }
1194*cdf0e10cSrcweir 
1195*cdf0e10cSrcweir     CGContextRestoreGState( mrContext );
1196*cdf0e10cSrcweir 
1197*cdf0e10cSrcweir     /* #i90291# in most cases invalidating the whole control region instead
1198*cdf0e10cSrcweir        of just the unclipped part of it is sufficient (and probably faster).
1199*cdf0e10cSrcweir        However for the window background we should not unnecessarily enlarge
1200*cdf0e10cSrcweir        the really changed rectangle since the difference is usually quite high
1201*cdf0e10cSrcweir        (the background is always drawn as a whole since we don't know anything
1202*cdf0e10cSrcweir        about its possible contents)
1203*cdf0e10cSrcweir     */
1204*cdf0e10cSrcweir     if( nType == CTRL_WINDOW_BACKGROUND )
1205*cdf0e10cSrcweir     {
1206*cdf0e10cSrcweir         CGRect aRect = { { 0, 0 }, { 0, 0 } };
1207*cdf0e10cSrcweir         if( mxClipPath )
1208*cdf0e10cSrcweir             aRect = CGPathGetBoundingBox( mxClipPath );
1209*cdf0e10cSrcweir         if( aRect.size.width != 0 && aRect.size.height != 0 )
1210*cdf0e10cSrcweir             buttonRect.Intersection( Rectangle( Point( static_cast<long int>(aRect.origin.x),
1211*cdf0e10cSrcweir 							static_cast<long int>(aRect.origin.y) ),
1212*cdf0e10cSrcweir                                                 Size( 	static_cast<long int>(aRect.size.width),
1213*cdf0e10cSrcweir 							static_cast<long int>(aRect.size.height) ) ) );
1214*cdf0e10cSrcweir     }
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir     RefreshRect( buttonRect.Left(), buttonRect.Top(), buttonRect.GetWidth(), buttonRect.GetHeight() );
1217*cdf0e10cSrcweir 
1218*cdf0e10cSrcweir     return bOK;
1219*cdf0e10cSrcweir }
1220*cdf0e10cSrcweir 
1221*cdf0e10cSrcweir /*
1222*cdf0e10cSrcweir  * DrawNativeControlText()
1223*cdf0e10cSrcweir  *
1224*cdf0e10cSrcweir  *  OPTIONAL.  Draws the requested text for the control described by nPart/nState.
1225*cdf0e10cSrcweir  *     Used if text not drawn by DrawNativeControl().
1226*cdf0e10cSrcweir  *
1227*cdf0e10cSrcweir  *  rControlRegion:	The bounding region of the complete control in VCL frame coordinates.
1228*cdf0e10cSrcweir  *  aValue:		An optional value (tristate/numerical/string)
1229*cdf0e10cSrcweir  *  aCaption:	A caption or title string (like button text etc)
1230*cdf0e10cSrcweir  */
1231*cdf0e10cSrcweir sal_Bool AquaSalGraphics::drawNativeControlText( ControlType /*nType*/, ControlPart /*nPart*/, const Rectangle& /*rControlRegion*/,
1232*cdf0e10cSrcweir                                                ControlState /*nState*/, const ImplControlValue& /*aValue*/,
1233*cdf0e10cSrcweir                                                const rtl::OUString& )
1234*cdf0e10cSrcweir {
1235*cdf0e10cSrcweir 	return( sal_False );
1236*cdf0e10cSrcweir }
1237*cdf0e10cSrcweir 
1238*cdf0e10cSrcweir 
1239*cdf0e10cSrcweir /*
1240*cdf0e10cSrcweir  * GetNativeControlRegion()
1241*cdf0e10cSrcweir  *
1242*cdf0e10cSrcweir  *  If the return value is sal_True, rNativeBoundingRegion
1243*cdf0e10cSrcweir  *  contains the true bounding region covered by the control
1244*cdf0e10cSrcweir  *  including any adornment, while rNativeContentRegion contains the area
1245*cdf0e10cSrcweir  *  within the control that can be safely drawn into without drawing over
1246*cdf0e10cSrcweir  *  the borders of the control.
1247*cdf0e10cSrcweir  *
1248*cdf0e10cSrcweir  *  rControlRegion:	The bounding region of the control in VCL frame coordinates.
1249*cdf0e10cSrcweir  *  aValue:		An optional value (tristate/numerical/string)
1250*cdf0e10cSrcweir  *  aCaption:		A caption or title string (like button text etc)
1251*cdf0e10cSrcweir  */
1252*cdf0e10cSrcweir sal_Bool AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState /*nState*/,
1253*cdf0e10cSrcweir                                                const ImplControlValue& aValue, const rtl::OUString&,
1254*cdf0e10cSrcweir                                                 Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion )
1255*cdf0e10cSrcweir 
1256*cdf0e10cSrcweir {
1257*cdf0e10cSrcweir 	sal_Bool toReturn = sal_False;
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir 	Rectangle aCtrlBoundRect( rControlRegion );
1260*cdf0e10cSrcweir     short x = aCtrlBoundRect.Left();
1261*cdf0e10cSrcweir     short y = aCtrlBoundRect.Top();
1262*cdf0e10cSrcweir     short w, h;
1263*cdf0e10cSrcweir 
1264*cdf0e10cSrcweir     sal_uInt8 nBorderCleanup = 0;
1265*cdf0e10cSrcweir 
1266*cdf0e10cSrcweir     switch (nType)
1267*cdf0e10cSrcweir     {
1268*cdf0e10cSrcweir         case CTRL_SLIDER:
1269*cdf0e10cSrcweir             {
1270*cdf0e10cSrcweir                 if( nPart == PART_THUMB_HORZ )
1271*cdf0e10cSrcweir                 {
1272*cdf0e10cSrcweir                     w = 19; // taken from HIG
1273*cdf0e10cSrcweir                     h = aCtrlBoundRect.GetHeight();
1274*cdf0e10cSrcweir                     rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1275*cdf0e10cSrcweir                     toReturn = true;
1276*cdf0e10cSrcweir                 }
1277*cdf0e10cSrcweir                 else if( nPart == PART_THUMB_VERT )
1278*cdf0e10cSrcweir                 {
1279*cdf0e10cSrcweir                     w = aCtrlBoundRect.GetWidth();
1280*cdf0e10cSrcweir                     h = 18; // taken from HIG
1281*cdf0e10cSrcweir                     rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1282*cdf0e10cSrcweir                     toReturn = true;
1283*cdf0e10cSrcweir                 }
1284*cdf0e10cSrcweir             }
1285*cdf0e10cSrcweir             break;
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir         case CTRL_SCROLLBAR:
1288*cdf0e10cSrcweir             {
1289*cdf0e10cSrcweir 				Rectangle aRect;
1290*cdf0e10cSrcweir 				if( AquaGetScrollRect( /* m_nScreen */ nPart, aCtrlBoundRect, aRect ) )
1291*cdf0e10cSrcweir                 {
1292*cdf0e10cSrcweir 					toReturn = sal_True;
1293*cdf0e10cSrcweir 					rNativeBoundingRegion = aRect;
1294*cdf0e10cSrcweir 					rNativeContentRegion = aRect;
1295*cdf0e10cSrcweir                 }
1296*cdf0e10cSrcweir             }
1297*cdf0e10cSrcweir             break;
1298*cdf0e10cSrcweir 
1299*cdf0e10cSrcweir         case CTRL_PUSHBUTTON:
1300*cdf0e10cSrcweir         case CTRL_RADIOBUTTON:
1301*cdf0e10cSrcweir         case CTRL_CHECKBOX:
1302*cdf0e10cSrcweir             {
1303*cdf0e10cSrcweir                 if ( nType == CTRL_PUSHBUTTON )
1304*cdf0e10cSrcweir                 {
1305*cdf0e10cSrcweir                     w = aCtrlBoundRect.GetWidth();
1306*cdf0e10cSrcweir                     h = aCtrlBoundRect.GetHeight();
1307*cdf0e10cSrcweir                 }
1308*cdf0e10cSrcweir                 else
1309*cdf0e10cSrcweir                 {
1310*cdf0e10cSrcweir                     // checkbox and radio borders need cleanup after unchecking them
1311*cdf0e10cSrcweir                     nBorderCleanup = 4;
1312*cdf0e10cSrcweir 
1313*cdf0e10cSrcweir                     // TEXT_SEPARATOR to respect Aqua HIG
1314*cdf0e10cSrcweir                     w = BUTTON_WIDTH + TEXT_SEPARATOR;
1315*cdf0e10cSrcweir                     h = BUTTON_HEIGHT;
1316*cdf0e10cSrcweir 
1317*cdf0e10cSrcweir                 }
1318*cdf0e10cSrcweir 
1319*cdf0e10cSrcweir                 rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h + nBorderCleanup) );
1320*cdf0e10cSrcweir                 rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );
1321*cdf0e10cSrcweir 
1322*cdf0e10cSrcweir                 toReturn = sal_True;
1323*cdf0e10cSrcweir             }
1324*cdf0e10cSrcweir             break;
1325*cdf0e10cSrcweir         case CTRL_PROGRESS:
1326*cdf0e10cSrcweir             {
1327*cdf0e10cSrcweir                 Rectangle aRect( aCtrlBoundRect );
1328*cdf0e10cSrcweir                 if( aRect.GetHeight() < 16 )
1329*cdf0e10cSrcweir                     aRect.Bottom() = aRect.Top() + 9; // values taken from HIG for medium progress
1330*cdf0e10cSrcweir                 else
1331*cdf0e10cSrcweir                     aRect.Bottom() = aRect.Top() + 15; // values taken from HIG for large progress
1332*cdf0e10cSrcweir                 rNativeBoundingRegion = aRect;
1333*cdf0e10cSrcweir                 rNativeContentRegion = aRect;
1334*cdf0e10cSrcweir                 toReturn = sal_True;
1335*cdf0e10cSrcweir             }
1336*cdf0e10cSrcweir             break;
1337*cdf0e10cSrcweir 
1338*cdf0e10cSrcweir         case CTRL_INTROPROGRESS:
1339*cdf0e10cSrcweir             {
1340*cdf0e10cSrcweir                 Rectangle aRect( aCtrlBoundRect );
1341*cdf0e10cSrcweir                 aRect.Bottom() = aRect.Top() + INTRO_PROGRESS_HEIGHT; // values taken from HIG for medium progress
1342*cdf0e10cSrcweir                 rNativeBoundingRegion = aRect;
1343*cdf0e10cSrcweir                 rNativeContentRegion = aRect;
1344*cdf0e10cSrcweir                 toReturn = sal_True;
1345*cdf0e10cSrcweir             }
1346*cdf0e10cSrcweir             break;
1347*cdf0e10cSrcweir 
1348*cdf0e10cSrcweir          case CTRL_TAB_ITEM:
1349*cdf0e10cSrcweir 
1350*cdf0e10cSrcweir             w = aCtrlBoundRect.GetWidth() + 2*TAB_TEXT_OFFSET - 2*VCL_TAB_TEXT_OFFSET;
1351*cdf0e10cSrcweir 
1352*cdf0e10cSrcweir #ifdef OLD_TAB_STYLE
1353*cdf0e10cSrcweir             h = TAB_HEIGHT_NORMAL;
1354*cdf0e10cSrcweir #else
1355*cdf0e10cSrcweir             h = TAB_HEIGHT_NORMAL+2;
1356*cdf0e10cSrcweir #endif
1357*cdf0e10cSrcweir             rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1358*cdf0e10cSrcweir             rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );
1359*cdf0e10cSrcweir 
1360*cdf0e10cSrcweir             toReturn = sal_True;
1361*cdf0e10cSrcweir 
1362*cdf0e10cSrcweir             break;
1363*cdf0e10cSrcweir 
1364*cdf0e10cSrcweir         case CTRL_EDITBOX:
1365*cdf0e10cSrcweir             {
1366*cdf0e10cSrcweir                 w = aCtrlBoundRect.GetWidth();
1367*cdf0e10cSrcweir                 if( w < 3+2*FOCUS_RING_WIDTH )
1368*cdf0e10cSrcweir                     w = 3+2*FOCUS_RING_WIDTH;
1369*cdf0e10cSrcweir                 h = TEXT_EDIT_HEIGHT_NORMAL+2*FOCUS_RING_WIDTH;
1370*cdf0e10cSrcweir                 if( h < aCtrlBoundRect.GetHeight() )
1371*cdf0e10cSrcweir                     h = aCtrlBoundRect.GetHeight();
1372*cdf0e10cSrcweir 
1373*cdf0e10cSrcweir                 rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*(FOCUS_RING_WIDTH+1), h-2*(FOCUS_RING_WIDTH+1) ) );
1374*cdf0e10cSrcweir                 rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );
1375*cdf0e10cSrcweir 
1376*cdf0e10cSrcweir                 toReturn = sal_True;
1377*cdf0e10cSrcweir             }
1378*cdf0e10cSrcweir             break;
1379*cdf0e10cSrcweir         case CTRL_LISTBOX:
1380*cdf0e10cSrcweir         case CTRL_COMBOBOX:
1381*cdf0e10cSrcweir             {
1382*cdf0e10cSrcweir                 if( nPart == PART_ENTIRE_CONTROL )
1383*cdf0e10cSrcweir                 {
1384*cdf0e10cSrcweir                     w = aCtrlBoundRect.GetWidth();
1385*cdf0e10cSrcweir                     h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height
1386*cdf0e10cSrcweir 
1387*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*FOCUS_RING_WIDTH, h ) );
1388*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) );
1389*cdf0e10cSrcweir 
1390*cdf0e10cSrcweir                     toReturn = sal_True;
1391*cdf0e10cSrcweir                 }
1392*cdf0e10cSrcweir                 else if( nPart == PART_BUTTON_DOWN )
1393*cdf0e10cSrcweir                 {
1394*cdf0e10cSrcweir                     w = aCtrlBoundRect.GetWidth();
1395*cdf0e10cSrcweir                 if( w < 3+2*FOCUS_RING_WIDTH )
1396*cdf0e10cSrcweir                     w = 3+2*FOCUS_RING_WIDTH;
1397*cdf0e10cSrcweir                     h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height
1398*cdf0e10cSrcweir 
1399*cdf0e10cSrcweir                     x += w-DROPDOWN_BUTTON_WIDTH - FOCUS_RING_WIDTH;
1400*cdf0e10cSrcweir                     y += FOCUS_RING_WIDTH;
1401*cdf0e10cSrcweir                     w = DROPDOWN_BUTTON_WIDTH;
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1404*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w+FOCUS_RING_WIDTH, h+2*FOCUS_RING_WIDTH ) );
1405*cdf0e10cSrcweir 
1406*cdf0e10cSrcweir                     toReturn = true;
1407*cdf0e10cSrcweir                 }
1408*cdf0e10cSrcweir                 else if( nPart == PART_SUB_EDIT )
1409*cdf0e10cSrcweir                 {
1410*cdf0e10cSrcweir                     w = aCtrlBoundRect.GetWidth();
1411*cdf0e10cSrcweir                     h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height
1412*cdf0e10cSrcweir 
1413*cdf0e10cSrcweir                     x += FOCUS_RING_WIDTH;
1414*cdf0e10cSrcweir                     x += 3; // add an offset for rounded borders
1415*cdf0e10cSrcweir                     y += 2; // don't draw into upper border
1416*cdf0e10cSrcweir                     y += FOCUS_RING_WIDTH;
1417*cdf0e10cSrcweir                     w -= 3 + DROPDOWN_BUTTON_WIDTH + 2*FOCUS_RING_WIDTH;
1418*cdf0e10cSrcweir                     if( nType == CTRL_LISTBOX )
1419*cdf0e10cSrcweir                         w -= 9; // HIG specifies 9 units distance between dropdown button area and content
1420*cdf0e10cSrcweir                     h -= 4; // don't draw into lower border
1421*cdf0e10cSrcweir 
1422*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1423*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w+FOCUS_RING_WIDTH, h+2*FOCUS_RING_WIDTH ) );
1424*cdf0e10cSrcweir 
1425*cdf0e10cSrcweir                     toReturn = true;
1426*cdf0e10cSrcweir                 }
1427*cdf0e10cSrcweir             }
1428*cdf0e10cSrcweir             break;
1429*cdf0e10cSrcweir         case CTRL_SPINBOX:
1430*cdf0e10cSrcweir                 if( nPart == PART_ENTIRE_CONTROL ) {
1431*cdf0e10cSrcweir                     w = aCtrlBoundRect.GetWidth();
1432*cdf0e10cSrcweir                     if( w < 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH )
1433*cdf0e10cSrcweir                         w = 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH;
1434*cdf0e10cSrcweir                     h = TEXT_EDIT_HEIGHT_NORMAL;
1435*cdf0e10cSrcweir 
1436*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y ), Size( w-2*FOCUS_RING_WIDTH, h ) );
1437*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) );
1438*cdf0e10cSrcweir 
1439*cdf0e10cSrcweir                     toReturn = sal_True;
1440*cdf0e10cSrcweir                 }
1441*cdf0e10cSrcweir                 else if( nPart == PART_SUB_EDIT ) {
1442*cdf0e10cSrcweir                     w = aCtrlBoundRect.GetWidth() - SPIN_BUTTON_SPACE - SPIN_BUTTON_WIDTH;
1443*cdf0e10cSrcweir                     h = TEXT_EDIT_HEIGHT_NORMAL;
1444*cdf0e10cSrcweir                     x += 4; // add an offset for rounded borders
1445*cdf0e10cSrcweir                     y += 2; // don't draw into upper border
1446*cdf0e10cSrcweir                     w -= 8; // offset for left and right rounded border
1447*cdf0e10cSrcweir                     h -= 4; // don't draw into upper or ower border
1448*cdf0e10cSrcweir 
1449*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x + FOCUS_RING_WIDTH, y + FOCUS_RING_WIDTH ), Size( w - 2* FOCUS_RING_WIDTH, h ) );
1450*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) );
1451*cdf0e10cSrcweir 
1452*cdf0e10cSrcweir                     toReturn = sal_True;
1453*cdf0e10cSrcweir                 }
1454*cdf0e10cSrcweir                 else if( nPart == PART_BUTTON_UP ) {
1455*cdf0e10cSrcweir                     //aCtrlBoundRect.GetWidth() contains the width of the full control
1456*cdf0e10cSrcweir                     //ie the width of the textfield + button
1457*cdf0e10cSrcweir                     //x is the position of the left corner of the full control
1458*cdf0e10cSrcweir                     x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ;
1459*cdf0e10cSrcweir                     y += FOCUS_RING_WIDTH - CLIP_FUZZ;
1460*cdf0e10cSrcweir                     w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ;
1461*cdf0e10cSrcweir                     h = SPIN_UPPER_BUTTON_HEIGHT + 2*CLIP_FUZZ;
1462*cdf0e10cSrcweir 
1463*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1464*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );
1465*cdf0e10cSrcweir 
1466*cdf0e10cSrcweir                     toReturn = sal_True;
1467*cdf0e10cSrcweir                 }
1468*cdf0e10cSrcweir                 else if( nPart == PART_BUTTON_DOWN ) {
1469*cdf0e10cSrcweir                     x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ;
1470*cdf0e10cSrcweir                     y += SPIN_UPPER_BUTTON_HEIGHT + FOCUS_RING_WIDTH - CLIP_FUZZ;
1471*cdf0e10cSrcweir                     w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ;
1472*cdf0e10cSrcweir                     h = SPIN_LOWER_BUTTON_HEIGHT + 2*CLIP_FUZZ;
1473*cdf0e10cSrcweir 
1474*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1475*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );
1476*cdf0e10cSrcweir 
1477*cdf0e10cSrcweir                     toReturn = sal_True;
1478*cdf0e10cSrcweir                 }
1479*cdf0e10cSrcweir             break;
1480*cdf0e10cSrcweir         case CTRL_FRAME:
1481*cdf0e10cSrcweir             {
1482*cdf0e10cSrcweir                 sal_uInt16 nStyle = aValue.getNumericVal();
1483*cdf0e10cSrcweir                 if(  ( nPart == PART_BORDER ) &&
1484*cdf0e10cSrcweir                     !( nStyle & (FRAME_DRAW_MENU | FRAME_DRAW_WINDOWBORDER | FRAME_DRAW_BORDERWINDOWBORDER) ) )
1485*cdf0e10cSrcweir                 {
1486*cdf0e10cSrcweir                     Rectangle aRect(aCtrlBoundRect);
1487*cdf0e10cSrcweir                     if( nStyle & FRAME_DRAW_DOUBLEIN )
1488*cdf0e10cSrcweir                     {
1489*cdf0e10cSrcweir                         aRect.Left()	+= 1;
1490*cdf0e10cSrcweir                         aRect.Top() 	+= 1;
1491*cdf0e10cSrcweir                         //rRect.Right()	-= 1;
1492*cdf0e10cSrcweir                         //rRect.Bottom()	-= 1;
1493*cdf0e10cSrcweir                     }
1494*cdf0e10cSrcweir                     else
1495*cdf0e10cSrcweir                     {
1496*cdf0e10cSrcweir                         aRect.Left()	+= 1;
1497*cdf0e10cSrcweir                         aRect.Top() 	+= 1;
1498*cdf0e10cSrcweir                         aRect.Right()	-= 1;
1499*cdf0e10cSrcweir                         aRect.Bottom()	-= 1;
1500*cdf0e10cSrcweir                     }
1501*cdf0e10cSrcweir 
1502*cdf0e10cSrcweir                     rNativeContentRegion = aRect;
1503*cdf0e10cSrcweir                     rNativeBoundingRegion = aRect;
1504*cdf0e10cSrcweir 
1505*cdf0e10cSrcweir                     toReturn = sal_True;
1506*cdf0e10cSrcweir                 }
1507*cdf0e10cSrcweir             }
1508*cdf0e10cSrcweir             break;
1509*cdf0e10cSrcweir 
1510*cdf0e10cSrcweir         case CTRL_MENUBAR:
1511*cdf0e10cSrcweir         case CTRL_MENU_POPUP:
1512*cdf0e10cSrcweir             {
1513*cdf0e10cSrcweir                 if(( nPart == PART_MENU_ITEM_CHECK_MARK )||( nPart == PART_MENU_ITEM_RADIO_MARK )) {
1514*cdf0e10cSrcweir 
1515*cdf0e10cSrcweir                     w=10;
1516*cdf0e10cSrcweir                     h=10;//dimensions of the mark (10px font)
1517*cdf0e10cSrcweir 
1518*cdf0e10cSrcweir                     rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
1519*cdf0e10cSrcweir                     rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );
1520*cdf0e10cSrcweir 
1521*cdf0e10cSrcweir                     toReturn = sal_True;
1522*cdf0e10cSrcweir                 }
1523*cdf0e10cSrcweir             }
1524*cdf0e10cSrcweir             break;
1525*cdf0e10cSrcweir 
1526*cdf0e10cSrcweir     }
1527*cdf0e10cSrcweir 
1528*cdf0e10cSrcweir     return toReturn;
1529*cdf0e10cSrcweir }
1530