Superimpose a NSTextField over NSImageView?

  • Hello again,
    Still struggling with my splash window.
    I have created 2 versions so far: one with a NSWindow subclass, which
    creates an NSImageView with an image provided and sets this as its
    contentView.

    The other version creates an instance of NSWindow, sets its attributes and
    contentView, which is a IB custom View (fully covered by a NSImageView with
    my splash image. I did this second version, because I thought it would be
    easier to put a loading status text field in it in IB.
    But it isn¹t. What ever I put on my NSImageView disappears behind the image
    even in IB test mode.

    I am able to load a status line into my splash window in the first version
    by virtually drawing the string onto the image. But I don¹t wan¹t to redraw
    it over and over with status messages that show up half a second or so...

    Is there a way to superimpose a textfield on my customView/imageView inIB,
    so that I can update it like any other textfield?
    Is there an more convenient way to put loading status messages in a splash
    window than drawing and redrawing?

    Thanks,
    Peter
    --
    peter schwaiger
    desktoast music productions
    http://www.autlawmusic.com
  • On Apr 23, 2006, at 8:10 AM, desktoast music productions wrote:
    > Is there a way to superimpose a textfield on my customView/
    > imageView inIB,
    > so that I can update it like any other textfield?

    Sibling views are not guaranteed to be drawn in any particular order,
    so it might be that your image view is getting drawn after the text
    field.  You might have better luck if you make the text field a
    subview of the image view.  You may have to do this in code -- I
    don't know if there is a way to do this in IB, though there may be
    some trick for doing so.

    --Andy
  • On 23 Apr 2006, at 13:46, Andy Lee wrote:

    > On Apr 23, 2006, at 8:10 AM, desktoast music productions wrote:
    >> Is there a way to superimpose a textfield on my customView/
    >> imageView inIB,
    >> so that I can update it like any other textfield?
    >
    > Sibling views are not guaranteed to be drawn in any particular
    > order, so it might be that your image view is getting drawn after
    > the text field.

    Interesting? Why are there "Bring to Front" and "Sent to Back" menu
    commands in IB's Layout menu?
    If I overlap a NSImageView and a NSTextField in a window in IB these
    commands seem to do what you'd expect when you run Test Interface.

    - Alan
  • Alan,

    On 23.4.2006, at 15:34, Alan Hart wrote:

    > Interesting? Why are there "Bring to Front" and "Sent to Back" menu
    > commands in IB's Layout menu?

    Since you may want to have more views on the same place, *if* all of
    them (but one) are kept hidden (e.g., through the "hidden" binding).
    Though generally a tabless tabview is better for this, sometimes due
    to widget layout you have to do it this way.

    > If I overlap a NSImageView and a NSTextField in a window in IB
    > these commands seem to do what you'd expect when you run Test
    > Interface.

    It often do. The trick is, it is not guaranteed to always. Very
    particularly, it may work as you presumed now, and the very opposite
    way in the next OS X release.
    ---
    Ondra ÄŒada
    OCSoftware:    <ocs...>              http://www.ocs.cz
    private        <ondra...>            http://www.ocs.cz/oc
  • What about:
    - (void)addSubview:(NSView *)aView positioned:(NSWindowOrderingMode)
    place relativeTo:(NSView *)otherView

    "Inserts aView among the receiver’s subviews so it’s displayed
    immediately above or below otherView according to whether place is
    NSWindowAbove or NSWindowBelow. If otherView is nil (or isn’t a
    subview of the receiver), aView is added above or below all of its
    new siblings. Also sets the receiver as the next responder of aView."

    This should do what the OP was looking for, and in fact very likely
    forms the basis for "Bring to Front" and "Send to Back".  It doesn't
    seem like the drawing order of sibling NSViews is really undefined at
    all.

    TTYL
    Dave R

    On 23-Apr-06, at 6:52 AM, Ondra Cada wrote:

    > Alan,
    >
    > On 23.4.2006, at 15:34, Alan Hart wrote:
    >
    >> Interesting? Why are there "Bring to Front" and "Sent to Back"
    >> menu commands in IB's Layout menu?
    >
    > Since you may want to have more views on the same place, *if* all
    > of them (but one) are kept hidden (e.g., through the "hidden"
    > binding). Though generally a tabless tabview is better for this,
    > sometimes due to widget layout you have to do it this way.
    >
    >> If I overlap a NSImageView and a NSTextField in a window in IB
    >> these commands seem to do what you'd expect when you run Test
    >> Interface.
    >
    > It often do. The trick is, it is not guaranteed to always. Very
    > particularly, it may work as you presumed now, and the very
    > opposite way in the next OS X release.
    > ---
    > Ondra ÄŒada
    > OCSoftware:    <ocs...>              http://www.ocs.cz
    > private        <ondra...>            http://www.ocs.cz/oc
    >
    >
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/<list...>
    >
    > This email sent to <list...>
  • On Apr 23, 2006, at 9:02 AM, Dave Rosborough wrote:

    > What about:
    > - (void)addSubview:(NSView *)aView positioned:(NSWindowOrderingMode)
    > place relativeTo:(NSView *)otherView
    >
    > "Inserts aView among the receiver’s subviews so it’s displayed
    > immediately above or below otherView according to whether place is
    > NSWindowAbove or NSWindowBelow. If otherView is nil (or isn’t a
    > subview of the receiver), aView is added above or below all of its
    > new siblings. Also sets the receiver as the next responder of aView."
    >
    > This should do what the OP was looking for, and in fact very likely
    > forms the basis for "Bring to Front" and "Send to Back".  It
    > doesn't seem like the drawing order of sibling NSViews is really
    > undefined at all.

    From <http://developer.apple.com/documentation/Cocoa/Conceptual/
    CocoaViewsGuide/WorkingWithAViewHierarchy/chapter_4_section_5.html
    >

    >
    > Note: For performance reasons, Cocoa does not enforce clipping
    > among sibling views or guarantee correct invalidation and drawing
    > behavior when sibling views overlap. If you want a view to be drawn
    > in front of another view, you should make the front view a subview
    > (or descendant) of the rear view.
    >

    It's been explicitly documented (and has for as long as there has
    been OS X, probably even before), that the behavior of drawing
    overlapping views is undefined.

    For the OP, they can simply make the NSTextField a subview of the
    NSImageView to guarantee that it is drawn correctly.

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | build, mutate, evolve | images, textures, backgrounds, art
  • On 23/04/06, Dave Rosborough <list...> wrote:
    > This should do what the OP was looking for, and in fact very likely
    > forms the basis for "Bring to Front" and "Send to Back".  It doesn't
    > seem like the drawing order of sibling NSViews is really undefined at
    > all.

    <http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaViewsGuide/WorkingWithAViewHierarchy/chapter_4_section_5.html
    clearly states:

    Note: For performance reasons, Cocoa does not enforce clipping among
    sibling views or guarantee correct invalidation and drawing behavior
    when sibling views overlap. If you want a view to be drawn in front of
    another view, you should make the front view a subview (or descendant)
    of the rear view.

    -- Finlay
  • On Apr 23, 2006, at 10:21 AM, glenn andreas wrote:
    > CocoaViewsGuide/WorkingWithAViewHierarchy/chapter_4_section_5.html>
    >
    >>
    >> Note: For performance reasons, Cocoa does not enforce clipping
    >> among sibling views or guarantee correct invalidation and drawing
    >> behavior when sibling views overlap. If you want a view to be
    >> drawn in front of another view, you should make the front view a
    >> subview (or descendant) of the rear view.
    >>
    >
    >
    > It's been explicitly documented (and has for as long as there has
    > been OS X, probably even before), that the behavior of drawing
    > overlapping views is undefined.

    I think the doc for -addSubview:positioned:relativeTo: should include
    a caveat to this effect.  Maybe the method should really have been
    private and was accidentally exposed?  Maybe it *is* guaranteed to
    work, but only under certain conditions (and maybe it was used to
    implement Send to Back/Front in IB)?  I submitted a feedback note
    about this using the link at the bottom of the NSView doc page.

    --Andy
  • On Apr 23, 2006, at 8:46 AM, Andy Lee wrote:
    > Sibling views are not guaranteed to be drawn in any particular order

    Given the existence of -addSubview:positioned:relativeTo:, I may have
    misspoken about this.  It would have been more accurate to invoke the
    note that Glenn and Finlay pointed to, which says the *clipping*
    behavior is not guaranteed.

    --Andy
  • On Apr 23, 2006, at 9:37 AM, Andy Lee wrote:

    > On Apr 23, 2006, at 10:21 AM, glenn andreas wrote:
    >> From <http://developer.apple.com/documentation/Cocoa/Conceptual/
    >> CocoaViewsGuide/WorkingWithAViewHierarchy/chapter_4_section_5.html>
    >>
    >>>
    >>> Note: For performance reasons, Cocoa does not enforce clipping
    >>> among sibling views or guarantee correct invalidation and drawing
    >>> behavior when sibling views overlap. If you want a view to be
    >>> drawn in front of another view, you should make the front view a
    >>> subview (or descendant) of the rear view.
    >>>
    >>
    >>
    >> It's been explicitly documented (and has for as long as there has
    >> been OS X, probably even before), that the behavior of drawing
    >> overlapping views is undefined.
    >
    > I think the doc for -addSubview:positioned:relativeTo: should
    > include a caveat to this effect.  Maybe the method should really
    > have been private and was accidentally exposed?  Maybe it *is*
    > guaranteed to work, but only under certain conditions (and maybe it
    > was used to implement Send to Back/Front in IB)?  I submitted a
    > feedback note about this using the link at the bottom of the NSView
    > doc page.

    I'd *guess* two things:

    1) At one point it was guaranteed to work, but that was back when
    Hair Metal Bands ruled the world.

    2) Hit testing has to go through the list of subviews - the
    addSubview:positioned:relativeTo: probably directly impacts that
    (since there's nothing stated about hit testing not working, only
    invalidation & drawing).

    But those are just guess (the former is somewhat supported by the
    lack of any such disclaimer in <http://docs.sun.com/app/docs/doc/
    802-2112/6i63mn62o?l=fr&a=view
    >, the latter due to Occam)

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | build, mutate, evolve | images, textures, backgrounds, art
  • Greetings,

    All of this discussion about drawing order and using NSViews to draw over other NSViews brings me to a (hopefully) simple feature that I've been meaning to add to my application for months.

    When a user opens a new document window they get an empty NSTableView -- this is not very informative. I'd like to superimpose some subtle text (light grey or semi-transparent) over the center of the table to the effect of "To add items to the table, drag and drop them here." This text would go away as soon as the table was no longer empty.

    What would be the sane+Cocoa way of accomplishing this?

    - I know that I could simply override the NSTableView's drawing routine and draw my text directly into the view after the table is finished drawing. I've been putting this off because it just seems like a lot of work (get a font, measure it, calculate a centering rectangle, ...).

    - Using NSTextField would make less work for me because it would handle all of the centering, clipping, wrapping, etc. of the text (and I could localize the message in the NIB). But where do I stick it in the NSView hierarchy and how to I keep it centered over the table? From the earlier thread, it appears that just cramming it into the same NSView that the NSTableView is in is a bad idea. On the other hand, making an NSTextField a subview of an NSTableView just seems bizarre and I'm afraid of messing up the NSTableView's subview(s).

    Any suggestions from the NSView mavens out there?

    --
    James Bucanek
  • James,

    On 23.4.2006, at 17:20, James Bucanek wrote:

    > When a user opens a new document window they get an empty
    > NSTableView -- this is not very informative. I'd like to
    > superimpose some subtle text (light grey or semi-transparent) over
    > the center of the table to the effect of "To add items to the
    > table, drag and drop them here." This text would go away as soon as
    > the table was no longer empty.
    >
    > What would be the sane+Cocoa way of accomplishing this?
    >
    > - I know that I could simply override the NSTableView's drawing
    > routine and draw my text directly into the view after the table is
    > finished drawing. I've been putting this off because it just seems
    > like a lot of work (get a font, measure it, calculate a centering
    > rectangle, ...).
    >
    > - Using NSTextField would make less work for me because it would
    > handle all of the centering, clipping, wrapping, etc. of the text
    > (and I could localize the message in the NIB). But where do I stick
    > it in the NSView hierarchy and how to I keep it centered over the
    > table? From the earlier thread, it appears that just cramming it
    > into the same NSView that the NSTableView is in is a bad idea. On
    > the other hand, making an NSTextField a subview of an NSTableView
    > just seems bizarre and I'm afraid of messing up the NSTableView's
    > subview(s).
    >
    > Any suggestions from the NSView mavens out there?

    To be frank, I would do neither: most probably I would add a child
    semi-transparent click-through window overlay with whatever "intro
    views" needed. As soon as the user begins editing in the parent
    window, I would remove the child.
    ---
    Ondra ÄŒada
    OCSoftware:    <ocs...>              http://www.ocs.cz
    private        <ondra...>            http://www.ocs.cz/oc
  • James,

    as for using whole window (I am just paraphrasing for I am returning
    this to the list for benefit of other readers), IMHO, semi-
    transparent (and, depending on the task, possibly also click-through)
    child windows are one of hidden gems of Cocoa: comparatively small
    number of programmers is aware of them, and there's even smaller
    number of those who can use them right.

    The child windows are very convenient though, using them is not
    difficult at all, and they work like a charm: I use them for a number
    of tasks, from my own corner tips (like those in Xcode; unlike them
    though, mine are never multiplicated when the view scrolls :)) to
    selecting areas (like in iPhoto).
    ---
    Ondra ÄŒada
    OCSoftware:    <ocs...>              http://www.ocs.cz
    private        <ondra...>            http://www.ocs.cz/oc
  • >> On Apr 23, 2006, at 8:10 AM, desktoast music productions wrote:
    >>> Is there a way to superimpose a textfield on my customView/
    >>> imageView inIB,
    >>> so that I can update it like any other textfield?
    >>
    >> Sibling views are not guaranteed to be drawn in any particular
    >> order, so it might be that your image view is getting drawn after
    >> the text field.
    >
    > Interesting? Why are there "Bring to Front" and "Sent to Back" menu
    > commands in IB's Layout menu?
    > If I overlap a NSImageView and a NSTextField in a window in IB these
    > commands seem to do what you'd expect when you run Test Interface.
    >
    > - Alan

    Do you really expect me to post a question like that without having tried
    "Bring to Front" and "Sent to Back" and the like at least a hundred times?
    But seriously -  I also made the text field a subview of the image view from
    the very beginning. (They don't just overlap - the text field is completely
    ON the image.)

    Here is what I do:
    - In IB I create a custom view of size 507 x 320
    - I put a NSImageView with of the same size on it.
    - I set the image view's image to my splash image (.psd file, 507 x 320 as
    well)
    - I put a NSTextField (miniSystemFont, blue textcolor, draws no background)
    onto the image view.

    And this is what I get:
    - As soon as I press Command-R the text field disppears (the same would
    happen to buttons, etc.)

    Due to the hints I received from this list, I tried adding the text field as
    subview of the image view programmatically. This time the status line text
    field really showed up im my splash - with a new unwanted side effect: it
    looks as if the text field draws its background kind of gray (the image is
    white, and - yes - I tried setting drawsBackground to NO in code, too).
    But I guess, this is not the text field's background, I guess, my image just
    does not draw, where overlapped by the text field...?

    I put a screenshot of my splash online at:
    http://www.autlawmusic.com/cocoa/WDVSplash.html
    Just to give you an idea of what I'm doing here.

    Thanks for all the input,
    Peter
    --
    Leselust...?
    http://www.peterschwaiger.com
  • On Apr 23, 2006, at 3:23 PM, desktoast music productions wrote:
    > Here is what I do:
    > - In IB I create a custom view of size 507 x 320
    > - I put a NSImageView with of the same size on it.
    > - I set the image view's image to my splash image (.psd file, 507 x
    > 320 as
    > well)
    > - I put a NSTextField (miniSystemFont, blue textcolor, draws no
    > background)
    > onto the image view.

    Ah, I see how this is different from what I tried (I too thought it
    was working as expected in IB).  When I tried it, I didn't have the
    custom view; I just dropped the views into a window.  It looks like
    when you drop views into a custom view, their display order is
    reversed.  Try dropping in the text field first, then the image view.

    > I put a screenshot of my splash online at:
    > http://www.autlawmusic.com/cocoa/WDVSplash.html
    > Just to give you an idea of what I'm doing here.

    I can't tell what the problem is from this screenshot.  The stuff in
    the lower left corner looks okay to me, except the text isn't blue.
    I can't tell that there is a problem with background color.

    --Andy
  • On 23 Apr 2006, at 20:23, desktoast music productions wrote:

    >>> On Apr 23, 2006, at 8:10 AM, desktoast music productions wrote:
    >>>> Is there a way to superimpose a textfield on my customView/
    >>>> imageView inIB,
    >>>> so that I can update it like any other textfield?
    >>>
    >>> Sibling views are not guaranteed to be drawn in any particular
    >>> order, so it might be that your image view is getting drawn after
    >>> the text field.
    >>
    >> Interesting? Why are there "Bring to Front" and "Sent to Back" menu
    >> commands in IB's Layout menu?
    >> If I overlap a NSImageView and a NSTextField in a window in IB these
    >> commands seem to do what you'd expect when you run Test Interface.
    >>
    >> - Alan
    >
    > Do you really expect me to post a question like that without having
    > tried
    > "Bring to Front" and "Sent to Back" and the like at least a hundred
    > times?

    Apologies if I expressed myself badly. I wasn't questioning your
    results.

    Any other drawing program with those menu items would use them to
    define front-to-back object ordering. My quick check seemed to
    confirm it, and the IB Help says nothing about them as far as I can
    tell. Hence my surprise when Andy pointed out that you can't rely on
    it. It has never occurred to me to look for information on what they
    actually do, and I'm still not sure I know.

    -- Alan
  • On Apr 23, 2006, at 10:20 AM, James Bucanek wrote:

    > When a user opens a new document window they get an empty
    > NSTableView -- this is not very informative. I'd like to
    > superimpose some subtle text (light grey or semi-transparent) over
    > the center of the table to the effect of "To add items to the
    > table, drag and drop them here." This text would go away as soon as
    > the table was no longer empty.
    >
    > What would be the sane+Cocoa way of accomplishing this?
    >
    > - I know that I could simply override the NSTableView's drawing
    > routine and draw my text directly into the view after the table is
    > finished drawing. I've been putting this off because it just seems
    > like a lot of work (get a font, measure it, calculate a centering
    > rectangle, ...).
    >
    > - Using NSTextField would make less work for me because it would
    > handle all of the centering, clipping, wrapping, etc. of the text
    > (and I could localize the message in the NIB). But where do I stick
    > it in the NSView hierarchy and how to I keep it centered over the
    > table? From the earlier thread, it appears that just cramming it
    > into the same NSView that the NSTableView is in is a bad idea. On
    > the other hand, making an NSTextField a subview of an NSTableView
    > just seems bizarre and I'm afraid of messing up the NSTableView's
    > subview(s).

    I would look into using an overlay window.  Basically you:

    (a) subclass NSWindow and set appropriate attributes.  Here's how I
    set things up for a "watermark" window:

    if ((self = [super initWithContentRect:theContentRect
      styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered
      defer:NO]) != nil)
      {
      [self setLevel:NSFloatingWindowLevel];
      [self setBackgroundColor:[NSColor clearColor]];
      [self setIgnoresMouseEvents:YES];
      [self setHidesOnDeactivate:YES];
      [self setReleasedWhenClosed:NO];
      [self setMovableByWindowBackground:NO];
      [self setHasShadow:NO];
      [self useOptimizedDrawing:YES];

      [self setOpaque:NO];
      [self setAlphaValue:1.0];
      }

    (b) create and add the window as a child to your table-view's window:

    MyOverlayWindow* theOverlayWindow = ...

    [theOverlayWindow orderFront:nil];
    [theTableViewWindow addChildWindow:theOverlayWindow
    ordered:NSWindowAbove];

    (c) Add a text control as a subview of the overlay window's content view

    NSControl* theTextMessage] = ...

    [[theOverlayWindow contentView] addSubview:theTextMessage];

    (d) add logic to show/hide the overlay as needed.

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • On Apr 23, 2006, at 5:09 PM, Ricky Sharp wrote:
    > On Apr 23, 2006, at 10:20 AM, James Bucanek wrote:
    >> On the other hand, making an NSTextField a subview of an
    >> NSTableView just seems bizarre and I'm afraid of messing up the
    >> NSTableView's subview(s).

    This is the approach I would have tried.  Does an NSTableView even
    have subviews?  Note that the table view shouldn't be confused with
    the scroll view that contains it.

    On the other hand, now that Ondra and Ricky have advocated the
    overlay window approach, I'd give that serious consideration.  It has
    the advantage that it doesn't care whether the table has subviews.

    > I would look into using an overlay window.  Basically you:
    [...]
    > (d) add logic to show/hide the overlay as needed.

    Depending on how permissive you are about resizing the parent window,
    you might need to (e) listen for resize notifications in case the
    table view gets resized or clipped in response to resizing of the
    parent window.  The logic could get a little tricky, because if the
    table view gets clipped, you want the overlay text to be clipped as
    well.

    I just thought of another possible approach: when the table is
    logically empty, you could add a single row to it whose height fills
    the whole table, and use that cell to display your message.

    --Andy
  • I just did this in Interface Builder:

    1) Start Interface Builder
    2) Select File->New... menu item
    3) In "Starting Point" dialog that appears, Select "Window" and press
    the button labeled "New".
    4) Drag text fields, progress bars, and any other controls of
    interest from Interface Builder's palette to the editable window that
    IB provides.
    5) Arrange the configure controls as desired.
    6) Select all of the controls.
    7) Use Layout->Make subviews of->Custom View
    8) Select the custom view.
    9) Use IB's custom calls inspector (Cmd-5) to set the class of the
    custom view to NSImageView or any other kind of view you like.
    10) Use the outline mode of IB's inspector's Instances tab to verify
    that the view hierarchy was created as desired.

    Use this technique to create whatever view hierarchy you want from
    now on and always remember that sibling views should not overlap.
  • > I can't tell what the problem is from this screenshot.  The stuff in
    > the lower left corner looks okay to me, except the text isn't blue.
    > I can't tell that there is a problem with background color.

    Sorry. I put this online in response to another post.
    All you can see there is why I can't do it all in an IB window
    (transparency, rounded edges etc.).
    The blue status line is drawn above the text you can see.

    Peter
    --
    --
    peter schwaiger
    desktoast music productions
    http://www.autlawmusic.com
  • > I just did this in Interface Builder:
    >
    > 1) Start Interface Builder
    > 2) Select File->New... menu item
    > 3) In "Starting Point" dialog that appears, Select "Window" and press
    > the button labeled "New".
    > 4) Drag text fields, progress bars, and any other controls of
    > interest from Interface Builder's palette to the editable window that
    > IB provides.
    > 5) Arrange the configure controls as desired.
    > 6) Select all of the controls.
    > 7) Use Layout->Make subviews of->Custom View
    > 8) Select the custom view.
    > 9) Use IB's custom calls inspector (Cmd-5) to set the class of the
    > custom view to NSImageView or any other kind of view you like.
    > 10) Use the outline mode of IB's inspector's Instances tab to verify
    > that the view hierarchy was created as desired.
    >
    > Use this technique to create whatever view hierarchy you want from
    > now on and always remember that sibling views should not overlap.

    Sorry, but this approach didn't work for me. I need to create the window
    programmatically and set its contentView to the NSView | NSImageView from IB
    (the window is partially transparent and has rounded edges).
    Perhaps there is a way to use the custom view from IB w|o its window (btw.
    In my "Starting Point" dialog there is "Window" only under "Carbon", not
    "Cocoa") but that would make things even more complicated.

    Nevertheless, the solution to my problem was much easier. Someone mentioned
    it on this list: all you have to do is make up your view hierarchy in the
    reverse order!

    If I put the text field on the custom view, then drag the big image view
    OVER it, so that I can't see the text - all I have to do is press Command-R
    and ta-daah, the text field is displayed ABOVE the image just like I want it
    to. Funny, isn't it?

    Thank you everyone,
    Peter

    --
    peter schwaiger
    desktoast music productions
    http://www.autlawmusic.com
  • Andy Lee wrote on Sunday, April 23, 2006:
    >
    > On the other hand, now that Ondra and Ricky have advocated the
    > overlay window approach, I'd give that serious consideration.  It has
    > the advantage that it doesn't care whether the table has subviews.

    Right, and it's what make the approach so appealing. I don't have to worry anything about any side effects (both documented and undocumented) of modifying the view hierarchy of NSTableView.

    >> I would look into using an overlay window.  Basically you:
    > [...]
    >> (d) add logic to show/hide the overlay as needed.
    >
    > Depending on how permissive you are about resizing the parent window,
    > you might need to (e) listen for resize notifications in case the
    > table view gets resized or clipped in response to resizing of the
    > parent window.  The logic could get a little tricky, because if the
    > table view gets clipped, you want the overlay text to be clipped as
    > well.

    I think I should be relatively immune to these problems. The NSTableView/NSScrollView in question fills one pane of an NSSplitView. The pane can't be minimized and that table should never (famous last words) get clipped by anything else in that window.

    > I just thought of another possible approach: when the table is
    > logically empty, you could add a single row to it whose height fills
    > the whole table, and use that cell to display your message.

    That's a brilliant suggestion, but is complicated by the fact that the table has multiple columns. I'm also looking into making this a more generic solution for several other elements in my interface, so a non-table-specific solution still looks better.

    Thanks for the insights,

    James
    --
    James Bucanek
  • In your particular case, there may be another solution:

    Create your window *without* the image. Then, once you have that, create an
    NSColor from your image and set that as the window's background color. That
    should ensure your image is drawn correctly under the text field.

    I'm doing this with a metal window in one of my apps. Haven't tried it with
    an Aqua window yet, and not in a splash screen, but might work.

    Both solutions seem rather inelegant to me, though...

    Cheers,
    M. Uli Kusterer
    ------------------------------------------------------------
          "The Witnesses of TeachText are everywhere..."
                      http://www.zathras.de
  • On 24/04/06, desktoast music productions <desktoast...> wrote:
    >
    > Sorry, but this approach didn't work for me. I need to create the window
    > programmatically and set its contentView to the NSView | NSImageView from
    > IB
    > (the window is partially transparent and has rounded edges).
    > Perhaps there is a way to use the custom view from IB w|o its window (btw.
    > In my "Starting Point" dialog there is "Window" only under "Carbon", not
    > "Cocoa") but that would make things even more complicated.

    To get a custom window under IB, you need to subclass NSWindow and override
    initWithRect:backingstore:defer: or whatever the method was called. Then
    drag that into your NIB file and you'll be able to choose this class as the
    window's "custom class".

    Nevertheless, the solution to my problem was much easier. Someone mentioned
    > it on this list: all you have to do is make up your view hierarchy in the
    > reverse order!

    Well, as the docs state, this is not guaranteed to work in future MacOS X
    versions. If you change the text field, it may clip and invalidate
    differently in the future. Since resolution-independence is on the horizon
    Apple will probably make substantial changes to the drawing system soon, so
    I would not rely on this approach.

    Cheers,
    M. Uli Kusterer
    ------------------------------------------------------------
          "The Witnesses of TeachText are everywhere..."
                      http://www.zathras.de
  • On 24/04/06, desktoast music productions <desktoast...> wrote:
    >
    > Sorry, but this approach didn't work for me. I need to create the window
    > programmatically and set its contentView to the NSView | NSImageView from
    > IB
    > (the window is partially transparent and has rounded edges).
    > Perhaps there is a way to use the custom view from IB w|o its window (btw.
    > In my "Starting Point" dialog there is "Window" only under "Carbon", not
    > "Cocoa") but that would make things even more complicated.

    Oh, not sure whether you're doing this, but the programming equivalent to
    the custom view thing Erik mentioned is creating your NSImageView and then
    using addSubview: to putyour text view into your image view.

    Cheers,
    M. Uli Kusterer
    ------------------------------------------------------------
          "The Witnesses of TeachText are everywhere..."
                      http://www.zathras.de
  • On Apr 24, 2006, at 8:18 AM, M. Uli Kusterer wrote:

    > On 24/04/06, desktoast music productions <desktoast...> wrote:
    >>
    >> Sorry, but this approach didn't work for me. I need to create the
    >> window
    >> programmatically and set its contentView to the NSView | NSImageView
    >> from
    >> IB
    >> (the window is partially transparent and has rounded edges).
    >> Perhaps there is a way to use the custom view from IB w|o its window
    >> (btw.
    >> In my "Starting Point" dialog there is "Window" only under "Carbon",
    >> not
    >> "Cocoa") but that would make things even more complicated.
    >
    >
    > Oh, not sure whether you're doing this, but the programming
    > equivalent to
    > the custom view thing Erik mentioned is creating your NSImageView and
    > then
    > using addSubview: to putyour text view into your image view.

    I must be missing something critical here.    What is wrong
    with just having the image view and using the NSString
    drawing additions to superimpose the text ?

        Cheers,
            ........  Henry

    ===============================+============================
      Henry McGilton, Boulevardier |    Trilithon Software
        Objective-C/Java Composer  |    Seroia Research
    -------------------------------+----------------------------
      mailto:<henry...>  |  http://www.trilithon.com
                                    |
    ===============================+============================
  • On 24/04/06, Henry McGilton <henry...> wrote:
    >
    > I must be missing something critical here.    What is wrong
    > with just having the image view and using the NSString
    > drawing additions to superimpose the text ?

    For one thing, performance. NSStringDrawing creates and tears down several
    text system objects to draw a string. It also doesn't necessarily wrap text.
    An NSTextView carries arround its text system objects and reuses them.

    Also, you can use bindings with an NSTextField or NSTextView while you'd
    have to write a bunch of code to use them with a subclassed NSImageView.

    And did I mentioned you can just reuse an NSImageView and NSTextView instead
    of having to subclass the former?

    Mind you, I'd personally use IB for this, but the OP insisted on having to
    do this programmatically, so I suggested use of addSubview. IMHO using IB is
    the better choice. If you need custom border drawing, you can create a
    reusable NSWindow subclass once and use it in other apps easily just by
    dragging it into IB. I'm doing that with UKBorderlessWindow all the time.

    Cheers,
    M. Uli Kusterer
    ------------------------------------------------------------
          "The Witnesses of TeachText are everywhere..."
                      http://www.zathras.de
  • Here's a snippet from the docs to consider when deciding which option
    you use.

    > Prior to Mac OS X v10.4, the NSString and NSAttributedString
    > classes were intended for rendering text occasionally in your
    > program. The performance of these drawing methods was not as good
    > as the performance you could get by rendering text using the Cocoa
    > text system. Also, the layout for strings is limited to a simple
    > rectangular area in the current view. In Mac OS X v10.4,
    > performance of the string drawing methods improved significantly
    > and is useful in many situations; of course, you should always
    > measure the performance yourself and see if it is adequate for your
    > program. If you need to do more complex text layout, you should
    > still consider using the Cocoa text system.

    On Apr 24, 2006, at 8:41 AM, M. Uli Kusterer wrote:

    > On 24/04/06, Henry McGilton <henry...> wrote:
    >>
    >> I must be missing something critical here.    What is wrong
    >> with just having the image view and using the NSString
    >> drawing additions to superimpose the text ?
    >
    >
    > For one thing, performance. NSStringDrawing creates and tears down
    > several
    > text system objects to draw a string. It also doesn't necessarily
    > wrap text.
    > An NSTextView carries arround its text system objects and reuses them.
    >
    > Also, you can use bindings with an NSTextField or NSTextView while
    > you'd
    > have to write a bunch of code to use them with a subclassed
    > NSImageView.
    >
    > And did I mentioned you can just reuse an NSImageView and
    > NSTextView instead
    > of having to subclass the former?
    >
    > Mind you, I'd personally use IB for this, but the OP insisted on
    > having to
    > do this programmatically, so I suggested use of addSubview. IMHO
    > using IB is
    > the better choice. If you need custom border drawing, you can create a
    > reusable NSWindow subclass once and use it in other apps easily
    > just by
    > dragging it into IB. I'm doing that with UKBorderlessWindow all the
    > time.
    >
    > Cheers,
    > M. Uli Kusterer
    > ------------------------------------------------------------
    > "The Witnesses of TeachText are everywhere..."
    > http://www.zathras.de
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/<enigma0...>
    >
    > This email sent to <enigma0...>