Re: How to embed a popup menu in an NSTextField
Re: How to embed a popup menu in an NSTextField
- Subject: Re: How to embed a popup menu in an NSTextField
- From: Ryan Stevens <email@hidden>
- Date: Tue, 16 Nov 2004 15:27:18 -0800
Here's a reusable NSTextField subclass to do it. <http://www.cocoadev.com/index.pl?CCDTextField>
The underlying cell it uses (CCDTextFieldCell) is modeled after NSSearchFieldCell.
Usage is simple...
- (void)awakeFromNib
{
// change the class of your NSTextField to CCDTextField in IB and..
[[myTextField rightButtonCell] setImage: yourImage];
[[myTextField rightButtonCell] setTarget:self];
[[myTextField rightButtonCell] setAction:@selector(textfieldButtonClicked:)];
}
On Nov 15, 2004, at 12:13 AM, Evan Schoenberg wrote:
This could be done externally or, as in the code I'm pasting below, within a subclass of NSTextField (if externally, you'd use the instance variable name instead of self). Clearly there are some instance variables used in here, like the BOOL for whether it's visible at present, and the image to show for the button, which you'll need to declare.
---
//Indicator
- (BOOL)visible
{
if(visible && !currentlyVisible){
currentlyVisible = visible;
//Push text over to make room for indicator
NSSize size = [self frame].size;
size.width -= ([buttonImage size].width + 2);
[self setFrameSize:size];
// Make the indicator and set its action. It is a button with no border.
indicator = [[NSButton alloc] initWithFrame:
NSMakeRect(0, 0, [buttonImage size].width, [buttonImage size].height)];
[indicator setButtonType:NSMomentaryPushButton];
[indicator setAutoresizingMask:(NSViewMinXMargin)];
[indicator setImage:buttonImage];
[indicator setImagePosition:NSImageOnly];
[indicator setBezelStyle:NSRegularSquareBezelStyle];
[indicator setBordered:NO];
[[self superview] addSubview:indicator];
[indicator setTarget:self];
[indicator setAction:@selector(popContent)];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_positionIndicator:) name:NSViewBoundsDidChangeNotification object:[self superview]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_positionIndicator:) name:NSViewFrameDidChangeNotification object:[self superview]];
[self _positionIndicator:nil]; //Set the indicators initial position
}else if(!visible && currentlyVisible){
currentlyVisible = visible;
//Push text back
NSSize size = [self frame].size;
size.width += [buttonImage size].width;
[self setFrameSize:size];
//Remove indicator
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewBoundsDidChangeNotification object:[self superview]];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewFrameDidChangeNotification object:[self superview]];
[indicator removeFromSuperview];
[indicator release]; indicator = nil;
}
}
//Reposition indicator into lower right corner
- (void)_positionIndicator:(NSNotification *)notification
{
NSRect visRect = [[self enclosingScrollView] documentVisibleRect];
NSRect indFrame = [indicator frame];
[indicator setFrameOrigin:NSMakePoint(NSMaxX(visRect) - indFrame.size.width - 2, NSMaxY(visRect) - indFrame.size.height - 2)];
[[self enclosingScrollView] setNeedsDisplay:YES];
}
----
The code above adds an NSButton, so it'd be clickable but not show a menu. The next step is to implement a menu button which shows a menu. I'd do this with an NSButton subclass which has the following within it:
//Mouse Tracking -------------------------------------------------------------------------------------------------------
#pragma mark Mouse Tracking
//Custom mouse down tracking to display our menu and highlight
- (void)mouseDown:(NSEvent *)theEvent
{
self menu]){
[super mouseDown:theEvent];
}else{
self isEnabled]){
[self highlight:YES];
NSPoint point = [self convertPoint:[self bounds].origin toView:nil];
point.y -= NSHeight([self frame]) + 2;
point.x -= 1;
NSEvent *event = [NSEvent mouseEventWithType:[theEvent type]
location:point
modifierFlags:[theEvent modifierFlags]
timestamp:[theEvent timestamp]
windowNumber:[[theEvent window] windowNumber]
context:[theEvent context]
eventNumber:[theEvent eventNumber]
clickCount:[theEvent clickCount]
pressure:[theEvent pressure]];
[NSMenu popUpContextMenu:[self menu] withEvent:event forView:self];
[self mouseUp:[[NSApplication sharedApplication] currentEvent]];
}
}
}
//Remove highlight on mouse up
- (void)mouseUp:(NSEvent *)theEvent
{
[self highlight:NO];
[super mouseUp:theEvent];
}
//Ignore dragging
- (void)mouseDragged:(NSEvent *)theEvent
{
//Empty
}
---
Hope that helps.
-Evan
www.adiumx.com
On Nov 15, 2004, at 1:09 AM, Larry Gerndt wrote:
(This is a revised version of my original post from a few days ago)
I would like to implement a popup menu located in the bottom-right corner an NSTextField (just like iChat has for picking a smiley face, except my menu will be a normal menu of strings). Since I'm new to Cocoa, I'm not sure how to go about accomplishing this.
I've gotten some helpful ideas, like trying an NSTextAttachment, which was very interesting, but I couldn't get that work well and to me, it seems like the wrong approach. I know that the Charla project has a way of doing this, and I may have to resort to that, but it would seem to me that some the Cocoa experts out there would know the best approach and I would appreciate very much to hear what that would be. Thanks, and sorry to repost.
--
Larry Gerndt
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden