From 4a6880df596b77f5cbc997a146619c1140cdfccf Mon Sep 17 00:00:00 2001 From: Vladimir Date: Thu, 31 Jan 2019 05:07:19 +0300 Subject: [PATCH] feat: flexible autoresize for BrowserViews (#16184) * feat: flexible autoresize for BrowserViews * fix: change to static_cast * Slight format code --- atom/browser/api/atom_api_browser_view.cc | 8 +++ atom/browser/native_browser_view.h | 2 + atom/browser/native_browser_view_mac.mm | 8 +++ atom/browser/native_browser_view_views.cc | 71 +++++++++++++++++++++++ atom/browser/native_browser_view_views.h | 18 +++++- atom/browser/native_window_views.cc | 25 ++------ atom/browser/native_window_views.h | 2 + docs/api/browser-view.md | 4 ++ 8 files changed, 116 insertions(+), 22 deletions(-) diff --git a/atom/browser/api/atom_api_browser_view.cc b/atom/browser/api/atom_api_browser_view.cc index 6c9578c61eafe..630f0b887a1ff 100644 --- a/atom/browser/api/atom_api_browser_view.cc +++ b/atom/browser/api/atom_api_browser_view.cc @@ -37,6 +37,14 @@ struct Converter { if (params.Get("height", &height) && height) { flags |= atom::kAutoResizeHeight; } + bool horizontal = false; + if (params.Get("horizontal", &horizontal) && horizontal) { + flags |= atom::kAutoResizeHorizontal; + } + bool vertical = false; + if (params.Get("vertical", &vertical) && vertical) { + flags |= atom::kAutoResizeVertical; + } *auto_resize_flags = static_cast(flags); return true; diff --git a/atom/browser/native_browser_view.h b/atom/browser/native_browser_view.h index 56937e4c8c69e..dec6b430cbb0b 100644 --- a/atom/browser/native_browser_view.h +++ b/atom/browser/native_browser_view.h @@ -26,6 +26,8 @@ namespace atom { enum AutoResizeFlags { kAutoResizeWidth = 0x1, kAutoResizeHeight = 0x2, + kAutoResizeHorizontal = 0x4, + kAutoResizeVertical = 0x8, }; class NativeBrowserView { diff --git a/atom/browser/native_browser_view_mac.mm b/atom/browser/native_browser_view_mac.mm index 300e9b1050576..9e7cae5d888e0 100644 --- a/atom/browser/native_browser_view_mac.mm +++ b/atom/browser/native_browser_view_mac.mm @@ -174,6 +174,14 @@ - (BOOL)mouseDownCanMoveWindow { if (flags & kAutoResizeHeight) { autoresizing_mask |= NSViewHeightSizable; } + if (flags & kAutoResizeHorizontal) { + autoresizing_mask |= + NSViewMaxXMargin | NSViewMinXMargin | NSViewWidthSizable; + } + if (flags & kAutoResizeVertical) { + autoresizing_mask |= + NSViewMaxYMargin | NSViewMinYMargin | NSViewHeightSizable; + } auto* view = GetInspectableWebContentsView()->GetNativeView(); view.autoresizingMask = autoresizing_mask; diff --git a/atom/browser/native_browser_view_views.cc b/atom/browser/native_browser_view_views.cc index 10e8dd1937aee..1b187fcd3842f 100644 --- a/atom/browser/native_browser_view_views.cc +++ b/atom/browser/native_browser_view_views.cc @@ -19,11 +19,82 @@ NativeBrowserViewViews::~NativeBrowserViewViews() {} void NativeBrowserViewViews::SetAutoResizeFlags(uint8_t flags) { auto_resize_flags_ = flags; + ResetAutoResizeProportions(); +} + +void NativeBrowserViewViews::SetAutoResizeProportions( + const gfx::Size& window_size) { + if ((auto_resize_flags_ & AutoResizeFlags::kAutoResizeHorizontal) && + !auto_horizontal_proportion_set_) { + auto* view = GetInspectableWebContentsView()->GetView(); + auto view_bounds = view->bounds(); + auto_horizontal_proportion_width_ = + static_cast(window_size.width()) / + static_cast(view_bounds.width()); + auto_horizontal_proportion_left_ = static_cast(window_size.width()) / + static_cast(view_bounds.x()); + auto_horizontal_proportion_set_ = true; + } + if ((auto_resize_flags_ & AutoResizeFlags::kAutoResizeVertical) && + !auto_vertical_proportion_set_) { + auto* view = GetInspectableWebContentsView()->GetView(); + auto view_bounds = view->bounds(); + auto_vertical_proportion_height_ = + static_cast(window_size.height()) / + static_cast(view_bounds.height()); + auto_vertical_proportion_top_ = static_cast(window_size.height()) / + static_cast(view_bounds.y()); + auto_vertical_proportion_set_ = true; + } +} + +void NativeBrowserViewViews::AutoResize(const gfx::Rect& new_window, + int width_delta, + int height_delta) { + auto* view = GetInspectableWebContentsView()->GetView(); + const auto flags = GetAutoResizeFlags(); + if (!(flags & kAutoResizeWidth)) { + width_delta = 0; + } + if (!(flags & kAutoResizeHeight)) { + height_delta = 0; + } + if (height_delta || width_delta) { + auto new_view_size = view->size(); + new_view_size.set_width(new_view_size.width() + width_delta); + new_view_size.set_height(new_view_size.height() + height_delta); + view->SetSize(new_view_size); + } + auto new_view_bounds = view->bounds(); + if (flags & kAutoResizeHorizontal) { + new_view_bounds.set_width(new_window.width() / + auto_horizontal_proportion_width_); + new_view_bounds.set_x(new_window.width() / + auto_horizontal_proportion_left_); + } + if (flags & kAutoResizeVertical) { + new_view_bounds.set_height(new_window.height() / + auto_vertical_proportion_height_); + new_view_bounds.set_y(new_window.height() / auto_vertical_proportion_top_); + } + if ((flags & kAutoResizeHorizontal) || (flags & kAutoResizeVertical)) { + view->SetBoundsRect(new_view_bounds); + } +} + +void NativeBrowserViewViews::ResetAutoResizeProportions() { + if (auto_resize_flags_ & AutoResizeFlags::kAutoResizeHorizontal) { + auto_horizontal_proportion_set_ = false; + } + if (auto_resize_flags_ & AutoResizeFlags::kAutoResizeVertical) { + auto_vertical_proportion_set_ = false; + } } void NativeBrowserViewViews::SetBounds(const gfx::Rect& bounds) { auto* view = GetInspectableWebContentsView()->GetView(); view->SetBoundsRect(bounds); + ResetAutoResizeProportions(); } void NativeBrowserViewViews::SetBackgroundColor(SkColor color) { diff --git a/atom/browser/native_browser_view_views.h b/atom/browser/native_browser_view_views.h index 8f8e860292bad..536a9b38b4095 100644 --- a/atom/browser/native_browser_view_views.h +++ b/atom/browser/native_browser_view_views.h @@ -15,13 +15,29 @@ class NativeBrowserViewViews : public NativeBrowserView { brightray::InspectableWebContents* inspectable_web_contents); ~NativeBrowserViewViews() override; + void SetAutoResizeProportions(const gfx::Size& window_size); + void AutoResize(const gfx::Rect& new_window, + int width_delta, + int height_delta); uint8_t GetAutoResizeFlags() { return auto_resize_flags_; } + + // NativeBrowserView: void SetAutoResizeFlags(uint8_t flags) override; void SetBounds(const gfx::Rect& bounds) override; void SetBackgroundColor(SkColor color) override; private: - uint8_t auto_resize_flags_; + void ResetAutoResizeProportions(); + + uint8_t auto_resize_flags_ = 0; + + bool auto_horizontal_proportion_set_ = false; + float auto_horizontal_proportion_width_ = 0.; + float auto_horizontal_proportion_left_ = 0.; + + bool auto_vertical_proportion_set_ = false; + float auto_vertical_proportion_height_ = 0.; + float auto_vertical_proportion_top_ = 0.; DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewViews); }; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 2d50a23fca0e8..0224c7bc2fae0 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -1155,26 +1155,6 @@ void NativeWindowViews::OnWidgetActivationChanged(views::Widget* changed_widget, root_view_->ResetAltState(); } -void NativeWindowViews::AutoresizeBrowserView(int width_delta, - int height_delta, - NativeBrowserView* browser_view) { - const auto flags = - static_cast(browser_view)->GetAutoResizeFlags(); - if (!(flags & kAutoResizeWidth)) { - width_delta = 0; - } - if (!(flags & kAutoResizeHeight)) { - height_delta = 0; - } - if (height_delta || width_delta) { - auto* view = browser_view->GetInspectableWebContentsView()->GetView(); - auto new_view_size = view->size(); - new_view_size.set_width(new_view_size.width() + width_delta); - new_view_size.set_height(new_view_size.height() + height_delta); - view->SetSize(new_view_size); - } -} - void NativeWindowViews::OnWidgetBoundsChanged(views::Widget* changed_widget, const gfx::Rect& bounds) { if (changed_widget != widget()) @@ -1187,7 +1167,10 @@ void NativeWindowViews::OnWidgetBoundsChanged(views::Widget* changed_widget, int width_delta = new_bounds.width() - widget_size_.width(); int height_delta = new_bounds.height() - widget_size_.height(); for (NativeBrowserView* item : browser_views()) { - AutoresizeBrowserView(width_delta, height_delta, item); + NativeBrowserViewViews* native_view = + static_cast(item); + native_view->SetAutoResizeProportions(widget_size_); + native_view->AutoResize(new_bounds, width_delta, height_delta); } NotifyWindowResize(); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index f6c4b9bbf28c7..d49d04436dd04 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -160,6 +160,8 @@ class NativeWindowViews : public NativeWindow, void AutoresizeBrowserView(int width_delta, int height_delta, NativeBrowserView* browser_view); + void OnWidgetDestroying(views::Widget* widget) override; + // views::WidgetDelegate: void DeleteDelegate() override; views::View* GetInitiallyFocusedView() override; diff --git a/docs/api/browser-view.md b/docs/api/browser-view.md index 4a851c91624e6..ce21f0705051b 100644 --- a/docs/api/browser-view.md +++ b/docs/api/browser-view.md @@ -87,6 +87,10 @@ Returns `Boolean` - Whether the view is destroyed. with the window. `false` by default. * `height` Boolean - If `true`, the view's height will grow and shrink together with the window. `false` by default. + * `horizontal` Boolean - If `true`, the view's x position and width will grow + and shrink proportionly with the window. `false` by default. + * `vertical` Boolean - If `true`, the view's y position and height will grow + and shrink proportinaly with the window. `false` by default. #### `view.setBounds(bounds)` _Experimental_