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) { ...@@ -39,10 +39,17 @@ void SharesheetService::ShowBubble(views::View* bubble_anchor_view) {
} }
// Cleanup delegate when bubble closes. // 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(); auto iter = active_delegates_.begin();
while (iter != active_delegates_.end()) { while (iter != active_delegates_.end()) {
if ((*iter)->GetId() == id) { 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); active_delegates_.erase(iter);
break; break;
} }
...@@ -50,4 +57,35 @@ void SharesheetService::OnBubbleClosed(uint32_t id) { ...@@ -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 } // namespace sharesheet
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "base/strings/string16.h"
#include "chrome/browser/sharesheet/sharesheet_action_cache.h" #include "chrome/browser/sharesheet/sharesheet_action_cache.h"
#include "chrome/browser/sharesheet/sharesheet_types.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
class Profile; class Profile;
...@@ -32,7 +34,12 @@ class SharesheetService : public KeyedService { ...@@ -32,7 +34,12 @@ class SharesheetService : public KeyedService {
SharesheetService& operator=(const SharesheetService&) = delete; SharesheetService& operator=(const SharesheetService&) = delete;
void ShowBubble(views::View* bubble_anchor_view); 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: private:
uint32_t delegate_counter_ = 0; uint32_t delegate_counter_ = 0;
......
...@@ -30,9 +30,22 @@ void SharesheetServiceDelegate::ShowBubble(std::vector<TargetInfo> targets) { ...@@ -30,9 +30,22 @@ void SharesheetServiceDelegate::ShowBubble(std::vector<TargetInfo> targets) {
sharesheet_bubble_view_->ShowBubble(std::move(targets)); sharesheet_bubble_view_->ShowBubble(std::move(targets));
} }
void SharesheetServiceDelegate::OnBubbleClosed() { void SharesheetServiceDelegate::OnBubbleClosed(
const base::string16& active_action) {
sharesheet_bubble_view_.release(); 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() { uint32_t SharesheetServiceDelegate::GetId() {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "base/strings/string16.h"
#include "chrome/browser/sharesheet/sharesheet_controller.h" #include "chrome/browser/sharesheet/sharesheet_controller.h"
#include "chrome/browser/sharesheet/sharesheet_types.h" #include "chrome/browser/sharesheet/sharesheet_types.h"
...@@ -33,7 +34,11 @@ class SharesheetServiceDelegate : public SharesheetController { ...@@ -33,7 +34,11 @@ class SharesheetServiceDelegate : public SharesheetController {
delete; delete;
void ShowBubble(std::vector<TargetInfo> targets); 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 // SharesheetController overrides
uint32_t GetId() override; uint32_t GetId() override;
...@@ -41,6 +46,7 @@ class SharesheetServiceDelegate : public SharesheetController { ...@@ -41,6 +46,7 @@ class SharesheetServiceDelegate : public SharesheetController {
private: private:
const uint32_t id_; const uint32_t id_;
base::string16 active_action_;
std::unique_ptr<SharesheetBubbleView> sharesheet_bubble_view_; std::unique_ptr<SharesheetBubbleView> sharesheet_bubble_view_;
SharesheetService* sharesheet_service_; SharesheetService* sharesheet_service_;
}; };
......
...@@ -6,11 +6,17 @@ ...@@ -6,11 +6,17 @@
#include <utility> #include <utility>
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/sharesheet/sharesheet_service_delegate.h" #include "chrome/browser/sharesheet/sharesheet_service_delegate.h"
#include "chrome/browser/ui/views/chrome_layout_provider.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/insets.h"
#include "ui/gfx/geometry/size.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/label.h"
#include "ui/views/controls/styled_label.h" #include "ui/views/controls/styled_label.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
...@@ -18,12 +24,54 @@ ...@@ -18,12 +24,54 @@
namespace { namespace {
constexpr int kColumnSetIdTitle = 0; constexpr int kButtonSize = 64;
constexpr int kVerticalSpacing = 24; constexpr int kMaxTargetRowSize = 4;
constexpr int kSpacing = 24;
constexpr char kTitle[] = "Share"; constexpr char kTitle[] = "Share";
enum { COLUMN_SET_ID_TITLE, COLUMN_SET_ID_TARGETS };
} // namespace } // 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( SharesheetBubbleView::SharesheetBubbleView(
views::View* anchor_view, views::View* anchor_view,
sharesheet::SharesheetServiceDelegate* delegate) sharesheet::SharesheetServiceDelegate* delegate)
...@@ -65,34 +113,82 @@ void SharesheetBubbleView::ShowBubble(std::vector<TargetInfo> targets) { ...@@ -65,34 +113,82 @@ void SharesheetBubbleView::ShowBubble(std::vector<TargetInfo> targets) {
main_view_->SetLayoutManager(std::make_unique<views::GridLayout>()); main_view_->SetLayoutManager(std::make_unique<views::GridLayout>());
// Set up columnsets // 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, cs->AddColumn(/* h_align */ views::GridLayout::FILL,
/* v_align */ views::GridLayout::CENTER, /* v_align */ views::GridLayout::CENTER,
/* resize_percent */ 1.0, /* resize_percent */ 1.0,
views::GridLayout::ColumnSize::kUsePreferred, views::GridLayout::ColumnSize::kUsePreferred,
/* fixed_width */ 0, /*min_width*/ 0); /* 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 // Add Title label
main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kVerticalSpacing); main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing);
main_layout->StartRow(views::GridLayout::kFixedSize, kColumnSetIdTitle, main_layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE,
/* height */ kVerticalSpacing); /* height */ kSpacing);
auto* title = main_layout->AddView(std::make_unique<views::Label>( auto* title = main_layout->AddView(std::make_unique<views::Label>(
base::UTF8ToUTF16(base::StringPiece(kTitle)), base::UTF8ToUTF16(base::StringPiece(kTitle)),
views::style::CONTEXT_DIALOG_TITLE, views::style::STYLE_PRIMARY)); views::style::CONTEXT_DIALOG_TITLE, views::style::STYLE_PRIMARY));
title->SetHorizontalAlignment(gfx::ALIGN_CENTER); 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); views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this);
GetWidget()->GetRootView()->Layout(); GetWidget()->GetRootView()->Layout();
widget->Show(); widget->Show();
} }
void SharesheetBubbleView::ShowActionView() {
main_view_->SetVisible(false);
share_action_view_->SetVisible(true);
}
void SharesheetBubbleView::CloseBubble() { void SharesheetBubbleView::CloseBubble() {
views::Widget* widget = View::GetWidget(); views::Widget* widget = View::GetWidget();
widget->CloseWithReason(views::Widget::ClosedReason::kAcceptButtonClicked); 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) { void SharesheetBubbleView::OnWidgetDestroyed(views::Widget* widget) {
delegate_->OnBubbleClosed(); delegate_->OnBubbleClosed(active_target_);
} }
gfx::Size SharesheetBubbleView::CalculatePreferredSize() const { gfx::Size SharesheetBubbleView::CalculatePreferredSize() const {
......
...@@ -9,12 +9,14 @@ ...@@ -9,12 +9,14 @@
#include "chrome/browser/sharesheet/sharesheet_types.h" #include "chrome/browser/sharesheet/sharesheet_types.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/button/button.h"
namespace sharesheet { namespace sharesheet {
class SharesheetServiceDelegate; class SharesheetServiceDelegate;
} }
class SharesheetBubbleView : public views::BubbleDialogDelegateView { class SharesheetBubbleView : public views::BubbleDialogDelegateView,
public views::ButtonListener {
public: public:
using TargetInfo = sharesheet::TargetInfo; using TargetInfo = sharesheet::TargetInfo;
...@@ -25,8 +27,12 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView { ...@@ -25,8 +27,12 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView {
~SharesheetBubbleView() override; ~SharesheetBubbleView() override;
void ShowBubble(std::vector<TargetInfo> targets); void ShowBubble(std::vector<TargetInfo> targets);
void ShowActionView();
void CloseBubble(); void CloseBubble();
// views::ButtonListener overrides
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
// views::BubbleDialogDelegateView overrides // views::BubbleDialogDelegateView overrides
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
void OnWidgetDestroyed(views::Widget* widget) override; void OnWidgetDestroyed(views::Widget* widget) override;
...@@ -35,6 +41,7 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView { ...@@ -35,6 +41,7 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView {
// Owns this class. // Owns this class.
sharesheet::SharesheetServiceDelegate* delegate_; sharesheet::SharesheetServiceDelegate* delegate_;
std::vector<TargetInfo> targets_; std::vector<TargetInfo> targets_;
base::string16 active_target_;
views::View* root_view_ = nullptr; views::View* root_view_ = nullptr;
views::View* main_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