+/*****************************************************************************
+ * VLCTimeField implementation
+ *****************************************************************************
+ * we need this to catch our click-event in the controller window
+ *****************************************************************************/
+
+@implementation VLCTimeField
++ (void)initialize
+{
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"NO", @"DisplayTimeAsTimeRemaining",
+ @"YES", @"DisplayFullscreenTimeAsTimeRemaining",
+ nil];
+
+ [defaults registerDefaults:appDefaults];
+}
+
+- (void)setRemainingIdentifier:(NSString *)o_string
+{
+ o_remaining_identifier = o_string;
+ b_time_remaining = [[NSUserDefaults standardUserDefaults] boolForKey:o_remaining_identifier];
+}
+
+- (void)setAlignment:(NSTextAlignment)alignment
+{
+ textAlignment = alignment;
+ [self setStringValue:[self stringValue]];
+}
+
+- (void)dealloc
+{
+ [o_string_shadow release];
+ [super dealloc];
+}
+
+- (void)setStringValue:(NSString *)string
+{
+ if (!o_string_shadow) {
+ o_string_shadow = [[NSShadow alloc] init];
+ [o_string_shadow setShadowColor: [NSColor colorWithCalibratedWhite:1.0 alpha:0.5]];
+ [o_string_shadow setShadowOffset:NSMakeSize(0.0, -1.0)];
+ [o_string_shadow setShadowBlurRadius:0.0];
+ }
+
+ NSMutableAttributedString *o_attributed_string = [[NSMutableAttributedString alloc] initWithString:string attributes: nil];
+ NSUInteger i_stringLength = [string length];
+
+ [o_attributed_string addAttribute: NSShadowAttributeName value: o_string_shadow range: NSMakeRange(0, i_stringLength)];
+ [o_attributed_string setAlignment: textAlignment range: NSMakeRange(0, i_stringLength)];
+ [self setAttributedStringValue: o_attributed_string];
+ [o_attributed_string release];
+}
+
+- (void)mouseDown: (NSEvent *)ourEvent
+{
+ if ( [ourEvent clickCount] > 1 )
+ [[[VLCMain sharedInstance] controls] goToSpecificTime: nil];
+ else
+ {
+ if (o_remaining_identifier) {
+ b_time_remaining = [[NSUserDefaults standardUserDefaults] boolForKey:o_remaining_identifier];
+ b_time_remaining = !b_time_remaining;
+ [[NSUserDefaults standardUserDefaults] setObject:(b_time_remaining ? @"YES" : @"NO") forKey:o_remaining_identifier];
+ } else {
+ b_time_remaining = !b_time_remaining;
+ }
+ }
+}
+
+- (BOOL)timeRemaining
+{
+ if (o_remaining_identifier)
+ return [[NSUserDefaults standardUserDefaults] boolForKey:o_remaining_identifier];
+ else
+ return b_time_remaining;
+}
+
+@end
+
+/*****************************************************************************
+ * VLCMainWindowSplitView implementation
+ * comment 1 + 2 taken from NSSplitView.h (10.7 SDK)
+ *****************************************************************************/
+@implementation VLCMainWindowSplitView : NSSplitView
+/* Return the color of the dividers that the split view is drawing between subviews. The default implementation of this method returns [NSColor clearColor] for the thick divider style. It will also return [NSColor clearColor] for the thin divider style when the split view is in a textured window. All other thin dividers are drawn with a color that looks good between two white panes. You can override this method to change the color of dividers.
+ */
+- (NSColor *)dividerColor
+{
+ return [NSColor colorWithCalibratedRed:.60 green:.60 blue:.60 alpha:1.];
+}
+
+/* Return the thickness of the dividers that the split view is drawing between subviews. The default implementation returns a value that depends on the divider style. You can override this method to change the size of dividers.
+ */
+- (CGFloat)dividerThickness
+{
+ return 1.0;
+}
+@end
+
+/*****************************************************************************
+ * VLCThreePartImageView interface
+ *****************************************************************************/
+@implementation VLCThreePartImageView
+
+- (void)dealloc
+{
+ [o_left_img release];
+ [o_middle_img release];
+ [o_right_img release];
+
+ [super dealloc];
+}
+
+- (void)setImagesLeft:(NSImage *)left middle: (NSImage *)middle right:(NSImage *)right
+{
+ if (o_left_img)
+ [o_left_img release];
+ if (o_middle_img)
+ [o_middle_img release];
+ if (o_right_img)
+ [o_right_img release];
+
+ o_left_img = [left retain];
+ o_middle_img = [middle retain];
+ o_right_img = [right retain];
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ NSRect bnds = [self bounds];
+ NSDrawThreePartImage( bnds, o_left_img, o_middle_img, o_right_img, NO, NSCompositeSourceOver, 1, NO );
+}
+
+@end
+
+
+@implementation PositionFormatter
+
+- (id)init
+{
+ self = [super init];
+ NSMutableCharacterSet *nonNumbers = [[[NSCharacterSet decimalDigitCharacterSet] invertedSet] mutableCopy];
+ [nonNumbers removeCharactersInString:@"-:"];
+ o_forbidden_characters = [nonNumbers copy];
+ [nonNumbers release];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [o_forbidden_characters release];
+ [super dealloc];
+}
+
+- (NSString*)stringForObjectValue:(id)obj
+{
+ if([obj isKindOfClass:[NSString class]])
+ return obj;
+ if([obj isKindOfClass:[NSNumber class]])
+ return [obj stringValue];
+
+ return nil;
+}
+
+- (BOOL)getObjectValue:(id*)obj forString:(NSString*)string errorDescription:(NSString**)error
+{
+ *obj = [[string copy] autorelease];
+ return YES;
+}
+
+- (BOOL)isPartialStringValid:(NSString*)partialString newEditingString:(NSString**)newString errorDescription:(NSString**)error
+{
+ if ([partialString rangeOfCharacterFromSet:o_forbidden_characters options:NSLiteralSearch].location != NSNotFound) {
+ return NO;
+ } else {
+ return YES;
+ }
+}
+
+@end
+
+@implementation NSView (EnableSubviews)
+
+- (void)enableSubviews:(BOOL)b_enable
+{
+ for (NSView *o_view in [self subviews]) {
+ [o_view enableSubviews:b_enable];
+
+ // enable NSControl
+ if ([o_view respondsToSelector:@selector(setEnabled:)]) {
+ [(NSControl *)o_view setEnabled:b_enable];
+ }
+ // also "enable / disable" text views
+ if ([o_view respondsToSelector:@selector(setTextColor:)]) {
+ if (b_enable == NO) {
+ [(NSTextField *)o_view setTextColor:[NSColor disabledControlTextColor]];
+ } else {
+ [(NSTextField *)o_view setTextColor:[NSColor controlTextColor]];
+ }
+ }
+
+ }
+}
+
+@end
+
+/*****************************************************************************
+ * VLCByteCountFormatter addition
+ *****************************************************************************/
+
+@implementation VLCByteCountFormatter
+
++ (NSString *)stringFromByteCount:(long long)byteCount countStyle:(NSByteCountFormatterCountStyle)countStyle
+{
+ // Use native implementation on >= mountain lion
+ Class byteFormatterClass = NSClassFromString(@"NSByteCountFormatter");
+ if (byteFormatterClass && [byteFormatterClass respondsToSelector:@selector(stringFromByteCount:countStyle:)]) {
+ return [byteFormatterClass stringFromByteCount:byteCount countStyle:NSByteCountFormatterCountStyleFile];
+ }
+
+ float devider = 0.;
+ float returnValue = 0.;
+ NSString *suffix;
+
+ NSNumberFormatter *theFormatter = [[NSNumberFormatter alloc] init];
+ [theFormatter setLocale:[NSLocale currentLocale]];
+ [theFormatter setAllowsFloats:YES];
+
+ NSString *returnString = @"";
+
+ if (countStyle != NSByteCountFormatterCountStyleDecimal)
+ devider = 1024.;
+ else
+ devider = 1000.;
+
+ if (byteCount < 1000) {
+ returnValue = byteCount;
+ suffix = _NS("B");
+ [theFormatter setMaximumFractionDigits:0];
+ goto end;
+ }
+
+ if (byteCount < 1000000) {
+ returnValue = byteCount / devider;
+ suffix = _NS("KB");
+ [theFormatter setMaximumFractionDigits:0];
+ goto end;
+ }
+
+ if (byteCount < 1000000000) {
+ returnValue = byteCount / devider / devider;
+ suffix = _NS("MB");
+ [theFormatter setMaximumFractionDigits:1];
+ goto end;
+ }
+
+ [theFormatter setMaximumFractionDigits:2];
+ if (byteCount < 1000000000000) {
+ returnValue = byteCount / devider / devider / devider;
+ suffix = _NS("GB");
+ goto end;
+ }
+
+ returnValue = byteCount / devider / devider / devider / devider;
+ suffix = _NS("TB");
+
+end:
+ returnString = [NSString stringWithFormat:@"%@ %@", [theFormatter stringFromNumber:[NSNumber numberWithFloat:returnValue]], suffix];
+ [theFormatter release];
+
+ return returnString;
+}
+
+@end