Commit f55c7509 authored by Melissa Zhang's avatar Melissa Zhang Committed by Commit Bot

[Sharesheet] Add targets to Sharesheet bubble.

This CL adds targets to the sharesheet bubble and lifecycle
support for those targets. Clicking on a ShareAction target
now triggers the bubble to show the ShareActionView.

Bug: 1097623
Change-Id: Ibbe829f3ea303588fcc90eb2ae9d7d1b662fc0bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2305820
Commit-Queue: Melissa Zhang <melzhang@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790341}
parent 827a5f4d
......@@ -39,10 +39,17 @@ void SharesheetService::ShowBubble(views::View* bubble_anchor_view) {
}
// Cleanup delegate when bubble closes.
void SharesheetService::OnBubbleClosed(uint32_t id) {
void SharesheetService::OnBubbleClosed(uint32_t id,
const base::string16& active_action) {
auto iter = active_delegates_.begin();
while (iter != active_delegates_.end()) {
if ((*iter)->GetId() == id) {
if (!active_action.empty()) {
ShareAction* share_action =
sharesheet_action_cache_->GetActionFromName(active_action);
if (share_action != nullptr)
share_action->OnClosing(iter->get());
}
active_delegates_.erase(iter);
break;
}
......@@ -50,4 +57,35 @@ void SharesheetService::OnBubbleClosed(uint32_t id) {
}
}
void SharesheetService::OnTargetSelected(uint32_t delegate_id,
const base::string16& target_name,
const TargetType type,
views::View* share_action_view) {
if (type == TargetType::kAction) {
ShareAction* share_action =
sharesheet_action_cache_->GetActionFromName(target_name);
if (share_action == nullptr)
return;
SharesheetServiceDelegate* delegate = GetDelegate(delegate_id);
if (delegate == nullptr)
return;
delegate->OnActionLaunched();
share_action->LaunchAction(delegate, share_action_view);
}
}
SharesheetServiceDelegate* SharesheetService::GetDelegate(
uint32_t delegate_id) {
auto iter = active_delegates_.begin();
while (iter != active_delegates_.end()) {
if ((*iter)->GetId() == delegate_id) {
return iter->get();
}
++iter;
}
return nullptr;
}
} // namespace sharesheet
......@@ -8,7 +8,9 @@
#include <memory>
#include <vector>
#include "base/strings/string16.h"
#include "chrome/browser/sharesheet/sharesheet_action_cache.h"
#include "chrome/browser/sharesheet/sharesheet_types.h"
#include "components/keyed_service/core/keyed_service.h"
class Profile;
......@@ -32,7 +34,12 @@ class SharesheetService : public KeyedService {
SharesheetService& operator=(const SharesheetService&) = delete;
void ShowBubble(views::View* bubble_anchor_view);
void OnBubbleClosed(uint32_t id);
void OnBubbleClosed(uint32_t id, const base::string16& active_action);
void OnTargetSelected(uint32_t delegate_id,
const base::string16& target_name,
const TargetType type,
views::View* share_action_view);
SharesheetServiceDelegate* GetDelegate(uint32_t delegate_id);
private:
uint32_t delegate_counter_ = 0;
......
......@@ -30,9 +30,22 @@ void SharesheetServiceDelegate::ShowBubble(std::vector<TargetInfo> targets) {
sharesheet_bubble_view_->ShowBubble(std::move(targets));
}
void SharesheetServiceDelegate::OnBubbleClosed() {
void SharesheetServiceDelegate::OnBubbleClosed(
const base::string16& active_action) {
sharesheet_bubble_view_.release();
sharesheet_service_->OnBubbleClosed(id_);
sharesheet_service_->OnBubbleClosed(id_, active_action);
}
void SharesheetServiceDelegate::OnTargetSelected(
const base::string16& target_name,
const TargetType type,
views::View* share_action_view) {
sharesheet_service_->OnTargetSelected(id_, target_name, type,
share_action_view);
}
void SharesheetServiceDelegate::OnActionLaunched() {
sharesheet_bubble_view_->ShowActionView();
}
uint32_t SharesheetServiceDelegate::GetId() {
......
......@@ -7,6 +7,7 @@
#include <memory>
#include "base/strings/string16.h"
#include "chrome/browser/sharesheet/sharesheet_controller.h"
#include "chrome/browser/sharesheet/sharesheet_types.h"
......@@ -33,7 +34,11 @@ class SharesheetServiceDelegate : public SharesheetController {
delete;
void ShowBubble(std::vector<TargetInfo> targets);
void OnBubbleClosed();
void OnBubbleClosed(const base::string16& active_action);
void OnTargetSelected(const base::string16& target_name,
const TargetType type,
views::View* share_action_view);
void OnActionLaunched();
// SharesheetController overrides
uint32_t GetId() override;
......@@ -41,6 +46,7 @@ class SharesheetServiceDelegate : public SharesheetController {
private:
const uint32_t id_;
base::string16 active_action_;
std::unique_ptr<SharesheetBubbleView> sharesheet_bubble_view_;
SharesheetService* sharesheet_service_;
};
......
......@@ -6,11 +6,17 @@
#include <utility>
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/sharesheet/sharesheet_service_delegate.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/layout/box_layout.h"
......@@ -18,12 +24,54 @@
namespace {
constexpr int kColumnSetIdTitle = 0;
constexpr int kVerticalSpacing = 24;
constexpr int kButtonSize = 64;
constexpr int kMaxTargetRowSize = 4;
constexpr int kSpacing = 24;
constexpr char kTitle[] = "Share";
enum { COLUMN_SET_ID_TITLE, COLUMN_SET_ID_TARGETS };
} // namespace
// ShareSheetTargetButton
// A button that represents a candidate share target.
class ShareSheetTargetButton : public views::Button {
public:
ShareSheetTargetButton(views::ButtonListener* listener,
const base::string16& display_name,
const gfx::Image* icon)
: Button(listener) {
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, gfx::Insets(),
ChromeLayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_RELATED_CONTROL_VERTICAL)));
auto* image = AddChildView(std::make_unique<views::ImageView>());
image->set_can_process_events_within_subtree(false);
if (!icon->IsEmpty()) {
image->SetImage(*icon->ToImageSkia());
}
auto* label = AddChildView(std::make_unique<views::Label>(display_name));
label->SetBackgroundColor(SK_ColorTRANSPARENT);
label->SetHandlesTooltips(false);
label->SetMultiLine(true);
label->SetAutoColorReadabilityEnabled(false);
label->SetHorizontalAlignment(gfx::ALIGN_CENTER);
SetFocusForPlatform();
}
ShareSheetTargetButton(const ShareSheetTargetButton&) = delete;
ShareSheetTargetButton& operator=(const ShareSheetTargetButton&) = delete;
gfx::Size CalculatePreferredSize() const override {
return gfx::Size(kButtonSize, kButtonSize);
}
};
SharesheetBubbleView::SharesheetBubbleView(
views::View* anchor_view,
sharesheet::SharesheetServiceDelegate* delegate)
......@@ -65,34 +113,82 @@ void SharesheetBubbleView::ShowBubble(std::vector<TargetInfo> targets) {
main_view_->SetLayoutManager(std::make_unique<views::GridLayout>());
// Set up columnsets
views::ColumnSet* cs = main_layout->AddColumnSet(kColumnSetIdTitle);
views::ColumnSet* cs = main_layout->AddColumnSet(COLUMN_SET_ID_TITLE);
cs->AddColumn(/* h_align */ views::GridLayout::FILL,
/* v_align */ views::GridLayout::CENTER,
/* resize_percent */ 1.0,
views::GridLayout::ColumnSize::kUsePreferred,
/* fixed_width */ 0, /*min_width*/ 0);
views::ColumnSet* cs_buttons =
main_layout->AddColumnSet(COLUMN_SET_ID_TARGETS);
cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing);
cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize,
0);
cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing);
cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize,
0);
cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing);
cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize,
0);
cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing);
cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER,
1.0, views::GridLayout::ColumnSize::kFixed, kButtonSize,
0);
cs_buttons->AddPaddingColumn(/* resize_percent */ 1, kSpacing);
// Add Title label
main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kVerticalSpacing);
main_layout->StartRow(views::GridLayout::kFixedSize, kColumnSetIdTitle,
/* height */ kVerticalSpacing);
main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing);
main_layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE,
/* height */ kSpacing);
auto* title = main_layout->AddView(std::make_unique<views::Label>(
base::UTF8ToUTF16(base::StringPiece(kTitle)),
views::style::CONTEXT_DIALOG_TITLE, views::style::STYLE_PRIMARY));
title->SetHorizontalAlignment(gfx::ALIGN_CENTER);
// Add Targets
size_t i = 0;
for (const auto& target : targets_) {
if (i % kMaxTargetRowSize == 0) {
main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing);
main_layout->StartRow(views::GridLayout::kFixedSize,
COLUMN_SET_ID_TARGETS);
}
auto target_view = std::make_unique<ShareSheetTargetButton>(
this, target.display_name, &target.icon);
target_view->set_tag(i++);
main_layout->AddView(std::move(target_view));
}
main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing);
views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this);
GetWidget()->GetRootView()->Layout();
widget->Show();
}
void SharesheetBubbleView::ShowActionView() {
main_view_->SetVisible(false);
share_action_view_->SetVisible(true);
}
void SharesheetBubbleView::CloseBubble() {
views::Widget* widget = View::GetWidget();
widget->CloseWithReason(views::Widget::ClosedReason::kAcceptButtonClicked);
}
void SharesheetBubbleView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
active_target_ = targets_[sender->tag()].launch_name;
delegate_->OnTargetSelected(active_target_, targets_[sender->tag()].type,
share_action_view_);
RequestFocus();
}
void SharesheetBubbleView::OnWidgetDestroyed(views::Widget* widget) {
delegate_->OnBubbleClosed();
delegate_->OnBubbleClosed(active_target_);
}
gfx::Size SharesheetBubbleView::CalculatePreferredSize() const {
......
......@@ -9,12 +9,14 @@
#include "chrome/browser/sharesheet/sharesheet_types.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/button/button.h"
namespace sharesheet {
class SharesheetServiceDelegate;
}
class SharesheetBubbleView : public views::BubbleDialogDelegateView {
class SharesheetBubbleView : public views::BubbleDialogDelegateView,
public views::ButtonListener {
public:
using TargetInfo = sharesheet::TargetInfo;
......@@ -25,8 +27,12 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView {
~SharesheetBubbleView() override;
void ShowBubble(std::vector<TargetInfo> targets);
void ShowActionView();
void CloseBubble();
// views::ButtonListener overrides
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// views::BubbleDialogDelegateView overrides
gfx::Size CalculatePreferredSize() const override;
void OnWidgetDestroyed(views::Widget* widget) override;
......@@ -35,6 +41,7 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView {
// Owns this class.
sharesheet::SharesheetServiceDelegate* delegate_;
std::vector<TargetInfo> targets_;
base::string16 active_target_;
views::View* root_view_ = nullptr;
views::View* main_view_ = nullptr;
......
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