Browse Source

feat: add MdTextButton to View APIs (#15328)

* view: make button focusable by default

* view: add MdTextButton

* view: add common methods to LabelButton
Cheng Zhao 6 years ago
parent
commit
260778e0fb

+ 3 - 0
BUILD.gn

@@ -155,6 +155,7 @@ asar("js2asar") {
       "lib/browser/api/views/button.js",
       "lib/browser/api/views/label-button.js",
       "lib/browser/api/views/layout-manager.js",
+      "lib/browser/api/views/md-text-button.js",
       "lib/browser/api/views/text-field.js",
     ]
   }
@@ -422,6 +423,8 @@ static_library("electron_lib") {
       "atom/browser/api/views/atom_api_label_button.h",
       "atom/browser/api/views/atom_api_layout_manager.cc",
       "atom/browser/api/views/atom_api_layout_manager.h",
+      "atom/browser/api/views/atom_api_md_text_button.cc",
+      "atom/browser/api/views/atom_api_md_text_button.h",
       "atom/browser/api/views/atom_api_text_field.cc",
       "atom/browser/api/views/atom_api_text_field.h",
     ]

+ 3 - 1
atom/browser/api/views/atom_api_button.cc

@@ -13,8 +13,10 @@ namespace atom {
 
 namespace api {
 
-Button::Button(views::Button* button) : View(button) {
+Button::Button(views::Button* impl) : View(impl) {
   view()->set_owned_by_client();
+  // Make the button focusable as per the platform.
+  button()->SetFocusForPlatform();
 }
 
 Button::~Button() {}

+ 2 - 0
atom/browser/api/views/atom_api_button.h

@@ -27,6 +27,8 @@ class Button : public View, public views::ButtonListener {
   // views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
+  views::Button* button() const { return static_cast<views::Button*>(view()); }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(Button);
 };

+ 23 - 1
atom/browser/api/views/atom_api_label_button.cc

@@ -7,7 +7,6 @@
 #include "atom/common/api/constructor.h"
 #include "base/strings/utf_string_conversions.h"
 #include "native_mate/dictionary.h"
-#include "ui/views/controls/button/label_button.h"
 
 #include "atom/common/node_includes.h"
 
@@ -15,11 +14,29 @@ namespace atom {
 
 namespace api {
 
+LabelButton::LabelButton(views::LabelButton* impl) : Button(impl) {}
+
 LabelButton::LabelButton(const std::string& text)
     : Button(new views::LabelButton(this, base::UTF8ToUTF16(text))) {}
 
 LabelButton::~LabelButton() {}
 
+const base::string16& LabelButton::GetText() const {
+  return label_button()->GetText();
+}
+
+void LabelButton::SetText(const base::string16& text) {
+  label_button()->SetText(text);
+}
+
+bool LabelButton::IsDefault() const {
+  return label_button()->is_default();
+}
+
+void LabelButton::SetIsDefault(bool is_default) {
+  label_button()->SetIsDefault(is_default);
+}
+
 // static
 mate::WrappableBase* LabelButton::New(mate::Arguments* args,
                                       const std::string& text) {
@@ -33,6 +50,11 @@ mate::WrappableBase* LabelButton::New(mate::Arguments* args,
 void LabelButton::BuildPrototype(v8::Isolate* isolate,
                                  v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "LabelButton"));
+  mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
+      .SetMethod("getText", &LabelButton::GetText)
+      .SetMethod("setText", &LabelButton::SetText)
+      .SetMethod("isDefault", &LabelButton::IsDefault)
+      .SetMethod("setIsDefault", &LabelButton::SetIsDefault);
 }
 
 }  // namespace api

+ 11 - 0
atom/browser/api/views/atom_api_label_button.h

@@ -8,6 +8,7 @@
 #include <string>
 
 #include "atom/browser/api/views/atom_api_button.h"
+#include "ui/views/controls/button/label_button.h"
 
 namespace atom {
 
@@ -21,10 +22,20 @@ class LabelButton : public Button {
   static void BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype);
 
+  const base::string16& GetText() const;
+  void SetText(const base::string16& text);
+  bool IsDefault() const;
+  void SetIsDefault(bool is_default);
+
  protected:
+  explicit LabelButton(views::LabelButton* impl);
   explicit LabelButton(const std::string& text);
   ~LabelButton() override;
 
+  views::LabelButton* label_button() const {
+    return static_cast<views::LabelButton*>(view());
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(LabelButton);
 };

+ 57 - 0
atom/browser/api/views/atom_api_md_text_button.cc

@@ -0,0 +1,57 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "atom/browser/api/views/atom_api_md_text_button.h"
+
+#include "atom/common/api/constructor.h"
+#include "base/strings/utf_string_conversions.h"
+#include "native_mate/dictionary.h"
+
+#include "atom/common/node_includes.h"
+
+namespace atom {
+
+namespace api {
+
+MdTextButton::MdTextButton(const std::string& text)
+    : LabelButton(views::MdTextButton::Create(this, base::UTF8ToUTF16(text))) {}
+
+MdTextButton::~MdTextButton() {}
+
+// static
+mate::WrappableBase* MdTextButton::New(mate::Arguments* args,
+                                       const std::string& text) {
+  // Constructor call.
+  auto* view = new MdTextButton(text);
+  view->InitWith(args->isolate(), args->GetThis());
+  return view;
+}
+
+// static
+void MdTextButton::BuildPrototype(v8::Isolate* isolate,
+                                  v8::Local<v8::FunctionTemplate> prototype) {
+  prototype->SetClassName(mate::StringToV8(isolate, "MdTextButton"));
+}
+
+}  // namespace api
+
+}  // namespace atom
+
+namespace {
+
+using atom::api::MdTextButton;
+
+void Initialize(v8::Local<v8::Object> exports,
+                v8::Local<v8::Value> unused,
+                v8::Local<v8::Context> context,
+                void* priv) {
+  v8::Isolate* isolate = context->GetIsolate();
+  mate::Dictionary dict(isolate, exports);
+  dict.Set("MdTextButton", mate::CreateConstructor<MdTextButton>(
+                               isolate, base::Bind(&MdTextButton::New)));
+}
+
+}  // namespace
+
+NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_md_text_button, Initialize)

+ 41 - 0
atom/browser/api/views/atom_api_md_text_button.h

@@ -0,0 +1,41 @@
+// Copyright (c) 2018 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_BROWSER_API_VIEWS_ATOM_API_MD_TEXT_BUTTON_H_
+#define ATOM_BROWSER_API_VIEWS_ATOM_API_MD_TEXT_BUTTON_H_
+
+#include <string>
+
+#include "atom/browser/api/views/atom_api_label_button.h"
+#include "ui/views/controls/button/md_text_button.h"
+
+namespace atom {
+
+namespace api {
+
+class MdTextButton : public LabelButton {
+ public:
+  static mate::WrappableBase* New(mate::Arguments* args,
+                                  const std::string& text);
+
+  static void BuildPrototype(v8::Isolate* isolate,
+                             v8::Local<v8::FunctionTemplate> prototype);
+
+ protected:
+  explicit MdTextButton(const std::string& text);
+  ~MdTextButton() override;
+
+  views::MdTextButton* md_text_button() const {
+    return static_cast<views::MdTextButton*>(view());
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MdTextButton);
+};
+
+}  // namespace api
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_API_VIEWS_ATOM_API_MD_TEXT_BUTTON_H_

+ 1 - 0
atom/common/node_bindings.cc

@@ -73,6 +73,7 @@
   V(atom_browser_button)         \
   V(atom_browser_label_button)   \
   V(atom_browser_layout_manager) \
+  V(atom_browser_md_text_button) \
   V(atom_browser_text_field)
 
 #define ELECTRON_DESKTOP_CAPTURER_MODULE(V) V(atom_browser_desktop_capturer)

+ 1 - 0
lib/browser/api/module-list.js

@@ -41,6 +41,7 @@ if (features.isViewApiEnabled()) {
     { name: 'Button', file: 'views/button' },
     { name: 'LabelButton', file: 'views/label-button' },
     { name: 'LayoutManager', file: 'views/layout-manager' },
+    { name: 'MdTextButton', file: 'views/md-text-button' },
     { name: 'TextField', file: 'views/text-field' }
   )
 }

+ 15 - 0
lib/browser/api/views/md-text-button.js

@@ -0,0 +1,15 @@
+'use strict'
+
+const electron = require('electron')
+
+const { LabelButton } = electron
+const { MdTextButton } = process.atomBinding('md_text_button')
+
+Object.setPrototypeOf(MdTextButton.prototype, LabelButton.prototype)
+
+MdTextButton.prototype._init = function () {
+  // Call parent class's _init.
+  LabelButton.prototype._init.call(this)
+}
+
+module.exports = MdTextButton