1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
// Copyright 2012 The Chromium Authors
// 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_FRAME_BROWSER_ROOT_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_
#include <memory>
#include <optional>
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/widget/root_view.h"
class ToolbarView;
namespace ui {
class OSExchangeData;
}
// RootView implementation used by BrowserFrame. This forwards drop events to
// the TabStrip. Visually the tabstrip extends to the top of the frame, but in
// actually it doesn't. The tabstrip is only as high as a tab. To enable
// dropping above the tabstrip BrowserRootView forwards drop events to the
// TabStrip.
class BrowserRootView : public views::internal::RootView {
METADATA_HEADER(BrowserRootView, views::internal::RootView)
public:
struct DropIndex {
// The index within the tabstrip to drop on/before (see `relative_to_index`
// below).
int index = 0;
// Whether the dropped item should be inserted before `index` or replace
// the tab at `index`.
enum class RelativeToIndex { kInsertBeforeIndex, kReplaceIndex };
RelativeToIndex relative_to_index = RelativeToIndex::kReplaceIndex;
// If `relative_to_index` is `kInsertBeforeIndex`, and `index` is the first
// tab in a tab group, determines whether to drop in the group or just
// before it. This disambiguates a drop before or after a group header.
enum class GroupInclusion { kIncludeInGroup, kDontIncludeInGroup };
GroupInclusion group_inclusion = GroupInclusion::kDontIncludeInGroup;
bool operator==(const DropIndex& other) const = default;
};
class DropTarget {
public:
DropTarget(const DropTarget&) = delete;
DropTarget& operator=(const DropTarget&) = delete;
// Returns a `DropIndex` for the drop. Returns `nullopt` if it is not
// possible to drop at this location.
virtual std::optional<DropIndex> GetDropIndex(
const ui::DropTargetEvent& event) = 0;
virtual DropTarget* GetDropTarget(gfx::Point loc_in_local_coords) = 0;
virtual views::View* GetViewForDrop() = 0;
virtual void HandleDragUpdate(const std::optional<DropIndex>& index) {}
virtual void HandleDragExited() {}
protected:
DropTarget() = default;
virtual ~DropTarget() = default;
};
// You must call set_tabstrip before this class will accept drops.
BrowserRootView(BrowserView* browser_view, views::Widget* widget);
BrowserRootView(const BrowserRootView&) = delete;
BrowserRootView& operator=(const BrowserRootView&) = delete;
~BrowserRootView() override;
// views::View:
bool GetDropFormats(int* formats,
std::set<ui::ClipboardFormatType>* format_types) override;
bool AreDropTypesRequired() override;
bool CanDrop(const ui::OSExchangeData& data) override;
void OnDragEntered(const ui::DropTargetEvent& event) override;
int OnDragUpdated(const ui::DropTargetEvent& event) override;
void OnDragExited() override;
DropCallback GetDropCallback(const ui::DropTargetEvent& event) override;
bool OnMouseWheel(const ui::MouseWheelEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
protected:
// views::View:
void PaintChildren(const views::PaintInfo& paint_info) override;
private:
friend class BrowserRootViewBrowserTest;
FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest, ClearDropInfo);
FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest, DropOrderingCorrect);
FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest,
InitiatorOriginForDroppedLink);
// Used during a drop session of a url. Tracks the position of the drop.
struct DropInfo {
DropInfo();
~DropInfo();
raw_ptr<DropTarget, DanglingUntriaged> target = nullptr;
// Where to drop the urls.
std::optional<DropIndex> index;
// The validated URLs for the drop event.
std::vector<GURL> urls;
// An incrementing sequence number for `DropInfo`s.
int sequence = 0;
// Set to true when the filtering of the URLs being dropped is complete.
bool filtering_complete = false;
};
// Converts `event` from the hosts coordinate system to the view's
// coordinate system, and gets the `DropIndex` for the drop.
std::optional<DropIndex> GetDropIndexForEvent(
const ui::DropTargetEvent& event,
const ui::OSExchangeData& data,
DropTarget* target);
DropTarget* GetDropTarget(const ui::DropTargetEvent& event);
// Called when the filtering for supported URLs is complete.
void OnFilteringComplete(int sequence, std::vector<GURL> urls);
// Sets a callback for when URL filtering is complete. Be sure to wait for
// filtering to be complete before checking the drag operation returned by
// `OnDragUpdated()` or calling the drop callback in tests.
void SetOnFilteringCompleteClosureForTesting(base::OnceClosure closure);
TabStrip* tabstrip() { return browser_view_->tabstrip(); }
ToolbarView* toolbar() { return browser_view_->toolbar(); }
// Returns a URL if |data| has string contents and the user can "paste and
// go".
std::optional<GURL> GetPasteAndGoURL(const ui::OSExchangeData& data);
// Navigates to the dropped URLs.
void NavigateToDroppedUrls(
std::unique_ptr<DropInfo> drop_info,
const ui::DropTargetEvent& event,
ui::mojom::DragOperation& output_drag_op,
std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner);
// The BrowserView.
raw_ptr<BrowserView, AcrossTasksDanglingUntriaged> browser_view_ = nullptr;
// Used to calculate partial offsets in scrolls that occur for a smooth
// scroll device.
int scroll_remainder_x_ = 0;
int scroll_remainder_y_ = 0;
std::unique_ptr<DropInfo> drop_info_;
base::OnceClosure on_filtering_complete_closure_;
base::WeakPtrFactory<BrowserRootView> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_ROOT_VIEW_H_
|