Commit 934cf814 authored by Thomas Lukaszewicz's avatar Thomas Lukaszewicz Committed by Commit Bot

Views: Update the logic for invoking an instance of Tab Search

This CL updates the TabSearchBubbleView and the TabSearchButton
such that there can only be a single instance of the
Tab Search UI shown at any given time.

This CL also changes the TabSearchButton such that it enters the
active state immediately on bubble creation so that the bubble's
status is communicated to the user while it loads in
asynchronously.

This behavior mimics that in the IconLabelBubbleView.

Bug: 1099917
Change-Id: Ifb5602e55750fd6dd4b834c4dc42835ca08d0f2b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2354509
Commit-Queue: Thomas Lukaszewicz <tluk@chromium.org>
Reviewed-by: default avatarPeter Boström <pbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800585}
parent 44f5ba08
......@@ -82,12 +82,13 @@ class TabSearchWebView : public views::WebView {
} // namespace
void TabSearchBubbleView::CreateTabSearchBubble(
// static.
views::Widget* TabSearchBubbleView::CreateTabSearchBubble(
content::BrowserContext* browser_context,
views::View* anchor_view) {
auto delegate =
std::make_unique<TabSearchBubbleView>(browser_context, anchor_view);
BubbleDialogDelegateView::CreateBubble(delegate.release());
return BubbleDialogDelegateView::CreateBubble(delegate.release());
}
TabSearchBubbleView::TabSearchBubbleView(
......@@ -104,8 +105,6 @@ TabSearchBubbleView::TabSearchBubbleView(
web_view_->LoadInitialURL(GURL(chrome::kChromeUITabSearchURL));
}
TabSearchBubbleView::~TabSearchBubbleView() = default;
gfx::Size TabSearchBubbleView::CalculatePreferredSize() const {
// Constrain the size to popup min/max.
gfx::Size preferred_size = views::View::CalculatePreferredSize();
......
......@@ -21,12 +21,13 @@ class TabSearchBubbleView : public views::BubbleDialogDelegateView {
public:
// TODO(tluk): Since the Bubble is shown asynchronously, we shouldn't call
// this if the Widget is hidden and yet to be revealed.
static void CreateTabSearchBubble(content::BrowserContext* browser_context,
static views::Widget* CreateTabSearchBubble(
content::BrowserContext* browser_context,
views::View* anchor_view);
TabSearchBubbleView(content::BrowserContext* browser_context,
views::View* anchor_view);
~TabSearchBubbleView() override;
~TabSearchBubbleView() override = default;
// views::BubbleDialogDelegateView:
gfx::Size CalculatePreferredSize() const override;
......
......@@ -41,7 +41,7 @@ class NewTabButton : public views::ImageButton,
void AnimateInkDropToStateForTesting(views::InkDropState state);
// views::View:
// views::ImageButton:
const char* GetClassName() const override;
void AddLayerBeneathView(ui::Layer* new_layer) override;
void RemoveLayerBeneathView(ui::Layer* old_layer) override;
......@@ -49,9 +49,11 @@ class NewTabButton : public views::ImageButton,
protected:
virtual void PaintIcon(gfx::Canvas* canvas);
TabStrip* tab_strip() { return tab_strip_; }
SkColor GetForegroundColor() const;
// views::View:
// views::ImageButton:
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
private:
......
......@@ -4,8 +4,12 @@
#include "chrome/browser/ui/views/tabs/tab_search_button.h"
#include "base/scoped_observer.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/ui/views/tab_search/tab_search_bubble_view.h"
#include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/widget/widget.h"
namespace {
constexpr int kIconSize = 20;
......@@ -13,9 +17,36 @@ constexpr int kIconSize = 20;
TabSearchButton::TabSearchButton(TabStrip* tab_strip,
views::ButtonListener* listener)
: NewTabButton(tab_strip, listener) {
: NewTabButton(tab_strip, nullptr) {
SetImageHorizontalAlignment(HorizontalAlignment::ALIGN_CENTER);
SetImageVerticalAlignment(VerticalAlignment::ALIGN_MIDDLE);
auto menu_button_controller = std::make_unique<views::MenuButtonController>(
this, this,
std::make_unique<views::Button::DefaultButtonControllerDelegate>(this));
menu_button_controller_ = menu_button_controller.get();
SetButtonController(std::move(menu_button_controller));
}
TabSearchButton::~TabSearchButton() = default;
void TabSearchButton::ButtonPressed(views::Button* sender,
const ui::Event& event) {
if (bubble_)
return;
bubble_ = TabSearchBubbleView::CreateTabSearchBubble(
tab_strip()->controller()->GetProfile(), this);
observed_bubble_widget_.Add(bubble_);
// Hold the pressed lock while the |bubble_| is active.
pressed_lock_ = menu_button_controller_->TakeLock();
}
void TabSearchButton::OnWidgetClosing(views::Widget* widget) {
DCHECK_EQ(bubble_, widget);
observed_bubble_widget_.Remove(bubble_);
bubble_ = nullptr;
pressed_lock_.reset();
}
void TabSearchButton::PaintIcon(gfx::Canvas* canvas) {
......
......@@ -6,6 +6,8 @@
#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_SEARCH_BUTTON_H_
#include "chrome/browser/ui/views/tabs/new_tab_button.h"
#include "ui/views/controls/button/menu_button_controller.h"
#include "ui/views/widget/widget_observer.h"
namespace gfx {
class Canvas;
......@@ -13,6 +15,7 @@ class Canvas;
namespace views {
class ButtonListener;
class Widget;
}
class TabStrip;
......@@ -24,16 +27,37 @@ class TabStrip;
//
// TODO(tluk): Break away common code from the NewTabButton and the
// TabSearchButton into a TabStripControlButton or similar.
class TabSearchButton : public NewTabButton {
class TabSearchButton : public NewTabButton,
public views::ButtonListener,
public views::WidgetObserver {
public:
TabSearchButton(TabStrip* tab_strip, views::ButtonListener* listener);
TabSearchButton(const TabSearchButton&) = delete;
TabSearchButton& operator=(const TabSearchButton&) = delete;
~TabSearchButton() override = default;
~TabSearchButton() override;
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// views::WidgetObserver:
void OnWidgetClosing(views::Widget* widget) override;
protected:
// NewTabButton:
void PaintIcon(gfx::Canvas* canvas) override;
private:
views::MenuButtonController* menu_button_controller_ = nullptr;
// A lock to keep the TabSearchButton pressed while |bubble_| is showing or
// in the process of being shown.
std::unique_ptr<views::MenuButtonController::PressedLock> pressed_lock_;
// |bubble_| is non-null while the tab search bubble is active.
views::Widget* bubble_ = nullptr;
ScopedObserver<views::Widget, views::WidgetObserver> observed_bubble_widget_{
this};
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_SEARCH_BUTTON_H_
......@@ -3598,12 +3598,6 @@ void TabStrip::ButtonPressed(views::Button* sender, const ui::Event& event) {
if (event.type() == ui::ET_GESTURE_TAP)
TouchUMA::RecordGestureAction(TouchUMA::kGestureNewTabTap);
}
#if BUILDFLAG(ENABLE_TAB_SEARCH)
if (sender == tab_search_button_) {
TabSearchBubbleView::CreateTabSearchBubble(controller()->GetProfile(),
tab_search_button_);
}
#endif
}
// Overridden to support automation. See automation_proxy_uitest.cc.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment