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