I have seen that in Cocoa I can create a custom view using drawing primitives which allows me to draw what I like but at a very low level.
Instead I'd like to create custom widgets using a combination of existing controls. For example:
I'd like to create a table with images and combobox in cells
I'd like to create a custom widget wich is a combination of several (for example a list, a button and combobox)
How can I approach this problem ?
Secondly a typical cocoa developer uses external controls? Is there a repository or a list of interesting external custom controls (commercial or free) ?
I'd like to create a table with images and combobox in cells
There already exists NSImageCell and NSComboBoxCell. Are you sure you need to do anything different?
If the problem is that you want an image and a combo box in the same cell, you will have to subclass NSCell. Currently table views can only contain cells, not views, which makes your life harder (as understanding how cell drawing works is more difficult). That will change in Lion, however, so if you can wait until then, this will become easier!
I'd like to create a custom widget wich is a combination of several (for example a list, a button and combobox)
How is your custom widget different to just placing those three things in the same view?
You could write your own NSView subclass. When it's created, it should create a list, a button and a combobox and add them as subviews to itself. Your NSView subclass should handle the logic of keeping them in sync or doing whatever it is you want them to do. Then, to use this combination control in Interface Builder, you place a Custom View and set its class (rightmost tab of the inspector) to your NSView subclass.
BTW, on a tangent, are you sure you mean combobox? Loads of people coming from Windows get this one wrong. A combobox is a combination of a menu and a text field: it allows the user to enter custom text that is not in the menu. If you just want a dropdown menu of choices (and the user can't enter a custom one), you use an NSPopupButton.
Secondly a typical cocoa developer uses external controls?
Yes, sometimes. Things like BWToolkit can be very useful. There's a lot more that are just floating around mailing lists as code snippets, rather than being cleaned up and put in a library. Search for what you need to do!
Related
This question already has an answer here:
NSTableView with +/- buttons like in System Preferences using only Interface Builder
(1 answer)
Closed 7 years ago.
I'm building an OSX app and want to create a set of controls similar to what's found at bottom of the standard Network Preferences configuration panel. I'm running into some layout problems that I wouldn't have expected.
These are my specific questions:
What contains the 3 buttons so there's similar shading all they way across the row where the buttons are positioned? In particular, what's causing the area without buttons to have shading?
How do you do this without getting a double border where the row of buttons meets up with the table?
I want to do this with an xib file. This may be incredibly simple, but I'm missing something I guess.
I find that if you make a button with style "Gradient" and type "Momentary Change", then it looks like the other buttons but does not respond to clicks, so you can use that as the area after the last button. (The NSMomentaryChangeButton is documented as changing the image and title when clicked, so if you don't use an image or title, nothing should change.)
If you check Refuses First Responder in the attributes inspector, then it will not be possible to highlight this blank button using Full Keyboard Access.
Ken Thomases also brings up the issue of the blank button being shown as a button to Accessibility. One can fix that by using a subclass of NSButtonCell that has just one method:
- (BOOL)accessibilityIsIgnored
{
return YES;
}
I think that's easier than writing a custom view.
As d00dle says, avoid double borders by slightly overlapping things.
Since you want the slack space to have the same background as the buttons, and since the buttons can change appearance from release to release of the OS, the best thing to do is to get the frameworks to draw it like it would the buttons.
Rather than using an actual button as JWWalker suggests, I have used a custom view that leverages NSButtonCell to draw the background. The advantage is that you can be sure there's no chance of getting undesirable behavior. For example, a button could get focus (for users who have All Controls selected in System Preferences > Keyboard > Shortcuts > Full Keyboard Access) so that the user could Tab to it. Accessibility will report the presence of the button through VoiceOver. Etc.
Configure the button cell just like the buttons (set buttonType and bezelStyle). In the view's -drawRect: call [buttonCell drawWithFrame:rect inView:self];, where rect is similar to the frames of the buttons. Since one way to avoid double borders is to make the buttons larger than the view's bounds, you may need to do the same for rect. For example, you might want to use NSInsetRect(self.bounds, -1, -1).
The buttons are buttons... This can be accomplished with a custom view drawing border and the background "shading".
To avoid the double border where the table and the custom view meet you simply align it so they overlap by 1 point (pixel) or avoid drawing the top border in your custom view.
I don't know of any standard object capable of doing this.
I am reworded the above question.
Let's say I am using 20 toolbox buttons and or labels or whatever on a VB window app form, and I have changed the default colors, size, and so on. Is there a way to view in code or design view all the properties and values that have been changed for any one tool (object) in a pop-up window.
In other words instead of having to go to properties and scroll, I push a hot key and magic! In one small pop-up window, I can see the changes for btnone, or lblTwo and or even better, make changes on the fly or go back to default values, or change to new values. Like an Xray format tool in brackets, or google.
I'm trying to implement a sort of drag functionality into my app. As a simplistic example imagine I have a 2x2 square of buttons, so four buttons total. Clicking a button will perform some other functionality however I want when they hold and drag one of these buttons for it to do something else (ideally if you drag one button and drop it while in the space of another button the two buttons will swap places, as long as I can get dragging and dropping working the swap should be easy).
I've done some research and followed a few tutorials but seemed to get errors at one step or another with all of those. It seems ListViews and GridViews have some drag and drop functionality in them already , but I had trouble properly arranging my buttons (there are many more than four and they are in very specific positions, like a diagram) inside these views, let alone getting drag and drop working with them.
How would I go about doing this? Ideally I could just tag these buttons as draggable, and then on a drag-drop event check for a drop position, then if the position is valid perform a swap method. I just can't seem to figure out how to make them draggable or how to have an event that checks a drop position.
Thanks.
Easy peasy, create a custom control that looks the way you want it to, set ManipulationMode to TranslateX|TranslateY, handle manipulation delta events to update positioning with something like a Canvas or TranslateTransform and when manipulation completes - either make it click or animate to the new position. From my experience - getting any other manipulations to work with a regular Button class just isn't working and since a button is a really simple control - it is easier to create your own than try to extend the existing one in such cases.
I'm facing the following problems:
We have meta data for items, each item can be a different type of NSControl, currently NSTokenField and NSTextField, but we might need NSCombo or other types.
I need to build a form in which each entry will have a label and an editable control.
this form has to be built dynamically since the items are retrieved from the server.
I've implemented it with NSMatrix, and apart from it looking pretty shabby, I'm faced with some visual issues I don't know how to solve.
The visual issue is every time I move the mouse over the NSTextFieldCell the tokens get drawn on the top left corner of the NSMatrix form.
now, I'm considering moving to another type of control,
I've googled for few hours, and found the following controls:
NSForm,
NSMatirx (parent of NSForm),
NSCollectionView,
NSTableView
which one of these is the most appropriate for this task?
I hope I am clear since I wanted to add pictures, but it wouldn't let me due to lack of "reputation points".
Thanks for your help,
Eyal.
NSTokenField is a subclass of NSTextField so you could use an NSTableView to display them.
You could also draw a custom NSCell with all elements in it. When each "item" has a different number of elements then this becomes a bit more complicated though.
I'm guessing it is using a custom NSWindow, NSTextField, NSSecureTextField, NSButton? I don't necessarily want to replicate it, I would just like to know what would be involved in customizing my app's UI to this level.
The window itself could be a HUD-style panel, which you can get in IB without subclassing anything. It looks like there's a bit of custom background to it, unless it's just faintly showing something behind it; if it is a custom background, a custom view as the content view could do that job.
The separator could be an image view or a custom view.
The static text fields can be done without subclassing. Just change the text color.
The editable text fields, both the regular one and the secure one, you would need to subclass. I have no idea how you would do that.
The follow-link button is a mix of custom drawing and a standard image. Start with the NSImageNameFollowLinkFreestandingTemplate image; draw that, then fill an empty path with white using the source-in blend mode.
The other two buttons are customized, probably using custom cells in order to override the background without overriding the text drawing.