Adding an NSButton to a layer-hosted view

  • Hi,

    I have a layer-hosted view containing several layers making up the UI
    of my application. In a few cases, I would actually like to use
    standard controls *inside* of this layer-hosted view. For example, I'd
    like to have a standard NSButton in one location, and use an
    NSTextField to edit some text in another location.

    What I've done until now is to create the NSButton/NSTextField in the
    standard way, then add them as sub-views of my main view. Once this is
    done, I obtain the "layer" property of those objects and manipulate
    this layer like the other ones, to position them, set their z-
    position, hide or show them, and so on.

    This seems to work relatively well, except that the NSButton instance
    does not react to mouse events. For example, it does not perform the
    action or toggle its state when I click on it. Instead, my layer-
    hosted view gets the event (i.e. its mouseDown: method gets invoked).
    I found a partial work-around, which consists in calling
    "performClick:" on the button whenever its layer is the one under the
    mouse when the click happens, but this is not satisfactory (e.g. the
    button does not highlight when the mouse hovers over it, even though
    it should, given how it's configured).

    So I have two questions:

    1. Is it actually valid to add an NSButton or NSTextField as a sub-
    view of a layer-hosted view?

    2a. If it is, then how do I make sure the NSButton I add reacts to
    mouse events as it should?

    2b. If it isn't, then is there a better way to do what I'm trying to
    do, i.e. have a view containing many many layers managed directly by
    my application, with a few standard controls mixed in?

    Thanks,
    Michel.
  • On Nov 14, 2008, at 8:22 AM, Michel Schinz wrote:

    > This seems to work relatively well, except that the NSButton
    > instance does not react to mouse events. For example, it does not
    > perform the action or toggle its state when I click on it. Instead,
    > my layer-hosted view gets the event (i.e. its mouseDown: method gets
    > invoked). I found a partial work-around, which consists in calling
    > "performClick:" on the button whenever its layer is the one under
    > the mouse when the click happens, but this is not satisfactory (e.g.
    > the button does not highlight when the mouse hovers over it, even
    > though it should, given how it's configured).

    AppKit doesn't do hit testing via the layer tree, so by moving the
    button's layer, you've desynchronized the graphical location of the
    button with the hit test location of the button. If you want to use
    layer-backed AppKit views, you always need to move them via AppKit for
    the graphical and logical locations to match.
    --
    David Duncan
    Apple DTS Animation and Printing
  • Le 14 nov. 08 à 18:04, David Duncan a écrit :

    > AppKit doesn't do hit testing via the layer tree, so by moving the
    > button's layer, you've desynchronized the graphical location of the
    > button with the hit test location of the button. If you want to use
    > layer-backed AppKit views, you always need to move them via AppKit
    > for the graphical and logical locations to match.

    That was the problem indeed, thanks a lot David! Moving the button
    using setFrameOrigin: makes it behave correctly.

    I'll also conclude from your answer that putting these NSControl
    instances in my layer-hosted view is legal. Please correct me if I'm
    wrong.

    Michel.
  • On Nov 14, 2008, at 10:33 AM, Michel Schinz wrote:

    > Le 14 nov. 08 à 18:04, David Duncan a écrit :
    >
    >> AppKit doesn't do hit testing via the layer tree, so by moving the
    >> button's layer, you've desynchronized the graphical location of the
    >> button with the hit test location of the button. If you want to use
    >> layer-backed AppKit views, you always need to move them via AppKit
    >> for the graphical and logical locations to match.
    >
    > That was the problem indeed, thanks a lot David! Moving the button
    > using setFrameOrigin: makes it behave correctly.
    >
    > I'll also conclude from your answer that putting these NSControl
    > instances in my layer-hosted view is legal. Please correct me if I'm
    > wrong.

    It is legal, and AppKit tries to make sure that nothing bad will
    happen (i.e. you shouldn't crash). In general however, its an easier
    programming model if you either work entirely with Views or entirely
    with Layers. You can mix them, but you have to be careful about what
    your doing. Graphical attributes usually aren't a problem, but
    geometrical ones can be (as you've already found out).
    --
    David Duncan
    Apple DTS Animation and Printing
previous month november 2008 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today
MindNode
MindNode offered a free license !