From 4462d8bf22a569647a2286baf935eb0672677978 Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Sun, 13 May 2018 19:40:33 +0200 Subject: [PATCH 1/5] CHANGED: CPSegmentedControl code refactoring (#2704) --- AppKit/CPSegmentedControl.j | 98 +++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/AppKit/CPSegmentedControl.j b/AppKit/CPSegmentedControl.j index bd9ec8e04..9a42a8cab 100644 --- a/AppKit/CPSegmentedControl.j +++ b/AppKit/CPSegmentedControl.j @@ -872,64 +872,68 @@ CPSegmentSwitchTrackingMomentary = 2; var type = [anEvent type], location = [self convertPoint:[anEvent locationInWindow] fromView:nil]; - if (type == CPLeftMouseUp) + switch (type) { - if (_trackingSegment == -1) + case CPLeftMouseUp: + + if (_trackingSegment === CPNotFound) + return; + + if (_trackingSegment === [self testSegment:location]) + { + if (_trackingMode == CPSegmentSwitchTrackingSelectAny) + { + [self setSelected:![self isSelectedForSegment:_trackingSegment] forSegment:_trackingSegment]; + + // With ANY, _selectedSegment means last pressed. + _selectedSegment = _trackingSegment; + } + else + [self setSelected:YES forSegment:_trackingSegment]; + + [self sendAction:[self action] to:[self target]]; + + if (_trackingMode == CPSegmentSwitchTrackingMomentary) + { + [self setSelected:NO forSegment:_trackingSegment]; + + _selectedSegment = CPNotFound; + } + } + + [self drawSegmentBezel:_trackingSegment highlight:NO]; + + _trackingSegment = CPNotFound; + return; - if (_trackingSegment === [self testSegment:location]) - { - if (_trackingMode == CPSegmentSwitchTrackingSelectAny) + case CPLeftMouseDown: + + var trackingSegment = [self testSegment:location]; + if (trackingSegment > CPNotFound && [self isEnabledForSegment:trackingSegment]) { - [self setSelected:![self isSelectedForSegment:_trackingSegment] forSegment:_trackingSegment]; - - // With ANY, _selectedSegment means last pressed. - _selectedSegment = _trackingSegment; + _trackingHighlighted = YES; + _trackingSegment = trackingSegment; + [self drawSegmentBezel:_trackingSegment highlight:YES]; } - else - [self setSelected:YES forSegment:_trackingSegment]; - [self sendAction:[self action] to:[self target]]; + break; - if (_trackingMode == CPSegmentSwitchTrackingMomentary) + case CPLeftMouseDragged: + + if (_trackingSegment === CPNotFound) + return; + + var highlighted = [self testSegment:location] === _trackingSegment; + + if (highlighted != _trackingHighlighted) { - [self setSelected:NO forSegment:_trackingSegment]; + _trackingHighlighted = highlighted; - _selectedSegment = CPNotFound; + [self drawSegmentBezel:_trackingSegment highlight:_trackingHighlighted]; } - } - [self drawSegmentBezel:_trackingSegment highlight:NO]; - - _trackingSegment = -1; - - return; - } - - if (type == CPLeftMouseDown) - { - var trackingSegment = [self testSegment:location]; - if (trackingSegment > -1 && [self isEnabledForSegment:trackingSegment]) - { - _trackingHighlighted = YES; - _trackingSegment = trackingSegment; - [self drawSegmentBezel:_trackingSegment highlight:YES]; - } - } - - else if (type == CPLeftMouseDragged) - { - if (_trackingSegment == -1) - return; - - var highlighted = [self testSegment:location] === _trackingSegment; - - if (highlighted != _trackingHighlighted) - { - _trackingHighlighted = highlighted; - - [self drawSegmentBezel:_trackingSegment highlight:_trackingHighlighted]; - } + break; } [CPApp setTarget:self selector:@selector(trackSegment:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; From e27bb4de5086aeb97b5f5ca27762d237d9665de9 Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Sun, 13 May 2018 19:47:53 +0200 Subject: [PATCH 2/5] FIXED: _CPTableColumnHeaderView was using hard coded values instead of theme values (#2703) --- AppKit/CPTableHeaderView.j | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/AppKit/CPTableHeaderView.j b/AppKit/CPTableHeaderView.j index 8ec2a5beb..971bfeaa8 100644 --- a/AppKit/CPTableHeaderView.j +++ b/AppKit/CPTableHeaderView.j @@ -66,18 +66,20 @@ - (void)_init { + var inset = [self valueForThemeAttribute:@"text-inset"]; + _textField = [[_CPImageAndTextView alloc] initWithFrame: - CGRectMake(5.0, 0.0, CGRectGetWidth([self bounds]) - 10.0, CGRectGetHeight([self bounds]))]; + CGRectMake(inset.left, inset.top, CGRectGetWidth([self bounds]) - (inset.left + inset.right), CGRectGetHeight([self bounds]) - (inset.top + inset.bottom))]; [_textField setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable]; - [_textField setLineBreakMode:CPLineBreakByTruncatingTail]; - [_textField setTextColor:[CPColor colorWithRed:51.0 / 255.0 green:51.0 / 255.0 blue:51.0 / 255.0 alpha:1.0]]; - [_textField setFont:[CPFont boldSystemFontOfSize:12.0]]; - [_textField setAlignment:CPLeftTextAlignment]; + [_textField setLineBreakMode:[self valueForThemeAttribute:@"line-break-mode"]]; + [_textField setTextColor:[self valueForThemeAttribute:@"text-color"]]; + [_textField setFont:[self valueForThemeAttribute:@"font"]]; + [_textField setAlignment:[self valueForThemeAttribute:@"text-alignment"]]; [_textField setVerticalAlignment:CPCenterVerticalTextAlignment]; - [_textField setTextShadowColor:[CPColor whiteColor]]; - [_textField setTextShadowOffset:CGSizeMake(0,1)]; + [_textField setTextShadowColor:[self valueForThemeAttribute:@"text-shadow-color"]]; + [_textField setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset"]]; [self addSubview:_textField]; } From 61d97338e2a91cf73000dd1144fb0bd63165ee19 Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Sun, 13 May 2018 19:48:33 +0200 Subject: [PATCH 3/5] FIXED: _CPMenuItemStandardView was bypassing theme for disabled text color (#2695) --- AppKit/CPMenuItem/_CPMenuItemStandardView.j | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AppKit/CPMenuItem/_CPMenuItemStandardView.j b/AppKit/CPMenuItem/_CPMenuItemStandardView.j index f7112befb..abfd1fead 100644 --- a/AppKit/CPMenuItem/_CPMenuItemStandardView.j +++ b/AppKit/CPMenuItem/_CPMenuItemStandardView.j @@ -55,6 +55,7 @@ @"menu-item-selection-color": [CPNull null], @"menu-item-text-shadow-color": [CPNull null], @"menu-item-text-color": [CPNull null], + @"menu-item-disabled-text-color": [CPColor lightGrayColor], @"menu-item-default-off-state-image": [CPNull null], @"menu-item-default-off-state-highlighted-image": [CPNull null], @"menu-item-default-on-state-image": [CPNull null], @@ -124,7 +125,7 @@ - (CPColor)textColor { if (![_menuItem isEnabled]) - return [CPColor lightGrayColor]; + return [self valueForThemeAttribute:@"menu-item-disabled-text-color"]; if (_highlighted) return [CPColor whiteColor]; From 3650c38aa9e9235eadf60a126af3502094747d60 Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Sun, 13 May 2018 19:49:18 +0200 Subject: [PATCH 4/5] FIXED: In CPSearchField, the space between the magnifier and the textfield was hard coded (#2690) --- AppKit/CPSearchField.j | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/AppKit/CPSearchField.j b/AppKit/CPSearchField.j index 4c65f04dc..a92c792e9 100644 --- a/AppKit/CPSearchField.j +++ b/AppKit/CPSearchField.j @@ -73,7 +73,8 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat @"image-cancel": [CPNull null], @"image-cancel-pressed": [CPNull null], @"image-search-inset" : CGInsetMake(0, 0, 0, 5), - @"image-cancel-inset" : CGInsetMake(0, 5, 0, 0) + @"image-cancel-inset" : CGInsetMake(0, 5, 0, 0), + @"search-right-margin": 2 }; } @@ -246,8 +247,9 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat if (_searchButton) { - var searchBounds = [self searchButtonRectForBounds:bounds]; - leftOffset = CGRectGetMaxX(searchBounds) + 2; + var searchBounds = [self searchButtonRectForBounds:bounds], + rightMargin = [self currentValueForThemeAttribute:@"search-right-margin"]; + leftOffset = CGRectGetMaxX(searchBounds) + rightMargin; } if (_cancelButton) From ff0ce164da386e2b4a37d34885e27cf6884ccd5f Mon Sep 17 00:00:00 2001 From: Didier Korthoudt Date: Mon, 14 May 2018 07:10:43 +0200 Subject: [PATCH 5/5] FIXED: CPTabView tabs were not reacting as in modern Cocoa (#2694) Before this commit, the segments of a tab view were selected at mouse down. Now, they are selected at mouse up and there is a visible feedback when tracking tabs. --- AppKit/CPTabView.j | 89 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 80c15e12c..84f6907ed 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -35,6 +35,7 @@ CPNoTabsLineBorder = 5; //Has no tabs and displays a line border. CPNoTabsNoBorder = 6; //Displays no tabs and no border. @class _CPTabViewBox +@class _CPSegmentedControl var CPTabViewDidSelectTabViewItemSelector = 1 << 1, CPTabViewShouldSelectTabViewItemSelector = 1 << 2, @@ -65,7 +66,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1, { CPArray _items; - CPSegmentedControl _tabs; + _CPSegmentedControl _tabs; _CPTabViewBox _box; CPView _placeholderView @accessors; @@ -92,8 +93,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1, - (void)_init { - _tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()]; - [_tabs setHitTests:NO]; + _tabs = [[_CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()]; + [_tabs setTabView:self]; [_tabs setSegments:[CPArray array]]; var height = [_tabs valueForThemeAttribute:@"min-size"].height; @@ -525,14 +526,6 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1, return [_box backgroundColor]; } -- (void)mouseDown:(CPEvent)anEvent -{ - var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]]; - - if (segmentIndex != CPNotFound && [self selectTabViewItemAtIndex:segmentIndex]) - [_tabs trackSegment:anEvent]; -} - - (void)_repositionTabs { var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2, @@ -887,3 +880,77 @@ var CPTabViewItemsKey = "CPTabViewItemsKey", } @end + +# pragma mark - + +// This subclass of CPSegmentedControl implements specific behaviour needed by CPTabView, which +// differs in some ways from normal CPSegmentedControl habits : +// +// - all items are enabled +// - when you select a tab (mouse down, holding) and drag upon another tab, the second one reacts +// (showing a pushed state) and can then be selected by releasing the mouse over it. +// - a delegate has the opportunity to accept or not the selection of an item + +@implementation _CPSegmentedControl : CPSegmentedControl +{ + CPTabView _tabView @accessors(property=tabView); +} + +- (void)trackSegment:(CPEvent)anEvent +{ + var type = [anEvent type], + location = [self convertPoint:[anEvent locationInWindow] fromView:nil], + currentSegment = [self testSegment:location]; + + switch (type) + { + case CPLeftMouseUp: + + if (_trackingSegment === CPNotFound) + return; + + if ((_trackingSegment !== _selectedSegment) && + [_tabView _sendDelegateShouldSelectTabViewItem:[_tabView tabViewItemAtIndex:_trackingSegment]]) + { + [self setSelected:YES forSegment:_trackingSegment]; + _selectedSegment = _trackingSegment; + [_tabView selectTabViewItemAtIndex:_selectedSegment]; + } + + [self drawSegmentBezel:_trackingSegment highlight:NO]; + + _trackingSegment = CPNotFound; + + return; + + case CPLeftMouseDown: + + if (currentSegment > CPNotFound) + { + _trackingSegment = currentSegment; + [self drawSegmentBezel:_trackingSegment highlight:YES]; + } + + break; + + case CPLeftMouseDragged: + + if (_trackingSegment !== currentSegment) + { + if (_trackingSegment > CPNotFound) + [self drawSegmentBezel:_trackingSegment highlight:NO]; + + _trackingSegment = currentSegment; + + if (_trackingSegment > CPNotFound) + [self drawSegmentBezel:_trackingSegment highlight:YES]; + } + + break; + } + + [CPApp setTarget:self selector:@selector(trackSegment:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; +} + +@end +