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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
// 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 UI_VIEWS_BUBBLE_BUBBLE_DIALOG_DELEGATE_H_
#define UI_VIEWS_BUBBLE_BUBBLE_DIALOG_DELEGATE_H_
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
#include "ui/views/window/dialog_delegate.h"
namespace gfx {
class FontList;
class Rect;
}
namespace views {
class BubbleFrameView;
// BubbleDialogDelegateView is a special DialogDelegateView for bubbles.
class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView,
public WidgetObserver {
public:
// Internal class name.
static const char kViewClassName[];
enum class CloseReason {
DEACTIVATION,
ESCAPE,
CLOSE_BUTTON,
UNKNOWN,
};
~BubbleDialogDelegateView() override;
// Create and initialize the bubble Widget(s) with proper bounds.
static Widget* CreateBubble(BubbleDialogDelegateView* bubble_delegate);
// WidgetDelegateView overrides:
bool ShouldShowCloseButton() const override;
ClientView* CreateClientView(Widget* widget) override;
NonClientFrameView* CreateNonClientFrameView(Widget* widget) override;
void GetAccessibleState(ui::AXViewState* state) override;
const char* GetClassName() const override;
// WidgetObserver overrides:
void OnWidgetClosing(Widget* widget) override;
void OnWidgetDestroying(Widget* widget) override;
void OnWidgetVisibilityChanging(Widget* widget, bool visible) override;
void OnWidgetVisibilityChanged(Widget* widget, bool visible) override;
void OnWidgetActivationChanged(Widget* widget, bool active) override;
void OnWidgetBoundsChanged(Widget* widget,
const gfx::Rect& new_bounds) override;
bool close_on_esc() const { return close_on_esc_; }
void set_close_on_esc(bool close_on_esc) { close_on_esc_ = close_on_esc; }
bool close_on_deactivate() const { return close_on_deactivate_; }
void set_close_on_deactivate(bool close) { close_on_deactivate_ = close; }
View* GetAnchorView() const;
Widget* anchor_widget() const { return anchor_widget_; }
// The anchor rect is used in the absence of an assigned anchor view.
const gfx::Rect& anchor_rect() const { return anchor_rect_; }
BubbleBorder::Arrow arrow() const { return arrow_; }
void set_arrow(BubbleBorder::Arrow arrow) { arrow_ = arrow; }
BubbleBorder::Shadow shadow() const { return shadow_; }
void set_shadow(BubbleBorder::Shadow shadow) { shadow_ = shadow; }
SkColor color() const { return color_; }
void set_color(SkColor color) {
color_ = color;
color_explicitly_set_ = true;
}
const gfx::Insets& margins() const { return margins_; }
void set_margins(const gfx::Insets& margins) { margins_ = margins; }
const gfx::Insets& anchor_view_insets() const { return anchor_view_insets_; }
void set_anchor_view_insets(const gfx::Insets& i) { anchor_view_insets_ = i; }
gfx::NativeView parent_window() const { return parent_window_; }
void set_parent_window(gfx::NativeView window) { parent_window_ = window; }
bool accept_events() const { return accept_events_; }
void set_accept_events(bool accept_events) { accept_events_ = accept_events; }
bool border_accepts_events() const { return border_accepts_events_; }
void set_border_accepts_events(bool event) { border_accepts_events_ = event; }
bool adjust_if_offscreen() const { return adjust_if_offscreen_; }
void set_adjust_if_offscreen(bool adjust) { adjust_if_offscreen_ = adjust; }
CloseReason close_reason() const { return close_reason_; }
// Get the arrow's anchor rect in screen space.
virtual gfx::Rect GetAnchorRect() const;
// Allows delegates to provide custom parameters before widget initialization.
virtual void OnBeforeBubbleWidgetInit(Widget::InitParams* params,
Widget* widget) const;
// Sets |margins_| to a default picked for smaller bubbles.
void UseCompactMargins();
// Sets the bubble alignment relative to the anchor. This may only be called
// after calling CreateBubble.
void SetAlignment(BubbleBorder::BubbleAlignment alignment);
// Sets the bubble arrow paint type.
void SetArrowPaintType(BubbleBorder::ArrowPaintType paint_type);
// Call this method when the anchor bounds have changed to reposition the
// bubble. The bubble is automatically repositioned when the anchor view
// bounds change as a result of the widget's bounds changing.
void OnAnchorBoundsChanged();
protected:
BubbleDialogDelegateView();
BubbleDialogDelegateView(View* anchor_view, BubbleBorder::Arrow arrow);
// Get bubble bounds from the anchor rect and client view's preferred size.
virtual gfx::Rect GetBubbleBounds();
// Return a FontList to use for the title of the bubble.
// (The default is MediumFont).
virtual const gfx::FontList& GetTitleFontList() const;
// View overrides:
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
// Perform view initialization on the contents for bubble sizing.
virtual void Init();
// Sets the anchor view or rect and repositions the bubble. Note that if a
// valid view gets passed, the anchor rect will get ignored. If the view gets
// deleted, but no new view gets set, the last known anchor postion will get
// returned.
void SetAnchorView(View* anchor_view);
void SetAnchorRect(const gfx::Rect& rect);
// Resize and potentially move the bubble to fit the content's preferred size.
void SizeToContents();
BubbleFrameView* GetBubbleFrameView() const;
private:
friend class BubbleBorderDelegate;
friend class BubbleWindowTargeter;
FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, CreateDelegate);
FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, NonClientHitTest);
// Update the bubble color from |theme|, unless it was explicitly set.
void UpdateColorsFromTheme(const ui::NativeTheme* theme);
// Handles widget visibility changes.
void HandleVisibilityChanged(Widget* widget, bool visible);
// Flags controlling bubble closure on the escape key and deactivation.
bool close_on_esc_;
bool close_on_deactivate_;
// The view and widget to which this bubble is anchored. Since an anchor view
// can be deleted without notice, we store it in the ViewStorage and retrieve
// it from there. It will make sure that the view is still valid.
const int anchor_view_storage_id_;
Widget* anchor_widget_;
// The anchor rect used in the absence of an anchor view.
mutable gfx::Rect anchor_rect_;
// The arrow's location on the bubble.
BubbleBorder::Arrow arrow_;
// Bubble border shadow to use.
BubbleBorder::Shadow shadow_;
// The background color of the bubble; and flag for when it's explicitly set.
SkColor color_;
bool color_explicitly_set_;
// The margins between the content and the inside of the border.
gfx::Insets margins_;
// Insets applied to the |anchor_view_| bounds.
gfx::Insets anchor_view_insets_;
// Specifies whether the bubble (or its border) handles mouse events, etc.
bool accept_events_;
bool border_accepts_events_;
// If true (defaults to true), the arrow may be mirrored and moved to fit the
// bubble on screen better. It would be a no-op if the bubble has no arrow.
bool adjust_if_offscreen_;
// Parent native window of the bubble.
gfx::NativeView parent_window_;
CloseReason close_reason_;
DISALLOW_COPY_AND_ASSIGN(BubbleDialogDelegateView);
};
} // namespace views
#endif // UI_VIEWS_BUBBLE_BUBBLE_DELEGATE2_H_
|