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