From d7b837d03d47a5ffa60975081a2a7598edc839e3 Mon Sep 17 00:00:00 2001 From: Matthew Judy Date: Mon, 24 Nov 2003 07:46:39 +0000 Subject: [PATCH 01/16] Positioning changes are now reflected properly by the prefs. When changing positions, effects will be disabled/changed accordingly. Position prefs are now reflected when the panel opens. --- ITWindowEffect.m | 1 - ITWindowPositioning.h | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ITWindowEffect.m b/ITWindowEffect.m index 5745bd7..231dc76 100755 --- a/ITWindowEffect.m +++ b/ITWindowEffect.m @@ -27,7 +27,6 @@ __idle = YES; if ( [window conformsToProtocol:@protocol(ITWindowPositioning)] ) { - // Casts so the compiler won't gripe _verticalPosition = (ITVerticalWindowPosition)[(ITTransientStatusWindow *)window verticalPosition]; _horizontalPosition = (ITHorizontalWindowPosition)[(ITTransientStatusWindow *)window horizontalPosition]; } else { diff --git a/ITWindowPositioning.h b/ITWindowPositioning.h index bdb28f3..e2e5850 100755 --- a/ITWindowPositioning.h +++ b/ITWindowPositioning.h @@ -15,15 +15,15 @@ typedef enum { - ITWindowPositionLeft, - ITWindowPositionCenter, - ITWindowPositionRight, + ITWindowPositionLeft = 0, + ITWindowPositionCenter = 1, + ITWindowPositionRight = 2, } ITHorizontalWindowPosition; typedef enum { - ITWindowPositionTop, - ITWindowPositionMiddle, - ITWindowPositionBottom, + ITWindowPositionTop = 0, + ITWindowPositionMiddle = 1, + ITWindowPositionBottom = 2, } ITVerticalWindowPosition; -- 2.20.1 From 4f3da8543caacbaf1ce219e547e24a5490bee090 Mon Sep 17 00:00:00 2001 From: Matthew Judy Date: Mon, 24 Nov 2003 18:53:02 +0000 Subject: [PATCH 02/16] This about does it. I want to do a couple more things, especially multiple screen support. With the way I've got this set up, it should be pretty easy, but I need sleep first. If you want it in there, I'll do it after some sleep. --- Deprecated/ITChasingArrowsView.h | 4 +- ITBevelView.h | 4 +- ITButton.h | 15 ++++ ITButtonCell.h | 15 ++++ ITCategory-NSMenu.h | 2 +- ITCategory-NSView.h | 2 +- ITCoreGraphicsHacks.h | 4 +- ITCutWindowEffect.h | 4 +- ITCutWindowEffect.m | 25 ------- ITDissolveWindowEffect.h | 4 +- ITDissolveWindowEffect.m | 24 ------- ITHotKey.h | 21 ++++-- ITHotKeyCenter.h | 22 ++++-- ITImageCell.h | 6 +- ITImageView.h | 6 +- ITKeyBroadcaster.h | 21 ++++-- ITKeyCombo.h | 21 ++++-- ITKeyComboPanel.h | 22 ++++-- ITKit.h | 4 +- ITPivotWindowEffect.h | 4 +- ITPivotWindowEffect.m | 116 ++++++++++++++++-------------- ITSlideHorizontallyWindowEffect.h | 4 +- ITSlideHorizontallyWindowEffect.m | 23 ++---- ITSlideVerticallyWindowEffect.h | 4 +- ITSlideVerticallyWindowEffect.m | 25 +++---- ITStatusItem.h | 4 +- ITTSWBackgroundView.h | 4 +- ITTabView.h | 2 +- ITTableCornerView.h | 2 +- ITTableView.h | 2 +- ITTextField.h | 4 +- ITTextFieldCell.h | 6 +- ITTransientStatusWindow.h | 6 +- ITWindowEffect.h | 4 +- ITWindowPositioning.h | 5 +- 35 files changed, 229 insertions(+), 212 deletions(-) diff --git a/Deprecated/ITChasingArrowsView.h b/Deprecated/ITChasingArrowsView.h index 46ace83..6ef2844 100755 --- a/Deprecated/ITChasingArrowsView.h +++ b/Deprecated/ITChasingArrowsView.h @@ -2,10 +2,10 @@ * ITKit * ITChasingArrowsView * Animating Asynchronous Arrows Widget - * *** DEPRECATED: NSProgressIndicator now offers an async widget. MLJ - 01/14/2003 + * *** DEPRECATED: NSProgressIndicator now offers an async mode. MLJ - 01/14/2003 * * Original Author : Doug Brown <...> - * Responsibility : Matt Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITBevelView.h b/ITBevelView.h index de07fd0..e582c2e 100755 --- a/ITBevelView.h +++ b/ITBevelView.h @@ -3,8 +3,8 @@ * ITBevelView * NSView subclass which draws a bevel. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2003 iThink Software. * All Rights Reserved diff --git a/ITButton.h b/ITButton.h index 12f5599..618437d 100755 --- a/ITButton.h +++ b/ITButton.h @@ -1,3 +1,18 @@ +/* + * ITKit + * ITButton + * Stylized button for use in Status Windows. + * + * Original Author : Matthew Judy + * Responsibility : Matthew Judy + * Responsibility : Joseph Spiros + * + * Copyright (c) 2002 - 2003 iThink Software. + * All Rights Reserved + * + */ + + #import diff --git a/ITButtonCell.h b/ITButtonCell.h index fea3247..e99ef10 100755 --- a/ITButtonCell.h +++ b/ITButtonCell.h @@ -1,3 +1,18 @@ +/* + * ITKit + * ITButtonCell + * Cell used by the ITButton control. + * + * Original Author : Matthew Judy + * Responsibility : Matthew Judy + * Responsibility : Joseph Spiros + * + * Copyright (c) 2002 - 2003 iThink Software. + * All Rights Reserved + * + */ + + #import diff --git a/ITCategory-NSMenu.h b/ITCategory-NSMenu.h index ad058bd..6ccfb6e 100755 --- a/ITCategory-NSMenu.h +++ b/ITCategory-NSMenu.h @@ -4,7 +4,7 @@ * Category which extends NSMenu * * Original Author : Joseph Spiros - * Responsibility : Matt Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITCategory-NSView.h b/ITCategory-NSView.h index f4894b2..de8beff 100755 --- a/ITCategory-NSView.h +++ b/ITCategory-NSView.h @@ -4,7 +4,7 @@ * Category which extends NSView * * Original Author : Joseph Spiros - * Responsibility : Matt Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITCoreGraphicsHacks.h b/ITCoreGraphicsHacks.h index 31bc676..a07942b 100755 --- a/ITCoreGraphicsHacks.h +++ b/ITCoreGraphicsHacks.h @@ -3,8 +3,8 @@ * ITCoreGraphicsHacks * Header to import to work with private CoreGraphics API * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITCutWindowEffect.h b/ITCutWindowEffect.h index 4826001..fe53fc1 100755 --- a/ITCutWindowEffect.h +++ b/ITCutWindowEffect.h @@ -3,8 +3,8 @@ * ITCutWindowEffect * Effect subclass which performs a simple cut in or out, with no transition. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITCutWindowEffect.m b/ITCutWindowEffect.m index a33bac3..b4fa449 100755 --- a/ITCutWindowEffect.m +++ b/ITCutWindowEffect.m @@ -40,31 +40,6 @@ - (void)performAppear { - CGAffineTransform transform; - NSPoint appearPoint; - - //Set the location on the screen - if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) { - appearPoint.x = -( 32.0 + [[_window screen] visibleFrame].origin.x ); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) { - appearPoint.x = -(([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) - 32.0 - [_window frame].size.width); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionCenter ) { - appearPoint.x = ( [_window frame].size.width - [[_window screen] visibleFrame].size.width ) / 2; - } - - if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) { - appearPoint.y = ( 64.0 + [[_window screen] visibleFrame].origin.y - [_window frame].size.height ); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) { - appearPoint.y = -( [[_window screen] frame].size.height - ( [_window frame].size.height + 32.0 + [[_window screen] visibleFrame].origin.y) ); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionMiddle ) { - appearPoint.y = ( [_window frame].size.height - [[_window screen] visibleFrame].size.height) / 2; - } - - transform = CGAffineTransformMakeTranslation(appearPoint.x, appearPoint.y); - CGSSetWindowTransform([NSApp contextID], - (CGSWindowID)[_window windowNumber], - transform); - [_window orderFront:self]; [self setWindowVisibility:ITWindowVisibleState]; } diff --git a/ITDissolveWindowEffect.h b/ITDissolveWindowEffect.h index 4455e73..ebc6342 100755 --- a/ITDissolveWindowEffect.h +++ b/ITDissolveWindowEffect.h @@ -3,8 +3,8 @@ * ITDissolveWindowEffect * Effect subclass which performs a dissolve fade effect on a window. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITDissolveWindowEffect.m b/ITDissolveWindowEffect.m index 6e5011a..5481832 100755 --- a/ITDissolveWindowEffect.m +++ b/ITDissolveWindowEffect.m @@ -50,32 +50,8 @@ - (void)performAppear { - CGAffineTransform transform; - NSPoint appearPoint; __idle = NO; - //Set the location on the screen - if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) { - appearPoint.x = -( 32.0 + [[_window screen] visibleFrame].origin.x ); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) { - appearPoint.x = -(([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) - 32.0 - [_window frame].size.width); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionCenter ) { - appearPoint.x = ( [_window frame].size.width - [[_window screen] visibleFrame].size.width ) / 2; - } - - if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) { - appearPoint.y = ( 64.0 + [[_window screen] visibleFrame].origin.y - [_window frame].size.height ); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) { - appearPoint.y = -( [[_window screen] frame].size.height - ( [_window frame].size.height + 32.0 + [[_window screen] visibleFrame].origin.y) ); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionMiddle ) { - appearPoint.y = ( [_window frame].size.height - [[_window screen] visibleFrame].size.height) / 2; - } - - transform = CGAffineTransformMakeTranslation(appearPoint.x, appearPoint.y); - CGSSetWindowTransform([NSApp contextID], - (CGSWindowID)[_window windowNumber], - transform); - [self setWindowVisibility:ITWindowAppearingState]; [self performAppearFromProgress:0.0 effectTime:_effectTime]; } diff --git a/ITHotKey.h b/ITHotKey.h index d654bbc..7910081 100755 --- a/ITHotKey.h +++ b/ITHotKey.h @@ -1,14 +1,21 @@ -// -// ITHotKey.h -// -// Created by Quentin Carnicelli on Sat Aug 02 2003. -// Copyright (c) 2003 iThink Software. All rights reserved. -// +/* + * ITKit + * ITHotKey + * + * Original Author : Quentin Carnicelli <...> + * Responsibility : Kent Sutherland + * Responsibility : Matthew Judy + * + * Copyright (c) 2002 - 2003 iThink Software. + * All Rights Reserved + * + */ -#import +#import #import "ITKeyCombo.h" + @interface ITHotKey : NSObject { NSString* mName; diff --git a/ITHotKeyCenter.h b/ITHotKeyCenter.h index e984bc5..3c8bb4c 100755 --- a/ITHotKeyCenter.h +++ b/ITHotKeyCenter.h @@ -1,14 +1,23 @@ -// -// ITHotKeyCenter.h -// -// Created by Quentin Carnicelli on Sat Aug 02 2003. -// Copyright (c) 2003 iThink Software. All rights reserved. -// +/* + * ITKit + * ITHotKeyCenter + * + * Original Author : Quentin Carnicelli <...> + * Responsibility : Kent Sutherland + * Responsibility : Matthew Judy + * + * Copyright (c) 2002 - 2003 iThink Software. + * All Rights Reserved + * + */ + #import + @class ITHotKey; + @interface ITHotKeyCenter : NSObject { NSMutableDictionary* mHotKeys; //Keys are NSValue of EventHotKeyRef @@ -24,4 +33,5 @@ - (void)sendEvent: (NSEvent*)event; + @end diff --git a/ITImageCell.h b/ITImageCell.h index c4bb080..4da918b 100755 --- a/ITImageCell.h +++ b/ITImageCell.h @@ -1,10 +1,10 @@ /* * ITKit * ITImageCell - * NSImageCell subclass which adds new features. + * Cell used by the ITImageView control. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2003 iThink Software. * All Rights Reserved diff --git a/ITImageView.h b/ITImageView.h index d9141c8..aafb576 100755 --- a/ITImageView.h +++ b/ITImageView.h @@ -1,10 +1,10 @@ /* * ITKit * ITImageView - * NSImageView subclass which adds new features. + * NSImageView subclass which adds new features, such as smooth scaling. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2003 iThink Software. * All Rights Reserved diff --git a/ITKeyBroadcaster.h b/ITKeyBroadcaster.h index 9e30ed4..1fed89f 100755 --- a/ITKeyBroadcaster.h +++ b/ITKeyBroadcaster.h @@ -1,9 +1,16 @@ -// -// ITKeyBroadcaster.h -// -// Created by Quentin Carnicelli on Sun Aug 03 2003. -// Copyright (c) 2003 iThink Software. All rights reserved. -// +/* + * ITKit + * ITHotKeyBroadcaster + * + * Original Author : Quentin Carnicelli <...> + * Responsibility : Kent Sutherland + * Responsibility : Matthew Judy + * + * Copyright (c) 2002 - 2003 iThink Software. + * All Rights Reserved + * + */ + #import @@ -14,6 +21,8 @@ + (long)cocoaModifiersAsCarbonModifiers: (long)cocoaModifiers; + @end + __private_extern__ NSString* ITKeyBroadcasterKeyEvent; //keys: keyCombo as ITKeyCombo \ No newline at end of file diff --git a/ITKeyCombo.h b/ITKeyCombo.h index 5bda4c5..d5c3d77 100755 --- a/ITKeyCombo.h +++ b/ITKeyCombo.h @@ -1,9 +1,16 @@ -// -// ITKeyCombo.h -// -// Created by Quentin Carnicelli on Sat Aug 02 2003. -// Copyright (c) 2003 iThink Software. All rights reserved. -// +/* + * ITKit + * ITKeyCombo + * + * Original Author : Quentin Carnicelli <...> + * Responsibility : Kent Sutherland + * Responsibility : Matthew Judy + * + * Copyright (c) 2002 - 2003 iThink Software. + * All Rights Reserved + * + */ + #import @@ -30,8 +37,10 @@ - (BOOL)isClearCombo; - (BOOL)isValidHotKeyCombo; + @end + @interface ITKeyCombo (UserDisplayAdditions) - (NSString*)description; diff --git a/ITKeyComboPanel.h b/ITKeyComboPanel.h index fbe18aa..85806d4 100755 --- a/ITKeyComboPanel.h +++ b/ITKeyComboPanel.h @@ -1,17 +1,25 @@ -// -// ITKeyComboPanel.h +/* + * ITKit + * ITKeyComboPanel + * + * Original Author : Quentin Carnicelli <...> + * Responsibility : Kent Sutherland + * Responsibility : Matthew Judy + * + * Copyright (c) 2002 - 2003 iThink Software. + * All Rights Reserved + * + */ -// -// Created by Quentin Carnicelli on Sun Aug 03 2003. -// Copyright (c) 2003 iThink Software. All rights reserved. -// #import + @class ITKeyBroadcaster; @class ITKeyCombo; @class ITHotKey; + @interface ITKeyComboPanel : NSWindowController { IBOutlet NSTextField* mTitleField; @@ -37,4 +45,6 @@ - (IBAction)ok: (id)sender; - (IBAction)cancel: (id)sender; - (IBAction)clear: (id)sender; + + @end diff --git a/ITKit.h b/ITKit.h index ba348f0..50dacfb 100755 --- a/ITKit.h +++ b/ITKit.h @@ -2,8 +2,8 @@ * ITKit * iThink Software's custom extensions to Apple's AppKit framework * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITPivotWindowEffect.h b/ITPivotWindowEffect.h index 90be383..ae69b00 100755 --- a/ITPivotWindowEffect.h +++ b/ITPivotWindowEffect.h @@ -3,8 +3,8 @@ * ITPivotWindowEffect * Effect subclass which pivots (rotates) a window into position on the screen. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITPivotWindowEffect.m b/ITPivotWindowEffect.m index b5fe7c9..05dc3ac 100755 --- a/ITPivotWindowEffect.m +++ b/ITPivotWindowEffect.m @@ -68,7 +68,7 @@ [self setPivot:315.0]; [_window setAlphaValue:0.0]; } - + [_window orderFront:self]; _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) target:self @@ -80,13 +80,17 @@ - (void)appearStep { float interPivot = 0.0; - [_window setEffectProgress:([_window effectProgress] + _effectSpeed)]; - [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)]; - interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2); - [self setPivot:((interPivot * 45) + 315)]; + float progress = ([_window effectProgress] + _effectSpeed); + + progress = ( (progress < 1.0) ? progress : 1.0 ); + + [_window setEffectProgress:progress]; + + interPivot = (( sin((progress * pi) - (pi / 2)) + 1 ) / 2); + [self setPivot:(315 + (interPivot * 45))]; [_window setAlphaValue:interPivot]; - - if ( [_window effectProgress] >= 1.0 ) { + + if ( progress >= 1.0 ) { [self appearFinish]; } } @@ -96,9 +100,9 @@ [_effectTimer invalidate]; _effectTimer = nil; [self setWindowVisibility:ITWindowVisibleState]; - + __idle = YES; - + if ( __shouldReleaseWhenIdle ) { [self release]; } @@ -107,10 +111,10 @@ - (void)cancelAppear { [self setWindowVisibility:ITWindowVanishingState]; - + [_effectTimer invalidate]; _effectTimer = nil; - + [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; } @@ -136,7 +140,7 @@ [self setPivot:0.0]; [_window setAlphaValue:1.0]; } - + [_window orderFront:self]; _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) target:self @@ -148,13 +152,17 @@ - (void)vanishStep { float interPivot = 1.0; - [_window setEffectProgress:([_window effectProgress] - _effectSpeed)]; - [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)]; + float progress = ([_window effectProgress] - _effectSpeed); + + progress = ( (progress > 0.0) ? progress : 0.0); + + [_window setEffectProgress:progress]; + interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2); - [self setPivot:((interPivot * 45) + 315)]; + [self setPivot:(315 + (interPivot * 45))]; [_window setAlphaValue:interPivot]; - - if ( [_window effectProgress] <= 0.0 ) { + + if ( progress <= 0.0 ) { [self vanishFinish]; } } @@ -167,9 +175,9 @@ [_window setAlphaValue:1.0]; [self setPivot:0.0]; [self setWindowVisibility:ITWindowHiddenState]; - + __idle = YES; - + if ( __shouldReleaseWhenIdle ) { [self release]; } @@ -178,10 +186,10 @@ - (void)cancelVanish { [self setWindowVisibility:ITWindowAppearingState]; - + [_effectTimer invalidate]; _effectTimer = nil; - + [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; } @@ -194,51 +202,53 @@ - (void)setPivot:(float)angle { float degAngle; - NSPoint appearPoint; CGAffineTransform transform; + NSRect windowFrame = [_window frame]; + NSRect screenFrame = [[_window screen] frame]; + int hPos = [_window horizontalPosition]; + int vPos = [_window verticalPosition]; + float translateX; + float translateY; - if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) { - if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) { - degAngle = (angle * (pi / 180)); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) { - degAngle = (-angle * (pi / 180)); + if ( vPos == ITWindowPositionBottom ) { + if ( hPos == ITWindowPositionLeft ) { + angle = angle; + } else if ( hPos == ITWindowPositionRight ) { + angle = ( 45 - -(315 - angle) ); } - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) { - if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) { - degAngle = (angle * (pi / 180)); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) { - degAngle = (angle * (pi / 180)); + } else if ( vPos == ITWindowPositionTop ) { + if ( hPos == ITWindowPositionLeft ) { + angle = ( 45 - -(315 - angle) ); + } else if ( hPos == ITWindowPositionRight ) { + angle = angle; } } + degAngle = (angle * (pi / 180)); transform = CGAffineTransformMakeRotation(degAngle); - // Set pivot rotation point - //transform.tx = -( 32.0 + [[_window screen] visibleFrame].origin.x ); - transform.ty = ( [_window frame].size.height + 32.0 + [[_window screen] visibleFrame].origin.y ); - - if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) { - appearPoint.x = -( 32.0 + [[_window screen] visibleFrame].origin.x ); - transform.tx = -( 32.0 + [[_window screen] visibleFrame].origin.x ); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) { - transform.tx = -( 32.0 + [[_window screen] visibleFrame].origin.x ) + [_window frame].size.width; - appearPoint.x = -(([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) - 64.0); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionCenter ) { - appearPoint.x = ( [_window frame].size.width - [[_window screen] visibleFrame].size.width ) / 2; + if ( vPos == ITWindowPositionBottom ) { + transform.ty = ( windowFrame.size.height + windowFrame.origin.y); + translateY = -(screenFrame.size.height); + } else if ( vPos == ITWindowPositionTop ) { + transform.ty = -( screenFrame.size.height - windowFrame.origin.y - windowFrame.size.height ); + translateY = 0; + } + + if ( hPos == ITWindowPositionLeft ) { + transform.tx = -( windowFrame.origin.x ); + translateX = 0; + } else if ( hPos == ITWindowPositionRight ) { + transform.tx = ( screenFrame.size.width - windowFrame.origin.x ); + translateX = -(screenFrame.size.width); } - if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) { - appearPoint.y = ( [_window frame].size.height - [[_window screen] visibleFrame].size.height) / 2; - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) { - appearPoint.y = -( [[_window screen] frame].size.height - ([_window frame].origin.y) + 32.0 + [[_window screen] visibleFrame].origin.y) ; - }/* else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionMiddle ) { - appearPoint.y = ( [_window frame].size.height - [[_window screen] visibleFrame].size.height) / 2; - }*/ CGSSetWindowTransform([NSApp contextID], (CGSWindowID)[_window windowNumber], CGAffineTransformTranslate( transform, - appearPoint.x, - appearPoint.y ) ); + translateX, + translateY ) ); } + @end diff --git a/ITSlideHorizontallyWindowEffect.h b/ITSlideHorizontallyWindowEffect.h index 5b3047c..5054912 100755 --- a/ITSlideHorizontallyWindowEffect.h +++ b/ITSlideHorizontallyWindowEffect.h @@ -3,8 +3,8 @@ * ITSlideHorizontallyWindowEffect * Effect subclass which slides a window in from the right or left side of the screen. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITSlideHorizontallyWindowEffect.m b/ITSlideHorizontallyWindowEffect.m index e1b3066..f0e5d78 100755 --- a/ITSlideHorizontallyWindowEffect.m +++ b/ITSlideHorizontallyWindowEffect.m @@ -186,26 +186,17 @@ - (void)setSlide:(float)distance { CGAffineTransform transform; - float yPoint; + NSPoint translation; - if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) { - yPoint = ( 64.0 + [[_window screen] visibleFrame].origin.y - [_window frame].size.height ); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) { - yPoint = -( [[_window screen] frame].size.height - ( [_window frame].size.height + 32.0 + [[_window screen] visibleFrame].origin.y) ); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionMiddle ) { - yPoint = ( [_window frame].size.height - [[_window screen] visibleFrame].size.height) / 2; + if ( [_window horizontalPosition] == ITWindowPositionLeft ) { + translation.x = ( -([_window frame].origin.x) + distance ) ; + } else if ( [_window horizontalPosition] == ITWindowPositionRight ) { + translation.x = ( -([_window frame].origin.x) - distance ) ; } - /*if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) { - transform = CGAffineTransformMakeTranslation((distance - (32.0 + [[_window screen] visibleFrame].origin.x)), - ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) ? -( [[_window screen] frame].size.height - ( [_window frame].size.height + 32.0 + [[_window screen] visibleFrame].origin.y) ) : ( 64.0 + [[_window screen] visibleFrame].origin.y - [_window frame].size.height ) ); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) { - transform = CGAffineTransformMakeTranslation(-((([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) + distance) - 32.0 - [_window frame].size.width), - ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) ? -( [[_window screen] frame].size.height - ( [_window frame].size.height + 32.0 + [[_window screen] visibleFrame].origin.y) ) : ( 64.0 + [[_window screen] visibleFrame].origin.y - [_window frame].size.height ) ); - }*/ + translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); - transform = CGAffineTransformMakeTranslation( ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) ? (distance - (32.0 + [[_window screen] visibleFrame].origin.x)) : -((([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) + distance) - 32.0 - [_window frame].size.width), - yPoint); + transform = CGAffineTransformMakeTranslation( translation.x, translation.y ); CGSSetWindowTransform([NSApp contextID], (CGSWindowID)[_window windowNumber], diff --git a/ITSlideVerticallyWindowEffect.h b/ITSlideVerticallyWindowEffect.h index e267182..58a4fe9 100755 --- a/ITSlideVerticallyWindowEffect.h +++ b/ITSlideVerticallyWindowEffect.h @@ -3,8 +3,8 @@ * ITSlideVerticallyWindowEffect * Effect subclass which slides a window in from the top or bottom of the screen. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITSlideVerticallyWindowEffect.m b/ITSlideVerticallyWindowEffect.m index 6f2f47a..a8825ab 100755 --- a/ITSlideVerticallyWindowEffect.m +++ b/ITSlideVerticallyWindowEffect.m @@ -186,26 +186,17 @@ - (void)setSlide:(float)distance { CGAffineTransform transform; - float xPoint; + NSPoint translation; - if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) { - xPoint = -( 32.0 + [[_window screen] visibleFrame].origin.x ); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionRight ) { - xPoint = -(([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) - 32.0 - [_window frame].size.width); - } else if ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionCenter ) { - xPoint = ( [_window frame].size.width - [[_window screen] visibleFrame].size.width ) / 2; - } + translation.x = -( [_window frame].origin.x ); - /*if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionBottom ) { - transform = CGAffineTransformMakeTranslation( ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) ? -( 32.0 + [[_window screen] visibleFrame].origin.x ) : -(([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) - 32.0 - [_window frame].size.width), - -( [[_window screen] frame].size.height - ( distance + 32.0 + [[_window screen] visibleFrame].origin.y ) ) ); - } else if ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) { - transform = CGAffineTransformMakeTranslation( ( [(ITTransientStatusWindow *)_window horizontalPosition] == ITWindowPositionLeft ) ? -( 32.0 + [[_window screen] visibleFrame].origin.x ) : -(([[_window screen] visibleFrame].size.width + [[_window screen] visibleFrame].origin.x) - 32.0 - [_window frame].size.width), - [[_window screen] visibleFrame].origin.y - distance + 64.0 ); - }*/ + if ( [_window verticalPosition] == ITWindowPositionTop ) { + translation.y = ( (([_window frame].size.height * 2) - ([[_window screen] frame].size.height - [_window frame].origin.y)) - distance); + } else if ( [_window verticalPosition] == ITWindowPositionBottom ) { + translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - distance ); + } - transform = CGAffineTransformMakeTranslation(xPoint, - ( [(ITTransientStatusWindow *)_window verticalPosition] == ITWindowPositionTop ) ? ( [[_window screen] visibleFrame].origin.y - distance + 64.0 ) : -( [[_window screen] frame].size.height - ( distance + 32.0 + [[_window screen] visibleFrame].origin.y ) ) ); + transform = CGAffineTransformMakeTranslation( translation.x, translation.y ); CGSSetWindowTransform([NSApp contextID], (CGSWindowID)[_window windowNumber], diff --git a/ITStatusItem.h b/ITStatusItem.h index 4116107..fb381e0 100755 --- a/ITStatusItem.h +++ b/ITStatusItem.h @@ -4,8 +4,8 @@ * NSStatusItem subclass which reduces suckage * * Original Author : Joseph Spiros - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITTSWBackgroundView.h b/ITTSWBackgroundView.h index 7c80758..129eb03 100755 --- a/ITTSWBackgroundView.h +++ b/ITTSWBackgroundView.h @@ -3,8 +3,8 @@ * ITTSWBackgroundView * NSView subclass which draws a translucent background with rounded corners. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITTabView.h b/ITTabView.h index 278238a..89b5fef 100755 --- a/ITTabView.h +++ b/ITTabView.h @@ -4,7 +4,7 @@ * NSTabView subclass which includes convenience features * * Original Author : Kent Sutherland - * Responsibility : Matt Judy + * Responsibility : Matthew Judy * Responsibility : Kent Sutherland * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITTableCornerView.h b/ITTableCornerView.h index 43afa7e..b9a3577 100755 --- a/ITTableCornerView.h +++ b/ITTableCornerView.h @@ -4,7 +4,7 @@ * NSPopUpButton subclass for corner views in a table view. * * Original Author : Joseph Spiros - * Responsibility : Matt Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITTableView.h b/ITTableView.h index af06287..66444e8 100755 --- a/ITTableView.h +++ b/ITTableView.h @@ -5,7 +5,7 @@ * (with optional image) to the corner view of the TableView. * * Original Author : Joseph Spiros - * Responsibility : Matt Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002-2003 iThink Software. diff --git a/ITTextField.h b/ITTextField.h index 0a100ae..d796245 100755 --- a/ITTextField.h +++ b/ITTextField.h @@ -3,8 +3,8 @@ * ITTextField * Allows shadows to be drawn under text. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. diff --git a/ITTextFieldCell.h b/ITTextFieldCell.h index 50d8cf0..5285faf 100755 --- a/ITTextFieldCell.h +++ b/ITTextFieldCell.h @@ -1,10 +1,10 @@ /* * ITKit * ITTextFieldCell - * Allows shadows to be drawn under text in cells. + * Cell used by the ITTextField control. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2003 iThink Software. diff --git a/ITTransientStatusWindow.h b/ITTransientStatusWindow.h index 39f637e..26fd426 100755 --- a/ITTransientStatusWindow.h +++ b/ITTransientStatusWindow.h @@ -4,10 +4,10 @@ * NSWindow subclass for quick display of status information. * Similar to volume/brightness/eject bezel key windows. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros - * Contributor : Kent Sutherland + * Contributor : Kent Sutherland * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITWindowEffect.h b/ITWindowEffect.h index 8663331..9b6c0bd 100755 --- a/ITWindowEffect.h +++ b/ITWindowEffect.h @@ -3,8 +3,8 @@ * ITWindowEffect * Protocal and abstract superclass for performing effects on windows. * - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * * Copyright (c) 2002 - 2003 iThink Software. * All Rights Reserved diff --git a/ITWindowPositioning.h b/ITWindowPositioning.h index e2e5850..c43a7f4 100755 --- a/ITWindowPositioning.h +++ b/ITWindowPositioning.h @@ -3,9 +3,8 @@ * ITWindowPositioning * Protocol which defines methods for window positioning presets. * - * Original Author : Kent Sutherland - * Original Author : Matt Judy - * Responsibility : Matt Judy + * Original Author : Matthew Judy + * Responsibility : Matthew Judy * Responsibility : Joseph Spiros * * Copyright (c) 2002 - 2003 iThink Software. -- 2.20.1 From 55f9d57f56bbbbb2c589201246a29858c6cf4e56 Mon Sep 17 00:00:00 2001 From: Matthew Judy Date: Wed, 3 Dec 2003 11:34:32 +0000 Subject: [PATCH 03/16] Positioning Fixes. The window might still do some weirdness if you change its position when its appearing or vanishing, but the weirdness isn't as weird, and the window will recover and perform correctly on its next entrance or exit. --- ITPivotWindowEffect.m | 95 ++++++++++++++++++------------- ITSlideHorizontallyWindowEffect.m | 4 ++ ITSlideVerticallyWindowEffect.m | 2 + ITTransientStatusWindow.m | 1 - 4 files changed, 62 insertions(+), 40 deletions(-) diff --git a/ITPivotWindowEffect.m b/ITPivotWindowEffect.m index 05dc3ac..373c5f3 100755 --- a/ITPivotWindowEffect.m +++ b/ITPivotWindowEffect.m @@ -201,53 +201,70 @@ - (void)setPivot:(float)angle { - float degAngle; - CGAffineTransform transform; - NSRect windowFrame = [_window frame]; - NSRect screenFrame = [[_window screen] frame]; int hPos = [_window horizontalPosition]; int vPos = [_window verticalPosition]; - float translateX; - float translateY; + + if ( (hPos == ITWindowPositionCenter) || (vPos == ITWindowPositionMiddle) ) { - if ( vPos == ITWindowPositionBottom ) { - if ( hPos == ITWindowPositionLeft ) { - angle = angle; - } else if ( hPos == ITWindowPositionRight ) { - angle = ( 45 - -(315 - angle) ); + CGAffineTransform transform; + NSPoint translation; + + translation.x = ( -([_window frame].origin.x) ) ; + translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); + + transform = CGAffineTransformMakeTranslation( translation.x, translation.y ); + + CGSSetWindowTransform([NSApp contextID], + (CGSWindowID)[_window windowNumber], + transform); + } else { + + float degAngle; + NSRect windowFrame = [_window frame]; + NSRect screenFrame = [[_window screen] frame]; + float translateX; + float translateY; + CGAffineTransform transform; + + if ( vPos == ITWindowPositionBottom ) { + if ( hPos == ITWindowPositionLeft ) { + angle = angle; + } else if ( hPos == ITWindowPositionRight ) { + angle = ( 45 - -(315 - angle) ); + } + } else if ( vPos == ITWindowPositionTop ) { + if ( hPos == ITWindowPositionLeft ) { + angle = ( 45 - -(315 - angle) ); + } else if ( hPos == ITWindowPositionRight ) { + angle = angle; + } + } + + degAngle = (angle * (pi / 180)); + transform = CGAffineTransformMakeRotation(degAngle); + + if ( vPos == ITWindowPositionBottom ) { + transform.ty = ( windowFrame.size.height + windowFrame.origin.y); + translateY = -(screenFrame.size.height); + } else if ( vPos == ITWindowPositionTop ) { + transform.ty = -( screenFrame.size.height - windowFrame.origin.y - windowFrame.size.height ); + translateY = 0; } - } else if ( vPos == ITWindowPositionTop ) { + if ( hPos == ITWindowPositionLeft ) { - angle = ( 45 - -(315 - angle) ); + transform.tx = -( windowFrame.origin.x ); + translateX = 0; } else if ( hPos == ITWindowPositionRight ) { - angle = angle; + transform.tx = ( screenFrame.size.width - windowFrame.origin.x ); + translateX = -(screenFrame.size.width); } + + CGSSetWindowTransform([NSApp contextID], + (CGSWindowID)[_window windowNumber], + CGAffineTransformTranslate( transform, + translateX, + translateY ) ); } - - degAngle = (angle * (pi / 180)); - transform = CGAffineTransformMakeRotation(degAngle); - - if ( vPos == ITWindowPositionBottom ) { - transform.ty = ( windowFrame.size.height + windowFrame.origin.y); - translateY = -(screenFrame.size.height); - } else if ( vPos == ITWindowPositionTop ) { - transform.ty = -( screenFrame.size.height - windowFrame.origin.y - windowFrame.size.height ); - translateY = 0; - } - - if ( hPos == ITWindowPositionLeft ) { - transform.tx = -( windowFrame.origin.x ); - translateX = 0; - } else if ( hPos == ITWindowPositionRight ) { - transform.tx = ( screenFrame.size.width - windowFrame.origin.x ); - translateX = -(screenFrame.size.width); - } - - CGSSetWindowTransform([NSApp contextID], - (CGSWindowID)[_window windowNumber], - CGAffineTransformTranslate( transform, - translateX, - translateY ) ); } diff --git a/ITSlideHorizontallyWindowEffect.m b/ITSlideHorizontallyWindowEffect.m index f0e5d78..1a26d1f 100755 --- a/ITSlideHorizontallyWindowEffect.m +++ b/ITSlideHorizontallyWindowEffect.m @@ -192,6 +192,8 @@ translation.x = ( -([_window frame].origin.x) + distance ) ; } else if ( [_window horizontalPosition] == ITWindowPositionRight ) { translation.x = ( -([_window frame].origin.x) - distance ) ; + } else { + translation.x = ( -([_window frame].origin.x) ) ; } translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); @@ -202,4 +204,6 @@ (CGSWindowID)[_window windowNumber], transform); } + + @end diff --git a/ITSlideVerticallyWindowEffect.m b/ITSlideVerticallyWindowEffect.m index a8825ab..7237620 100755 --- a/ITSlideVerticallyWindowEffect.m +++ b/ITSlideVerticallyWindowEffect.m @@ -194,6 +194,8 @@ translation.y = ( (([_window frame].size.height * 2) - ([[_window screen] frame].size.height - [_window frame].origin.y)) - distance); } else if ( [_window verticalPosition] == ITWindowPositionBottom ) { translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - distance ); + } else { + translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); } transform = CGAffineTransformMakeTranslation( translation.x, translation.y ); diff --git a/ITTransientStatusWindow.m b/ITTransientStatusWindow.m index c47f9af..4f03f53 100755 --- a/ITTransientStatusWindow.m +++ b/ITTransientStatusWindow.m @@ -126,7 +126,6 @@ static ITTransientStatusWindow *staticWindow = nil; _reallyIgnoresEvents = flag; } - /* - (id)contentView -- 2.20.1 From 3269e9dfcbe058cef9e1da01ab45a93f07ee2be1 Mon Sep 17 00:00:00 2001 From: Matthew Judy Date: Wed, 3 Dec 2003 13:45:00 +0000 Subject: [PATCH 04/16] Shadowless StatusWindow graphics, as well as an ITImageView which casts a shadow. --- ITImageCell.h | 28 +++++++++++ ITImageCell.m | 136 +++++++++++++++++++++++++++++++++++++++++++++++--- ITImageView.h | 22 ++++++++ ITImageView.m | 70 ++++++++++++++++++++++++++ 4 files changed, 248 insertions(+), 8 deletions(-) diff --git a/ITImageCell.h b/ITImageCell.h index 4da918b..d3a9424 100755 --- a/ITImageCell.h +++ b/ITImageCell.h @@ -19,10 +19,38 @@ BOOL _scalesSmoothly; + BOOL castsShadow; + + float shadowElevation; + float shadowAzimuth; + float shadowAmbient; + float shadowHeight; + float shadowRadius; + float shadowSaturation; } - (BOOL)scalesSmoothly; - (void)setScalesSmoothly:(BOOL)flag; +- (BOOL)castsShadow; +- (void)setCastsShadow:(BOOL)newSetting; + +- (float)shadowElevation; /* Light source elevation in degrees. Defaults to 45.0 */ +- (void)setShadowElevation:(float)newElevation; + +- (float)shadowAzimuth; /* Light source azimuth in degrees. Defaults to 90.0 */ +- (void)setShadowAzimuth:(float)newAzimuth; + +- (float)shadowAmbient; /* Amount of ambient light. Defaults to 0.15 */ +- (void)setShadowAmbient:(float)newAmbient; + +- (float)shadowHeight; /* Height above the canvas. Defaults to 1.0 */ +- (void)setShadowHeight:(float)newHeight; + +- (float)shadowRadius; /* Blur radius. Defaults to 4.0 */ +- (void)setShadowRadius:(float)newRadius; + +- (float)shadowSaturation; /* Maximum saturation. Defaults to 1.0 */ +- (void)setShadowSaturation:(float)newSaturation; @end diff --git a/ITImageCell.m b/ITImageCell.m index cefbcff..d8f38b9 100755 --- a/ITImageCell.m +++ b/ITImageCell.m @@ -1,4 +1,6 @@ #import "ITImageCell.h" +#import +#import "ITCoreGraphicsHacks.h" @implementation ITImageCell @@ -7,27 +9,68 @@ - (id)initImageCell:(NSImage *)image { if ( (self = [super initImageCell:image]) ) { - _scalesSmoothly = YES; + _scalesSmoothly = YES; + castsShadow = NO; + shadowElevation = 45.0; + shadowAzimuth = 90.0; + shadowAmbient = 0.15; + shadowHeight = 1.00; + shadowRadius = 4.00; + shadowSaturation = 1.0; } NSLog(@"foo"); return self; } - +- (id)init +{ + if ( (self = [super init]) ) { + _scalesSmoothly = YES; + castsShadow = NO; + shadowElevation = 45.0; + shadowAzimuth = 90.0; + shadowAmbient = 0.15; + shadowHeight = 1.00; + shadowRadius = 4.00; + shadowSaturation = 1.0; + } + return self; +} - (void)drawWithFrame:(NSRect)rect inView:(NSView *)controlView { - NSImageInterpolation interpolation; - + CGSGenericObj style = nil; + CGShadowStyle shadow; + + if ( _scalesSmoothly || castsShadow ) { + [NSGraphicsContext saveGraphicsState]; + } + if ( _scalesSmoothly ) { - interpolation = [[NSGraphicsContext currentContext] imageInterpolation]; - [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]; + CGContextSetInterpolationQuality([[NSGraphicsContext currentContext] graphicsPort], kCGInterpolationHigh); + } + + if ( castsShadow ) { + // Create the shadow style to use for drawing the string + shadow.version = 0; + shadow.elevation = shadowElevation; + shadow.azimuth = shadowAzimuth; + shadow.ambient = shadowAmbient; + shadow.height = shadowHeight; + shadow.radius = shadowRadius; + shadow.saturation = shadowSaturation; + style = CGStyleCreateShadow(&shadow); + CGContextSetStyle([[NSGraphicsContext currentContext] graphicsPort], style); } [super drawWithFrame:rect inView:controlView]; - if ( _scalesSmoothly ) { - [[NSGraphicsContext currentContext] setImageInterpolation:interpolation]; + if ( _scalesSmoothly || castsShadow ) { + [NSGraphicsContext restoreGraphicsState]; + } + + if ( castsShadow ) { + CGStyleRelease(style); } } @@ -42,5 +85,82 @@ [[self controlView] setNeedsDisplay:YES]; } +- (BOOL)castsShadow; +{ + return castsShadow; +} + +- (void)setCastsShadow:(BOOL)newSetting; +{ + castsShadow = newSetting; + [[self controlView] setNeedsDisplay:YES]; +} + +- (float)shadowElevation; +{ + return shadowElevation; +} + +- (void)setShadowElevation:(float)newElevation; +{ + shadowElevation = newElevation; + [[self controlView] setNeedsDisplay:YES]; +} + +- (float)shadowAzimuth; +{ + return shadowAzimuth; +} + +- (void)setShadowAzimuth:(float)newAzimuth; +{ + shadowAzimuth = newAzimuth; + [[self controlView] setNeedsDisplay:YES]; +} + +- (float)shadowAmbient; +{ + return shadowAmbient; +} + +- (void)setShadowAmbient:(float)newAmbient; +{ + shadowAmbient = newAmbient; + [[self controlView] setNeedsDisplay:YES]; +} + +- (float)shadowHeight; +{ + return shadowHeight; +} + +- (void)setShadowHeight:(float)newHeight; +{ + shadowHeight = newHeight; + [[self controlView] setNeedsDisplay:YES]; +} + +- (float)shadowRadius; +{ + return shadowRadius; +} + +- (void)setShadowRadius:(float)newRadius; +{ + shadowRadius = newRadius; + [[self controlView] setNeedsDisplay:YES]; +} + +- (float)shadowSaturation; +{ + return shadowSaturation; +} + +- (void)setShadowSaturation:(float)newSaturation; +{ + shadowSaturation = newSaturation; + [[self controlView] setNeedsDisplay:YES]; +} + @end diff --git a/ITImageView.h b/ITImageView.h index aafb576..72b768d 100755 --- a/ITImageView.h +++ b/ITImageView.h @@ -22,4 +22,26 @@ - (BOOL)scalesSmoothly; - (void)setScalesSmoothly:(BOOL)flag; +- (BOOL)castsShadow; +- (void)setCastsShadow:(BOOL)newSetting; + +- (float)shadowElevation; /* Light source elevation in degrees. Defaults to 45.0 */ +- (void)setShadowElevation:(float)newElevation; + +- (float)shadowAzimuth; /* Light source azimuth in degrees. Defaults to 90.0 */ +- (void)setShadowAzimuth:(float)newAzimuth; + +- (float)shadowAmbient; /* Amount of ambient light. Defaults to 0.15 */ +- (void)setShadowAmbient:(float)newAmbient; + +- (float)shadowHeight; /* Height above the canvas. Defaults to 1.0 */ +- (void)setShadowHeight:(float)newHeight; + +- (float)shadowRadius; /* Blur radius. Defaults to 4.0 */ +- (void)setShadowRadius:(float)newRadius; + +- (float)shadowSaturation; /* Maximum saturation. Defaults to 1.0 */ +- (void)setShadowSaturation:(float)newSaturation; + + @end diff --git a/ITImageView.m b/ITImageView.m index 899cae6..228e2f4 100755 --- a/ITImageView.m +++ b/ITImageView.m @@ -36,5 +36,75 @@ [[self cell] setScalesSmoothly:flag]; } +- (BOOL)castsShadow; +{ + return [[self cell] castsShadow]; +} + +- (void)setCastsShadow:(BOOL)newSetting; +{ + [[self cell] setCastsShadow:newSetting]; +} + +- (float)shadowElevation; +{ + return [[self cell] shadowElevation]; +} + +- (void)setShadowElevation:(float)newElevation; +{ + [[self cell] setShadowElevation:newElevation]; +} + +- (float)shadowAzimuth; +{ + return [[self cell] shadowAzimuth]; +} + +- (void)setShadowAzimuth:(float)newAzimuth; +{ + [[self cell] setShadowAzimuth:newAzimuth]; +} + +- (float)shadowAmbient; +{ + return [[self cell] shadowAmbient]; +} + +- (void)setShadowAmbient:(float)newAmbient; +{ + [[self cell] setShadowAmbient:newAmbient]; +} + +- (float)shadowHeight; +{ + return [[self cell] shadowHeight]; +} + +- (void)setShadowHeight:(float)newHeight; +{ + [[self cell] setShadowHeight:newHeight]; +} + +- (float)shadowRadius; +{ + return [[self cell] shadowRadius]; +} + +- (void)setShadowRadius:(float)newRadius; +{ + [[self cell] setShadowRadius:newRadius]; +} + +- (float)shadowSaturation; +{ + return [[self cell] shadowSaturation]; +} + +- (void)setShadowSaturation:(float)newSaturation; +{ + [[self cell] setShadowSaturation:newSaturation]; +} + @end -- 2.20.1 From a95939f73c92bc42ae05d4585b57c6b95126601a Mon Sep 17 00:00:00 2001 From: Joseph Spiros Date: Thu, 25 Dec 2003 23:29:31 +0000 Subject: [PATCH 05/16] Adding some new classes that ease access of Carbon/Mac-style resource files/forks. These classes are also easily extensible to add support for getting native forms of the data contained within various resources. Also fixed some random warnings in Status Window code. --- ITKit.xcode/project.pbxproj | 289 +++++++++++++++++++++++------------- ITMacResource.h | 33 ++++ ITMacResource.m | 89 +++++++++++ ITMacResourceFile.h | 22 +++ ITMacResourceFile.m | 53 +++++++ ITPivotWindowEffect.m | 4 +- ITStringMacResource.h | 16 ++ ITStringMacResource.m | 26 ++++ 8 files changed, 426 insertions(+), 106 deletions(-) create mode 100755 ITMacResource.h create mode 100755 ITMacResource.m create mode 100755 ITMacResourceFile.h create mode 100755 ITMacResourceFile.m create mode 100755 ITStringMacResource.h create mode 100755 ITStringMacResource.m diff --git a/ITKit.xcode/project.pbxproj b/ITKit.xcode/project.pbxproj index b00a982..d77009f 100755 --- a/ITKit.xcode/project.pbxproj +++ b/ITKit.xcode/project.pbxproj @@ -109,18 +109,18 @@ sourceTree = ""; }; 0867D69BFE84028FC02AAC07 = { - expectedFileType = wrapper.framework; fallbackIsa = PBXFileReference; isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; refType = 0; sourceTree = ""; }; 0867D6A5FE840307C02AAC07 = { - expectedFileType = wrapper.framework; fallbackIsa = PBXFileReference; isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; refType = 0; @@ -150,9 +150,9 @@ sourceTree = ""; }; 089C1667FE841158C02AAC07 = { - expectedFileType = text.plist.strings; fileEncoding = 10; isa = PBXFileReference; + lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; refType = 4; @@ -160,6 +160,7 @@ }; 08FB77AEFE84172EC02AAC07 = { children = ( + 7C01A1B7059B4A86003A4662, 7C992F93054F53F2000B93EA, 7C992F96054F53F7000B93EA, 7C992F9B054F547C000B93EA, @@ -195,9 +196,9 @@ sourceTree = ""; }; 1058C7B1FEA5585E11CA2CBB = { - expectedFileType = wrapper.framework; fallbackIsa = PBXFileReference; isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; refType = 0; @@ -237,9 +238,9 @@ sourceTree = ""; }; 2A30D88E056B3AD90087AE54 = { - expectedFileType = text.plist; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = text.plist; name = English; path = English.lproj/ITKeyCodes.plist; refType = 4; @@ -252,24 +253,24 @@ }; }; 2A30D892056B3AE30087AE54 = { - expectedFileType = text.plist; isa = PBXFileReference; + lastKnownFileType = text.plist; name = French; path = French.lproj/ITKeyCodes.plist; refType = 4; sourceTree = ""; }; 2A30D895056B3AF20087AE54 = { - expectedFileType = text.plist; isa = PBXFileReference; + lastKnownFileType = text.plist; name = German; path = German.lproj/ITKeyCodes.plist; refType = 4; sourceTree = ""; }; 2A30D898056B3B000087AE54 = { - expectedFileType = text.plist; isa = PBXFileReference; + lastKnownFileType = text.plist; name = Japanese; path = Japanese.lproj/ITKeyCodes.plist; refType = 4; @@ -309,8 +310,8 @@ sourceTree = ""; }; 2A30D8A2056B3BE30087AE54 = { - expectedFileType = wrapper.nib; isa = PBXFileReference; + lastKnownFileType = wrapper.nib; name = English; path = English.lproj/ITKeyComboPanel.nib; refType = 4; @@ -323,24 +324,24 @@ }; }; 2A30D8A6056B3BEE0087AE54 = { - expectedFileType = wrapper.nib; isa = PBXFileReference; + lastKnownFileType = wrapper.nib; name = French; path = French.lproj/ITKeyComboPanel.nib; refType = 4; sourceTree = ""; }; 2A30D8A9056B3BF60087AE54 = { - expectedFileType = wrapper.nib; isa = PBXFileReference; + lastKnownFileType = wrapper.nib; name = German; path = German.lproj/ITKeyComboPanel.nib; refType = 4; sourceTree = ""; }; 2A30D8B5056B3C1B0087AE54 = { - expectedFileType = wrapper.nib; isa = PBXFileReference; + lastKnownFileType = wrapper.nib; name = Japanese; path = Japanese.lproj/ITKeyComboPanel.nib; refType = 4; @@ -360,9 +361,9 @@ sourceTree = ""; }; 2A30D8BD056B3C5D0087AE54 = { - expectedFileType = text.plist.strings; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; refType = 4; @@ -375,24 +376,24 @@ }; }; 2A30D8C1056B3C670087AE54 = { - expectedFileType = text.plist.strings; isa = PBXFileReference; + lastKnownFileType = text.plist.strings; name = French; path = French.lproj/Localizable.strings; refType = 4; sourceTree = ""; }; 2A30D8C4056B3C750087AE54 = { - expectedFileType = text.plist.strings; isa = PBXFileReference; + lastKnownFileType = text.plist.strings; name = German; path = German.lproj/Localizable.strings; refType = 4; sourceTree = ""; }; 2A30D8C7056B3C830087AE54 = { - expectedFileType = text.plist.strings; isa = PBXFileReference; + lastKnownFileType = text.plist.strings; name = Japanese; path = Japanese.lproj/Localizable.strings; refType = 4; @@ -433,17 +434,17 @@ targetProxy = 2AC8297F056C451900A7D7E2; }; 2AC8313F056D00F700A7D7E2 = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITImageView.h; refType = 4; sourceTree = ""; }; 2AC83140056D00F700A7D7E2 = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITImageView.m; refType = 4; sourceTree = ""; @@ -464,17 +465,17 @@ }; }; 2AC8319B056D037700A7D7E2 = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITImageCell.h; refType = 4; sourceTree = ""; }; 2AC8319C056D037700A7D7E2 = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITImageCell.m; refType = 4; sourceTree = ""; @@ -514,9 +515,9 @@ sourceTree = ""; }; 32DBCF5E0370ADEE00C91783 = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITKit_Prefix.pch; refType = 4; sourceTree = ""; @@ -531,6 +532,86 @@ //7C2 //7C3 //7C4 + 7C01A1B7059B4A86003A4662 = { + children = ( + 7C01A1BA059B4A8B003A4662, + ); + isa = PBXGroup; + name = Carbon; + refType = 4; + sourceTree = ""; + }; + 7C01A1BA059B4A8B003A4662 = { + children = ( + 7C01A1BF059B4AA1003A4662, + 7C01A1C0059B4AA1003A4662, + 7C01A1C5059B4AAC003A4662, + 7C01A1C6059B4AAC003A4662, + 7C23B320059BA4C000E08741, + ); + isa = PBXGroup; + name = Resources; + refType = 4; + sourceTree = ""; + }; + 7C01A1BF059B4AA1003A4662 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITMacResourceFile.h; + refType = 4; + sourceTree = ""; + }; + 7C01A1C0059B4AA1003A4662 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITMacResourceFile.m; + refType = 4; + sourceTree = ""; + }; + 7C01A1C5059B4AAC003A4662 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITMacResource.h; + refType = 4; + sourceTree = ""; + }; + 7C01A1C6059B4AAC003A4662 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITMacResource.m; + refType = 4; + sourceTree = ""; + }; + 7C23B316059BA4AA00E08741 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITStringMacResource.h; + refType = 4; + sourceTree = ""; + }; + 7C23B317059BA4AA00E08741 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITStringMacResource.m; + refType = 4; + sourceTree = ""; + }; + 7C23B320059BA4C000E08741 = { + children = ( + 7C23B316059BA4AA00E08741, + 7C23B317059BA4AA00E08741, + ); + isa = PBXGroup; + name = "Custom Types"; + refType = 4; + sourceTree = ""; + }; 7C5B7C93054F6EC9008379B6 = { fileRef = 8DC2EF5B0486A6940098B216; isa = PBXBuildFile; @@ -538,409 +619,409 @@ }; }; 7C992DC9054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITBevelView.h; refType = 4; sourceTree = ""; }; 7C992DCA054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITBevelView.m; refType = 4; sourceTree = ""; }; 7C992DCB054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITButton.h; refType = 4; sourceTree = ""; }; 7C992DCC054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITButton.m; refType = 4; sourceTree = ""; }; 7C992DCD054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITButtonCell.h; refType = 4; sourceTree = ""; }; 7C992DCE054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITButtonCell.m; refType = 4; sourceTree = ""; }; 7C992DCF054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = "ITCategory-NSMenu.h"; refType = 4; sourceTree = ""; }; 7C992DD0054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = "ITCategory-NSMenu.m"; refType = 4; sourceTree = ""; }; 7C992DD1054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = "ITCategory-NSView.h"; refType = 4; sourceTree = ""; }; 7C992DD2054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = "ITCategory-NSView.m"; refType = 4; sourceTree = ""; }; 7C992DD3054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITCoreGraphicsHacks.h; refType = 4; sourceTree = ""; }; 7C992DD4054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITCutWindowEffect.h; refType = 4; sourceTree = ""; }; 7C992DD5054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITCutWindowEffect.m; refType = 4; sourceTree = ""; }; 7C992DD6054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITDissolveWindowEffect.h; refType = 4; sourceTree = ""; }; 7C992DD7054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITDissolveWindowEffect.m; refType = 4; sourceTree = ""; }; 7C992DD8054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITTSWBackgroundView.h; refType = 4; sourceTree = ""; }; 7C992DD9054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITTSWBackgroundView.m; refType = 4; sourceTree = ""; }; 7C992DDA054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITHotKey.h; refType = 4; sourceTree = ""; }; 7C992DDB054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITHotKey.m; refType = 4; sourceTree = ""; }; 7C992DDC054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITHotKeyCenter.h; refType = 4; sourceTree = ""; }; 7C992DDD054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITHotKeyCenter.m; refType = 4; sourceTree = ""; }; 7C992DDE054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITKeyBroadcaster.h; refType = 4; sourceTree = ""; }; 7C992DDF054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITKeyBroadcaster.m; refType = 4; sourceTree = ""; }; 7C992DE0054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITKeyCombo.h; refType = 4; sourceTree = ""; }; 7C992DE1054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITKeyCombo.m; refType = 4; sourceTree = ""; }; 7C992DE2054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITKeyComboPanel.h; refType = 4; sourceTree = ""; }; 7C992DE3054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITKeyComboPanel.m; refType = 4; sourceTree = ""; }; 7C992DE4054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITKit.h; refType = 4; sourceTree = ""; }; 7C992DE7054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITPivotWindowEffect.h; refType = 4; sourceTree = ""; }; 7C992DE8054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITPivotWindowEffect.m; refType = 4; sourceTree = ""; }; 7C992DE9054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITSlideHorizontallyWindowEffect.h; refType = 4; sourceTree = ""; }; 7C992DEA054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITSlideHorizontallyWindowEffect.m; refType = 4; sourceTree = ""; }; 7C992DEB054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITSlideVerticallyWindowEffect.h; refType = 4; sourceTree = ""; }; 7C992DEC054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITSlideVerticallyWindowEffect.m; refType = 4; sourceTree = ""; }; 7C992DED054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITStatusItem.h; refType = 4; sourceTree = ""; }; 7C992DEE054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITStatusItem.m; refType = 4; sourceTree = ""; }; 7C992DEF054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITTableCornerView.h; refType = 4; sourceTree = ""; }; 7C992DF0054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITTableCornerView.m; refType = 4; sourceTree = ""; }; 7C992DF1054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITTableView.h; refType = 4; sourceTree = ""; }; 7C992DF2054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITTableView.m; refType = 4; sourceTree = ""; }; 7C992DF3054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITTabView.h; refType = 4; sourceTree = ""; }; 7C992DF4054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITTabView.m; refType = 4; sourceTree = ""; }; 7C992DF5054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITTextField.h; refType = 4; sourceTree = ""; }; 7C992DF6054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITTextField.m; refType = 4; sourceTree = ""; }; 7C992DF7054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITTextFieldCell.h; refType = 4; sourceTree = ""; }; 7C992DF8054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITTextFieldCell.m; refType = 4; sourceTree = ""; }; 7C992DF9054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITTransientStatusWindow.h; refType = 4; sourceTree = ""; }; 7C992DFA054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITTransientStatusWindow.m; refType = 4; sourceTree = ""; }; 7C992DFB054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITWindowEffect.h; refType = 4; sourceTree = ""; }; 7C992DFC054F5179000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; path = ITWindowEffect.m; refType = 4; sourceTree = ""; }; 7C992DFD054F5179000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; path = ITWindowPositioning.h; refType = 4; sourceTree = ""; @@ -1337,15 +1418,15 @@ sourceTree = ""; }; 7C992E3F054F5246000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; path = ITKeyboardIcon.tiff; refType = 4; sourceTree = ""; }; 7C992E43054F5246000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; path = URLTextViewHand.tiff; refType = 4; sourceTree = ""; @@ -1363,9 +1444,9 @@ }; }; 7C992E78054F5285000B93EA = { - expectedFileType = text; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = text; path = EffectSupport.txt; refType = 4; sourceTree = ""; @@ -1473,7 +1554,7 @@ productType = "com.apple.product-type.application"; }; 7C992F87054F5389000B93EA = { - expectedFileType = wrapper.application; + explicitFileType = wrapper.application; includeInIndex = 0; isa = PBXFileReference; path = ITKitShowcase.app; @@ -1564,18 +1645,18 @@ sourceTree = ""; }; 7C993015054F54F0000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; name = ITChasingArrowsView.h; path = Deprecated/ITChasingArrowsView.h; refType = 4; sourceTree = ""; }; 7C993016054F54F0000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; name = ITChasingArrowsView.m; path = Deprecated/ITChasingArrowsView.m; refType = 4; @@ -1600,80 +1681,80 @@ sourceTree = ""; }; 7C993035054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow1.tiff; path = Deprecated/ITChasingArrow1.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C993036054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow2.tiff; path = Deprecated/ITChasingArrow2.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C993037054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow3.tiff; path = Deprecated/ITChasingArrow3.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C993038054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow4.tiff; path = Deprecated/ITChasingArrow4.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C993039054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow5.tiff; path = Deprecated/ITChasingArrow5.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C99303A054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow6.tiff; path = Deprecated/ITChasingArrow6.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C99303B054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow7.tiff; path = Deprecated/ITChasingArrow7.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C99303C054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow8.tiff; path = Deprecated/ITChasingArrow8.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C99303D054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow9.tiff; path = Deprecated/ITChasingArrow9.tiff; refType = 2; sourceTree = SOURCE_ROOT; }; 7C99303E054F6524000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITChasingArrow10.tiff; path = Deprecated/ITChasingArrow10.tiff; refType = 2; @@ -1736,9 +1817,9 @@ sourceTree = ""; }; 7C99309F054F6992000B93EA = { - expectedFileType = text.plist.strings; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = text.plist.strings; name = English; path = Showcase/English.lproj/InfoPlist.strings; refType = 4; @@ -1761,8 +1842,8 @@ sourceTree = ""; }; 7C9930DC054F699B000B93EA = { - expectedFileType = wrapper.nib; isa = PBXFileReference; + lastKnownFileType = wrapper.nib; name = English; path = Showcase/English.lproj/MainMenu.nib; refType = 4; @@ -1803,56 +1884,56 @@ sourceTree = ""; }; 7C993102054F69F9000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = CD.tiff; path = Showcase/CD.tiff; refType = 4; sourceTree = ""; }; 7C993103054F69F9000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = iPod.tif; path = Showcase/iPod.tif; refType = 4; sourceTree = ""; }; 7C993104054F69F9000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITStatusItem.tiff; path = Showcase/ITStatusItem.tiff; refType = 4; sourceTree = ""; }; 7C993105054F69F9000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = ITStatusItemInv.tiff; path = Showcase/ITStatusItemInv.tiff; refType = 4; sourceTree = ""; }; 7C993106054F69F9000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = Library.tiff; path = Showcase/Library.tiff; refType = 4; sourceTree = ""; }; 7C993107054F69F9000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = Radio.tiff; path = Showcase/Radio.tiff; refType = 4; sourceTree = ""; }; 7C993108054F69F9000B93EA = { - expectedFileType = image.tiff; isa = PBXFileReference; + lastKnownFileType = image.tiff; name = Volume.tiff; path = Showcase/Volume.tiff; refType = 4; @@ -1901,27 +1982,27 @@ }; }; 7C99312D054F6A03000B93EA = { - expectedFileType = sourcecode.c.h; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; name = Controller.h; path = Showcase/Controller.h; refType = 4; sourceTree = ""; }; 7C99312E054F6A03000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; name = Controller.m; path = Showcase/Controller.m; refType = 4; sourceTree = ""; }; 7C99312F054F6A03000B93EA = { - expectedFileType = sourcecode.c.objc; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; name = main.m; path = Showcase/main.m; refType = 4; @@ -1946,8 +2027,8 @@ }; }; 7CC84BE0054F6CA2001DC704 = { - expectedFileType = wrapper.framework; isa = PBXFileReference; + lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; refType = 0; @@ -1960,8 +2041,8 @@ }; }; 7CC84BE4054F6CAA001DC704 = { - expectedFileType = wrapper.framework; isa = PBXFileReference; + lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; refType = 0; @@ -2145,15 +2226,15 @@ runOnlyForDeploymentPostprocessing = 0; }; 8DC2EF5A0486A6940098B216 = { - expectedFileType = text.plist; fileEncoding = 4; isa = PBXFileReference; + lastKnownFileType = text.plist; path = Info.plist; refType = 4; sourceTree = ""; }; 8DC2EF5B0486A6940098B216 = { - expectedFileType = wrapper.framework; + explicitFileType = wrapper.framework; includeInIndex = 0; isa = PBXFileReference; path = ITKit.framework; diff --git a/ITMacResource.h b/ITMacResource.h new file mode 100755 index 0000000..c05da2f --- /dev/null +++ b/ITMacResource.h @@ -0,0 +1,33 @@ +// +// ITMacResource.h +// ITKit +// +// Created by Joseph Spiros on Thu Dec 25 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import +#import + +typedef ResType ITMacResourceType; + +@interface ITMacResource : NSObject { + @protected + Handle _handle; +} ++ (void)_registerClass:(Class)class forType:(ITMacResourceType)type; ++ (Class)_classForType:(ITMacResourceType)type; + ++ (id)_resourceWithHandle:(Handle)handle; +- (id)_initWithHandle:(Handle)handle; + +- (Handle)_handle; + +- (NSData *)data; +- (ITMacResourceType)type; +- (NSNumber *)id; +- (NSString *)name; + +- (Class)nativeRepresentationClass; +- (id)nativeRepresentation; +@end diff --git a/ITMacResource.m b/ITMacResource.m new file mode 100755 index 0000000..1ae8883 --- /dev/null +++ b/ITMacResource.m @@ -0,0 +1,89 @@ +// +// ITMacResource.m +// ITKit +// +// Created by Joseph Spiros on Thu Dec 25 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import "ITMacResource.h" + + +@implementation ITMacResource + +static NSMutableDictionary *_resourceTypeClasses = nil; + ++ (void)_registerClass:(Class)class forType:(ITMacResourceType)type { + if (!_resourceTypeClasses) { + _resourceTypeClasses = [[NSMutableDictionary dictionary] retain]; + } + [_resourceTypeClasses setObject:class forKey:[NSString stringWithCString:(char *)type]]; +} + ++ (Class)_classForType:(ITMacResourceType)type { + Class _class = [_resourceTypeClasses objectForKey:[NSString stringWithCString:(char *)type]]; + return ((_class == nil) ? [ITMacResource class] : _class); +} + ++ (id)_resourceWithHandle:(Handle)handle { // THIS *WILL* RETURN A MORE SPECIFIC INSTANCE USING THE REGISTRATION DATABASE IF SUCH A CLASS EXISTS + return [[[self alloc] _initWithHandle:handle] autorelease]; +} + +- (id)_initWithHandle:(Handle)handle { + if (self = [super init]) { + _handle = handle; + } + return self; +} + +- (Handle)_handle { + return _handle; +} + +- (NSData *)data { + NSData *_data; + HLock(_handle); + _data = [NSData dataWithBytes:(*_handle) length:GetHandleSize(_handle)]; + HUnlock(_handle); + return _data; +} + +- (ITMacResourceType)type { + short _id; + ResType _type; + Str255 _name; + GetResInfo(_handle, &_id, &_type, _name); + return (ITMacResourceType)_type; +} + +- (NSNumber *)id { + short _id; + ResType _type; + Str255 _name; + GetResInfo(_handle, &_id, &_type, _name); + return [NSNumber numberWithShort:_id]; +} + +- (NSString *)name { + short _id; + ResType _type; + Str255 _name; + GetResInfo(_handle, &_id, &_type, _name); + return [(NSString*)CFStringCreateWithPascalString(NULL, +_name, kCFStringEncodingMacRomanLatin1) autorelease]; +} + +- (Class)nativeRepresentationClass { + return nil; +} + +- (id)nativeRepresentation { + return nil; +} + +- (void)dealloc { + ReleaseResource(_handle); + [super dealloc]; +} + +@end diff --git a/ITMacResourceFile.h b/ITMacResourceFile.h new file mode 100755 index 0000000..4cfa271 --- /dev/null +++ b/ITMacResourceFile.h @@ -0,0 +1,22 @@ +// +// ITMacResourceFile.h +// ITKit +// +// Created by Joseph Spiros on Thu Dec 25 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import +#import +#import "ITMacResource.h" + +@interface ITMacResourceFile : NSObject { + FSRef _fileReference; + SInt16 _referenceNumber; +} +- (id)initWithContentsOfFile:(NSString *)path; +- (id)initWithContentsOfFile:(NSString *)path fork:(HFSUniStr255)namedFork; + +- (ITMacResource *)resourceOfType:(ITMacResourceType)type withID:(NSNumber *)idNum; +- (ITMacResource *)resourceOfType:(ITMacResourceType)type withName:(NSString *)name; +@end diff --git a/ITMacResourceFile.m b/ITMacResourceFile.m new file mode 100755 index 0000000..6f39d53 --- /dev/null +++ b/ITMacResourceFile.m @@ -0,0 +1,53 @@ +// +// ITMacResourceFile.m +// ITKit +// +// Created by Joseph Spiros on Thu Dec 25 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import "ITMacResourceFile.h" + + +@implementation ITMacResourceFile + +- (id)initWithContentsOfFile:(NSString *)path { + HFSUniStr255 dataForkName; + FSGetDataForkName(&dataForkName); + return [self initWithContentsOfFile:path fork:dataForkName]; +} + +- (id)initWithContentsOfFile:(NSString *)path fork:(HFSUniStr255)namedFork { + if (self = [super init]) { + if (FSPathMakeRef([path fileSystemRepresentation],&_fileReference,NULL) == noErr) { + FSOpenResourceFile(&_fileReference, namedFork.length, namedFork.unicode, fsRdPerm, &_referenceNumber); + } else { + // Raise Exception! + } + } + return self; +} + +- (ITMacResource *)resourceOfType:(ITMacResourceType)type withID:(NSNumber *)idNum { + return [[ITMacResource _classForType:type] _resourceWithHandle:GetResource((ResType)type,[idNum shortValue])]; +} + +- (ITMacResource *)resourceOfType:(ITMacResourceType)type withName:(NSString *)name { + Str255 _buffer; + StringPtr _ptr = CFStringGetPascalStringPtr((CFStringRef)name, kCFStringEncodingMacRomanLatin1); + if (_ptr == NULL) { + if (CFStringGetPascalString((CFStringRef)name, _buffer, 256, kCFStringEncodingMacRomanLatin1)) { + _ptr = _buffer; + } else { + // Raise exception! + } + } + return [[ITMacResource _classForType:type] _resourceWithHandle:GetNamedResource((ResType)type,_ptr)]; +} + +- (void)dealloc { + CloseResFile(_referenceNumber); + [super dealloc]; +} + +@end diff --git a/ITPivotWindowEffect.m b/ITPivotWindowEffect.m index 373c5f3..400d931 100755 --- a/ITPivotWindowEffect.m +++ b/ITPivotWindowEffect.m @@ -222,8 +222,8 @@ float degAngle; NSRect windowFrame = [_window frame]; NSRect screenFrame = [[_window screen] frame]; - float translateX; - float translateY; + float translateX = 0; + float translateY = 0; CGAffineTransform transform; if ( vPos == ITWindowPositionBottom ) { diff --git a/ITStringMacResource.h b/ITStringMacResource.h new file mode 100755 index 0000000..096d941 --- /dev/null +++ b/ITStringMacResource.h @@ -0,0 +1,16 @@ +// +// ITStringMacResource.h +// ITKit +// +// Created by Joseph Spiros on Thu Dec 25 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import +#import "ITMacResource.h" + +@interface ITStringMacResource : ITMacResource { + +} + +@end diff --git a/ITStringMacResource.m b/ITStringMacResource.m new file mode 100755 index 0000000..3cc887b --- /dev/null +++ b/ITStringMacResource.m @@ -0,0 +1,26 @@ +// +// ITStringMacResource.m +// ITKit +// +// Created by Joseph Spiros on Thu Dec 25 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import "ITStringMacResource.h" + + +@implementation ITStringMacResource + ++ (void)load { + [ITMacResource _registerClass:self forType:'STR ']; +} + +- (Class)nativeRepresentationClass { + return [NSString class]; +} + +- (id)nativeRepresentation { + return @"Not Implemented Yet"; +} + +@end -- 2.20.1 From 5e2815af6cd3f5dffaca2e8d1876c0a355209859 Mon Sep 17 00:00:00 2001 From: Kent Sutherland Date: Thu, 22 Jan 2004 23:06:10 +0000 Subject: [PATCH 06/16] Added sizing to the main status window class, and added a basic icon and text status window. --- ITIconAndTextStatusWindow.h | 25 ++++ ITIconAndTextStatusWindow.m | 223 ++++++++++++++++++++++++++++++++++++ ITKit.h | 2 + ITKit.xcode/project.pbxproj | 45 ++++++++ ITTransientStatusWindow.h | 9 ++ ITTransientStatusWindow.m | 10 ++ Showcase/Controller.h | 18 +-- Showcase/Controller.m | 81 +------------ 8 files changed, 329 insertions(+), 84 deletions(-) create mode 100755 ITIconAndTextStatusWindow.h create mode 100755 ITIconAndTextStatusWindow.m diff --git a/ITIconAndTextStatusWindow.h b/ITIconAndTextStatusWindow.h new file mode 100755 index 0000000..9955f04 --- /dev/null +++ b/ITIconAndTextStatusWindow.h @@ -0,0 +1,25 @@ +/* + * ITKit + * ITIconAndTextStatusWindow + * ITTransientStatusWindow subclass to show an icon and text. + * + * Original Author : Kent Sutherland + * Responsibility : Kent Sutherland + * Responsibility : Joseph Spiros + * + * Copyright (c) 2002 - 2004 iThink Software. + * All Rights Reserved + * + */ + +#import +#import "ITTransientStatusWindow.h" + +@interface ITIconAndTextStatusWindow : ITTransientStatusWindow { + NSImage *_image; +} + +- (void)setImage:(NSImage *)newImage; +- (void)buildTextWindowWithString:(NSString *)text; + +@end diff --git a/ITIconAndTextStatusWindow.m b/ITIconAndTextStatusWindow.m new file mode 100755 index 0000000..afe0066 --- /dev/null +++ b/ITIconAndTextStatusWindow.m @@ -0,0 +1,223 @@ +/* + * ITKit + * ITIconAndTextStatusWindow + * ITTransientStatusWindow subclass to show an icon and text. + * + * Original Author : Kent Sutherland + * Responsibility : Kent Sutherland + * Responsibility : Joseph Spiros + * + * Copyright (c) 2002 - 2004 iThink Software. + * All Rights Reserved + * + */ + +#import "ITIconAndTextStatusWindow.h" +#import "ITWindowPositioning.h" +#import "ITWindowEffect.h" +#import "ITImageView.h" +#import "ITTextField.h" + +#define SW_PAD 24.00 +#define SW_SPACE 24.00 +#define SW_MINW 211.00 +#define SW_BORDER 32.00 +#define SW_METER_PAD 4.00 +#define SW_BUTTON_PAD_R 30.00 +#define SW_BUTTON_PAD_B 24.00 +#define SW_BUTTON_DIV 12.00 +#define SW_BUTTON_EXTRA_W 8.00 +#define SW_SHADOW_SAT 1.25 +#define SMALL_DIVISOR 1.33333 +#define MINI_DIVISOR 1.66667 + +@implementation ITIconAndTextStatusWindow + +/*************************************************************************/ +#pragma mark - +#pragma mark INITIALIZATION / DEALLOCATION METHODS +/*************************************************************************/ + +- (id)initWithContentView:(NSView *)contentView + exitMode:(ITTransientStatusWindowExitMode)exitMode + backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType +{ + if ( ( self = [super initWithContentView:contentView exitMode:exitMode backgroundType:backgroundType] ) ) { + //Defaults + _image = [[NSImage imageNamed:@"NSApplicationIcon"] retain]; + [self setSizing:ITTransientStatusWindowRegular]; + } + return self; +} + +- (void)dealloc +{ + [_image release]; + [super dealloc]; +} + +- (void)setImage:(NSImage *)newImage +{ + [_image autorelease]; + _image = [newImage copy]; +} + +/*************************************************************************/ +#pragma mark - +#pragma mark INSTANCE METHODS +/*************************************************************************/ + +- (NSRect)setupWindowWithDataSize:(NSSize)dataSize +{ + float divisor = 1.0; + NSRect imageRect; + float imageWidth = 0.0; + float imageHeight = 0.0; + float dataWidth = dataSize.width; + float dataHeight = dataSize.height; + float contentHeight = 0.0; + float windowWidth = 0.0; + float windowHeight = 0.0; + NSRect visibleFrame = [[self screen] visibleFrame]; + NSPoint screenOrigin = visibleFrame.origin; + float screenWidth = visibleFrame.size.width; + float screenHeight = visibleFrame.size.height; + float maxWidth = ( screenWidth - (SW_BORDER * 2) ); + float maxHeight = ( screenHeight - (SW_BORDER * 2) ); + float excessWidth = 0.0; + float excessHeight = 0.0; + NSPoint windowOrigin; + ITImageView *imageView; + BOOL shouldAnimate = ( ! (([self visibilityState] == ITWindowAppearingState) || + ([self visibilityState] == ITWindowVanishingState)) ); + + if ( [self sizing] == ITTransientStatusWindowSmall ) { + divisor = SMALL_DIVISOR; + } else if ( [self sizing] == ITTransientStatusWindowMini ) { + divisor = MINI_DIVISOR; + } + +// Get image width and height. + imageWidth = ( [_image size].width / divisor ); + imageHeight = ( [_image size].height / divisor ); + +// Set the content height to the greater of the text and image heights. + contentHeight = ( ( imageHeight > dataHeight ) ? imageHeight : dataHeight ); + +// Setup the Window, and remove all its contentview's subviews. + windowWidth = ( (SW_PAD / divisor) + imageWidth + (SW_SPACE / divisor) + dataWidth + (SW_PAD / divisor) ); + windowHeight = ( (SW_PAD / divisor) + contentHeight + (SW_PAD / divisor) ); + +// Constrain size to max limits. Adjust data sizes accordingly. + excessWidth = (windowWidth - maxWidth ); + excessHeight = (windowHeight - maxHeight); + + if ( excessWidth > 0.0 ) { + windowWidth = maxWidth; + dataWidth -= excessWidth; + } + + if ( excessHeight > 0.0 ) { + windowHeight = maxHeight; + dataHeight -= excessHeight; + } + + if ( [self horizontalPosition] == ITWindowPositionLeft ) { + windowOrigin.x = ( SW_BORDER + screenOrigin.x ); + } else if ( [self horizontalPosition] == ITWindowPositionCenter ) { + windowOrigin.x = ( screenOrigin.x + (screenWidth / 2) - (windowWidth / 2) ); + } else if ( [self horizontalPosition] == ITWindowPositionRight ) { + windowOrigin.x = ( screenOrigin.x + screenWidth - (windowWidth + SW_BORDER) ); + } + + if ( [self verticalPosition] == ITWindowPositionTop ) { + windowOrigin.y = ( screenOrigin.y + screenHeight - (windowHeight + SW_BORDER) ); + } else if ( [self verticalPosition] == ITWindowPositionMiddle ) { +// Middle-oriented windows should be slightly proud of the screen's middle. + windowOrigin.y = ( (screenOrigin.y + (screenHeight / 2) - (windowHeight / 2)) + (screenHeight / 8) ); + } else if ( [self verticalPosition] == ITWindowPositionBottom ) { + windowOrigin.y = ( SW_BORDER + screenOrigin.y ); + } + + [self setFrame:NSMakeRect( windowOrigin.x, + windowOrigin.y, + windowWidth, + windowHeight) display:YES animate:shouldAnimate]; + + [[[self contentView] subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + +// Setup, position, fill, and add the image view to the content view. + imageRect = NSMakeRect( (SW_PAD / divisor), + ((SW_PAD / divisor) + ((contentHeight - imageHeight) / 2)), + imageWidth, + imageHeight ); + imageView = [[[ITImageView alloc] initWithFrame:imageRect] autorelease]; + [imageView setAutoresizingMask:(NSViewMinYMargin | NSViewMaxYMargin)]; + [imageView setImage:_image]; + [imageView setCastsShadow:YES]; + [[self contentView] addSubview:imageView]; + + return NSMakeRect( ((SW_PAD / divisor) + imageWidth + (SW_SPACE / divisor)), + ((SW_PAD / divisor) + ((contentHeight - dataHeight) / 2)), + dataWidth, + dataHeight); +} + +- (void)buildTextWindowWithString:(NSString *)text +{ + float divisor = 1.0; + float dataWidth = 0.0; + float dataHeight = 0.0; + NSRect dataRect; + NSArray *lines = [text componentsSeparatedByString:@"\n"]; + id oneLine = nil; + NSEnumerator *lineEnum = [lines objectEnumerator]; + float baseFontSize = 18.0; + ITTextField *textField; + NSFont *font; + NSDictionary *attr; + + if ( [self sizing] == ITTransientStatusWindowSmall ) { + divisor = SMALL_DIVISOR; + } else if ( [self sizing] == ITTransientStatusWindowMini ) { + divisor = MINI_DIVISOR; + } + + font = [NSFont fontWithName:@"Lucida Grande Bold" size:(baseFontSize / divisor)]; + attr = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; + +// Iterate over each line to get text width and height + while ( (oneLine = [lineEnum nextObject]) ) { +// Get the width of one line, adding 8.0 because Apple sucks donkey rectum. + float oneLineWidth = ( [oneLine sizeWithAttributes:attr].width + 8.0 ); +// Add the height of this line to the total text height + dataHeight += [oneLine sizeWithAttributes:attr].height; +// If this line wider than the last one, set it as the text width. + dataWidth = ( ( dataWidth > oneLineWidth ) ? dataWidth : oneLineWidth ); + } + +// Add 4.0 to the final dataHeight to accomodate the shadow. + dataHeight += 4.0; + + dataRect = [self setupWindowWithDataSize:NSMakeSize(dataWidth, dataHeight)]; + +// Create, position, setup, fill, and add the text view to the content view. + textField = [[[ITTextField alloc] initWithFrame:dataRect] autorelease]; + [textField setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)]; + [textField setEditable:NO]; + [textField setSelectable:NO]; + [textField setBordered:NO]; + [textField setDrawsBackground:NO]; + [textField setFont:font]; + [textField setTextColor:[NSColor whiteColor]]; + [textField setCastsShadow:YES]; + [[textField cell] setWraps:NO]; + [textField setStringValue:text]; + [textField setShadowSaturation:SW_SHADOW_SAT]; + [[self contentView] addSubview:textField]; + +// Display the window. + [[self contentView] setNeedsDisplay:YES]; +} + +@end diff --git a/ITKit.h b/ITKit.h index 50dacfb..8e03709 100755 --- a/ITKit.h +++ b/ITKit.h @@ -28,5 +28,7 @@ #import #import +#import + #import #import diff --git a/ITKit.xcode/project.pbxproj b/ITKit.xcode/project.pbxproj index d77009f..ed67085 100755 --- a/ITKit.xcode/project.pbxproj +++ b/ITKit.xcode/project.pbxproj @@ -527,6 +527,47 @@ //322 //323 //324 +//370 +//371 +//372 +//373 +//374 + 3710911905C07F6D00ED0F36 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITIconAndTextStatusWindow.h; + refType = 4; + sourceTree = ""; + }; + 3710911A05C07F6D00ED0F36 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITIconAndTextStatusWindow.m; + refType = 4; + sourceTree = ""; + }; + 3710912305C0821000ED0F36 = { + fileRef = 3710911A05C07F6D00ED0F36; + isa = PBXBuildFile; + settings = { + }; + }; + 3710912805C0825900ED0F36 = { + fileRef = 3710911905C07F6D00ED0F36; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; +//370 +//371 +//372 +//373 +//374 //7C0 //7C1 //7C2 @@ -1764,6 +1805,8 @@ children = ( 7C992DF9054F5179000B93EA, 7C992DFA054F5179000B93EA, + 3710911905C07F6D00ED0F36, + 3710911A05C07F6D00ED0F36, 7C992DD8054F5179000B93EA, 7C992DD9054F5179000B93EA, 7C992DFD054F5179000B93EA, @@ -2140,6 +2183,7 @@ 7C992E32054F5179000B93EA, 2AC83141056D00F700A7D7E2, 2AC8319D056D037700A7D7E2, + 3710912805C0825900ED0F36, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -2198,6 +2242,7 @@ 7C992E31054F5179000B93EA, 2AC83142056D00F700A7D7E2, 2AC8319E056D037700A7D7E2, + 3710912305C0821000ED0F36, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; diff --git a/ITTransientStatusWindow.h b/ITTransientStatusWindow.h index 26fd426..04f13ab 100755 --- a/ITTransientStatusWindow.h +++ b/ITTransientStatusWindow.h @@ -42,6 +42,11 @@ typedef enum { ITTransientStatusWindowAquaUtility } ITTransientStatusWindowBackgroundType; +typedef enum { + ITTransientStatusWindowRegular, + ITTransientStatusWindowSmall, + ITTransientStatusWindowMini +} ITTransientStatusWindowSizing; @interface ITTransientStatusWindow : NSWindow { @@ -54,6 +59,7 @@ typedef enum { double _effectProgress; ITVerticalWindowPosition _verticalPosition; ITHorizontalWindowPosition _horizontalPosition; + ITTransientStatusWindowSizing _sizing; float _screenPadding; // int _screenNumber; @@ -73,6 +79,9 @@ typedef enum { - (void)appear:(id)sender; - (void)vanish:(id)sender; +- (void)setSizing:(ITTransientStatusWindowSizing)newSizing; +- (ITTransientStatusWindowSizing)sizing; + - (ITWindowVisibilityState)visibilityState; - (void)setVisibilityState:(ITWindowVisibilityState)newState; diff --git a/ITTransientStatusWindow.m b/ITTransientStatusWindow.m index 4f03f53..3f01c35 100755 --- a/ITTransientStatusWindow.m +++ b/ITTransientStatusWindow.m @@ -183,6 +183,16 @@ static ITTransientStatusWindow *staticWindow = nil; } } +- (void)setSizing:(ITTransientStatusWindowSizing)newSizing +{ + _sizing = newSizing; +} + +- (ITTransientStatusWindowSizing)sizing +{ + return _sizing; +} + - (ITWindowVisibilityState)visibilityState { return _visibilityState; diff --git a/Showcase/Controller.h b/Showcase/Controller.h index dfb9836..18ea801 100755 --- a/Showcase/Controller.h +++ b/Showcase/Controller.h @@ -26,15 +26,15 @@ IBOutlet ITTextField *testTextField; // ITTransientStatusWindow Support - ITTransientStatusWindow *statusWindow; - IBOutlet NSTextView *swSampleTextView; - IBOutlet NSPopUpButton *swVanishModePopup; - IBOutlet NSPopUpButton *swBackgroundTypePopup; - IBOutlet NSPopUpButton *swDefinedPositionPopup; - IBOutlet NSTextField *swVanishDelay; - IBOutlet NSTextField *swShadowSaturation; - IBOutlet NSSlider *swEntrySpeedSlider; - IBOutlet NSSlider *swExitSpeedSlider; + ITIconAndTextStatusWindow *statusWindow; + IBOutlet NSTextView *swSampleTextView; + IBOutlet NSPopUpButton *swVanishModePopup; + IBOutlet NSPopUpButton *swBackgroundTypePopup; + IBOutlet NSPopUpButton *swDefinedPositionPopup; + IBOutlet NSTextField *swVanishDelay; + IBOutlet NSTextField *swShadowSaturation; + IBOutlet NSSlider *swEntrySpeedSlider; + IBOutlet NSSlider *swExitSpeedSlider; } // ITStatusItem Support diff --git a/Showcase/Controller.m b/Showcase/Controller.m index 8455cb2..49e9e35 100755 --- a/Showcase/Controller.m +++ b/Showcase/Controller.m @@ -1,5 +1,6 @@ #import "Controller.h" -#import "ITTransientStatusWindow.h" +//#import "ITTransientStatusWindow.h" +#import "ITIconAndTextStatusWindow.h" #import "ITTSWBackgroundView.h" #import "ITTextField.h" #import "ITBevelView.h" @@ -36,7 +37,7 @@ [testTextField setCastsShadow:YES]; [tabView setAllowsDragging:YES]; [bevelView setBevelDepth:10]; - statusWindow = [ITTransientStatusWindow sharedWindow]; + statusWindow = [ITIconAndTextStatusWindow sharedWindow]; [statusWindow setEntryEffect:[[ITCutWindowEffect alloc] initWithWindow:statusWindow]]; [statusWindow setExitEffect:[[ITDissolveWindowEffect alloc] initWithWindow:statusWindow]]; [[statusWindow entryEffect] setEffectTime:[swEntrySpeedSlider floatValue]]; @@ -148,80 +149,10 @@ - (IBAction)buildStatusWindow:(id)sender { - NSImageView *imageView = nil; - ITTextField *textField = nil; NSImage *image = [NSImage imageNamed:SW_IMAGE]; - NSRect imageRect; - NSRect textRect; - - float imageWidth = 0.0; - float imageHeight = 0.0; - float textWidth = 0.0; - float textHeight = 0.0; - float contentHeight = 0.0; - float windowWidth = 0.0; - float windowHeight = 0.0; - - NSString *text = [swSampleTextView string]; - NSArray *lines = [text componentsSeparatedByString:@"\n"]; - id oneLine = nil; - NSEnumerator *lineEnum = [lines objectEnumerator]; - - NSFont *font = [NSFont fontWithName:@"Lucida Grande Bold" size:18]; - NSDictionary *attr = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; - - // Get image width and height. - imageWidth = [image size].width; - imageHeight = [image size].height; - - // Iterate over each line to get text width and height - while ( oneLine = [lineEnum nextObject] ) { - // Get the width of one line, adding 8.0 because Apple sucks donkey rectum. - float oneLineWidth = ( [oneLine sizeWithAttributes:attr].width + 8.0 ); - // Add the height of this line to the total text height - textHeight += [oneLine sizeWithAttributes:attr].height; - // If this line wider than the last one, set it as the text width. - textWidth = ( ( textWidth > oneLineWidth ) ? textWidth : oneLineWidth ); - } - - // Add 4.0 to the final textHeight to accomodate the shadow. - textHeight += 4.0; - NSLog(@"%f", textHeight); - // Set the content height to the greater of the text and image heights. - contentHeight = ( ( imageHeight > textHeight ) ? imageHeight : textHeight ); - - // Setup the Window, and remove all its contentview's subviews. - windowWidth = ( SW_PAD + imageWidth + SW_SPACE + textWidth + SW_PAD ); - windowHeight = ( SW_PAD + contentHeight + SW_PAD ); - [statusWindow setFrame:NSMakeRect(SW_BORDER, SW_BORDER, windowWidth, windowHeight) display:YES animate:YES]; - [[[statusWindow contentView] subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; - - // Setup, position, fill, and add the image view to the content view. - imageRect = NSMakeRect( SW_PAD, - (SW_PAD + ((contentHeight - imageHeight) / 2)), - imageWidth, - imageHeight ); - imageView = [[[NSImageView alloc] initWithFrame:imageRect] autorelease]; - [imageView setImage:image]; - [[statusWindow contentView] addSubview:imageView]; - - // Setup, position, fill, and add the text view to the content view. - textRect = NSMakeRect( (SW_PAD + imageWidth + SW_SPACE), - (SW_PAD + ((contentHeight - textHeight) / 2)), - textWidth, - textHeight); - textField = [[[ITTextField alloc] initWithFrame:textRect] autorelease]; - [textField setEditable:NO]; - [textField setSelectable:NO]; - [textField setBordered:NO]; - [textField setDrawsBackground:NO]; - [textField setFont:[NSFont fontWithName:@"Lucida Grande Bold" size:18]]; - [textField setTextColor:[NSColor whiteColor]]; - [textField setCastsShadow:YES]; - [textField setStringValue:text]; - [[statusWindow contentView] addSubview:textField]; - - [[statusWindow contentView] setNeedsDisplay:YES]; + NSString *text = [swSampleTextView string]; + [statusWindow setImage:image]; + [statusWindow buildTextWindowWithString:text]; } - (IBAction)toggleStatusWindow:(id)sender -- 2.20.1 From ceb1dcca2b608f56e53188b5bb623755c4eeddbb Mon Sep 17 00:00:00 2001 From: Kent Sutherland Date: Fri, 30 Jan 2004 21:34:11 +0000 Subject: [PATCH 07/16] Changed the NSMenu category from NSMenuItem * to id --- ITCategory-NSMenu.h | 4 ++-- ITCategory-NSMenu.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ITCategory-NSMenu.h b/ITCategory-NSMenu.h index 6ccfb6e..6a41379 100755 --- a/ITCategory-NSMenu.h +++ b/ITCategory-NSMenu.h @@ -18,9 +18,9 @@ @interface NSMenu (ITCategory) -- (void)indentItem:(NSMenuItem *)item; +- (void)indentItem:(id )item; - (void)indentItemAtIndex:(int)index; -- (void)indentItem:(NSMenuItem *)item toLevel:(int)indentLevel; +- (void)indentItem:(id )item toLevel:(int)indentLevel; - (void)indentItemAtIndex:(int)index toLevel:(int)indentLevel; - (MenuRef)menuRef; diff --git a/ITCategory-NSMenu.m b/ITCategory-NSMenu.m index ec59bb1..78470cc 100755 --- a/ITCategory-NSMenu.m +++ b/ITCategory-NSMenu.m @@ -17,7 +17,7 @@ extern MenuRef _NSGetCarbonMenu( NSMenu *menu); @implementation NSMenu (ITCategory) -- (void)indentItem:(NSMenuItem *)item { +- (void)indentItem:(id )item { [self indentItem:item toLevel:1]; } @@ -25,7 +25,7 @@ extern MenuRef _NSGetCarbonMenu( NSMenu *menu); [self indentItemAtIndex:index toLevel:1]; } -- (void)indentItem:(NSMenuItem *)item toLevel:(int)indentLevel { +- (void)indentItem:(id )item toLevel:(int)indentLevel { [self indentItemAtIndex:[self indexOfItem:item] toLevel:indentLevel]; } -- 2.20.1 From e3ecd39c1d3a4803b8d4c051846ad6ad7b059d6f Mon Sep 17 00:00:00 2001 From: Alexander Strange Date: Wed, 11 Feb 2004 03:49:36 +0000 Subject: [PATCH 08/16] Another cleanup that doesn't seem to actually help --- ITImageCell.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ITImageCell.m b/ITImageCell.m index d8f38b9..055435a 100755 --- a/ITImageCell.m +++ b/ITImageCell.m @@ -47,7 +47,9 @@ } if ( _scalesSmoothly ) { - CGContextSetInterpolationQuality([[NSGraphicsContext currentContext] graphicsPort], kCGInterpolationHigh); + // CGContextSetInterpolationQuality([[NSGraphicsContext currentContext] graphicsPort], kCGInterpolationHigh); + [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]; + [[NSGraphicsContext currentContext] setShouldAntialias:YES]; } if ( castsShadow ) { -- 2.20.1 From f5ba1b3d36420e85c5708cea5a3ab1d816f614e9 Mon Sep 17 00:00:00 2001 From: Alexander Strange Date: Sat, 14 Feb 2004 05:25:03 +0000 Subject: [PATCH 09/16] Disable non-English --- ITKit.xcode/project.pbxproj | 54 ------------------------------------- 1 file changed, 54 deletions(-) diff --git a/ITKit.xcode/project.pbxproj b/ITKit.xcode/project.pbxproj index ed67085..422bfdf 100755 --- a/ITKit.xcode/project.pbxproj +++ b/ITKit.xcode/project.pbxproj @@ -299,9 +299,6 @@ 2A30D8A1056B3BE30087AE54 = { children = ( 2A30D8A2056B3BE30087AE54, - 2A30D8A6056B3BEE0087AE54, - 2A30D8A9056B3BF60087AE54, - 2A30D8B5056B3C1B0087AE54, ); isa = PBXVariantGroup; name = ITKeyComboPanel.nib; @@ -323,36 +320,9 @@ settings = { }; }; - 2A30D8A6056B3BEE0087AE54 = { - isa = PBXFileReference; - lastKnownFileType = wrapper.nib; - name = French; - path = French.lproj/ITKeyComboPanel.nib; - refType = 4; - sourceTree = ""; - }; - 2A30D8A9056B3BF60087AE54 = { - isa = PBXFileReference; - lastKnownFileType = wrapper.nib; - name = German; - path = German.lproj/ITKeyComboPanel.nib; - refType = 4; - sourceTree = ""; - }; - 2A30D8B5056B3C1B0087AE54 = { - isa = PBXFileReference; - lastKnownFileType = wrapper.nib; - name = Japanese; - path = Japanese.lproj/ITKeyComboPanel.nib; - refType = 4; - sourceTree = ""; - }; 2A30D8BC056B3C5D0087AE54 = { children = ( 2A30D8BD056B3C5D0087AE54, - 2A30D8C1056B3C670087AE54, - 2A30D8C4056B3C750087AE54, - 2A30D8C7056B3C830087AE54, ); isa = PBXVariantGroup; name = Localizable.strings; @@ -375,30 +345,6 @@ settings = { }; }; - 2A30D8C1056B3C670087AE54 = { - isa = PBXFileReference; - lastKnownFileType = text.plist.strings; - name = French; - path = French.lproj/Localizable.strings; - refType = 4; - sourceTree = ""; - }; - 2A30D8C4056B3C750087AE54 = { - isa = PBXFileReference; - lastKnownFileType = text.plist.strings; - name = German; - path = German.lproj/Localizable.strings; - refType = 4; - sourceTree = ""; - }; - 2A30D8C7056B3C830087AE54 = { - isa = PBXFileReference; - lastKnownFileType = text.plist.strings; - name = Japanese; - path = Japanese.lproj/Localizable.strings; - refType = 4; - sourceTree = ""; - }; 2AAF7B22056C3536009B9225 = { children = ( 7C992DC9054F5179000B93EA, -- 2.20.1 From c6baa45585d2caea0a6d824a63e308e47f2f52de Mon Sep 17 00:00:00 2001 From: Joseph Spiros Date: Sat, 6 Mar 2004 07:03:45 +0000 Subject: [PATCH 10/16] Adding the ITMultilineTextFieldCell work I've done so far... --- ITKit.xcode/project.pbxproj | 32 ++++++ ITMultilineTextFieldCell.h | 15 +++ ITMultilineTextFieldCell.m | 108 ++++++++++++++++++ Showcase/Controller.h | 3 + Showcase/Controller.m | 28 +++++ .../English.lproj/MainMenu.nib/classes.nib | 1 + Showcase/English.lproj/MainMenu.nib/info.nib | 5 +- .../MainMenu.nib/keyedobjects.nib | Bin 41143 -> 43473 bytes 8 files changed, 190 insertions(+), 2 deletions(-) create mode 100755 ITMultilineTextFieldCell.h create mode 100755 ITMultilineTextFieldCell.m diff --git a/ITKit.xcode/project.pbxproj b/ITKit.xcode/project.pbxproj index 422bfdf..7beefb5 100755 --- a/ITKit.xcode/project.pbxproj +++ b/ITKit.xcode/project.pbxproj @@ -599,6 +599,34 @@ refType = 4; sourceTree = ""; }; + 7C4BBADA05F98C9900734027 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITMultilineTextFieldCell.h; + refType = 4; + sourceTree = ""; + }; + 7C4BBADB05F98C9900734027 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITMultilineTextFieldCell.m; + refType = 4; + sourceTree = ""; + }; + 7C4BBADC05F98C9900734027 = { + fileRef = 7C4BBADA05F98C9900734027; + isa = PBXBuildFile; + settings = { + }; + }; + 7C4BBADD05F98C9900734027 = { + fileRef = 7C4BBADB05F98C9900734027; + isa = PBXBuildFile; + settings = { + }; + }; 7C5B7C93054F6EC9008379B6 = { fileRef = 8DC2EF5B0486A6940098B216; isa = PBXBuildFile; @@ -1594,6 +1622,8 @@ 7C992DF8054F5179000B93EA, 2AC8319B056D037700A7D7E2, 2AC8319C056D037700A7D7E2, + 7C4BBADA05F98C9900734027, + 7C4BBADB05F98C9900734027, ); isa = PBXGroup; name = Cells; @@ -2130,6 +2160,7 @@ 2AC83141056D00F700A7D7E2, 2AC8319D056D037700A7D7E2, 3710912805C0825900ED0F36, + 7C4BBADC05F98C9900734027, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -2189,6 +2220,7 @@ 2AC83142056D00F700A7D7E2, 2AC8319E056D037700A7D7E2, 3710912305C0821000ED0F36, + 7C4BBADD05F98C9900734027, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; diff --git a/ITMultilineTextFieldCell.h b/ITMultilineTextFieldCell.h new file mode 100755 index 0000000..59ca9c0 --- /dev/null +++ b/ITMultilineTextFieldCell.h @@ -0,0 +1,15 @@ +// +// ITMultilineTextFieldCell.h +// ITKit +// +// Created by Joseph Spiros on Fri Mar 05 2004. +// Copyright (c) 2004 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface ITMultilineTextFieldCell : NSCell { +} + +@end diff --git a/ITMultilineTextFieldCell.m b/ITMultilineTextFieldCell.m new file mode 100755 index 0000000..74b4749 --- /dev/null +++ b/ITMultilineTextFieldCell.m @@ -0,0 +1,108 @@ +// +// ITMultilineTextFieldCell.m +// ITKit +// +// Created by Joseph Spiros on Fri Mar 05 2004. +// Copyright (c) 2004 __MyCompanyName__. All rights reserved. +// + +#import "ITMultilineTextFieldCell.h" + + +@implementation ITMultilineTextFieldCell + +- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView +{ + /* + Okay, here's the different possibilities for the objectValue of this cell, and how they're displayed: + + NSArray of NSStrings - Draw first line with System Font, following lines with Small System Font + NSArray of NSAttributedStrings - Draw as given + NSArray of both - Draw each line as above! + + The number of lines is determined by the contents of the array... + */ + + NSColor *defaultColor; + NSMutableParagraphStyle *paragraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; + [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; + NSPoint cellPoint = cellFrame.origin; + NSSize cellSize = cellFrame.size; + + NSRect secondaryLineRect; + + if ([self isHighlighted] && ([self highlightColorWithFrame:cellFrame inView:controlView]!=[NSColor secondarySelectedControlColor])) { + defaultColor = [NSColor whiteColor]; + } else { + defaultColor = [NSColor blackColor]; + } + + // Process the first line... + { + NSDictionary *firstLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; + + NSRect firstLineRect = NSMakeRect(cellPoint.x+5, cellPoint.y+1, cellSize.width-5, cellSize.height); + + id firstString = [[self objectValue] objectAtIndex:0]; + NSMutableAttributedString *firstAttrString; + + if ([firstString isKindOfClass:[NSAttributedString class]]) { + firstAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:firstString] autorelease]; + [firstAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[firstAttrString length])]; + if ([defaultColor isEqual:[NSColor whiteColor]]) { + [firstAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[firstAttrString length])]; + } + } else if ([firstString isKindOfClass:[NSString class]]) { + firstAttrString = [[[NSMutableAttributedString alloc] initWithString:firstString attributes:firstLineAttributes] autorelease]; + } else { + firstAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", firstString] attributes:firstLineAttributes] autorelease]; + } + + [controlView lockFocus]; + + [firstAttrString drawInRect:firstLineRect]; + + [controlView unlockFocus]; + + secondaryLineRect = NSMakeRect(cellPoint.x+5, (cellPoint.y+1+[firstAttrString size].height), cellSize.width-5, cellSize.height); + } + + // Process the secondary lines + { + NSDictionary *secondaryLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; + + NSMutableArray *tMArray = [NSMutableArray arrayWithArray:[self objectValue]]; + [tMArray removeObjectAtIndex:0]; // Remove the first line string... already handled that above! + + NSEnumerator *enumerator = [tMArray objectEnumerator]; + id secondaryString; + + while (secondaryString = [enumerator nextObject]) { + + NSMutableAttributedString *secondaryAttrString; + + if ([secondaryString isKindOfClass:[NSAttributedString class]]) { + secondaryAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:secondaryString] autorelease]; + [secondaryAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[secondaryAttrString length])]; + if ([defaultColor isEqual:[NSColor whiteColor]]) { + [secondaryAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[secondaryAttrString length])]; + } + } else if ([secondaryString isKindOfClass:[NSString class]]) { + secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:secondaryString attributes:secondaryLineAttributes] autorelease]; + } else { + secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", secondaryString] attributes:secondaryLineAttributes] autorelease]; + } + + [controlView lockFocus]; + + [secondaryAttrString drawInRect:secondaryLineRect]; + + [controlView unlockFocus]; + + secondaryLineRect.origin.y = secondaryLineRect.origin.y+[secondaryAttrString size].height; // modify the rect for the next loop, based on the size and location of the most recently processed line. + + } + } +} + +@end diff --git a/Showcase/Controller.h b/Showcase/Controller.h index 18ea801..399b3c9 100755 --- a/Showcase/Controller.h +++ b/Showcase/Controller.h @@ -35,6 +35,9 @@ IBOutlet NSTextField *swShadowSaturation; IBOutlet NSSlider *swEntrySpeedSlider; IBOutlet NSSlider *swExitSpeedSlider; + + // ITMultilineTextFieldCell Support + IBOutlet NSTableView *tableView; } // ITStatusItem Support diff --git a/Showcase/Controller.m b/Showcase/Controller.m index 49e9e35..ba9c278 100755 --- a/Showcase/Controller.m +++ b/Showcase/Controller.m @@ -9,6 +9,7 @@ #import "ITSlideHorizontallyWindowEffect.h" #import "ITSlideVerticallyWindowEffect.h" #import "ITPivotWindowEffect.h" +#import "ITMultilineTextFieldCell.h" #define SW_PAD 24.0 @@ -44,6 +45,10 @@ [[statusWindow exitEffect] setEffectTime:[swExitSpeedSlider floatValue]]; // [tabView setAllowsDragging:YES]; [[NSColorPanel sharedColorPanel] setShowsAlpha:YES]; + + [tableView setRowHeight:200]; + [[tableView tableColumnWithIdentifier:@"custom"] setDataCell:[[[ITMultilineTextFieldCell alloc] init] autorelease]]; + [[tableView tableColumnWithIdentifier:@"image"] setDataCell:[[[NSImageCell alloc] init] autorelease]]; } /*************************************************************************/ @@ -299,5 +304,28 @@ [[note object] setMiniwindowImage:[NSImage imageNamed:@"ITStatusItem"]]; } +/*************************************************************************/ +#pragma mark - +#pragma mark ITMultilineTextFieldCell SUPPORT +/*************************************************************************/ + +- (int)numberOfRowsInTableView:(NSTableView *)aTableView { + return 50; +} + +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { + if ([[aTableColumn dataCell] isKindOfClass:[ITMultilineTextFieldCell class]]) { + if (rowIndex%2) { + return [NSArray arrayWithObjects:@"Foo", @"Bar", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", @"- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex", nil]; + } else { + return [NSArray arrayWithObjects:[[[NSAttributedString alloc] initWithString:@"This is a demo of ITMultilineTextFieldCell" attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"Gill Sans" size:48], NSFontAttributeName, [NSColor purpleColor], NSForegroundColorAttributeName, nil]] autorelease], [[[NSAttributedString alloc] initWithString:@"Bar" attributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"Gadget" size:20], NSFontAttributeName, nil]] autorelease], [[[NSObject alloc] init] autorelease], nil]; + } + } else if ([[aTableColumn dataCell] isKindOfClass:[NSImageCell class]]) { + return [NSImage imageNamed:@"NSApplicationIcon"]; + } else { + return @"I like cheese"; + } +} + @end diff --git a/Showcase/English.lproj/MainMenu.nib/classes.nib b/Showcase/English.lproj/MainMenu.nib/classes.nib index a9358a8..512782e 100755 --- a/Showcase/English.lproj/MainMenu.nib/classes.nib +++ b/Showcase/English.lproj/MainMenu.nib/classes.nib @@ -35,6 +35,7 @@ swVanishDelay = NSTextField; swVanishModePopup = NSPopUpButton; tabView = ITTabView; + tableView = NSTableView; testTextField = ITTextField; useInvertedCheckBox = NSButton; window = NSWindow; diff --git a/Showcase/English.lproj/MainMenu.nib/info.nib b/Showcase/English.lproj/MainMenu.nib/info.nib index 42842c4..03db0ad 100755 --- a/Showcase/English.lproj/MainMenu.nib/info.nib +++ b/Showcase/English.lproj/MainMenu.nib/info.nib @@ -7,7 +7,7 @@ IBEditorPositions 197 - 564 424 153 118 0 0 1056 770 + 624 471 153 118 0 0 1152 842 29 1 271 349 44 0 0 1056 770 @@ -15,9 +15,10 @@ 349.0 IBOpenObjects + 21 197 IBSystem Version - 7C107 + 7D24 diff --git a/Showcase/English.lproj/MainMenu.nib/keyedobjects.nib b/Showcase/English.lproj/MainMenu.nib/keyedobjects.nib index 240f29ae37ed468022816e27f8db99bcf864e91e..a0b1e188a65778fd727668ec9a156eb698c3a3f5 100755 GIT binary patch literal 43473 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

jxUDkF(B%W5; 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 bCig0ObIgPc^Ty--Uun7c|H}Wr?=Aly$=o+F -- 2.20.1 From ae43c1a7ec8eaa7844c69d2bf648b777704cc51c Mon Sep 17 00:00:00 2001 From: Joseph Spiros Date: Sun, 27 Jun 2004 02:30:20 +0000 Subject: [PATCH 11/16] Fixed a possible crasher where an ITMultilineTextFieldCell is treated as an NSTextFieldCell, in having an NSString set as it's objectValue. Previously, ITMultilineTextFieldCell assumed an NSArray as it's objectValue. --- ITMultilineTextFieldCell.m | 141 +++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 68 deletions(-) diff --git a/ITMultilineTextFieldCell.m b/ITMultilineTextFieldCell.m index 74b4749..b804768 100755 --- a/ITMultilineTextFieldCell.m +++ b/ITMultilineTextFieldCell.m @@ -13,95 +13,100 @@ - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { - /* - Okay, here's the different possibilities for the objectValue of this cell, and how they're displayed: - - NSArray of NSStrings - Draw first line with System Font, following lines with Small System Font - NSArray of NSAttributedStrings - Draw as given - NSArray of both - Draw each line as above! - - The number of lines is determined by the contents of the array... - */ - - NSColor *defaultColor; - NSMutableParagraphStyle *paragraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; - [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; - NSPoint cellPoint = cellFrame.origin; - NSSize cellSize = cellFrame.size; - - NSRect secondaryLineRect; + if ([[self objectValue] isKindOfClass:[NSArray class]]) { - if ([self isHighlighted] && ([self highlightColorWithFrame:cellFrame inView:controlView]!=[NSColor secondarySelectedControlColor])) { - defaultColor = [NSColor whiteColor]; - } else { - defaultColor = [NSColor blackColor]; - } + /* + Okay, here's the different possibilities for the objectValue of this cell, and how they're displayed: + + NSArray of NSStrings - Draw first line with System Font, following lines with Small System Font + NSArray of NSAttributedStrings - Draw as given + NSArray of both - Draw each line as above! + + The number of lines is determined by the contents of the array... + */ - // Process the first line... - { - NSDictionary *firstLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - - NSRect firstLineRect = NSMakeRect(cellPoint.x+5, cellPoint.y+1, cellSize.width-5, cellSize.height); + NSColor *defaultColor; + NSMutableParagraphStyle *paragraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease]; + [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; + NSPoint cellPoint = cellFrame.origin; + NSSize cellSize = cellFrame.size; - id firstString = [[self objectValue] objectAtIndex:0]; - NSMutableAttributedString *firstAttrString; + NSRect secondaryLineRect; - if ([firstString isKindOfClass:[NSAttributedString class]]) { - firstAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:firstString] autorelease]; - [firstAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[firstAttrString length])]; - if ([defaultColor isEqual:[NSColor whiteColor]]) { - [firstAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[firstAttrString length])]; - } - } else if ([firstString isKindOfClass:[NSString class]]) { - firstAttrString = [[[NSMutableAttributedString alloc] initWithString:firstString attributes:firstLineAttributes] autorelease]; + if ([self isHighlighted] && ([self highlightColorWithFrame:cellFrame inView:controlView]!=[NSColor secondarySelectedControlColor])) { + defaultColor = [NSColor whiteColor]; } else { - firstAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", firstString] attributes:firstLineAttributes] autorelease]; + defaultColor = [NSColor blackColor]; } - [controlView lockFocus]; - - [firstAttrString drawInRect:firstLineRect]; - - [controlView unlockFocus]; - - secondaryLineRect = NSMakeRect(cellPoint.x+5, (cellPoint.y+1+[firstAttrString size].height), cellSize.width-5, cellSize.height); - } - - // Process the secondary lines - { - NSDictionary *secondaryLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - - NSMutableArray *tMArray = [NSMutableArray arrayWithArray:[self objectValue]]; - [tMArray removeObjectAtIndex:0]; // Remove the first line string... already handled that above! - - NSEnumerator *enumerator = [tMArray objectEnumerator]; - id secondaryString; - - while (secondaryString = [enumerator nextObject]) { + // Process the first line... + { + NSDictionary *firstLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; - NSMutableAttributedString *secondaryAttrString; + NSRect firstLineRect = NSMakeRect(cellPoint.x+5, cellPoint.y+1, cellSize.width-5, cellSize.height); - if ([secondaryString isKindOfClass:[NSAttributedString class]]) { - secondaryAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:secondaryString] autorelease]; - [secondaryAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[secondaryAttrString length])]; + id firstString = [[self objectValue] objectAtIndex:0]; + NSMutableAttributedString *firstAttrString; + + if ([firstString isKindOfClass:[NSAttributedString class]]) { + firstAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:firstString] autorelease]; + [firstAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[firstAttrString length])]; if ([defaultColor isEqual:[NSColor whiteColor]]) { - [secondaryAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[secondaryAttrString length])]; + [firstAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[firstAttrString length])]; } - } else if ([secondaryString isKindOfClass:[NSString class]]) { - secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:secondaryString attributes:secondaryLineAttributes] autorelease]; + } else if ([firstString isKindOfClass:[NSString class]]) { + firstAttrString = [[[NSMutableAttributedString alloc] initWithString:firstString attributes:firstLineAttributes] autorelease]; } else { - secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", secondaryString] attributes:secondaryLineAttributes] autorelease]; + firstAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", firstString] attributes:firstLineAttributes] autorelease]; } [controlView lockFocus]; - [secondaryAttrString drawInRect:secondaryLineRect]; + [firstAttrString drawInRect:firstLineRect]; [controlView unlockFocus]; - secondaryLineRect.origin.y = secondaryLineRect.origin.y+[secondaryAttrString size].height; // modify the rect for the next loop, based on the size and location of the most recently processed line. + secondaryLineRect = NSMakeRect(cellPoint.x+5, (cellPoint.y+1+[firstAttrString size].height), cellSize.width-5, cellSize.height); + } + // Process the secondary lines + { + NSDictionary *secondaryLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil]; + + NSMutableArray *tMArray = [NSMutableArray arrayWithArray:[self objectValue]]; + [tMArray removeObjectAtIndex:0]; // Remove the first line string... already handled that above! + + NSEnumerator *enumerator = [tMArray objectEnumerator]; + id secondaryString; + + while (secondaryString = [enumerator nextObject]) { + + NSMutableAttributedString *secondaryAttrString; + + if ([secondaryString isKindOfClass:[NSAttributedString class]]) { + secondaryAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:secondaryString] autorelease]; + [secondaryAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[secondaryAttrString length])]; + if ([defaultColor isEqual:[NSColor whiteColor]]) { + [secondaryAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[secondaryAttrString length])]; + } + } else if ([secondaryString isKindOfClass:[NSString class]]) { + secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:secondaryString attributes:secondaryLineAttributes] autorelease]; + } else { + secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", secondaryString] attributes:secondaryLineAttributes] autorelease]; + } + + [controlView lockFocus]; + + [secondaryAttrString drawInRect:secondaryLineRect]; + + [controlView unlockFocus]; + + secondaryLineRect.origin.y = secondaryLineRect.origin.y+[secondaryAttrString size].height; // modify the rect for the next loop, based on the size and location of the most recently processed line. + + } } + } else { + [super drawInteriorWithFrame:cellFrame inView:controlView]; } } -- 2.20.1 From ee17fc263ed710648cfc5950a5bd603f8acacda2 Mon Sep 17 00:00:00 2001 From: Kent Sutherland Date: Tue, 29 Jun 2004 05:30:37 +0000 Subject: [PATCH 12/16] New zoom effect. --- ITKit.xcode/project.pbxproj | 32 +++ ITWindowEffect.m | 1 + ITZoomWindowEffect.h | 23 ++ ITZoomWindowEffect.m | 224 ++++++++++++++++++ Showcase/Controller.h | 3 + Showcase/Controller.m | 51 ++-- .../English.lproj/MainMenu.nib/classes.nib | 2 + Showcase/English.lproj/MainMenu.nib/info.nib | 6 +- .../MainMenu.nib/keyedobjects.nib | Bin 43473 -> 42743 bytes 9 files changed, 308 insertions(+), 34 deletions(-) create mode 100755 ITZoomWindowEffect.h create mode 100755 ITZoomWindowEffect.m diff --git a/ITKit.xcode/project.pbxproj b/ITKit.xcode/project.pbxproj index 7beefb5..e0c00c0 100755 --- a/ITKit.xcode/project.pbxproj +++ b/ITKit.xcode/project.pbxproj @@ -509,6 +509,34 @@ ); }; }; + 372C5812068FE72F00CEF54A = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITZoomWindowEffect.m; + refType = 4; + sourceTree = ""; + }; + 372C5813068FE72F00CEF54A = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITZoomWindowEffect.h; + refType = 4; + sourceTree = ""; + }; + 372C5814068FE72F00CEF54A = { + fileRef = 372C5812068FE72F00CEF54A; + isa = PBXBuildFile; + settings = { + }; + }; + 372C5815068FE72F00CEF54A = { + fileRef = 372C5813068FE72F00CEF54A; + isa = PBXBuildFile; + settings = { + }; + }; //370 //371 //372 @@ -1807,6 +1835,8 @@ 7C992DEA054F5179000B93EA, 7C992DE7054F5179000B93EA, 7C992DE8054F5179000B93EA, + 372C5813068FE72F00CEF54A, + 372C5812068FE72F00CEF54A, ); isa = PBXGroup; name = Effects; @@ -2161,6 +2191,7 @@ 2AC8319D056D037700A7D7E2, 3710912805C0825900ED0F36, 7C4BBADC05F98C9900734027, + 372C5815068FE72F00CEF54A, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -2221,6 +2252,7 @@ 2AC8319E056D037700A7D7E2, 3710912305C0821000ED0F36, 7C4BBADD05F98C9900734027, + 372C5814068FE72F00CEF54A, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; diff --git a/ITWindowEffect.m b/ITWindowEffect.m index 231dc76..576d6d1 100755 --- a/ITWindowEffect.m +++ b/ITWindowEffect.m @@ -12,6 +12,7 @@ NSClassFromString(@"ITSlideHorizontallyWindowEffect"), NSClassFromString(@"ITSlideVerticallyWindowEffect"), NSClassFromString(@"ITPivotWindowEffect"), + NSClassFromString(@"ITZoomWindowEffect"), nil]; return classes; diff --git a/ITZoomWindowEffect.h b/ITZoomWindowEffect.h new file mode 100755 index 0000000..9fc920e --- /dev/null +++ b/ITZoomWindowEffect.h @@ -0,0 +1,23 @@ +/* + * ITKit + * ITZoomWindowEffect + * Effect subclass which zooms (expands/shrinks) a window into position on the screen. + * + * Original Author : Kent Sutherland + * Responsibility : Kent Sutherland + * + * Copyright (c) 2002 - 2004 iThink Software. + * All Rights Reserved + * + */ + + +#import +#import "ITWindowEffect.h" + + +@interface ITZoomWindowEffect : ITWindowEffect { + +} + +@end diff --git a/ITZoomWindowEffect.m b/ITZoomWindowEffect.m new file mode 100755 index 0000000..e80735f --- /dev/null +++ b/ITZoomWindowEffect.m @@ -0,0 +1,224 @@ +#import "ITZoomWindowEffect.h" +#import "ITCoreGraphicsHacks.h" +#import "ITTransientStatusWindow.h" + + +@interface ITZoomWindowEffect (Private) +- (void)performAppearFromProgress:(float)progress effectTime:(float)time; +- (void)appearStep; +- (void)appearFinish; +- (void)performVanishFromProgress:(float)progress effectTime:(float)time; +- (void)vanishStep; +- (void)vanishFinish; +- (void)setZoom:(float)Zoom; +@end + + +@implementation ITZoomWindowEffect + + ++ (NSString *)effectName +{ + return @"Zoom"; +} + ++ (NSDictionary *)supportedPositions +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Top" , + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Middle" , + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Bottom" , nil]; +} + + ++ (unsigned int)listOrder +{ + return 600; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark APPEAR METHODS +/*************************************************************************/ + +- (void)performAppear +{ + __idle = NO; + + [self setWindowVisibility:ITWindowAppearingState]; + [self performAppearFromProgress:0.0 effectTime:_effectTime]; +} + +- (void)performAppearFromProgress:(float)progress effectTime:(float)time +{ + [_window setEffectProgress:progress]; + _effectSpeed = (1.0 / (EFFECT_FPS * time)); + + if ( progress == 0.0 ) { + [self setZoom:0.0]; + [_window setAlphaValue:0.0]; + } + + [_window orderFront:self]; + _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) + target:self + selector:@selector(appearStep) + userInfo:nil + repeats:YES]; +} + +- (void)appearStep +{ + float interZoom = 0.0; + [_window setEffectProgress:([_window effectProgress] + _effectSpeed)]; + [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)]; + interZoom = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2); + [self setZoom:interZoom]; + [_window setAlphaValue:interZoom]; + + if ( [_window effectProgress] >= 1.0 ) { + [self appearFinish]; + } +} + +- (void)appearFinish +{ + [_effectTimer invalidate]; + _effectTimer = nil; + [self setWindowVisibility:ITWindowVisibleState]; + + __idle = YES; + + if ( __shouldReleaseWhenIdle ) { + [self release]; + } +} + +- (void)cancelAppear +{ + [self setWindowVisibility:ITWindowVanishingState]; + + [_effectTimer invalidate]; + _effectTimer = nil; + + [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark VANISH METHODS +/*************************************************************************/ + +- (void)performVanish +{ + __idle = NO; + + [self setWindowVisibility:ITWindowVanishingState]; + [self performVanishFromProgress:1.0 effectTime:_effectTime]; +} + +- (void)performVanishFromProgress:(float)progress effectTime:(float)time +{ + [_window setEffectProgress:progress]; + _effectSpeed = (1.0 / (EFFECT_FPS * time)); + if ( progress == 1.0 ) { + [self setZoom:0.0]; + [_window setAlphaValue:1.0]; + } + + [_window orderFront:self]; + _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) + target:self + selector:@selector(vanishStep) + userInfo:nil + repeats:YES]; +} + +- (void)vanishStep +{ + float interZoom = 1.0; + [_window setEffectProgress:([_window effectProgress] - _effectSpeed)]; + [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)]; + interZoom = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2); + [self setZoom:interZoom]; + [_window setAlphaValue:interZoom]; + + if ( [_window effectProgress] <= 0.0 ) { + [self vanishFinish]; + } +} + +- (void)vanishFinish +{ + [_effectTimer invalidate]; + _effectTimer = nil; + [_window orderOut:self]; + [_window setAlphaValue:1.0]; + [self setZoom:0.0]; + [self setWindowVisibility:ITWindowHiddenState]; + + __idle = YES; + + if ( __shouldReleaseWhenIdle ) { + [self release]; + } +} + +- (void)cancelVanish +{ + [self setWindowVisibility:ITWindowAppearingState]; + + [_effectTimer invalidate]; + _effectTimer = nil; + + [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark PRIVATE METHOD IMPLEMENTATIONS +/*************************************************************************/ + +- (void)setZoom:(float)Zoom +{ + int hPos = [_window horizontalPosition]; + CGAffineTransform transform; + NSPoint translation; + NSRect screenFrame = [[_window screen] frame]; + + translation.x = screenFrame.origin.x + ([_window frame].size.width / 2.0); + translation.y = screenFrame.origin.y + ([_window frame].size.height / 2.0); + transform = CGAffineTransformMakeTranslation(translation.x, translation.y); + transform = CGAffineTransformScale(transform, 1.0 / Zoom, 1.0 / Zoom); + transform = CGAffineTransformTranslate(transform, -translation.x, -translation.y); + + if (hPos == ITWindowPositionLeft) { + translation.x = -[_window frame].origin.x; + } else if (hPos == ITWindowPositionRight) { + translation.x = -[_window frame].origin.x; + } else { + translation.x = -[_window frame].origin.x; + } + + translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); + + transform = CGAffineTransformTranslate(transform, translation.x, translation.y); + + CGSSetWindowTransform([NSApp contextID], + (CGSWindowID)[_window windowNumber], + transform); +} + +@end diff --git a/Showcase/Controller.h b/Showcase/Controller.h index 399b3c9..490bec0 100755 --- a/Showcase/Controller.h +++ b/Showcase/Controller.h @@ -26,6 +26,8 @@ IBOutlet ITTextField *testTextField; // ITTransientStatusWindow Support + IBOutlet NSPopUpButton *entryEffectPopup; + IBOutlet NSPopUpButton *exitEffectPopup; ITIconAndTextStatusWindow *statusWindow; IBOutlet NSTextView *swSampleTextView; IBOutlet NSPopUpButton *swVanishModePopup; @@ -50,6 +52,7 @@ - (IBAction)toggleCastsShadow:(id)sender; // ITTransientStatusWindow Support +- (void)populateEffectPopups; - (IBAction)buildStatusWindow:(id)sender; - (IBAction)toggleStatusWindow:(id)sender; - (IBAction)changeWindowSetting:(id)sender; diff --git a/Showcase/Controller.m b/Showcase/Controller.m index ba9c278..ac02c52 100755 --- a/Showcase/Controller.m +++ b/Showcase/Controller.m @@ -9,6 +9,7 @@ #import "ITSlideHorizontallyWindowEffect.h" #import "ITSlideVerticallyWindowEffect.h" #import "ITPivotWindowEffect.h" +#import "ITZoomWindowEffect.h" #import "ITMultilineTextFieldCell.h" @@ -40,9 +41,10 @@ [bevelView setBevelDepth:10]; statusWindow = [ITIconAndTextStatusWindow sharedWindow]; [statusWindow setEntryEffect:[[ITCutWindowEffect alloc] initWithWindow:statusWindow]]; - [statusWindow setExitEffect:[[ITDissolveWindowEffect alloc] initWithWindow:statusWindow]]; + [statusWindow setExitEffect:[[ITCutWindowEffect alloc] initWithWindow:statusWindow]]; [[statusWindow entryEffect] setEffectTime:[swEntrySpeedSlider floatValue]]; [[statusWindow exitEffect] setEffectTime:[swExitSpeedSlider floatValue]]; + [self populateEffectPopups]; // [tabView setAllowsDragging:YES]; [[NSColorPanel sharedColorPanel] setShowsAlpha:YES]; @@ -152,6 +154,21 @@ #pragma mark ITTransientStatusWindow SUPPORT /*************************************************************************/ +- (void)populateEffectPopups +{ + NSArray *effects = [ITWindowEffect effectClasses]; + int i; + [entryEffectPopup removeAllItems]; + [exitEffectPopup removeAllItems]; + for (i = 0; i < [effects count]; i++) { + id anItem = [effects objectAtIndex:i]; + [entryEffectPopup addItemWithTitle:[anItem effectName]]; + [exitEffectPopup addItemWithTitle:[anItem effectName]]; + [[entryEffectPopup lastItem] setRepresentedObject:anItem]; + [[exitEffectPopup lastItem] setRepresentedObject:anItem]; + } +} + - (IBAction)buildStatusWindow:(id)sender { NSImage *image = [NSImage imageNamed:SW_IMAGE]; @@ -194,39 +211,12 @@ } else if ( [sender tag] == 3061 ) { [[statusWindow exitEffect] setEffectTime:[sender floatValue]]; } else if ( [sender tag] == 3070 ) { - - if ( [sender indexOfSelectedItem] == 0 ) { - [statusWindow setEntryEffect:[[[ITCutWindowEffect alloc] initWithWindow:statusWindow] autorelease]]; - } else if ( [sender indexOfSelectedItem] == 1 ) { - [statusWindow setEntryEffect:[[[ITDissolveWindowEffect alloc] initWithWindow:statusWindow] autorelease]]; - } else if ( [sender indexOfSelectedItem] == 2 ) { - [statusWindow setEntryEffect:[[[ITSlideVerticallyWindowEffect alloc] initWithWindow:statusWindow] autorelease]]; - } else if ( [sender indexOfSelectedItem] == 3 ) { - [statusWindow setEntryEffect:[[[ITSlideHorizontallyWindowEffect alloc] initWithWindow:statusWindow] autorelease]]; - } else if ( [sender indexOfSelectedItem] == 4 ) { - [statusWindow setEntryEffect:[[[ITPivotWindowEffect alloc] initWithWindow:statusWindow] autorelease]]; - } - + [statusWindow setEntryEffect:[[[[[sender selectedItem] representedObject] alloc] initWithWindow:statusWindow] autorelease]]; [[statusWindow entryEffect] setEffectTime:[swEntrySpeedSlider floatValue]]; - } else if ( [sender tag] == 3080 ) { - - if ( [sender indexOfSelectedItem] == 0 ) { - [statusWindow setExitEffect:[[ITCutWindowEffect alloc] initWithWindow:statusWindow]]; - } else if ( [sender indexOfSelectedItem] == 1 ) { - [statusWindow setExitEffect:[[ITDissolveWindowEffect alloc] initWithWindow:statusWindow]]; - } else if ( [sender indexOfSelectedItem] == 2 ) { - [statusWindow setExitEffect:[[ITSlideVerticallyWindowEffect alloc] initWithWindow:statusWindow]]; - } else if ( [sender indexOfSelectedItem] == 3 ) { - [statusWindow setExitEffect:[[ITSlideHorizontallyWindowEffect alloc] initWithWindow:statusWindow]]; - } else if ( [sender indexOfSelectedItem] == 4 ) { - [statusWindow setExitEffect:[[ITPivotWindowEffect alloc] initWithWindow:statusWindow]]; - } - + [statusWindow setExitEffect:[[[[[sender selectedItem] representedObject] alloc] initWithWindow:statusWindow] autorelease]]; [[statusWindow exitEffect] setEffectTime:[swExitSpeedSlider floatValue]]; - } else if ( [sender tag] == 3090 ) { - if ( [sender indexOfSelectedItem] == 0 ) { [(ITTSWBackgroundView *)[statusWindow contentView] setBackgroundMode:ITTSWBackgroundApple]; } else if ( [sender indexOfSelectedItem] == 1 ) { @@ -234,7 +224,6 @@ } else if ( [sender indexOfSelectedItem] == 2 ) { [(ITTSWBackgroundView *)[statusWindow contentView] setBackgroundMode:ITTSWBackgroundColored]; } - } else if ( [sender tag] == 3100 ) { [(ITTSWBackgroundView *)[statusWindow contentView] setBackgroundColor:[sender color]]; } diff --git a/Showcase/English.lproj/MainMenu.nib/classes.nib b/Showcase/English.lproj/MainMenu.nib/classes.nib index 512782e..c083aec 100755 --- a/Showcase/English.lproj/MainMenu.nib/classes.nib +++ b/Showcase/English.lproj/MainMenu.nib/classes.nib @@ -22,6 +22,8 @@ OUTLETS = { bevelView = ITBevelView; button = ITButton; + entryEffectPopup = NSPopUpButton; + exitEffectPopup = NSPopUpButton; showImageCheckBox = NSButton; showStatusItemCheckBox = NSButton; showTitleCheckBox = NSButton; diff --git a/Showcase/English.lproj/MainMenu.nib/info.nib b/Showcase/English.lproj/MainMenu.nib/info.nib index 03db0ad..2f4c012 100755 --- a/Showcase/English.lproj/MainMenu.nib/info.nib +++ b/Showcase/English.lproj/MainMenu.nib/info.nib @@ -7,18 +7,18 @@ IBEditorPositions 197 - 624 471 153 118 0 0 1152 842 + 624 409 153 118 0 0 1152 746 29 1 271 349 44 0 0 1056 770 IBFramework Version - 349.0 + 364.0 IBOpenObjects 21 197 IBSystem Version - 7D24 + 7H63 diff --git a/Showcase/English.lproj/MainMenu.nib/keyedobjects.nib b/Showcase/English.lproj/MainMenu.nib/keyedobjects.nib index a0b1e188a65778fd727668ec9a156eb698c3a3f5..e3a07fa2bbaeb353a3c42617b562869bf6aaddad 100755 GIT binary patch literal 42743 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 literal 43473 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

jxUDkF(B%W5; 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 Date: Wed, 30 Jun 2004 03:21:15 +0000 Subject: [PATCH 13/16] Added a new spin effect. Silly, but looks cool :) --- ITKit.xcode/project.pbxproj | 32 +++++ ITSpinWindowEffect.h | 23 ++++ ITSpinWindowEffect.m | 226 ++++++++++++++++++++++++++++++++++++ ITWindowEffect.m | 1 + 4 files changed, 282 insertions(+) create mode 100755 ITSpinWindowEffect.h create mode 100755 ITSpinWindowEffect.m diff --git a/ITKit.xcode/project.pbxproj b/ITKit.xcode/project.pbxproj index e0c00c0..3f32676 100755 --- a/ITKit.xcode/project.pbxproj +++ b/ITKit.xcode/project.pbxproj @@ -537,6 +537,34 @@ settings = { }; }; + 37B3906906923D1200E828B9 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITSpinWindowEffect.h; + refType = 4; + sourceTree = ""; + }; + 37B3906A06923D1200E828B9 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITSpinWindowEffect.m; + refType = 4; + sourceTree = ""; + }; + 37B3906B06923D1200E828B9 = { + fileRef = 37B3906906923D1200E828B9; + isa = PBXBuildFile; + settings = { + }; + }; + 37B3906C06923D1200E828B9 = { + fileRef = 37B3906A06923D1200E828B9; + isa = PBXBuildFile; + settings = { + }; + }; //370 //371 //372 @@ -1837,6 +1865,8 @@ 7C992DE8054F5179000B93EA, 372C5813068FE72F00CEF54A, 372C5812068FE72F00CEF54A, + 37B3906906923D1200E828B9, + 37B3906A06923D1200E828B9, ); isa = PBXGroup; name = Effects; @@ -2192,6 +2222,7 @@ 3710912805C0825900ED0F36, 7C4BBADC05F98C9900734027, 372C5815068FE72F00CEF54A, + 37B3906B06923D1200E828B9, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -2253,6 +2284,7 @@ 3710912305C0821000ED0F36, 7C4BBADD05F98C9900734027, 372C5814068FE72F00CEF54A, + 37B3906C06923D1200E828B9, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; diff --git a/ITSpinWindowEffect.h b/ITSpinWindowEffect.h new file mode 100755 index 0000000..ee6fad8 --- /dev/null +++ b/ITSpinWindowEffect.h @@ -0,0 +1,23 @@ +/* + * ITKit + * ITSpinWindowEffect + * Effect subclass which Spins (expands/shrinks) a window into position on the screen. + * + * Original Author : Kent Sutherland + * Responsibility : Kent Sutherland + * + * Copyright (c) 2002 - 2004 iThink Software. + * All Rights Reserved + * + */ + + +#import +#import "ITWindowEffect.h" + + +@interface ITSpinWindowEffect : ITWindowEffect { + +} + +@end diff --git a/ITSpinWindowEffect.m b/ITSpinWindowEffect.m new file mode 100755 index 0000000..b3137bf --- /dev/null +++ b/ITSpinWindowEffect.m @@ -0,0 +1,226 @@ +#import "ITSpinWindowEffect.h" +#import "ITCoreGraphicsHacks.h" +#import "ITTransientStatusWindow.h" + + +@interface ITSpinWindowEffect (Private) +- (void)performAppearFromProgress:(float)progress effectTime:(float)time; +- (void)appearStep; +- (void)appearFinish; +- (void)performVanishFromProgress:(float)progress effectTime:(float)time; +- (void)vanishStep; +- (void)vanishFinish; +- (void)setSpin:(float)progress; +@end + + +@implementation ITSpinWindowEffect + + ++ (NSString *)effectName +{ + return @"Spin"; +} + ++ (NSDictionary *)supportedPositions +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Top" , + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Middle" , + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Bottom" , nil]; +} + + ++ (unsigned int)listOrder +{ + return 600; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark APPEAR METHODS +/*************************************************************************/ + +- (void)performAppear +{ + __idle = NO; + + [self setWindowVisibility:ITWindowAppearingState]; + [self performAppearFromProgress:0.0 effectTime:_effectTime]; +} + +- (void)performAppearFromProgress:(float)progress effectTime:(float)time +{ + [_window setEffectProgress:progress]; + _effectSpeed = (1.0 / (EFFECT_FPS * time)); + + if ( progress == 0.0 ) { + [self setSpin:0.0]; + [_window setAlphaValue:0.0]; + } + + [_window orderFront:self]; + _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) + target:self + selector:@selector(appearStep) + userInfo:nil + repeats:YES]; +} + +- (void)appearStep +{ + float interSpin = 0.0; + [_window setEffectProgress:([_window effectProgress] + _effectSpeed)]; + [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)]; + interSpin = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2); + [self setSpin:-interSpin]; + [_window setAlphaValue:interSpin]; + + if ( [_window effectProgress] >= 1.0 ) { + [self appearFinish]; + } +} + +- (void)appearFinish +{ + [_effectTimer invalidate]; + _effectTimer = nil; + [self setWindowVisibility:ITWindowVisibleState]; + + __idle = YES; + + if ( __shouldReleaseWhenIdle ) { + [self release]; + } +} + +- (void)cancelAppear +{ + [self setWindowVisibility:ITWindowVanishingState]; + + [_effectTimer invalidate]; + _effectTimer = nil; + + [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark VANISH METHODS +/*************************************************************************/ + +- (void)performVanish +{ + __idle = NO; + + [self setWindowVisibility:ITWindowVanishingState]; + [self performVanishFromProgress:1.0 effectTime:_effectTime]; +} + +- (void)performVanishFromProgress:(float)progress effectTime:(float)time +{ + [_window setEffectProgress:progress]; + _effectSpeed = (1.0 / (EFFECT_FPS * time)); + if ( progress == 1.0 ) { + [self setSpin:0.0]; + [_window setAlphaValue:1.0]; + } + + [_window orderFront:self]; + _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) + target:self + selector:@selector(vanishStep) + userInfo:nil + repeats:YES]; +} + +- (void)vanishStep +{ + float interSpin = 1.0; + [_window setEffectProgress:([_window effectProgress] - _effectSpeed)]; + [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)]; + interSpin = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2); + [self setSpin:interSpin]; + [_window setAlphaValue:interSpin]; + + if ( [_window effectProgress] <= 0.0 ) { + [self vanishFinish]; + } +} + +- (void)vanishFinish +{ + [_effectTimer invalidate]; + _effectTimer = nil; + [_window orderOut:self]; + [_window setAlphaValue:1.0]; + [self setSpin:0.0]; + [self setWindowVisibility:ITWindowHiddenState]; + + __idle = YES; + + if ( __shouldReleaseWhenIdle ) { + [self release]; + } +} + +- (void)cancelVanish +{ + [self setWindowVisibility:ITWindowAppearingState]; + + [_effectTimer invalidate]; + _effectTimer = nil; + + [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark PRIVATE METHOD IMPLEMENTATIONS +/*************************************************************************/ + +- (void)setSpin:(float)progress +{ + int hPos = [_window horizontalPosition]; + float radAngle = (progress * 4 * pi); + CGAffineTransform transform; + NSPoint translation; + NSRect screenFrame = [[_window screen] frame]; + + translation.x = screenFrame.origin.x + ([_window frame].size.width / 2.0); + translation.y = screenFrame.origin.y + ([_window frame].size.height / 2.0); + transform = CGAffineTransformMakeTranslation(translation.x, translation.y); + transform = CGAffineTransformRotate(transform, radAngle); + //transform = CGAffineTransformScale(transform, 1.0 / progress, 1.0 / progress); + transform = CGAffineTransformTranslate(transform, -translation.x, -translation.y); + + if (hPos == ITWindowPositionLeft) { + translation.x = -[_window frame].origin.x; + } else if (hPos == ITWindowPositionRight) { + translation.x = -[_window frame].origin.x; + } else { + translation.x = -[_window frame].origin.x; + } + + translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); + + transform = CGAffineTransformTranslate(transform, translation.x, translation.y); + + CGSSetWindowTransform([NSApp contextID], + (CGSWindowID)[_window windowNumber], + transform); +} + +@end diff --git a/ITWindowEffect.m b/ITWindowEffect.m index 576d6d1..7111d38 100755 --- a/ITWindowEffect.m +++ b/ITWindowEffect.m @@ -13,6 +13,7 @@ NSClassFromString(@"ITSlideVerticallyWindowEffect"), NSClassFromString(@"ITPivotWindowEffect"), NSClassFromString(@"ITZoomWindowEffect"), + NSClassFromString(@"ITSpinWindowEffect"), nil]; return classes; -- 2.20.1 From 5cbc248a68de115c0c10fda4a6896b47478000a8 Mon Sep 17 00:00:00 2001 From: Kent Sutherland Date: Thu, 1 Jul 2004 02:59:24 +0000 Subject: [PATCH 14/16] Changed hot key panel to allow longer hot key names --- English.lproj/ITKeyComboPanel.nib/info.nib | 6 +++--- English.lproj/ITKeyComboPanel.nib/objects.nib | Bin 2486 -> 2747 bytes ITKeyComboPanel.h | 1 - ITKeyComboPanel.m | 5 +---- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/English.lproj/ITKeyComboPanel.nib/info.nib b/English.lproj/ITKeyComboPanel.nib/info.nib index d6ed0ab..92bbfc7 100755 --- a/English.lproj/ITKeyComboPanel.nib/info.nib +++ b/English.lproj/ITKeyComboPanel.nib/info.nib @@ -3,9 +3,9 @@ IBDocumentLocation - 109 47 356 240 0 0 1280 1002 + 94 71 356 240 0 0 1152 746 IBFramework Version - 291.0 + 364.0 IBGroupedObjects 10 @@ -21,6 +21,6 @@ 19 IBSystem Version - 6L60 + 7H63 diff --git a/English.lproj/ITKeyComboPanel.nib/objects.nib b/English.lproj/ITKeyComboPanel.nib/objects.nib index 570f426881cd0102568c60ca205c143b901fa73f..9738afbff5ac82aba58c699164e77a1762740fa8 100755 GIT binary patch literal 2747 zcmai0TWs4@7(PzYwCiPSSyyP8hJgvx!Me5Url~?KO-5<7k#K96#W)y?zb6WL7{RWKLN=qwDM3Z$624k0S_rp>;4|TUTw~tJXP-#`}bH^8*LHNe?0=~30Txbd*bOXdAqf#v1qQ);RFbh?+dx(LqzPpA2jxj?- z5lyskPSX?_eO0IQ$JPXkP=ei2_#M$jF>yB&B+h(&ox)IPI_>HX#1vVm>0iNnvRP3i z5QTK~Yd2Fc3ZZR~0$_V-=A}3>8{dOR5#O>70&)YVUF14ljyPiW5{Xp+y(JYR#Q${hLU_8N^)?} zEy=@>bpJu7M^P9lP^_tHi8cYDx`ed3fPV9`oOA_-fqtN)?`dCvf446H|9S0XTt{F0 zkA=vqJ9b1juBSP2-{q<&4;!*KWA>(=8A1D z+2)*0nkq#4eNj#+`Gkkg2T6LY*|Up; zxh0(t!3oa*Xa`mou(bH_xbt|wv+}Gn-|fsDaGp8oYz{hp)@gXjS$)pge!-bxoaUp> y-T`Ord1vEAr?t;n>T();9lO(6Kj>IJ)+viIHy#ikY>$SiZ6hksRbEl24C5cmJVYS? delta 1407 zcmZ8gO>7%Q6rQm+P8O$-;G~cSsV-1eDGJb32oxc3V=3y7>ZaP13mmYWO|^=>3-$&l z2b8Rtoip9Vt85Q@h_FyxN9iGUOh77?DuRYuh(jbU9FUMAAr2e?LCPE3*iOgNtl!L= z_rCXi?|n5~4Sl+Z`)_@e#^SAC-?NkWM2L{5V$#(`J)TI(lAcl2o7nysUksIS36%tD znzR^1$TF$r+Ew4#01=dAGGhPY8@fSAe@wcN)D=yQ%Bj@g7oX<^e2DUWZy;18YimMG zQ)OB*P2y7~k!hJ$nTXk}qD1&I(03y^PxFySWMd7{#%7W`_GSO+!Hr{(oC84Aq|_pt z_Nsq$rHn8lTaP6PMB{2wPVqEbjU1J`U6I##WWJf(jX<|8&qbaIYsNsU27Z4KA--E4 zpo3o{MT3%Ac}bsE?AklvUS)lympeO3w(KNJs`0@89;m(v_xe^OKRjFxKnQ1VU5Pki(9pS*pxbO%#z z2dekMZJ_1Gp>FO(jNiBpT#=WDv+>WwG9 z{KYqad{iSF_CQbSGPa=9;g~e7q+~Uoma{VnEuNX1UH(9(bZ99YMkpM9Os`-}x|ELJ zl(|-8(1r-4LPa|fh$c$F4#U zzK=83!R~J3rZV=wcw`(j+riypiF#Y5Z=r=bm7cTiId#wR?1#NCt@!(!Nb-LyAyk8! zp-E=qDzq|;g7A(a=cs35BFw`AR6WS>|5m~~2HH1}VVN)*PI2AY^_)G=DSHm{oQmfh z6r6p}4LS!9ucsN!ap6A@)NW|%?7_(j%x?Q=f;tsA6JyfUqONP|IfxB*ASN|%IJ;nU z`@?;KA90P&WW(2Ts+^(Ddh^MYwgmTeFxv6XQ-^`w_kVoql%MXtpMW;|>7G3xzW!pB z@yLE{VUiF2U)2gXdy|bJZylBG1#xWr?`nZp8OSN>oR;IxxLV*@gK22#sbn0cE7Ll5 z?fYWrNx0{Q1kGBn0|US_?oF#k9cC)l4S zS^X4a&#}Ex_D`4{KF{`FW$tly5MsM0SOK&0Gpsnm)`#8mE_Uia@CF{ZG!@m7T6{VK LEu7Ob3zYr`Ap%WS diff --git a/ITKeyComboPanel.h b/ITKeyComboPanel.h index 85806d4..3df295a 100755 --- a/ITKeyComboPanel.h +++ b/ITKeyComboPanel.h @@ -26,7 +26,6 @@ IBOutlet NSTextField* mComboField; IBOutlet ITKeyBroadcaster* mKeyBcaster; - NSString* mTitleFormat; NSString* mKeyName; ITKeyCombo* mKeyCombo; } diff --git a/ITKeyComboPanel.m b/ITKeyComboPanel.m index e10ffc0..3f71636 100755 --- a/ITKeyComboPanel.m +++ b/ITKeyComboPanel.m @@ -43,15 +43,12 @@ static id _sharedKeyComboPanel = nil; { [[NSNotificationCenter defaultCenter] removeObserver: self]; [mKeyName release]; - [mTitleFormat release]; [super dealloc]; } - (void)windowDidLoad { - mTitleFormat = [[mTitleField stringValue] retain]; - [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector( noteKeyBroadcast: ) @@ -65,7 +62,7 @@ static id _sharedKeyComboPanel = nil; [mComboField setStringValue: [mKeyCombo description]]; if( mTitleField ) - [mTitleField setStringValue: [NSString stringWithFormat: mTitleFormat, mKeyName]]; + [mTitleField setStringValue:mKeyName]; } - (int)runModal -- 2.20.1 From cdaf08d75aed64cffcb54c908eb383b05dd92789 Mon Sep 17 00:00:00 2001 From: Kent Sutherland Date: Fri, 2 Jul 2004 03:39:25 +0000 Subject: [PATCH 15/16] Spin & Zoom effect. --- ITKit.xcode/project.pbxproj | 32 +++++ ITSpinAndZoomWindowEffect.h | 23 ++++ ITSpinAndZoomWindowEffect.m | 225 ++++++++++++++++++++++++++++++++++++ ITSpinWindowEffect.m | 2 - ITWindowEffect.m | 1 + 5 files changed, 281 insertions(+), 2 deletions(-) create mode 100755 ITSpinAndZoomWindowEffect.h create mode 100755 ITSpinAndZoomWindowEffect.m diff --git a/ITKit.xcode/project.pbxproj b/ITKit.xcode/project.pbxproj index 3f32676..1e394fa 100755 --- a/ITKit.xcode/project.pbxproj +++ b/ITKit.xcode/project.pbxproj @@ -537,6 +537,34 @@ settings = { }; }; + 3747E3F806950A0D001ACA46 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ITSpinAndZoomWindowEffect.h; + refType = 4; + sourceTree = ""; + }; + 3747E3F906950A0D001ACA46 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + path = ITSpinAndZoomWindowEffect.m; + refType = 4; + sourceTree = ""; + }; + 3747E3FA06950A0D001ACA46 = { + fileRef = 3747E3F806950A0D001ACA46; + isa = PBXBuildFile; + settings = { + }; + }; + 3747E3FB06950A0D001ACA46 = { + fileRef = 3747E3F906950A0D001ACA46; + isa = PBXBuildFile; + settings = { + }; + }; 37B3906906923D1200E828B9 = { fileEncoding = 30; isa = PBXFileReference; @@ -1867,6 +1895,8 @@ 372C5812068FE72F00CEF54A, 37B3906906923D1200E828B9, 37B3906A06923D1200E828B9, + 3747E3F806950A0D001ACA46, + 3747E3F906950A0D001ACA46, ); isa = PBXGroup; name = Effects; @@ -2223,6 +2253,7 @@ 7C4BBADC05F98C9900734027, 372C5815068FE72F00CEF54A, 37B3906B06923D1200E828B9, + 3747E3FA06950A0D001ACA46, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -2285,6 +2316,7 @@ 7C4BBADD05F98C9900734027, 372C5814068FE72F00CEF54A, 37B3906C06923D1200E828B9, + 3747E3FB06950A0D001ACA46, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; diff --git a/ITSpinAndZoomWindowEffect.h b/ITSpinAndZoomWindowEffect.h new file mode 100755 index 0000000..5f923ec --- /dev/null +++ b/ITSpinAndZoomWindowEffect.h @@ -0,0 +1,23 @@ +/* + * ITKit + * ITSpinAndZoomWindowEffect + * Effect subclass which Spins (expands/shrinks) a window into position on the screen. + * + * Original Author : Kent Sutherland + * Responsibility : Kent Sutherland + * + * Copyright (c) 2002 - 2004 iThink Software. + * All Rights Reserved + * + */ + + +#import +#import "ITWindowEffect.h" + + +@interface ITSpinAndZoomWindowEffect : ITWindowEffect { + +} + +@end diff --git a/ITSpinAndZoomWindowEffect.m b/ITSpinAndZoomWindowEffect.m new file mode 100755 index 0000000..029b7bd --- /dev/null +++ b/ITSpinAndZoomWindowEffect.m @@ -0,0 +1,225 @@ +#import "ITSpinAndZoomWindowEffect.h" +#import "ITCoreGraphicsHacks.h" +#import "ITTransientStatusWindow.h" + + +@interface ITSpinAndZoomWindowEffect (Private) +- (void)performAppearFromProgress:(float)progress effectTime:(float)time; +- (void)appearStep; +- (void)appearFinish; +- (void)performVanishFromProgress:(float)progress effectTime:(float)time; +- (void)vanishStep; +- (void)vanishFinish; +- (void)setScale:(float)scale angle:(float)angle; +@end + + +@implementation ITSpinAndZoomWindowEffect + + ++ (NSString *)effectName +{ + return @"Spin & Zoom"; +} + ++ (NSDictionary *)supportedPositions +{ + return [NSDictionary dictionaryWithObjectsAndKeys: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Top" , + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Middle" , + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], @"Left", + [NSNumber numberWithBool:YES], @"Center", + [NSNumber numberWithBool:YES], @"Right", nil] , @"Bottom" , nil]; +} + + ++ (unsigned int)listOrder +{ + return 600; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark APPEAR METHODS +/*************************************************************************/ + +- (void)performAppear +{ + __idle = NO; + + [self setWindowVisibility:ITWindowAppearingState]; + [self performAppearFromProgress:0.0 effectTime:_effectTime]; +} + +- (void)performAppearFromProgress:(float)progress effectTime:(float)time +{ + [_window setEffectProgress:progress]; + _effectSpeed = (1.0 / (EFFECT_FPS * time)); + + if ( progress == 0.0 ) { + [self setScale:0.0 angle:0.0]; + [_window setAlphaValue:0.0]; + } + + [_window orderFront:self]; + _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) + target:self + selector:@selector(appearStep) + userInfo:nil + repeats:YES]; +} + +- (void)appearStep +{ + float interSpin = 0.0; + [_window setEffectProgress:([_window effectProgress] + _effectSpeed)]; + [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)]; + interSpin = (( sin((([_window effectProgress]) * pi) - (pi / 2)) + 1 ) / 2); + [self setScale:interSpin angle:-interSpin]; + [_window setAlphaValue:interSpin]; + + if ( [_window effectProgress] >= 1.0 ) { + [self appearFinish]; + } +} + +- (void)appearFinish +{ + [_effectTimer invalidate]; + _effectTimer = nil; + [self setWindowVisibility:ITWindowVisibleState]; + + __idle = YES; + + if ( __shouldReleaseWhenIdle ) { + [self release]; + } +} + +- (void)cancelAppear +{ + [self setWindowVisibility:ITWindowVanishingState]; + + [_effectTimer invalidate]; + _effectTimer = nil; + + [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark VANISH METHODS +/*************************************************************************/ + +- (void)performVanish +{ + __idle = NO; + + [self setWindowVisibility:ITWindowVanishingState]; + [self performVanishFromProgress:1.0 effectTime:_effectTime]; +} + +- (void)performVanishFromProgress:(float)progress effectTime:(float)time +{ + [_window setEffectProgress:progress]; + _effectSpeed = (1.0 / (EFFECT_FPS * time)); + if ( progress == 1.0 ) { + [self setScale:1.0 angle:0.0]; + [_window setAlphaValue:1.0]; + } + + [_window orderFront:self]; + _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS) + target:self + selector:@selector(vanishStep) + userInfo:nil + repeats:YES]; +} + +- (void)vanishStep +{ + float interSpin = 1.0; + [_window setEffectProgress:([_window effectProgress] - _effectSpeed)]; + [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)]; + interSpin = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2); + [self setScale:interSpin angle:interSpin]; + [_window setAlphaValue:interSpin]; + + if ( [_window effectProgress] <= 0.0 ) { + [self vanishFinish]; + } +} + +- (void)vanishFinish +{ + [_effectTimer invalidate]; + _effectTimer = nil; + [_window orderOut:self]; + [_window setAlphaValue:1.0]; + [self setScale:0.0 angle:0.0]; + [self setWindowVisibility:ITWindowHiddenState]; + + __idle = YES; + + if ( __shouldReleaseWhenIdle ) { + [self release]; + } +} + +- (void)cancelVanish +{ + [self setWindowVisibility:ITWindowAppearingState]; + + [_effectTimer invalidate]; + _effectTimer = nil; + + [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)]; +} + + +/*************************************************************************/ +#pragma mark - +#pragma mark PRIVATE METHOD IMPLEMENTATIONS +/*************************************************************************/ + +- (void)setScale:(float)scale angle:(float)angle +{ + int hPos = [_window horizontalPosition]; + float radAngle = (angle * 4 * pi); + CGAffineTransform transform; + NSPoint translation; + NSRect screenFrame = [[_window screen] frame]; + + translation.x = screenFrame.origin.x + ([_window frame].size.width / 2.0); + translation.y = screenFrame.origin.y + ([_window frame].size.height / 2.0); + transform = CGAffineTransformMakeTranslation(translation.x, translation.y); + transform = CGAffineTransformScale(transform, 1.0 / scale, 1.0 / scale); + transform = CGAffineTransformRotate(transform, radAngle); + transform = CGAffineTransformTranslate(transform, -translation.x, -translation.y); + + if (hPos == ITWindowPositionLeft) { + translation.x = -[_window frame].origin.x; + } else if (hPos == ITWindowPositionRight) { + translation.x = -[_window frame].origin.x; + } else { + translation.x = -[_window frame].origin.x; + } + + translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); + + transform = CGAffineTransformTranslate(transform, translation.x, translation.y); + CGSSetWindowTransform([NSApp contextID], + (CGSWindowID)[_window windowNumber], + transform); +} + +@end diff --git a/ITSpinWindowEffect.m b/ITSpinWindowEffect.m index b3137bf..ad28792 100755 --- a/ITSpinWindowEffect.m +++ b/ITSpinWindowEffect.m @@ -203,7 +203,6 @@ translation.y = screenFrame.origin.y + ([_window frame].size.height / 2.0); transform = CGAffineTransformMakeTranslation(translation.x, translation.y); transform = CGAffineTransformRotate(transform, radAngle); - //transform = CGAffineTransformScale(transform, 1.0 / progress, 1.0 / progress); transform = CGAffineTransformTranslate(transform, -translation.x, -translation.y); if (hPos == ITWindowPositionLeft) { @@ -217,7 +216,6 @@ translation.y = -( [[_window screen] frame].size.height - [_window frame].origin.y - [_window frame].size.height ); transform = CGAffineTransformTranslate(transform, translation.x, translation.y); - CGSSetWindowTransform([NSApp contextID], (CGSWindowID)[_window windowNumber], transform); diff --git a/ITWindowEffect.m b/ITWindowEffect.m index 7111d38..54a73bf 100755 --- a/ITWindowEffect.m +++ b/ITWindowEffect.m @@ -14,6 +14,7 @@ NSClassFromString(@"ITPivotWindowEffect"), NSClassFromString(@"ITZoomWindowEffect"), NSClassFromString(@"ITSpinWindowEffect"), + NSClassFromString(@"ITSpinAndZoomWindowEffect"), nil]; return classes; -- 2.20.1 From 5a5f8385d7cf8bca82ac4bafe96d1dd313a1bc24 Mon Sep 17 00:00:00 2001 From: Kent Sutherland Date: Tue, 17 Aug 2004 22:25:09 +0000 Subject: [PATCH 16/16] Fixed the effect number. --- ITSpinAndZoomWindowEffect.m | 2 +- ITSpinWindowEffect.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ITSpinAndZoomWindowEffect.m b/ITSpinAndZoomWindowEffect.m index 029b7bd..8369fc2 100755 --- a/ITSpinAndZoomWindowEffect.m +++ b/ITSpinAndZoomWindowEffect.m @@ -42,7 +42,7 @@ + (unsigned int)listOrder { - return 600; + return 800; } diff --git a/ITSpinWindowEffect.m b/ITSpinWindowEffect.m index ad28792..ad1b8aa 100755 --- a/ITSpinWindowEffect.m +++ b/ITSpinWindowEffect.m @@ -42,7 +42,7 @@ + (unsigned int)listOrder { - return 600; + return 700; } -- 2.20.1