blob: 1dfe688e5338c05224ea0ee826dcf1428ab6c205 [file] [log] [blame]
// Copyright 2016 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_INTENT_PICKER_BUBBLE_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_INTENT_PICKER_BUBBLE_VIEW_H_
#include <memory>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "chrome/browser/apps/intent_helper/apps_navigation_types.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
#include "components/services/app_service/public/mojom/types.mojom-forward.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/gfx/image/image.h"
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/controls/scroll_view.h"
#include "url/origin.h"
namespace content {
class WebContents;
} // namespace content
namespace views {
class Button;
class Checkbox;
class Widget;
} // namespace views
// A bubble that displays a list of applications (icons and names), after the
// list the UI displays a checkbox to allow the user remember the selection and
// after that a couple of buttons for either using the selected app or just
// staying in Chrome. The top right close button and clicking somewhere else
// outside of the bubble allows the user to dismiss the bubble (and stay in
// Chrome) without remembering any decision.
//
// This class communicates the user's selection with a callback supplied by
// AppsNavigationThrottle.
// +--------------------------------+
// | Open with [x] |
// | |
// | Icon1 Name1 |
// | Icon2 Name2 |
// | ... |
// | Icon(N) Name(N) |
// | |
// | [_] Remember my choice |
// | |
// | [Use app] [Stay in Chrome] |
// +--------------------------------+
class IntentPickerBubbleView : public LocationBarBubbleDelegateView {
public:
METADATA_HEADER(IntentPickerBubbleView);
using AppInfo = apps::IntentPickerAppInfo;
using BubbleType = apps::IntentPickerBubbleType;
// Unique identifiers for Views within the IntentPickerBubbleView hierarchy.
enum ViewId {
// The container for app selection buttons.
kItemContainer = 1,
// The "Remember my choice" checkbox.
kRememberCheckbox,
};
IntentPickerBubbleView(views::View* anchor_view,
BubbleType bubble_type,
std::vector<AppInfo> app_info,
IntentPickerResponse intent_picker_cb,
content::WebContents* web_contents,
bool show_stay_in_chrome,
bool show_remember_selection,
const absl::optional<url::Origin>& initiating_origin);
IntentPickerBubbleView(const IntentPickerBubbleView&) = delete;
IntentPickerBubbleView& operator=(const IntentPickerBubbleView&) = delete;
~IntentPickerBubbleView() override;
static views::Widget* ShowBubble(
views::View* anchor_view,
views::Button* highlighted_button,
BubbleType bubble_type,
content::WebContents* web_contents,
std::vector<AppInfo> app_info,
bool show_stay_in_chrome,
bool show_remember_selection,
const absl::optional<url::Origin>& initiating_origin,
IntentPickerResponse intent_picker_cb);
static IntentPickerBubbleView* intent_picker_bubble() {
return intent_picker_bubble_;
}
static void CloseCurrentBubble();
// LocationBarBubbleDelegateView overrides:
bool ShouldShowCloseButton() const override;
BubbleType bubble_type() const { return bubble_type_; }
// Selects the default app for the current configuration. Must be called after
// the Bubble is shown.
void SelectDefaultItem();
// Returns the index of the currently selected item. May return nullopt to
// indicate no selection.
absl::optional<size_t> GetSelectedIndex() const;
// A ScrollView which contains a list of apps. This view manages the selection
// state for the dialog.
class IntentPickerAppsView : public views::ScrollView {
public:
virtual void SetSelectedIndex(absl::optional<size_t> index) = 0;
virtual absl::optional<size_t> GetSelectedIndex() const = 0;
};
const std::vector<AppInfo>& app_info_for_testing() const { return app_info_; }
protected:
// LocationBarBubbleDelegateView overrides:
std::u16string GetWindowTitle() const override;
void CloseBubble() override;
private:
FRIEND_TEST_ALL_PREFIXES(IntentPickerBubbleViewTest, WindowTitle);
// views::BubbleDialogDelegateView overrides:
void OnWidgetDestroying(views::Widget* widget) override;
// Called when the app at |index| is selected in the app list. If
// |accepted| is true, the dialog should be immediately accepted with that app
// selected. If |index| is nullopt, no app is selected, and the Accept button
// will be disabled
void OnAppSelected(absl::optional<size_t> index, bool accepted);
void Initialize();
void OnDialogAccepted();
void OnDialogCancelled();
void OnDialogClosed();
// Runs |intent_picker_cb_| and closes the current bubble view.
void RunCallbackAndCloseBubble(const std::string& launch_name,
apps::PickerEntryType entry_type,
apps::IntentPickerCloseReason close_reason,
bool should_persist);
// Returns true if this picker has candidates for the user to choose from, and
// false otherwise. For instance, if Chrome was the only app candidate
// provided, it will have been erased from |app_infos_| and this method would
// return false.
bool HasCandidates() const;
// Updates whether the persistence checkbox is enabled or not.
void UpdateCheckboxState(size_t index);
// Clears this bubble from being considered the currently open bubble.
void ClearIntentPickerBubbleView();
static IntentPickerBubbleView* intent_picker_bubble_;
// Callback used to respond to AppsNavigationThrottle.
IntentPickerResponse intent_picker_cb_;
std::vector<AppInfo> app_info_;
raw_ptr<IntentPickerAppsView> apps_view_ = nullptr;
raw_ptr<views::Checkbox> remember_selection_checkbox_ = nullptr;
// When true, enables an alternate layout which presents apps as a grid
// instead of a list.
const bool use_grid_view_;
// Tells whether 'Stay in Chrome' button should be shown or hidden.
const bool show_stay_in_chrome_;
// Whether 'Remember my choice' checkbox should be shown or hidden.
const bool show_remember_selection_;
// The type of bubble to show, used to customize some text and behavior.
const BubbleType bubble_type_;
// The origin initiating this picker.
const absl::optional<url::Origin> initiating_origin_;
};
#endif // CHROME_BROWSER_UI_VIEWS_INTENT_PICKER_BUBBLE_VIEW_H_