From 246a44c09fba59ad0598f7fff76b57d71078c880 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Tue, 15 May 2012 10:21:04 -0400 Subject: [PATCH 01/13] fixes the control that was previously entirely broken --- English.lproj/MainMenu.xib | 1047 +++------------------ TMSliderControl.h | 40 +- TMSliderControl.m | 277 +++--- TMSliderControl.xcodeproj/project.pbxproj | 18 +- TMSliderControlSmall.m | 68 +- 5 files changed, 292 insertions(+), 1158 deletions(-) diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index 9950777..7c37989 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -2,18 +2,24 @@ 1050 - 10F569 - 823 - 1038.29 - 461.00 + 11E52 + 2182 + 1138.47 + 569.00 com.apple.InterfaceBuilder.CocoaPlugin - 823 + 2182 - + YES - - + NSView + NSMenu + NSWindowTemplate + NSMenuItem + NSTextField + NSTextFieldCell + NSCustomView + NSCustomObject YES @@ -1117,7 +1123,7 @@ Window NSWindow - {3.40282e+38, 3.40282e+38} + 256 @@ -1128,6 +1134,8 @@ 268 {{129, 99}, {93, 28}} + + TMSliderControl @@ -1135,6 +1143,7 @@ 268 {{145, 54}, {55, 18}} + TMSliderControlSmall @@ -1142,6 +1151,8 @@ 268 {{78, 103}, {38, 22}} + + YES 67239424 @@ -1159,7 +1170,7 @@ controlColor 3 - MC42NjY2NjY2ODY1AA + MC42NjY2NjY2NjY3AA @@ -1178,6 +1189,8 @@ 268 {{233, 103}, {34, 22}} + + YES 67239424 @@ -1192,9 +1205,12 @@ {345, 177} + + - {{0, 0}, {1440, 878}} - {3.40282e+38, 3.40282e+38} + {{0, 0}, {1680, 1028}} + {10000000000000, 10000000000000} + YES NSFontManager @@ -1206,6 +1222,22 @@ YES + + + terminate: + + + + 449 + + + + orderFrontStandardAboutPanel: + + + + 142 + performMiniaturize: @@ -1246,14 +1278,6 @@ 127 - - - orderFrontStandardAboutPanel: - - - - 142 - performClose: @@ -1502,46 +1526,6 @@ 374 - - - addFontTrait: - - - - 421 - - - - addFontTrait: - - - - 422 - - - - modifyFont: - - - - 423 - - - - orderFrontFontPanel: - - - - 424 - - - - modifyFont: - - - - 425 - raiseBaseline: @@ -1728,43 +1712,43 @@ - terminate: - - + addFontTrait: + + - 449 + 421 - - textColor: onColor - - - - - - textColor: onColor - textColor - onColor - 2 - + + addFontTrait: + + - 461 + 422 - - textColor: offColor - - - - - - textColor: offColor - textColor - offColor - 2 - + + modifyFont: + + - 462 + 423 + + + + orderFrontFontPanel: + + + + 424 + + + + modifyFont: + + + + 425 @@ -1776,19 +1760,51 @@ - sliderChanged: + smallSliderChanged: - + - 464 + 467 - smallSliderChanged: + sliderChanged: - + - 467 + 468 + + + + textColor: offColor + + + + + + textColor: offColor + textColor + offColor + 2 + + + 462 + + + + textColor: onColor + + + + + + textColor: onColor + textColor + onColor + 2 + + + 461 @@ -2742,145 +2758,74 @@ YES YES + -1.IBPluginDependency + -2.IBPluginDependency -3.IBPluginDependency 103.IBPluginDependency - 103.ImportedFromIB2 106.IBPluginDependency - 106.ImportedFromIB2 - 106.editorWindowContentRectSynchronizationRect 111.IBPluginDependency - 111.ImportedFromIB2 112.IBPluginDependency - 112.ImportedFromIB2 124.IBPluginDependency - 124.ImportedFromIB2 125.IBPluginDependency - 125.ImportedFromIB2 - 125.editorWindowContentRectSynchronizationRect 126.IBPluginDependency - 126.ImportedFromIB2 129.IBPluginDependency - 129.ImportedFromIB2 130.IBPluginDependency - 130.ImportedFromIB2 - 130.editorWindowContentRectSynchronizationRect 131.IBPluginDependency - 131.ImportedFromIB2 134.IBPluginDependency - 134.ImportedFromIB2 136.IBPluginDependency - 136.ImportedFromIB2 143.IBPluginDependency - 143.ImportedFromIB2 144.IBPluginDependency - 144.ImportedFromIB2 145.IBPluginDependency - 145.ImportedFromIB2 149.IBPluginDependency - 149.ImportedFromIB2 150.IBPluginDependency - 150.ImportedFromIB2 19.IBPluginDependency - 19.ImportedFromIB2 195.IBPluginDependency - 195.ImportedFromIB2 196.IBPluginDependency - 196.ImportedFromIB2 197.IBPluginDependency - 197.ImportedFromIB2 198.IBPluginDependency - 198.ImportedFromIB2 199.IBPluginDependency - 199.ImportedFromIB2 200.IBPluginDependency - 200.ImportedFromIB2 - 200.editorWindowContentRectSynchronizationRect 201.IBPluginDependency - 201.ImportedFromIB2 202.IBPluginDependency - 202.ImportedFromIB2 203.IBPluginDependency - 203.ImportedFromIB2 204.IBPluginDependency - 204.ImportedFromIB2 205.IBPluginDependency - 205.ImportedFromIB2 - 205.editorWindowContentRectSynchronizationRect 206.IBPluginDependency - 206.ImportedFromIB2 207.IBPluginDependency - 207.ImportedFromIB2 208.IBPluginDependency - 208.ImportedFromIB2 209.IBPluginDependency - 209.ImportedFromIB2 210.IBPluginDependency - 210.ImportedFromIB2 211.IBPluginDependency - 211.ImportedFromIB2 212.IBPluginDependency - 212.ImportedFromIB2 - 212.editorWindowContentRectSynchronizationRect 213.IBPluginDependency - 213.ImportedFromIB2 214.IBPluginDependency - 214.ImportedFromIB2 215.IBPluginDependency - 215.ImportedFromIB2 216.IBPluginDependency - 216.ImportedFromIB2 217.IBPluginDependency - 217.ImportedFromIB2 218.IBPluginDependency - 218.ImportedFromIB2 219.IBPluginDependency - 219.ImportedFromIB2 220.IBPluginDependency - 220.ImportedFromIB2 - 220.editorWindowContentRectSynchronizationRect 221.IBPluginDependency - 221.ImportedFromIB2 23.IBPluginDependency - 23.ImportedFromIB2 236.IBPluginDependency - 236.ImportedFromIB2 239.IBPluginDependency - 239.ImportedFromIB2 24.IBPluginDependency - 24.ImportedFromIB2 - 24.editorWindowContentRectSynchronizationRect - 29.IBEditorWindowLastContentRect 29.IBPluginDependency - 29.ImportedFromIB2 - 29.WindowOrigin - 29.editorWindowContentRectSynchronizationRect 295.IBPluginDependency 296.IBPluginDependency - 296.editorWindowContentRectSynchronizationRect 297.IBPluginDependency 298.IBPluginDependency 346.IBPluginDependency - 346.ImportedFromIB2 348.IBPluginDependency - 348.ImportedFromIB2 349.IBPluginDependency - 349.ImportedFromIB2 - 349.editorWindowContentRectSynchronizationRect 350.IBPluginDependency - 350.ImportedFromIB2 351.IBPluginDependency - 351.ImportedFromIB2 354.IBPluginDependency - 354.ImportedFromIB2 - 371.IBEditorWindowLastContentRect 371.IBPluginDependency 371.IBWindowTemplateEditedContentRect 371.NSWindowTemplate.visibleAtLaunch - 371.editorWindowContentRectSynchronizationRect - 371.windowTemplate.maxSize 372.IBPluginDependency 375.IBPluginDependency - 376.IBEditorWindowLastContentRect 376.IBPluginDependency 377.IBPluginDependency 378.IBPluginDependency @@ -2893,7 +2838,6 @@ 385.IBPluginDependency 386.IBPluginDependency 387.IBPluginDependency - 388.IBEditorWindowLastContentRect 388.IBPluginDependency 389.IBPluginDependency 390.IBPluginDependency @@ -2926,190 +2870,101 @@ 417.IBPluginDependency 418.IBPluginDependency 419.IBPluginDependency + 420.IBPluginDependency + 450.IBPluginDependency 451.IBPluginDependency - 451.IBViewBoundsToFrameTransform 452.IBPluginDependency 453.IBPluginDependency 454.IBPluginDependency 455.IBPluginDependency 465.IBPluginDependency 5.IBPluginDependency - 5.ImportedFromIB2 56.IBPluginDependency - 56.ImportedFromIB2 - 57.IBEditorWindowLastContentRect 57.IBPluginDependency - 57.ImportedFromIB2 - 57.editorWindowContentRectSynchronizationRect 58.IBPluginDependency - 58.ImportedFromIB2 72.IBPluginDependency - 72.ImportedFromIB2 73.IBPluginDependency - 73.ImportedFromIB2 74.IBPluginDependency - 74.ImportedFromIB2 75.IBPluginDependency - 75.ImportedFromIB2 77.IBPluginDependency - 77.ImportedFromIB2 78.IBPluginDependency - 78.ImportedFromIB2 79.IBPluginDependency - 79.ImportedFromIB2 80.IBPluginDependency - 80.ImportedFromIB2 81.IBPluginDependency - 81.ImportedFromIB2 - 81.editorWindowContentRectSynchronizationRect 82.IBPluginDependency - 82.ImportedFromIB2 83.IBPluginDependency - 83.ImportedFromIB2 92.IBPluginDependency - 92.ImportedFromIB2 - + YES com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{596, 852}, {216, 23}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{522, 812}, {146, 23}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{436, 809}, {64, 6}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {275, 83}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{187, 434}, {243, 243}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {167, 43}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {241, 103}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{525, 802}, {197, 73}} - {{384, 285}, {478, 20}} com.apple.InterfaceBuilder.CocoaPlugin - - {74, 862} - {{6, 978}, {478, 20}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{475, 832}, {234, 43}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {215, 63}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{517, 443}, {345, 177}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{517, 443}, {345, 177}} - {{33, 99}, {480, 360}} - {3.40282e+38, 3.40282e+38} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{437, 242}, {86, 43}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3122,7 +2977,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{523, 2}, {178, 283}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -3156,68 +3010,44 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - - AUMBAABCxgAAA - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{396, 102}, {242, 183}} com.apple.InterfaceBuilder.CocoaPlugin - - {{23, 794}, {245, 183}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{145, 474}, {199, 203}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin YES - - YES - + YES - - YES - + - 467 + 468 @@ -3232,7 +3062,7 @@ sliderChanged: smallSliderChanged: - + YES id id @@ -3245,7 +3075,7 @@ sliderChanged: smallSliderChanged: - + YES sliderChanged: @@ -3264,7 +3094,7 @@ sliderControl smallSliderControl - + YES TMSliderControl TMSliderControlSmall @@ -3277,7 +3107,7 @@ sliderControl smallSliderControl - + YES sliderControl @@ -3291,26 +3121,15 @@ IBProjectSource - AppController.h + ./Classes/AppController.h TMSliderControl NSControl - - target - id - - - target - - target - id - - IBProjectSource - TMSliderControl.h + ./Classes/TMSliderControl.h @@ -3318,600 +3137,7 @@ TMSliderControl IBProjectSource - TMSliderControlSmall.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSBrowser - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSBrowser.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSDocument - NSObject - - YES - - YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: - - - YES - id - id - id - id - id - id - - - - YES - - YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: - - - YES - - printDocument: - id - - - revertDocumentToSaved: - id - - - runPageLayout: - id - - - saveDocument: - id - - - saveDocumentAs: - id - - - saveDocumentTo: - id - - - - - IBFrameworkSource - AppKit.framework/Headers/NSDocument.h - - - - NSDocument - - IBFrameworkSource - AppKit.framework/Headers/NSDocumentScripting.h - - - - NSDocumentController - NSObject - - YES - - YES - clearRecentDocuments: - newDocument: - openDocument: - saveAllDocuments: - - - YES - id - id - id - id - - - - YES - - YES - clearRecentDocuments: - newDocument: - openDocument: - saveAllDocuments: - - - YES - - clearRecentDocuments: - id - - - newDocument: - id - - - openDocument: - id - - - saveAllDocuments: - id - - - - - IBFrameworkSource - AppKit.framework/Headers/NSDocumentController.h - - - - NSFontManager - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMatrix - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSMatrix.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMovieView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMovieView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSTableView - NSControl - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSTextView - NSText - - IBFrameworkSource - AppKit.framework/Headers/NSTextView.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h + ./Classes/TMSliderControlSmall.h @@ -3922,16 +3148,11 @@ com.apple.InterfaceBuilder.CocoaPlugin.macosx - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 YES - ../TMSliderControl.xcodeproj 3 YES @@ -3940,10 +3161,10 @@ NSMenuCheckmark NSMenuMixedState - + YES - {9, 8} - {7, 2} + {11, 11} + {10, 3} diff --git a/TMSliderControl.h b/TMSliderControl.h index 4615e03..78c76c2 100644 --- a/TMSliderControl.h +++ b/TMSliderControl.h @@ -18,23 +18,22 @@ typedef enum @class TMSliderControlHandle; @interface TMSliderControl : NSControl { - NSImage *sliderWell; - NSImage *overlayMask; - NSImage *sliderHandle; - NSImage *sliderHandleDown; - TMSliderControlHandle *sliderHandleView; + CALayer *sliderWell; + CALayer *overlayMask; + NSImage *sliderHandleImage; + NSImage *sliderHandleDownImage; + CALayer *sliderHandle; // drawing - NSRect handleControlRect; - NSRect handleControlRectOn; - NSRect handleControlRectOff; - NSPoint mouseDownPosition; + CGRect handleControlRectOn; + CGRect handleControlRectOff; + CGPoint mouseDownPosition; // state - TMSliderControlState controlState; BOOL hasDragged; - BOOL state; - + NSInteger state; + BOOL enabled; + id target; SEL action; } @@ -44,13 +43,18 @@ typedef enum - (void)mouseDragged:(NSEvent*)theEvent; - (void)mouseUp:(NSEvent*)theEvent; -- (BOOL)state; -- (void)setState:(BOOL)newState; +- (void)layoutHandle; + +@property (nonatomic, retain) CALayer *sliderWell; +@property (nonatomic, retain) CALayer *overlayMask; +@property (nonatomic, retain) NSImage *sliderHandleImage; +@property (nonatomic, retain) NSImage *sliderHandleDownImage; +@property (nonatomic, retain) CALayer *sliderHandle; -- (void)setTarget:(id)anObject; -- (id)target; -- (void)setAction:(SEL)aSelector; -- (SEL)action; +@property (nonatomic, assign) BOOL enabled; +@property (nonatomic, assign) NSInteger state; +@property (nonatomic, assign) id target; +@property (nonatomic, assign) SEL action; @end diff --git a/TMSliderControl.m b/TMSliderControl.m index f5d3084..76c4cd7 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -7,104 +7,98 @@ // #import "TMSliderControl.h" +#import -/* - * Basic NSImageView subclass for handle - */ - -@interface TMSliderControlHandle : NSImageView { -} -@end -@implementation TMSliderControlHandle -- (void)mouseDown:(NSEvent *)theEvent { [[self superview] mouseDown:theEvent]; } -- (void)mouseDragged:(NSEvent*)theEvent { [[self superview] mouseDragged:theEvent]; } -- (void)mouseUp:(NSEvent*)theEvent { [[self superview] mouseUp:theEvent]; } -@end - -/* - * Private control methods - */ - -@interface TMSliderControl (Private) -- (void)drawBacking; -- (void)drawOverlay; -- (void)drawHandle; -@end - -@implementation TMSliderControl (Private) - -- (void)drawBacking -{ - [sliderWell drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; -} +@implementation TMSliderControl +@synthesize state, enabled; +@synthesize sliderHandleImage, sliderHandleDownImage; +@synthesize sliderWell, sliderHandle, overlayMask; +@synthesize target, action; -- (void)drawOverlay ++ (void)initialize { - [overlayMask drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; + if (self != [TMSliderControl class]) + return; + + [NSObject exposeBinding:@"state"]; + [NSObject exposeBinding:@"enabled"]; } -- (void)drawHandle ++ (NSImage*)sliderHandleImage { - NSImage *sliderImage; - if (controlState == kTMSliderControlState_Active) - { - sliderImage = sliderHandleDown; - } - else - { - sliderImage = sliderHandle; - } - [sliderHandleView setImage: sliderImage]; + return [NSImage imageNamed:@"SliderHandle"]; } -- (void)layoutHandle ++ (NSImage*)sliderHandleDownImage { - handleControlRectOff = NSMakeRect(-2,1, 44, 27); - handleControlRectOn = NSMakeRect([self bounds].size.width - 42,1, 44, 27); - handleControlRect = handleControlRectOff; + return [NSImage imageNamed:@"SliderHandleDown"]; } -@end - -@implementation TMSliderControl - - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code here. - sliderWell = [[NSImage imageNamed:@"SliderWell"] retain]; - overlayMask = [[NSImage imageNamed:@"OverlayMask"] retain]; - sliderHandle = [[NSImage imageNamed:@"SliderHandle"] retain]; - sliderHandleDown = [[NSImage imageNamed:@"SliderHandleDown"] retain]; [self layoutHandle]; - sliderHandleView = [[TMSliderControlHandle alloc] initWithFrame: handleControlRectOff]; - [sliderHandleView setWantsLayer: YES]; - [self addSubview: sliderHandleView]; - state = NO; - //[self setWantsLayer:YES]; + + self.state = kTMSliderControlState_Inactive; + self.enabled = YES; + + self.sliderHandleImage = [[self class] sliderHandleImage]; + self.sliderHandleDownImage = [[self class] sliderHandleImage]; + + [self setLayer:[CALayer layer]]; + [self setWantsLayer:YES]; + + self.sliderWell = [CALayer layer]; + sliderWell.frame = NSRectToCGRect(self.bounds); + sliderWell.contents = [NSImage imageNamed:@"SliderWell"]; + [self.layer addSublayer:sliderWell]; + + self.sliderHandle = [CALayer layer]; + sliderHandle.frame = handleControlRectOff; + sliderHandle.contents = sliderHandleImage; + [sliderWell addSublayer:sliderHandle]; + + self.overlayMask = [CALayer layer]; + overlayMask.frame = NSRectToCGRect(self.bounds); + overlayMask.contents = [NSImage imageNamed:@"OverlayMask"]; + [self.layer addSublayer:overlayMask]; + + [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:&self]; + [self addObserver:self forKeyPath:@"enabled" options:NSKeyValueObservingOptionNew context:&self]; } return self; } - (void)dealloc { + [self removeObserver:self forKeyPath:@"state"]; + [self removeObserver:self forKeyPath:@"enabled"]; + [sliderWell release]; [overlayMask release]; [sliderHandle release]; - [sliderHandleDown release]; - [sliderHandleView release]; + [sliderHandleImage release]; + [sliderHandleDownImage release]; + [super dealloc]; } -- (void)awakeFromNib +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - [self setWantsLayer:YES]; -} - -- (void)drawRect:(NSRect)rect { - [self drawBacking]; - [self drawHandle]; - [self drawOverlay]; + if([keyPath isEqualToString:@"state"]) + { + CGFloat newXPosition = (self.state == kTMSliderControlState_Active ? CGRectGetMidX(handleControlRectOn) : CGRectGetMidX(handleControlRectOff)); + + CGPoint sliderPosition = sliderHandle.position; + sliderPosition.x = newXPosition; + + sliderHandle.position = sliderPosition; + } + else if([keyPath isEqualToString:@"enabled"]) + { + self.layer.opacity = (self.enabled ? 1.0 : 0.25); + } } - (BOOL)acceptsFirstResponder @@ -114,15 +108,20 @@ - (BOOL)acceptsFirstResponder - (void)mouseDown:(NSEvent*)theEvent { - NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - hasDragged = NO; - // down on the position control rect - if(NSPointInRect(mousePoint,handleControlRect)) - { - controlState = kTMSliderControlState_Active; - mouseDownPosition = NSMakePoint(mousePoint.x - handleControlRect.origin.x, 0); - [self setNeedsDisplay:YES]; - } + if(self.enabled) + { + CGPoint mousePoint = NSPointToCGPoint([self convertPoint:[theEvent locationInWindow] fromView:nil]); + hasDragged = NO; + // down on the position control rect + if(CGRectContainsPoint(sliderHandle.frame, mousePoint)) + { + mouseDownPosition = CGPointMake(mousePoint.x - sliderHandle.position.x, 0); + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + sliderHandle.contents = sliderHandleDownImage; + [CATransaction commit]; + } + } } @@ -131,124 +130,64 @@ - (void)mouseDragged:(NSEvent*)theEvent NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; hasDragged = YES; - // dragging the position control rect - if(controlState == kTMSliderControlState_Active) - { // center the rect around the mouse point float newXPosition = mousePoint.x - mouseDownPosition.x; // clamp the position . - if (newXPosition < handleControlRectOff.origin.x) - newXPosition = handleControlRectOff.origin.x; - if (newXPosition > handleControlRectOn.origin.x) - newXPosition = handleControlRectOn.origin.x; + if (newXPosition < CGRectGetMidX(handleControlRectOff)) + newXPosition = CGRectGetMidX(handleControlRectOff); + if (newXPosition > CGRectGetMidX(handleControlRectOn)) + newXPosition = CGRectGetMidX(handleControlRectOn); + + CGPoint sliderPosition = sliderHandle.position; + sliderPosition.x = newXPosition; - handleControlRect.origin.x = newXPosition; - [sliderHandleView setFrame: handleControlRect]; - [self setNeedsDisplay:YES]; - } + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + sliderHandle.position = sliderPosition; + [CATransaction commit]; } - (void)mouseUp:(NSEvent*)theEvent { - float minimumMovement = 10.0; - if(controlState != kTMSliderControlState_Inactive) - { - // switch the state to inactive and redraw - controlState = kTMSliderControlState_Inactive; - if (!hasDragged) - { - // if they never dragged, but clicked/released in place on the handle, flip it over. - [self setState:![self state]]; - } - else if (state == NSOffState) + if(self.enabled) + { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + sliderHandle.contents = sliderHandleImage; + [CATransaction commit]; + + float minimumMovement = 10.0; + if(hasDragged && state != kTMSliderControlState_Inactive) { - if (handleControlRect.origin.x > minimumMovement) + if (sliderHandle.frame.origin.x < [self bounds].size.width - sliderHandle.frame.size.width - minimumMovement) { // moved it enough to set it - [self setState: NSOnState]; + self.state = kTMSliderControlState_Inactive; } else { // put it back where it was. - [self setState: NSOffState]; + self.state = kTMSliderControlState_Active; } } else { - if (handleControlRect.origin.x < [self bounds].size.width - handleControlRect.size.width - minimumMovement) - { - // moved it enough to set it - [self setState: NSOffState]; - } - else - { - // put it back where it was. - [self setState: NSOnState]; - } + self.state = !self.state; } - - } - else - { - [self setState:![self state]]; - } -} - - -- (BOOL)state -{ - return state; -} - -- (void)setState:(NSInteger)newState -{ - [super setState:newState]; - if ([self state] == NSOffState) - { - handleControlRect = handleControlRectOff; - } - else - { - handleControlRect = handleControlRectOn; - } - - if ([sliderHandleView window]) - { - // It's in a window, we can use CoreAnimation - [NSAnimationContext beginGrouping]; - [[NSAnimationContext currentContext] setDuration: 0.15]; - [[sliderHandleView animator] setFrameOrigin: handleControlRect.origin]; - [NSAnimationContext endGrouping]; - } - else { - // It's not in a window, just set it. - [sliderHandleView setFrameOrigin:handleControlRect.origin]; + + if(target && [target respondsToSelector:action]) + [target performSelector:action withObject:self]; + hasDragged = NO; } - - [self sendAction:[self action] to:[self target]]; - [self setNeedsDisplay: YES]; } - -- (void)setTarget:(id)anObject -{ - target = anObject; -} -- (id)target -{ - return target; -} -- (void)setAction:(SEL)aSelector -{ - action = aSelector; -} -- (SEL)action +- (void)layoutHandle { - return action; + handleControlRectOff = CGRectMake(-2,1, 44, 27); + handleControlRectOn = CGRectMake([self bounds].size.width - handleControlRectOff.size.width + 2,1, 44, 27); } - @end diff --git a/TMSliderControl.xcodeproj/project.pbxproj b/TMSliderControl.xcodeproj/project.pbxproj index 892adad..29057f0 100644 --- a/TMSliderControl.xcodeproj/project.pbxproj +++ b/TMSliderControl.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; }; - 5F8F327712BE9303009B2446 /* TMSliderControlSmall.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8F327612BE9303009B2446 /* TMSliderControlSmall.m */; }; 5F8F327D12BE951C009B2446 /* SmallSliderHandle.png in Resources */ = {isa = PBXBuildFile; fileRef = 5F8F327912BE951C009B2446 /* SmallSliderHandle.png */; }; 5F8F327E12BE951C009B2446 /* SmallSliderHandleDown.png in Resources */ = {isa = PBXBuildFile; fileRef = 5F8F327A12BE951C009B2446 /* SmallSliderHandleDown.png */; }; 5F8F327F12BE951C009B2446 /* SmallSliderWellOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 5F8F327B12BE951C009B2446 /* SmallSliderWellOff.png */; }; @@ -22,6 +21,8 @@ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + 938A6C0F154F47A6007FC919 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 938A6C0E154F47A6007FC919 /* QuartzCore.framework */; }; + 938A6C10154F48A0007FC919 /* TMSliderControlSmall.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8F327612BE9303009B2446 /* TMSliderControlSmall.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -49,6 +50,7 @@ 5F9409290F3656C900317331 /* OverlayMask.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = OverlayMask.png; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8D1107320486CEB800E47090 /* TMSliderControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TMSliderControl.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 938A6C0E154F47A6007FC919 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = ../../../../../../../System/Library/Frameworks/QuartzCore.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,6 +58,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 938A6C0F154F47A6007FC919 /* QuartzCore.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -105,6 +108,7 @@ 29B97314FDCFA39411CA2CEA /* TMSliderControl */ = { isa = PBXGroup; children = ( + 938A6C0E154F47A6007FC919 /* QuartzCore.framework */, 19C28FACFE9D520D11CA2CBB /* Products */, 080E96DDFE201D6D7F000001 /* Classes */, 29B97315FDCFA39411CA2CEA /* Other Sources */, @@ -223,7 +227,7 @@ 8D11072D0486CEB800E47090 /* main.m in Sources */, 5F9409190F36563700317331 /* TMSliderControl.m in Sources */, 5F9409200F36566000317331 /* AppController.m in Sources */, - 5F8F327712BE9303009B2446 /* TMSliderControlSmall.m in Sources */, + 938A6C10154F48A0007FC919 /* TMSliderControlSmall.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -283,26 +287,28 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = macosx10.5; + SDKROOT = ""; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; PREBINDING = NO; - SDKROOT = macosx10.5; + SDKROOT = ""; }; name = Release; }; diff --git a/TMSliderControlSmall.m b/TMSliderControlSmall.m index 150e295..0181ff2 100644 --- a/TMSliderControlSmall.m +++ b/TMSliderControlSmall.m @@ -8,79 +8,43 @@ #import "TMSliderControlSmall.h" -@interface TMSliderControlSmall (Private) -- (void)drawBacking; -- (void)drawHandle; -@end - -@implementation TMSliderControlSmall (Private) +@implementation TMSliderControlSmall -- (void)drawBacking ++ (NSImage*)sliderHandleImage { - [sliderWellOff drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; - CGFloat percentOn = (handleControlRect.origin.x - handleControlRectOff.origin.x) / (handleControlRectOn.origin.x - handleControlRectOff.origin.x); - [sliderWellOn drawInRect:[self bounds] fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:percentOn]; + return [NSImage imageNamed:@"SmallSliderHandle"]; } - -- (void)drawHandle ++ (NSImage*)sliderHandleDownImage { - NSImage *sliderImage; - if (controlState == kTMSliderControlState_Active) - { - sliderImage = sliderHandleDown; - } - else - { - sliderImage = sliderHandle; - } - [sliderHandleView setImage: sliderImage]; + return [NSImage imageNamed:@"SmallSliderHandleDown"]; } -- (void)layoutHandle +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - handleControlRectOff = NSMakeRect(0,0, 27, 18); - handleControlRectOn = NSMakeRect([self bounds].size.width - 27, 0, 27, 18); - handleControlRect = handleControlRectOff; -} - -@end - -@implementation TMSliderControlSmall - -- (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - if (self) { - // Initialization code here. - sliderWellOn = [[NSImage imageNamed:@"SmallSliderWellOn"] retain]; - sliderWellOff = [[NSImage imageNamed:@"SmallSliderWellOff"] retain]; - - [sliderHandle release]; - sliderHandle = [[NSImage imageNamed:@"SmallSliderHandle"] retain]; - [sliderHandleDown release]; - sliderHandleDown = [[NSImage imageNamed:@"SmallSliderHandleDown"] retain]; - [self layoutHandle]; + if([keyPath isEqualToString:@"state"]) + { + sliderWell.contents = (self.state == kTMSliderControlState_Active ? [NSImage imageNamed:@"SmallSliderWellOn"] : [NSImage imageNamed:@"SmallSliderWellOff"]); } - return self; + [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } - (void)dealloc { [sliderWellOn release]; [sliderWellOff release]; - [sliderHandle release]; - [sliderHandleDown release]; [super dealloc]; } -- (void)drawRect:(NSRect)rect { - [self drawBacking]; - [self drawHandle]; -} - - (BOOL)isFlipped { return NO; } +- (void)layoutHandle +{ + handleControlRectOff = CGRectMake(0,0, 27, 18); + handleControlRectOn = CGRectMake([self bounds].size.width - 27, 0, 27, 18); +} + @end From f00d1dca14ba3d9b05c5a4e61f5becb051a0fdd4 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Tue, 15 May 2012 10:43:32 -0400 Subject: [PATCH 02/13] fixes broken pressed image state --- TMSliderControl.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TMSliderControl.m b/TMSliderControl.m index 76c4cd7..d3fad74 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -44,7 +44,7 @@ - (id)initWithFrame:(NSRect)frame { self.enabled = YES; self.sliderHandleImage = [[self class] sliderHandleImage]; - self.sliderHandleDownImage = [[self class] sliderHandleImage]; + self.sliderHandleDownImage = [[self class] sliderHandleDownImage]; [self setLayer:[CALayer layer]]; [self setWantsLayer:YES]; From 71b0aa6793e9c4b69abdc2f8286194d1452b86f7 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Tue, 15 May 2012 10:55:50 -0400 Subject: [PATCH 03/13] fixes the small variant, since we don't provide a mask for that one --- TMSliderControl.m | 7 ++++++- TMSliderControlSmall.m | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/TMSliderControl.m b/TMSliderControl.m index d3fad74..be8d989 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -34,6 +34,11 @@ + (NSImage*)sliderHandleDownImage return [NSImage imageNamed:@"SliderHandleDown"]; } ++ (NSImage*)overlayMask +{ + return [NSImage imageNamed:@"OverlayMask"]; +} + - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { @@ -61,7 +66,7 @@ - (id)initWithFrame:(NSRect)frame { self.overlayMask = [CALayer layer]; overlayMask.frame = NSRectToCGRect(self.bounds); - overlayMask.contents = [NSImage imageNamed:@"OverlayMask"]; + overlayMask.contents = [[self class] overlayMask]; [self.layer addSublayer:overlayMask]; [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:&self]; diff --git a/TMSliderControlSmall.m b/TMSliderControlSmall.m index 0181ff2..5cf5a78 100644 --- a/TMSliderControlSmall.m +++ b/TMSliderControlSmall.m @@ -20,6 +20,11 @@ + (NSImage*)sliderHandleDownImage return [NSImage imageNamed:@"SmallSliderHandleDown"]; } ++ (NSImage*)overlayMask +{ + return nil; +} + - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if([keyPath isEqualToString:@"state"]) From 815b2d10bab06fcfd1cf5523e26974fbdbad27e7 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Tue, 15 May 2012 14:31:54 -0400 Subject: [PATCH 04/13] changes to support arbitrary movement values so you can define shorter or longer minimum movement in order to flip state, and pushes the on/off well images to class methods --- TMSliderControl.m | 22 ++++++++++++++++++---- TMSliderControlSmall.m | 12 +++++++++++- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/TMSliderControl.m b/TMSliderControl.m index be8d989..a2d927f 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -24,6 +24,16 @@ + (void)initialize [NSObject exposeBinding:@"enabled"]; } ++ (NSImage*)sliderWellOn +{ + return [NSImage imageNamed:@"SliderWell"]; +} + ++ (NSImage*)sliderWellOff +{ + return [NSImage imageNamed:@"SliderWell"]; +} + + (NSImage*)sliderHandleImage { return [NSImage imageNamed:@"SliderHandle"]; @@ -40,8 +50,7 @@ + (NSImage*)overlayMask } - (id)initWithFrame:(NSRect)frame { - self = [super initWithFrame:frame]; - if (self) { + if ((self = [super initWithFrame:frame])) { // Initialization code here. [self layoutHandle]; @@ -56,7 +65,7 @@ - (id)initWithFrame:(NSRect)frame { self.sliderWell = [CALayer layer]; sliderWell.frame = NSRectToCGRect(self.bounds); - sliderWell.contents = [NSImage imageNamed:@"SliderWell"]; + sliderWell.contents = [[self class] sliderWellOff]; [self.layer addSublayer:sliderWell]; self.sliderHandle = [CALayer layer]; @@ -106,6 +115,11 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N } } +- (CGFloat)minimumMovement +{ + return 10.0f; +} + - (BOOL)acceptsFirstResponder { return YES; @@ -164,7 +178,7 @@ - (void)mouseUp:(NSEvent*)theEvent sliderHandle.contents = sliderHandleImage; [CATransaction commit]; - float minimumMovement = 10.0; + float minimumMovement = [self minimumMovement]; if(hasDragged && state != kTMSliderControlState_Inactive) { if (sliderHandle.frame.origin.x < [self bounds].size.width - sliderHandle.frame.size.width - minimumMovement) diff --git a/TMSliderControlSmall.m b/TMSliderControlSmall.m index 5cf5a78..78b6256 100644 --- a/TMSliderControlSmall.m +++ b/TMSliderControlSmall.m @@ -10,6 +10,16 @@ @implementation TMSliderControlSmall ++ (NSImage*)sliderWellOn +{ + return [NSImage imageNamed:@"SmallSliderWellOn"]; +} + ++ (NSImage*)sliderWellOff +{ + return [NSImage imageNamed:@"SmallSliderWellOff"]; +} + + (NSImage*)sliderHandleImage { return [NSImage imageNamed:@"SmallSliderHandle"]; @@ -29,7 +39,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N { if([keyPath isEqualToString:@"state"]) { - sliderWell.contents = (self.state == kTMSliderControlState_Active ? [NSImage imageNamed:@"SmallSliderWellOn"] : [NSImage imageNamed:@"SmallSliderWellOff"]); + sliderWell.contents = (self.state == kTMSliderControlState_Active ? [[self class] sliderWellOn] : [[self class] sliderWellOff]); } [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } From 0096885e2fdb88d23d58b30c6bf49ca4276a2897 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Fri, 18 May 2012 19:35:47 -0400 Subject: [PATCH 05/13] support bindings --- TMSliderControl.h | 18 +++++- TMSliderControl.m | 121 ++++++++++++++++++++++++++++++++++------- TMSliderControlSmall.m | 11 ++-- 3 files changed, 123 insertions(+), 27 deletions(-) diff --git a/TMSliderControl.h b/TMSliderControl.h index 78c76c2..bfcfaa7 100644 --- a/TMSliderControl.h +++ b/TMSliderControl.h @@ -31,13 +31,21 @@ typedef enum // state BOOL hasDragged; - NSInteger state; + BOOL state; BOOL enabled; id target; SEL action; + + id observedObjectForState; + NSString *observedKeyPathForState; + + id observedObjectForEnabled; + NSString *observedKeyPathForEnabled; } +- (void)updateUI; + // events - (void)mouseDown:(NSEvent*)theEvent; - (void)mouseDragged:(NSEvent*)theEvent; @@ -52,10 +60,16 @@ typedef enum @property (nonatomic, retain) CALayer *sliderHandle; @property (nonatomic, assign) BOOL enabled; -@property (nonatomic, assign) NSInteger state; +@property (nonatomic, assign) BOOL state; @property (nonatomic, assign) id target; @property (nonatomic, assign) SEL action; +@property (nonatomic, retain) id observedObjectForState; +@property (nonatomic, copy) NSString *observedKeyPathForState; + +@property (nonatomic, retain) id observedObjectForEnabled; +@property (nonatomic, copy) NSString *observedKeyPathForEnabled; + @end diff --git a/TMSliderControl.m b/TMSliderControl.m index a2d927f..5633186 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -9,21 +9,37 @@ #import "TMSliderControl.h" #import +static void *StateObservationContext = (void *)2091; +static void *EnabledObservationContext = (void *)2092; + @implementation TMSliderControl @synthesize state, enabled; @synthesize sliderHandleImage, sliderHandleDownImage; @synthesize sliderWell, sliderHandle, overlayMask; @synthesize target, action; +//bindings support +@synthesize observedObjectForState; +@synthesize observedKeyPathForState; +@synthesize observedObjectForEnabled; +@synthesize observedKeyPathForEnabled; + + + (void)initialize { if (self != [TMSliderControl class]) - return; + return; [NSObject exposeBinding:@"state"]; [NSObject exposeBinding:@"enabled"]; } +- (Class)valueClassForBinding:(NSString *)binding +{ + // both require numbers + return [NSNumber class]; +} + + (NSImage*)sliderWellOn { return [NSImage imageNamed:@"SliderWell"]; @@ -77,18 +93,15 @@ - (id)initWithFrame:(NSRect)frame { overlayMask.frame = NSRectToCGRect(self.bounds); overlayMask.contents = [[self class] overlayMask]; [self.layer addSublayer:overlayMask]; - - [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:&self]; - [self addObserver:self forKeyPath:@"enabled" options:NSKeyValueObservingOptionNew context:&self]; } return self; } - (void)dealloc -{ - [self removeObserver:self forKeyPath:@"state"]; - [self removeObserver:self forKeyPath:@"enabled"]; - +{ + [self unbind:@"state"]; + [self unbind:@"enabled"]; + [sliderWell release]; [overlayMask release]; [sliderHandle release]; @@ -98,21 +111,32 @@ - (void)dealloc [super dealloc]; } +- (void)updateUI +{ + CGFloat newXPosition = (self.state == kTMSliderControlState_Active ? CGRectGetMidX(handleControlRectOn) : CGRectGetMidX(handleControlRectOff)); + + CGPoint sliderPosition = sliderHandle.position; + sliderPosition.x = newXPosition; + + sliderHandle.position = sliderPosition; + self.layer.opacity = (self.enabled ? 1.0 : 0.25); +} + - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if([keyPath isEqualToString:@"state"]) + if(context == StateObservationContext) { - CGFloat newXPosition = (self.state == kTMSliderControlState_Active ? CGRectGetMidX(handleControlRectOn) : CGRectGetMidX(handleControlRectOff)); - - CGPoint sliderPosition = sliderHandle.position; - sliderPosition.x = newXPosition; - - sliderHandle.position = sliderPosition; + NSNumber *value = [observedObjectForState valueForKey:observedKeyPathForState]; + if(value) + [self setValue:value forKey:@"state"]; } - else if([keyPath isEqualToString:@"enabled"]) + if(context == EnabledObservationContext) { - self.layer.opacity = (self.enabled ? 1.0 : 0.25); + NSNumber *value = [observedObjectForEnabled valueForKey:observedKeyPathForEnabled]; + if(value) + [self setValue:value forKey:@"enabled"]; } + [self updateUI]; } - (CGFloat)minimumMovement @@ -185,18 +209,34 @@ - (void)mouseUp:(NSEvent*)theEvent { // moved it enough to set it self.state = kTMSliderControlState_Inactive; - } + if (observedObjectForState) + { + [observedObjectForState setValue: [NSNumber numberWithBool:state] + forKeyPath: observedKeyPathForState]; + } + } else { // put it back where it was. self.state = kTMSliderControlState_Active; + if (observedObjectForState) + { + [observedObjectForState setValue: [NSNumber numberWithBool:state] + forKeyPath: observedKeyPathForState]; + } } } else { self.state = !self.state; + if (observedObjectForState) + { + [observedObjectForState setValue: [NSNumber numberWithBool:state] + forKeyPath: observedKeyPathForState]; + } } - + [self updateUI]; + if(target && [target respondsToSelector:action]) [target performSelector:action withObject:self]; hasDragged = NO; @@ -209,4 +249,47 @@ - (void)layoutHandle handleControlRectOn = CGRectMake([self bounds].size.width - handleControlRectOff.size.width + 2,1, 44, 27); } +#pragma mark Bindings Support + +- (void)bind:(NSString *)binding toObject:(id)observable withKeyPath:(NSString *)keyPath options:(NSDictionary *)options +{ + if([binding isEqualToString:@"state"]) + { + [observable addObserver:self forKeyPath:keyPath options:0 context:StateObservationContext]; + + [self setObservedObjectForState:observable]; + [self setObservedKeyPathForState:keyPath]; + } + else if ([binding isEqualToString:@"enabled"]) + { + [observable addObserver:self forKeyPath:keyPath options:0 context:EnabledObservationContext]; + + [self setObservedObjectForEnabled:observable]; + [self setObservedKeyPathForEnabled:keyPath]; + } + + [super bind:binding toObject:observable withKeyPath:keyPath options:options]; + [self updateUI]; +} + +- (void)unbind:bindingName +{ + if ([bindingName isEqualToString:@"state"]) + { + [observedObjectForState removeObserver:self + forKeyPath:observedKeyPathForState]; + [self setObservedObjectForState:nil]; + [self setObservedKeyPathForState:nil]; + } + if ([bindingName isEqualToString:@"enabled"]) + { + [observedObjectForEnabled removeObserver:self + forKeyPath:observedKeyPathForEnabled]; + [self setObservedObjectForEnabled:nil]; + [self setObservedKeyPathForEnabled:nil]; + } + [super unbind:bindingName]; + [self updateUI]; +} + @end diff --git a/TMSliderControlSmall.m b/TMSliderControlSmall.m index 78b6256..1f1f822 100644 --- a/TMSliderControlSmall.m +++ b/TMSliderControlSmall.m @@ -35,13 +35,12 @@ + (NSImage*)overlayMask return nil; } -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +- (void)updateUI { - if([keyPath isEqualToString:@"state"]) - { - sliderWell.contents = (self.state == kTMSliderControlState_Active ? [[self class] sliderWellOn] : [[self class] sliderWellOff]); - } - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; + [super updateUI]; + + sliderWell.contents = (self.state == kTMSliderControlState_Active ? [[self class] sliderWellOn] : [[self class] sliderWellOff]); + } - (void)dealloc From e18e76e73c9de6f5966c01237532557f524db7cb Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Thu, 24 May 2012 15:08:34 -0400 Subject: [PATCH 06/13] expose the disabled state opacity to subclasses and fix it so that mouseDragged is ignored if the control is disabled --- TMSliderControl.h | 1 + TMSliderControl.m | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/TMSliderControl.h b/TMSliderControl.h index bfcfaa7..86eca7d 100644 --- a/TMSliderControl.h +++ b/TMSliderControl.h @@ -52,6 +52,7 @@ typedef enum - (void)mouseUp:(NSEvent*)theEvent; - (void)layoutHandle; +- (CGFloat)disabledOpacity; @property (nonatomic, retain) CALayer *sliderWell; @property (nonatomic, retain) CALayer *overlayMask; diff --git a/TMSliderControl.m b/TMSliderControl.m index 5633186..41cad96 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -119,7 +119,7 @@ - (void)updateUI sliderPosition.x = newXPosition; sliderHandle.position = sliderPosition; - self.layer.opacity = (self.enabled ? 1.0 : 0.25); + self.layer.opacity = (self.enabled ? 1.0 : [self disabledOpacity]); } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context @@ -170,9 +170,11 @@ - (void)mouseDown:(NSEvent*)theEvent - (void)mouseDragged:(NSEvent*)theEvent { - NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - hasDragged = YES; - + if(self.enabled) + { + NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + hasDragged = YES; + // center the rect around the mouse point float newXPosition = mousePoint.x - mouseDownPosition.x; @@ -190,6 +192,7 @@ - (void)mouseDragged:(NSEvent*)theEvent [CATransaction setDisableActions:YES]; sliderHandle.position = sliderPosition; [CATransaction commit]; + } } @@ -249,6 +252,11 @@ - (void)layoutHandle handleControlRectOn = CGRectMake([self bounds].size.width - handleControlRectOff.size.width + 2,1, 44, 27); } +- (CGFloat)disabledOpacity +{ + return 0.25; +} + #pragma mark Bindings Support - (void)bind:(NSString *)binding toObject:(id)observable withKeyPath:(NSString *)keyPath options:(NSDictionary *)options From dcc848e1a5074eac4cb265de7ef36f62a216dff8 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Sun, 29 Jul 2012 12:50:37 -0400 Subject: [PATCH 07/13] moveLeft and moveRight behaviors --- TMSliderControl.h | 3 +++ TMSliderControl.m | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/TMSliderControl.h b/TMSliderControl.h index 86eca7d..7c4a747 100644 --- a/TMSliderControl.h +++ b/TMSliderControl.h @@ -51,6 +51,9 @@ typedef enum - (void)mouseDragged:(NSEvent*)theEvent; - (void)mouseUp:(NSEvent*)theEvent; +- (IBAction)moveLeft:(id)sender; +- (IBAction)moveRight:(id)sender; + - (void)layoutHandle; - (CGFloat)disabledOpacity; diff --git a/TMSliderControl.m b/TMSliderControl.m index 41cad96..8e7e0ec 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -149,6 +149,11 @@ - (BOOL)acceptsFirstResponder return YES; } +- (BOOL)canBecomeKeyView +{ + return YES; +} + - (void)mouseDown:(NSEvent*)theEvent { if(self.enabled) @@ -252,6 +257,16 @@ - (void)layoutHandle handleControlRectOn = CGRectMake([self bounds].size.width - handleControlRectOff.size.width + 2,1, 44, 27); } +- (IBAction)moveLeft:(id)sender +{ + self.state = NO; +} + +- (IBAction)moveRight:(id)sender +{ + self.state = YES; +} + - (CGFloat)disabledOpacity { return 0.25; From fba5360ba12abb58d3434fce6e30d7264a4d10d1 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Wed, 22 Aug 2012 21:40:52 -0400 Subject: [PATCH 08/13] retina artwork for the slider control --- OverlayMask@2x.png | Bin 0 -> 1056 bytes SliderHandle@2x.png | Bin 0 -> 3229 bytes SliderHandleDown@2x.png | Bin 0 -> 3286 bytes SliderWell@2x.png | Bin 0 -> 13116 bytes SmallSliderHandle@2x.png | Bin 0 -> 1918 bytes SmallSliderHandleDown@2x.png | Bin 0 -> 1904 bytes SmallSliderWellOff@2x.png | Bin 0 -> 2299 bytes SmallSliderWellOn@2x.png | Bin 0 -> 3438 bytes TMSliderControl.xcodeproj/project.pbxproj | 32 ++++++++++++++++++++++ 9 files changed, 32 insertions(+) create mode 100644 OverlayMask@2x.png create mode 100644 SliderHandle@2x.png create mode 100644 SliderHandleDown@2x.png create mode 100644 SliderWell@2x.png create mode 100644 SmallSliderHandle@2x.png create mode 100644 SmallSliderHandleDown@2x.png create mode 100644 SmallSliderWellOff@2x.png create mode 100644 SmallSliderWellOn@2x.png diff --git a/OverlayMask@2x.png b/OverlayMask@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f28e42bf33de397ed7117e00f056a0e1a43b2e GIT binary patch literal 1056 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 P00000NkvXXu0mjfti4}v literal 0 HcmV?d00001 diff --git a/SliderHandleDown@2x.png b/SliderHandleDown@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..02b92b9d6973a29e933146c9e9fc8cdf283eb323 GIT binary patch literal 3286 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 literal 0 HcmV?d00001 diff --git a/SliderWell@2x.png b/SliderWell@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9ed0e66f337911285e1774a3235a9a815322dee6 GIT binary patch literal 13116 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 Ef(TZ=3IG5A literal 0 HcmV?d00001 diff --git a/SmallSliderHandleDown@2x.png b/SmallSliderHandleDown@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..47e740eab5fd9bc0cce2d76b6f184086e3e4c842 GIT binary patch literal 1904 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 VW;BWDhlv0H002ovPDHLkV1lC<&G7&L literal 0 HcmV?d00001 diff --git a/SmallSliderWellOn@2x.png b/SmallSliderWellOn@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..90c1f276f7e1a21e4a35c2ffc1f8599971ca430a GIT binary patch literal 3438 zcmV-!4UzJRP){lrB9wxqN`hEQp|(w;X_|I2nYs7)eQWLSoPE|lGk20qI@!rRYoEQ>T6_KP zea@X*w{2UgJ@M@yJ@LXnE-{afY! zanwD&u%u<@>joq{`|9lxb#TX9IqZ&KVGe_ zu2xNBQ@a}>1aL%NGHrpL1$^PiNFNfUOO}-Iaru&ez|h*FkNg9Ac^d@`7)z#0`2s-= z2XAd}SDTxg)%CY-)XzS5@sWC3ormKdt-toIA3yPn-@N$Kt@eR>ef?y$dgu@gIDt`E z-pGlc@m4B245_811Qt_y;R^fBZ(QpA8{Kbthx};Eh1sV<*3o%aE?=#h`mOe>U;M<^ zn-~6h^~tUIk$Uaqsp`-Z1x<8qWjW6mg!XqK?Y^*f4!vjCj7SZr5^XSb@g z`J{U5>Y}F4nwS6cHavEsI`+W(s_E=#HE9lGe`_q`n00wZ_~QMwg==d3BV<#bkWI9N zY()kJdSfG9i~twuO8T_cUip(n-tJc3oEQ6d%P-P*y1KcbFfe$aTWrC9H>+dE;kdWo ztzLQk#;Imwvzkt@x2+smgTId8a|nsX{SDd1B5O_%CyJXlSy?fX&yDpXzh(5x@b7kh zOvZdH^3UhkUnYOVkNlR2d^#w5FlmXIyVlcC;GH|i4|7uSpUrQ5t(?ID)|?-4CBOQjckVl1BmanLeD+y?R=&2L_`ptw7$5Wgl;V|}VJiqygGKvKjumJZf!m(z1TEek;Xo3gD&XejJBtoGn{{B_771ce3$GvgGSaCPPp2oo5pdfrHWCvl5y@Hxx+d2rnVyaNodL zQw~g-eHch@I$UiUQI29M!#t98tW7Y-azV)ErNhT~Pg;$Q&G+m0dY+G7J{_O&*RM{M zNaIkw9N+s~)0_0ziT@b>!RrqNk#)>CIE>HNb90=(Az=xdBJ-F9bRe5$P&!$TDehy# zE6u2;eh0zZc{+~z${5k*P_!HqXTkB2eAfHop)##)fa^{&{nRI9bNLW#%tUMAEtrNg zptU%peh2SRe-AwP1@vq!K*KIefR#y1@V%lGD-P!{??y?~DjPkO~bn?;y{7;ygbmp!4JuLZ=vg4Qf;wI5Ff2aD}V*#BG-%RjE za@t~-vlBluZDRWzARU)VrG)AQVHu?2E{dKO47#Sf?`dfdvJ(ysvs6)(E?J-WiQXXB zqgTW;&0CgmjMMlGN^A0Bx5tS#;TutQDdjsD{rMo?!VdJ2K?sK93C||(IHsb?rQ~-L z_#H^m;XdG{#7!gh=m>YJN`rU^(vUqiM}1FmK2G0{`Fu`6CwlpEsnpL)86|KUU3*x_ zyOdu}%l^UW&v3C2WP+iL*MN8&a3|0xbQ&Q&Yi5HDaBG3h`{jnCa&A;(5H6bOVA@|K zgF9mPJ%uu;u{w~(4pbN{>4hmMT0z%Ivwmvyt%GAKvxIC1rN222<~Vk@ z$5SN@=oy!sNkHfMtqY$y#>*ySp*Msfbr+8J8Q>>M&q|{BZ13t8dyNN*^Hb1dzUnx$ zLxalLyx0DzQaW7SFi1sA-k_;ZD1HukZ+c_up!Me-XW5R^q*X`w3ujD7hz|EP+vif> z1c!c#I^G98oiq*Gd_?FBlpJA5y`yNrytJh_85ClTjq&%u@qLH$LpL~uT*N!}Rh)UR zJ|UZMJBZHxp#Oqj1|#DvAmJY>il=UtNH3F&-eQlF79*N*Pqb2{l!%rit;R?nS}bku zMwt`Hf!^_bO|pumE3h}&grm7!ohX0g?`wz>P{avF`c7Bs%ogPL!T!2e{p*x*JXO+H z^ckMLS)TB=#0LEVoNrIO$?7{v!tp*QN^CES%CTsexJS8{Gk##mGNnBx;F3&Y>SniH{g+)GA4ZXV(gUtN z>dRgO2FZpTQ&ji|k`u-7EcBBJuQX2{lR8 zu$dydx1j+u%^nAUL!GHhkWfr$#?PN^z%h=Mul<$1#_Y^XQpGglv(XBa+eQ z?+^WP@~~6o0>0rF0+g!ZpO)~3Dd=xd{GdX?%SIB#r5nVu*zI7MYQ|3)8|kBC-Ka2@ zEZFhRW4>RnG&Kp`xLiwX6SDa;9-PfcwIaeuQn&wSmrL&kV;LuuNJjrz0S*+HEIHMb)^nPe^C z7o`u2+389Ggu{u-qB2-zJSAYZkar7w3`?Z~nFA&tFm}}E-ssPQ!3Xdbk8U%3A4j?I zMJlU0pUS!UIqVN79^L((Lfk&$gPlip%?GKLXgDrjyYcsZ&bhc*n0IQCV-`a|3Hc$S z4pJ83a8P|hw!O$F37lg0t8gX%Uiedgdvl^{$R)tQ|8&8e27_Rd&f}9g8*UUb84H?`0D<1Z`i3_`!K=270}_>tNCMmwM4J*Fj^JB) zcpex9KNyAkD-Foz$9adm=V-p?#Zp!V29+UUS`Q%iD|tGC_xir$b3G$Z(}lc@e*C+a z`g4D?2X7oqHsGTczuY-}a^-UK(bLnXFJ8I!v;SVdQ6FDBQ61qgteA257?e&ObfxT; zc&1$%D>Y5?iFkCLYiU09^$M$7Gj)h39vsrzgx16;!H6%kouGJk{KgQq2IlUu{tRFq z^7(VZTU+z$f7fqR&Ei^1pH2Vr=jZ&p!q+(O`PD6(LEiI*KWyL_*1;w$o*d*qk7q+L9Db>2Ymu+|gwA9La~#Pb zNPP7P`3d~A_Ce`Sown!O)%AC7R&Ts{wYvW1E7fBU%`g1qyI*;nf7e`n?$Px#_4M+e zF8u4#r(e5yx^D0zkY*J>w_;(U_qs*{DU8`g-xSVqI%F%m+B-QKsLg-2Z6<$qtP?wy z?VO&G$Ma44L2K9N*q-=1T6fjj-Ifjh8tae-ouI)z)Sm%7K_K0_xlzqGu2qYT*V;25 z-?;GEhu6ce>h4J>(4}bmmzpt!(=k;s#`!}{GQ~r$uZP;T7Gr^!onC*Qmzeap9 z-)TNFT!tU!!)*~bx63}_-!;Q!0>U?kXN&mi_@% literal 0 HcmV?d00001 diff --git a/TMSliderControl.xcodeproj/project.pbxproj b/TMSliderControl.xcodeproj/project.pbxproj index 29057f0..be9ffcc 100644 --- a/TMSliderControl.xcodeproj/project.pbxproj +++ b/TMSliderControl.xcodeproj/project.pbxproj @@ -23,6 +23,14 @@ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 938A6C0F154F47A6007FC919 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 938A6C0E154F47A6007FC919 /* QuartzCore.framework */; }; 938A6C10154F48A0007FC919 /* TMSliderControlSmall.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8F327612BE9303009B2446 /* TMSliderControlSmall.m */; }; + 93F216EE15E5BB7500343EB1 /* OverlayMask@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216E615E5BB7500343EB1 /* OverlayMask@2x.png */; }; + 93F216EF15E5BB7500343EB1 /* SliderHandle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216E715E5BB7500343EB1 /* SliderHandle@2x.png */; }; + 93F216F015E5BB7500343EB1 /* SliderHandleDown@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216E815E5BB7500343EB1 /* SliderHandleDown@2x.png */; }; + 93F216F115E5BB7500343EB1 /* SliderWell@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216E915E5BB7500343EB1 /* SliderWell@2x.png */; }; + 93F216F215E5BB7500343EB1 /* SmallSliderHandle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216EA15E5BB7500343EB1 /* SmallSliderHandle@2x.png */; }; + 93F216F315E5BB7500343EB1 /* SmallSliderHandleDown@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216EB15E5BB7500343EB1 /* SmallSliderHandleDown@2x.png */; }; + 93F216F415E5BB7500343EB1 /* SmallSliderWellOff@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216EC15E5BB7500343EB1 /* SmallSliderWellOff@2x.png */; }; + 93F216F515E5BB7500343EB1 /* SmallSliderWellOn@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 93F216ED15E5BB7500343EB1 /* SmallSliderWellOn@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -51,6 +59,14 @@ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8D1107320486CEB800E47090 /* TMSliderControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TMSliderControl.app; sourceTree = BUILT_PRODUCTS_DIR; }; 938A6C0E154F47A6007FC919 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = ../../../../../../../System/Library/Frameworks/QuartzCore.framework; sourceTree = ""; }; + 93F216E615E5BB7500343EB1 /* OverlayMask@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "OverlayMask@2x.png"; sourceTree = ""; }; + 93F216E715E5BB7500343EB1 /* SliderHandle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SliderHandle@2x.png"; sourceTree = ""; }; + 93F216E815E5BB7500343EB1 /* SliderHandleDown@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SliderHandleDown@2x.png"; sourceTree = ""; }; + 93F216E915E5BB7500343EB1 /* SliderWell@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SliderWell@2x.png"; sourceTree = ""; }; + 93F216EA15E5BB7500343EB1 /* SmallSliderHandle@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SmallSliderHandle@2x.png"; sourceTree = ""; }; + 93F216EB15E5BB7500343EB1 /* SmallSliderHandleDown@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SmallSliderHandleDown@2x.png"; sourceTree = ""; }; + 93F216EC15E5BB7500343EB1 /* SmallSliderWellOff@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SmallSliderWellOff@2x.png"; sourceTree = ""; }; + 93F216ED15E5BB7500343EB1 /* SmallSliderWellOn@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "SmallSliderWellOn@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -131,13 +147,21 @@ isa = PBXGroup; children = ( 5F8F327912BE951C009B2446 /* SmallSliderHandle.png */, + 93F216EA15E5BB7500343EB1 /* SmallSliderHandle@2x.png */, 5F8F327A12BE951C009B2446 /* SmallSliderHandleDown.png */, + 93F216EB15E5BB7500343EB1 /* SmallSliderHandleDown@2x.png */, 5F8F327B12BE951C009B2446 /* SmallSliderWellOff.png */, + 93F216EC15E5BB7500343EB1 /* SmallSliderWellOff@2x.png */, 5F8F327C12BE951C009B2446 /* SmallSliderWellOn.png */, + 93F216ED15E5BB7500343EB1 /* SmallSliderWellOn@2x.png */, 5F9409230F3656C900317331 /* SliderWell.png */, + 93F216E915E5BB7500343EB1 /* SliderWell@2x.png */, 5F9409240F3656C900317331 /* SliderHandleDown.png */, + 93F216E815E5BB7500343EB1 /* SliderHandleDown@2x.png */, 5F9409250F3656C900317331 /* SliderHandle.png */, + 93F216E715E5BB7500343EB1 /* SliderHandle@2x.png */, 5F9409290F3656C900317331 /* OverlayMask.png */, + 93F216E615E5BB7500343EB1 /* OverlayMask@2x.png */, 8D1107310486CEB800E47090 /* Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, 1DDD58140DA1D0A300B32029 /* MainMenu.xib */, @@ -214,6 +238,14 @@ 5F8F327E12BE951C009B2446 /* SmallSliderHandleDown.png in Resources */, 5F8F327F12BE951C009B2446 /* SmallSliderWellOff.png in Resources */, 5F8F328012BE951C009B2446 /* SmallSliderWellOn.png in Resources */, + 93F216EE15E5BB7500343EB1 /* OverlayMask@2x.png in Resources */, + 93F216EF15E5BB7500343EB1 /* SliderHandle@2x.png in Resources */, + 93F216F015E5BB7500343EB1 /* SliderHandleDown@2x.png in Resources */, + 93F216F115E5BB7500343EB1 /* SliderWell@2x.png in Resources */, + 93F216F215E5BB7500343EB1 /* SmallSliderHandle@2x.png in Resources */, + 93F216F315E5BB7500343EB1 /* SmallSliderHandleDown@2x.png in Resources */, + 93F216F415E5BB7500343EB1 /* SmallSliderWellOff@2x.png in Resources */, + 93F216F515E5BB7500343EB1 /* SmallSliderWellOn@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; From f73e4ad2d7ba9038b022f1510335507bd13b95bc Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Mon, 27 Aug 2012 12:14:26 -0400 Subject: [PATCH 09/13] updates to tmslider to mask the contents to the well, and updated retina art --- OverlayMask@2x.png | Bin 1056 -> 1587 bytes SliderHandle@2x.png | Bin 3229 -> 2711 bytes SliderHandleDown@2x.png | Bin 3286 -> 2716 bytes SliderWell@2x.png | Bin 13116 -> 9369 bytes SmallSliderHandle@2x.png | Bin 1918 -> 2631 bytes SmallSliderHandleDown@2x.png | Bin 1904 -> 2592 bytes SmallSliderWellOff@2x.png | Bin 2299 -> 2534 bytes SmallSliderWellOn@2x.png | Bin 3438 -> 3321 bytes TMSliderControl.m | 9 +++++++-- 9 files changed, 7 insertions(+), 2 deletions(-) diff --git a/OverlayMask@2x.png b/OverlayMask@2x.png index c8f28e42bf33de397ed7117e00f056a0e1a43b2e..20147474baffe128fda1d8402e55c6aa74e5f7eb 100644 GIT binary patch delta 1581 zcmaKs`#aMM7{JFesZPpeZpmdvaZrfbWC}4dm!X!+Lb>KvBQ@XiEh(8JxpbkZ+~)GQ z)MCwLa*1Uv*J{XIj!TX$j%@AZc6Ry$`aIA3KA-1(pZ9s6_m}tSR@#ocY9JH>fdJ(S zyC9G)df|3kL!Lm-ED-}D}j8TC@KNsI9;fn&5!JEl_J)OzE685-)< zT`+7;slXXtI?pxKn?_lsRcOeL&No!Lk*{09)}(BQq4G}FI={h!$it%7FR}Pk!%D0Z z`Aes~j=n&~d$K7Z$N&#^`U!uqkBlFgL(c__+8-r`*XOHw-@ac}Q_!n-FNX@xEp(*} z(1u)~Lsj!Q<198u!K6+3`}>7SP0CibAnWS}PK0Q^n*O;zP1o&pw6Z3kCf?!kZYZ+B zMX6PGRUA%-eg3v*Y0z?ubd~f2;ITqtf49L=oDN3rPM_g|ay7WM8D`zg4Kbw$5}~TB zoJsF!jYi#&ELwGT;Kkla)66*f!A*ISNAW9s{~M=QAD1$MU&*KOj6`0{G|Z>^l|4%? zb;Mc*HV~8%XZ{#Sl1|j}SgFVcNW3{mBC%SD2jj_*`(vrwT~{OG50dw&KJOPI7ap<@ zhd;%KD$q(mm1~PW;+NduFInX*eE3A*M4K~EnMcfz^O;QwrkgK7)N4PRgg(@R=pNtLgNifwbTud{{bQXl|8TB9X3~DHT?fAvs9)W`!2Ysk; zMwhr3n&o!3oUpV;nz2%DcCZ5v>beamTo}7@B=fKCls{jnv=|q8l%l(9V_V-oKaIf; zORZ@I(f9{6LKREuthkT(TV2{vZ98SQU5r908x8{dgx{Lo;=SM~ocr>cEwJyl$NS+$ z^&cQ7bK_Qior}>5!maP1g|9$STUIeF-fF;x8X1Y<@3iiLHHqH~n30jBwYYB?W9d=d zmUYox4eerX?Q`R`C{Jnh*{hWM&w7>;+T{`vnn(Sl29dul#7q$SMm$HJ7nlD1@AW=} zejA2m^KO7K*;lzyv{4aVPApd$8b?Q@sDbD*J-`q!THgm40H*6FDI`Lp?z*1;J!Y1P z%#o(WmM2Iqxt18HI7aag`w;o$kO3aoL!MTd$z5w+dtt3nr^F!c&7n@WEb-+;oE__$ zEvlq#vmG`kskGN{QrQB?<~Sr zC498(Q9dLcK-C0x?1c~QEou(4%ouGncBmW4;vjjw9XyG)Id=>3V; zzI*o?*rTgi570Ha0RC z3>u9_r_&|!_U&6Xo6Y0##>dBJXJ`3*{>;pbMCRt^BrXsLmY0`>LZL_`l7{Zhm#i}& zdE)R8DX6@vfw={E$ja8y74LJJaOO-vKxpihr2K-XFY6na%)Y_J#T7B$Lc3csGmo`D z<`u>hjJ%11N5$x5I%kGXNoU1rV z@VJu+1&A|PrQ>A>oR=fqlBtFnP$%Wi@Oa(ALF-$7ai9$_<*t8y?@^~7=tqYwZAC#D zSh(Rp$Ax6n&2!;Vjq_!XqJNP#vuyC1TA|!>98=@5cdE!dU^|E0F?CZ^cEylUfA+FR z^Rgc**%c&KYL?&s&eUO*k%{z61*0QLWZ*I<);Cyx6l7w|01UAD{S{)^>Ci(^sxv#R UMRjq;R&q83>wvSbIes?zKMh&)`Tzg` literal 1056 zcmeAS@N?(olHy`uVBq!ia0vp^yMWk&gAGV}l|52oU|@dk>Eakt!T5Hrq5thHk+%L` zPXR{OPH%w=f-9Zb!@m9N`IcVt>cYcw-}AquhrBv)plj7C?qtS^A}n1^9n3rKzwQ=% zdtuSMg?5*cPkK4koSFUH=3mJp)tdztYu;Q83!Un_Jb1Q`+SkW-@7`TpUdh#1CUoNS zon3d=eXZL2%kcCj`6jXc_^GLx>FMcZm6eg*cC*j&T$C4nR2j|b@#W{wpHW}x_UEr& zz53eA61hiq9d)IpshOqQFJ`2;2Hwfd$*J)OKfe3z+qZw)7gsVhP7|`QvAN?Ld}9Cd z<;(StKQ3IiGQ~jR#-m3`b1g2vSY$tM&K!>~TCtq>%gW2=FD*Yktxhe;@j*C?)$iZG z<1eRt@)xr8<}R~6^<>t`^XJdMp86;5lcN>)r2ky1@3+o$m?`$EG3Hu{()Onn>n6Gy zSI){`^?T}`v+_+j0u@4xJ9U;n-6pf%^}6h|uV26RzvNl-#Q)F~cQL!eA6!y@;WB9^f%0(V>cA8D`%*m^BL@lvVbgDUGG9#sl+(C!7XG#_5m0 zPG|f&TM``|eRwQtO3`sA3+o>}KTmzOD5eZg++UyoMKjCp(t=)k3|w@z)^ za{Kn}|E|~DGg8729zE)+yL(;Bs#UlCNuFe9JiY0R$xM$=Q>RX?YRpp+pI7CYZ{b-M zD_V6$@8wMef!2m){A=&sGVOh_@n+qRODoMwHn2>8vCC`AX2%6@SxhQ3@@4*23jO30 X)(cFr+7apw%=rwSu6{1-oD!Mct>ZdwO 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 S7x0q+4h%hG-P+quasL3V)-Hzt literal 3229 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 P00000NkvXXu0mjfti4}v diff --git a/SliderHandleDown@2x.png b/SliderHandleDown@2x.png index 02b92b9d6973a29e933146c9e9fc8cdf283eb323..26c8891dbb33fc4a8ad524304c3f3937a0451aca 100644 GIT binary patch literal 2716 zcmc)Li91w#1HkdI%-FY#v34=m5ZM{~Qkj%>h$aoWiBQ~z>tZZLS#G(~Cecfl;@ZM= zY0xN6hEVVV6}S%|WXul7tzw}kBSIg$mW+-%h)AeWQK zTko5ZzIXMik#0$hk5cN|YhXXxyZFmGz8^1gw@KEs)^r>CC5o#ZCZgq;qF>hIn!4g4 z%|``Qu!kk*az>lR-37*LmOYN=lLn3$66L-RuF{U?2$ROrK zJBm}}iF@~tN8;U~okBajh_{fhn=0%v3qk%G{wKKSM-oPQbnHCT9YpRA>#fSw3KJl< zgsCv2w;>n-h28?1-*x3ScvyZ@?SqithG<54v2TqJqzsGVILx5i0XxqtT0{Sl%AV2R zLUm+2d}-mRu-zLl^{vQ|R4^}Zdo-CpLDie{`T-6*LqCnd)Iw(6={8GpW!Z$Dn< zU18HxAJh4{F~Gr>%(tt0xruo~`KoMrgXL5aQ`nt|AWDKoe~U)Q>5buZxtj#fI1~)w z;kB{rh||sT9wf7rwg>X|?>uX8*XL+>4jY@H*JRa%WW(buNA0U3BOREMwtbLyyur1O z$VlvN?B+dcZgh`D!}U-2F5XmqaeeC!ykpzvSb{F}^v?Nw<%mofl z`%E{!tXTPxKCGclbm+D3A8n-#SMQhYzrOwo^Gbev*5+Dtg@t>3ZQUuaDw)nh_rsX0O66Ok{>b$mVgk{09_AMO%%-`FZQKwB}t z6jUv=vza1W1LAu}+ZC{)P1nw~Bpv@Is9+|g1u2Gn`Go4usKLSlDK82teJpxEO>s1; z;x9g5e4LYjD9O=r%VyVaP%u#+?q7EQ)&7R+ar0&v@BPM+txl$f9bXW$@fJx z%k2^kUpAh5QuNk>n!Rdu=D>*NJvOUMMX_b4GxEE{G_d|t*fhRXlMwmXzL!X>*?tk z7#ILsva_=v{FI-cPaqK5f9mY){P5vJcXv05L>eC-pO}~!85yBaC_Ozry@1cXpAY-o z*9X+sN9qF(BMp!S0D}XAfT6)5!0^y8U}P9LcMLE-_P?PfCMPBjo1C1Q`~o0?aS1?QqSNUN z1`va>!dL;UuB-x>tIWfgYinyP77&ZYX0ZX^*xvvf-!?WjI2<4jmkY$@ZgIB`+uGjV zR$Y&b0A42&>*L|eFCYkp2nmabiit}|O3BE|!Q>Sbl~j)YqNWblGPkmEbwB6f=@oeC z*DGPy5)u-UaH*-OX+PDz=_CRVI1Sv&`uY~{hn1KP2qeHlx;mi(KD0cg&v7a#qguC6jrnGtSx+|{6-HO>Pw^Wumwk5H51 zSo4N{X5pC8=j9)ZnocFGP?g}b$*SrLYZZ^K9Mh67lXgCn0hRatvydgE8J@U3`n}w! zSQAx7!>swTo%>K(7j;cG1kMUqs9R69e;~BCa8d{ZO}6xlP`B7vx0iz(K@)j21!($t z!IPmGT6zZ!tCdSB^_FfMXJgV)D!RFhQp#S+GjLLF>@fK)Zw_5j{)eHoy5_GVD+4dk zNW;~9RAcR_s?&b=Via7toslp<4YLb@i99=`>7a~OhH*S+d{Rxn^yQC;Th&9f6Qxpc zF@2VORm6q#*ZjX5^~8qdq0z|_Hi1n0Y&ombA>f(RN~0z5SNd|_IxKC>pWYeSXdM4> z>V5OoYfN7w?_=lF718$3LxlvVt7ZH(TFA{eoI18fvHY-v5<)dmy1MASvTO{N-SD5d z{$M7@MLPI4kzU@}SPW|T=(w}wg7@ej#NL52!~|9Sa-TPMM1+<`I7Z{Y9*7fr?gX0_ z_sh7bK_!{42@nOe=8AQc#fwwpE1Z>) zYvc=i+!ws`cWoj=F}x@XvVyS$1Fd z_27JZbKCj!Xmgg-iDI9guw(9tFxwPK;uA!9#p6;%o2A=T5;0HkS)u-=3$X&p-J<)- zi;Le7f|wxTd*(#JXOFt@_ffOmMgsjy;_0N4b^DSu@(R~5n!HQ)8RRJ6DeLU8Cacy5 zp~a6U&EQ!LrgpcTcEiObHNfjulR0=Uk(tG^o&GydbS38Iod1&_B{!?boCW0q_WF0E zQpBY!Km0q@b;jf7*tvJxjaAp93N>=7XjzVSo2S%@F72QEHYJ{Tc5 zfP}PK$roP$VZr)CMuJ_Kh54RwJX!g6M@46Lbo{*wEoWes`a%jncJ|wWqlh` z=W-XpkPE4YtpD8lFRXuTefh+R6GsmpKFmQF?C$RFiR8Jtxn^f)r$N%BBY%`eT2i&? zO;|nlgQV5!84L!HySuWovhn=+^KVUu)YsPkZT-L2Gh%}u8InJwLKM65fOU2#I~Q_4 zwSID8Vd3b_n>T-d@#4kb9Y212X>k#LKisylvC+JI`EvdC?c0C5diCmGx3;$63R1qY z4zcWT^#SBUC=S}SM@;{v^#_uVDGf(}|qerhUUApw8$)^_f#QMLizp?(kb$0j$WkM`Fmm|S-_L%kG*v|dc z!-o(5aOTYEV{2>c&Bn%hV@Ipm-rgCKV}2i4V`I!U2M#PWi;GLm($Z4%`0?XcXV0Gf zqjB?3BjfMZUs>n+{MP!qzeJ#OncxlW;~O__Ts(E^)UlP7@0-=t)n;>Z)5zUUJ5IaK z{Kj@58i1Zx13^YJ2vh>a`+bGqko+Du|>UG-q;xtW7xg(^YcdXdb7N|+`tiB zUAc1QPv#4EkPDaTW&nkYGaUnCcJW8&&!7J-#J+p?u0yWPr6z({AeRm#ZD*%F{gJem zaBOLq4hWi$7b)08 zZsJw%d@NriFP%Jj@~FL;E&H8I5{{mi=rl>MW0PHSFY|-B7AHxsXME+UNuLuvHgIXe zm!6FF!kTHi?kW!?^M(gUa0O@PrrTJ85-@C|_&#s9VoMw$0JNjbCpD2JDfbh<3$Xb=V^g3|=oToq%EKVV~_ zq|}0?Bi~OGDWFN0+;0Xrf-9g)9fExuu8N&Yuuc&+8d7s~WvVe6HQwJKXjTTc_|yu)LBJMXT`9L>uo3@Vfk_m5P-l z&g&6J^++avtJ60hFI_Sc$_B#bHlTp%J;8Dq#AGUp80knF z#mL53y5_O@7XAGkdW@gdf6nex!9c2s48|f)(%aDc@|Wg`%bX24#76T3w-)!RA|#ng z@4CkA@ZFcAm;SZb@|AROL)FjK3YJflLlCFP2a|Nk625E>qN6HSMn8`0Palp&s{)*? z5)7#C6h*_9u0#2>#I9ZAaHm#d!R$6&=Kx9g`7|zp##21{_svJll7CurW&PXsYX^UZ zM7)Uv<1CVWAT~AWlCn!;XVJC!G-vmsNHt&ZGz%uq<9mI0cIA>2w&^~H@_HPP;dSp5 zb&n&xO0XORE-AYtc2A)64q@(qC{9wiUJ3&rbdk*1`!S};hAv+uEn)cssJ$VXyt*$Q zPr78+bCfUIHLemYKuHCZr1z078U3+G0%eo0kCiSdpGngDN|%gr*!${rzZD@*`;ksVC!q%1jg{WW+m__N0NdZbJCVc`eKwN@pVK=oQMb{#<_Q9|T2P1iz6 zV!S>L#wp*gFuYMR~h)%^_*gU%OE<`54K=W@?&qmk6f4|IpVIEku&Jj-Igx>$t%U@Ph-iU=cO0F@KIRg z0v+>dt^O`VHvD5g#*plglHTTZ%~Ow$kM;N% zulsn#FyGgz1lIzUNHY4#F3G&t<5+WErc*ZWjJU(RpK{CQv1NgKW)q1nmdk_tA7ZYFB87bQa-K z?b=^7ksJBm>T&qPW!2WN4Om%xmEcrt;pm7+NiC{^-)q*v(E&@hZFazP+on2dK&nGB z`43sCMeW_LJd!%VHN=?-jzDq8#re1cqkp^)CSJuyEXFau4?oUF%s#y6KkK+kFon@+ zDzXF~-{ng_!V#92QSV)_m6Q%ZK4qorpeUDQ#Ah5^$yc^mPmE>#{E0)YRS8x=Brqma zA(C-kIMd2fKH0#CJDz;9F;5+;fw6RCsl^XAytT-Nzj7mK5s!RYdvXXbRe}i;sFDyn zmwtKOO2*VJTRT7gzqHtEtyD0+zUY!JTa@7WdgDA}@l zA-q%xmY;&Va`az7R&Q#Ou^{2pWEWRhT4i|$c>*J@=8!aziBwZgjVDR@cI9aOb91e( zd=aZiFwW`#)2A)4TS!bdehNpAK0>GqA1x^QkL9;xrR#Lc1v{vCne4I7c z39Jl?1bg3jO0W^wt!_hj_o?(r1!_*R1nB3aOXA4?yWbuU0kibB= z{3LyB0{V$x;Aav?GZP$7almCOuQi_25G>n>=o*2-)+Ht8>zgmvG_uYbU-BQJjcZkc zn~s`Fal^!38N%Vw^qbPf7ygvidT$$ywsfHM4swZZr#?!e9^xT&*%17 z8Nb6J^Pb>gtT`t~lBM4XbKT6Fj#D|k$z($xfm*m^^zS3UFG9LVQNhA4jWs8!SfubK z$#&`W_49j(j4g6iMv{@>F(-Y_N752O?tgtFL1{jJ7)Sx(MGLLTNWjea+~3+N((e;e z!CB8Mi+G{Dc73k?Y1SVwIvheUhOsUJv|xeAUX%D~PI|-;7BU_X#ZD`QjieFhZ{ws7 z?^0}Den_2-!})g0+G{>#%}2HPxRl4`Oi%?LO9XGfe*JoVYirYafs<1{B5di!oP)<~M(|dB#IVsxX*B(F{kOM59ex<{irQ`RO zoz1FC1V%l`y#D0LlW$j7*S=d`KKO~*4UEe}&XC6AN7pZkm|9a|@)wy%HO(=WE-4>L z?83k%eLr}tb(Bx~czxvHF2Wwx{0`16y-0@36aaG!L@wWPz@wmRckkZ)nuqN4L?a1{ z-L84bj`VuP->_ZrBfW@S!SKFgcwB?YF=ag-3q8eV>GkLbxp1?#zSi8kckgTS<@+Mw zE`3jg$;2y&)rZ0F-@pHbJ;C_dp+kq#^SNyji{J{CH!&LzT^kS|?IJw;ntYM87~eM^ z@uPp7kN9yujy+zh8*@CmwY`-dGk*H?A5YJnJNISnVQ`*Iq_dN~KCrF7{NTZZ7Z&_8 zd#d~xh0)+a&(M*Gq>|_yRZ0Bz+l7Vny3VYK?|slmwU%q~{`gK)KTmhQefzd~_U!qS z%anHuk1ywrUEB;a8>0Wr_@RIpAMtsr(=MGa z@7%fb)wOHazOtRmwHI=~vCbueuQ3qGo0JV>>|Tf#$s*c+rOd(8r%!)!b%7 diff --git a/SliderWell@2x.png b/SliderWell@2x.png index 9ed0e66f337911285e1774a3235a9a815322dee6..89001be29c473df51dac4f7cbba6a3f70dfe552d 100644 GIT binary patch literal 9369 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 TX09b800000NkvXXu0mjfJL+r_ literal 13116 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 KVcxHfcmEBKOi#%G delta 1914 zcmV-=2Zi{@6#fp78Gi-<006>U$xQ$N2SrIlK~z`?&6&Gy6n7NHcXr2X)>xJxLW(FT z!li&Gpi1%psX`az5|p$NGyx)v(jcWxK}mxYktTV9JOHEtnjl4r5K@9562h##_U`8U zotba^XFRiOE{QnS&N*`~-#O=ho7r_XolZMYmSx?q&Yk@;Nc9fY%r7rCHm={id2>ByroKFX{^Iu5)|tUz zuyl5H^@CHVPA#vjtTZ+Q;QK_+pFf{IxPSk}kGF0;eK{PSSy@_Q0bR|s{65u8eZP?B z2fn#-<;cN<2g`N$K9xVemS@kNO}<-O`*XCl^^dmG*MGg!r%zuPZEl|U;_TT&A00h9 z0D|SIR$`5u-oG6_>QM8dXW98`Z=BpX=$O~ z@6mBIrhodoIt~~mDAR$43^%!H->2NRl)D)GEW?|KS-|F5wru|tm-wi&oMC$CFD~|k zyf4>A65uFautf*{>}L& z<4N=YkaA{uJfpM(nJt>4kd!=I)eMrDu_zPQM}Lr5>r%N%SJ=50&6QHYl*5$9#y~4K z9HI{I$8syhbCjhRB@*n90nObM_Y?gE7*8FD{ES6e2Ll66eSmO0795M#HjocJ=%jV57JF}wj*=o1&K@N+mg^(t1oP|# z>dtkZf8EZ^p!1fooaCqAPH}iB4;!#;#vDXBmdyl_U0QrWs$`G4@i z&Pzue9$I=?%ogp{W(@FIVKf2{4EDw*Y8#@Z4 zM?4Ljm9Sn|#Hq$A-f~iRWfQRTd1+PqyY%O1V>S7RBi1>o%d#!tk}cneh!}i1BUGwhf;l{-01WW@;ekFL zl4YZo;~@cNja-yD<|f%XxQoZvG8{_%;=X)X$Ci3^H$G7qKP9=;q- z7Zw)utwpn@zmzHvDGiY7Qs2GEX>5IlnwDlAGmS@fV;dVA+9A`iR^3ZpsUFIBh*S$BE`Rm|2hM(QGwzfKtA3y$E6F5?%4|Dxc`jdV^ zJ$>iSo&NIj^5)Xg(to06uGoa-@=J@YHww6Qso(!0lbetJmDCvyhnwnQJ@5C2y1%Uk zJKf8dFMq3!Ki3ovPM$ouc<9if!z@b*ep_{{{8$K{Mo&G_Xg7apShi0Z%I4&#QkN zyy6e8YTlO5NZV&aP5r#SzJ8sas<(O>yO%Cq`lR3QGjqokM1wrV16lX6JlUu`5+KX) zCc@7?P5$%jb<8Gzl{eIOdZ;|N*Vfj4r77b61!-P_27Y3es{jB107*qoM6N<$f?oN= AzyJUM diff --git a/SmallSliderHandleDown@2x.png b/SmallSliderHandleDown@2x.png index 47e740eab5fd9bc0cce2d76b6f184086e3e4c842..372695b465e1da9edb18cd1d06d7e461db895b8a 100644 GIT binary patch literal 2592 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 diff --git a/SmallSliderWellOn@2x.png b/SmallSliderWellOn@2x.png index 90c1f276f7e1a21e4a35c2ffc1f8599971ca430a..debc9feb495b7511002932f95d63dc4342193114 100644 GIT binary patch delta 3318 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 A!vFvP delta 3436 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 Date: Thu, 10 Jan 2013 21:32:02 -0500 Subject: [PATCH 10/13] resolve warnings about float vs CGFLoat --- TMSliderControl.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TMSliderControl.m b/TMSliderControl.m index c663126..021094f 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -187,7 +187,7 @@ - (void)mouseDragged:(NSEvent*)theEvent // center the rect around the mouse point - float newXPosition = mousePoint.x - mouseDownPosition.x; + CGFloat newXPosition = mousePoint.x - mouseDownPosition.x; // clamp the position . if (newXPosition < CGRectGetMidX(handleControlRectOff)) @@ -215,7 +215,7 @@ - (void)mouseUp:(NSEvent*)theEvent sliderHandle.contents = sliderHandleImage; [CATransaction commit]; - float minimumMovement = [self minimumMovement]; + CGFloat minimumMovement = [self minimumMovement]; if(hasDragged && state != kTMSliderControlState_Inactive) { if (sliderHandle.frame.origin.x < [self bounds].size.width - sliderHandle.frame.size.width - minimumMovement) From bcd0038aa62cdc09fa8b5cadc9ad89341cc9a08c Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Thu, 17 Oct 2013 19:35:27 -0400 Subject: [PATCH 11/13] making the slider control slightly more accessible. --- TMSliderControl.h | 14 +-- TMSliderControl.m | 222 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 189 insertions(+), 47 deletions(-) diff --git a/TMSliderControl.h b/TMSliderControl.h index 7c4a747..12c4a6c 100644 --- a/TMSliderControl.h +++ b/TMSliderControl.h @@ -17,12 +17,7 @@ typedef enum @class TMSliderControlHandle; -@interface TMSliderControl : NSControl { - CALayer *sliderWell; - CALayer *overlayMask; - NSImage *sliderHandleImage; - NSImage *sliderHandleDownImage; - CALayer *sliderHandle; +@interface TMSliderControl : NSView { // drawing CGRect handleControlRectOn; @@ -31,11 +26,6 @@ typedef enum // state BOOL hasDragged; - BOOL state; - BOOL enabled; - - id target; - SEL action; id observedObjectForState; NSString *observedKeyPathForState; @@ -74,6 +64,8 @@ typedef enum @property (nonatomic, retain) id observedObjectForEnabled; @property (nonatomic, copy) NSString *observedKeyPathForEnabled; +@property (nonatomic, retain) NSString *purposeDescription; + @end diff --git a/TMSliderControl.m b/TMSliderControl.m index 021094f..2c0e9a5 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -13,10 +13,6 @@ static void *EnabledObservationContext = (void *)2092; @implementation TMSliderControl -@synthesize state, enabled; -@synthesize sliderHandleImage, sliderHandleDownImage; -@synthesize sliderWell, sliderHandle, overlayMask; -@synthesize target, action; //bindings support @synthesize observedObjectForState; @@ -84,20 +80,20 @@ - (id)initWithFrame:(NSRect)frame { mask.contents = [[self class] sliderWellOff]; self.sliderWell = [CALayer layer]; - sliderWell.frame = self.bounds; - sliderWell.contents = [[self class] sliderWellOff]; - sliderWell.mask = mask; - [self.layer addSublayer:sliderWell]; + _sliderWell.frame = self.bounds; + _sliderWell.contents = [[self class] sliderWellOff]; + _sliderWell.mask = mask; + [self.layer addSublayer:_sliderWell]; self.sliderHandle = [CALayer layer]; - sliderHandle.frame = handleControlRectOff; - sliderHandle.contents = sliderHandleImage; - [sliderWell addSublayer:sliderHandle]; + _sliderHandle.frame = handleControlRectOff; + _sliderHandle.contents = _sliderHandleImage; + [_sliderWell addSublayer:_sliderHandle]; self.overlayMask = [CALayer layer]; - overlayMask.frame = self.bounds; - overlayMask.contents = [[self class] overlayMask]; - [self.layer addSublayer:overlayMask]; + _overlayMask.frame = self.bounds; + _overlayMask.contents = [[self class] overlayMask]; + [self.layer addSublayer:_overlayMask]; } return self; } @@ -107,12 +103,14 @@ - (void)dealloc [self unbind:@"state"]; [self unbind:@"enabled"]; - [sliderWell release]; - [overlayMask release]; - [sliderHandle release]; - [sliderHandleImage release]; - [sliderHandleDownImage release]; + [_sliderWell release]; + [_overlayMask release]; + [_sliderHandle release]; + [_sliderHandleImage release]; + [_sliderHandleDownImage release]; + [_purposeDescription release]; + [super dealloc]; } @@ -120,10 +118,10 @@ - (void)updateUI { CGFloat newXPosition = (self.state == kTMSliderControlState_Active ? CGRectGetMidX(handleControlRectOn) : CGRectGetMidX(handleControlRectOff)); - CGPoint sliderPosition = sliderHandle.position; + CGPoint sliderPosition = _sliderHandle.position; sliderPosition.x = newXPosition; - sliderHandle.position = sliderPosition; + _sliderHandle.position = sliderPosition; self.layer.opacity = (self.enabled ? 1.0 : [self disabledOpacity]); } @@ -151,12 +149,22 @@ - (CGFloat)minimumMovement - (BOOL)acceptsFirstResponder { - return YES; + return [NSApp isFullKeyboardAccessEnabled]; } - (BOOL)canBecomeKeyView { - return YES; + return [NSApp isFullKeyboardAccessEnabled]; +} + +- (NSRect)focusRingMaskBounds +{ + return [self bounds]; +} + +- (void)drawFocusRingMask +{ + [self.layer renderInContext:[[NSGraphicsContext currentContext] graphicsPort]]; } - (void)mouseDown:(NSEvent*)theEvent @@ -166,12 +174,12 @@ - (void)mouseDown:(NSEvent*)theEvent CGPoint mousePoint = NSPointToCGPoint([self convertPoint:[theEvent locationInWindow] fromView:nil]); hasDragged = NO; // down on the position control rect - if(CGRectContainsPoint(sliderHandle.frame, mousePoint)) + if(CGRectContainsPoint(_sliderHandle.frame, mousePoint)) { - mouseDownPosition = CGPointMake(mousePoint.x - sliderHandle.position.x, 0); + mouseDownPosition = CGPointMake(mousePoint.x - _sliderHandle.position.x, 0); [CATransaction begin]; [CATransaction setDisableActions:YES]; - sliderHandle.contents = sliderHandleDownImage; + _sliderHandle.contents = _sliderHandleDownImage; [CATransaction commit]; } } @@ -195,12 +203,12 @@ - (void)mouseDragged:(NSEvent*)theEvent if (newXPosition > CGRectGetMidX(handleControlRectOn)) newXPosition = CGRectGetMidX(handleControlRectOn); - CGPoint sliderPosition = sliderHandle.position; + CGPoint sliderPosition = _sliderHandle.position; sliderPosition.x = newXPosition; [CATransaction begin]; [CATransaction setDisableActions:YES]; - sliderHandle.position = sliderPosition; + _sliderHandle.position = sliderPosition; [CATransaction commit]; } } @@ -212,19 +220,19 @@ - (void)mouseUp:(NSEvent*)theEvent { [CATransaction begin]; [CATransaction setDisableActions:YES]; - sliderHandle.contents = sliderHandleImage; + _sliderHandle.contents = _sliderHandleImage; [CATransaction commit]; CGFloat minimumMovement = [self minimumMovement]; - if(hasDragged && state != kTMSliderControlState_Inactive) + if(hasDragged && _state != kTMSliderControlState_Inactive) { - if (sliderHandle.frame.origin.x < [self bounds].size.width - sliderHandle.frame.size.width - minimumMovement) + if (_sliderHandle.frame.origin.x < [self bounds].size.width - _sliderHandle.frame.size.width - minimumMovement) { // moved it enough to set it self.state = kTMSliderControlState_Inactive; if (observedObjectForState) { - [observedObjectForState setValue: [NSNumber numberWithBool:state] + [observedObjectForState setValue: [NSNumber numberWithBool:_state] forKeyPath: observedKeyPathForState]; } } @@ -234,7 +242,7 @@ - (void)mouseUp:(NSEvent*)theEvent self.state = kTMSliderControlState_Active; if (observedObjectForState) { - [observedObjectForState setValue: [NSNumber numberWithBool:state] + [observedObjectForState setValue: [NSNumber numberWithBool:_state] forKeyPath: observedKeyPathForState]; } } @@ -244,14 +252,14 @@ - (void)mouseUp:(NSEvent*)theEvent self.state = !self.state; if (observedObjectForState) { - [observedObjectForState setValue: [NSNumber numberWithBool:state] + [observedObjectForState setValue: [NSNumber numberWithBool:_state] forKeyPath: observedKeyPathForState]; } } [self updateUI]; - if(target && [target respondsToSelector:action]) - [target performSelector:action withObject:self]; + if(_target && [_target respondsToSelector:_action]) + [_target performSelector:_action withObject:self]; hasDragged = NO; } } @@ -277,6 +285,11 @@ - (CGFloat)disabledOpacity return 0.25; } +- (void)drawRect:(NSRect)dirtyRect +{ + [super drawRect:[self bounds]]; +} + #pragma mark Bindings Support - (void)bind:(NSString *)binding toObject:(id)observable withKeyPath:(NSString *)keyPath options:(NSDictionary *)options @@ -320,4 +333,141 @@ - (void)unbind:bindingName [self updateUI]; } +#pragma mark - + +- (void)setState:(BOOL)state +{ + if (_state != state) + { + _state = state; + NSAccessibilityPostNotification(self, NSAccessibilityValueChangedNotification); + } +} + +#pragma mark - Accessibility + +- (BOOL)accessibilityIsIgnored +{ + return NO; +} + +- (NSArray *)accessibilityAttributeNames +{ + static NSArray *attributes = nil; + if (attributes == nil) + { + NSMutableArray *mutableAttributes = [[super accessibilityAttributeNames] mutableCopy]; + if (mutableAttributes == nil) + mutableAttributes = [NSMutableArray new]; + + // Add attributes + if (![mutableAttributes containsObject:NSAccessibilityValueAttribute]) + [mutableAttributes addObject:NSAccessibilityValueAttribute]; + + if (![mutableAttributes containsObject:NSAccessibilityValueDescriptionAttribute]) + [mutableAttributes addObject:NSAccessibilityValueDescriptionAttribute]; + + if (![mutableAttributes containsObject:NSAccessibilityEnabledAttribute]) + [mutableAttributes addObject:NSAccessibilityEnabledAttribute]; + + if (![mutableAttributes containsObject:NSAccessibilityDescriptionAttribute]) + [mutableAttributes addObject:NSAccessibilityDescriptionAttribute]; + + // Remove attributes + if ([mutableAttributes containsObject:NSAccessibilityChildrenAttribute]) + [mutableAttributes removeObject:NSAccessibilityChildrenAttribute]; + + attributes = [mutableAttributes copy]; + [mutableAttributes release]; + } + return attributes; +} + +- (id)accessibilityAttributeValue:(NSString *)attribute +{ + id retVal = nil; + if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) + retVal = NSAccessibilityCheckBoxRole; + else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) + retVal = [NSString stringWithFormat:@"%@ %@", self.purposeDescription, NSLocalizedString(@"switch", @"") ]; + else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) + retVal = [NSNumber numberWithInt:self.state]; + else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) + retVal = [NSNumber numberWithBool:self.enabled]; + else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) + retVal = NSLocalizedString(@"toggle", @""); + else if ([attribute isEqualToString:NSAccessibilityValueDescriptionAttribute]) + retVal = self.state ? NSLocalizedString(@"on", @"") : NSLocalizedString(@"off", @""); + else + retVal = [super accessibilityAttributeValue:attribute]; + return retVal; +} + +- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute +{ + BOOL retVal; + if ([attribute isEqualToString:NSAccessibilityValueAttribute]) + retVal = YES; + else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) + retVal = YES; + else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) + retVal = NO; + else + retVal = [super accessibilityIsAttributeSettable:attribute]; + return retVal; +} + +- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute +{ + if ([attribute isEqualToString:NSAccessibilityValueAttribute]) + { + self.state = [value boolValue]; + [self updateUI]; + } + else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) + { + self.enabled = [value boolValue]; + [self updateUI]; + } + else + [super accessibilitySetValue:value forAttribute:attribute]; +} + +- (NSArray *)accessibilityActionNames +{ + static NSArray *actions = nil; + if (actions == nil) + { + NSMutableArray *mutableActions = [[super accessibilityActionNames] mutableCopy]; + if (mutableActions == nil) + mutableActions = [NSMutableArray new]; + if (![mutableActions containsObject:NSAccessibilityPressAction]) + [mutableActions addObject:NSAccessibilityPressAction]; + actions = [mutableActions copy]; + [mutableActions release]; + } + return actions; +} + +- (NSString *)accessibilityActionDescription:(NSString *)actionString +{ + id retVal = nil; + if ([actionString isEqualToString:NSAccessibilityPressAction]) + retVal = self.state ? NSLocalizedString(@"turn off", @"") : NSLocalizedString(@"turn on", @""); + else + retVal = [super accessibilityActionDescription:actionString]; + return retVal; +} + +- (void)accessibilityPerformAction:(NSString *)actionString +{ + if ([actionString isEqualToString:NSAccessibilityPressAction]) + { + self.state = !self.state; + [self updateUI]; + } + else + [super accessibilityPerformAction:actionString]; +} + @end From 1235ab14b68fe1f982e8445aeff0570376fbf9a4 Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Sun, 2 Aug 2015 22:06:51 -0400 Subject: [PATCH 12/13] modernization and arc --- TMSliderControl.h | 24 ++++++++++++------------ TMSliderControl.m | 21 ++++++--------------- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/TMSliderControl.h b/TMSliderControl.h index 12c4a6c..5805260 100644 --- a/TMSliderControl.h +++ b/TMSliderControl.h @@ -8,12 +8,12 @@ #import -typedef enum +typedef NS_ENUM(unsigned int, TMSliderControlState) { kTMSliderControlState_Inactive = 0, kTMSliderControlState_Active = 1 -}TMSliderControlState; +}; @class TMSliderControlHandle; @@ -45,26 +45,26 @@ typedef enum - (IBAction)moveRight:(id)sender; - (void)layoutHandle; -- (CGFloat)disabledOpacity; +@property (nonatomic, readonly) CGFloat disabledOpacity; -@property (nonatomic, retain) CALayer *sliderWell; -@property (nonatomic, retain) CALayer *overlayMask; -@property (nonatomic, retain) NSImage *sliderHandleImage; -@property (nonatomic, retain) NSImage *sliderHandleDownImage; -@property (nonatomic, retain) CALayer *sliderHandle; +@property (nonatomic, strong) CALayer *sliderWell; +@property (nonatomic, strong) CALayer *overlayMask; +@property (nonatomic, strong) NSImage *sliderHandleImage; +@property (nonatomic, strong) NSImage *sliderHandleDownImage; +@property (nonatomic, strong) CALayer *sliderHandle; @property (nonatomic, assign) BOOL enabled; @property (nonatomic, assign) BOOL state; -@property (nonatomic, assign) id target; +@property (nonatomic, unsafe_unretained) id target; @property (nonatomic, assign) SEL action; -@property (nonatomic, retain) id observedObjectForState; +@property (nonatomic, strong) id observedObjectForState; @property (nonatomic, copy) NSString *observedKeyPathForState; -@property (nonatomic, retain) id observedObjectForEnabled; +@property (nonatomic, strong) id observedObjectForEnabled; @property (nonatomic, copy) NSString *observedKeyPathForEnabled; -@property (nonatomic, retain) NSString *purposeDescription; +@property (nonatomic, strong) NSString *purposeDescription; @end diff --git a/TMSliderControl.m b/TMSliderControl.m index 2c0e9a5..7eb98f4 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -61,7 +61,7 @@ + (NSImage*)overlayMask return [NSImage imageNamed:@"OverlayMask"]; } -- (id)initWithFrame:(NSRect)frame { +- (instancetype)initWithFrame:(NSRect)frame { if ((self = [super initWithFrame:frame])) { // Initialization code here. [self layoutHandle]; @@ -103,15 +103,8 @@ - (void)dealloc [self unbind:@"state"]; [self unbind:@"enabled"]; - [_sliderWell release]; - [_overlayMask release]; - [_sliderHandle release]; - [_sliderHandleImage release]; - [_sliderHandleDownImage release]; - [_purposeDescription release]; - [super dealloc]; } - (void)updateUI @@ -232,7 +225,7 @@ - (void)mouseUp:(NSEvent*)theEvent self.state = kTMSliderControlState_Inactive; if (observedObjectForState) { - [observedObjectForState setValue: [NSNumber numberWithBool:_state] + [observedObjectForState setValue: @(_state) forKeyPath: observedKeyPathForState]; } } @@ -242,7 +235,7 @@ - (void)mouseUp:(NSEvent*)theEvent self.state = kTMSliderControlState_Active; if (observedObjectForState) { - [observedObjectForState setValue: [NSNumber numberWithBool:_state] + [observedObjectForState setValue: @(_state) forKeyPath: observedKeyPathForState]; } } @@ -252,7 +245,7 @@ - (void)mouseUp:(NSEvent*)theEvent self.state = !self.state; if (observedObjectForState) { - [observedObjectForState setValue: [NSNumber numberWithBool:_state] + [observedObjectForState setValue: @(_state) forKeyPath: observedKeyPathForState]; } } @@ -378,7 +371,6 @@ - (NSArray *)accessibilityAttributeNames [mutableAttributes removeObject:NSAccessibilityChildrenAttribute]; attributes = [mutableAttributes copy]; - [mutableAttributes release]; } return attributes; } @@ -391,9 +383,9 @@ - (id)accessibilityAttributeValue:(NSString *)attribute else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) retVal = [NSString stringWithFormat:@"%@ %@", self.purposeDescription, NSLocalizedString(@"switch", @"") ]; else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) - retVal = [NSNumber numberWithInt:self.state]; + retVal = @(self.state); else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) - retVal = [NSNumber numberWithBool:self.enabled]; + retVal = @(self.enabled); else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) retVal = NSLocalizedString(@"toggle", @""); else if ([attribute isEqualToString:NSAccessibilityValueDescriptionAttribute]) @@ -444,7 +436,6 @@ - (NSArray *)accessibilityActionNames if (![mutableActions containsObject:NSAccessibilityPressAction]) [mutableActions addObject:NSAccessibilityPressAction]; actions = [mutableActions copy]; - [mutableActions release]; } return actions; } From 0ddcd93e87e462f79758220dc4ceecbb4f85579b Mon Sep 17 00:00:00 2001 From: Rudy Richter Date: Sat, 24 Oct 2015 19:32:44 -0400 Subject: [PATCH 13/13] warnings and accessibility standards --- TMSliderControl.h | 1 + TMSliderControl.m | 131 ++++++---------------------------------------- 2 files changed, 16 insertions(+), 116 deletions(-) diff --git a/TMSliderControl.h b/TMSliderControl.h index 5805260..2015771 100644 --- a/TMSliderControl.h +++ b/TMSliderControl.h @@ -65,6 +65,7 @@ typedef NS_ENUM(unsigned int, TMSliderControlState) @property (nonatomic, copy) NSString *observedKeyPathForEnabled; @property (nonatomic, strong) NSString *purposeDescription; +@property (nonatomic, strong) NSString *accessibilityText; @end diff --git a/TMSliderControl.m b/TMSliderControl.m index 7eb98f4..42608cd 100644 --- a/TMSliderControl.m +++ b/TMSliderControl.m @@ -115,7 +115,7 @@ - (void)updateUI sliderPosition.x = newXPosition; _sliderHandle.position = sliderPosition; - self.layer.opacity = (self.enabled ? 1.0 : [self disabledOpacity]); + self.layer.opacity = (float)(self.enabled ? 1.0f : [self disabledOpacity]); } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context @@ -289,14 +289,14 @@ - (void)bind:(NSString *)binding toObject:(id)observable withKeyPath:(NSString * { if([binding isEqualToString:@"state"]) { - [observable addObserver:self forKeyPath:keyPath options:0 context:StateObservationContext]; + [observable addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:StateObservationContext]; [self setObservedObjectForState:observable]; [self setObservedKeyPathForState:keyPath]; } else if ([binding isEqualToString:@"enabled"]) { - [observable addObserver:self forKeyPath:keyPath options:0 context:EnabledObservationContext]; + [observable addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:EnabledObservationContext]; [self setObservedObjectForEnabled:observable]; [self setObservedKeyPathForEnabled:keyPath]; @@ -339,126 +339,25 @@ - (void)setState:(BOOL)state #pragma mark - Accessibility -- (BOOL)accessibilityIsIgnored +- (id)accessibilityValue { - return NO; + return [NSNumber numberWithBool:self.state]; } -- (NSArray *)accessibilityAttributeNames +- (id)accessibilityLabel { - static NSArray *attributes = nil; - if (attributes == nil) - { - NSMutableArray *mutableAttributes = [[super accessibilityAttributeNames] mutableCopy]; - if (mutableAttributes == nil) - mutableAttributes = [NSMutableArray new]; - - // Add attributes - if (![mutableAttributes containsObject:NSAccessibilityValueAttribute]) - [mutableAttributes addObject:NSAccessibilityValueAttribute]; - - if (![mutableAttributes containsObject:NSAccessibilityValueDescriptionAttribute]) - [mutableAttributes addObject:NSAccessibilityValueDescriptionAttribute]; - - if (![mutableAttributes containsObject:NSAccessibilityEnabledAttribute]) - [mutableAttributes addObject:NSAccessibilityEnabledAttribute]; - - if (![mutableAttributes containsObject:NSAccessibilityDescriptionAttribute]) - [mutableAttributes addObject:NSAccessibilityDescriptionAttribute]; - - // Remove attributes - if ([mutableAttributes containsObject:NSAccessibilityChildrenAttribute]) - [mutableAttributes removeObject:NSAccessibilityChildrenAttribute]; - - attributes = [mutableAttributes copy]; - } - return attributes; -} - -- (id)accessibilityAttributeValue:(NSString *)attribute -{ - id retVal = nil; - if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) - retVal = NSAccessibilityCheckBoxRole; - else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) - retVal = [NSString stringWithFormat:@"%@ %@", self.purposeDescription, NSLocalizedString(@"switch", @"") ]; - else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) - retVal = @(self.state); - else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) - retVal = @(self.enabled); - else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) - retVal = NSLocalizedString(@"toggle", @""); - else if ([attribute isEqualToString:NSAccessibilityValueDescriptionAttribute]) - retVal = self.state ? NSLocalizedString(@"on", @"") : NSLocalizedString(@"off", @""); - else - retVal = [super accessibilityAttributeValue:attribute]; - return retVal; -} - -- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute -{ - BOOL retVal; - if ([attribute isEqualToString:NSAccessibilityValueAttribute]) - retVal = YES; - else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) - retVal = YES; - else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) - retVal = NO; - else - retVal = [super accessibilityIsAttributeSettable:attribute]; - return retVal; -} - -- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute -{ - if ([attribute isEqualToString:NSAccessibilityValueAttribute]) - { - self.state = [value boolValue]; - [self updateUI]; - } - else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) - { - self.enabled = [value boolValue]; - [self updateUI]; - } - else - [super accessibilitySetValue:value forAttribute:attribute]; -} - -- (NSArray *)accessibilityActionNames -{ - static NSArray *actions = nil; - if (actions == nil) - { - NSMutableArray *mutableActions = [[super accessibilityActionNames] mutableCopy]; - if (mutableActions == nil) - mutableActions = [NSMutableArray new]; - if (![mutableActions containsObject:NSAccessibilityPressAction]) - [mutableActions addObject:NSAccessibilityPressAction]; - actions = [mutableActions copy]; - } - return actions; -} - -- (NSString *)accessibilityActionDescription:(NSString *)actionString -{ - id retVal = nil; - if ([actionString isEqualToString:NSAccessibilityPressAction]) - retVal = self.state ? NSLocalizedString(@"turn off", @"") : NSLocalizedString(@"turn on", @""); - else - retVal = [super accessibilityActionDescription:actionString]; - return retVal; + if (self.accessibilityText) { + return self.accessibilityText; + } + + return NSLocalizedStringWithDefaultValue(@"LOCALIZED_SWITCH_LABEL", @"Localizable", [NSBundle mainBundle], @"switch", @"switch label when no accessibility text is set");; } -- (void)accessibilityPerformAction:(NSString *)actionString +- (BOOL)accessibilityPerformPress { - if ([actionString isEqualToString:NSAccessibilityPressAction]) - { - self.state = !self.state; - [self updateUI]; - } - else - [super accessibilityPerformAction:actionString]; + self.state = !self.state; + [self updateUI]; + return YES; } @end