diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 026f86e599c5..b960290c82d3 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -14,6 +14,7 @@ #include "base/mac/scoped_nsobject.h" #include "content/public/browser/render_widget_host.h" #include "native_mate/constructor.h" +#include "native_mate/persistent_dictionary.h" @class AtomNSWindow; @class AtomNSWindowDelegate; @@ -103,7 +104,7 @@ class NativeWindowMac : public NativeWindow, void SetVibrancy(const std::string& type) override; void DestroyTouchBar() override; void SetTouchBar(mate::Arguments* args) override; - std::vector GetTouchBarItems(); + std::vector GetTouchBarItems(); // content::RenderWidgetHost::InputEventObserver: void OnInputEvent(const blink::WebInputEvent& event) override; @@ -158,7 +159,7 @@ class NativeWindowMac : public NativeWindow, base::scoped_nsobject window_; base::scoped_nsobject window_delegate_; - std::vector touch_bar_items_; + std::vector touch_bar_items_; // Event monitor for scroll wheel event. id wheel_event_monitor_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 1e83d133cfbd..b7537ecb7429 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -10,6 +10,7 @@ #include "atom/browser/window_list.h" #include "atom/common/color_util.h" #include "atom/common/draggable_region.h" +#include "atom/common/native_mate_converters/image_converter.h" #include "atom/common/options_switches.h" #include "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" @@ -361,7 +362,7 @@ bool ScopedDisableResize::disable_resize_ = false; @implementation AtomNSWindow NSMutableArray* bar_items_ = [[NSMutableArray alloc] init]; - std::map item_labels; + std::map item_id_map; - (void)setShell:(atom::NativeWindowMac*)shell { shell_ = shell; @@ -379,39 +380,29 @@ bool ScopedDisableResize::disable_resize_ = false; - (void)reloadTouchBar { bar_items_ = [[NSMutableArray alloc] init]; - std::vector items = shell_->GetTouchBarItems(); - std::map new_labels; - item_labels = new_labels; + std::vector items = shell_->GetTouchBarItems(); + std::map new_map; + item_id_map = new_map; - NSLog(@"reload"); - for (mate::Dictionary &item : items ) { - NSLog(@"reload iter"); + for (mate::PersistentDictionary &item : items ) { std::string type; std::string item_id; if (item.Get("type", &type) && item.Get("id", &item_id)) { NSLog(@"type: %@", [NSString stringWithUTF8String:type.c_str()]); NSLog(@"id: %@", [NSString stringWithUTF8String:item_id.c_str()]); + item_id_map.insert(make_pair(item_id, item)); if (type == "button") { - std::string label; - if (item.Get("label", &label)) { - [bar_items_ addObject:[NSString stringWithFormat:@"%@%@", ButtonIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]]; - item_labels.insert(make_pair(item_id, label)); - } + [bar_items_ addObject:[NSString stringWithFormat:@"%@%@", ButtonIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]]; } else if (type == "label") { - std::string label; - if (item.Get("label", &label)) { - [bar_items_ addObject:[NSString stringWithFormat:@"%@%@", LabelIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]]; - item_labels.insert(make_pair(item_id, label)); - } + [bar_items_ addObject:[NSString stringWithFormat:@"%@%@", LabelIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]]; } else if (type == "colorpicker") { [bar_items_ addObject:[NSString stringWithFormat:@"%@%@", ColorPickerIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]]; + } else if (type == "slider") { + [bar_items_ addObject:[NSString stringWithFormat:@"%@%@", SliderIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]]; } } } - // [bar_items_ addObject:@"com.electron.tb.button.1"]; - // [bar_items_ addObject:@"com.electron.tb.button.2"]; [bar_items_ addObject:NSTouchBarItemIdentifierOtherItemsProxy]; - // NSLog(@"Reloading Touch Bar --> '%@'", bar_items_[1]); self.touchBar = nil; } @@ -445,11 +436,11 @@ bool ScopedDisableResize::disable_resize_ = false; shell_->NotifyTouchBarItemInteraction("color_picker", { std::string([item_id UTF8String]), std::string([colorHexString UTF8String]) }); } -static NSTouchBarItemIdentifier ButtonIdentifier = @"com.electron.tb.button."; -static NSTouchBarItemIdentifier ColorPickerIdentifier = @"com.electron.tb.colorpicker."; -// static NSTouchBarItemIdentifier ListIdentifier = @"com.electron.tb.list."; -static NSTouchBarItemIdentifier LabelIdentifier = @"com.electron.tb.label."; -// static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.tb.slider."; +- (void)sliderAction:(id)sender { + NSString* item_id = ((NSSliderTouchBarItem *)sender).identifier; + NSLog(@"Slider with ID: '%@' was changed", item_id); + shell_->NotifyTouchBarItemInteraction("slider", { std::string([item_id UTF8String]), std::to_string([((NSSliderTouchBarItem *)sender).slider intValue]) }); +} - (NSString*)idFromIdentifier:(NSString*)identifier withPrefix:(NSString*)prefix { NSString *idCopy = [identifier copy]; @@ -457,35 +448,164 @@ static NSTouchBarItemIdentifier LabelIdentifier = @"com.electron.tb.label."; return idCopy; } -- (bool)hasLabel:(NSString*)id { - return item_labels.find(std::string([id UTF8String])) != item_labels.end(); +- (bool)hasTBDict:(std::string)id { + return item_id_map.find(id) != item_id_map.end(); } -- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier hasPrefix:ButtonIdentifier]) { - NSString* id = [self idFromIdentifier:identifier withPrefix:ButtonIdentifier]; - if (![self hasLabel:id]) return nil; - NSButton *theButton = [NSButton buttonWithTitle:[NSString stringWithUTF8String:item_labels[std::string([id UTF8String])].c_str()] target:self action:@selector(buttonAction:)]; +- (NSColor*)colorFromHexColorString:(NSString*)inColorString { + NSColor* result = nil; + unsigned colorCode = 0; + unsigned char redByte, greenByte, blueByte; + + if (nil != inColorString) + { + NSScanner* scanner = [NSScanner scannerWithString:inColorString]; + (void) [scanner scanHexInt:&colorCode]; // ignore error + } + redByte = (unsigned char)(colorCode >> 16); + greenByte = (unsigned char)(colorCode >> 8); + blueByte = (unsigned char)(colorCode); // masks off high bits + + result = [NSColor + colorWithCalibratedRed:(CGFloat)redByte / 0xff + green:(CGFloat)greenByte / 0xff + blue:(CGFloat)blueByte / 0xff + alpha:1.0]; + return result; +} + +- (nullable NSTouchBarItem *)makeButtonForID:(NSString*)id withIdentifier:(NSString*)identifier { + std::string s_id = std::string([id UTF8String]); + if (![self hasTBDict:s_id]) return nil; + mate::PersistentDictionary item = item_id_map[s_id]; + std::string label; + if (item.Get("label", &label)) { + NSButton *theButton = [NSButton buttonWithTitle:[NSString stringWithUTF8String:label.c_str()] target:self action:@selector(buttonAction:)]; theButton.tag = [id floatValue]; NSCustomTouchBarItem *customItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; customItem.view = theButton; + std::string customizationLabel; + if (item.Get("customizationLabel", &customizationLabel)) { + customItem.customizationLabel = [NSString stringWithUTF8String:customizationLabel.c_str()]; + } + + std::string backgroundColor; + if (item.Get("backgroundColor", &backgroundColor)) { + theButton.bezelColor = [self colorFromHexColorString:[NSString stringWithUTF8String:backgroundColor.c_str()]]; + } + + std::string labelColor; + if (item.Get("labelColor", &labelColor)) { + NSMutableAttributedString *attrTitle = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithUTF8String:label.c_str()]]; + NSUInteger len = [attrTitle length]; + NSRange range = NSMakeRange(0, len); + [attrTitle addAttribute:NSForegroundColorAttributeName value:[self colorFromHexColorString:[NSString stringWithUTF8String:labelColor.c_str()]] range:range]; + [attrTitle fixAttributesInRange:range]; + [theButton setAttributedTitle:attrTitle]; + } + + gfx::Image image; + if (item.Get("image", &image)) { + theButton.image = image.AsNSImage(); + } + return customItem; - } else if ([identifier hasPrefix:LabelIdentifier]) { - NSString* id = [self idFromIdentifier:identifier withPrefix:LabelIdentifier]; - if (![self hasLabel:id]) return nil; - NSTextField *theLabel = [NSTextField labelWithString:[NSString stringWithUTF8String:item_labels[std::string([id UTF8String])].c_str()]]; + } + return nil; +} + +- (nullable NSTouchBarItem*) makeLabelForID:(NSString*)id withIdentifier:(NSString*)identifier { + std::string s_id = std::string([id UTF8String]); + NSLog(@"Making label: '%@'", id); + if (![self hasTBDict:s_id]) return nil; + mate::PersistentDictionary item = item_id_map[s_id]; + std::string label; + if (item.Get("label", &label)) { + NSTextField *theLabel = [NSTextField labelWithString:[NSString stringWithUTF8String:label.c_str()]]; NSCustomTouchBarItem *customItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; customItem.view = theLabel; + std::string customizationLabel; + if (item.Get("customizationLabel", &customizationLabel)) { + customItem.customizationLabel = [NSString stringWithUTF8String:customizationLabel.c_str()]; + } + return customItem; + } + return nil; +} + +- (nullable NSTouchBarItem*) makeColorPickerForID:(NSString*)id withIdentifier:(NSString*)identifier { + std::string s_id = std::string([id UTF8String]); + if (![self hasTBDict:s_id]) return nil; + mate::PersistentDictionary item = item_id_map[s_id]; + + NSColorPickerTouchBarItem *colorPickerItem = [[NSColorPickerTouchBarItem alloc] initWithIdentifier:identifier]; + colorPickerItem.target = self; + colorPickerItem.action = @selector(colorPickerAction:); + + std::string customizationLabel; + if (item.Get("customizationLabel", &customizationLabel)) { + colorPickerItem.customizationLabel = [NSString stringWithUTF8String:customizationLabel.c_str()]; + } + + return colorPickerItem; +} + +- (nullable NSTouchBarItem*) makeSliderForID:(NSString*)id withIdentifier:(NSString*)identifier { + std::string s_id = std::string([id UTF8String]); + if (![self hasTBDict:s_id]) return nil; + mate::PersistentDictionary item = item_id_map[s_id]; + + NSSliderTouchBarItem *sliderItem = [[NSSliderTouchBarItem alloc] initWithIdentifier:identifier]; + sliderItem.target = self; + sliderItem.action = @selector(sliderAction:); + + std::string customizationLabel; + if (item.Get("customizationLabel", &customizationLabel)) { + sliderItem.customizationLabel = [NSString stringWithUTF8String:customizationLabel.c_str()]; + } + + std::string label; + if (item.Get("label", &label)) { + sliderItem.label = [NSString stringWithUTF8String:label.c_str()]; + } + + int maxValue = 100; + int minValue = 0; + int initialValue = 50; + if (item.Get("minValue", &minValue) && item.Get("maxValue", &maxValue)) { + item.Get("initialValue", &initialValue); + } + sliderItem.slider.minValue = minValue; + sliderItem.slider.maxValue = maxValue; + sliderItem.slider.doubleValue = initialValue; + + return sliderItem; +} + +static NSTouchBarItemIdentifier ButtonIdentifier = @"com.electron.tb.button."; +static NSTouchBarItemIdentifier ColorPickerIdentifier = @"com.electron.tb.colorpicker."; +// static NSTouchBarItemIdentifier ListIdentifier = @"com.electron.tb.list."; +static NSTouchBarItemIdentifier LabelIdentifier = @"com.electron.tb.label."; +static NSTouchBarItemIdentifier SliderIdentifier = @"com.electron.tb.slider."; + +- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { + if ([identifier hasPrefix:ButtonIdentifier]) { + NSString* id = [self idFromIdentifier:identifier withPrefix:ButtonIdentifier]; + return [self makeButtonForID:id withIdentifier:identifier]; + } else if ([identifier hasPrefix:LabelIdentifier]) { + NSString* id = [self idFromIdentifier:identifier withPrefix:LabelIdentifier]; + return [self makeLabelForID:id withIdentifier:identifier]; } else if ([identifier hasPrefix:ColorPickerIdentifier]) { - NSColorPickerTouchBarItem *colorPickerItem = [[NSColorPickerTouchBarItem alloc] initWithIdentifier:identifier]; - colorPickerItem.target = self; - colorPickerItem.action = @selector(colorPickerAction:); - return colorPickerItem; + NSString* id = [self idFromIdentifier:identifier withPrefix:ColorPickerIdentifier]; + return [self makeColorPickerForID:id withIdentifier:identifier]; + } else if ([identifier hasPrefix:SliderIdentifier]) { + NSString* id = [self idFromIdentifier:identifier withPrefix:SliderIdentifier]; + return [self makeSliderForID:id withIdentifier:identifier]; } return nil; @@ -1480,16 +1600,14 @@ void NativeWindowMac::DestroyTouchBar() { } void NativeWindowMac::SetTouchBar(mate::Arguments* args) { - std::vector items; - LOG(ERROR) << "FOO"; + std::vector items; if (args->GetNext(&items)) { - LOG(ERROR) << "BAR"; touch_bar_items_ = items; [window_ reloadTouchBar]; } } -std::vector NativeWindowMac::GetTouchBarItems() { +std::vector NativeWindowMac::GetTouchBarItems() { return touch_bar_items_; } diff --git a/default_app/default_app.js b/default_app/default_app.js index 3856c8e90abe..17f591b48fd0 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -28,6 +28,8 @@ exports.load = (appUrl) => { mainWindow.setTouchBar(new TouchBar([ new (TouchBar.Button)({ label: 'Hello World!', + backgroundColor: "DDDDDD", + labelColor: "000000", click: () => { console.log('Hello World Clicked') } @@ -36,10 +38,18 @@ exports.load = (appUrl) => { label: 'This is a Label' }), new (TouchBar.ColorPicker)({ - change: (...args) => { - console.log('Color was changed', ...args) + change: (newColor) => { + console.log('Color was changed', newColor) } - }) + }), + new (TouchBar.Slider)({ + label: 'Slider 123', + minValue: 50, + maxValue: 1000, + change: (newVal) => { + console.log('Slider was changed', newVal, typeof newVal) + } + }), ])) }) } diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index fd72a4cf0f88..ba1fdadcb62a 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -134,7 +134,7 @@ BrowserWindow.prototype._init = function () { // Proxy TouchBar events this.on('-touch-bar-interaction', (event, item_type, id, ...args) => { - TouchBar._event(id, ...args) + TouchBar._event(item_type, id, ...args) }) } diff --git a/lib/browser/api/touch-bar.js b/lib/browser/api/touch-bar.js index f62d7c2ff03a..0709e07f1c98 100644 --- a/lib/browser/api/touch-bar.js +++ b/lib/browser/api/touch-bar.js @@ -23,8 +23,11 @@ class TouchBar { let item_id_incrementor = 1 const item_event_handlers = {} -TouchBar._event = (eventArgs) => { - const args = eventArgs.slice(1) +TouchBar._event = (itemType, eventArgs) => { + let args = eventArgs.slice(1) + if (itemType === 'slider') { + args = args.map(val => parseInt(val, 10)) + } const id_parts = eventArgs[0].split('.') const item_id = id_parts[id_parts.length - 1] if (item_event_handlers[item_id]) item_event_handlers[item_id](...args) @@ -79,11 +82,17 @@ TouchBar.Label = class TouchBarLabel extends TouchBarItem { } } -TouchBar.List = class TouchBarList extends TouchBarItem {} +TouchBar.List = class TouchBarList extends TouchBarItem { + constructor (config) { + super(config) + this.config.type = 'list' + } +} TouchBar.Slider = class TouchBarSlider extends TouchBarItem { constructor (config) { super(config) + this.config.type = 'slider'; const change = this.config.change if (typeof change === 'function') { item_event_handlers[this.id] = change