From 1c027c526b6b09cd7091824b4666d7ee3a62ee91 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Fri, 10 Mar 2017 17:40:39 +1100 Subject: [PATCH] Add segmented control implementation --- atom/browser/ui/cocoa/atom_touch_bar.mm | 86 ++++++++++++++++++++++++++++++++- lib/browser/api/touch-bar.js | 19 ++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index b2f8dc6..37dc6e7 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -18,6 +18,7 @@ static NSTouchBarItemIdentifier GroupIdentifier = @"com.electron.touchbar.group. static NSTouchBarItemIdentifier LabelIdentifier = @"com.electron.touchbar.label."; static NSTouchBarItemIdentifier PopoverIdentifier = @"com.electron.touchbar.popover."; static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slider."; +static NSTouchBarItemIdentifier SegmentedControlIdentifier = @"com.electron.touchbar.segmentedcontrol."; - (id)initWithDelegate:(id)delegate window:(atom::NativeWindow*)window @@ -97,6 +98,9 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide } else if ([identifier hasPrefix:GroupIdentifier]) { item_id = [self idFromIdentifier:identifier withPrefix:GroupIdentifier]; return [self makeGroupForID:item_id withIdentifier:identifier]; + } else if ([identifier hasPrefix:SegmentedControlIdentifier]) { + item_id = [self idFromIdentifier:identifier withPrefix:SegmentedControlIdentifier]; + return [self makeSegmentedControlForID:item_id withIdentifier:identifier]; } return nil; @@ -129,7 +133,8 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide [self updateSlider:(NSSliderTouchBarItem*)item withSettings:settings]; } else if (item_type == "popover") { [self updatePopover:(NSPopoverTouchBarItem*)item withSettings:settings]; - } + } else if (item_type == "segmented_control") + [self updateSegmentedControl:(NSCustomTouchBarItem*)item withSettings:settings]; } - (void)buttonAction:(id)sender { @@ -164,6 +169,14 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide return [identifier substringFromIndex:[prefix length]]; } +- (void)segmentedControlAction:(id)sender { + NSString* item_id = [NSString stringWithFormat:@"%ld", ((NSSegmentedControl*)sender).tag]; + base::DictionaryValue details; + details.SetInteger("selectedIndex", ((NSSegmentedControl*)sender).selectedSegment); + window_->NotifyTouchBarItemInteraction([item_id UTF8String], + details); +} + - (NSTouchBarItemIdentifier)identifierFromID:(const std::string&)item_id type:(const std::string&)type { NSTouchBarItemIdentifier base_identifier = nil; @@ -179,6 +192,8 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide base_identifier = PopoverIdentifier; else if (type == "group") base_identifier = GroupIdentifier; + else if (type == "segmented_control") + base_identifier = SegmentedControlIdentifier; if (base_identifier) return [NSString stringWithFormat:@"%@%s", base_identifier, item_id.data()]; @@ -384,4 +399,73 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide items:generatedItems]; } +- (NSTouchBarItem*)makeSegmentedControlForID:(NSString*)id + withIdentifier:(NSString*)identifier { + std::string s_id([id UTF8String]); + if (![self hasItemWithID:s_id]) return nil; + + mate::PersistentDictionary settings = settings_[s_id]; + base::scoped_nsobject item([[NSClassFromString( + @"NSCustomTouchBarItem") alloc] initWithIdentifier:identifier]); + + NSSegmentedControl* control = [NSSegmentedControl segmentedControlWithLabels:[NSMutableArray array] + trackingMode:NSSegmentSwitchTrackingSelectOne + target:self + action:@selector(segmentedControlAction:)]; + control.tag = [id floatValue]; + [item setView:control]; + + [self updateSegmentedControl:item withSettings:settings]; + return item.autorelease(); +} + +- (void)updateSegmentedControl:(NSCustomTouchBarItem*)item + withSettings:(const mate::PersistentDictionary&)settings { + + NSSegmentedControl* control = item.view; + + std::string segmentStyle; + settings.Get("segmentStyle", &segmentStyle); + if (segmentStyle == "automatic") + control.segmentStyle = NSSegmentStyleAutomatic; + else if (segmentStyle == "rounded") + control.segmentStyle = NSSegmentStyleRounded; + else if (segmentStyle == "textured-rounded") + control.segmentStyle = NSSegmentStyleTexturedRounded; + else if (segmentStyle == "round-rect") + control.segmentStyle = NSSegmentStyleRoundRect; + else if (segmentStyle == "textured-square") + control.segmentStyle = NSSegmentStyleTexturedSquare; + else if (segmentStyle == "capsule") + control.segmentStyle = NSSegmentStyleCapsule; + else if (segmentStyle == "small-square") + control.segmentStyle = NSSegmentStyleSmallSquare; + else if (segmentStyle == "separated") + control.segmentStyle = NSSegmentStyleSeparated; + else + control.segmentStyle = NSSegmentStyleAutomatic; + + std::vector segments; + settings.Get("segments", &segments); + + control.segmentCount = segments.size(); + for (int i = 0; i < (int)segments.size(); i++) { + std::string label; + gfx::Image image; + bool enabled = true; + segments[i].Get("enabled", &enabled); + if (segments[i].Get("label", &label)) { + [control setLabel:base::SysUTF8ToNSString(label) forSegment:i]; + } else if (segments[i].Get("icon", &image)) { + [control setImage:image.AsNSImage() forSegment:i]; + [control setImageScaling:NSImageScaleProportionallyUpOrDown forSegment:i]; + } + [control setEnabled:enabled forSegment:i]; + } + + int selectedIndex = 0; + settings.Get("selectedIndex", &selectedIndex); + control.selectedSegment = selectedIndex; +} + @end diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index ee7388f..a6e2e59 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -212,4 +212,23 @@ TouchBar.TouchBarSpacer = class TouchBarSpacer extends TouchBarItem { } } +TouchBar.TouchBarSegmentedControl = class TouchBarSegmentedControl extends TouchBarItem { + constructor (config) { + super() + if (config == null) config = {} + const {segmentStyle, segments, selectedIndex, change} = config + this.type = 'segmented_control' + this._addLiveProperty('segmentStyle', segmentStyle); + this._addLiveProperty('segments', segments || []); + this._addLiveProperty('selectedIndex', selectedIndex) + + if (typeof change === 'function') { + this.onInteraction = (details) => { + this._selectedIndex = details.selectedIndex; + change(details.selectedIndex); + } + } + } +} + module.exports = TouchBar -- 2.7.4