1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
21 #include <tools/long.hxx>
22 #include <vcl/salnativewidgets.hxx>
23 #include <vcl/decoview.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/timer.hxx>
26 #include <vcl/settings.hxx>
28 #include <quartz/salgdi.h>
29 #include <osx/salnativewidgets.h>
30 #include <osx/saldata.hxx>
31 #include <osx/salframe.h>
34 #include <Carbon/Carbon.h>
37 #include "cuidraw.hxx"
39 // presentation of native widgets consists of two important methods:
41 // AquaSalGraphics::getNativeControlRegion to determine native rectangle in pixels to draw the widget
42 // AquaSalGraphics::drawNativeControl to do the drawing operation itself
44 // getNativeControlRegion has to calculate a content rectangle within it is safe to draw the widget. Furthermore a bounding rectangle
45 // has to be calculated by getNativeControlRegion to consider adornments like a focus rectangle. As drawNativeControl uses Carbon
46 // API calls, all widgets are drawn without text. Drawing of text is done separately by VCL on top of graphical Carbon widget
47 // representation. drawNativeControl is called by VCL using content rectangle determined by getNativeControlRegion.
49 // FIXME: when calculation bounding rectangle larger then content rectangle, text displayed by VCL will become misaligned. To avoid
50 // misalignment bounding rectangle and content rectangle are calculated equally including adornments. Reduction of size for content
51 // is done by drawNativeControl subsequently. Only exception is editbox: As other widgets have distinct ControlPart::SubEdit control
52 // parts, editbox bounding rectangle and content rectangle are both calculated to reflect content area. Extending size for
53 // adornments is done by drawNativeControl subsequently.
55 #if !HAVE_FEATURE_MACOSX_SANDBOX
57 @interface
NSWindow(CoreUIRendererPrivate
)
58 + (CUIRendererRef
)coreUIRenderer
;
63 static HIRect
ImplGetHIRectFromRectangle(tools::Rectangle aRect
)
66 aHIRect
.origin
.x
= static_cast<float>(aRect
.Left());
67 aHIRect
.origin
.y
= static_cast<float>(aRect
.Top());
68 aHIRect
.size
.width
= static_cast<float>(aRect
.GetWidth());
69 aHIRect
.size
.height
= static_cast<float>(aRect
.GetHeight());
73 static ThemeButtonValue
ImplGetButtonValue(ButtonValue aButtonValue
)
78 return kThemeButtonOn
;
79 case ButtonValue::Off
:
80 case ButtonValue::DontKnow
:
81 return kThemeButtonOff
;
82 case ButtonValue::Mixed
:
84 return kThemeButtonMixed
;
88 static bool AquaGetScrollRect(/* TODO: int nScreen, */
89 ControlPart nPart
, const tools::Rectangle
&rControlRect
, tools::Rectangle
&rResultRect
)
92 rResultRect
= rControlRect
;
95 case ControlPart::ButtonUp
:
96 rResultRect
.SetBottom(rResultRect
.Top());
98 case ControlPart::ButtonDown
:
99 rResultRect
.SetTop(rResultRect
.Bottom());
101 case ControlPart::ButtonLeft
:
102 rResultRect
.SetRight(rResultRect
.Left());
104 case ControlPart::ButtonRight
:
105 rResultRect
.SetLeft(rResultRect
.Right());
107 case ControlPart::TrackHorzArea
:
108 case ControlPart::TrackVertArea
:
109 case ControlPart::ThumbHorz
:
110 case ControlPart::ThumbVert
:
111 case ControlPart::TrackHorzLeft
:
112 case ControlPart::TrackHorzRight
:
113 case ControlPart::TrackVertUpper
:
114 case ControlPart::TrackVertLower
:
122 bool AquaSalGraphics::isNativeControlSupported(ControlType nType
, ControlPart nPart
)
124 // native controls are now defaults. If you want to disable native controls, set the environment variable SAL_NO_NWF to
125 // something and VCL controls will be used as default again.
129 case ControlType::Pushbutton
:
130 case ControlType::Radiobutton
:
131 case ControlType::Checkbox
:
132 case ControlType::ListNode
:
133 if (nPart
== ControlPart::Entire
)
136 case ControlType::Scrollbar
:
137 if (nPart
== ControlPart::DrawBackgroundHorz
|| nPart
== ControlPart::DrawBackgroundVert
138 || nPart
== ControlPart::Entire
|| nPart
== ControlPart::HasThreeButtons
)
141 case ControlType::Slider
:
142 if (nPart
== ControlPart::TrackHorzArea
|| nPart
== ControlPart::TrackVertArea
)
145 case ControlType::Editbox
:
146 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::HasBackgroundTexture
)
149 case ControlType::MultilineEditbox
:
150 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::HasBackgroundTexture
)
153 case ControlType::Spinbox
:
154 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::AllButtons
|| nPart
== ControlPart::HasBackgroundTexture
)
157 case ControlType::SpinButtons
:
159 case ControlType::Combobox
:
160 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::HasBackgroundTexture
)
163 case ControlType::Listbox
:
164 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::ListboxWindow
|| nPart
== ControlPart::HasBackgroundTexture
165 || nPart
== ControlPart::SubEdit
)
168 case ControlType::TabItem
:
169 case ControlType::TabPane
:
170 case ControlType::TabBody
:
171 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::TabsDrawRtl
|| nPart
== ControlPart::HasBackgroundTexture
)
174 case ControlType::Toolbar
:
175 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::DrawBackgroundHorz
176 || nPart
== ControlPart::DrawBackgroundVert
)
179 case ControlType::WindowBackground
:
180 if (nPart
== ControlPart::BackgroundWindow
|| nPart
== ControlPart::BackgroundDialog
)
183 case ControlType::Menubar
:
184 if (nPart
== ControlPart::Entire
)
187 case ControlType::Tooltip
:
188 if (nPart
== ControlPart::Entire
)
191 case ControlType::MenuPopup
:
192 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::MenuItem
|| nPart
== ControlPart::MenuItemCheckMark
193 || nPart
== ControlPart::MenuItemRadioMark
)
196 case ControlType::Progress
:
197 case ControlType::IntroProgress
:
198 if (nPart
== ControlPart::Entire
)
201 case ControlType::Frame
:
202 if (nPart
== ControlPart::Border
)
205 case ControlType::ListNet
:
206 if (nPart
== ControlPart::Entire
)
215 bool AquaSalGraphics::hitTestNativeControl(ControlType nType
, ControlPart nPart
, const tools::Rectangle
&rControlRegion
,
216 const Point
&rPos
, bool& rIsInside
)
218 if (nType
== ControlType::Scrollbar
)
220 tools::Rectangle aRect
;
221 bool bValid
= AquaGetScrollRect(/* TODO: int nScreen, */
222 nPart
, rControlRegion
, aRect
);
223 rIsInside
= bValid
&& aRect
.IsInside(rPos
);
229 UInt32
AquaSalGraphics::getState(ControlState nState
)
232 // there are non key windows which are children of key windows, e.g. autofilter configuration dialog or sidebar dropdown dialogs.
233 // To handle these windows correctly, parent frame's key window state is considered here additionally.
235 const bool bDrawActive
= maShared
.mpFrame
== nullptr || [maShared
.mpFrame
->getNSWindow() isKeyWindow
]
236 || maShared
.mpFrame
->mpParent
== nullptr || [maShared
.mpFrame
->mpParent
->getNSWindow() isKeyWindow
];
237 if (!(nState
& ControlState::ENABLED
) || !bDrawActive
)
239 return kThemeStateInactive
;
241 if (nState
& ControlState::PRESSED
)
242 return kThemeStatePressed
;
243 return kThemeStateActive
;
246 UInt32
AquaSalGraphics::getTrackState(ControlState nState
)
248 const bool bDrawActive
= maShared
.mpFrame
== nullptr || [maShared
.mpFrame
->getNSWindow() isKeyWindow
];
249 if (!(nState
& ControlState::ENABLED
) || !bDrawActive
)
250 return kThemeTrackInactive
;
251 return kThemeTrackActive
;
254 bool AquaSalGraphics::drawNativeControl(ControlType nType
,
256 const tools::Rectangle
&rControlRegion
,
258 const ImplControlValue
&aValue
,
263 if (!maShared
.checkContext())
265 maShared
.maContextHolder
.saveState();
266 tools::Rectangle buttonRect
= rControlRegion
;
267 HIRect rc
= ImplGetHIRectFromRectangle(buttonRect
);
270 case ControlType::Toolbar
:
272 #if HAVE_FEATURE_MACOSX_SANDBOX
273 HIThemeMenuItemDrawInfo aMenuItemDrawInfo
;
274 aMenuItemDrawInfo
.version
= 0;
275 aMenuItemDrawInfo
.state
= kThemeMenuActive
;
276 aMenuItemDrawInfo
.itemType
= kThemeMenuItemHierBackground
;
277 HIThemeDrawMenuItem(&rc
, &rc
, &aMenuItemDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
279 if (rControlRegion
.Top() == 0 && nPart
== ControlPart::DrawBackgroundHorz
)
281 const bool bDrawActive
= maShared
.mpFrame
== nullptr || [maShared
.mpFrame
->getNSWindow() isKeyWindow
];
282 CGFloat unifiedHeight
= rControlRegion
.GetHeight();
283 CGRect drawRect
= CGRectMake(rControlRegion
.Left(), rControlRegion
.Top(),
284 rControlRegion
.GetWidth(), rControlRegion
.GetHeight());
285 CUIDraw([NSWindow coreUIRenderer
], drawRect
, maShared
.maContextHolder
.get(),
286 reinterpret_cast<CFDictionaryRef
>([NSDictionary dictionaryWithObjectsAndKeys
:
287 @
"kCUIWidgetWindowFrame",
291 (bDrawActive
? @
"normal" : @
"inactive"),
293 [NSNumber numberWithDouble
:unifiedHeight
],
294 @
"kCUIWindowFrameUnifiedTitleBarHeightKey",
295 [NSNumber numberWithBool
:NO
],
296 @
"kCUIWindowFrameDrawTitleSeparatorKey",
297 [NSNumber numberWithBool
:YES
],
304 HIThemeMenuItemDrawInfo aMenuItemDrawInfo
;
305 aMenuItemDrawInfo
.version
= 0;
306 aMenuItemDrawInfo
.state
= kThemeMenuActive
;
307 aMenuItemDrawInfo
.itemType
= kThemeMenuItemHierBackground
;
308 HIThemeDrawMenuItem(&rc
, &rc
, &aMenuItemDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
314 case ControlType::WindowBackground
:
316 HIThemeBackgroundDrawInfo aThemeBackgroundInfo
;
317 aThemeBackgroundInfo
.version
= 0;
318 aThemeBackgroundInfo
.state
= getState(nState
);
319 aThemeBackgroundInfo
.kind
= kThemeBrushDialogBackgroundActive
;
321 // FIXME: without this magical offset there is a 2 pixel black border on the right and bottom
325 HIThemeApplyBackground( &rc
, &aThemeBackgroundInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
326 CGContextFillRect(maShared
.maContextHolder
.get(), rc
);
330 case ControlType::Tooltip
:
332 HIThemeBackgroundDrawInfo aThemeBackgroundInfo
;
333 aThemeBackgroundInfo
.version
= 0;
334 aThemeBackgroundInfo
.state
= getState(nState
);
335 aThemeBackgroundInfo
.kind
= kThemeBrushAlertBackgroundActive
;
338 HIThemeApplyBackground(&rc
, &aThemeBackgroundInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
339 CGContextFillRect(maShared
.maContextHolder
.get(), rc
);
343 case ControlType::Menubar
:
344 case ControlType::MenuPopup
:
345 if (nPart
== ControlPart::Entire
|| nPart
== ControlPart::MenuItem
|| nPart
== ControlPart::HasBackgroundTexture
)
348 // FIXME: without this magical offset there is a 2 pixel black border on the right
351 HIThemeMenuDrawInfo aMenuInfo
;
352 aMenuInfo
.version
= 0;
353 aMenuInfo
.menuType
= kThemeMenuTypePullDown
;
354 HIThemeMenuItemDrawInfo aMenuItemDrawInfo
;
356 // grey theme when the item is selected is drawn here.
358 aMenuItemDrawInfo
.itemType
= kThemeMenuItemPlain
;
359 if ((nPart
== ControlPart::MenuItem
) && (nState
& ControlState::SELECTED
))
361 // blue theme when the item is selected is drawn here.
363 aMenuItemDrawInfo
.state
= kThemeMenuSelected
;
366 // normal color for non selected item
368 aMenuItemDrawInfo
.state
= kThemeMenuActive
;
370 // repaints the background of the pull down menu
372 HIThemeDrawMenuBackground(&rc
, &aMenuInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
374 // repaints the item either blue (selected) and/or grey (active only)
376 HIThemeDrawMenuItem(&rc
, &rc
, &aMenuItemDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, &rc
);
379 else if (nPart
== ControlPart::MenuItemCheckMark
|| nPart
== ControlPart::MenuItemRadioMark
)
382 // checked, else it is not displayed (see vcl/source/window/menu.cxx)
384 if (nState
& ControlState::PRESSED
)
386 HIThemeTextInfo aTextInfo
;
387 aTextInfo
.version
= 0;
388 aTextInfo
.state
= (nState
& ControlState::ENABLED
) ? kThemeStateInactive
: kThemeStateActive
;
389 aTextInfo
.fontID
= kThemeMenuItemMarkFont
;
390 aTextInfo
.horizontalFlushness
= kHIThemeTextHorizontalFlushCenter
;
391 aTextInfo
.verticalFlushness
= kHIThemeTextVerticalFlushTop
;
392 aTextInfo
.options
= kHIThemeTextBoxOptionNone
;
393 aTextInfo
.truncationPosition
= kHIThemeTextTruncationNone
;
395 // aTextInfo.truncationMaxLines unused because of kHIThemeTextTruncationNone item highlighted
397 if (nState
& ControlState::SELECTED
) aTextInfo
.state
= kThemeStatePressed
;
398 UniChar mark
=(nPart
== ControlPart::MenuItemCheckMark
) ? kCheckUnicode
: kBulletUnicode
;
399 CFStringRef cfString
= CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault
, &mark
, 1, kCFAllocatorNull
);
400 HIThemeDrawTextBox(cfString
, &rc
, &aTextInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
407 case ControlType::Pushbutton
:
410 // FIXME: instead of use a value, VCL can retrieve correct values on the fly (to be implemented)
412 HIThemeButtonDrawInfo aPushInfo
;
413 aPushInfo
.version
= 0;
417 aPushInfo
.animation
.time
.start
= 0;
418 aPushInfo
.animation
.time
.current
= 0;
419 PushButtonValue
const *pPBVal
= aValue
.getType() == ControlType::Pushbutton
?
420 static_cast<PushButtonValue
const *>(&aValue
) : nullptr;
421 int nPaintHeight
= static_cast<int>(rc
.size
.height
);
422 if (pPBVal
&& pPBVal
->mbBevelButton
)
424 aPushInfo
.kind
= kThemeRoundedBevelButton
;
426 else if (rc
.size
.height
<= PUSH_BUTTON_NORMAL_HEIGHT
)
428 aPushInfo
.kind
= kThemePushButtonMini
;
429 nPaintHeight
= PUSH_BUTTON_SMALL_HEIGHT
;
431 else if ((pPBVal
&& pPBVal
->mbSingleLine
) || rc
.size
.height
< PUSH_BUTTON_NORMAL_HEIGHT
* 3 / 2)
433 aPushInfo
.kind
= kThemePushButtonNormal
;
434 nPaintHeight
= PUSH_BUTTON_NORMAL_HEIGHT
;
436 // avoid clipping when focused
438 rc
.origin
.x
+= FOCUS_RING_WIDTH
/ 2;
439 rc
.size
.width
-= FOCUS_RING_WIDTH
;
442 aPushInfo
.kind
= kThemeBevelButton
;
444 // translate the origin for controls with fixed paint height so content ends up somewhere sensible
446 rc
.origin
.y
+= (rc
.size
.height
- nPaintHeight
) / 2;
447 aPushInfo
.state
= getState(nState
);
448 aPushInfo
.value
= ImplGetButtonValue(aValue
.getTristateVal());
449 aPushInfo
.adornment
= (nState
& ControlState::DEFAULT
) ? kThemeAdornmentDefault
: kThemeAdornmentNone
;
450 if (nState
& ControlState::FOCUSED
)
451 aPushInfo
.adornment
|= kThemeAdornmentFocus
;
452 HIThemeDrawButton(&rc
, &aPushInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
456 case ControlType::Radiobutton
:
457 case ControlType::Checkbox
:
459 HIThemeButtonDrawInfo aInfo
;
463 case ControlType::Radiobutton
:
464 if (rc
.size
.width
>= RADIO_BUTTON_SMALL_SIZE
)
465 aInfo
.kind
= kThemeRadioButton
;
467 aInfo
.kind
= kThemeSmallRadioButton
;
469 case ControlType::Checkbox
:
470 if (rc
.size
.width
>= CHECKBOX_SMALL_SIZE
)
471 aInfo
.kind
= kThemeCheckBox
;
473 aInfo
.kind
= kThemeSmallCheckBox
;
478 aInfo
.state
= getState(nState
);
479 ButtonValue aButtonValue
= aValue
.getTristateVal();
480 aInfo
.value
= ImplGetButtonValue(aButtonValue
);
481 aInfo
.adornment
= (nState
& ControlState::DEFAULT
) ? kThemeAdornmentDefault
: kThemeAdornmentNone
;
482 if (nState
& ControlState::FOCUSED
)
483 aInfo
.adornment
|= kThemeAdornmentFocus
;
484 rc
.size
.width
-= 2 * FOCUS_RING_WIDTH
;
485 rc
.size
.height
= RADIO_BUTTON_SMALL_SIZE
;
486 rc
.origin
.x
+= FOCUS_RING_WIDTH
;
487 rc
.origin
.y
+= FOCUS_RING_WIDTH
;
488 HIThemeDrawButton(&rc
, &aInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
492 case ControlType::ListNode
:
494 ButtonValue aButtonValue
= aValue
.getTristateVal();
495 HIThemeButtonDrawInfo aInfo
;
497 aInfo
.kind
= kThemeDisclosureTriangle
;
498 aInfo
.value
= kThemeDisclosureRight
;
499 aInfo
.state
= getState(nState
);
500 aInfo
.adornment
= kThemeAdornmentNone
;
501 switch (aButtonValue
)
503 case ButtonValue::On
:
504 aInfo
.value
= kThemeDisclosureDown
;
506 case ButtonValue::Off
:
507 if (AllSettings::GetLayoutRTL())
508 aInfo
.value
= kThemeDisclosureLeft
;
510 case ButtonValue::DontKnow
:
514 HIThemeDrawButton(&rc
, &aInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
518 case ControlType::Progress
:
519 case ControlType::IntroProgress
:
521 tools::Long nProgressWidth
= aValue
.getNumericVal();
522 HIThemeTrackDrawInfo aTrackInfo
;
523 aTrackInfo
.version
= 0;
524 aTrackInfo
.kind
= (rc
.size
.height
> 10) ? kThemeProgressBarLarge
: kThemeProgressBarMedium
;
525 aTrackInfo
.bounds
= rc
;
527 aTrackInfo
.max
= static_cast<SInt32
>(rc
.size
.width
);
528 aTrackInfo
.value
= nProgressWidth
;
529 aTrackInfo
.reserved
= 0;
530 aTrackInfo
.attributes
= kThemeTrackHorizontal
;
531 if (AllSettings::GetLayoutRTL())
532 aTrackInfo
.attributes
|= kThemeTrackRightToLeft
;
533 aTrackInfo
.enableState
= getTrackState(nState
);
535 // the intro bitmap never gets key anyway; we want to draw that enabled
537 if (nType
== ControlType::IntroProgress
)
538 aTrackInfo
.enableState
= kThemeTrackActive
;
539 aTrackInfo
.filler1
= 0;
540 aTrackInfo
.trackInfo
.progress
.phase
= static_cast<long long>(CFAbsoluteTimeGetCurrent() * 10.0);
541 HIThemeDrawTrack(&aTrackInfo
, nullptr, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
545 case ControlType::Slider
:
547 const SliderValue
*pSliderVal
= static_cast<SliderValue
const *>(&aValue
);
548 HIThemeTrackDrawInfo aTrackDraw
;
549 aTrackDraw
.kind
= kThemeSliderMedium
;
550 if (nPart
== ControlPart::TrackHorzArea
|| nPart
== ControlPart::TrackVertArea
)
552 aTrackDraw
.bounds
= rc
;
553 aTrackDraw
.min
= pSliderVal
->mnMin
;
554 aTrackDraw
.max
= pSliderVal
->mnMax
;
555 aTrackDraw
.value
= pSliderVal
->mnCur
;
556 aTrackDraw
.reserved
= 0;
557 aTrackDraw
.attributes
= kThemeTrackShowThumb
;
558 if (nPart
== ControlPart::TrackHorzArea
)
559 aTrackDraw
.attributes
|= kThemeTrackHorizontal
;
560 aTrackDraw
.enableState
= (nState
& ControlState::ENABLED
) ? kThemeTrackActive
: kThemeTrackInactive
;
561 SliderTrackInfo aSlideInfo
;
562 aSlideInfo
.thumbDir
= kThemeThumbUpward
;
563 aSlideInfo
.pressState
= 0;
564 aTrackDraw
.trackInfo
.slider
= aSlideInfo
;
565 HIThemeDrawTrack(&aTrackDraw
, nullptr, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
570 case ControlType::Scrollbar
:
572 const ScrollbarValue
*pScrollbarVal
= (aValue
.getType() == ControlType::Scrollbar
)
573 ? static_cast<const ScrollbarValue
*>(&aValue
) : nullptr;
574 if (nPart
== ControlPart::DrawBackgroundVert
|| nPart
== ControlPart::DrawBackgroundHorz
)
576 HIThemeTrackDrawInfo aTrackDraw
;
577 aTrackDraw
.kind
= kThemeMediumScrollBar
;
578 aTrackDraw
.bounds
= rc
;
579 aTrackDraw
.min
= pScrollbarVal
->mnMin
;
580 aTrackDraw
.max
= pScrollbarVal
->mnMax
- pScrollbarVal
->mnVisibleSize
;
581 aTrackDraw
.value
= pScrollbarVal
->mnCur
;
582 aTrackDraw
.reserved
= 0;
583 aTrackDraw
.attributes
= kThemeTrackShowThumb
;
584 if (nPart
== ControlPart::DrawBackgroundHorz
)
585 aTrackDraw
.attributes
|= kThemeTrackHorizontal
;
586 aTrackDraw
.enableState
= getTrackState(nState
);
587 ScrollBarTrackInfo aScrollInfo
;
588 aScrollInfo
.viewsize
= pScrollbarVal
->mnVisibleSize
;
589 aScrollInfo
.pressState
= 0;
590 if (pScrollbarVal
->mnButton1State
& ControlState::ENABLED
)
591 if (pScrollbarVal
->mnButton1State
& ControlState::PRESSED
)
592 aScrollInfo
.pressState
= kThemeTopOutsideArrowPressed
;
593 if (pScrollbarVal
->mnButton2State
& ControlState::ENABLED
)
594 if (pScrollbarVal
->mnButton2State
& ControlState::PRESSED
)
595 aScrollInfo
.pressState
= kThemeBottomOutsideArrowPressed
;
596 if ( pScrollbarVal
->mnThumbState
& ControlState::ENABLED
)
597 if (pScrollbarVal
->mnThumbState
& ControlState::PRESSED
)
598 aScrollInfo
.pressState
= kThemeThumbPressed
;
599 aTrackDraw
.trackInfo
.scrollbar
= aScrollInfo
;
600 HIThemeDrawTrack(&aTrackDraw
, nullptr, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
605 case ControlType::TabPane
:
607 HIThemeTabPaneDrawInfo aTabPaneDrawInfo
;
608 aTabPaneDrawInfo
.version
= 1;
609 aTabPaneDrawInfo
.state
= kThemeStateActive
;
610 aTabPaneDrawInfo
.direction
= kThemeTabNorth
;
611 aTabPaneDrawInfo
.size
= kHIThemeTabSizeNormal
;
612 aTabPaneDrawInfo
.kind
= kHIThemeTabKindNormal
;
614 // border is outside the rect rc for Carbon but for VCL it should be inside
617 rc
.origin
.y
-= TAB_HEIGHT
/ 2;
618 rc
.size
.height
+= TAB_HEIGHT
/ 2;
620 HIThemeDrawTabPane(&rc
, &aTabPaneDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
624 case ControlType::TabItem
:
626 HIThemeTabDrawInfo aTabItemDrawInfo
;
627 aTabItemDrawInfo
.version
= 1;
628 aTabItemDrawInfo
.style
= kThemeTabNonFront
;
629 aTabItemDrawInfo
.direction
= kThemeTabNorth
;
630 aTabItemDrawInfo
.size
= kHIThemeTabSizeNormal
;
631 aTabItemDrawInfo
.adornment
= kHIThemeTabAdornmentTrailingSeparator
;
632 if (nState
& ControlState::SELECTED
)
633 aTabItemDrawInfo
.style
= kThemeTabFront
;
634 if(nState
& ControlState::FOCUSED
)
635 aTabItemDrawInfo
.adornment
|= kHIThemeTabAdornmentFocus
;
637 // first, last or middle tab
639 aTabItemDrawInfo
.position
= kHIThemeTabPositionMiddle
;
640 TabitemValue
const * pTabValue
= static_cast<TabitemValue
const *>(&aValue
);
641 TabitemFlags nAlignment
= pTabValue
->mnAlignment
;
643 // TabitemFlags::LeftAligned (and TabitemFlags::RightAligned) for the leftmost (or rightmost) tab
644 // when there are several lines of tabs because there is only one first tab and one
645 // last tab and TabitemFlags::FirstInGroup (and TabitemFlags::LastInGroup) because when the
646 // line width is different from window width, there may not be TabitemFlags::RightAligned
648 if (((nAlignment
& TabitemFlags::LeftAligned
) && (nAlignment
& TabitemFlags::RightAligned
))
649 || ((nAlignment
& TabitemFlags::FirstInGroup
) && (nAlignment
& TabitemFlags::LastInGroup
)))
650 aTabItemDrawInfo
.position
= kHIThemeTabPositionOnly
;
651 else if ((nAlignment
& TabitemFlags::LeftAligned
) || (nAlignment
& TabitemFlags::FirstInGroup
))
652 aTabItemDrawInfo
.position
= kHIThemeTabPositionFirst
;
653 else if ((nAlignment
& TabitemFlags::RightAligned
) || (nAlignment
& TabitemFlags::LastInGroup
))
654 aTabItemDrawInfo
.position
= kHIThemeTabPositionLast
;
656 // support for RTL (see issue 79748)
658 if (AllSettings::GetLayoutRTL()) {
659 if (aTabItemDrawInfo
.position
== kHIThemeTabPositionFirst
)
660 aTabItemDrawInfo
.position
= kHIThemeTabPositionLast
;
661 else if (aTabItemDrawInfo
.position
== kHIThemeTabPositionLast
)
662 aTabItemDrawInfo
.position
= kHIThemeTabPositionFirst
;
664 HIThemeDrawTab(&rc
, &aTabItemDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
668 case ControlType::Editbox
:
669 case ControlType::MultilineEditbox
:
671 HIThemeFrameDrawInfo aTextDrawInfo
;
672 aTextDrawInfo
.version
= 0;
673 aTextDrawInfo
.kind
= kHIThemeFrameTextFieldSquare
;
674 aTextDrawInfo
.state
= getState(nState
);
675 aTextDrawInfo
.isFocused
= false;
676 rc
.size
.width
+= 2 * EDITBOX_INSET_MARGIN
;
677 if (nType
== ControlType::Editbox
)
678 rc
.size
.height
= EDITBOX_HEIGHT
;
680 rc
.size
.height
+= 2 * (EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
);
681 rc
.origin
.x
-= EDITBOX_INSET_MARGIN
;
682 rc
.origin
.y
-= EDITBOX_INSET_MARGIN
;
684 // fill a white background, because HIThemeDrawFrame only draws the border
686 CGContextFillRect(maShared
.maContextHolder
.get(), CGRectMake(rc
.origin
.x
, rc
.origin
.y
, rc
.size
.width
, rc
.size
.height
));
687 HIThemeDrawFrame(&rc
, &aTextDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
688 if (nState
& ControlState::FOCUSED
)
689 HIThemeDrawFocusRect(&rc
, true, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
693 case ControlType::Combobox
:
694 if (nPart
== ControlPart::HasBackgroundTexture
|| nPart
== ControlPart::Entire
)
696 HIThemeButtonDrawInfo aComboInfo
;
697 aComboInfo
.version
= 0;
698 aComboInfo
.kind
= kThemeComboBox
;
699 aComboInfo
.state
= getState(nState
);
700 aComboInfo
.value
= kThemeButtonOn
;
701 aComboInfo
.adornment
= kThemeAdornmentNone
;
702 if (nState
& ControlState::FOCUSED
)
703 aComboInfo
.adornment
|= kThemeAdornmentFocus
;
704 rc
.size
.width
-= 2 * FOCUS_RING_WIDTH
;
705 rc
.size
.height
= COMBOBOX_HEIGHT
;
706 rc
.origin
.x
+= FOCUS_RING_WIDTH
;
707 rc
.origin
.y
+= FOCUS_RING_WIDTH
;
708 HIThemeDrawButton(&rc
, &aComboInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
712 case ControlType::Listbox
:
715 case ControlPart::Entire
:
716 case ControlPart::ButtonDown
:
717 HIThemeButtonDrawInfo aListInfo
;
718 aListInfo
.version
= 0;
719 aListInfo
.kind
= kThemePopupButton
;
720 aListInfo
.state
= getState(nState
);
721 aListInfo
.value
= kThemeButtonOn
;
722 aListInfo
.adornment
= kThemeAdornmentDefault
;
723 if (nState
& ControlState::FOCUSED
)
724 aListInfo
.adornment
|= kThemeAdornmentFocus
;
725 rc
.size
.width
-= 2 * FOCUS_RING_WIDTH
;
726 rc
.size
.height
= LISTBOX_HEIGHT
;
727 rc
.origin
.x
+= FOCUS_RING_WIDTH
;
728 rc
.origin
.y
+= FOCUS_RING_WIDTH
;
729 HIThemeDrawButton(&rc
, &aListInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
732 case ControlPart::ListboxWindow
:
733 HIThemeFrameDrawInfo aTextDrawInfo
;
734 aTextDrawInfo
.version
= 0;
735 aTextDrawInfo
.kind
= kHIThemeFrameListBox
;
736 aTextDrawInfo
.state
= kThemeStateActive
;
737 aTextDrawInfo
.isFocused
= false;
738 HIThemeDrawFrame(&rc
, &aTextDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
745 case ControlType::Spinbox
:
746 if (nPart
== ControlPart::Entire
)
751 HIThemeFrameDrawInfo aTextDrawInfo
;
752 aTextDrawInfo
.version
= 0;
753 aTextDrawInfo
.kind
= kHIThemeFrameTextFieldSquare
;
754 aTextDrawInfo
.state
= getState(nState
);
755 aTextDrawInfo
.isFocused
= false;
756 rc
.size
.width
-= SPIN_BUTTON_WIDTH
+ 4 * FOCUS_RING_WIDTH
;
757 rc
.size
.height
= EDITBOX_HEIGHT
;
758 rc
.origin
.x
+= FOCUS_RING_WIDTH
;
759 rc
.origin
.y
+= FOCUS_RING_WIDTH
;
761 // fill a white background, because HIThemeDrawFrame only draws the border
763 CGContextFillRect(maShared
.maContextHolder
.get(), CGRectMake(rc
.origin
.x
, rc
.origin
.y
, rc
.size
.width
, rc
.size
.height
));
764 HIThemeDrawFrame(&rc
, &aTextDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
765 if (nState
& ControlState::FOCUSED
)
766 HIThemeDrawFocusRect(&rc
, true, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
770 const SpinbuttonValue
*pSpinButtonVal
= (aValue
.getType() == ControlType::SpinButtons
)
771 ? static_cast <const SpinbuttonValue
*>(&aValue
) : nullptr;
772 ControlState nUpperState
= ControlState::ENABLED
;
773 ControlState nLowerState
= ControlState::ENABLED
;
776 nUpperState
= pSpinButtonVal
->mnUpperState
;
777 nLowerState
= pSpinButtonVal
->mnLowerState
;
778 HIThemeButtonDrawInfo aSpinInfo
;
779 aSpinInfo
.kind
= kThemeIncDecButton
;
780 aSpinInfo
.state
= kThemeStateActive
;
781 if (nUpperState
& ControlState::PRESSED
)
782 aSpinInfo
.state
= kThemeStatePressedUp
;
783 else if (nLowerState
& ControlState::PRESSED
)
784 aSpinInfo
.state
= kThemeStatePressedDown
;
785 else if (nUpperState
& ~ControlState::ENABLED
|| nLowerState
& ~ControlState::ENABLED
)
786 aSpinInfo
.state
= kThemeStateInactive
;
787 else if (nUpperState
& ControlState::ROLLOVER
|| nLowerState
& ControlState::ROLLOVER
)
788 aSpinInfo
.state
= kThemeStateRollover
;
789 switch (aValue
.getTristateVal())
791 case ButtonValue::On
:
792 aSpinInfo
.value
= kThemeButtonOn
;
794 case ButtonValue::Off
:
795 aSpinInfo
.value
= kThemeButtonOff
;
797 case ButtonValue::Mixed
:
798 case ButtonValue::DontKnow
:
800 aSpinInfo
.value
= kThemeButtonMixed
;
803 aSpinInfo
.adornment
= (nUpperState
& ControlState::DEFAULT
|| nLowerState
& ControlState::DEFAULT
)
804 ? kThemeAdornmentDefault
: kThemeAdornmentNone
;
805 if (nUpperState
& ControlState::FOCUSED
|| nLowerState
& ControlState::FOCUSED
)
806 aSpinInfo
.adornment
|= kThemeAdornmentFocus
;
807 rc
.origin
.x
+= rc
.size
.width
+ FOCUS_RING_WIDTH
+ 1;
809 rc
.size
.width
= SPIN_BUTTON_WIDTH
;
810 rc
.size
.height
= SPIN_LOWER_BUTTON_HEIGHT
+ SPIN_LOWER_BUTTON_HEIGHT
;
811 HIThemeDrawButton(&rc
, &aSpinInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
, nullptr);
816 case ControlType::Frame
:
818 DrawFrameFlags nStyle
= static_cast<DrawFrameFlags
>(aValue
.getNumericVal());
819 if (nPart
== ControlPart::Border
)
821 if (!(nStyle
& DrawFrameFlags::Menu
) && !(nStyle
& DrawFrameFlags::WindowBorder
))
824 // strange effects start to happen when HIThemeDrawFrame meets the border of the window.
825 // These can be avoided by clipping to the boundary of the frame (see issue 84756)
827 if (rc
.origin
.y
+ rc
.size
.height
>= maShared
.mpFrame
->maGeometry
.nHeight
- 3)
829 CGMutablePathRef rPath
= CGPathCreateMutable();
830 CGPathAddRect(rPath
, nullptr,
831 CGRectMake(0, 0, maShared
.mpFrame
->maGeometry
.nWidth
- 1, maShared
.mpFrame
->maGeometry
.nHeight
- 1));
832 CGContextBeginPath(maShared
.maContextHolder
.get());
833 CGContextAddPath(maShared
.maContextHolder
.get(), rPath
);
834 CGContextClip(maShared
.maContextHolder
.get());
835 CGPathRelease(rPath
);
837 HIThemeFrameDrawInfo aTextDrawInfo
;
838 aTextDrawInfo
.version
= 0;
839 aTextDrawInfo
.kind
= kHIThemeFrameListBox
;
840 aTextDrawInfo
.state
= kThemeStateActive
;
841 aTextDrawInfo
.isFocused
= false;
842 HIThemeDrawFrame(&rc
, &aTextDrawInfo
, maShared
.maContextHolder
.get(), kHIThemeOrientationNormal
);
848 case ControlType::ListNet
:
850 // do nothing as there isn't net for listviews on macOS
857 maShared
.maContextHolder
.restoreState();
859 // in most cases invalidating the whole control region instead of just the unclipped part of it is sufficient (and probably
860 // faster). However for the window background we should not unnecessarily enlarge the really changed rectangle since the
861 // difference is usually quite high. Background is always drawn as a whole since we don't know anything about its possible
862 // contents (see issue i90291).
864 if (nType
== ControlType::WindowBackground
)
866 CGRect aRect
= {{0, 0}, {0, 0}};
867 if (maShared
.mxClipPath
)
868 aRect
= CGPathGetBoundingBox(maShared
.mxClipPath
);
869 if (aRect
.size
.width
!= 0 && aRect
.size
.height
!= 0)
870 buttonRect
.Intersection(tools::Rectangle(Point(static_cast<tools::Long
>(aRect
.origin
.x
),
871 static_cast<tools::Long
>(aRect
.origin
.y
)),
872 Size(static_cast<tools::Long
>(aRect
.size
.width
),
873 static_cast<tools::Long
>(aRect
.size
.height
))));
875 maShared
.refreshRect(buttonRect
.Left(), buttonRect
.Top(), buttonRect
.GetWidth(), buttonRect
.GetHeight());
879 bool AquaSalGraphics::getNativeControlRegion(ControlType nType
,
881 const tools::Rectangle
&rControlRegion
,
883 const ImplControlValue
&aValue
,
885 tools::Rectangle
&rNativeBoundingRegion
,
886 tools::Rectangle
&rNativeContentRegion
)
888 bool toReturn
= false;
889 tools::Rectangle
aCtrlBoundRect(rControlRegion
);
890 short x
= aCtrlBoundRect
.Left();
891 short y
= aCtrlBoundRect
.Top();
895 case ControlType::Pushbutton
:
896 case ControlType::Radiobutton
:
897 case ControlType::Checkbox
:
899 if (nType
== ControlType::Pushbutton
)
901 w
= aCtrlBoundRect
.GetWidth();
902 h
= aCtrlBoundRect
.GetHeight();
906 w
= RADIO_BUTTON_SMALL_SIZE
+ 2 * FOCUS_RING_WIDTH
+ RADIO_BUTTON_TEXT_SEPARATOR
;
907 h
= RADIO_BUTTON_SMALL_SIZE
+ 2 * FOCUS_RING_WIDTH
;
909 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
910 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
914 case ControlType::Progress
:
916 tools::Rectangle
aRect(aCtrlBoundRect
);
917 if (aRect
.GetHeight() < LARGE_PROGRESS_INDICATOR_HEIGHT
)
918 aRect
.SetBottom(aRect
.Top() + MEDIUM_PROGRESS_INDICATOR_HEIGHT
- 1);
920 aRect
.SetBottom(aRect
.Top() + LARGE_PROGRESS_INDICATOR_HEIGHT
- 1);
921 rNativeBoundingRegion
= aRect
;
922 rNativeContentRegion
= aRect
;
926 case ControlType::IntroProgress
:
928 tools::Rectangle
aRect(aCtrlBoundRect
);
929 aRect
.SetBottom(aRect
.Top() + MEDIUM_PROGRESS_INDICATOR_HEIGHT
- 1);
930 rNativeBoundingRegion
= aRect
;
931 rNativeContentRegion
= aRect
;
935 case ControlType::Slider
:
936 if (nPart
== ControlPart::ThumbHorz
)
939 h
= aCtrlBoundRect
.GetHeight();
940 rNativeBoundingRegion
= rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
943 else if (nPart
== ControlPart::ThumbVert
)
945 w
= aCtrlBoundRect
.GetWidth();
947 rNativeBoundingRegion
= rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
951 case ControlType::Scrollbar
:
953 tools::Rectangle aRect
;
954 if (AquaGetScrollRect(nPart
, aCtrlBoundRect
, aRect
))
957 rNativeBoundingRegion
= aRect
;
958 rNativeContentRegion
= aRect
;
962 case ControlType::TabItem
:
964 w
= aCtrlBoundRect
.GetWidth() + 2 * TAB_TEXT_MARGIN
;
966 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
967 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
971 case ControlType::Editbox
:
973 w
= aCtrlBoundRect
.GetWidth();
974 h
= EDITBOX_HEIGHT
+ 2 * FOCUS_RING_WIDTH
;
975 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
976 w
-= 2 * (FOCUS_RING_WIDTH
+ EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
);
977 h
-= 2 * (FOCUS_RING_WIDTH
+ EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
);
978 x
+= FOCUS_RING_WIDTH
+ EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
;
979 y
+= FOCUS_RING_WIDTH
+ EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
;
980 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
984 case ControlType::Combobox
:
985 if (nPart
== ControlPart::Entire
)
987 w
= aCtrlBoundRect
.GetWidth();
988 h
= COMBOBOX_HEIGHT
+ 2 * FOCUS_RING_WIDTH
;
989 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
990 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
993 else if (nPart
== ControlPart::ButtonDown
)
995 w
= COMBOBOX_BUTTON_WIDTH
+ FOCUS_RING_WIDTH
;
996 h
= COMBOBOX_HEIGHT
+ 2 * FOCUS_RING_WIDTH
;
997 x
+= aCtrlBoundRect
.GetWidth() - w
;
998 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
999 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1002 else if (nPart
== ControlPart::SubEdit
)
1004 w
= aCtrlBoundRect
.GetWidth() - 2 * FOCUS_RING_WIDTH
- COMBOBOX_BUTTON_WIDTH
- COMBOBOX_BORDER_WIDTH
1005 - 2 * COMBOBOX_TEXT_MARGIN
;
1006 h
= COMBOBOX_HEIGHT
- 2 * COMBOBOX_BORDER_WIDTH
;
1007 x
+= FOCUS_RING_WIDTH
+ COMBOBOX_BORDER_WIDTH
+ COMBOBOX_TEXT_MARGIN
;
1008 y
+= FOCUS_RING_WIDTH
+ COMBOBOX_BORDER_WIDTH
;
1009 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1010 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1014 case ControlType::Listbox
:
1015 if (nPart
== ControlPart::Entire
)
1017 w
= aCtrlBoundRect
.GetWidth();
1018 h
= LISTBOX_HEIGHT
+ 2 * FOCUS_RING_WIDTH
;
1019 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1020 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1023 else if (nPart
== ControlPart::ButtonDown
)
1025 w
= LISTBOX_BUTTON_WIDTH
+ FOCUS_RING_WIDTH
;
1026 h
= LISTBOX_HEIGHT
+ 2 * FOCUS_RING_WIDTH
;
1027 x
+= aCtrlBoundRect
.GetWidth() - w
;
1028 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1029 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1032 else if (nPart
== ControlPart::SubEdit
)
1034 w
= aCtrlBoundRect
.GetWidth() - 2 * FOCUS_RING_WIDTH
- LISTBOX_BUTTON_WIDTH
- LISTBOX_BORDER_WIDTH
1035 - 2 * LISTBOX_TEXT_MARGIN
;
1036 h
= LISTBOX_HEIGHT
- 2 * LISTBOX_BORDER_WIDTH
;
1037 x
+= FOCUS_RING_WIDTH
+ LISTBOX_BORDER_WIDTH
+ LISTBOX_TEXT_MARGIN
;
1038 y
+= FOCUS_RING_WIDTH
+ LISTBOX_BORDER_WIDTH
;
1039 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1040 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1043 else if (nPart
== ControlPart::ListboxWindow
)
1045 w
= aCtrlBoundRect
.GetWidth() - 2;
1046 h
= aCtrlBoundRect
.GetHeight() - 2;
1049 rNativeBoundingRegion
= aCtrlBoundRect
;
1050 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1054 case ControlType::Spinbox
:
1055 if (nPart
== ControlPart::Entire
)
1057 w
= aCtrlBoundRect
.GetWidth();
1058 h
= EDITBOX_HEIGHT
+ 2 * FOCUS_RING_WIDTH
;
1059 x
+= SPINBOX_OFFSET
;
1060 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1061 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1064 else if (nPart
== ControlPart::SubEdit
)
1066 w
= aCtrlBoundRect
.GetWidth() - 4 * FOCUS_RING_WIDTH
- SPIN_BUTTON_WIDTH
- 2 * EDITBOX_BORDER_WIDTH
1067 - 2 * EDITBOX_INSET_MARGIN
;
1068 h
= EDITBOX_HEIGHT
- 2 * (EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
);
1069 x
+= FOCUS_RING_WIDTH
+ EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
+ SPINBOX_OFFSET
;
1070 y
+= FOCUS_RING_WIDTH
+ EDITBOX_BORDER_WIDTH
+ EDITBOX_INSET_MARGIN
;
1071 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1072 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1075 else if (nPart
== ControlPart::ButtonUp
)
1077 w
= SPIN_BUTTON_WIDTH
+ 2 * FOCUS_RING_WIDTH
;
1078 h
= SPIN_UPPER_BUTTON_HEIGHT
+ FOCUS_RING_WIDTH
;
1079 x
+= aCtrlBoundRect
.GetWidth() - SPIN_BUTTON_WIDTH
- 2 * FOCUS_RING_WIDTH
+ SPINBOX_OFFSET
;
1080 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1081 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1084 else if (nPart
== ControlPart::ButtonDown
)
1086 w
= SPIN_BUTTON_WIDTH
+ 2 * FOCUS_RING_WIDTH
;
1087 h
= SPIN_LOWER_BUTTON_HEIGHT
+ FOCUS_RING_WIDTH
;
1088 x
+= aCtrlBoundRect
.GetWidth() - SPIN_BUTTON_WIDTH
- 2 * FOCUS_RING_WIDTH
+ SPINBOX_OFFSET
;
1089 y
+= FOCUS_RING_WIDTH
+ SPIN_UPPER_BUTTON_HEIGHT
;
1090 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1091 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1095 case ControlType::Frame
:
1097 DrawFrameStyle nStyle
= static_cast<DrawFrameStyle
>(aValue
.getNumericVal() & 0x000f);
1098 DrawFrameFlags nFlags
= static_cast<DrawFrameFlags
>(aValue
.getNumericVal() & 0xfff0);
1099 if (nPart
== ControlPart::Border
1100 && !(nFlags
& (DrawFrameFlags::Menu
| DrawFrameFlags::WindowBorder
| DrawFrameFlags::BorderWindowBorder
)))
1102 tools::Rectangle
aRect(aCtrlBoundRect
);
1103 if (nStyle
== DrawFrameStyle::DoubleIn
)
1105 aRect
.AdjustLeft(1);
1107 // rRect.Right() -= 1;
1108 // rRect.Bottom() -= 1;
1112 aRect
.AdjustLeft(1);
1114 aRect
.AdjustRight(-1);
1115 aRect
.AdjustBottom(-1);
1117 rNativeContentRegion
= aRect
;
1118 rNativeBoundingRegion
= aRect
;
1123 case ControlType::Menubar
:
1124 case ControlType::MenuPopup
:
1125 if (nPart
== ControlPart::MenuItemCheckMark
|| nPart
== ControlPart::MenuItemRadioMark
)
1129 rNativeContentRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1130 rNativeBoundingRegion
= tools::Rectangle(Point(x
, y
), Size(w
, h
));
1140 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */