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

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