NSToolbarItemGroup Without Spacing - cocoa

I'm using an NSToolbarItemGroup to group a set of NSToolbarItem's together. Currently there is a 2pt space between each item in the group, ideally I would like them to be completely merged visually similar to an NSSegmentedControl.
After inspecting the Mail application it looks like they are using a custom NSToolbarItem containing an NSSegmentedControl. I have tried this in the past but I cannot figure out how to get individual labels under each component and to have each component show up individually in the 'overflow' menu.
Current Look:
Desired Look:
I know 'Centered' is being clipped, this is just a quick implementation.

You can add an NSToolbarItem object to the toolbar, and then set the NSViewController like this (using Swift):
runStatus.view = RunStatusView()
where "runStatus" is the name of the #IBOutlet for the NSToolbarItem, and "RunStatusView" is an NSView object with an override on the drawRect method. You can also specify the width and height of the NSView; for example, force the width to be constant at 125:
runStatus.minSize = NSSize(width: 125, height: 32)
runStatus.maxSize = NSSize(width: 125, height: 32)
This can make the NSToolbar items appear closer to each other, depending on what you are drawing on them.
Finally, if you still cannot get exactly what you want, then make the group of buttons a single NSToobarItem, and in "RunStatusView" (using the above example) draw it however you want, and override the mouseDown event (also in "RunStatusView") to see where exactly the user is clicking. Then there's one NSToolbarItem that essentially acts like multiple buttons, and you have total control and can make it behave however you want.

I can suggest you to use NSSegmentedControl added to a NSToolbarItem like in a picture below.
You need some labels under the buttons (like "Reply" etc.).
To achieve this you can set NSToolbarItem label-property and play with space between words.

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 remove NSTableView's border and change cell selection color as same as Finder's?

I'm making an Cocoa app for Yosemite.
I added a view based NSTableView in Interface builder, but the border 2 pixel width and thicker than Yosemite's Finder's.
And the cell selection color is blue, while Yosemite's Finder's is gray.
And this is how Yosemite's Finder's table view looks like.
I checked the settings in Interface Builder.
The super scroll view of NSTableView's frame setting is (0,0,149,257):
While the Clip View's frame setting is (1, 1, 147, 255) and can not be changed.
And how to make a same NSTableView as Yosemite's Finder's?
Thanks a ton!
The Finder sidebar isn't a table-view it's a Source List NSOutlineView:
The border is applied around the enclosing scroll view:
Note also that a standard NSOutlineView lets you adjust the highlight style from within Interface Buider:
In my experience selected rows are still painted blue, even when the "Source List" highlight style is selected. To avoid that, I needed to prevent the table or outline view from becoming the first responder by subclassing it and adding
- (BOOL)becomeFirstResponder {
return NO;
}
Edit:
Turns out becomeFirstResponder is actually important if you want to support keyboard navigation. I have found a better solution that does not override becomeFirstResponder.
First, create a custom NSTableRowView subclass with an (overridden) empty setEmphasized: method:
- (void)setEmphasized:(BOOL)emphasized {
// This avoids a blue background when selected in a source list that has first responder status.
}
You can then provide an instance of your custom NSTableRowView class by implementing
- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row
in your NSTableViewDelegate.
To whoever wants to remove the NSTableView border...
My requirement was to remove the border colour of the NSTableView so that, it should look like a white box. Tried all properties and forums but couldn't find a way to do that. Finally I came up with a dirty hack in the Storyboard which could fix the problem. If someone have a better option, please let us know.
Embed the NSTableView in a CustomBox. Set the Box BorderType as 'None'
Then set the constraints (Left, Top, Right and Bottom) of NSTableView to the containing Box. Set the values to -2. so that the NSTableView border will be outside of the Box
Now in Storyboard, select the 'clipView(NSClipView)' of the NSTableView. clipView is the superView of the NSTableView
Go to the Size Inspector and uncheck the 'Automatically Adjust' property of the "Content Insets"
Set the values to Left=2, Top=2, Bottom=-2 and Right=-2
Thats it.

Xcode - Visually identify custom views in interface builder / storyboard

If you build a custom UIView, and integrate it inside of a parent view/view controller in interface builder, the graphical element representing your custom view is invisible, if you don't specify a background color (I don't).
Is there any way, solely during development, to identify different custom views? Any hacks/tricks to distinguish them?
The closest I could come up with is setting the background color in IB, then removing the background in the implementation of the custom view.
Bounds Rectangles
You might find bounds rectangles useful. You can turn them on by going to the menu bar and choosing Editor > Canvas > Show Bounds Rectangles.
Here's an example. I have a view (a UICollectionViewCell subclass) laid out in a nib. It has a single-line label, a two-line label, and a custom subview. The custom subview itself contains a smaller custom subview. Here's the nib with bounds rectangles off:
Here's the same nib with bounds rectangles on:
Background Color Override
Here's another technique that builds on the idea of setting the background color. This technique requires your deployment target to be iOS 5.0 or later.
As you described, set the background color to make the view visible in the nib:
Then switch to the Identity Inspector and add backgroundColor in the User Defined Runtime Attributes section. Set it to the background color you want the view to have at runtime. For example, if you want it to be white at runtime:
If you want the background color to be clear, you can set backgroundColor to a color with opacity 0, or you can set it to “Nil” instead of any color:
That approach of setting the background color in Interface Builder, but resetting it in code is a simple, but effective technique. Two refinements:
If you have multiple custom views on a single storyboard scene, you can save yourself from having to programmatically clear the background color for all of them individually by using IBOutletCollection. So, in Interface Builder, give them all background colors and then add all of your custom views for a given scene to a collection. You then can set the background color for all of them in a single statement. So, for example, if you have a dozen controls on one scene all in a single IBOutletCollection is named viewsCollection:
#property (strong, nonatomic) IBOutletCollection(UIView) NSArray *viewsCollection;
you can clear the background color of all of them in a single statement:
[self.viewsCollection setValue:[UIColor clearColor] forKey:#"backgroundColor"];
You can also make the identification of your custom views in Interface Builder a little easier by setting the "Label" in the "Document" properties on the "Identity inspector":
Once you've done that, when you look at the document outline in the left side of the main panel, you'll see your labels show up:
Then, using the document outline makes it easier to identify your individual views in the scene. You can use a random label like I did here, or you could use the name of your custom view class, or whatever.

NSWindow and text smoothing in NSTableView cell view

I'm writing an OS X app and have a problem with font smoothing in separate window.
I have a text field where you put text and suggestion window which pops up with a list of suggestions according to what you wrote. I'm using View-cell based NSTableView to display those suggestions and SFBPopoverWindowController to display it as a "popup" window (tried other classes with the same effect). When rows are first drawn they look fine but after I select them (keyboard or mouse) the font changes it's weight. It's only visual - like you would change smoothing method on the font, not it's bold setting.
"Music note" is the selected cell here
What's even more strange is that after I hide and show the window 3 times everything works fine from that point on.
Again - "Music note" is the selected cell.
The selection is done by overwriting NSTableRowView class and its drawSelectionInRect: method but I tried with drawing everything inside custom NSTableCellView class and it didn't help. The text is standard NSTextField - nothing's changed there.
The SFBPopoverWindow (and it's controller) are created once and reused with styleMask NSBorderlessWindowMask, backing NSBackingStoreBuffered, defer set to YES. The only change in SFBPopoverWindowController I made was to turn off window becoming key window but it doesn't change anything.
It might be related to the way a table view draws it's selected cells (setSelectionHightLightStyle:). Try to set the style to None/ NSTableViewSelectionHighlightStyleNone in your code or IB / Storyboard-file and draw the selection yourself (in a NSTableRowView subclass).
Background: When you use NSTableViewSelectionHighlightStyleRegular or NSTableViewSelectionHighlightStyleSourceList the table view assumes that you use the standard selection behaviour and appearance and does some magic to support that.
==========
UPDATE
==========
My previous answer is still valid but since it only describes the problem and hints at a workaround, I wanted to add a real solution. If you want to use NSTableViewSelectionHighlightStyleRegular for your table view (with custom font and colors), you need a way to 'disable' the system magic that comes into place once your row is highlighted. One proposed solution is to decline the first responder status. It has a lot of drawbacks and isn't a good solution at all.
So, let's have a closer look at the system 'magic' that kicks in as soon as the row will be highlighted: NSTableRowView has a property interiorBackgroundStyle that is – according to the documentation – 'an indication of how the subviews should draw'. Furthermore 'This value is dynamically computed based on the set of properties set for the NSTableRowView. Subclassers can override this value when they draw differently based on the currently displayed properties. This method can also be called to determine what color a subview should use, or alternatively, NSControls can have the -backgroundStyle set on their cell to this value.'
I assume that this style will be handed down the subview hierarchy and causes your text fields to look odd. The system assumes that a highlighted cell has a dark background and changes the interiorBackgroundStyle to dark. Other controls try to adapt accordingly.
I think there are two solutions to this problem:
1) Override interiorBackgroundStyle in your NSTableRowView subclass and return the style that fits your interface (in my case it's .light because my highlight color is a very bright blue). This worked for me.
2) If changing the whole style is a bit too much because you only want certain elements to not change their style, you may only need to adjust these subclasses. I haven't tried this yet.

Dynamically lay out a Window in Cocoa using Core Animation and populate it

What I'm looking for is a way with CA to dynamically lay out a window. Imagine the following SQL query in a window, each name between +PLUSSIGNS+ being a NSPopUpButton, rest is static text.
Select *
from +BURRITOS/TACOS1+ +AND/OR1+
+BURRITOS/TACOS2+ +AND/OR2+
Where
+TOPPING1+ +EQUALS/LT/GT1+ +TOPPINGLIST1+ +AND/OR3+
+TOPPING2+ +EQUALS/LT/GT2+ +TOPPINGLIST2+ +AND/OR4+
Ok: So the window starts showing "Select *" and "from" plain text labels, and BURRITOS/TACOS1 selected to "--" instead of a valid value.
When I set BURRITOS/TACOS1 to a valid value (BURRITOS), I want the AND/OR1 NSPopUpButton to appear, selected to "--". I also want the "Where" label to appear and I want "TOPPING1" "EQUALS/LT/GT1" "TOPPINGLIST1" to appear. All 3 of those will be selected to "--".
When I put AND/OR1 to a valid value (AND or OR), I want BURRITOS/TACOS2 to appear. If I select that to a value, I want AND/OR2 to appear. If I set that to a value, I want BURRITOS/TACOS3 to appear ....
If I set TOPPING1, EQUALS/LT/GT1, and TOPPINGLIST1 to valid values I want AND/OR3 to appear (as "--"). If I set AND/OR3 to a valid value, I want TOPPING2, EQUALS/LT/GT2, TOPPINGLIST2 to appear. If I set them to valid values, I want AND/OR4 to appear...
If for instance AND/OR3 is set to -- and there was a line under it, I'd want that entire line to disappear.
At the bottom of the entire Window I need a static checkbox "enable", always appears. I also want a left and right arrow button - clicking left would make the entire window "flip" to the left. Clicking right would make the entire window "flip" to the right to new queries.
I'd like these new NSPopUpButtons to appear similar to Mail.app where a new text entry for CC BCC etc appears based on your settings using that picker control thing.
Ends up this is truly 2 questions.
1 - Dynamic layout of window. In simplest way this is done by putting an NSView in an NSWindow and then using NSView's addSubview.. example:
NSRect rect = NSMakeRect(0, y, 100, 10);
NSButton *button = [[NSButton alloc] initWithFrame:rect];
y += 15;
[topView addSubview:button];
Here an NSButton is put every 15 pixels inside the view. Note that y has to be maintained by me, it's not automatic. If we overrun our NSView bounds we have to manage that size ourselves as well.
2 - Animating this transition. Using Core Animation isn't that smart, the more sensible route is NSAnimation and specifically NSViewAnimation. There's a great example thanks to Apple here. For my purpose I need to use this to resize and also move NSViews. Also If I want a Button to "fade in" what I can do is copy the NSView, keep that as "old", modify my NSView, and fade between those.
...thanks to #cocoa on freenode..

Resources