diff --git a/Documentation/ChangeLog b/Documentation/ChangeLog index 48d128f..3ef1867 100644 --- a/Documentation/ChangeLog +++ b/Documentation/ChangeLog @@ -1,3 +1,14 @@ +2004-07-22 Serg Stoyan + + * Library/PCButton.m: Rewritten tooltips code. Almost ready for + incorporation into NSView. + + * Library/PCProjectBuilder.m: Use new tooltip code and remove old + style code. + * Library/PCProjectLauncher.m: ditto. + * Library/PCProjectWindow.m: ditto. + + 2004-07-15 Serg Stoyan * Library/PCProject.m: diff --git a/Library/GNUmakefile.preamble b/Library/GNUmakefile.preamble index aec18a1..5eacfab 100644 --- a/Library/GNUmakefile.preamble +++ b/Library/GNUmakefile.preamble @@ -41,7 +41,7 @@ ADDITIONAL_CPPFLAGS += # Additional flags to pass to the Objective-C compiler -ADDITIONAL_OBJCFLAGS += +ADDITIONAL_OBJCFLAGS += -Wall -Werror # Additional flags to pass to the C compiler ADDITIONAL_CFLAGS += diff --git a/Library/PCButton.h b/Library/PCButton.h index 0950f1d..659d10f 100644 --- a/Library/PCButton.h +++ b/Library/PCButton.h @@ -32,20 +32,16 @@ */ @interface PCButton : NSButton { - NSString *_toolTipText; + NSToolTipTag mainToolTip; - NSTrackingRectTag tRectTag; - NSTimer *ttTimer; - NSWindow *ttWindow; - NSPoint mouseLocation; + NSTimer *ttTimer; + NSWindow *ttWindow; + NSMutableDictionary *ttTitleAttrs; + NSColor *ttBackground; - BOOL _hasTooltip; + BOOL _hasTooltips; } -- (void)setShowTooltip:(BOOL)yn; - -- (void)updateTrackingRect; - @end #endif diff --git a/Library/PCButton.m b/Library/PCButton.m index 45b244f..0a3adc4 100644 --- a/Library/PCButton.m +++ b/Library/PCButton.m @@ -25,8 +25,15 @@ #include "PCButton.h" #include "PCDefines.h" +#include "AppKit/NSBezierPath.h" +#include "GNUstepGUI/GSTrackingRect.h" + @implementation PCButton +// ============================================================================ +// ==== Main +// ============================================================================ + - (id)initWithFrame:(NSRect)frameRect { self = [super initWithFrame:frameRect]; @@ -36,254 +43,317 @@ ttTimer = nil; ttWindow = nil; + ttTitleAttrs = [[NSMutableDictionary alloc] init]; + [ttTitleAttrs setObject:[NSFont systemFontOfSize:10.0] + forKey:NSFontAttributeName]; + ttBackground = [NSColor colorWithDeviceRed:1.0 green:1.0 blue:0.90 alpha:1.0]; + RETAIN(ttBackground); + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(_updateTrackingRects:) + name:NSViewFrameDidChangeNotification + object:[[self window] contentView]]; return self; } - (void)dealloc { - if (_hasTooltip) - { - [[self superview] removeTrackingRect:tRectTag]; - [ttTimer invalidate]; - ttTimer = nil; - RELEASE(ttTimer); - } - - if (ttWindow != nil) + if (_hasTooltips) { + [self removeAllToolTips]; + RELEASE(ttTitleAttrs); + RELEASE(ttBackground); RELEASE(ttWindow); } [super dealloc]; } -- (void)setFrame:(NSRect)frameRect -{ -// NSLog (@"setFrame"); - [super setFrame:frameRect]; +// ============================================================================ +// ==== Private methods +// ============================================================================ - if (_hasTooltip) +- (void)_updateTrackingRects:(NSNotification *)aNotif +{ + NSTrackingRectTag tag; + NSRect rect; + NSString *string = nil; + int i, j; + GSTrackingRect *tr = nil; + + if (_hasTooltips == NO) { - [self updateTrackingRect]; + return; + } + + j = [_tracking_rects count]; + for (i = 0; i < j; i++) + { + tr = [_tracking_rects objectAtIndex:i]; + +// NSLog(@"PCButton: tr: %i data: %@", tr->tag, tr->user_data); + + string = [(NSString *)tr->user_data copy]; + + rect = [self frame]; + rect.origin.x = 0; + rect.origin.y = 0; + tag = [self addTrackingRect:rect + owner:self + userData:string + assumeInside:NO]; + + if (tr->tag == mainToolTip) + { + mainToolTip = tag; + } + + [self removeTrackingRect:tr->tag]; + RELEASE(string); } } -- (void)setShowTooltip:(BOOL)yn +- (void)_invalidateTimer { - _hasTooltip = yn; - if (_hasTooltip) + if (ttTimer == nil) { - tRectTag = [[self superview] addTrackingRect:[self frame] - owner:self - userData:nil - assumeInside:NO]; - [[self window] setAcceptsMouseMovedEvents:YES]; + return; + } + +// NSLog(@"_invalidateTimer"); + if ([ttTimer isValid]) + { + [ttTimer invalidate]; + } + ttTimer = nil; +} + +- (void)_closeToolTipWindow +{ + if (ttWindow) + { + [ttWindow close]; + ttWindow = nil; } } -- (void)updateTrackingRect +- (void)_drawToolTip:(NSAttributedString *)title { - [[self superview] removeTrackingRect:tRectTag]; - tRectTag = [[self superview] addTrackingRect:[self frame] - owner:self - userData:nil - assumeInside:NO]; + NSRectEdge sides[] = {NSMinXEdge, NSMaxYEdge, NSMaxXEdge, NSMinYEdge}; + NSColor *black = [NSColor blackColor]; + NSColor *colors[] = {black, black, black, black}; + NSRect bounds = [[ttWindow contentView] bounds]; + NSRect titleRect; + + titleRect = [ttWindow frame]; + titleRect.origin.x = 2; + titleRect.origin.y = -2; + + [[ttWindow contentView] lockFocus]; + + [title drawInRect:titleRect]; + NSDrawColorTiledRects(bounds, bounds, sides, colors, 4); + + [[ttWindow contentView] unlockFocus]; } -- (void)showTooltip:(NSTimer *)timer +- (void)_showTooltip:(NSTimer *)timer { - NSAttributedString *attributedTitle = [self attributedTitle]; - NSSize titleSize = [attributedTitle size]; + NSString *ttText = [timer userInfo]; + + [self _invalidateTimer]; + +// NSLog(@"showTooltip: %@", ttText); +// NSLog(@"toolTips: %@", toolTips); -// NSLog (@"showTooltip"); if (ttWindow == nil) { - NSTextField *ttText; - NSRect windowRect; - NSRect titleRect; - NSRect contentRect; + NSAttributedString *attributedTitle = nil; + NSSize titleSize; + NSPoint mouseLocation = [NSEvent mouseLocation]; + NSRect windowRect; - windowRect = NSMakeRect(mouseLocation.x, - mouseLocation.y-16-(titleSize.height+3), - titleSize.width+10, titleSize.height+3); + attributedTitle = + [[NSAttributedString alloc] initWithString:ttText + attributes:ttTitleAttrs]; + titleSize = [attributedTitle size]; - titleRect = NSMakeRect(0,0, titleSize.width+10,titleSize.height+3); -/* windowRect = NSMakeRect(mouseLocation.x, - mouseLocation.y-16-(titleSize.height+3), - titleSize.width, titleSize.height); - titleRect = NSMakeRect(0,0, titleSize.width,titleSize.height);*/ - contentRect = [NSWindow frameRectForContentRect:titleRect - styleMask:NSBorderlessWindowMask]; + // Window + windowRect = NSMakeRect(mouseLocation.x + 8, + mouseLocation.y - 16 - (titleSize.height+3), + titleSize.width + 4, titleSize.height + 4); ttWindow = [[NSWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreRetained defer:YES]; + [ttWindow setBackgroundColor:ttBackground]; + [ttWindow setReleasedWhenClosed:YES]; [ttWindow setExcludedFromWindowsMenu:YES]; + [ttWindow setLevel:NSStatusWindowLevel]; - ttText = [[NSTextField alloc] initWithFrame:contentRect]; - [ttText setEditable:NO]; - [ttText setSelectable:NO]; - [ttText setBezeled:NO]; - [ttText setBordered:YES]; - [ttText setBackgroundColor:[NSColor colorWithDeviceRed:1.0 - green:1.0 - blue:0.80 - alpha:1.0]]; - [ttText setFont:[self font]]; - [ttText setStringValue:[self title]]; - [[ttWindow contentView] addSubview:ttText]; - } - else if (![ttWindow isVisible]) - { - [ttWindow setFrameOrigin: - NSMakePoint(mouseLocation.x, - mouseLocation.y-16-(titleSize.height+3))]; - [ttWindow orderFront:self]; + [ttWindow orderFront:nil]; + + [self _drawToolTip:attributedTitle]; + RELEASE(attributedTitle); } } +// ============================================================================ +// ==== Tool Tips +// ============================================================================ + - (void)mouseEntered:(NSEvent *)theEvent { - // NSLog (@"mouseEntered"); + NSLog (@"mouseEntered"); if (ttTimer == nil) { - ttTimer = [NSTimer - scheduledTimerWithTimeInterval:0.5 - target:self - selector:@selector(showTooltip:) - userInfo:nil - repeats:YES]; +// NSLog (@"mouseEntered: setTimer: %@", data); + ttTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 + target:self + selector:@selector(_showTooltip:) + userInfo:[theEvent userData] + repeats:YES]; + [[self window] setAcceptsMouseMovedEvents:YES]; } } - (void)mouseExited:(NSEvent *)theEvent { // NSLog (@"mouseExited"); - - if (ttTimer != nil) - { -// NSLog (@"-- invalidate"); - [ttTimer invalidate]; - ttTimer = nil; - - if (ttWindow && [ttWindow isVisible]) - { - [ttWindow orderOut:self]; - } - } + [self _invalidateTimer]; + [self _closeToolTipWindow]; + [[self window] setAcceptsMouseMovedEvents:NO]; } - (void)mouseDown:(NSEvent *)theEvent { // NSLog (@"mouseDown"); - - if (ttTimer != nil) - { -// NSLog (@"-- invalidate"); - [ttTimer invalidate]; - ttTimer = nil; - } + [self _invalidateTimer]; + [self _closeToolTipWindow]; [super mouseDown:theEvent]; } - (void)mouseMoved:(NSEvent *)theEvent { + NSPoint mouseLocation; + NSPoint origin; + +// NSLog(@"mouseMoved"); mouseLocation = [NSEvent mouseLocation]; -// NSLog (@"mouseMoved %f %f", mouseLocation.x, mouseLocation.y); - if (ttWindow && [ttWindow isVisible]) - { - [ttWindow orderOut:self]; - } -} - -// -// Tool Tips -// - -- (void)_invalidateToolTip:(NSTimer *)timer -{ - [timer invalidate]; - timer = nil; - - if (ttWindow && [ttWindow isVisible]) - { - [ttWindow orderOut:self]; - } -} - -- (NSToolTipTag) addToolTipRect: (NSRect)aRect - owner: (id)anObject - userData: (void *)data -{ - SEL ownerSelector = @selector(view:stringForToolTip:point:userData:); -/* if (aRect == NSZeroRect) - { - return; - }*/ + origin = NSMakePoint(mouseLocation.x + 8, + mouseLocation.y - 16 - [ttWindow frame].size.height); + [ttWindow setFrameOrigin:origin]; +} + +- (NSToolTipTag)addToolTipRect:(NSRect)aRect + owner:(id)anObject + userData:(void *)data +{ + SEL ownerSelector; + NSTrackingRectTag tag; + + if (NSEqualRects(aRect,NSZeroRect) || ttTimer != nil) + { + return -1; + } + + ownerSelector = @selector(view:stringForToolTip:point:userData:); if (![anObject respondsToSelector:ownerSelector] && ![anObject isKindOfClass:[NSString class]]) + { + return -1; + } + + // Set rect tracking + tag = [[self superview] addTrackingRect:aRect + owner:self + userData:data + assumeInside:NO]; + + return tag; +} + +- (void)removeToolTip:(NSToolTipTag)tag +{ + [self removeTrackingRect:tag]; +// [toolTips removeObjectForKey:[NSNumber numberWithInt:tag]]; +} + +- (void)removeAllToolTips +{ + int i, j; + GSTrackingRect *tr = nil; + + if (_hasTooltips == NO) { return; } - tRectTag = [[self superview] addTrackingRect:aRect - owner:self - userData:data - assumeInside:NO]; - [[self window] setAcceptsMouseMovedEvents:YES]; - - if (ttTimer == nil) + [self _invalidateTimer]; + [self _closeToolTipWindow]; + + j = [_tracking_rects count]; + for (i = 0; i < j; i++) { - ttTimer = [NSTimer - scheduledTimerWithTimeInterval:0.5 - target:self - selector:@selector(showTooltip:) - userInfo:nil - repeats:YES]; + tr = [_tracking_rects objectAtIndex:i]; + [self removeTrackingRect:tr->tag]; } - return 0; + mainToolTip = -1; + _hasTooltips = NO; } -- (void) removeAllToolTips +- (void)setToolTip:(NSString *)string { -} - -- (void) removeToolTip: (NSToolTipTag)tag -{ -} - -- (void) setToolTip: (NSString *)string -{ - ASSIGN(_toolTipText, string); - - if (string == nil) + NSTrackingRectTag tag; + NSRect rect; + + if (string == nil) // Remove tooltip { - _hasTooltip = NO; - if (ttTimer != nil) + if (_hasTooltips) { + [self _invalidateTimer]; + [self _closeToolTipWindow]; + [self removeToolTip:mainToolTip]; + mainToolTip = -1; + _hasTooltips = NO; } } - - if (_hasTooltip) + else { - tRectTag = [[self superview] addTrackingRect:[self frame] - owner:self - userData:nil - assumeInside:NO]; - [[self window] setAcceptsMouseMovedEvents:YES]; +// NSLog(@"setToolTip"); + rect = [self frame]; + rect.origin.x = 0; + rect.origin.y = 0; + tag = [self addTrackingRect:rect + owner:self + userData:string + assumeInside:NO]; + _hasTooltips = YES; } } -- (NSString *) toolTip +- (NSString *)toolTip { - return _toolTipText; + NSEnumerator *enumerator = [_tracking_rects objectEnumerator]; + GSTrackingRect *tr = nil; + + while ((tr = [enumerator nextObject])) + { + if (tr->tag == mainToolTip) + { + return tr->user_data; + } + } + + return nil; } @end diff --git a/Library/PCProject.m b/Library/PCProject.m index cdd5eb2..3bdd8ea 100644 --- a/Library/PCProject.m +++ b/Library/PCProject.m @@ -679,7 +679,7 @@ NSString return YES; } - while (key = [keyEnum nextObject]) + while ((key = [keyEnum nextObject])) { projectFiles = [projectDict objectForKey:key]; if ([projectFiles containsObject:pFile]) @@ -1322,8 +1322,6 @@ NSString - (BOOL)hasChildrenAtCategoryPath:(NSString *)categoryPath { NSString *listEntry = nil; - NSString *categoryKey = nil; - NSString *category = nil; PCProject *activeProject = [projectManager activeProject]; if (self != activeProject) diff --git a/Library/PCProjectBrowser.m b/Library/PCProjectBrowser.m index b6e00f8..b68ce49 100644 --- a/Library/PCProjectBrowser.m +++ b/Library/PCProjectBrowser.m @@ -228,8 +228,6 @@ NSString *PCBrowserDidSetPathNotification = @"PCBrowserDidSetPathNotification"; - (BOOL)setPath:(NSString *)path { - int selectedColumn; - NSMatrix *columnMatrix = nil; BOOL res; if ([[browser path] isEqualToString: path]) diff --git a/Library/PCProjectBuilder.h b/Library/PCProjectBuilder.h index f8a6d79..286aa98 100644 --- a/Library/PCProjectBuilder.h +++ b/Library/PCProjectBuilder.h @@ -71,7 +71,6 @@ - (void)dealloc; - (NSView *)componentView; -- (void)setTooltips; // --- Accessory - (BOOL)isBuilding; diff --git a/Library/PCProjectBuilder.m b/Library/PCProjectBuilder.m index 34ea0e3..f36f3af 100644 --- a/Library/PCProjectBuilder.m +++ b/Library/PCProjectBuilder.m @@ -63,7 +63,7 @@ * 4 build Buttons */ buildButton = [[PCButton alloc] initWithFrame: NSMakeRect(0,271,43,43)]; - [buildButton setTitle: @"Build"]; + [buildButton setToolTip: @"Build"]; [buildButton setImage: IMAGE(@"Build")]; [buildButton setAlternateImage: IMAGE(@"Stop")]; [buildButton setTarget: self]; @@ -74,7 +74,7 @@ RELEASE (buildButton); cleanButton = [[PCButton alloc] initWithFrame: NSMakeRect(44,271,43,43)]; - [cleanButton setTitle: @"Clean"]; + [cleanButton setToolTip: @"Clean"]; [cleanButton setImage: IMAGE(@"Clean")]; [cleanButton setAlternateImage: IMAGE(@"Stop")]; [cleanButton setTarget: self]; @@ -85,7 +85,7 @@ RELEASE (cleanButton); installButton = [[PCButton alloc] initWithFrame: NSMakeRect(88,271,43,43)]; - [installButton setTitle: @"Install"]; + [installButton setToolTip: @"Install"]; [installButton setImage: IMAGE(@"Install")]; [installButton setAlternateImage: IMAGE(@"Stop")]; [installButton setTarget: self]; @@ -96,7 +96,7 @@ RELEASE (installButton); optionsButton = [[PCButton alloc] initWithFrame: NSMakeRect(132,271,43,43)]; - [optionsButton setTitle: @"Options"]; + [optionsButton setToolTip: @"Options"]; [optionsButton setImage: IMAGE(@"Options")]; [optionsButton setTarget: self]; [optionsButton setAction: @selector(showOptionsPanel:)]; @@ -407,14 +407,6 @@ return componentView; } -- (void)setTooltips -{ - [buildButton setShowTooltip:NO]; - [cleanButton setShowTooltip:NO]; - [installButton setShowTooltip:NO]; - [optionsButton setShowTooltip:NO]; -} - // --- Accessory - (BOOL)isBuilding { diff --git a/Library/PCProjectLauncher.h b/Library/PCProjectLauncher.h index df6983d..d309c06 100644 --- a/Library/PCProjectLauncher.h +++ b/Library/PCProjectLauncher.h @@ -55,7 +55,6 @@ - (void)dealloc; - (NSView *) componentView; -- (void)setTooltips; - (BOOL)isRunning; - (BOOL)isDebugging; diff --git a/Library/PCProjectLauncher.m b/Library/PCProjectLauncher.m index a7d74cf..21f6748 100644 --- a/Library/PCProjectLauncher.m +++ b/Library/PCProjectLauncher.m @@ -175,12 +175,6 @@ enum { return componentView; } -- (void)setTooltips -{ - [runButton setShowTooltip:YES]; - [debugButton setShowTooltip:YES]; -} - - (BOOL)isRunning { return _isRunning; diff --git a/Library/PCProjectLoadedFiles.m b/Library/PCProjectLoadedFiles.m index b187105..aed96c2 100644 --- a/Library/PCProjectLoadedFiles.m +++ b/Library/PCProjectLoadedFiles.m @@ -63,12 +63,7 @@ [filesList setHeaderView:nil]; [filesList addTableColumn:filesColumn]; [filesList setDataSource:self]; -/* [filesList setBackgroundColor: [NSColor colorWithDeviceRed:0.88 - green:0.76 - blue:0.60 - alpha:1.0]];*/ - // Hack! Should be [filesList setDrawsGrid:NO] - [filesList setGridColor: [NSColor lightGrayColor]]; + [filesList setDrawsGrid:NO]; [filesList setTarget:self]; [filesList setDoubleAction:@selector(doubleClick:)]; [filesList setAction:@selector(click:)]; diff --git a/Library/PCProjectWindow.m b/Library/PCProjectWindow.m index 3e10fe4..2034807 100644 --- a/Library/PCProjectWindow.m +++ b/Library/PCProjectWindow.m @@ -105,62 +105,57 @@ buildButton = [[PCButton alloc] initWithFrame: NSMakeRect(0,5,43,43)]; [buildButton setRefusesFirstResponder:YES]; - [buildButton setTitle: @"Build"]; + [buildButton setToolTip: @"Build"]; [buildButton setImage: IMAGE(@"Build")]; [buildButton setTarget: self]; [buildButton setAction: @selector(showProjectBuild:)]; [buildButton setAutoresizingMask: (NSViewMaxXMargin | NSViewMinYMargin)]; [buildButton setButtonType: NSMomentaryPushButton]; [toolbarView addSubview: buildButton]; -// [buildButton setShowTooltip:YES]; RELEASE (buildButton); launchButton = [[PCButton alloc] initWithFrame: NSMakeRect(44,5,43,43)]; [launchButton setRefusesFirstResponder:YES]; - [launchButton setTitle: @"Launch/Debug"]; + [launchButton setToolTip: @"Launch/Debug"]; [launchButton setImage: IMAGE(@"Run")]; [launchButton setTarget: self]; [launchButton setAction: @selector(showProjectLaunch:)]; [launchButton setAutoresizingMask: (NSViewMaxXMargin | NSViewMinYMargin)]; [launchButton setButtonType: NSMomentaryPushButton]; [toolbarView addSubview: launchButton]; -// [launchButton setShowTooltip:YES]; RELEASE (launchButton); editorButton = [[PCButton alloc] initWithFrame: NSMakeRect(88,5,43,43)]; [editorButton setRefusesFirstResponder:YES]; - [editorButton setTitle: @"Editor"]; + [editorButton setToolTip: @"Editor"]; [editorButton setImage: IMAGE(@"Editor")]; [editorButton setTarget: self]; [editorButton setAction: @selector(showProjectEditor:)]; [editorButton setAutoresizingMask: (NSViewMaxXMargin | NSViewMinYMargin)]; [editorButton setButtonType: NSMomentaryPushButton]; [toolbarView addSubview: editorButton]; -// [editorButton setShowTooltip:YES]; RELEASE (editorButton); findButton = [[PCButton alloc] initWithFrame: NSMakeRect(132,5,43,43)]; [findButton setRefusesFirstResponder:YES]; - [findButton setTitle: @"Find"]; + [findButton setToolTip: @"Find"]; [findButton setImage: IMAGE(@"Find")]; [findButton setTarget: project]; [findButton setAction: @selector(showFindView:)]; [findButton setAutoresizingMask: (NSViewMaxXMargin | NSViewMinYMargin)]; [findButton setButtonType: NSMomentaryPushButton]; [toolbarView addSubview: findButton]; -// [findButton setShowTooltip:YES]; RELEASE (findButton); inspectorButton = [[PCButton alloc] initWithFrame: NSMakeRect(176,5,43,43)]; [inspectorButton setRefusesFirstResponder:YES]; - [inspectorButton setTitle: @"Inspector"]; + [inspectorButton setToolTip: @"Inspector"]; [inspectorButton setImage: IMAGE(@"Inspector")]; [inspectorButton setTarget: [project projectManager]]; [inspectorButton setAction: @selector(showProjectInspector:)]; [inspectorButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; [inspectorButton setButtonType: NSMomentaryPushButton]; [toolbarView addSubview: inspectorButton]; -// [inspectorButton setShowTooltip:YES]; RELEASE (inspectorButton); @@ -557,6 +552,7 @@ } [componentView setBorderType:NSBezelBorder]; + [componentView setFrame:NSMakeRect(0,0,128,130)]; [v_split addSubview:[[project projectLoadedFiles] componentView]]; [v_split adjustSubviews]; } @@ -590,8 +586,6 @@ } [self setCustomContentView:view]; } - - [[project projectBuilder] setTooltips]; } - (void)showProjectLaunch:(id)sender @@ -619,8 +613,6 @@ } [self setCustomContentView:view]; } - - [[project projectLauncher] setTooltips]; } - (void)showProjectEditor:(id)sender