Browse Source

Make dynamic buttons work along with click events

Samuel Attard 8 years ago
parent
commit
7857c83ea1

+ 9 - 4
atom/browser/api/atom_api_window.cc

@@ -283,7 +283,7 @@ void Window::OnExecuteWindowsCommand(const std::string& command_name) {
 }
 
 void Window::OnTouchBarItemResult(const std::string& item_type, const std::string& item_id) {
-  Emit("_touch-bar-interaction", item_type, item_id);
+  Emit("-touch-bar-interaction", item_type, item_id);
 }
 
 #if defined(OS_WIN)
@@ -844,8 +844,12 @@ void Window::SetVibrancy(mate::Arguments* args) {
   window_->SetVibrancy(type);
 }
 
-void Window::InitTouchBar()  {
-  window_->InitTouchBar();
+void Window::DestroyTouchBar()  {
+  window_->DestroyTouchBar();
+}
+
+void Window::SetTouchBar(mate::Arguments* args) {
+  window_->SetTouchBar(args);
 }
 
 int32_t Window::ID() const {
@@ -968,7 +972,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
       .SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
 #endif
       .SetMethod("setVibrancy", &Window::SetVibrancy)
-      .SetMethod("initTouchBar", &Window::InitTouchBar)
+      .SetMethod("_destroyTouchBar", &Window::DestroyTouchBar)
+      .SetMethod("_setTouchBar", &Window::SetTouchBar)
 #if defined(OS_WIN)
       .SetMethod("hookWindowMessage", &Window::HookWindowMessage)
       .SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)

+ 2 - 1
atom/browser/api/atom_api_window.h

@@ -204,7 +204,8 @@ class Window : public mate::TrackableObject<Window>,
   void SetAutoHideCursor(bool auto_hide);
 
   void SetVibrancy(mate::Arguments* args);
-  void InitTouchBar();
+  void DestroyTouchBar();
+  void SetTouchBar(mate::Arguments* args);
 
   v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
 

+ 5 - 1
atom/browser/native_window.cc

@@ -33,6 +33,7 @@
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/common/content_switches.h"
 #include "ipc/ipc_message_macros.h"
+#include "native_mate/constructor.h"
 #include "native_mate/dictionary.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/gfx/codec/png_codec.h"
@@ -340,7 +341,10 @@ void NativeWindow::SetAutoHideCursor(bool auto_hide) {
 void NativeWindow::SetVibrancy(const std::string& filename) {
 }
 
-void NativeWindow::InitTouchBar() {
+void NativeWindow::DestroyTouchBar() {
+}
+
+void NativeWindow::SetTouchBar(mate::Arguments* args) {
 }
 
 void NativeWindow::FocusOnWebView() {

+ 3 - 1
atom/browser/native_window.h

@@ -23,6 +23,7 @@
 #include "extensions/browser/app_window/size_constraints.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
+#include "native_mate/constructor.h"
 
 class SkRegion;
 
@@ -170,7 +171,8 @@ class NativeWindow : public base::SupportsUserData,
   virtual void SetVibrancy(const std::string& type);
 
   // Touchbar API
-  virtual void InitTouchBar();
+  virtual void DestroyTouchBar();
+  virtual void SetTouchBar(mate::Arguments* args);
 
   // Webview APIs.
   virtual void FocusOnWebView();

+ 6 - 1
atom/browser/native_window_mac.h

@@ -13,6 +13,7 @@
 #include "atom/browser/native_window.h"
 #include "base/mac/scoped_nsobject.h"
 #include "content/public/browser/render_widget_host.h"
+#include "native_mate/constructor.h"
 
 @class AtomNSWindow;
 @class AtomNSWindowDelegate;
@@ -100,7 +101,9 @@ class NativeWindowMac : public NativeWindow,
   void SetAutoHideCursor(bool auto_hide) override;
 
   void SetVibrancy(const std::string& type) override;
-  void InitTouchBar() override;
+  void DestroyTouchBar() override;
+  void SetTouchBar(mate::Arguments* args) override;
+  std::vector<mate::Dictionary> GetTouchBarItems();
 
   // content::RenderWidgetHost::InputEventObserver:
   void OnInputEvent(const blink::WebInputEvent& event) override;
@@ -155,6 +158,8 @@ class NativeWindowMac : public NativeWindow,
   base::scoped_nsobject<AtomNSWindow> window_;
   base::scoped_nsobject<AtomNSWindowDelegate> window_delegate_;
 
+  std::vector<mate::Dictionary> touch_bar_items_;
+
   // Event monitor for scroll wheel event.
   id wheel_event_monitor_;
 

+ 55 - 10
atom/browser/native_window_mac.mm

@@ -352,6 +352,8 @@ bool ScopedDisableResize::disable_resize_ = false;
 - (void)setEnableLargerThanScreen:(bool)enable;
 - (void)enableWindowButtonsOffset;
 - (void)reloadTouchBar;
+- (void)resetTouchBar;
+- (NSTouchBar*)touchBarFromMutatableArray:(NSMutableArray<NSTouchBarItemIdentifier>*)items;
 @end
 
 @interface AtomNSWindow () <NSTouchBarDelegate>
@@ -359,6 +361,7 @@ bool ScopedDisableResize::disable_resize_ = false;
 
 @implementation AtomNSWindow
   NSMutableArray<NSTouchBarItemIdentifier>* bar_items_ = [[NSMutableArray alloc] init];
+  std::map<std::string, std::string> button_labels;
 
 - (void)setShell:(atom::NativeWindowMac*)shell {
   shell_ = shell;
@@ -368,24 +371,52 @@ bool ScopedDisableResize::disable_resize_ = false;
   enable_larger_than_screen_ = enable;
 }
 
+- (void)resetTouchBar {
+  bar_items_ = [[NSMutableArray alloc] init];
+  self.touchBar = nil;
+  NSLog(@"Destroying TouchBar");
+}
+
 - (void)reloadTouchBar {
   bar_items_ = [[NSMutableArray alloc] init];
-  [bar_items_ addObject:@"com.electron.tb.button.1"];
-  [bar_items_ addObject:@"com.electron.tb.button.2"];
+  std::vector<mate::Dictionary> items = shell_->GetTouchBarItems();
+  std::map<std::string, std::string> new_button_labels;
+  button_labels = new_button_labels;
+
+  NSLog(@"reload");
+  for (mate::Dictionary &item : items ) {
+    NSLog(@"reload iter");
+    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()]);
+      if (type == "button") {
+        std::string label;
+        if (item.Get("label", &label)) {
+          [bar_items_ addObject:[NSString stringWithFormat:@"%@%@", ButtonIdentifier, [NSString stringWithUTF8String:item_id.c_str()]]];
+          button_labels.insert(make_pair(item_id, label));
+        }
+      }
+    }
+  }
+  // [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]);
+  // NSLog(@"Reloading Touch Bar --> '%@'", bar_items_[1]);
   self.touchBar = nil;
 }
 
 - (NSTouchBar *)makeTouchBar {
   NSLog(@"Making Touch Bar");
+  return [self touchBarFromMutatableArray:bar_items_];
+}
+
+- (NSTouchBar *)touchBarFromMutatableArray:(NSMutableArray<NSTouchBarItemIdentifier>*)items {
   NSTouchBar* bar = [[NSTouchBar alloc] init];
   bar.delegate = self;
 
-  // Set the default ordering of items.
-
-  // NSLog(@"%@", bar_items_[1]);
-  bar.defaultItemIdentifiers = [bar_items_ copy];
+  bar.defaultItemIdentifiers = [items copy];
 
   return bar;
 }
@@ -412,7 +443,7 @@ static NSTouchBarItemIdentifier LabelIdentifier = @"com.electron.tb.label.";
   if ([identifier hasPrefix:ButtonIdentifier]) {
     NSString *idCopy = [identifier copy];
     idCopy = [identifier substringFromIndex:[ButtonIdentifier length]];
-    NSButton *theButton = [NSButton buttonWithTitle:@"Electron Button" target:self action:@selector(buttonAction:)];
+    NSButton *theButton = [NSButton buttonWithTitle:[NSString stringWithUTF8String:button_labels[std::string([idCopy UTF8String])].c_str()] target:self action:@selector(buttonAction:)];
     theButton.tag = [idCopy floatValue];
 
     NSCustomTouchBarItem *customItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
@@ -1420,8 +1451,22 @@ void NativeWindowMac::SetVibrancy(const std::string& type) {
   [effect_view setMaterial:vibrancyType];
 }
 
-void NativeWindowMac::InitTouchBar() {
-  [window_ reloadTouchBar];
+void NativeWindowMac::DestroyTouchBar() {
+  [window_ resetTouchBar];
+}
+
+void NativeWindowMac::SetTouchBar(mate::Arguments* args) {
+  std::vector<mate::Dictionary> items;
+  LOG(ERROR) << "FOO";
+  if (args->GetNext(&items)) {
+    LOG(ERROR) << "BAR";
+    touch_bar_items_ = items;
+    [window_ reloadTouchBar];
+  }
+}
+
+std::vector<mate::Dictionary> NativeWindowMac::GetTouchBarItems() {
+  return touch_bar_items_;
 }
 
 void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {

+ 10 - 1
default_app/default_app.js

@@ -1,4 +1,4 @@
-const {app, BrowserWindow} = require('electron')
+const {app, BrowserWindow,TouchBar} = require('electron')
 const path = require('path')
 
 let mainWindow = null
@@ -24,5 +24,14 @@ exports.load = (appUrl) => {
     mainWindow = new BrowserWindow(options)
     mainWindow.loadURL(appUrl)
     mainWindow.focus()
+
+    mainWindow.setTouchBar(new TouchBar([
+      new (TouchBar.Button)({
+        label: 'Hello World!',
+        click: () => {
+          console.log('Hello World Clicked')
+        }
+      })
+    ]))
   })
 }

+ 1 - 0
filenames.gypi

@@ -30,6 +30,7 @@
       'lib/browser/api/session.js',
       'lib/browser/api/screen.js',
       'lib/browser/api/system-preferences.js',
+      'lib/browser/api/touch-bar.js',
       'lib/browser/api/tray.js',
       'lib/browser/api/web-contents.js',
       'lib/browser/chrome-extension.js',

+ 17 - 1
lib/browser/api/browser-window.js

@@ -1,6 +1,6 @@
 'use strict'
 
-const {ipcMain} = require('electron')
+const {ipcMain,TouchBar} = require('electron')
 const {EventEmitter} = require('events')
 const {BrowserWindow} = process.atomBinding('window')
 const v8Util = process.atomBinding('v8_util')
@@ -131,6 +131,11 @@ BrowserWindow.prototype._init = function () {
       return this.webContents.devToolsWebContents
     }
   })
+
+  // Proxy TouchBar events
+  this.on('-touch-bar-interaction', (event, item_type, id, ...args) => {
+    TouchBar._event(id, ...args)
+  })
 }
 
 BrowserWindow.getFocusedWindow = () => {
@@ -198,4 +203,15 @@ Object.assign(BrowserWindow.prototype, {
   }
 })
 
+// TouchBar API
+BrowserWindow.prototype.setTouchBar = function (touchBar) {
+  if (touchBar === null || typeof touchBar === 'undefined') {
+    this._destroyTouchBar();
+  } else if (Array.isArray(touchBar)) {
+    this._setTouchBar((new TouchBar(touchBar)).toJSON());
+  } else {
+    this._setTouchBar(touchBar.toJSON())
+  }
+}
+
 module.exports = BrowserWindow

+ 6 - 0
lib/browser/api/exports/electron.js

@@ -103,6 +103,12 @@ Object.defineProperties(exports, {
       return require('../system-preferences')
     }
   },
+  TouchBar: {
+    enumerable: true,
+    get: function () {
+      return require('../touch-bar')
+    }
+  },
   Tray: {
     enumerable: true,
     get: function () {

+ 89 - 0
lib/browser/api/touch-bar.js

@@ -0,0 +1,89 @@
+const {EventEmitter} = require('events')
+const {app} = require('electron')
+
+class TouchBar {
+  constructor (items) {
+    this.items = items;
+    if (!Array.isArray(items)) {
+      throw new Error('The items object provided has to be an array')
+    }
+    console.log(items)
+    items.forEach((item) => {
+      if (!item.id) {
+        throw new Error('Each item must be an instance of a TouchBarItem')
+      }
+    })
+  }
+
+  toJSON () {
+    return this.items.map((item) => item.toJSON ? item.toJSON() : item);
+  }
+}
+
+let item_id_incrementor = 1
+const item_event_handlers = {}
+
+TouchBar._event = (id, ...args) => {
+  const id_parts = id.split('.')
+  const item_id = id_parts[id_parts.length - 1]
+  if (item_event_handlers[item_id]) item_event_handlers[item_id](...args)
+}
+
+class TouchBarItem {
+  constructor (config) {
+    this.id = item_id_incrementor++
+    const mConfig = Object.assign({}, config || {})
+    Object.defineProperty(this, 'config', {
+      configurable: false,
+      enumerable: false,
+      get: () => mConfig
+    })
+    this.config.id = `${this.config.id || this.id}`;
+    this.config.type = 'button';
+    if (typeof this.config !== 'object' || this.config === null) {
+      throw new Error('Provided config must be a non-null object')
+    }
+  }
+
+  toJSON () {
+    return this.config
+  }
+}
+
+TouchBar.Button = class TouchBarButton extends TouchBarItem {
+  constructor (config) {
+    super(config)
+    this.config.type = 'button';
+    const click = config.click
+    if (typeof click === 'function') {
+      item_event_handlers[`${this.id}`] = click
+    }
+  }
+}
+
+TouchBar.ColorPicker = class TouchBarColorPicker extends TouchBarItem {
+  constructor (config) {
+    super(config)
+    this.config.type = 'colorpicker';
+    const change = config.change
+    if (typeof change === 'function') {
+      item_event_handlers[`${this.id}`] = change
+    }
+  }
+}
+
+TouchBar.Label = class TouchBarLabel extends TouchBarItem {}
+
+TouchBar.List = class TouchBarList extends TouchBarItem {}
+
+TouchBar.Slider = class TouchBarSlider extends TouchBarItem {
+  constructor (config) {
+    super(config)
+    const change = config.change
+    if (typeof change === 'function') {
+      item_event_handlers[this.id] = change
+    }
+  }
+}
+
+module.exports = TouchBar;