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

Side by Side Diff: ash/wm/custom_frame_view_ash.cc

Issue 59043013: Add flag to enable immersive fullscreen for v2 apps (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « ash/wm/custom_frame_view_ash.h ('k') | ash/wm/immersive_fullscreen_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/custom_frame_view_ash.h" 5 #include "ash/wm/custom_frame_view_ash.h"
6 6
7 #include "ash/wm/caption_buttons/frame_caption_button_container_view.h" 7 #include "ash/wm/caption_buttons/frame_caption_button_container_view.h"
8 #include "ash/wm/caption_buttons/frame_maximize_button.h"
9 #include "ash/wm/caption_buttons/frame_maximize_button_observer.h"
8 #include "ash/wm/frame_border_hit_test_controller.h" 10 #include "ash/wm/frame_border_hit_test_controller.h"
9 #include "ash/wm/header_painter.h" 11 #include "ash/wm/header_painter.h"
12 #include "ash/wm/immersive_fullscreen_controller.h"
10 #include "grit/ash_resources.h" 13 #include "grit/ash_resources.h"
11 #include "ui/gfx/canvas.h" 14 #include "ui/gfx/canvas.h"
12 #include "ui/gfx/font.h" 15 #include "ui/gfx/font.h"
13 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
14 #include "ui/gfx/size.h" 17 #include "ui/gfx/size.h"
18 #include "ui/views/view.h"
15 #include "ui/views/widget/native_widget_aura.h" 19 #include "ui/views/widget/native_widget_aura.h"
16 #include "ui/views/widget/widget.h" 20 #include "ui/views/widget/widget.h"
17 #include "ui/views/widget/widget_delegate.h" 21 #include "ui/views/widget/widget_delegate.h"
22 #include "ui/views/widget/widget_deletion_observer.h"
18 23
19 namespace { 24 namespace {
20 25
21 const gfx::Font& GetTitleFont() { 26 const gfx::Font& GetTitleFont() {
22 static gfx::Font* title_font = NULL; 27 static gfx::Font* title_font = NULL;
23 if (!title_font) 28 if (!title_font)
24 title_font = new gfx::Font(views::NativeWidgetAura::GetWindowTitleFont()); 29 title_font = new gfx::Font(views::NativeWidgetAura::GetWindowTitleFont());
25 return *title_font; 30 return *title_font;
26 } 31 }
27 32
28 } // namespace 33 } // namespace
29 34
30 namespace ash { 35 namespace ash {
31 36
32 // static 37 ///////////////////////////////////////////////////////////////////////////////
33 const char CustomFrameViewAsh::kViewClassName[] = "CustomFrameViewAsh"; 38 // CustomFrameViewAsh::HeaderView
34 39
35 //////////////////////////////////////////////////////////////////////////////// 40 // View which paints the header. It slides off and on screen in immersive
36 // CustomFrameViewAsh, public: 41 // fullscreen.
37 CustomFrameViewAsh::CustomFrameViewAsh(views::Widget* frame) 42 class CustomFrameViewAsh::HeaderView
43 : public views::View,
44 public ImmersiveFullscreenController::Delegate,
45 public FrameMaximizeButtonObserver {
46 public:
47 // |frame| is the widget that the caption buttons act on.
48 explicit HeaderView(views::Widget* frame);
49 virtual ~HeaderView();
50
51 // Schedules a repaint for the entire title.
52 void SchedulePaintForTitle();
53
54 // Tells the window controls to reset themselves to the normal state.
55 void ResetWindowControls();
56
57 // Returns the amount of the view's pixels which should be on screen.
58 int GetPreferredOnScreenHeight() const;
59
60 // Returns the view's preferred height.
61 int GetPreferredHeight() const;
62
63 // Returns the view's minimum width.
64 int GetMinimumWidth() const;
65
66 // views::View overrides:
67 virtual void Layout() OVERRIDE;
68 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
69
70 // Sets whether the header should be painted as active.
71 void set_paint_as_active(bool paint_as_active) {
72 paint_as_active_ = paint_as_active;
73 }
74
75 HeaderPainter* header_painter() {
76 return header_painter_.get();
77 }
78
79 private:
80 // ImmersiveFullscreenController::Delegate overrides:
81 virtual void OnImmersiveRevealStarted() OVERRIDE;
82 virtual void OnImmersiveRevealEnded() OVERRIDE;
83 virtual void OnImmersiveFullscreenExited() OVERRIDE;
84 virtual void SetVisibleFraction(double visible_fraction) OVERRIDE;
85 virtual std::vector<gfx::Rect> GetVisibleBoundsInScreen() const OVERRIDE;
86
87 // FrameMaximizeButtonObserver overrides:
88 virtual void OnMaximizeBubbleShown(views::Widget* bubble) OVERRIDE;
89
90 // The widget that the caption buttons act on.
91 views::Widget* frame_;
92
93 // Helper for painting the header.
94 scoped_ptr<HeaderPainter> header_painter_;
95
96 // View which contains the window caption buttons.
97 FrameCaptionButtonContainerView* caption_button_container_;
98
99 // The maximize bubble widget. |maximize_bubble_| may be non-NULL but have
100 // been already destroyed.
101 views::Widget* maximize_bubble_;
102
103 // Keeps track of whether |maximize_bubble_| is still alive.
104 scoped_ptr<views::WidgetDeletionObserver> maximize_bubble_lifetime_observer_;
105
106 // Whether the header should be painted as active.
107 bool paint_as_active_;
108
109 // The fraction of the header's height which is visible while in fullscreen.
110 // This value is meaningless when not in fullscreen.
111 double fullscreen_visible_fraction_;
112
113 DISALLOW_COPY_AND_ASSIGN(HeaderView);
114 };
115
116 CustomFrameViewAsh::HeaderView::HeaderView(views::Widget* frame)
38 : frame_(frame), 117 : frame_(frame),
118 header_painter_(new ash::HeaderPainter),
39 caption_button_container_(NULL), 119 caption_button_container_(NULL),
40 header_painter_(new ash::HeaderPainter), 120 maximize_bubble_(NULL),
41 frame_border_hit_test_controller_( 121 paint_as_active_(false),
42 new FrameBorderHitTestController(frame_)) { 122 fullscreen_visible_fraction_(0) {
43 // Unfortunately, there is no views::WidgetDelegate::CanMinimize(). Assume 123 // Unfortunately, there is no views::WidgetDelegate::CanMinimize(). Assume
44 // that the window frame can be minimized if it can be maximized. 124 // that the window frame can be minimized if it can be maximized.
45 FrameCaptionButtonContainerView::MinimizeAllowed minimize_allowed = 125 FrameCaptionButtonContainerView::MinimizeAllowed minimize_allowed =
46 frame_->widget_delegate()->CanMaximize() ? 126 frame_->widget_delegate()->CanMaximize() ?
47 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED : 127 FrameCaptionButtonContainerView::MINIMIZE_ALLOWED :
48 FrameCaptionButtonContainerView::MINIMIZE_DISALLOWED; 128 FrameCaptionButtonContainerView::MINIMIZE_DISALLOWED;
49 caption_button_container_ = new FrameCaptionButtonContainerView(frame, 129 caption_button_container_ = new FrameCaptionButtonContainerView(frame_,
50 minimize_allowed); 130 minimize_allowed);
51 AddChildView(caption_button_container_); 131 AddChildView(caption_button_container_);
132 FrameMaximizeButton* frame_maximize_button =
133 caption_button_container_->GetOldStyleSizeButton();
134 if (frame_maximize_button)
135 frame_maximize_button->AddObserver(this);
52 136
53 header_painter_->Init(frame_, this, NULL, caption_button_container_); 137 header_painter_->Init(frame_, this, NULL, caption_button_container_);
54 } 138 }
55 139
140 CustomFrameViewAsh::HeaderView::~HeaderView() {
141 }
142
143 void CustomFrameViewAsh::HeaderView::SchedulePaintForTitle() {
144 header_painter_->SchedulePaintForTitle(GetTitleFont());
145 }
146
147 void CustomFrameViewAsh::HeaderView::ResetWindowControls() {
148 caption_button_container_->ResetWindowControls();
149 }
150
151 int CustomFrameViewAsh::HeaderView::GetPreferredOnScreenHeight() const {
152 if (frame_->IsFullscreen()) {
153 return static_cast<int>(
154 GetPreferredHeight() * fullscreen_visible_fraction_);
155 }
156 return GetPreferredHeight();
157 }
158
159 int CustomFrameViewAsh::HeaderView::GetPreferredHeight() const {
160 // Reserve enough space to see the buttons and the separator line.
161 return caption_button_container_->bounds().bottom() +
162 header_painter_->HeaderContentSeparatorSize();
163 }
164
165 int CustomFrameViewAsh::HeaderView::GetMinimumWidth() const {
166 return header_painter_->GetMinimumHeaderWidth();
167 }
168
169 void CustomFrameViewAsh::HeaderView::Layout() {
170 header_painter_->LayoutHeader(true);
171 header_painter_->set_header_height(GetPreferredHeight());
172 }
173
174 void CustomFrameViewAsh::HeaderView::OnPaint(gfx::Canvas* canvas) {
175 int theme_image_id = 0;
176 if (header_painter_->ShouldUseMinimalHeaderStyle(HeaderPainter::THEMED_NO))
177 theme_image_id = IDR_AURA_WINDOW_HEADER_BASE_MINIMAL;
178 else if (paint_as_active_)
179 theme_image_id = IDR_AURA_WINDOW_HEADER_BASE_ACTIVE;
180 else
181 theme_image_id = IDR_AURA_WINDOW_HEADER_BASE_INACTIVE;
182
183 header_painter_->PaintHeader(
184 canvas,
185 paint_as_active_ ? HeaderPainter::ACTIVE : HeaderPainter::INACTIVE,
186 theme_image_id,
187 0);
188 header_painter_->PaintTitleBar(canvas, GetTitleFont());
189 header_painter_->PaintHeaderContentSeparator(canvas);
190 }
191
192 void CustomFrameViewAsh::HeaderView::OnImmersiveRevealStarted() {
193 fullscreen_visible_fraction_ = 0;
194 SetPaintToLayer(true);
195 parent()->Layout();
196 }
197
198 void CustomFrameViewAsh::HeaderView::OnImmersiveRevealEnded() {
199 fullscreen_visible_fraction_ = 0;
200 SetPaintToLayer(false);
201 parent()->Layout();
202 }
203
204 void CustomFrameViewAsh::HeaderView::OnImmersiveFullscreenExited() {
205 fullscreen_visible_fraction_ = 0;
206 SetPaintToLayer(false);
207 parent()->Layout();
208 }
209
210 void CustomFrameViewAsh::HeaderView::SetVisibleFraction(
211 double visible_fraction) {
212 if (fullscreen_visible_fraction_ != visible_fraction) {
213 fullscreen_visible_fraction_ = visible_fraction;
214 parent()->Layout();
215 }
216 }
217
218 std::vector<gfx::Rect>
219 CustomFrameViewAsh::HeaderView::GetVisibleBoundsInScreen() const {
220 // TODO(pkotwicz): Implement views::View::ConvertRectToScreen().
221 gfx::Rect visible_bounds(GetVisibleBounds());
222 gfx::Point visible_origin_in_screen(visible_bounds.origin());
223 views::View::ConvertPointToScreen(this, &visible_origin_in_screen);
224 std::vector<gfx::Rect> bounds_in_screen;
225 bounds_in_screen.push_back(
226 gfx::Rect(visible_origin_in_screen, visible_bounds.size()));
227 if (maximize_bubble_lifetime_observer_.get() &&
228 maximize_bubble_lifetime_observer_->IsWidgetAlive()) {
229 bounds_in_screen.push_back(maximize_bubble_->GetWindowBoundsInScreen());
230 }
231 return bounds_in_screen;
232 }
233
234 void CustomFrameViewAsh::HeaderView::OnMaximizeBubbleShown(
235 views::Widget* bubble) {
236 maximize_bubble_ = bubble;
237 maximize_bubble_lifetime_observer_.reset(
238 new views::WidgetDeletionObserver(bubble));
239 }
240
241 ///////////////////////////////////////////////////////////////////////////////
242 // CustomFrameViewAsh::OverlayView
243
244 // View which takes up the entire widget and contains the HeaderView. HeaderView
245 // is a child of OverlayView to avoid creating a larger texture than necessary
246 // when painting the HeaderView to its own layer.
247 class CustomFrameViewAsh::OverlayView : public views::View {
248 public:
249 explicit OverlayView(HeaderView* header_view);
250 virtual ~OverlayView();
251
252 // views::View override:
253 virtual void Layout() OVERRIDE;
254 virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE;
255
256 private:
257 HeaderView* header_view_;
258
259 DISALLOW_COPY_AND_ASSIGN(OverlayView);
260 };
261
262 CustomFrameViewAsh::OverlayView::OverlayView(HeaderView* header_view)
263 : header_view_(header_view) {
264 AddChildView(header_view);
265 }
266
267 CustomFrameViewAsh::OverlayView::~OverlayView() {
268 }
269
270 void CustomFrameViewAsh::OverlayView::Layout() {
271 int onscreen_height = header_view_->GetPreferredOnScreenHeight();
272 if (onscreen_height == 0) {
273 header_view_->SetVisible(false);
274 } else {
275 int height = header_view_->GetPreferredHeight();
276 header_view_->SetBounds(0, onscreen_height - height, width(), height);
277 header_view_->SetVisible(true);
278 }
279 }
280
281 bool CustomFrameViewAsh::OverlayView::HitTestRect(const gfx::Rect& rect) const {
282 // Grab events in the header view. Return false for other events so that they
283 // can be handled by the client view.
284 return header_view_->HitTestRect(rect);
285 }
286
287 ////////////////////////////////////////////////////////////////////////////////
288 // CustomFrameViewAsh, public:
289
290 // static
291 const char CustomFrameViewAsh::kViewClassName[] = "CustomFrameViewAsh";
292
293 CustomFrameViewAsh::CustomFrameViewAsh(views::Widget* frame)
294 : frame_(frame),
295 header_view_(new HeaderView(frame)),
296 frame_border_hit_test_controller_(
297 new FrameBorderHitTestController(frame_)) {
298 // |header_view_| is set as the non client view's overlay view so that it can
299 // overlay the web contents in immersive fullscreen.
300 frame->non_client_view()->SetOverlayView(new OverlayView(header_view_));
301 }
302
56 CustomFrameViewAsh::~CustomFrameViewAsh() { 303 CustomFrameViewAsh::~CustomFrameViewAsh() {
57 } 304 }
58 305
306 void CustomFrameViewAsh::InitImmersiveFullscreenControllerForView(
307 ImmersiveFullscreenController* immersive_fullscreen_controller) {
308 immersive_fullscreen_controller->Init(header_view_, frame_, header_view_);
309 }
310
59 //////////////////////////////////////////////////////////////////////////////// 311 ////////////////////////////////////////////////////////////////////////////////
60 // CustomFrameViewAsh, views::NonClientFrameView overrides: 312 // CustomFrameViewAsh, views::NonClientFrameView overrides:
313
61 gfx::Rect CustomFrameViewAsh::GetBoundsForClientView() const { 314 gfx::Rect CustomFrameViewAsh::GetBoundsForClientView() const {
62 int top_height = NonClientTopBorderHeight(); 315 int top_height = NonClientTopBorderHeight();
63 return HeaderPainter::GetBoundsForClientView(top_height, bounds()); 316 return HeaderPainter::GetBoundsForClientView(top_height, bounds());
64 } 317 }
65 318
66 gfx::Rect CustomFrameViewAsh::GetWindowBoundsForClientBounds( 319 gfx::Rect CustomFrameViewAsh::GetWindowBoundsForClientBounds(
67 const gfx::Rect& client_bounds) const { 320 const gfx::Rect& client_bounds) const {
68 int top_height = NonClientTopBorderHeight(); 321 int top_height = NonClientTopBorderHeight();
69 return HeaderPainter::GetWindowBoundsForClientBounds(top_height, 322 return HeaderPainter::GetWindowBoundsForClientBounds(top_height,
70 client_bounds); 323 client_bounds);
71 } 324 }
72 325
73 int CustomFrameViewAsh::NonClientHitTest(const gfx::Point& point) { 326 int CustomFrameViewAsh::NonClientHitTest(const gfx::Point& point) {
74 return FrameBorderHitTestController::NonClientHitTest(this, 327 return FrameBorderHitTestController::NonClientHitTest(this,
75 header_painter_.get(), point); 328 header_view_->header_painter(), point);
76 } 329 }
77 330
78 void CustomFrameViewAsh::GetWindowMask(const gfx::Size& size, 331 void CustomFrameViewAsh::GetWindowMask(const gfx::Size& size,
79 gfx::Path* window_mask) { 332 gfx::Path* window_mask) {
80 // No window masks in Aura. 333 // No window masks in Aura.
81 } 334 }
82 335
83 void CustomFrameViewAsh::ResetWindowControls() { 336 void CustomFrameViewAsh::ResetWindowControls() {
84 caption_button_container_->ResetWindowControls(); 337 header_view_->ResetWindowControls();
85 } 338 }
86 339
87 void CustomFrameViewAsh::UpdateWindowIcon() { 340 void CustomFrameViewAsh::UpdateWindowIcon() {
88 } 341 }
89 342
90 void CustomFrameViewAsh::UpdateWindowTitle() { 343 void CustomFrameViewAsh::UpdateWindowTitle() {
91 header_painter_->SchedulePaintForTitle(GetTitleFont()); 344 header_view_->SchedulePaintForTitle();
92 } 345 }
93 346
94 //////////////////////////////////////////////////////////////////////////////// 347 ////////////////////////////////////////////////////////////////////////////////
95 // CustomFrameViewAsh, views::View overrides: 348 // CustomFrameViewAsh, views::View overrides:
96 349
97 gfx::Size CustomFrameViewAsh::GetPreferredSize() { 350 gfx::Size CustomFrameViewAsh::GetPreferredSize() {
98 gfx::Size pref = frame_->client_view()->GetPreferredSize(); 351 gfx::Size pref = frame_->client_view()->GetPreferredSize();
99 gfx::Rect bounds(0, 0, pref.width(), pref.height()); 352 gfx::Rect bounds(0, 0, pref.width(), pref.height());
100 return frame_->non_client_view()->GetWindowBoundsForClientBounds( 353 return frame_->non_client_view()->GetWindowBoundsForClientBounds(
101 bounds).size(); 354 bounds).size();
102 } 355 }
103 356
104 void CustomFrameViewAsh::Layout() {
105 // Use the shorter maximized layout headers.
106 header_painter_->LayoutHeader(true);
107 header_painter_->set_header_height(NonClientTopBorderHeight());
108 }
109
110 void CustomFrameViewAsh::OnPaint(gfx::Canvas* canvas) {
111 if (frame_->IsFullscreen())
112 return;
113
114 // Prevent bleeding paint onto the client area below the window frame, which
115 // may become visible when the WebContent is transparent.
116 canvas->Save();
117 canvas->ClipRect(gfx::Rect(0, 0, width(), NonClientTopBorderHeight()));
118
119 bool paint_as_active = ShouldPaintAsActive();
120 int theme_image_id = 0;
121 if (header_painter_->ShouldUseMinimalHeaderStyle(HeaderPainter::THEMED_NO))
122 theme_image_id = IDR_AURA_WINDOW_HEADER_BASE_MINIMAL;
123 else if (paint_as_active)
124 theme_image_id = IDR_AURA_WINDOW_HEADER_BASE_ACTIVE;
125 else
126 theme_image_id = IDR_AURA_WINDOW_HEADER_BASE_INACTIVE;
127
128 header_painter_->PaintHeader(
129 canvas,
130 paint_as_active ? HeaderPainter::ACTIVE : HeaderPainter::INACTIVE,
131 theme_image_id,
132 0);
133 header_painter_->PaintTitleBar(canvas, GetTitleFont());
134 header_painter_->PaintHeaderContentSeparator(canvas);
135 canvas->Restore();
136 }
137
138 const char* CustomFrameViewAsh::GetClassName() const { 357 const char* CustomFrameViewAsh::GetClassName() const {
139 return kViewClassName; 358 return kViewClassName;
140 } 359 }
141 360
142 gfx::Size CustomFrameViewAsh::GetMinimumSize() { 361 gfx::Size CustomFrameViewAsh::GetMinimumSize() {
143 gfx::Size min_client_view_size(frame_->client_view()->GetMinimumSize()); 362 gfx::Size min_client_view_size(frame_->client_view()->GetMinimumSize());
144 return gfx::Size( 363 return gfx::Size(
145 std::max(header_painter_->GetMinimumHeaderWidth(), 364 std::max(header_view_->GetMinimumWidth(), min_client_view_size.width()),
146 min_client_view_size.width()),
147 NonClientTopBorderHeight() + min_client_view_size.height()); 365 NonClientTopBorderHeight() + min_client_view_size.height());
148 } 366 }
149 367
150 gfx::Size CustomFrameViewAsh::GetMaximumSize() { 368 gfx::Size CustomFrameViewAsh::GetMaximumSize() {
151 return frame_->client_view()->GetMaximumSize(); 369 return frame_->client_view()->GetMaximumSize();
152 } 370 }
153 371
372 void CustomFrameViewAsh::SchedulePaintInRect(const gfx::Rect& r) {
373 // The HeaderView is not a child of CustomFrameViewAsh. Redirect the paint to
374 // HeaderView instead.
375 header_view_->set_paint_as_active(ShouldPaintAsActive());
376 header_view_->SchedulePaint();
377 }
378
379 bool CustomFrameViewAsh::HitTestRect(const gfx::Rect& rect) const {
380 // NonClientView hit tests the NonClientFrameView first instead of going in
381 // z-order. Return false so that events get to the OverlayView.
382 return false;
383 }
384
154 //////////////////////////////////////////////////////////////////////////////// 385 ////////////////////////////////////////////////////////////////////////////////
155 // CustomFrameViewAsh, private: 386 // CustomFrameViewAsh, private:
156 387
157 int CustomFrameViewAsh::NonClientTopBorderHeight() const { 388 int CustomFrameViewAsh::NonClientTopBorderHeight() const {
158 if (frame_->IsFullscreen()) 389 return frame_->IsFullscreen() ? 0 : header_view_->GetPreferredHeight();
159 return 0;
160
161 // Reserve enough space to see the buttons, including any offset from top and
162 // reserving space for the separator line.
163 return caption_button_container_->bounds().bottom() +
164 header_painter_->HeaderContentSeparatorSize();
165 } 390 }
166 391
167 } // namespace ash 392 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/custom_frame_view_ash.h ('k') | ash/wm/immersive_fullscreen_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698