Browse Source

osx: Add NativeWindow::SetSizeConstraints

Cheng Zhao 9 years ago
parent
commit
8577f2b52f

+ 69 - 0
atom/browser/native_window.cc

@@ -162,6 +162,14 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
     Show();
 }
 
+gfx::Size NativeWindow::ContentSizeToWindowSize(const gfx::Size& size) {
+  return size;
+}
+
+gfx::Size NativeWindow::WindowSizeToContentSize(const gfx::Size& size) {
+  return size;
+}
+
 void NativeWindow::SetSize(const gfx::Size& size) {
   SetBounds(gfx::Rect(GetPosition(), size));
 }
@@ -178,6 +186,67 @@ gfx::Point NativeWindow::GetPosition() {
   return GetBounds().origin();
 }
 
+void NativeWindow::SetContentSize(const gfx::Size& size) {
+  SetSize(ContentSizeToWindowSize(size));
+}
+
+gfx::Size NativeWindow::GetContentSize() {
+  return WindowSizeToContentSize(GetSize());
+}
+
+void NativeWindow::SetSizeConstraints(
+    const extensions::SizeConstraints& window_constraints) {
+  extensions::SizeConstraints content_constraints;
+  if (window_constraints.HasMaximumSize())
+    content_constraints.set_maximum_size(
+        WindowSizeToContentSize(window_constraints.GetMaximumSize()));
+  if (window_constraints.HasMinimumSize())
+    content_constraints.set_minimum_size(
+        WindowSizeToContentSize(window_constraints.GetMinimumSize()));
+  SetContentSizeConstraints(content_constraints);
+}
+
+extensions::SizeConstraints NativeWindow::GetSizeConstraints() {
+  extensions::SizeConstraints content_constraints = GetContentSizeConstraints();
+  extensions::SizeConstraints window_constraints;
+  if (content_constraints.HasMaximumSize())
+    window_constraints.set_maximum_size(
+        ContentSizeToWindowSize(content_constraints.GetMaximumSize()));
+  if (content_constraints.HasMinimumSize())
+    window_constraints.set_minimum_size(
+        ContentSizeToWindowSize(content_constraints.GetMinimumSize()));
+  return window_constraints;
+}
+
+void NativeWindow::SetContentSizeConstraints(
+    const extensions::SizeConstraints& size_constraints) {
+  size_constraints_ = size_constraints;
+}
+
+extensions::SizeConstraints NativeWindow::GetContentSizeConstraints() {
+  return size_constraints_;
+}
+
+void NativeWindow::SetMinimumSize(const gfx::Size& size) {
+  extensions::SizeConstraints size_constraints;
+  size_constraints.set_minimum_size(size);
+  SetSizeConstraints(size_constraints);
+}
+
+gfx::Size NativeWindow::GetMinimumSize() {
+  return GetSizeConstraints().GetMinimumSize();
+}
+
+void NativeWindow::SetMaximumSize(const gfx::Size& size) {
+  extensions::SizeConstraints size_constraints;
+  size_constraints.set_maximum_size(size);
+  SetSizeConstraints(size_constraints);
+}
+
+gfx::Size NativeWindow::GetMaximumSize() {
+  return GetSizeConstraints().GetMaximumSize();
+}
+
 void NativeWindow::SetRepresentedFilename(const std::string& filename) {
 }
 

+ 20 - 6
atom/browser/native_window.h

@@ -19,6 +19,7 @@
 #include "content/public/browser/readback_types.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
+#include "extensions/browser/app_window/size_constraints.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
 
@@ -110,12 +111,18 @@ class NativeWindow : public base::SupportsUserData,
   virtual gfx::Size GetSize();
   virtual void SetPosition(const gfx::Point& position);
   virtual gfx::Point GetPosition();
-  virtual void SetContentSize(const gfx::Size& size) = 0;
-  virtual gfx::Size GetContentSize() = 0;
-  virtual void SetMinimumSize(const gfx::Size& size) = 0;
-  virtual gfx::Size GetMinimumSize() = 0;
-  virtual void SetMaximumSize(const gfx::Size& size) = 0;
-  virtual gfx::Size GetMaximumSize() = 0;
+  virtual void SetContentSize(const gfx::Size& size);
+  virtual gfx::Size GetContentSize();
+  virtual void SetSizeConstraints(
+      const extensions::SizeConstraints& size_constraints);
+  virtual extensions::SizeConstraints GetSizeConstraints();
+  virtual void SetContentSizeConstraints(
+      const extensions::SizeConstraints& size_constraints);
+  virtual extensions::SizeConstraints GetContentSizeConstraints();
+  virtual void SetMinimumSize(const gfx::Size& size);
+  virtual gfx::Size GetMinimumSize();
+  virtual void SetMaximumSize(const gfx::Size& size);
+  virtual gfx::Size GetMaximumSize();
   virtual void SetResizable(bool resizable) = 0;
   virtual bool IsResizable() = 0;
   virtual void SetAlwaysOnTop(bool top) = 0;
@@ -234,6 +241,10 @@ class NativeWindow : public base::SupportsUserData,
   NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
                const mate::Dictionary& options);
 
+  // Converts between content size to window size.
+  virtual gfx::Size ContentSizeToWindowSize(const gfx::Size& size);
+  virtual gfx::Size WindowSizeToContentSize(const gfx::Size& size);
+
   // content::WebContentsObserver:
   void RenderViewCreated(content::RenderViewHost* render_view_host) override;
   void BeforeUnloadDialogCancelled() override;
@@ -269,6 +280,9 @@ class NativeWindow : public base::SupportsUserData,
   // has to been explicitly provided.
   scoped_ptr<SkRegion> draggable_region_;  // used in custom drag.
 
+  // Minimum and maximum size, stored as content size.
+  extensions::SizeConstraints size_constraints_;
+
   // Whether window can be resized larger than screen.
   bool enable_larger_than_screen_;
 

+ 6 - 6
atom/browser/native_window_mac.h

@@ -44,12 +44,8 @@ class NativeWindowMac : public NativeWindow {
   bool IsFullscreen() const override;
   void SetBounds(const gfx::Rect& bounds) override;
   gfx::Rect GetBounds() override;
-  void SetContentSize(const gfx::Size& size) override;
-  gfx::Size GetContentSize() override;
-  void SetMinimumSize(const gfx::Size& size) override;
-  gfx::Size GetMinimumSize() override;
-  void SetMaximumSize(const gfx::Size& size) override;
-  gfx::Size GetMaximumSize() override;
+  void SetContentSizeConstraints(
+      const extensions::SizeConstraints& size_constraints) override;
   void SetResizable(bool resizable) override;
   bool IsResizable() override;
   void SetAlwaysOnTop(bool top) override;
@@ -89,6 +85,10 @@ class NativeWindowMac : public NativeWindow {
       const content::NativeWebKeyboardEvent&) override;
 
  private:
+  // NativeWindow:
+  gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override;
+  gfx::Size WindowSizeToContentSize(const gfx::Size& size) override;
+
   void InstallView();
   void UninstallView();
 

+ 28 - 49
atom/browser/native_window_mac.mm

@@ -22,6 +22,11 @@
 
 namespace {
 
+// Converts gfx::Size to NSSize.
+inline NSSize ToNSSize(const gfx::Size& size) {
+  return NSMakeSize(size.width(), size.height());
+}
+
 // Prevents window from resizing during the scope.
 class ScopedDisableResize {
  public:
@@ -549,56 +554,18 @@ gfx::Rect NativeWindowMac::GetBounds() {
   return bounds;
 }
 
-void NativeWindowMac::SetContentSize(const gfx::Size& size) {
-  if (!has_frame()) {
-    SetSize(size);
-    return;
-  }
-
-  NSRect frame_nsrect = [window_ frame];
-  NSSize frame = frame_nsrect.size;
-  NSSize content = [window_ contentRectForFrameRect:frame_nsrect].size;
-
-  int width = size.width() + frame.width - content.width;
-  int height = size.height() + frame.height - content.height;
-  frame_nsrect.origin.y -= height - frame_nsrect.size.height;
-  frame_nsrect.size.width = width;
-  frame_nsrect.size.height = height;
-  [window_ setFrame:frame_nsrect display:YES];
-}
-
-gfx::Size NativeWindowMac::GetContentSize() {
-  if (!has_frame())
-    return GetSize();
-
-  NSRect bounds = [[window_ contentView] bounds];
-  return gfx::Size(bounds.size.width, bounds.size.height);
-}
-
-void NativeWindowMac::SetMinimumSize(const gfx::Size& size) {
-  NSSize min_size = NSMakeSize(size.width(), size.height());
+void NativeWindowMac::SetContentSizeConstraints(
+    const extensions::SizeConstraints& size_constraints) {
   NSView* content = [window_ contentView];
-  [window_ setContentMinSize:[content convertSize:min_size toView:nil]];
-}
-
-gfx::Size NativeWindowMac::GetMinimumSize() {
-  NSView* content = [window_ contentView];
-  NSSize min_size = [content convertSize:[window_ contentMinSize]
-                                fromView:nil];
-  return gfx::Size(min_size.width, min_size.height);
-}
-
-void NativeWindowMac::SetMaximumSize(const gfx::Size& size) {
-  NSSize max_size = NSMakeSize(size.width(), size.height());
-  NSView* content = [window_ contentView];
-  [window_ setContentMaxSize:[content convertSize:max_size toView:nil]];
-}
-
-gfx::Size NativeWindowMac::GetMaximumSize() {
-  NSView* content = [window_ contentView];
-  NSSize max_size = [content convertSize:[window_ contentMaxSize]
-                                fromView:nil];
-  return gfx::Size(max_size.width, max_size.height);
+  if (size_constraints.HasMinimumSize()) {
+    NSSize min_size = ToNSSize(size_constraints.GetMinimumSize());
+    [window_ setMinSize:[content convertSize:min_size toView:nil]];
+  }
+  if (size_constraints.HasMaximumSize()) {
+    NSSize max_size = ToNSSize(size_constraints.GetMaximumSize());
+    [window_ setMaxSize:[content convertSize:max_size toView:nil]];
+  }
+  NativeWindow::SetContentSizeConstraints(size_constraints);
 }
 
 void NativeWindowMac::SetResizable(bool resizable) {
@@ -821,6 +788,18 @@ void NativeWindowMac::HandleKeyboardEvent(
   }
 }
 
+gfx::Size NativeWindowMac::ContentSizeToWindowSize(const gfx::Size& size) {
+  NSRect content = NSMakeRect(0, 0, size.width(), size.height());
+  NSRect frame = [window_ frameRectForContentRect:content];
+  return gfx::Size(frame.size);
+}
+
+gfx::Size NativeWindowMac::WindowSizeToContentSize(const gfx::Size& size) {
+  NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
+  NSRect content = [window_ contentRectForFrameRect:frame];
+  return gfx::Size(content.size);
+}
+
 void NativeWindowMac::InstallView() {
   // Make sure the bottom corner is rounded: http://crbug.com/396264.
   [[window_ contentView] setWantsLayer:YES];

+ 16 - 0
atom/browser/native_window_views.cc

@@ -440,6 +440,22 @@ gfx::Rect NativeWindowViews::GetBounds() {
   return window_->GetWindowBoundsInScreen();
 }
 
+void NativeWindowViews::SetSizeConstraints(
+    const extensions::SizeConstraints& size_constraints) {
+}
+
+extensions::SizeConstraints NativeWindowViews::GetSizeConstraints() {
+  return extensions::SizeConstraints();
+}
+
+void NativeWindowViews::SetContentSizeConstraints(
+    const extensions::SizeConstraints& size_constraints) {
+}
+
+extensions::SizeConstraints NativeWindowViews::GetContentSizeConstraints() {
+  return extensions::SizeConstraints();
+}
+
 void NativeWindowViews::SetContentSize(const gfx::Size& size) {
   if (!has_frame()) {
     NativeWindow::SetSize(size);

+ 6 - 0
atom/browser/native_window_views.h

@@ -63,6 +63,12 @@ class NativeWindowViews : public NativeWindow,
   bool IsFullscreen() const override;
   void SetBounds(const gfx::Rect& bounds) override;
   gfx::Rect GetBounds() override;
+  void SetSizeConstraints(
+      const extensions::SizeConstraints& size_constraints) override;
+  extensions::SizeConstraints GetSizeConstraints() override;
+  void SetContentSizeConstraints(
+      const extensions::SizeConstraints& size_constraints) override;
+  extensions::SizeConstraints GetContentSizeConstraints() override;
   void SetContentSize(const gfx::Size& size) override;
   gfx::Size GetContentSize() override;
   void SetMinimumSize(const gfx::Size& size) override;

+ 83 - 0
chromium_src/extensions/browser/app_window/size_constraints.cc

@@ -0,0 +1,83 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/app_window/size_constraints.h"
+
+#include <algorithm>
+
+#include "ui/gfx/geometry/insets.h"
+
+namespace extensions {
+
+SizeConstraints::SizeConstraints()
+    : maximum_size_(kUnboundedSize, kUnboundedSize) {}
+
+SizeConstraints::SizeConstraints(const gfx::Size& min_size,
+                                 const gfx::Size& max_size)
+    : minimum_size_(min_size), maximum_size_(max_size) {}
+
+SizeConstraints::~SizeConstraints() {}
+
+// static
+gfx::Size SizeConstraints::AddFrameToConstraints(
+    const gfx::Size& size_constraints,
+    const gfx::Insets& frame_insets) {
+  return gfx::Size(
+      size_constraints.width() == kUnboundedSize
+          ? kUnboundedSize
+          : size_constraints.width() + frame_insets.width(),
+      size_constraints.height() == kUnboundedSize
+          ? kUnboundedSize
+          : size_constraints.height() + frame_insets.height());
+}
+
+gfx::Size SizeConstraints::ClampSize(gfx::Size size) const {
+  const gfx::Size max_size = GetMaximumSize();
+  if (max_size.width() != kUnboundedSize)
+    size.set_width(std::min(size.width(), max_size.width()));
+  if (max_size.height() != kUnboundedSize)
+    size.set_height(std::min(size.height(), max_size.height()));
+  size.SetToMax(GetMinimumSize());
+  return size;
+}
+
+bool SizeConstraints::HasMinimumSize() const {
+  const gfx::Size min_size = GetMinimumSize();
+  return min_size.width() != kUnboundedSize ||
+         min_size.height() != kUnboundedSize;
+}
+
+bool SizeConstraints::HasMaximumSize() const {
+  const gfx::Size max_size = GetMaximumSize();
+  return max_size.width() != kUnboundedSize ||
+         max_size.height() != kUnboundedSize;
+}
+
+bool SizeConstraints::HasFixedSize() const {
+  return !GetMinimumSize().IsEmpty() && GetMinimumSize() == GetMaximumSize();
+}
+
+gfx::Size SizeConstraints::GetMinimumSize() const {
+  return minimum_size_;
+}
+
+gfx::Size SizeConstraints::GetMaximumSize() const {
+  return gfx::Size(
+      maximum_size_.width() == kUnboundedSize
+          ? kUnboundedSize
+          : std::max(maximum_size_.width(), minimum_size_.width()),
+      maximum_size_.height() == kUnboundedSize
+          ? kUnboundedSize
+          : std::max(maximum_size_.height(), minimum_size_.height()));
+}
+
+void SizeConstraints::set_minimum_size(const gfx::Size& min_size) {
+  minimum_size_ = min_size;
+}
+
+void SizeConstraints::set_maximum_size(const gfx::Size& max_size) {
+  maximum_size_ = max_size;
+}
+
+}  // namespace extensions

+ 57 - 0
chromium_src/extensions/browser/app_window/size_constraints.h

@@ -0,0 +1,57 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_APP_WINDOW_SIZE_CONSTRAINTS_H_
+#define EXTENSIONS_BROWSER_APP_WINDOW_SIZE_CONSTRAINTS_H_
+
+#include "ui/gfx/geometry/size.h"
+
+namespace gfx {
+class Insets;
+}
+
+namespace extensions {
+
+class SizeConstraints {
+ public:
+  // The value SizeConstraints uses to represent an unbounded width or height.
+  // This is an enum so that it can be declared inline here.
+  enum { kUnboundedSize = 0 };
+
+  SizeConstraints();
+  SizeConstraints(const gfx::Size& min_size, const gfx::Size& max_size);
+  ~SizeConstraints();
+
+  // Adds frame insets to a size constraint.
+  static gfx::Size AddFrameToConstraints(const gfx::Size& size_constraints,
+                                         const gfx::Insets& frame_insets);
+
+  // Returns the bounds with its size clamped to the min/max size.
+  gfx::Size ClampSize(gfx::Size size) const;
+
+  // When gfx::Size is used as a min/max size, a zero represents an unbounded
+  // component. This method checks whether either component is specified.
+  // Note we can't use gfx::Size::IsEmpty as it returns true if either width
+  // or height is zero.
+  bool HasMinimumSize() const;
+  bool HasMaximumSize() const;
+
+  // This returns true if all components are specified, and min and max are
+  // equal.
+  bool HasFixedSize() const;
+
+  gfx::Size GetMaximumSize() const;
+  gfx::Size GetMinimumSize() const;
+
+  void set_minimum_size(const gfx::Size& min_size);
+  void set_maximum_size(const gfx::Size& max_size);
+
+ private:
+  gfx::Size minimum_size_;
+  gfx::Size maximum_size_;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_APP_WINDOW_SIZE_CONSTRAINTS_H_

+ 2 - 0
filenames.gypi

@@ -429,6 +429,8 @@
       'chromium_src/chrome/renderer/tts_dispatcher.cc',
       'chromium_src/chrome/renderer/tts_dispatcher.h',
       'chromium_src/chrome/utility/utility_message_handler.h',
+      'chromium_src/extensions/browser/app_window/size_constraints.cc',
+      'chromium_src/extensions/browser/app_window/size_constraints.h',
       'chromium_src/library_loaders/libspeechd_loader.cc',
       'chromium_src/library_loaders/libspeechd.h',
       'chromium_src/net/test/embedded_test_server/stream_listen_socket.cc',