Commit 9746a60d authored by Tina Wang's avatar Tina Wang Committed by Commit Bot

[SendTabToSelf] Build selectable items inside omnibox pop-up bubble

Omnibox pop-up bubble appears when the user click on the omnibox share
icon. It lists all valid devices that a user can share tab to. In this
change I introduced a new class ShareBubbleDeviceButton to implement
each device button.

Bug: 960595, 950388
Change-Id: I947175db88e4bc5ce657eb5108854107728b1eeb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1600462Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarJeffrey Cohen <jeffreycohen@chromium.org>
Reviewed-by: default avatarsebsg <sebsg@chromium.org>
Commit-Queue: Tina Wang <tinazwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#661072}
parent 9f17897c
......@@ -54,6 +54,8 @@ aggregate_vector_icons("chrome_vector_icons") {
"forward_arrow_touch.icon",
"generic_stop.icon",
"globe.icon",
"hardware_computer.icon",
"hardware_smartphone.icon",
"horizontal_menu.icon",
"incognito.icon",
"incognito_profile.icon",
......
// Copyright 2019 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 20, 18,
R_CUBIC_TO, 1.1f, 0, 1.99f, -0.9f, 1.99f, -2,
LINE_TO, 22, 6,
R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2,
H_LINE_TO, 4,
R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
R_V_LINE_TO, 10,
R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2,
H_LINE_TO, 0,
R_V_LINE_TO, 2,
R_H_LINE_TO, 24,
R_V_LINE_TO, -2,
R_H_LINE_TO, -4,
CLOSE,
MOVE_TO, 4, 6,
R_H_LINE_TO, 16,
R_V_LINE_TO, 10,
H_LINE_TO, 4,
V_LINE_TO, 6,
CLOSE
// Copyright 2019 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 17, 1.01f,
LINE_TO, 7, 1,
R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
R_V_LINE_TO, 18,
R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2,
R_H_LINE_TO, 10,
R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2,
V_LINE_TO, 3,
R_CUBIC_TO, 0, -1.1f, -0.9f, -1.99f, -2, -1.99f,
CLOSE,
MOVE_TO, 17, 19,
H_LINE_TO, 7,
V_LINE_TO, 5,
R_H_LINE_TO, 10,
R_V_LINE_TO, 14,
CLOSE
\ No newline at end of file
......@@ -2873,6 +2873,8 @@ jumbo_split_static_library("ui") {
"views/sad_tab_view.h",
"views/safe_browsing/password_reuse_modal_warning_dialog.cc",
"views/safe_browsing/password_reuse_modal_warning_dialog.h",
"views/send_tab_to_self/send_tab_to_self_bubble_device_button.cc",
"views/send_tab_to_self/send_tab_to_self_bubble_device_button.h",
"views/send_tab_to_self/send_tab_to_self_bubble_view_impl.cc",
"views/send_tab_to_self/send_tab_to_self_bubble_view_impl.h",
"views/send_tab_to_self/send_tab_to_self_icon_view.cc",
......
......@@ -7,11 +7,14 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/send_tab_to_self/send_tab_to_self_desktop_util.h"
#include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_view.h"
#include "chrome/grit/generated_resources.h"
#include "components/send_tab_to_self/send_tab_to_self_model.h"
#include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
#include "components/send_tab_to_self/target_device_info.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -86,8 +89,18 @@ SendTabToSelfBubbleController::SendTabToSelfBubbleController(
}
void SendTabToSelfBubbleController::FetchDeviceInfo() {
// TODO(crbug/960595): get devices info map from SendTabToSelfModel.
NOTIMPLEMENTED();
valid_devices_.clear();
send_tab_to_self::SendTabToSelfSyncService* service =
SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile());
if (!service) {
return;
}
send_tab_to_self::SendTabToSelfModel* model =
service->GetSendTabToSelfModel();
if (!model) {
return;
}
valid_devices_ = model->GetTargetDeviceNameToCacheInfoMap();
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(SendTabToSelfBubbleController)
......
......@@ -9,6 +9,7 @@
#include <memory>
#include "base/macros.h"
#include "base/strings/string16.h"
#include "content/public/browser/web_contents_user_data.h"
class Profile;
......
// Copyright 2019 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 "chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_device_button.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "components/send_tab_to_self/target_device_info.h"
#include "components/sync/protocol/sync.pb.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/paint_vector_icon.h"
namespace send_tab_to_self {
namespace {
// Icon sizes in DIP.
constexpr int kPrimaryIconSize = 20;
enum class DeviceIconType {
DESKTOP = 0,
PHONE = 1,
TOTAL_COUNT = 2 // Add new types above this line.
};
gfx::ImageSkia CreateDeviceIcon(DeviceIconType icon_type, bool enabled = true) {
const gfx::VectorIcon* vector_icon;
switch (icon_type) {
case DeviceIconType::DESKTOP:
vector_icon = &kHardwareComputerIcon;
break;
case DeviceIconType::PHONE:
vector_icon = &kHardwareSmartphoneIcon;
break;
default:
vector_icon = &kSendTabToSelfIcon;
}
SkColor icon_color = enabled ? gfx::kChromeIconGrey : gfx::kGoogleGrey500;
return gfx::CreateVectorIcon(*vector_icon, kPrimaryIconSize, icon_color);
}
gfx::ImageSkia CreateIconView(
const sync_pb::SyncEnums::DeviceType device_type) {
if (device_type == sync_pb::SyncEnums::TYPE_PHONE) {
return CreateDeviceIcon(DeviceIconType::PHONE);
}
return CreateDeviceIcon(DeviceIconType::DESKTOP);
}
} // namespace
SendTabToSelfBubbleDeviceButton::SendTabToSelfBubbleDeviceButton(
views::ButtonListener* button_listener,
const std::string& device_name,
const TargetDeviceInfo& device_info,
int button_tag)
: HoverButton(button_listener,
CreateIconView(device_info.device_type),
base::UTF8ToUTF16(device_name)) {
device_name_ = device_name;
device_guid_ = device_info.cache_guid;
device_type_ = device_info.device_type;
set_tag(button_tag);
SetEnabled(true);
}
SendTabToSelfBubbleDeviceButton::~SendTabToSelfBubbleDeviceButton() = default;
} // namespace send_tab_to_self
// Copyright 2019 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 CHROME_BROWSER_UI_VIEWS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_BUBBLE_DEVICE_BUTTON_H_
#define CHROME_BROWSER_UI_VIEWS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_BUBBLE_DEVICE_BUTTON_H_
#include <string>
#include "base/bind.h"
#include "chrome/browser/ui/views/hover_button.h"
#include "components/sync/protocol/sync.pb.h"
namespace send_tab_to_self {
struct TargetDeviceInfo;
// A button representing a device in share bubble. It is highlighted when
// hovered.
class SendTabToSelfBubbleDeviceButton : public HoverButton {
public:
SendTabToSelfBubbleDeviceButton(views::ButtonListener* button_listener,
const std::string& device_name,
const TargetDeviceInfo& device_info,
int button_tag);
~SendTabToSelfBubbleDeviceButton() override;
const std::string device_name() const { return device_name_; }
const std::string device_guid() const { return device_guid_; }
sync_pb::SyncEnums::DeviceType device_type() const { return device_type_; }
private:
std::string device_name_;
std::string device_guid_;
sync_pb::SyncEnums::DeviceType device_type_;
DISALLOW_COPY_AND_ASSIGN(SendTabToSelfBubbleDeviceButton);
};
} // namespace send_tab_to_self
#endif // CHROME_BROWSER_UI_VIEWS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_BUBBLE_DEVICE_BUTTON_H_
......@@ -5,11 +5,19 @@
#include "chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_view_impl.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble_controller.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_bubble_device_button.h"
#include "chrome/grit/generated_resources.h"
#include "components/send_tab_to_self/target_device_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_types.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
namespace send_tab_to_self {
......@@ -20,7 +28,8 @@ SendTabToSelfBubbleViewImpl::SendTabToSelfBubbleViewImpl(
content::WebContents* web_contents,
SendTabToSelfBubbleController* controller)
: LocationBarBubbleDelegateView(anchor_view, anchor_point, web_contents),
controller_(controller) {
controller_(controller),
weak_factory_(this) {
DCHECK(controller);
}
......@@ -59,8 +68,10 @@ bool SendTabToSelfBubbleViewImpl::Close() {
void SendTabToSelfBubbleViewImpl::ButtonPressed(views::Button* sender,
const ui::Event& event) {
// TODO(crbug/959698): handle the action when a button has been clicked.
NOTIMPLEMENTED();
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&SendTabToSelfBubbleViewImpl::DevicePressed,
weak_factory_.GetWeakPtr(), sender->tag()));
}
gfx::Size SendTabToSelfBubbleViewImpl::CalculatePreferredSize() const {
......@@ -87,17 +98,45 @@ void SendTabToSelfBubbleViewImpl::Init() {
views::DISTANCE_DIALOG_CONTENT_MARGIN_BOTTOM_CONTROL),
0));
SetLayoutManager(std::make_unique<views::FillLayout>());
CreateScrollView();
PopulateScrollView(controller_->GetValidDevices());
}
void SendTabToSelfBubbleViewImpl::ShowScrollView() {
// TODO(crbug/960595): show the scroll view.
NOTIMPLEMENTED();
void SendTabToSelfBubbleViewImpl::CreateScrollView() {
scroll_view_ = new views::ScrollView();
AddChildView(scroll_view_);
scroll_view_->ClipHeightTo(0, kDeviceButtonHeight * kMaximumButtons);
}
void SendTabToSelfBubbleViewImpl::PopulateScrollView() {
// TODO(crbug/960595): get the valid devices data and populate the bubble
// scroll view.
NOTIMPLEMENTED();
void SendTabToSelfBubbleViewImpl::PopulateScrollView(
const std::map<std::string, TargetDeviceInfo> devices) {
device_buttons_.clear();
auto device_list_view = std::make_unique<views::View>();
device_list_view->SetLayoutManager(
std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
int tag = 0;
for (const auto& device : devices) {
auto device_button = std::make_unique<SendTabToSelfBubbleDeviceButton>(
this, device.first, device.second,
/** button_tag */ tag++);
device_buttons_.push_back(std::move(device_button));
device_list_view->AddChildView(device_buttons_.back().get());
}
scroll_view_->SetContents(std::move(device_list_view));
MaybeSizeToContents();
Layout();
}
void SendTabToSelfBubbleViewImpl::DevicePressed(size_t index) {
if (!controller_) {
return;
}
SendTabToSelfBubbleDeviceButton* device_button =
device_buttons_.at(index).get();
controller_->OnDeviceSelected(device_button->device_guid());
}
void SendTabToSelfBubbleViewImpl::MaybeSizeToContents() {
......
......@@ -26,6 +26,8 @@ class WebContents;
namespace send_tab_to_self {
class SendTabToSelfBubbleController;
class SendTabToSelfBubbleDeviceButton;
struct TargetDeviceInfo;
// View component of the send tab to self bubble that allows users to choose
// target device to send tab to.
......@@ -33,6 +35,13 @@ class SendTabToSelfBubbleViewImpl : public SendTabToSelfBubbleView,
public views::ButtonListener,
public LocationBarBubbleDelegateView {
public:
// The valid device button height.
static constexpr int kDeviceButtonHeight = 56;
// Maximum number of buttons that are shown without scroll. If the device
// number is larger than kMaximumButtons, the bubble content will be
// scrollable.
static constexpr int kMaximumButtons = 5;
// Bubble will be anchored to |anchor_view|.
SendTabToSelfBubbleViewImpl(views::View* anchor_view,
const gfx::Point& anchor_point,
......@@ -60,17 +69,22 @@ class SendTabToSelfBubbleViewImpl : public SendTabToSelfBubbleView,
gfx::Size CalculatePreferredSize() const override;
void OnPaint(gfx::Canvas* canvas) override;
// Shows the bubble view.
void Show(DisplayReason reason);
private:
// views::BubbleDialogDelegateView:
void Init() override;
// Shows the scroll view.
void ShowScrollView();
// Creates the scroll view.
void CreateScrollView();
// Populates the scroll view containing valid devices.
void PopulateScrollView();
void PopulateScrollView(
const std::map<std::string, TargetDeviceInfo> devices);
// Handles the action when a target device has been pressed.
void DevicePressed(size_t index);
// Resizes and potentially moves the bubble to fit the content's preferred
// size.
......@@ -79,11 +93,19 @@ class SendTabToSelfBubbleViewImpl : public SendTabToSelfBubbleView,
// Title shown at the top of the bubble.
base::string16 bubble_title_;
// Contains references to device buttons in the order they appear.
std::vector<std::unique_ptr<SendTabToSelfBubbleDeviceButton>> device_buttons_;
SendTabToSelfBubbleController* controller_; // Weak reference.
// ScrollView containing the list of device buttons.
views::ScrollView* scroll_view_ = nullptr;
// The device that the user has selected to share tab to.
base::Optional<size_t> selected_device_index_;
base::WeakPtrFactory<SendTabToSelfBubbleViewImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SendTabToSelfBubbleViewImpl);
};
......
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