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

Side by Side Diff: ash/common/frame/custom_frame_view_ash.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
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/frame/custom_frame_view_ash.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "ash/common/frame/caption_buttons/frame_caption_button_container_view.h "
11 #include "ash/common/frame/frame_border_hit_test.h"
12 #include "ash/common/frame/header_view.h"
13 #include "ash/common/wm/window_state.h"
14 #include "ash/common/wm/window_state_delegate.h"
15 #include "ash/common/wm/window_state_observer.h"
16 #include "ash/common/wm_shell.h"
17 #include "ash/common/wm_window.h"
18 #include "ash/shared/immersive_fullscreen_controller.h"
19 #include "ash/shared/immersive_fullscreen_controller_delegate.h"
20 #include "ui/aura/client/aura_constants.h"
21 #include "ui/aura/window.h"
22 #include "ui/aura/window_observer.h"
23 #include "ui/gfx/geometry/rect.h"
24 #include "ui/gfx/geometry/rect_conversions.h"
25 #include "ui/gfx/geometry/size.h"
26 #include "ui/views/view.h"
27 #include "ui/views/view_targeter.h"
28 #include "ui/views/widget/widget.h"
29 #include "ui/views/widget/widget_delegate.h"
30
31 namespace ash {
32
33 namespace {
34
35 ///////////////////////////////////////////////////////////////////////////////
36 // CustomFrameViewAshWindowStateDelegate
37
38 // Handles a user's fullscreen request (Shift+F4/F4). Puts the window into
39 // immersive fullscreen if immersive fullscreen is enabled for non-browser
40 // windows.
41 class CustomFrameViewAshWindowStateDelegate : public wm::WindowStateDelegate,
42 public wm::WindowStateObserver,
43 public aura::WindowObserver {
44 public:
45 CustomFrameViewAshWindowStateDelegate(wm::WindowState* window_state,
46 CustomFrameViewAsh* custom_frame_view,
47 bool enable_immersive)
48 : window_state_(nullptr) {
49 // Add a window state observer to exit fullscreen properly in case
50 // fullscreen is exited without going through
51 // WindowState::ToggleFullscreen(). This is the case when exiting
52 // immersive fullscreen via the "Restore" window control.
53 // TODO(pkotwicz): This is a hack. Remove ASAP. http://crbug.com/319048
54 window_state_ = window_state;
55 window_state_->AddObserver(this);
56 window_state_->window()->aura_window()->AddObserver(this);
57
58 if (!enable_immersive)
59 return;
60
61 immersive_fullscreen_controller_ =
62 WmShell::Get()->CreateImmersiveFullscreenController();
63 if (immersive_fullscreen_controller_) {
64 custom_frame_view->InitImmersiveFullscreenControllerForView(
65 immersive_fullscreen_controller_.get());
66 }
67 }
68 ~CustomFrameViewAshWindowStateDelegate() override {
69 if (window_state_) {
70 window_state_->RemoveObserver(this);
71 window_state_->window()->aura_window()->RemoveObserver(this);
72 }
73 }
74
75 private:
76 // Overridden from wm::WindowStateDelegate:
77 bool ToggleFullscreen(wm::WindowState* window_state) override {
78 bool enter_fullscreen = !window_state->IsFullscreen();
79 if (enter_fullscreen)
80 window_state_->window()->SetShowState(ui::SHOW_STATE_FULLSCREEN);
81 else
82 window_state->Restore();
83 if (immersive_fullscreen_controller_) {
84 immersive_fullscreen_controller_->SetEnabled(
85 ImmersiveFullscreenController::WINDOW_TYPE_OTHER, enter_fullscreen);
86 }
87 return true;
88 }
89 // Overridden from aura::WindowObserver:
90 void OnWindowDestroying(aura::Window* window) override {
91 window_state_->RemoveObserver(this);
92 window->RemoveObserver(this);
93 window_state_ = nullptr;
94 }
95 // Overridden from wm::WindowStateObserver:
96 void OnPostWindowStateTypeChange(wm::WindowState* window_state,
97 wm::WindowStateType old_type) override {
98 if (!window_state->IsFullscreen() && !window_state->IsMinimized() &&
99 immersive_fullscreen_controller_ &&
100 immersive_fullscreen_controller_->IsEnabled()) {
101 immersive_fullscreen_controller_->SetEnabled(
102 ImmersiveFullscreenController::WINDOW_TYPE_OTHER, false);
103 }
104 }
105
106 wm::WindowState* window_state_;
107 std::unique_ptr<ImmersiveFullscreenController>
108 immersive_fullscreen_controller_;
109
110 DISALLOW_COPY_AND_ASSIGN(CustomFrameViewAshWindowStateDelegate);
111 };
112
113 } // namespace
114
115 ///////////////////////////////////////////////////////////////////////////////
116 // CustomFrameViewAsh::OverlayView
117
118 // View which takes up the entire widget and contains the HeaderView. HeaderView
119 // is a child of OverlayView to avoid creating a larger texture than necessary
120 // when painting the HeaderView to its own layer.
121 class CustomFrameViewAsh::OverlayView : public views::View,
122 public views::ViewTargeterDelegate {
123 public:
124 explicit OverlayView(HeaderView* header_view);
125 ~OverlayView() override;
126
127 // views::View:
128 void Layout() override;
129
130 private:
131 // views::ViewTargeterDelegate:
132 bool DoesIntersectRect(const views::View* target,
133 const gfx::Rect& rect) const override;
134
135 HeaderView* header_view_;
136
137 DISALLOW_COPY_AND_ASSIGN(OverlayView);
138 };
139
140 CustomFrameViewAsh::OverlayView::OverlayView(HeaderView* header_view)
141 : header_view_(header_view) {
142 AddChildView(header_view);
143 SetEventTargeter(
144 std::unique_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
145 }
146
147 CustomFrameViewAsh::OverlayView::~OverlayView() {}
148
149 ///////////////////////////////////////////////////////////////////////////////
150 // CustomFrameViewAsh::OverlayView, views::View overrides:
151
152 void CustomFrameViewAsh::OverlayView::Layout() {
153 // Layout |header_view_| because layout affects the result of
154 // GetPreferredOnScreenHeight().
155 header_view_->Layout();
156
157 int onscreen_height = header_view_->GetPreferredOnScreenHeight();
158 if (onscreen_height == 0) {
159 header_view_->SetVisible(false);
160 } else {
161 int height = header_view_->GetPreferredHeight();
162 header_view_->SetBounds(0, onscreen_height - height, width(), height);
163 header_view_->SetVisible(true);
164 }
165 }
166
167 ///////////////////////////////////////////////////////////////////////////////
168 // CustomFrameViewAsh::OverlayView, views::ViewTargeterDelegate overrides:
169
170 bool CustomFrameViewAsh::OverlayView::DoesIntersectRect(
171 const views::View* target,
172 const gfx::Rect& rect) const {
173 CHECK_EQ(target, this);
174 // Grab events in the header view. Return false for other events so that they
175 // can be handled by the client view.
176 return header_view_->HitTestRect(rect);
177 }
178
179 ////////////////////////////////////////////////////////////////////////////////
180 // CustomFrameViewAsh, public:
181
182 // static
183 const char CustomFrameViewAsh::kViewClassName[] = "CustomFrameViewAsh";
184
185 CustomFrameViewAsh::CustomFrameViewAsh(
186 views::Widget* frame,
187 ImmersiveFullscreenControllerDelegate* immersive_delegate,
188 bool enable_immersive)
189 : frame_(frame),
190 header_view_(new HeaderView(frame)),
191 immersive_delegate_(immersive_delegate ? immersive_delegate
192 : header_view_) {
193 WmWindow* frame_window = WmWindow::Get(frame->GetNativeWindow());
194 frame_window->InstallResizeHandleWindowTargeter(nullptr);
195 // |header_view_| is set as the non client view's overlay view so that it can
196 // overlay the web contents in immersive fullscreen.
197 frame->non_client_view()->SetOverlayView(new OverlayView(header_view_));
198 frame_window->aura_window()->SetProperty(
199 aura::client::kTopViewColor, header_view_->GetInactiveFrameColor());
200
201 // A delegate for a more complex way of fullscreening the window may already
202 // be set. This is the case for packaged apps.
203 wm::WindowState* window_state = frame_window->GetWindowState();
204 if (!window_state->HasDelegate()) {
205 window_state->SetDelegate(std::unique_ptr<wm::WindowStateDelegate>(
206 new CustomFrameViewAshWindowStateDelegate(window_state, this,
207 enable_immersive)));
208 }
209 }
210
211 CustomFrameViewAsh::~CustomFrameViewAsh() {}
212
213 void CustomFrameViewAsh::InitImmersiveFullscreenControllerForView(
214 ImmersiveFullscreenController* immersive_fullscreen_controller) {
215 immersive_fullscreen_controller->Init(immersive_delegate_, frame_,
216 header_view_);
217 }
218
219 void CustomFrameViewAsh::SetFrameColors(SkColor active_frame_color,
220 SkColor inactive_frame_color) {
221 header_view_->SetFrameColors(active_frame_color, inactive_frame_color);
222 WmWindow* frame_window = WmWindow::Get(frame_->GetNativeWindow());
223 frame_window->aura_window()->SetProperty(
224 aura::client::kTopViewColor, header_view_->GetInactiveFrameColor());
225 }
226
227 ////////////////////////////////////////////////////////////////////////////////
228 // CustomFrameViewAsh, views::NonClientFrameView overrides:
229
230 gfx::Rect CustomFrameViewAsh::GetBoundsForClientView() const {
231 gfx::Rect client_bounds = bounds();
232 client_bounds.Inset(0, NonClientTopBorderHeight(), 0, 0);
233 return client_bounds;
234 }
235
236 gfx::Rect CustomFrameViewAsh::GetWindowBoundsForClientBounds(
237 const gfx::Rect& client_bounds) const {
238 gfx::Rect window_bounds = client_bounds;
239 window_bounds.Inset(0, -NonClientTopBorderHeight(), 0, 0);
240 return window_bounds;
241 }
242
243 int CustomFrameViewAsh::NonClientHitTest(const gfx::Point& point) {
244 return FrameBorderNonClientHitTest(
245 this, header_view_->caption_button_container(), point);
246 }
247
248 void CustomFrameViewAsh::GetWindowMask(const gfx::Size& size,
249 gfx::Path* window_mask) {
250 // No window masks in Aura.
251 }
252
253 void CustomFrameViewAsh::ResetWindowControls() {
254 header_view_->ResetWindowControls();
255 }
256
257 void CustomFrameViewAsh::UpdateWindowIcon() {}
258
259 void CustomFrameViewAsh::UpdateWindowTitle() {
260 header_view_->SchedulePaintForTitle();
261 }
262
263 void CustomFrameViewAsh::SizeConstraintsChanged() {
264 header_view_->SizeConstraintsChanged();
265 }
266
267 void CustomFrameViewAsh::ActivationChanged(bool active) {
268 // The icons differ between active and inactive.
269 header_view_->SchedulePaint();
270 }
271
272 ////////////////////////////////////////////////////////////////////////////////
273 // CustomFrameViewAsh, views::View overrides:
274
275 gfx::Size CustomFrameViewAsh::GetPreferredSize() const {
276 gfx::Size pref = frame_->client_view()->GetPreferredSize();
277 gfx::Rect bounds(0, 0, pref.width(), pref.height());
278 return frame_->non_client_view()
279 ->GetWindowBoundsForClientBounds(bounds)
280 .size();
281 }
282
283 void CustomFrameViewAsh::Layout() {
284 views::NonClientFrameView::Layout();
285 WmWindow* frame_window = WmWindow::Get(frame_->GetNativeWindow());
286 frame_window->aura_window()->SetProperty(aura::client::kTopViewInset,
287 NonClientTopBorderHeight());
288 }
289
290 const char* CustomFrameViewAsh::GetClassName() const {
291 return kViewClassName;
292 }
293
294 gfx::Size CustomFrameViewAsh::GetMinimumSize() const {
295 gfx::Size min_client_view_size(frame_->client_view()->GetMinimumSize());
296 return gfx::Size(
297 std::max(header_view_->GetMinimumWidth(), min_client_view_size.width()),
298 NonClientTopBorderHeight() + min_client_view_size.height());
299 }
300
301 gfx::Size CustomFrameViewAsh::GetMaximumSize() const {
302 gfx::Size max_client_size(frame_->client_view()->GetMaximumSize());
303 int width = 0;
304 int height = 0;
305
306 if (max_client_size.width() > 0)
307 width = std::max(header_view_->GetMinimumWidth(), max_client_size.width());
308 if (max_client_size.height() > 0)
309 height = NonClientTopBorderHeight() + max_client_size.height();
310
311 return gfx::Size(width, height);
312 }
313
314 void CustomFrameViewAsh::SchedulePaintInRect(const gfx::Rect& r) {
315 // We may end up here before |header_view_| has been added to the Widget.
316 if (header_view_->GetWidget()) {
317 // The HeaderView is not a child of CustomFrameViewAsh. Redirect the paint
318 // to HeaderView instead.
319 gfx::RectF to_paint(r);
320 views::View::ConvertRectToTarget(this, header_view_, &to_paint);
321 header_view_->SchedulePaintInRect(gfx::ToEnclosingRect(to_paint));
322 } else {
323 views::NonClientFrameView::SchedulePaintInRect(r);
324 }
325 }
326
327 void CustomFrameViewAsh::VisibilityChanged(views::View* starting_from,
328 bool is_visible) {
329 if (is_visible)
330 header_view_->UpdateAvatarIcon();
331 }
332
333 views::View* CustomFrameViewAsh::GetHeaderView() {
334 return header_view_;
335 }
336
337 const views::View* CustomFrameViewAsh::GetAvatarIconViewForTest() const {
338 return header_view_->avatar_icon();
339 }
340
341 ////////////////////////////////////////////////////////////////////////////////
342 // CustomFrameViewAsh, private:
343
344 // views::NonClientFrameView:
345 bool CustomFrameViewAsh::DoesIntersectRect(const views::View* target,
346 const gfx::Rect& rect) const {
347 CHECK_EQ(target, this);
348 // NonClientView hit tests the NonClientFrameView first instead of going in
349 // z-order. Return false so that events get to the OverlayView.
350 return false;
351 }
352
353 FrameCaptionButtonContainerView*
354 CustomFrameViewAsh::GetFrameCaptionButtonContainerViewForTest() {
355 return header_view_->caption_button_container();
356 }
357
358 int CustomFrameViewAsh::NonClientTopBorderHeight() const {
359 return frame_->IsFullscreen() ? 0 : header_view_->GetPreferredHeight();
360 }
361
362 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/frame/custom_frame_view_ash.h ('k') | ash/common/frame/custom_frame_view_ash_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698