3

i'm trying to manage different state of a simple push button on an OS X application : When the user click on it, and when the user release the click.

Currently i set my button type by NSMomentaryLightButton

NSMomentaryLightButton When the button is clicked (on state), it appears illuminated. If the button has borders, it may also appear recessed. When the button is released, it returns to its normal (off) state.

This type of button is best for simply triggering actions because it doesn’t show its state; it always displays its normal image or title. This option is called Momentary Light in Interface Builder’s Button inspector

I thought it was the good way, but when i print my button status, it's like a toggle button than the push button that i set. As you can see on exemple gif

To sum up, How can i have a real push button behaviour ? Call function when the user click on it, and when the user release the click.

Thank,

Kyz
  • 141
  • 9
  • With a regular push button, you should only cause an action when the user releases the click. No one would ever expect a separate action when they push down on a button -- they still have the chance to change their mind. Do you mean: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSButtonCell_Class/index.html#//apple_ref/c/econst/NSPushOnPushOffButton ? A toggle switch, in other words? Can you clarify your language? – BaseZen Aug 20 '16 at 23:41
  • Sorry for my bad english. In my application, buttons are from a piano keyboard, so i would like to trig something when the user push down, and other thing when push up. Currently the button change his state for each click, than have two state on one click. Is it clear ? :/ – Kyz Aug 21 '16 at 08:31
  • finally i found solution : override public func mouseDown(theEvent: NSEvent) { Swift.print("MouseDown !") } override public func mouseUp(theEvent: NSEvent) { Swift.print("Mouse Up !") } – Kyz Aug 22 '16 at 11:13

1 Answers1

1

You don't want to use buttons for piano keys. First, they are non-rectangular, and they don't act as buttons do: neither single-action push-button, nor toggle switches. You are interacting in a custom way, with a custom view, meaning the NSButton control hierarchy isn't called for. Instead you're subclassing NSView and capturing low-level mouse events as detailed here:

https://developer.apple.com/library/prerelease/content/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html#//apple_ref/doc/uid/10000060i-CH6-SW1

You found this yourself as you detailed in your own comments, but I wanted to make sure you had a higher level point of view. It's even possible, and probably best, to consolidate all of the piano keys into a single view, and let the keys themselves be rendered using NSBezierPath and perform mouse hit detection using containsPoint:

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSBezierPath_Class/#//apple_ref/occ/instm/NSBezierPath/containsPoint:

This is a lot more work but the only way to make a truly professional looking piano simulation. Then you can render the keys with whatever outline, fill, and labeling you need without the limitations of built-in button shapes and layout. You could even have the bottom edges of the keys slightly rounded, for example, or apply a shiny texture.

BaseZen
  • 8,650
  • 3
  • 35
  • 47