Difference between revisions of "Cocoa Internals/Buttons"
m (→TrackBar) |
m (→TrackBar) |
||
Line 78: | Line 78: | ||
==TrackBar== | ==TrackBar== | ||
− | + | [[TTrackBar]] implementation is based on top of '''NSSlider''' class. | |
'''NSSlider''' doesn't have a defined property if it should vertical or horizontal. It draws itself depending on which size (height or width) is larger than another. Determining of preferred size is also uses the current TTrackBar dimension. Thus the frame rect might needs to be updated to match the selected orientation. | '''NSSlider''' doesn't have a defined property if it should vertical or horizontal. It draws itself depending on which size (height or width) is larger than another. Determining of preferred size is also uses the current TTrackBar dimension. Thus the frame rect might needs to be updated to match the selected orientation. |
Revision as of 20:21, 2 July 2019
Buttons Map
Despite of being a very basic control, buttons are complicated topic on macOS.
LCL Button | OSX Button / Style | Description |
---|---|---|
TButton | Push Button
NSRoundedBezelStyle |
Per macOS design guidelines, Push buttons should only have labels on them, and no Icons. This is exactly, how LCL TButton behaves.
The biggest issue, is that macOS Push Buttons are of the fixed height. While LCL buttons can be any height. The approach similar to Carbon implementation could be used - after a certain hight the button changes its bezel. currently r56760 it's disabled |
TBitBtn | Image Button
NSRegularSquareBezelStyle |
TBitBtn is a button that could hold an image in it's body.
The closest (not deprecated) to such tasks is NSRegularSquareBezelStyle in macOS TBitBtn could also be used as a replacement for TButton. I.e. TBitBtn could be a "Default" button on a modal dialog. And there's no corresponding replacement for that in macOS |
TSpeedButton | This is not an actual control button, it's LCL-drawn button.
todo: no themes API customdrawn controls used? The font used for caption of the button is NSFont.systemFontOfSize |
Textured styles
There are number of styles for buttons named "Textured" (i.e. NSTexturedRoundedBezelStyle, NSTexturedSquareBezelStyle). These buttons a designed to be used in "Metal" aka "Textured" style windows, and Window Frames (borders/tool bars) Thus these styles should not be used.
Sizing
Cocoa vs Carbon
Styles are for Cocoa and Carbon are a little bit different for buttons. For example "default" height of Push button is different between Cocoa and Carbon. Thus a UI designed for Carbon might not look good for Cocoa.
This is a problem of buttons only, other rectangular controls (textbox, listbox) doesn't experience such problem.
Control Sizes
Most buttons in macOS design have fixed height (i.e. Push Button). For such buttons macOS API provides property "controlSize". Buttons are available in 3 variations: regular, small, mini. Each variant paints in its own manner:
Since Lazarus r56773, the widgetset auto detects one of 3 variants from the button's Height.
Prior to that only "regular" size was used, causing visual artifacts, if height of a button was smaller than expected by controlSize.
Also, the font of a button is forced to match the detected controlSize. (Todo: should do it, only if standard font is selected.)
Example of artifact, if button's Height is 21 (it must be 32). Note that top edge is clipped, and some blue area is painted.
Smart Style Selection
In macOS guidelines, style of a button should be used depending on the placement/usage of a button.
In LCL design, there's not such thing as "style". It's presumed that the button would look the same, no matter where on the screen it's or what the button's parent. (It's not uncommon to design the interface in such a way).
Thus some LCLs might look foreign to macOS native applications, just because wrong button styles are used. I.e. a push button is used in a tool bar.
There are a few approaches what could be used:
- adding new TxxxButton classes into LCL (quite wasteful, and might not be applicable for other OSes)
- adding a style property to TBitBtn button (non delphi compatible)
- changes styles within Cocoa widgetset, automatically, depending on the placement of the button.
Radio Buttons
from stackoverflow
- NOTE: Use of NSMatrix is discouraged in apps that run in OS X v10.8 and later. If you need to create a radio button group in an app that runs in OS X v10.8 and later, create instances of NSButton that each specify a button type of NSRadioButton and specify the same action and the same superview for each button in the group.
If all buttons call the same action method and are in the same supperview, Cocoa automatically selects the clicked button and deselects the previous button and -- no code necessary to do that.
TrackBar
TTrackBar implementation is based on top of NSSlider class.
NSSlider doesn't have a defined property if it should vertical or horizontal. It draws itself depending on which size (height or width) is larger than another. Determining of preferred size is also uses the current TTrackBar dimension. Thus the frame rect might needs to be updated to match the selected orientation.
Autosizing allows to resize on of the size. (For Horizontal oriented trackbar, the height cannot be changed, while width can.)
NSSlider doesn't support custom tick marks. Those are drawn by TCocoaSlider class (refer to drawRect:) method.
See Also
- Cocoa Internals
- https://developer.apple.com/macos/human-interface-guidelines/buttons/checkboxes/ - the official guide to macOS button styles
- https://developer.apple.com/documentation/appkit/nsbezelstyle?language=objc - bezel constants descriptions
- https://mackuba.eu/2014/10/06/a-guide-to-nsbutton-styles/ - a non-official guide to macOS button styles