diff --git a/.gitignore b/.gitignore index 527b85c..703f2a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,18 @@ Build/ + +# Temporary files of every sort +.sass-cache +.DS_Store +.idea +.rvmrc +.stgit* +*.swap +*.swo +*.swp +*~ +bin/* +nbproject +patches-* +capybara-*.html +dump.rdb + diff --git a/LPCalendarHeaderView.j b/LPCalendarHeaderView.j index 465d4a2..ecca1d3 100644 --- a/LPCalendarHeaderView.j +++ b/LPCalendarHeaderView.j @@ -56,8 +56,10 @@ var LPMonthNames = [@"January", @"February", @"March", @"April", @"May", @"June" { if(self = [super initWithFrame:aFrame]) { - monthLabel = [[CPTextField alloc] initWithFrame:CGRectMakeZero()]; - [monthLabel setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin]; + monthLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 8, aFrame.size.width, aFrame.size.height)]; + [monthLabel setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; + [monthLabel setValue:CPCenterTextAlignment forThemeAttribute:@"alignment"]; + [monthLabel setHitTests:NO]; [self addSubview:monthLabel]; prevButton = [[LPCalendarHeaderArrowButton alloc] initWithFrame:CGRectMake(6, 9, 0, 0)]; @@ -91,8 +93,7 @@ var LPMonthNames = [@"January", @"February", @"March", @"April", @"May", @"June" representedDate = [aDate copy]; [monthLabel setStringValue:[CPString stringWithFormat:@"%s %i", LPMonthNames[representedDate.getUTCMonth()], representedDate.getUTCFullYear()]]; - [monthLabel sizeToFit]; - [monthLabel setCenter:CGPointMake(CGRectGetMidX([self bounds]), 16)]; + } - (void)setWeekStartsOnMonday:(BOOL)shouldWeekStartOnMonday diff --git a/LPCalendarMonthView.j b/LPCalendarMonthView.j index 91e0bee..0cfef69 100644 --- a/LPCalendarMonthView.j +++ b/LPCalendarMonthView.j @@ -293,7 +293,7 @@ var _startAndEndOfWeekCache = {}; for (var dayIndex = 0; dayIndex < 7; dayIndex++) { // CGRectInset() mucks up the frame for some reason. - var tileFrame = CGRectMake((dayIndex * tileSize.width) + dayIndex, weekIndex * tileSize.height, tileSize.width, tileSize.height -1); + var tileFrame = CGRectMake((dayIndex * tileSize.width), weekIndex * tileSize.height, tileSize.width, tileSize.height); [tiles[tileIndex] setFrame:tileFrame]; tileIndex += 1; @@ -464,23 +464,34 @@ var _startAndEndOfWeekCache = {}; end:(anEndIndex > -1) ? [[tiles objectAtIndex:anEndIndex] date] : nil]; } -- (void)drawRect:(CGRect)aRect -{ - var context = [[CPGraphicsContext currentContext] graphicsPort], - bounds = [self bounds], - width = CGRectGetWidth(bounds), - height = CGRectGetHeight(bounds), - tileSize = [self tileSize]; +- (void) drawRect:(CGRect)aRect { + + var context = [[CPGraphicsContext currentContext] graphicsPort], + bounds = [self bounds], + width = CGRectGetWidth(bounds), + height = CGRectGetHeight(bounds), + tileSize = [self tileSize]; + + var hLine = function (inMarginTop) { + + CGContextFillRect(context, CGRectMake(0, inMarginTop, width, 1)); + + }, + + vLine = function (inMarginLeft) { + + CGContextFillRect(context, CGRectMake(inMarginLeft, 0, 1, height)); + + }; - CGContextSetFillColor(context, [calendarView currentValueForThemeAttribute:@"grid-color"]); + CGContextSetFillColor(context, [calendarView currentValueForThemeAttribute:@"grid-shadow-color"]); + for (var i = 1; i < 6; i++) hLine(tileSize.height * i - 1); + for (var i = 1; i < 7; i++) vLine(tileSize.width * i - 1); - // Horizontal lines - for (var i = 1; i < 6; i++) - CGContextFillRect(context, CGRectMake(0, i * tileSize.height - 1, width, 1)); + CGContextSetFillColor(context, [calendarView currentValueForThemeAttribute:@"grid-color"]); + for (var i = 1; i < 6; i++) hLine(tileSize.height * i); + for (var i = 1; i < 7; i++) vLine(tileSize.width * i); - // Vertical lines - for (var i = 0; i < 7; i++) - CGContextFillRect(context, CGRectMake((i - 1) + (i * tileSize.width), 0, 1, height)); } @end diff --git a/LPCalendarView.j b/LPCalendarView.j index f322a6b..57d11bc 100644 --- a/LPCalendarView.j +++ b/LPCalendarView.j @@ -56,8 +56,8 @@ + (id)themeAttributes { - return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], CGSizeMake(0,0), [CPNull null], [CPNull null], 40, [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], 30, [CPNull null], [CPNull null], [CPNull null], [CPNull null]] - forKeys:[@"background-color", @"grid-color", + return [CPDictionary dictionaryWithObjects:[[CPNull null], CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], CGSizeMake(0,0), [CPNull null], [CPNull null], 40, [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], 30, [CPNull null], [CPNull null], [CPNull null], [CPNull null]] + forKeys:[@"bezel-color", @"bezel-inset", @"grid-color", @"grid-shadow-color", @"tile-size", @"tile-font", @"tile-text-color", @"tile-text-shadow-color", @"tile-text-shadow-offset", @"tile-bezel-color", @"header-button-offset", @"header-prev-button-image", @"header-next-button-image", @"header-height", @"header-background-color", @"header-font", @"header-text-color", @"header-text-shadow-color", @"header-text-shadow-offset", @"header-alignment", @"header-weekday-offset", @"header-weekday-label-font", @"header-weekday-label-color", @"header-weekday-label-shadow-color", @"header-weekday-label-shadow-offset"]]; @@ -71,6 +71,7 @@ fullSelection = [nil, nil]; var bounds = [self bounds]; + [self setClipsToBounds:NO]; headerView = [[LPCalendarHeaderView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(bounds), 40)]; [[headerView prevButton] setTarget:self]; @@ -87,6 +88,10 @@ [slideView setAnimationDuration:0.2]; [self addSubview:slideView]; + bezelView = [[CPView alloc] initWithFrame:[slideView frame]]; + [bezelView setHitTests:NO]; + [self addSubview:bezelView positioned:CPWindowBelow relativeTo:nil]; + firstMonthView = [[LPCalendarMonthView alloc] initWithFrame:[slideView bounds] calendarView:self]; [firstMonthView setDelegate:self]; [slideView addSubview:firstMonthView]; @@ -199,8 +204,20 @@ [headerView setFrameSize:CGSizeMake(width, headerHeight)]; [slideView setFrame:CGRectMake(0, headerHeight, width, CGRectGetHeight([self bounds]) - headerHeight)]; - - [slideView setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]]; + + [bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]]; + var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"]; + + var viewFrame = [self frame]; + [bezelView setFrame:CGRectMake( + + 0 + bezelInset.left, + 0 + bezelInset.top, + viewFrame.size.width - bezelInset.left - bezelInset.right, + viewFrame.size.height - bezelInset.top - bezelInset.bottom + + )]; + } - (void)didClickPrevButton:(id)sender diff --git a/LPChartView.j b/LPChartView.j index c20291c..f0a2d35 100644 --- a/LPChartView.j +++ b/LPChartView.j @@ -128,8 +128,13 @@ var labelViewHeight = 20, [aGridView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; [self replaceSubview:gridView with:aGridView]; - + + var gridViewFrame = [drawView frame]; + gridViewFrame.height -= 1; + [aGridView setFrame:gridViewFrame]; + gridView = aGridView; + } - (void)setDisplayLabels:(BOOL)shouldDisplayLabels @@ -228,7 +233,7 @@ var labelViewHeight = 20, if (_maxValuePosition !== 1.0) drawViewSize.height -= maxValueHeightDelta; - // Make sure we don't do unnecessary word + // Make sure we don't do unnecessary work if (_currentSize && CGSizeEqualToSize(_currentSize, drawViewSize)) return _framesSet; diff --git a/LPMultiLineTextField.j b/LPMultiLineTextField.j index b8b53b1..a729893 100644 --- a/LPMultiLineTextField.j +++ b/LPMultiLineTextField.j @@ -64,9 +64,7 @@ var CPTextFieldInputOwner = nil; - (id)initWithFrame:(CGRect)aFrame { - if (self = [super initWithFrame:aFrame]) - { - } + if (self != [super initWithFrame:aFrame]) return nil; return self; } @@ -94,8 +92,10 @@ var CPTextFieldInputOwner = nil; - (void)layoutSubviews { + [super layoutSubviews]; + var contentView = [self layoutEphemeralSubviewNamed:@"content-view" positioned:CPWindowAbove relativeToEphemeralSubviewNamed:@"bezel-view"]; @@ -115,7 +115,7 @@ var CPTextFieldInputOwner = nil; DOMElement.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString]; DOMElement.style.font = [[self currentValueForThemeAttribute:@"font"] cssString]; - + switch ([self currentValueForThemeAttribute:@"alignment"]) { case CPLeftTextAlignment: @@ -133,8 +133,17 @@ var CPTextFieldInputOwner = nil; default: DOMElement.style.textAlign = "left"; } - - DOMElement.value = _stringValue || @""; + + // We explicitly want a placeholder when the value is an empty string. + if ([self hasThemeState:CPTextFieldStatePlaceholder]) { + + DOMElement.value = [self placeholderString]; + + } else { + + DOMElement.value = [self stringValue]; + + } if(_hideOverflow) DOMElement.style.overflow=@"hidden"; @@ -182,10 +191,12 @@ var CPTextFieldInputOwner = nil; - (void)keyUp:(CPEvent)anEvent { - if (_stringValue !== [self stringValue]) + var oldStringValue = [self stringValue]; + [self _setStringValue:[self _DOMTextareaElement].value]; + + if (oldStringValue !== [self stringValue]) { - _stringValue = [self stringValue]; - + if (!_isEditing) { _isEditing = YES; @@ -209,6 +220,7 @@ var CPTextFieldInputOwner = nil; _stringValue = [self stringValue]; [self setThemeState:CPThemeStateEditing]; + [self _updatePlaceholderState]; setTimeout(function(){ [self _DOMTextareaElement].focus(); @@ -223,7 +235,7 @@ var CPTextFieldInputOwner = nil; - (BOOL)resignFirstResponder { [self unsetThemeState:CPThemeStateEditing]; - + [self _updatePlaceholderState]; [self setStringValue:[self stringValue]]; [self _DOMTextareaElement].blur(); @@ -243,15 +255,32 @@ var CPTextFieldInputOwner = nil; return YES; } -- (CPString)stringValue +- (void)_setStringValue:(id)aValue { - return (!!_DOMTextareaElement) ? _DOMTextareaElement.value : @""; + [self willChangeValueForKey:@"objectValue"]; + [super setObjectValue:String(aValue)]; + [self _updatePlaceholderState]; + [self didChangeValueForKey:@"objectValue"]; } -- (void)setStringValue:(CPString)aString +- (void)setObjectValue:(id)aValue { - _stringValue = aString; - [self setNeedsLayout]; + [super setObjectValue:aValue]; + + if (CPTextFieldInputOwner === self || [[self window] firstResponder] === self) + [self _DOMTextareaElement].value = aValue; + + [self _updatePlaceholderState]; +} + +- (void) _setCurrentValueIsPlaceholder:(BOOL)isPlaceholder { + +// Under certain circumstances, _originalPlaceholderString is empty. + if (!_originalPlaceholderString) + _originalPlaceholderString = [self placeholderString]; + + [super _setCurrentValueIsPlaceholder:isPlaceholder]; + } @end diff --git a/LPSwitch.j b/LPSwitch.j index 8313223..c01af71 100644 --- a/LPSwitch.j +++ b/LPSwitch.j @@ -62,7 +62,7 @@ + (id)themeAttributes { - return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]] + return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], CGSizeMake(30.0, 24.0), [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]] forKeys:[@"off-background-color", @"on-background-color", @"knob-background-color", @"knob-size", @"label-offset", @"off-label-font", @"off-label-text-color", @"off-label-text-shadow-color", @"off-label-text-shadow-offset", @"on-label-font", @"on-label-text-color", @"on-label-text-shadow-color", @"on-label-text-shadow-offset"]];