Browse Source

:wrench: Enable mode indication for setProgressBar

This commit enables setting a mode for the setProgressBar method.
Old behavior is kept intact, usage is entirely optional.
Felix Rieseberg 8 years ago
parent
commit
73c91dae9e

+ 6 - 2
atom/browser/api/atom_api_window.cc

@@ -584,8 +584,12 @@ void Window::SetFocusable(bool focusable) {
   return window_->SetFocusable(focusable);
 }
 
-void Window::SetProgressBar(double progress) {
-  window_->SetProgressBar(progress);
+void Window::SetProgressBar(double progress, mate::Arguments* args) {
+  mate::Dictionary options;
+  std::string mode;
+  args->GetNext(&options) && options.Get("mode", &mode);
+
+  window_->SetProgressBar(progress, mode);
 }
 
 void Window::SetOverlayIcon(const gfx::Image& overlay,

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

@@ -155,7 +155,7 @@ class Window : public mate::TrackableObject<Window>,
   void SetIgnoreMouseEvents(bool ignore);
   void SetContentProtection(bool enable);
   void SetFocusable(bool focusable);
-  void SetProgressBar(double progress);
+  void SetProgressBar(double progress, mate::Arguments* args);
   void SetOverlayIcon(const gfx::Image& overlay,
                       const std::string& description);
   bool SetThumbarButtons(mate::Arguments* args);

+ 2 - 1
atom/browser/native_window.h

@@ -143,7 +143,8 @@ class NativeWindow : public base::SupportsUserData,
   virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;
 
   // Taskbar/Dock APIs.
-  virtual void SetProgressBar(double progress) = 0;
+  virtual void SetProgressBar(double progress,
+                              const std::string& mode) = 0;
   virtual void SetOverlayIcon(const gfx::Image& overlay,
                               const std::string& description) = 0;
 

+ 1 - 1
atom/browser/native_window_mac.h

@@ -83,7 +83,7 @@ class NativeWindowMac : public NativeWindow {
   void SetParentWindow(NativeWindow* parent) override;
   gfx::NativeWindow GetNativeWindow() override;
   gfx::AcceleratedWidget GetAcceleratedWidget() override;
-  void SetProgressBar(double progress) override;
+  void SetProgressBar(double progress, const std::string& mode) override;
   void SetOverlayIcon(const gfx::Image& overlay,
                       const std::string& description) override;
 

+ 1 - 1
atom/browser/native_window_mac.mm

@@ -973,7 +973,7 @@ gfx::AcceleratedWidget NativeWindowMac::GetAcceleratedWidget() {
   return inspectable_web_contents()->GetView()->GetNativeView();
 }
 
-void NativeWindowMac::SetProgressBar(double progress) {
+void NativeWindowMac::SetProgressBar(double progress, const std::string& mode) {
   NSDockTile* dock_tile = [NSApp dockTile];
 
   // For the first time API invoked, we need to create a ContentView in DockTile.

+ 3 - 2
atom/browser/native_window_views.cc

@@ -904,9 +904,10 @@ gfx::NativeWindow NativeWindowViews::GetNativeWindow() {
   return window_->GetNativeWindow();
 }
 
-void NativeWindowViews::SetProgressBar(double progress) {
+void NativeWindowViews::SetProgressBar(
+  double progress, const std::string& mode) {
 #if defined(OS_WIN)
-  taskbar_host_.SetProgressBar(GetAcceleratedWidget(), progress);
+  taskbar_host_.SetProgressBar(GetAcceleratedWidget(), progress, mode);
 #elif defined(USE_X11)
   if (unity::IsRunning()) {
     unity::SetProgressFraction(progress);

+ 1 - 1
atom/browser/native_window_views.h

@@ -104,7 +104,7 @@ class NativeWindowViews : public NativeWindow,
   gfx::NativeWindow GetNativeWindow() override;
   void SetOverlayIcon(const gfx::Image& overlay,
                       const std::string& description) override;
-  void SetProgressBar(double value) override;
+  void SetProgressBar(double value, const std::string& mode) override;
   void SetAutoHideMenuBar(bool auto_hide) override;
   bool IsMenuBarAutoHide() override;
   void SetMenuBarVisibility(bool visible) override;

+ 31 - 9
atom/browser/ui/win/taskbar_host.cc

@@ -117,18 +117,40 @@ bool TaskbarHost::SetThumbarButtons(
   return SUCCEEDED(r);
 }
 
-bool TaskbarHost::SetProgressBar(HWND window, double value) {
+bool TaskbarHost::SetProgressBar(
+  HWND window, double value, const std::string& mode) {
   if (!InitializeTaskbar())
     return false;
 
-  HRESULT r;
-  if (value > 1.0)
-    r = taskbar_->SetProgressState(window, TBPF_INDETERMINATE);
-  else if (value < 0)
-    r = taskbar_->SetProgressState(window, TBPF_NOPROGRESS);
-  else
-    r = taskbar_->SetProgressValue(window, static_cast<int>(value * 100), 100);
-  return SUCCEEDED(r);
+  HRESULT barR;
+  HRESULT stateR;
+
+  if (value > 1.0 || mode == "indeterminate") {
+    barR = taskbar_->SetProgressState(window, TBPF_INDETERMINATE);
+  } else if (value < 0 || mode == "none") {
+    barR = taskbar_->SetProgressState(window, TBPF_NOPROGRESS);
+  } else {
+    // Unless SetProgressState set a blocking state (TBPF_ERROR, TBPF_PAUSED)
+    // for the window, a call to SetProgressValue assumes the TBPF_NORMAL
+    // state even if it is not explicitly set.
+    // SetProgressValue overrides and clears the TBPF_INDETERMINATE state.
+    if (mode == "error") {
+      stateR = taskbar_->SetProgressState(window, TBPF_ERROR);
+    } else if (mode == "paused") {
+      stateR = taskbar_->SetProgressState(window, TBPF_PAUSED);
+    } else {
+      stateR = taskbar_->SetProgressState(window, TBPF_NORMAL);
+    }
+
+    if (SUCCEEDED(stateR)) {
+      int val = static_cast<int>(value * 100);
+      barR = taskbar_->SetProgressValue(window, val, 100);
+    } else {
+      return SUCCEEDED(stateR);
+    }
+  }
+
+  return SUCCEEDED(barR);
 }
 
 bool TaskbarHost::SetOverlayIcon(

+ 1 - 1
atom/browser/ui/win/taskbar_host.h

@@ -35,7 +35,7 @@ class TaskbarHost {
       HWND window, const std::vector<ThumbarButton>& buttons);
 
   // Set the progress state in taskbar.
-  bool SetProgressBar(HWND window, double value);
+  bool SetProgressBar(HWND window, double value, const std::string& mode);
 
   // Set the overlay icon in taskbar.
   bool SetOverlayIcon(

+ 7 - 1
docs/api/browser-window.md

@@ -956,9 +956,11 @@ Same as `webContents.reload`.
 Sets the `menu` as the window's menu bar, setting it to `null` will remove the
 menu bar.
 
-#### `win.setProgressBar(progress)`
+#### `win.setProgressBar(progress[, options])`
 
 * `progress` Double
+* `options` Object (optional)
+  * `mode` String _Windows_ - Mode for the progres bar (`none`, `normal`, `indeterminate`, `error`, or `paused`)
 
 Sets progress value in progress bar. Valid range is [0, 1.0].
 
@@ -969,6 +971,10 @@ On Linux platform, only supports Unity desktop environment, you need to specify
 the `*.desktop` file name to `desktopName` field in `package.json`. By default,
 it will assume `app.getName().desktop`.
 
+On Windows, a mode can be passed. Accepted values are `none`, `normal`, 
+`indeterminate`, `error`, and `paused`. If you call `setProgressBar` without a
+mode set (but with a value within the valid range), `normal` will be assumed.
+
 #### `win.setOverlayIcon(overlay, description)` _Windows_
 
 * `overlay` [NativeImage](native-image.md) - the icon to display on the bottom

+ 18 - 0
spec/api-browser-window-spec.js

@@ -391,6 +391,24 @@ describe('browser-window module', function () {
         w.setProgressBar(-1)
       })
     })
+
+    it('sets the progress using "paused" mode', function () {
+      assert.doesNotThrow(function () {
+        w.setProgressBar(0.5, {mode: 'paused'})
+      })
+    })
+
+    it('sets the progress using "error" mode', function () {
+      assert.doesNotThrow(function () {
+        w.setProgressBar(0.5, {mode: 'error'})
+      })
+    })
+
+    it('sets the progress using "normal" mode', function () {
+      assert.doesNotThrow(function () {
+        w.setProgressBar(0.5, {mode: 'normal'})
+      })
+    })
   })
 
   describe('BrowserWindow.fromId(id)', function () {