How to make a NSToolbar item toggle state - macos

I have an NSToolbar with NSToolbarItem instances. One of the toolbar buttons is in one of two modes, depending on whether it currently operating (has been clicked) or not. I am handling this in code by changing the icon for the button to have a background rectangle when the command it represents is operational, but I can't help thinking there must be another way.
I've tried using the Selectable checkbox in XCode Interface Builder attribute inspector, and it sort of gives the result I want, except when it is selected I can't click any of the other toolbar items. I also can't see how to deselect it.
I'm a bit of a Cocoa noob so I expect the two state toggle thing is just waiting for me to find it, except so far I haven't been able to.
This seems like it would be a common thing to want to do, thing is how?

Related

How to display elements inside NSCollectionView with various shapes

I am a rookie Cocoa guy. I need to design and implement a view which will show collection of labels on Mac OS using Xamarin. These labels will have a text and color associated with them. When shown inside the view, label should expand till it covers whole text and it will be shown with background and foreground colors.
I have attached the picture of this user control on Windows, you can see that labels inside the StackPanel are expanding till they cover the whole text. Hope this gives better idea about my ask.
The $64,000 question is "are these labels controls?" In other words, do you expect the user to click on these to do something, or are they just for display?
If your answer is "just for display", the solution is super simple: Use an NSTextField and programmatically add attributed text (NSAttributedString) to it. Attributed text attaches display properties to runs of text within the field; properties like "background color".
If you want these to be buttons that you can click on, then things get a lot more complicated.
Since you apparently want the button layout to "flow", you might look into imbedding buttons (well, button cells) into an NSTextField using attachments. This is normally how non-text content (say, an image) can be inserted, but with some fiddling it can actually be anything a control cell can draw. See How to insert a NSButton into a NSTextView? (inline).
Warning: this is not a "rookie" topic and will involve control cells and custom event handling.
If I were doing this, I'd probably just create NSButton objects for each label (choosing an appropriate style/look like NSRecessedBezelStyle), create a custom subclass of NSView to contain them, and then override the layout method to position all of the buttons the way I want.
To be thorough, I'd also override the intrinsic size methods so the whole thing could participate in auto-layout, based on the number and size of buttons it contained.

How to create consistent toolbar buttons with icons

Desired look
I wish to make a toolbar for my app that will contain some simple buttons, each with a single monochromatic icon. Here is an example of some toolbar buttons similar to I'm trying to achieve, from Mail's compose window:
Notice these buttons have a consistent size, inner padding, padding, and shading. This is a pretty consistent style across macOS, present in Mail, Safari, Finder, etc. This leads me to suspect there's a standardized UI component for creating such buttons.
If I use a segmented control, each button looks correct, with each icon being correctly padded:
Now I would like to add individual buttons that match the style.
Attempt 1
My first attempt was to add a "Push Button" (NSButton) to the toolbar:
This resulted in a wide button that's a bit too short, and not lined up with the segmented control:
Attempt 2
My second attempt was to use a segmented control, with only 1 segment.
This resulted in a button that's the right shape, size, etc., but it was off center relative to its label.
Naturally, I can manually adjust the button to match the goal, but I feel like I'm missing something. What's the proper way to create these standard buttons?
This is actually quite easy to do and you were close already.
You can use NSButton for that. Note that it has different styles (defined in NSButton.BezelStyle) to choose from. The default one is the one to use inside windows and modals. But for toolbars, to match the style of segmented controls and search bars, you can choose the style .texturedRounded.
You can also set the style via Interface Builder. Note that you have to select the button itself, not the toolbar item around it.
To get the correct size, you seem to set the icon within the toolbar item, not the button itself.
Here is my result:

How to keep a hidden view in responder chain?

I have a NSSplitViewController and in one of the items I have multiple buttons with keyboard shortcuts.
Once the user hides the item, the shortcuts don't fire.
Is there any way to keep the buttons in the hidden view as part of the responder chain?
Sounds like the simple answer is no, according to Apple's docs. A simple workaround, however, might be to move the buttons out of the visible area by, say, shifting their bounds right by 10,000 or so. If they are in a scrollview/clipview that would expand to show the items in their new position, then this would not work so well, but if they aren't, it ought to work fine. If they are in a scrollview, then you might find a way to make them completely transparent, to achieve a similar effect.
That said, perhaps it is worth considering whether you have the right design in the first place, since having buttons that are not visible respond to key events is a questionable design from a user-interface perspective (as reflected by the fact that Apple tries to prevent it). Maybe those keyboard events should really be getting handled by a view higher in the view hierarchy, or by the window, or some such entity?

FirstResponder as delegate for NSToolBar

I have a Mac app that consists of a window with a variable number of panes in it, each containing a tableview. The window has a toolbar with buttons, and I want the VC for the currently selected pane to handle validating the toolbar items, as well as being target for their actions.
If I could set first responder as delegate for the toolbar, this would be handled automatically, so my question is if that is possible! I have obviously googled around for this and some articles seem to hint that it is possible, but IB doesn't seem to let me do it.
An NSWindowController subclass would be better suited for this, that is the toolbar's delegate (it's natural role anyway) and can talk with the currently selected pane, using a custom protocol to decide on business logic.
Same goes for the UI/Menu action handlers; the window controller is perfect for this and your design will fit within it well.
It's not really got anything to do with the first responder as you are interested in the currently selected pane, not the first responder.

How do I get Mac Toolbar Items that look like the standard toolbar buttons?

I'm working on some updates to my first Mac app and I'm trying to get my window's toolbar buttons to look like the toolbar buttons on EVERY standard Mac app. However, for the life of me, I can't find a button type or a barbutton type that gets me what I'm looking for. Am I missing something?
Here is an image showing several Mac apps (Preview, Finder, and Safari) with toolbars at the top which have very-slighty rounded corner buttons which also have a slight gradient on them, etc.
However, in my .xib I've got a toolbar and I've dropped every kind of button I can find on the thing and nothing looks like the standard Mac button.
The first button looks pretty close, but it's clearly not the same color. Am I missing something?
#Matt Ball is right - you can use NSSegmentedControls, even for single one-time click buttons. Just set the number of segments to 1, and set the mode to "Select None".
One of my shipping apps uses this technique, see below:
All of the controls there are NSSegmentedControl, including the single one.
Update: there are a few standard button icons which are meant for toolbars. The NSImage Class Reference has a list.
In the above screenshot, only two of the buttons are using built-in images: NSLeftFacingTriangleTemplate, and NSRightFacingTriangleTemplate. The others I drew myself.

Resources