From cbb6f8c33ec4caa82f3bb9cd1f3010bed0c6f89a Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Tue, 28 Feb 2017 15:37:15 -0800 Subject: [PATCH] Store event listeners in each TouchBar class --- atom/browser/api/atom_api_window.cc | 6 +- atom/browser/api/atom_api_window.h | 4 +- atom/browser/native_window.cc | 6 +- atom/browser/native_window.h | 4 +- atom/browser/native_window_observer.h | 5 +- atom/browser/ui/cocoa/atom_touch_bar.mm | 33 ++++-- lib/browser/api/browser-window.js | 14 +-- lib/browser/api/touch-bar.js | 134 +++++++++++------------- 8 files changed, 104 insertions(+), 102 deletions(-) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index adafab9173b1..6c14d8b3c679 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -282,9 +282,9 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) { Emit("app-command", command_name); } -void Window::OnTouchBarItemResult(const std::string& item_type, - const std::vector& args) { - Emit("-touch-bar-interaction", item_type, args); +void Window::OnTouchBarItemResult(const std::string& item_id, + const base::DictionaryValue& details) { + Emit("-touch-bar-interaction", item_id, details); } #if defined(OS_WIN) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 2620292b253e..bf3e8cb5e761 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -85,8 +85,8 @@ class Window : public mate::TrackableObject, void OnRendererUnresponsive() override; void OnRendererResponsive() override; void OnExecuteWindowsCommand(const std::string& command_name) override; - void OnTouchBarItemResult(const std::string& item_type, - const std::vector& args) override; + void OnTouchBarItemResult(const std::string& item_id, + const base::DictionaryValue& details) override; #if defined(OS_WIN) void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index b008739709c6..322ca8a0e4fe 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -576,10 +576,10 @@ void NativeWindow::NotifyWindowExecuteWindowsCommand( } void NativeWindow::NotifyTouchBarItemInteraction( - const std::string& type, - const std::vector& args) { + const std::string& item_id, + const base::DictionaryValue& details) { for (NativeWindowObserver& observer : observers_) - observer.OnTouchBarItemResult(type, args); + observer.OnTouchBarItemResult(item_id, details); } #if defined(OS_WIN) diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 23c393e7aee2..77188d849402 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -234,8 +234,8 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowEnterHtmlFullScreen(); void NotifyWindowLeaveHtmlFullScreen(); void NotifyWindowExecuteWindowsCommand(const std::string& command); - void NotifyTouchBarItemInteraction(const std::string& item_type, - const std::vector& args); + void NotifyTouchBarItemInteraction(const std::string& item_id, + const base::DictionaryValue& details); #if defined(OS_WIN) void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param); diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 7fd1b7caebd3..7f1f5aace82a 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -9,6 +9,7 @@ #include #include "base/strings/string16.h" +#include "base/values.h" #include "ui/base/window_open_disposition.h" #include "url/gurl.h" @@ -71,8 +72,8 @@ class NativeWindowObserver { virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} virtual void OnWindowLeaveHtmlFullScreen() {} - virtual void OnTouchBarItemResult(const std::string& item_type, - const std::vector& args) {} + virtual void OnTouchBarItemResult(const std::string& item_id, + const base::DictionaryValue& details) {} // Called when window message received #if defined(OS_WIN) diff --git a/atom/browser/ui/cocoa/atom_touch_bar.mm b/atom/browser/ui/cocoa/atom_touch_bar.mm index f24baad10aa1..194be6f5a801 100644 --- a/atom/browser/ui/cocoa/atom_touch_bar.mm +++ b/atom/browser/ui/cocoa/atom_touch_bar.mm @@ -131,20 +131,30 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide } - (void)buttonAction:(id)sender { - NSString* item_id = [NSString stringWithFormat:@"%@.%d", ButtonIdentifier, (int)((NSButton*)sender).tag]; - window_->NotifyTouchBarItemInteraction("button", { std::string([item_id UTF8String]) }); + NSString* item_id = [NSString stringWithFormat:@"%ld", ((NSButton*)sender).tag]; + window_->NotifyTouchBarItemInteraction([item_id UTF8String], + base::DictionaryValue()); } - (void)colorPickerAction:(id)sender { - NSString* item_id = ((NSColorPickerTouchBarItem*)sender).identifier; + NSString* identifier = ((NSColorPickerTouchBarItem*)sender).identifier; + NSString* item_id = [self idFromIdentifier:identifier + withPrefix:ColorPickerIdentifier]; NSColor* color = ((NSColorPickerTouchBarItem*)sender).color; std::string hex_color = atom::ToRGBHex(skia::NSDeviceColorToSkColor(color)); - window_->NotifyTouchBarItemInteraction("color_picker", { std::string([item_id UTF8String]), hex_color }); + base::DictionaryValue details; + details.SetString("color", hex_color); + window_->NotifyTouchBarItemInteraction([item_id UTF8String], details); } - (void)sliderAction:(id)sender { - NSString* item_id = ((NSSliderTouchBarItem*)sender).identifier; - window_->NotifyTouchBarItemInteraction("slider", { std::string([item_id UTF8String]), std::to_string([((NSSliderTouchBarItem*)sender).slider intValue]) }); + NSString* identifier = ((NSSliderTouchBarItem*)sender).identifier; + NSString* item_id = [self idFromIdentifier:identifier + withPrefix:SliderIdentifier]; + base::DictionaryValue details; + details.SetInteger("value", + [((NSSliderTouchBarItem*)sender).slider intValue]); + window_->NotifyTouchBarItemInteraction([item_id UTF8String], details); } - (NSString*)idFromIdentifier:(NSString*)identifier withPrefix:(NSString*)prefix { @@ -326,9 +336,10 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide item.showsCloseButton = showCloseButton; } - std::vector touchBar; - if (options.Get("touchBar", &touchBar)) { - item.popoverTouchBar = [self touchBarFromItemIdentifiers:[self identifierArrayFromDicts:touchBar]]; + mate::PersistentDictionary child; + std::vector items; + if (options.Get("child", &child) && child.Get("ordereredItems", &items)) { + item.popoverTouchBar = [self touchBarFromItemIdentifiers:[self identifierArrayFromDicts:items]]; } } @@ -338,8 +349,10 @@ static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.touchbar.slide if (![self hasItemWithID:s_id]) return nil; mate::PersistentDictionary options = item_id_map[s_id]; + mate::PersistentDictionary child; + if (!options.Get("child", &child)) return nil; std::vector items; - if (!options.Get("items", &items)) return nil; + if (!child.Get("ordereredItems", &items)) return nil; NSMutableArray* generatedItems = [[NSMutableArray alloc] init]; NSMutableArray* identList = [self identifierArrayFromDicts:items]; diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index ecfd9195f430..a8a81cbd59d1 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -133,8 +133,10 @@ BrowserWindow.prototype._init = function () { }) // Proxy TouchBar events - this.on('-touch-bar-interaction', (event, itemType, id, ...args) => { - TouchBar._event(itemType, id, ...args) + this.on('-touch-bar-interaction', (event, id, details) => { + if (this._touchBar != null) { + this._touchBar.emit('interaction', id, details) + } }) } @@ -207,6 +209,7 @@ Object.assign(BrowserWindow.prototype, { BrowserWindow.prototype.setTouchBar = function (touchBar) { if (touchBar == null) { this._destroyTouchBar() + this._touchBar = null return } @@ -214,11 +217,8 @@ BrowserWindow.prototype.setTouchBar = function (touchBar) { touchBar = new TouchBar(touchBar) } - this._setTouchBar(touchBar.toJSON()) - touchBar._owner = this - touchBar.items.forEach((item) => { - item._owner = this - }) + this._touchBar = touchBar + this._setTouchBar(touchBar.ordereredItems) } BrowserWindow.prototype._updateTouchBarItem = function (itemID) { diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index 07b2631a77dd..fe75e3ade566 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -1,82 +1,67 @@ -class TouchBar { +const {EventEmitter} = require('events') + +let itemIdIncrementor = 1 + +class TouchBar extends EventEmitter { constructor (items) { - this.items = items + super() + if (!Array.isArray(items)) { throw new Error('The items object provided has to be an array') } + + this.items = {} + this.ordereredItems = [] + const registerItem = (item) => { + this.items[item.id] = item + if (item.child instanceof TouchBar) { + item.child.ordereredItems.forEach(registerItem) + } + } items.forEach((item) => { - if (!item.id) { + this.ordereredItems.push(item) + if (!(item instanceof TouchBarItem)) { throw new Error('Each item must be an instance of a TouchBarItem') } + registerItem(item) + }) + + this.on('interaction', (itemID, details) => { + const item = this.items[itemID] + if (item != null && item.onInteraction != null) { + item.onInteraction(details) + } }) } - - toJSON () { - return this.items.map((item) => item.toJSON ? item.toJSON() : item) - } -} - -let itemIdIncrementor = 1 -const itemEventHandlers = {} - -TouchBar._event = (itemType, eventArgs) => { - let args = eventArgs.slice(1) - if (itemType === 'slider') { - args = args.map(val => parseInt(val, 10)) - } - const idParts = eventArgs[0].split('.') - const itemId = idParts[idParts.length - 1] - if (itemEventHandlers[itemId]) itemEventHandlers[itemId](...args) } class TouchBarItem { constructor (config) { - this.id = itemIdIncrementor++ - const mConfig = Object.assign({}, config || {}) - Object.defineProperty(this, 'config', { - configurable: false, - enumerable: false, - get: () => mConfig - }) - this.config.id = `${this.config.id || this.id}` - if (typeof this.config !== 'object' || this.config === null) { - throw new Error('Provided config must be a non-null object') - } - } - - updateConfig (newConfig) { - if (!this._owner) { - throw new Error('Cannot call methods on TouchBarItems without assigning to a BrowserWindow') - } - const dupConfig = Object.assign({}, newConfig) - delete dupConfig.id - Object.assign(this.config, dupConfig) - this._owner._updateTouchBarItem(this.toJSON()) - } - - toJSON () { - return this.config + this.id = `${itemIdIncrementor++}` } } TouchBar.Button = class TouchBarButton extends TouchBarItem { constructor (config) { super(config) - this.config.type = 'button' - const click = config.click - if (typeof click === 'function') { - itemEventHandlers[`${this.id}`] = click - } + this.type = 'button' + this.label = config.label + this.backgroundColor = config.backgroundColor + this.labelColor = config.labelColor + this.onInteraction = config.click } } TouchBar.ColorPicker = class TouchBarColorPicker extends TouchBarItem { constructor (config) { super(config) - this.config.type = 'colorpicker' - const change = this.config.change + this.type = 'colorpicker' + + const {change} = config if (typeof change === 'function') { - itemEventHandlers[`${this.id}`] = change + this.onInteraction = (details) => { + change(details.color) + } } } } @@ -84,45 +69,48 @@ TouchBar.ColorPicker = class TouchBarColorPicker extends TouchBarItem { TouchBar.Group = class TouchBarGroup extends TouchBarItem { constructor (config) { super(config) - this.config.type = 'group' - } - - toJSON () { - const config = this.config - return Object.assign({}, config, { - items: config.items && config.items.toJSON ? config.items.toJSON() : [] - }) + this.type = 'group' + this.child = config.items + if (!(this.child instanceof TouchBar)) { + this.child = new TouchBar(this.items) + } } } TouchBar.Label = class TouchBarLabel extends TouchBarItem { constructor (config) { super(config) - this.config.type = 'label' + this.type = 'label' + this.label = config.label } } TouchBar.PopOver = class TouchBarPopOver extends TouchBarItem { constructor (config) { super(config) - this.config.type = 'popover' - } - - toJSON () { - const config = this.config - return Object.assign({}, config, { - touchBar: config.touchBar && config.touchBar.toJSON ? config.touchBar.toJSON() : [] - }) + this.type = 'popover' + this.label = config.label + this.showCloseButton = config.showCloseButton + this.child = config.items + if (!(this.child instanceof TouchBar)) { + this.child = new TouchBar(this.items) + } } } TouchBar.Slider = class TouchBarSlider extends TouchBarItem { constructor (config) { super(config) - this.config.type = 'slider' - const change = this.config.change + this.type = 'slider' + this.minValue = config.minValue + this.maxValue = config.maxValue + this.initialValue = config.initialValue + + const {change} = config if (typeof change === 'function') { - itemEventHandlers[this.id] = change + this.onInteraction = (details) => { + change(details.value) + } } } }