Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1016)

Side by Side Diff: ash/common/shelf/overflow_bubble_view.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/common/shelf/overflow_bubble_view.h ('k') | ash/common/shelf/overflow_button.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/common/shelf/overflow_bubble_view.h"
6
7 #include <algorithm>
8
9 #include "ash/common/shelf/shelf_constants.h"
10 #include "ash/common/shelf/wm_shelf.h"
11 #include "ash/common/wm_window.h"
12 #include "ash/public/cpp/shell_window_ids.h"
13 #include "ash/root_window_controller.h"
14 #include "ui/display/display.h"
15 #include "ui/display/screen.h"
16 #include "ui/events/event.h"
17 #include "ui/gfx/geometry/insets.h"
18 #include "ui/views/bubble/bubble_frame_view.h"
19 #include "ui/views/view.h"
20 #include "ui/views/widget/widget.h"
21
22 namespace ash {
23 namespace {
24
25 // Max bubble size to screen size ratio.
26 const float kMaxBubbleSizeToScreenRatio = 0.5f;
27
28 // Inner padding in pixels for shelf view inside bubble.
29 const int kPadding = 2;
30
31 // Padding space in pixels between ShelfView's left/top edge to its contents.
32 const int kShelfViewLeadingInset = 8;
33
34 } // namespace
35
36 OverflowBubbleView::OverflowBubbleView(WmShelf* wm_shelf)
37 : wm_shelf_(wm_shelf), shelf_view_(nullptr) {
38 DCHECK(wm_shelf_);
39 }
40
41 OverflowBubbleView::~OverflowBubbleView() {}
42
43 void OverflowBubbleView::InitOverflowBubble(views::View* anchor,
44 views::View* shelf_view) {
45 shelf_view_ = shelf_view;
46
47 SetAnchorView(anchor);
48 set_arrow(GetBubbleArrow());
49 set_mirror_arrow_in_rtl(false);
50 set_background(nullptr);
51 set_color(kShelfDefaultBaseColor);
52 set_margins(gfx::Insets(kPadding, kPadding, kPadding, kPadding));
53 // Overflow bubble should not get focus. If it get focus when it is shown,
54 // active state item is changed to running state.
55 set_can_activate(false);
56
57 // Makes bubble view has a layer and clip its children layers.
58 SetPaintToLayer();
59 layer()->SetFillsBoundsOpaquely(false);
60 layer()->SetMasksToBounds(true);
61
62 // Calls into OnBeforeBubbleWidgetInit to set the window parent container.
63 views::BubbleDialogDelegateView::CreateBubble(this);
64 AddChildView(shelf_view_);
65 }
66
67 const gfx::Size OverflowBubbleView::GetContentsSize() const {
68 return shelf_view_->GetPreferredSize();
69 }
70
71 // Gets arrow location based on shelf alignment.
72 views::BubbleBorder::Arrow OverflowBubbleView::GetBubbleArrow() const {
73 switch (wm_shelf_->GetAlignment()) {
74 case SHELF_ALIGNMENT_BOTTOM:
75 case SHELF_ALIGNMENT_BOTTOM_LOCKED:
76 return views::BubbleBorder::BOTTOM_LEFT;
77 case SHELF_ALIGNMENT_LEFT:
78 return views::BubbleBorder::LEFT_TOP;
79 case SHELF_ALIGNMENT_RIGHT:
80 return views::BubbleBorder::RIGHT_TOP;
81 }
82 NOTREACHED();
83 return views::BubbleBorder::NONE;
84 }
85
86 void OverflowBubbleView::ScrollByXOffset(int x_offset) {
87 const gfx::Rect visible_bounds(GetContentsBounds());
88 const gfx::Size contents_size(GetContentsSize());
89
90 DCHECK_GE(contents_size.width(), visible_bounds.width());
91 int x = std::min(contents_size.width() - visible_bounds.width(),
92 std::max(0, scroll_offset_.x() + x_offset));
93 scroll_offset_.set_x(x);
94 }
95
96 void OverflowBubbleView::ScrollByYOffset(int y_offset) {
97 const gfx::Rect visible_bounds(GetContentsBounds());
98 const gfx::Size contents_size(GetContentsSize());
99
100 DCHECK_GE(contents_size.width(), visible_bounds.width());
101 int y = std::min(contents_size.height() - visible_bounds.height(),
102 std::max(0, scroll_offset_.y() + y_offset));
103 scroll_offset_.set_y(y);
104 }
105
106 gfx::Size OverflowBubbleView::GetPreferredSize() const {
107 gfx::Size preferred_size = GetContentsSize();
108
109 const gfx::Rect monitor_rect =
110 display::Screen::GetScreen()
111 ->GetDisplayNearestPoint(GetAnchorRect().CenterPoint())
112 .work_area();
113 if (!monitor_rect.IsEmpty()) {
114 if (wm_shelf_->IsHorizontalAlignment()) {
115 preferred_size.set_width(
116 std::min(preferred_size.width(),
117 static_cast<int>(monitor_rect.width() *
118 kMaxBubbleSizeToScreenRatio)));
119 } else {
120 preferred_size.set_height(
121 std::min(preferred_size.height(),
122 static_cast<int>(monitor_rect.height() *
123 kMaxBubbleSizeToScreenRatio)));
124 }
125 }
126
127 return preferred_size;
128 }
129
130 void OverflowBubbleView::Layout() {
131 shelf_view_->SetBoundsRect(gfx::Rect(
132 gfx::PointAtOffsetFromOrigin(-scroll_offset_), GetContentsSize()));
133 }
134
135 void OverflowBubbleView::ChildPreferredSizeChanged(views::View* child) {
136 // When contents size is changed, ContentsBounds should be updated before
137 // calculating scroll offset.
138 SizeToContents();
139
140 // Ensures |shelf_view_| is still visible.
141 if (wm_shelf_->IsHorizontalAlignment())
142 ScrollByXOffset(0);
143 else
144 ScrollByYOffset(0);
145 Layout();
146 }
147
148 bool OverflowBubbleView::OnMouseWheel(const ui::MouseWheelEvent& event) {
149 // The MouseWheelEvent was changed to support both X and Y offsets
150 // recently, but the behavior of this function was retained to continue
151 // using Y offsets only. Might be good to simply scroll in both
152 // directions as in OverflowBubbleView::OnScrollEvent.
153 if (wm_shelf_->IsHorizontalAlignment())
154 ScrollByXOffset(-event.y_offset());
155 else
156 ScrollByYOffset(-event.y_offset());
157 Layout();
158
159 return true;
160 }
161
162 void OverflowBubbleView::OnScrollEvent(ui::ScrollEvent* event) {
163 ScrollByXOffset(-event->x_offset());
164 ScrollByYOffset(-event->y_offset());
165 Layout();
166 event->SetHandled();
167 }
168
169 int OverflowBubbleView::GetDialogButtons() const {
170 return ui::DIALOG_BUTTON_NONE;
171 }
172
173 void OverflowBubbleView::OnBeforeBubbleWidgetInit(
174 views::Widget::InitParams* params,
175 views::Widget* bubble_widget) const {
176 // Place the bubble in the same root window as the anchor.
177 WmWindow::Get(anchor_widget()->GetNativeWindow())
178 ->GetRootWindowController()
179 ->ConfigureWidgetInitParamsForContainer(
180 bubble_widget, kShellWindowId_ShelfBubbleContainer, params);
181 }
182
183 gfx::Rect OverflowBubbleView::GetBubbleBounds() {
184 views::BubbleBorder* border = GetBubbleFrameView()->bubble_border();
185 gfx::Insets bubble_insets = border->GetInsets();
186
187 const int border_size = views::BubbleBorder::is_arrow_on_horizontal(arrow())
188 ? bubble_insets.left()
189 : bubble_insets.top();
190 const int arrow_offset = border_size + kPadding + kShelfViewLeadingInset +
191 GetShelfConstant(SHELF_SIZE) / 2;
192
193 const gfx::Size content_size = GetPreferredSize();
194 border->set_arrow_offset(arrow_offset);
195
196 const gfx::Rect anchor_rect = GetAnchorRect();
197 gfx::Rect bubble_rect = GetBubbleFrameView()->GetUpdatedWindowBounds(
198 anchor_rect, content_size, false);
199
200 gfx::Rect monitor_rect =
201 display::Screen::GetScreen()
202 ->GetDisplayNearestPoint(anchor_rect.CenterPoint())
203 .work_area();
204
205 int offset = 0;
206 if (views::BubbleBorder::is_arrow_on_horizontal(arrow())) {
207 if (bubble_rect.x() < monitor_rect.x())
208 offset = monitor_rect.x() - bubble_rect.x();
209 else if (bubble_rect.right() > monitor_rect.right())
210 offset = monitor_rect.right() - bubble_rect.right();
211
212 bubble_rect.Offset(offset, 0);
213 border->set_arrow_offset(anchor_rect.CenterPoint().x() - bubble_rect.x());
214 } else {
215 if (bubble_rect.y() < monitor_rect.y())
216 offset = monitor_rect.y() - bubble_rect.y();
217 else if (bubble_rect.bottom() > monitor_rect.bottom())
218 offset = monitor_rect.bottom() - bubble_rect.bottom();
219
220 bubble_rect.Offset(0, offset);
221 border->set_arrow_offset(anchor_rect.CenterPoint().y() - bubble_rect.y());
222 }
223
224 GetBubbleFrameView()->SchedulePaint();
225 return bubble_rect;
226 }
227
228 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/shelf/overflow_bubble_view.h ('k') | ash/common/shelf/overflow_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698