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

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

Issue 2164733002: mash: Convert ash shelf overflow bubble to wm common types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review comments Created 4 years, 5 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/shelf/overflow_bubble_view.h ('k') | ash/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/shelf/overflow_bubble_view.h"
6
7 #include <algorithm>
8
9 #include "ash/common/material_design/material_design_controller.h"
10 #include "ash/common/shelf/shelf_constants.h"
11 #include "ash/common/shell_window_ids.h"
12 #include "ash/root_window_controller.h"
13 #include "ash/shelf/shelf.h"
14 #include "ash/shelf/shelf_view.h"
15 #include "ash/shell.h"
16 #include "ui/display/display.h"
17 #include "ui/display/screen.h"
18 #include "ui/events/event.h"
19 #include "ui/gfx/geometry/insets.h"
20 #include "ui/views/bubble/bubble_frame_view.h"
21 #include "ui/views/widget/widget.h"
22
23 namespace ash {
24 namespace {
25
26 // Max bubble size to screen size ratio.
27 const float kMaxBubbleSizeToScreenRatio = 0.5f;
28
29 // Inner padding in pixels for shelf view inside bubble.
30 const int kPadding = 2;
31
32 // Padding space in pixels between ShelfView's left/top edge to its contents.
33 const int kShelfViewLeadingInset = 8;
34
35 } // namespace
36
37 OverflowBubbleView::OverflowBubbleView() : shelf_view_(NULL) {}
38
39 OverflowBubbleView::~OverflowBubbleView() {}
40
41 void OverflowBubbleView::InitOverflowBubble(views::View* anchor,
42 ShelfView* shelf_view) {
43 shelf_view_ = shelf_view;
44
45 SetAnchorView(anchor);
46 set_arrow(GetBubbleArrow());
47 set_mirror_arrow_in_rtl(false);
48 set_background(NULL);
49 SkColor color = MaterialDesignController::IsShelfMaterial()
50 ? kShelfBaseColor
51 : SkColorSetA(kShelfBaseColor,
52 GetShelfConstant(SHELF_BACKGROUND_ALPHA));
53 set_color(color);
54 set_margins(gfx::Insets(kPadding, kPadding, kPadding, kPadding));
55 // Overflow bubble should not get focus. If it get focus when it is shown,
56 // active state item is changed to running state.
57 set_can_activate(false);
58
59 // Makes bubble view has a layer and clip its children layers.
60 SetPaintToLayer(true);
61 layer()->SetFillsBoundsOpaquely(false);
62 layer()->SetMasksToBounds(true);
63
64 set_parent_window(Shell::GetContainer(
65 anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
66 kShellWindowId_ShelfBubbleContainer));
67 views::BubbleDialogDelegateView::CreateBubble(this);
68 AddChildView(shelf_view_);
69 }
70
71 bool OverflowBubbleView::IsHorizontalAlignment() const {
72 return shelf_view_ ? shelf_view_->shelf()->IsHorizontalAlignment() : false;
73 }
74
75 const gfx::Size OverflowBubbleView::GetContentsSize() const {
76 return static_cast<views::View*>(shelf_view_)->GetPreferredSize();
77 }
78
79 // Gets arrow location based on shelf alignment.
80 views::BubbleBorder::Arrow OverflowBubbleView::GetBubbleArrow() const {
81 if (!shelf_view_)
82 return views::BubbleBorder::NONE;
83 return shelf_view_->shelf()->SelectValueForShelfAlignment(
84 views::BubbleBorder::BOTTOM_LEFT, views::BubbleBorder::LEFT_TOP,
85 views::BubbleBorder::RIGHT_TOP);
86 }
87
88 void OverflowBubbleView::ScrollByXOffset(int x_offset) {
89 const gfx::Rect visible_bounds(GetContentsBounds());
90 const gfx::Size contents_size(GetContentsSize());
91
92 DCHECK_GE(contents_size.width(), visible_bounds.width());
93 int x = std::min(contents_size.width() - visible_bounds.width(),
94 std::max(0, scroll_offset_.x() + x_offset));
95 scroll_offset_.set_x(x);
96 }
97
98 void OverflowBubbleView::ScrollByYOffset(int y_offset) {
99 const gfx::Rect visible_bounds(GetContentsBounds());
100 const gfx::Size contents_size(GetContentsSize());
101
102 DCHECK_GE(contents_size.width(), visible_bounds.width());
103 int y = std::min(contents_size.height() - visible_bounds.height(),
104 std::max(0, scroll_offset_.y() + y_offset));
105 scroll_offset_.set_y(y);
106 }
107
108 gfx::Size OverflowBubbleView::GetPreferredSize() const {
109 gfx::Size preferred_size = GetContentsSize();
110
111 const gfx::Rect monitor_rect =
112 display::Screen::GetScreen()
113 ->GetDisplayNearestPoint(GetAnchorRect().CenterPoint())
114 .work_area();
115 if (!monitor_rect.IsEmpty()) {
116 if (IsHorizontalAlignment()) {
117 preferred_size.set_width(
118 std::min(preferred_size.width(),
119 static_cast<int>(monitor_rect.width() *
120 kMaxBubbleSizeToScreenRatio)));
121 } else {
122 preferred_size.set_height(
123 std::min(preferred_size.height(),
124 static_cast<int>(monitor_rect.height() *
125 kMaxBubbleSizeToScreenRatio)));
126 }
127 }
128
129 return preferred_size;
130 }
131
132 void OverflowBubbleView::Layout() {
133 shelf_view_->SetBoundsRect(gfx::Rect(
134 gfx::PointAtOffsetFromOrigin(-scroll_offset_), GetContentsSize()));
135 }
136
137 void OverflowBubbleView::ChildPreferredSizeChanged(views::View* child) {
138 // When contents size is changed, ContentsBounds should be updated before
139 // calculating scroll offset.
140 SizeToContents();
141
142 // Ensures |shelf_view_| is still visible.
143 if (IsHorizontalAlignment())
144 ScrollByXOffset(0);
145 else
146 ScrollByYOffset(0);
147 Layout();
148 }
149
150 bool OverflowBubbleView::OnMouseWheel(const ui::MouseWheelEvent& event) {
151 // The MouseWheelEvent was changed to support both X and Y offsets
152 // recently, but the behavior of this function was retained to continue
153 // using Y offsets only. Might be good to simply scroll in both
154 // directions as in OverflowBubbleView::OnScrollEvent.
155 if (IsHorizontalAlignment())
156 ScrollByXOffset(-event.y_offset());
157 else
158 ScrollByYOffset(-event.y_offset());
159 Layout();
160
161 return true;
162 }
163
164 void OverflowBubbleView::OnScrollEvent(ui::ScrollEvent* event) {
165 ScrollByXOffset(-event->x_offset());
166 ScrollByYOffset(-event->y_offset());
167 Layout();
168 event->SetHandled();
169 }
170
171 int OverflowBubbleView::GetDialogButtons() const {
172 return ui::DIALOG_BUTTON_NONE;
173 }
174
175 gfx::Rect OverflowBubbleView::GetBubbleBounds() {
176 views::BubbleBorder* border = GetBubbleFrameView()->bubble_border();
177 gfx::Insets bubble_insets = border->GetInsets();
178
179 const int border_size = views::BubbleBorder::is_arrow_on_horizontal(arrow())
180 ? bubble_insets.left()
181 : bubble_insets.top();
182 const int arrow_offset = border_size + kPadding + kShelfViewLeadingInset +
183 GetShelfConstant(SHELF_SIZE) / 2;
184
185 const gfx::Size content_size = GetPreferredSize();
186 border->set_arrow_offset(arrow_offset);
187
188 const gfx::Rect anchor_rect = GetAnchorRect();
189 gfx::Rect bubble_rect = GetBubbleFrameView()->GetUpdatedWindowBounds(
190 anchor_rect, content_size, false);
191
192 gfx::Rect monitor_rect =
193 display::Screen::GetScreen()
194 ->GetDisplayNearestPoint(anchor_rect.CenterPoint())
195 .work_area();
196
197 int offset = 0;
198 if (views::BubbleBorder::is_arrow_on_horizontal(arrow())) {
199 if (bubble_rect.x() < monitor_rect.x())
200 offset = monitor_rect.x() - bubble_rect.x();
201 else if (bubble_rect.right() > monitor_rect.right())
202 offset = monitor_rect.right() - bubble_rect.right();
203
204 bubble_rect.Offset(offset, 0);
205 border->set_arrow_offset(anchor_rect.CenterPoint().x() - bubble_rect.x());
206 } else {
207 if (bubble_rect.y() < monitor_rect.y())
208 offset = monitor_rect.y() - bubble_rect.y();
209 else if (bubble_rect.bottom() > monitor_rect.bottom())
210 offset = monitor_rect.bottom() - bubble_rect.bottom();
211
212 bubble_rect.Offset(0, offset);
213 border->set_arrow_offset(anchor_rect.CenterPoint().y() - bubble_rect.y());
214 }
215
216 GetBubbleFrameView()->SchedulePaint();
217 return bubble_rect;
218 }
219
220 } // namespace ash
OLDNEW
« no previous file with comments | « ash/shelf/overflow_bubble_view.h ('k') | ash/shelf/overflow_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698