Skip to content
Didier Korthoudt edited this page Aug 3, 2019 · 24 revisions

CPButtonBar is a special AppKit widget as it doesn't exist in Cocoa...

With the introduction of CSS theming and the Aristo3 theme, CPButtonBar has been completely reworked to provide more ease of use and more capabilities.

Even if button bars are aimed to be used inside CPSplitView, they can also be used to provide control & status bar to any window.

CPButtonBar can now be used with one of the three provided styles :

  • CPButtonBarLegacyStyle : bordered button bar and buttons, gray background

    Legacy BB

  • CPButtonBarModernStyle : bordered button bar (not buttons), gray background

    Modern BB

  • CPButtonBarSmoothStyle : unbordered button bar and buttons, translucide background

    Smooth BB Smooth BB

The style can be specified using - (void)setStyle:(CPButtonBarStyle)style (or specifying a "user defined runtime attribute" style in IB with numeric value 1, 2 or 3 (corresponding to legacy, modern and smooth style).

How to use it

The simplest way is to add a custom view to a split view view or to a window, to specify CPButtonBar as the custom view class and to bind its delegate outlet to your code.

The delegate has to implement - (void)populateButtonBar:(CPButtonBar)aButtonBar in order to populate the button bar with "buttons".

You can use "user defined runtime attributes" in IB to control some behaviors (see below).

You can also create a button bar by code with initWithFrame method.

Available buttons

You can only use specific buttons provided by a CPButtonBar.

Compatibility with previous implementation is done by supporting the following class methods (that should be avoided) :

+(id)plusButton, +(id)minusButton and +(id)actionPopupButton.

In CPButtonBar 2.0, you don't ask the class for buttons anymore but you have to ask your instance. That is : instead of doing myPlusButton = [CPButtonBar plusButton], you have to do myPlusButton = [myButtonBar plusButton].

Here are the various items you can use with the new CPButtonBar :

Image button

- (id)buttonWithImage:(CPImage)image alternateImage:(CPImage)alternateImage

The provided images should be 16x16. For better rendering, use double resolution images (32x32 declared as 16x16) or, even better, pure CSS images (not always easy). The alternate image is used when the button is pushed.

Template image button

- (id)buttonWithTemplateImage:(CPTemplateImage)templateImage

where template image is :

  • CPAddTemplateImage : a plus (+) sign
  • CPRemoveTemplateImage : a minus (-) sign
  • CPActionTemplateImage : a gearing
  • (more to come in the future)

BTW, - (id)plusButton just returns buttonWithTemplateImage:CPAddTemplateImage, etc.

Image pulldown menu

- (id)pulldownButtonWithImage:(CPImage)image alternateImage:(CPImage)alternateImage

Provides a pulldown menu button. See buttonWithImage for more information. Please note that your images must not include the down arrow (as this was the case with previous implementation).

Template image pulldown menu

- (id)pulldownButtonWithTemplateImage:(CPTemplateImage)templateImage

Provides a pulldown menu button based on standard images. See buttonWithTemplateImage for more information.

Textual pulldown menu

- (id)pulldownButtonWithTitle:(CPString)aTitle

Provides a pulldown menu button using aTitle as label.

Textual popup button

- (id)popUpButton

Provides a popup menu button that will adapt its width to the selected item.

To populate your popup menu, you can use the standard methods :

- (void)addItem:(CPMenuItem)anItem

- (void)addItemWithTitle:(CPString)aTitle

or the new specific method :

- (CPMenuItem)addItemWithTitle:(CPString)aTitle shortTitle:(CPString)aShortTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent

Using this, the menu displays the title but the button displays the short title.

If you pass nil as short title, the button uses the title as label.

Typical usage :

    var popupMenu = [aButtonBar popUpButton];

    [popupMenu addItemWithTitle:@"Auto"                              shortTitle:nil      action:nil keyEquivalent:nil];
    [popupMenu addItemWithTitle:@"All variables, local, global, etc" shortTitle:@"All"   action:nil keyEquivalent:nil];
    [popupMenu addItemWithTitle:@"Debug things only"                 shortTitle:@"Debug" action:nil keyEquivalent:nil];

Search field

- (id)searchFieldWithPlaceholder:(CPString)placeholder minWidth:(int)minWidth maxWidth:(int)maxWidth

Provides a search field that can be either fixed width (just specify the needed width in both minWidth and maxWidth) or flexible (that is it will adapt its width between minWidth and maxWidth, regarding available space).

Fixed width label

- (id)labelWithTitle:(CPString)aTitle

or

- (id)labelWithTitle:(CPString)aTitle width:(int)aWidth

Provides a fixed width label. With the first method, the width of the label is exactly the width of the provided title ; with the second method, the width is fixed to the provided width.

Adaptative width label

- (id)adaptativeLabelWithTitle:(CPString)aTitle

Provides a label that will adapt its width when the title changes.

Separator

- (id)separator

Draws a vertical separator. When using "legacy style", separators are not displayed as buttons are bordered.

Typical usage : [myButtonBar addButton:[myButtonBar separator]];

Separator

Flexible space

- (id)flexibleSpace

Provides a flexible space that will adapt its width to the available space. If multiple flexible spaces are used in a button bar, available space is distributed equally between them.

Typical usage : [myButtonBar addButton:[myButtonBar flexibleSpace]];

Flexible spaces enable complex layouts for your button bars, like on those two examples :

  • 2 buttons on the left, a flexible space, 1 pulldown button on the right

    Flexible 1

  • 2 buttons on the left, a flexible space, 1 flexible label at the center, a flexible space, 1 pulldown button on the right

    Flexible 2

Available methods

Managing buttons

Set the buttons

- (void)setButtons:(CPArray)buttons

Replaces all current buttons with the provided array of buttons.

Typical usage : [myButtonBar setButtons:@[aFirstButton, aSecondButton, [myButtonBar flexibleSpace], aLastButton]];

Note that you can, after setting an array of buttons, use addButton to add more buttons.

Add a button

- (void)addButton:(id)button

Adds a button to the current array of buttons.

Typical usage : [myButtonBar addButton:aLastLastButton];

Get the buttons

- (CPArray)buttons

Returns the current array of buttons.

Controlling the appearance

Choose the button bar style

- (void)setStyle:(CPButtonBarStyle)style

Sets the visual style of the button bar.

Style must be a valid value for CPButtonBarStyle :

  • CPButtonBarLegacyStyle (= 1)
  • CPButtonBarModernStyle (= 2)
  • CPButtonBarSmoothStyle (= 3)

If you want to set the style of your button bar via IB, just add a "User Defined Runtime Attribute" named style, of type Number and specify the corresponding value (1, 2 or 3).

Predefined styles set values for the 3 next properties (borders, top separator and transparency). You can, if you want, set them by your own (please note that Aristo3 doesn't support the combination top separator + transparent background).

Add or remove borders to buttons

- (void)setButtonsAreBordered:(BOOL)shouldBeBordered

Legacy style uses bordered buttons, modern and smooth styles don't.

Add or remove top separator

- (void)setDrawsSeparator:(BOOL)shouldDrawSeparator

Legacy and modern styles draw a top separator, smooth style doesn't.

Set transparency

- (void)setIsTransparent:(BOOL)shouldBeTransparent

Legacy and modern styles use plain background, smooth style uses a transparent (translucide) one.

Resize controls

If your button bar is part of a split view, it can display resize controls that "extend" the dividers.

If you use IB to design your split view and add your button bar, connection between the two will be done automatically. If you create them by code, you have to "attach" your button bar to your split view (remember that your button bar must be a subview of an arranged subview of the split view), by using :

[mySplitView attachButtonBar:myButtonBar];

At that moment, your button bar is able to display resize controls.

Important : by default, Aristo3 doesn't show resize controls (whereas Aristo2 does).

So, if you want them (or some of them), use the following methods (or add "User Defined Runtime Attributes" in IB).

Automatic resize control

- (void)setAutomaticResizeControl:(BOOL)shouldAutomaticallyAddResizeControl

If you set automatic resize control, when attaching the button bar to a split view, the split view will automatically determine which resize control(s) must be added.

Manual resize control

- (void)setHasLeftResizeControl:(BOOL)shouldHaveLeftResizeControl

- (void)setHasRightResizeControl:(BOOL)shouldHaveRightResizeControl

Those two methods let you decide if you want a left resize control, a right one, both or none.

Delegating

- (void)setDelegate:(id <CPButtonBarDelegate>)aDelegate

The delegate must implement - (void)populateButtonBar:(CPButtonBar)buttonBar;.

If you're using the adapted version of XCodeCapp that you can find here, you can link your button bar to its delegate via IB (a delegate outlet should be present).

Clone this wiki locally