Fixed up position slider and time display.

CQTexperiment
vspader 2009-02-22 14:28:09 -08:00
parent c522a69499
commit a1f6139ea4
16 changed files with 499 additions and 161 deletions

16
Application/MiniWindow.h Normal file
View File

@ -0,0 +1,16 @@
//
// MiniWindow.h
// Cog
//
// Created by Vincent Spader on 2/22/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "DualWindow.h"
@interface MiniWindow : DualWindow {
}
@end

44
Application/MiniWindow.m Normal file
View File

@ -0,0 +1,44 @@
//
// MiniWindow.m
// Cog
//
// Created by Vincent Spader on 2/22/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "MiniWindow.h"
@implementation MiniWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
{
self = [super initWithContentRect:contentRect styleMask:windowStyle backing:bufferingType defer:deferCreation];
if (self)
{
[self setShowsResizeIndicator:NO];
[self setExcludedFromWindowsMenu:YES];
[self setContentBorderThickness:24.0 forEdge:NSMinYEdge];
}
return self;
}
- (void)awakeFromNib
{
if ([self hiddenDefaultsKey]) {
// Hide the mini window by default.
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:[self hiddenDefaultsKey]]];
}
[super awakeFromNib];
}
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize {
// Do not allow height to change
proposedFrameSize.height = [self frame].size.height;
return proposedFrameSize;
}
@end

View File

@ -19,9 +19,7 @@
IBOutlet PlaylistController *playlistController;
IBOutlet PlaylistView *playlistView;
IBOutlet TrackingSlider *positionSlider;
IBOutlet NSSlider *volumeSlider;
IBOutlet NSTextField *timeField;
IBOutlet NSSegmentedControl *playbackButtons;
@ -32,10 +30,13 @@
AudioPlayer *audioPlayer;
int playbackStatus;
double position;
BOOL seekable;
BOOL showTimeRemaining;
AudioScrobbler *scrobbler;
}
@property int playbackStatus;
@ -69,9 +70,15 @@
- (void)audioFadeDown:(NSTimer *)audioTimer;
- (void)audioFadeUp:(NSTimer *)audioTimer;
- (void)updateTimeField:(double)pos;
- (void)playEntryAtIndex:(int)i;
- (void)playEntry:(PlaylistEntry *)pe;
// For bindings
- (void)setPosition:(double)p;
- (double)position;
- (void)setSeekable:(BOOL)s;
- (BOOL)seekable;
@end

View File

@ -13,6 +13,11 @@
@synthesize playbackStatus;
+ (NSSet *)keyPathsForValuesAffectingSeekable
{
return [NSSet setWithObjects:@"playlistController.currentEntry",@"playlistController.currentEntry.seekable",nil];
}
- (id)init
{
self = [super init];
@ -60,8 +65,8 @@
[volumeSlider setDoubleValue:logarithmicToLinear(100.0)];
[audioPlayer setVolume: 100];
[positionSlider setEnabled:NO];
[self setSeekable:NO];
}
- (IBAction)playPauseResume:(id)sender
@ -158,8 +163,7 @@
NSLog(@"PLAYLIST CONTROLLER: %@", [playlistController class]);
[playlistController setCurrentEntry:pe];
[positionSlider setDoubleValue:0.0];
[self updateTimeField:0.0f];
[self setPosition:0.0];
if (pe == nil)
return;
@ -195,15 +199,19 @@
[self playEntry:[playlistController currentEntry]];
}
- (void)updatePosition:(id)sender
{
double pos = [audioPlayer amountPlayed];
[self setPosition:pos];
}
- (IBAction)seek:(id)sender
{
double time;
time = [positionSlider doubleValue];
double time = [sender doubleValue];
if ([sender tracking] == NO) // check if user stopped sliding before playing audio
[audioPlayer seekToTime:time];
[audioPlayer seekToTime:time];
[self updateTimeField:time];
}
- (IBAction)eventSeekForward:(id)sender
@ -215,15 +223,14 @@
{
double seekTo = [audioPlayer amountPlayed] + amount;
if (seekTo > (int)[positionSlider maxValue])
if (seekTo > [[[playlistController currentEntry] length] doubleValue])
{
[self next:self];
}
else
{
[audioPlayer seekToTime:seekTo];
[self updateTimeField:seekTo];
[positionSlider setDoubleValue:seekTo];
[self setPosition:seekTo];
}
}
@ -240,8 +247,7 @@
seekTo = 0;
[audioPlayer seekToTime:seekTo];
[self updateTimeField:seekTo];
[positionSlider setDoubleValue:seekTo];
[self setPosition:seekTo];
}
- (void)changePlayButtonImage:(NSString *)name
@ -459,7 +465,7 @@
}
/*
- (void)updateTimeField:(double)pos
{
NSString *text;
@ -470,19 +476,19 @@
}
else
{
int sec = (int)(([positionSlider maxValue] - pos));
int sec = (int)(([[[playlistController currentEntry] length] doubleValue] - pos));
if (sec < 0)
sec = 0;
text = [NSString stringWithFormat:NSLocalizedString(@"TimeRemaining", @""), sec/60, sec%60];
}
[timeField setStringValue:text];
}
*/
- (IBAction)toggleShowTimeRemaining:(id)sender
{
showTimeRemaining = !showTimeRemaining;
[self updateTimeField:[positionSlider doubleValue]];
// [self updateTimeField:position];
}
- (void)audioPlayer:(AudioPlayer *)player requestNextStream:(id)userInfo
@ -504,10 +510,8 @@
[playlistController setCurrentEntry:pe];
[positionSlider setDoubleValue:0.0f];
[self setPosition:0];
[self updateTimeField:0.0f];
if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) {
[scrobbler start:pe];
}
@ -521,18 +525,6 @@
clickContext:nil];
}
- (void)updatePosition:(id)sender
{
double pos = [audioPlayer amountPlayed];
if ([positionSlider tracking] == NO)
{
[positionSlider setDoubleValue:pos];
[self updateTimeField:pos];
}
}
- (void)audioPlayer:(AudioPlayer *)player statusChanged:(id)s
{
int status = [s intValue];
@ -543,11 +535,11 @@
[positionTimer invalidate];
positionTimer = NULL;
}
if (status == kCogStatusStopped)
{
[positionSlider setDoubleValue:0.0f];
[positionSlider setEnabled:NO]; // the player stopped, disable the slider
[self updateTimeField:0.0f];
[self setPosition:0];
[self setSeekable:NO]; // the player stopped, disable the slider
}
//Show play image
@ -559,7 +551,7 @@
positionTimer = [NSTimer timerWithTimeInterval:1.00 target:self selector:@selector(updatePosition:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:positionTimer forMode:NSRunLoopCommonModes];
}
//Show pause
[self changePlayButtonImage:@"pause"];
}
@ -567,15 +559,35 @@
if (status == kCogStatusStopped) {
NSLog(@"DONE!");
[playlistController setCurrentEntry:nil];
[positionSlider setEnabled:NO]; // the player stopped, disable the slider
[self setSeekable:NO]; // the player stopped, disable the slider
}
else {
NSLog(@"PLAYING!");
[self setSeekable:YES];
}
playbackStatus = status;
}
- (void)setPosition:(double)p
{
position = p;
}
- (double)position
{
return position;
}
- (void)setSeekable:(BOOL)s
{
seekable = s;
}
- (BOOL)seekable
{
return seekable && [[playlistController currentEntry] seekable];
}
@end

View File

@ -0,0 +1,18 @@
//
// PositionSlider.h
// Cog
//
// Created by Vincent Spader on 2/22/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "TrackingSlider.h"
@class TimeField;
@interface PositionSlider : TrackingSlider {
IBOutlet TimeField *positionTextField;
}
@end

View File

@ -0,0 +1,33 @@
//
// PositionSlider.m
// Cog
//
// Created by Vincent Spader on 2/22/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "PositionSlider.h"
#import "TimeField.h"
@implementation PositionSlider
- (void)setDoubleValue:(double)value
{
[positionTextField setDoubleValue:value];
[super setDoubleValue:value];
}
- (void)setMaxValue:(double)value
{
[positionTextField setMaxDoubleValue:value];
}
- (void)mouseDragged:(NSEvent *)theEvent
{
[positionTextField setDoubleValue:[self doubleValue]];
[super mouseDragged:theEvent];
}
@end

22
Application/TimeField.h Normal file
View File

@ -0,0 +1,22 @@
//
// TimeField.h
// Cog
//
// Created by Vincent Spader on 2/22/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface TimeField : NSTextField {
BOOL showTimeRemaining;
double value;
double maxValue;
}
- (void)setMaxDoubleValue:(double)v;
- (void)setDoubleValue:(double)v;
@end

49
Application/TimeField.m Normal file
View File

@ -0,0 +1,49 @@
//
// TimeField.m
// Cog
//
// Created by Vincent Spader on 2/22/09.
// Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import "TimeField.h"
@implementation TimeField
- (void)update
{
NSString *text;
if (showTimeRemaining == NO)
{
int sec = value;
text = [NSString stringWithFormat:NSLocalizedString(@"TimeElapsed", @""), sec/60, sec%60];
}
else
{
int sec = maxValue - value;
if (sec < 0)
sec = 0;
text = [NSString stringWithFormat:NSLocalizedString(@"TimeRemaining", @""), sec/60, sec%60];
}
[self setStringValue:text];
}
- (void)mouseDown:(NSEvent *)theEvent
{
showTimeRemaining = !showTimeRemaining;
[self update];
}
- (void)setMaxDoubleValue:(double)v
{
maxValue = v;
}
- (void)setDoubleValue:(double)v
{
value = v;
[self update];
}
@end

View File

@ -42,7 +42,6 @@
177EBFA70B8BC2A70000BC8C /* ImageTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 177EBF870B8BC2A70000BC8C /* ImageTextCell.m */; };
177EBFAB0B8BC2A70000BC8C /* NDHotKeyControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 177EBF8D0B8BC2A70000BC8C /* NDHotKeyControl.m */; };
177EBFAD0B8BC2A70000BC8C /* NDHotKeyEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 177EBF8F0B8BC2A70000BC8C /* NDHotKeyEvent.m */; };
177EC01F0B8BC2CF0000BC8C /* ClickField.m in Sources */ = {isa = PBXBuildFile; fileRef = 177EC0130B8BC2CF0000BC8C /* ClickField.m */; };
177EC0210B8BC2CF0000BC8C /* DBLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 177EC0150B8BC2CF0000BC8C /* DBLog.m */; };
177EC0230B8BC2CF0000BC8C /* DragScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 177EC0170B8BC2CF0000BC8C /* DragScrollView.m */; };
177EC0270B8BC2CF0000BC8C /* TrackingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 177EC01B0B8BC2CF0000BC8C /* TrackingCell.m */; };
@ -120,6 +119,8 @@
17D1B2810CF8B2830028F5B5 /* song.icns in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B27A0CF8B2830028F5B5 /* song.icns */; };
17D1B2820CF8B2830028F5B5 /* vg.icns in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B27B0CF8B2830028F5B5 /* vg.icns */; };
17D1B2830CF8B2830028F5B5 /* xm.icns in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B27C0CF8B2830028F5B5 /* xm.icns */; };
17E0D4CA0F51FF78005B6FED /* PositionSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E0D4C90F51FF78005B6FED /* PositionSlider.m */; };
17E0D55B0F520636005B6FED /* TimeField.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E0D55A0F520636005B6FED /* TimeField.m */; };
17E41E070C130DFF00AC744D /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = 17E41E060C130DFF00AC744D /* Credits.html */; };
17E41E230C130EE200AC744D /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 17E41E220C130EE200AC744D /* Help */; };
17E78CB10D68D46F005C5A59 /* StringToURLTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E78CB00D68D46F005C5A59 /* StringToURLTransformer.m */; };
@ -560,8 +561,6 @@
177EBF8D0B8BC2A70000BC8C /* NDHotKeyControl.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NDHotKeyControl.m; sourceTree = "<group>"; };
177EBF8E0B8BC2A70000BC8C /* NDHotKeyEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NDHotKeyEvent.h; sourceTree = "<group>"; };
177EBF8F0B8BC2A70000BC8C /* NDHotKeyEvent.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NDHotKeyEvent.m; sourceTree = "<group>"; };
177EC0120B8BC2CF0000BC8C /* ClickField.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ClickField.h; sourceTree = "<group>"; };
177EC0130B8BC2CF0000BC8C /* ClickField.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = ClickField.m; sourceTree = "<group>"; };
177EC0140B8BC2CF0000BC8C /* DBLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DBLog.h; sourceTree = "<group>"; };
177EC0150B8BC2CF0000BC8C /* DBLog.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = DBLog.m; sourceTree = "<group>"; };
177EC0160B8BC2CF0000BC8C /* DragScrollView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DragScrollView.h; sourceTree = "<group>"; };
@ -665,6 +664,10 @@
17D1B27A0CF8B2830028F5B5 /* song.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = song.icns; sourceTree = "<group>"; };
17D1B27B0CF8B2830028F5B5 /* vg.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = vg.icns; sourceTree = "<group>"; };
17D1B27C0CF8B2830028F5B5 /* xm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = xm.icns; sourceTree = "<group>"; };
17E0D4C80F51FF78005B6FED /* PositionSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PositionSlider.h; sourceTree = "<group>"; };
17E0D4C90F51FF78005B6FED /* PositionSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PositionSlider.m; sourceTree = "<group>"; };
17E0D5590F520636005B6FED /* TimeField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeField.h; sourceTree = "<group>"; };
17E0D55A0F520636005B6FED /* TimeField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TimeField.m; sourceTree = "<group>"; };
17E78CAF0D68D46F005C5A59 /* StringToURLTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringToURLTransformer.h; sourceTree = "<group>"; };
17E78CB00D68D46F005C5A59 /* StringToURLTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StringToURLTransformer.m; sourceTree = "<group>"; };
17F3BB830CBC565100864489 /* CueSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CueSheet.xcodeproj; path = Plugins/CueSheet/CueSheet.xcodeproj; sourceTree = "<group>"; };
@ -840,6 +843,10 @@
179571580F51DF4100E4168D /* MiniWindow.m */,
179571710F51E21400E4168D /* MainWindow.h */,
179571720F51E21400E4168D /* MainWindow.m */,
17E0D4C80F51FF78005B6FED /* PositionSlider.h */,
17E0D4C90F51FF78005B6FED /* PositionSlider.m */,
17E0D5590F520636005B6FED /* TimeField.h */,
17E0D55A0F520636005B6FED /* TimeField.m */,
);
path = Application;
sourceTree = "<group>";
@ -889,8 +896,6 @@
177EC0110B8BC2CF0000BC8C /* Utils */ = {
isa = PBXGroup;
children = (
177EC0120B8BC2CF0000BC8C /* ClickField.h */,
177EC0130B8BC2CF0000BC8C /* ClickField.m */,
177EC0140B8BC2CF0000BC8C /* DBLog.h */,
177EC0150B8BC2CF0000BC8C /* DBLog.m */,
177EC0160B8BC2CF0000BC8C /* DragScrollView.h */,
@ -1775,7 +1780,6 @@
177EBFA70B8BC2A70000BC8C /* ImageTextCell.m in Sources */,
177EBFAB0B8BC2A70000BC8C /* NDHotKeyControl.m in Sources */,
177EBFAD0B8BC2A70000BC8C /* NDHotKeyEvent.m in Sources */,
177EC01F0B8BC2CF0000BC8C /* ClickField.m in Sources */,
177EC0210B8BC2CF0000BC8C /* DBLog.m in Sources */,
177EC0230B8BC2CF0000BC8C /* DragScrollView.m in Sources */,
177EC0270B8BC2CF0000BC8C /* TrackingCell.m in Sources */,
@ -1832,6 +1836,8 @@
1752C6B00F3FE3CC00FC3235 /* VolumeSlider.m in Sources */,
179571590F51DF4100E4168D /* MiniWindow.m in Sources */,
179571730F51E21400E4168D /* MainWindow.m in Sources */,
17E0D4CA0F51FF78005B6FED /* PositionSlider.m in Sources */,
17E0D55B0F520636005B6FED /* TimeField.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -8,9 +8,9 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="21"/>
<integer value="29"/>
<integer value="2234"/>
<integer value="807"/>
<integer value="29"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -186,7 +186,7 @@
<string key="NSFrame">{{0, 14}, {96, 15}}</string>
<bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="543888159">
<int key="NSCellFlags">604372736</int>
<int key="NSCellFlags">604110336</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents"/>
<object class="NSFont" key="NSSupport" id="26">
@ -5046,22 +5046,6 @@ OQA</bytes>
</object>
<int key="connectionID">1597</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">timeField</string>
<reference key="source" ref="936098491"/>
<reference key="destination" ref="362320150"/>
</object>
<int key="connectionID">1598</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">toggleShowTimeRemaining:</string>
<reference key="source" ref="936098491"/>
<reference key="destination" ref="362320150"/>
</object>
<int key="connectionID">1599</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">playbackButtons</string>
@ -5683,42 +5667,6 @@ OQA</bytes>
</object>
<int key="connectionID">1903</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">maxValue: content.length</string>
<reference key="source" ref="505703107"/>
<reference key="destination" ref="200345764"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="505703107"/>
<reference key="NSDestination" ref="200345764"/>
<string key="NSLabel">maxValue: content.length</string>
<string key="NSBinding">maxValue</string>
<string key="NSKeyPath">content.length</string>
<object class="NSDictionary" key="NSOptions">
<string key="NS.key.0">NSRaisesForNotApplicableKeys</string>
<reference key="NS.object.0" ref="8"/>
</object>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">1905</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">enabled: content.seekable</string>
<reference key="source" ref="505703107"/>
<reference key="destination" ref="200345764"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="505703107"/>
<reference key="NSDestination" ref="200345764"/>
<string key="NSLabel">enabled: content.seekable</string>
<string key="NSBinding">enabled</string>
<string key="NSKeyPath">content.seekable</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">1908</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">fontSize: values.fontSize</string>
@ -6710,6 +6658,124 @@ OQA</bytes>
</object>
<int key="connectionID">2374</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">enabled: seekable</string>
<reference key="source" ref="505703107"/>
<reference key="destination" ref="936098491"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="505703107"/>
<reference key="NSDestination" ref="936098491"/>
<string key="NSLabel">enabled: seekable</string>
<string key="NSBinding">enabled</string>
<string key="NSKeyPath">seekable</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">2376</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">maxValue: content.length</string>
<reference key="source" ref="505703107"/>
<reference key="destination" ref="200345764"/>
<object class="NSNibBindingConnector" key="connector" id="875245063">
<reference key="NSSource" ref="505703107"/>
<reference key="NSDestination" ref="200345764"/>
<string key="NSLabel">maxValue: content.length</string>
<string key="NSBinding">maxValue</string>
<string key="NSKeyPath">content.length</string>
<object class="NSDictionary" key="NSOptions">
<string key="NS.key.0">NSRaisesForNotApplicableKeys</string>
<boolean value="NO" key="NS.object.0" id="6"/>
</object>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">2377</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: position</string>
<reference key="source" ref="505703107"/>
<reference key="destination" ref="936098491"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="505703107"/>
<reference key="NSDestination" ref="936098491"/>
<string key="NSLabel">value: position</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">position</string>
<reference key="NSPreviousConnector" ref="875245063"/>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">2378</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">maxValue: content.length</string>
<reference key="source" ref="163997941"/>
<reference key="destination" ref="200345764"/>
<object class="NSNibBindingConnector" key="connector" id="518066525">
<reference key="NSSource" ref="163997941"/>
<reference key="NSDestination" ref="200345764"/>
<string key="NSLabel">maxValue: content.length</string>
<string key="NSBinding">maxValue</string>
<string key="NSKeyPath">content.length</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">2381</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">value: position</string>
<reference key="source" ref="163997941"/>
<reference key="destination" ref="936098491"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="163997941"/>
<reference key="NSDestination" ref="936098491"/>
<string key="NSLabel">value: position</string>
<string key="NSBinding">value</string>
<string key="NSKeyPath">position</string>
<reference key="NSPreviousConnector" ref="518066525"/>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">2382</int>
</object>
<object class="IBConnectionRecord">
<object class="IBBindingConnection" key="connection">
<string key="label">enabled: seekable</string>
<reference key="source" ref="163997941"/>
<reference key="destination" ref="936098491"/>
<object class="NSNibBindingConnector" key="connector">
<reference key="NSSource" ref="163997941"/>
<reference key="NSDestination" ref="936098491"/>
<string key="NSLabel">enabled: seekable</string>
<string key="NSBinding">enabled</string>
<string key="NSKeyPath">seekable</string>
<int key="NSNibBindingConnectorVersion">2</int>
</object>
</object>
<int key="connectionID">2384</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">positionTextField</string>
<reference key="source" ref="505703107"/>
<reference key="destination" ref="362320150"/>
</object>
<int key="connectionID">2385</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">positionTextField</string>
<reference key="source" ref="163997941"/>
<reference key="destination" ref="201123626"/>
</object>
<int key="connectionID">2386</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@ -9834,7 +9900,7 @@ OQA</bytes>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>TrackingSlider</string>
<string>PositionSlider</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>TrackingCell</string>
@ -9845,7 +9911,7 @@ OQA</bytes>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>ClickField</string>
<string>TimeField</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@ -9997,7 +10063,7 @@ OQA</bytes>
<string>{{334, 92}, {691, 397}}</string>
<string>{{334, 92}, {691, 397}}</string>
<reference ref="9"/>
<boolean value="NO" id="6"/>
<reference ref="6"/>
<string>{{25, 14}, {683, 396}}</string>
<reference ref="8"/>
<string>{3.40282e+38, 3.40282e+38}</string>
@ -10079,12 +10145,12 @@ OQA</bytes>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>ClickField</string>
<string>TimeField</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>TrackingSlider</string>
<string>PositionSlider</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>TrackingCell</string>
@ -10285,7 +10351,7 @@ OQA</bytes>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">2374</int>
<int key="maxID">2386</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@ -10397,22 +10463,6 @@ OQA</bytes>
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">ClickField</string>
<string key="superclassName">NSTextField</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">Utils/ClickField.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">ClickField</string>
<string key="superclassName">NSTextField</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBUserSource</string>
<string key="minorKey"/>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">DNDArrayController</string>
<string key="superclassName">NSArrayController</string>
@ -10655,8 +10705,6 @@ OQA</bytes>
<string>playbackButtons</string>
<string>playlistController</string>
<string>playlistView</string>
<string>positionSlider</string>
<string>timeField</string>
<string>volumeSlider</string>
</object>
<object class="NSMutableArray" key="dict.values">
@ -10665,8 +10713,6 @@ OQA</bytes>
<string>NSSegmentedControl</string>
<string>PlaylistController</string>
<string>PlaylistView</string>
<string>TrackingSlider</string>
<string>NSTextField</string>
<string>NSSlider</string>
</object>
</object>
@ -10846,6 +10892,18 @@ OQA</bytes>
<string key="minorKey">ThirdParty/GCWindowMenu/PopupButton.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PositionSlider</string>
<string key="superclassName">TrackingSlider</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">positionTextField</string>
<string key="NS.object.0">TimeField</string>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">Application/PositionSlider.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">PreferencesController</string>
<string key="superclassName">NSObject</string>
@ -10995,6 +11053,14 @@ OQA</bytes>
<string key="minorKey">TagEditor/TagEditorController.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">TimeField</string>
<string key="superclassName">NSTextField</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">Application/TimeField.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">TrackingCell</string>
<string key="superclassName">NSSliderCell</string>

View File

@ -1,9 +0,0 @@
/* ClickField */
#import <Cocoa/Cocoa.h>
@interface ClickField : NSTextField
{
}
@end

View File

@ -1,17 +0,0 @@
#import "ClickField.h"
@implementation ClickField
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent {
return YES;
}
- (void)mouseDown:(NSEvent *)theEvent
{
if([theEvent type] == NSLeftMouseDown)
{
[self sendAction:[self action] to:[self target]];
}
}
@end

View File

@ -9,6 +9,7 @@
- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView;
- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flags;
- (BOOL)tracking;
- (BOOL)isTracking;
@end

View File

@ -9,6 +9,16 @@
}
- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView
{
NSEvent *event = [NSEvent mouseEventWithType:NSLeftMouseDragged location:currentPoint modifierFlags:NSLeftMouseDown timestamp:0 windowNumber:[[controlView window] windowNumber] context:nil eventNumber:0 clickCount:0 pressure:0];
[controlView mouseDragged:event];
return [super continueTracking:lastPoint at:currentPoint inView:controlView];
}
- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag
{
tracking = NO;
@ -16,10 +26,9 @@
[super stopTracking:lastPoint at:stopPoint inView:controlView mouseIsUp:flag];
}
- (BOOL)tracking
- (BOOL)isTracking
{
return tracking;
}
@end

View File

@ -13,7 +13,9 @@
@interface TrackingSlider : NSSlider
{
NSMutableDictionary *bindingInfo;
}
-(BOOL)tracking;
- (BOOL)isTracking;
@end

View File

@ -3,9 +3,88 @@
@implementation TrackingSlider
-(BOOL)tracking
static NSString *TrackingSliderValueObservationContext = @"TrackingSliderValueObservationContext";
- (id)initWithFrame:(NSRect)frameRect
{
return [[self cell] tracking];
self = [super initWithFrame:frameRect];
if (self)
{
bindingInfo = [[NSMutableDictionary alloc] init];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super initWithCoder:decoder];
if (self)
{
bindingInfo = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([TrackingSliderValueObservationContext isEqual:context])
{
if (![self isTracking])
{
id value = [change objectForKey:NSKeyValueChangeNewKey];
[self setDoubleValue:[value doubleValue]];
}
}
else
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)bind:(NSString *)binding toObject:(id)observableController withKeyPath:(NSString *)keyPath options:(NSDictionary *)options
{
if ([binding isEqualToString:@"value"])
{
[observableController addObserver:self forKeyPath:keyPath options:(NSKeyValueObservingOptionNew) context:TrackingSliderValueObservationContext];
NSDictionary *bindingsData = [NSDictionary dictionaryWithObjectsAndKeys:
observableController, NSObservedObjectKey,
[keyPath copy], NSObservedKeyPathKey,
[options copy], NSOptionsKey, nil];
[bindingInfo setObject:bindingsData forKey:binding];
}
else
{
[super bind:binding toObject:observableController withKeyPath:keyPath options:options];
}
}
- (void)unbind:(NSString *)binding
{
if ([binding isEqualToString:@"value"])
{
NSDictionary *info = [bindingInfo objectForKey:binding];
NSString *keyPath = [info objectForKey:NSObservedKeyPathKey];
id observedObject = [info objectForKey:NSObservedObjectKey];
[observedObject removeObserver:self forKeyPath:keyPath];
}
else
{
[super unbind:binding];
}
}
- (BOOL)isTracking
{
return [[self cell] isTracking];
}
@end