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