| OLD | NEW |
| (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/frame/custom_frame_view_ash.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "ash/aura/wm_window_aura.h" | |
| 11 #include "ash/common/ash_switches.h" | |
| 12 #include "ash/common/frame/caption_buttons/frame_caption_button_container_view.h
" | |
| 13 #include "ash/common/frame/default_header_painter.h" | |
| 14 #include "ash/common/frame/frame_border_hit_test.h" | |
| 15 #include "ash/common/frame/header_painter.h" | |
| 16 #include "ash/common/material_design/material_design_controller.h" | |
| 17 #include "ash/common/session/session_state_delegate.h" | |
| 18 #include "ash/common/shell_observer.h" | |
| 19 #include "ash/common/wm/window_state.h" | |
| 20 #include "ash/common/wm/window_state_delegate.h" | |
| 21 #include "ash/common/wm/window_state_observer.h" | |
| 22 #include "ash/common/wm_lookup.h" | |
| 23 #include "ash/common/wm_shell.h" | |
| 24 #include "ash/frame/frame_border_hit_test_controller.h" | |
| 25 #include "ash/wm/immersive_fullscreen_controller.h" | |
| 26 #include "ash/wm/window_state_aura.h" | |
| 27 #include "base/command_line.h" | |
| 28 #include "ui/aura/client/aura_constants.h" | |
| 29 #include "ui/aura/window.h" | |
| 30 #include "ui/aura/window_observer.h" | |
| 31 #include "ui/gfx/canvas.h" | |
| 32 #include "ui/gfx/geometry/rect.h" | |
| 33 #include "ui/gfx/geometry/rect_conversions.h" | |
| 34 #include "ui/gfx/geometry/size.h" | |
| 35 #include "ui/gfx/image/image.h" | |
| 36 #include "ui/views/controls/image_view.h" | |
| 37 #include "ui/views/view.h" | |
| 38 #include "ui/views/view_targeter.h" | |
| 39 #include "ui/views/widget/widget.h" | |
| 40 #include "ui/views/widget/widget_delegate.h" | |
| 41 | |
| 42 namespace { | |
| 43 | |
| 44 /////////////////////////////////////////////////////////////////////////////// | |
| 45 // CustomFrameViewAshWindowStateDelegate | |
| 46 | |
| 47 // Handles a user's fullscreen request (Shift+F4/F4). Puts the window into | |
| 48 // immersive fullscreen if immersive fullscreen is enabled for non-browser | |
| 49 // windows. | |
| 50 class CustomFrameViewAshWindowStateDelegate | |
| 51 : public ash::wm::WindowStateDelegate, | |
| 52 public ash::wm::WindowStateObserver, | |
| 53 public aura::WindowObserver { | |
| 54 public: | |
| 55 CustomFrameViewAshWindowStateDelegate( | |
| 56 ash::wm::WindowState* window_state, | |
| 57 ash::CustomFrameViewAsh* custom_frame_view) | |
| 58 : window_state_(NULL) { | |
| 59 immersive_fullscreen_controller_.reset( | |
| 60 new ash::ImmersiveFullscreenController); | |
| 61 custom_frame_view->InitImmersiveFullscreenControllerForView( | |
| 62 immersive_fullscreen_controller_.get()); | |
| 63 | |
| 64 // Add a window state observer to exit fullscreen properly in case | |
| 65 // fullscreen is exited without going through | |
| 66 // WindowState::ToggleFullscreen(). This is the case when exiting | |
| 67 // immersive fullscreen via the "Restore" window control. | |
| 68 // TODO(pkotwicz): This is a hack. Remove ASAP. http://crbug.com/319048 | |
| 69 window_state_ = window_state; | |
| 70 window_state_->AddObserver(this); | |
| 71 GetAuraWindow()->AddObserver(this); | |
| 72 } | |
| 73 ~CustomFrameViewAshWindowStateDelegate() override { | |
| 74 if (window_state_) { | |
| 75 window_state_->RemoveObserver(this); | |
| 76 GetAuraWindow()->RemoveObserver(this); | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 private: | |
| 81 aura::Window* GetAuraWindow() { | |
| 82 return ash::WmWindowAura::GetAuraWindow(window_state_->window()); | |
| 83 } | |
| 84 | |
| 85 // Overridden from ash::wm::WindowStateDelegate: | |
| 86 bool ToggleFullscreen(ash::wm::WindowState* window_state) override { | |
| 87 bool enter_fullscreen = !window_state->IsFullscreen(); | |
| 88 if (enter_fullscreen) { | |
| 89 GetAuraWindow()->SetProperty(aura::client::kShowStateKey, | |
| 90 ui::SHOW_STATE_FULLSCREEN); | |
| 91 } else { | |
| 92 window_state->Restore(); | |
| 93 } | |
| 94 if (immersive_fullscreen_controller_) { | |
| 95 immersive_fullscreen_controller_->SetEnabled( | |
| 96 ash::ImmersiveFullscreenController::WINDOW_TYPE_OTHER, | |
| 97 enter_fullscreen); | |
| 98 } | |
| 99 return true; | |
| 100 } | |
| 101 // Overridden from aura::WindowObserver: | |
| 102 void OnWindowDestroying(aura::Window* window) override { | |
| 103 window_state_->RemoveObserver(this); | |
| 104 GetAuraWindow()->RemoveObserver(this); | |
| 105 window_state_ = NULL; | |
| 106 } | |
| 107 // Overridden from ash::wm::WindowStateObserver: | |
| 108 void OnPostWindowStateTypeChange(ash::wm::WindowState* window_state, | |
| 109 ash::wm::WindowStateType old_type) override { | |
| 110 if (!window_state->IsFullscreen() && !window_state->IsMinimized() && | |
| 111 immersive_fullscreen_controller_.get() && | |
| 112 immersive_fullscreen_controller_->IsEnabled()) { | |
| 113 immersive_fullscreen_controller_->SetEnabled( | |
| 114 ash::ImmersiveFullscreenController::WINDOW_TYPE_OTHER, false); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 ash::wm::WindowState* window_state_; | |
| 119 std::unique_ptr<ash::ImmersiveFullscreenController> | |
| 120 immersive_fullscreen_controller_; | |
| 121 | |
| 122 DISALLOW_COPY_AND_ASSIGN(CustomFrameViewAshWindowStateDelegate); | |
| 123 }; | |
| 124 | |
| 125 } // namespace | |
| 126 | |
| 127 namespace ash { | |
| 128 | |
| 129 /////////////////////////////////////////////////////////////////////////////// | |
| 130 // CustomFrameViewAsh::HeaderView | |
| 131 | |
| 132 // View which paints the header. It slides off and on screen in immersive | |
| 133 // fullscreen. | |
| 134 class CustomFrameViewAsh::HeaderView | |
| 135 : public views::View, | |
| 136 public ImmersiveFullscreenController::Delegate, | |
| 137 public ShellObserver { | |
| 138 public: | |
| 139 // |frame| is the widget that the caption buttons act on. | |
| 140 explicit HeaderView(views::Widget* frame); | |
| 141 ~HeaderView() override; | |
| 142 | |
| 143 // Schedules a repaint for the entire title. | |
| 144 void SchedulePaintForTitle(); | |
| 145 | |
| 146 // Tells the window controls to reset themselves to the normal state. | |
| 147 void ResetWindowControls(); | |
| 148 | |
| 149 // Returns the amount of the view's pixels which should be on screen. | |
| 150 int GetPreferredOnScreenHeight() const; | |
| 151 | |
| 152 // Returns the view's preferred height. | |
| 153 int GetPreferredHeight() const; | |
| 154 | |
| 155 // Returns the view's minimum width. | |
| 156 int GetMinimumWidth() const; | |
| 157 | |
| 158 void UpdateAvatarIcon(); | |
| 159 | |
| 160 void SizeConstraintsChanged(); | |
| 161 | |
| 162 void SetFrameColors(SkColor active_frame_color, SkColor inactive_frame_color); | |
| 163 | |
| 164 // views::View: | |
| 165 void Layout() override; | |
| 166 void OnPaint(gfx::Canvas* canvas) override; | |
| 167 void ChildPreferredSizeChanged(views::View* child) override; | |
| 168 | |
| 169 // ShellObserver: | |
| 170 void OnOverviewModeStarting() override; | |
| 171 void OnOverviewModeEnded() override; | |
| 172 void OnMaximizeModeStarted() override; | |
| 173 void OnMaximizeModeEnded() override; | |
| 174 | |
| 175 FrameCaptionButtonContainerView* caption_button_container() { | |
| 176 return caption_button_container_; | |
| 177 } | |
| 178 | |
| 179 views::View* avatar_icon() const { return avatar_icon_; } | |
| 180 | |
| 181 private: | |
| 182 // ImmersiveFullscreenController::Delegate: | |
| 183 void OnImmersiveRevealStarted() override; | |
| 184 void OnImmersiveRevealEnded() override; | |
| 185 void OnImmersiveFullscreenExited() override; | |
| 186 void SetVisibleFraction(double visible_fraction) override; | |
| 187 std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override; | |
| 188 | |
| 189 // The widget that the caption buttons act on. | |
| 190 views::Widget* frame_; | |
| 191 | |
| 192 // Helper for painting the header. | |
| 193 std::unique_ptr<DefaultHeaderPainter> header_painter_; | |
| 194 | |
| 195 views::ImageView* avatar_icon_; | |
| 196 | |
| 197 // View which contains the window caption buttons. | |
| 198 FrameCaptionButtonContainerView* caption_button_container_; | |
| 199 | |
| 200 // The fraction of the header's height which is visible while in fullscreen. | |
| 201 // This value is meaningless when not in fullscreen. | |
| 202 double fullscreen_visible_fraction_; | |
| 203 | |
| 204 DISALLOW_COPY_AND_ASSIGN(HeaderView); | |
| 205 }; | |
| 206 | |
| 207 CustomFrameViewAsh::HeaderView::HeaderView(views::Widget* frame) | |
| 208 : frame_(frame), | |
| 209 header_painter_(new ash::DefaultHeaderPainter), | |
| 210 avatar_icon_(NULL), | |
| 211 caption_button_container_(NULL), | |
| 212 fullscreen_visible_fraction_(0) { | |
| 213 caption_button_container_ = new FrameCaptionButtonContainerView(frame_); | |
| 214 caption_button_container_->UpdateSizeButtonVisibility(); | |
| 215 AddChildView(caption_button_container_); | |
| 216 | |
| 217 header_painter_->Init(frame_, this, caption_button_container_); | |
| 218 UpdateAvatarIcon(); | |
| 219 | |
| 220 WmShell::Get()->AddShellObserver(this); | |
| 221 } | |
| 222 | |
| 223 CustomFrameViewAsh::HeaderView::~HeaderView() { | |
| 224 WmShell::Get()->RemoveShellObserver(this); | |
| 225 } | |
| 226 | |
| 227 void CustomFrameViewAsh::HeaderView::SchedulePaintForTitle() { | |
| 228 header_painter_->SchedulePaintForTitle(); | |
| 229 } | |
| 230 | |
| 231 void CustomFrameViewAsh::HeaderView::ResetWindowControls() { | |
| 232 caption_button_container_->ResetWindowControls(); | |
| 233 } | |
| 234 | |
| 235 int CustomFrameViewAsh::HeaderView::GetPreferredOnScreenHeight() const { | |
| 236 if (frame_->IsFullscreen()) { | |
| 237 return static_cast<int>(GetPreferredHeight() * | |
| 238 fullscreen_visible_fraction_); | |
| 239 } | |
| 240 return GetPreferredHeight(); | |
| 241 } | |
| 242 | |
| 243 int CustomFrameViewAsh::HeaderView::GetPreferredHeight() const { | |
| 244 return header_painter_->GetHeaderHeightForPainting(); | |
| 245 } | |
| 246 | |
| 247 int CustomFrameViewAsh::HeaderView::GetMinimumWidth() const { | |
| 248 return header_painter_->GetMinimumHeaderWidth(); | |
| 249 } | |
| 250 | |
| 251 void CustomFrameViewAsh::HeaderView::UpdateAvatarIcon() { | |
| 252 SessionStateDelegate* delegate = WmShell::Get()->GetSessionStateDelegate(); | |
| 253 WmWindow* window = WmLookup::Get()->GetWindowForWidget(frame_); | |
| 254 bool show = delegate->ShouldShowAvatar(window); | |
| 255 if (!show) { | |
| 256 if (!avatar_icon_) | |
| 257 return; | |
| 258 delete avatar_icon_; | |
| 259 avatar_icon_ = NULL; | |
| 260 } else { | |
| 261 gfx::ImageSkia image = delegate->GetAvatarImageForWindow(window); | |
| 262 DCHECK_EQ(image.width(), image.height()); | |
| 263 if (!avatar_icon_) { | |
| 264 avatar_icon_ = new views::ImageView(); | |
| 265 AddChildView(avatar_icon_); | |
| 266 } | |
| 267 avatar_icon_->SetImage(image); | |
| 268 } | |
| 269 header_painter_->UpdateLeftHeaderView(avatar_icon_); | |
| 270 Layout(); | |
| 271 } | |
| 272 | |
| 273 void CustomFrameViewAsh::HeaderView::SizeConstraintsChanged() { | |
| 274 caption_button_container_->ResetWindowControls(); | |
| 275 caption_button_container_->UpdateSizeButtonVisibility(); | |
| 276 Layout(); | |
| 277 } | |
| 278 | |
| 279 void CustomFrameViewAsh::HeaderView::SetFrameColors( | |
| 280 SkColor active_frame_color, | |
| 281 SkColor inactive_frame_color) { | |
| 282 header_painter_->SetFrameColors(active_frame_color, inactive_frame_color); | |
| 283 } | |
| 284 | |
| 285 /////////////////////////////////////////////////////////////////////////////// | |
| 286 // CustomFrameViewAsh::HeaderView, views::View overrides: | |
| 287 | |
| 288 void CustomFrameViewAsh::HeaderView::Layout() { | |
| 289 header_painter_->LayoutHeader(); | |
| 290 } | |
| 291 | |
| 292 void CustomFrameViewAsh::HeaderView::OnPaint(gfx::Canvas* canvas) { | |
| 293 bool paint_as_active = | |
| 294 frame_->non_client_view()->frame_view()->ShouldPaintAsActive(); | |
| 295 caption_button_container_->SetPaintAsActive(paint_as_active); | |
| 296 | |
| 297 HeaderPainter::Mode header_mode = paint_as_active | |
| 298 ? HeaderPainter::MODE_ACTIVE | |
| 299 : HeaderPainter::MODE_INACTIVE; | |
| 300 header_painter_->PaintHeader(canvas, header_mode); | |
| 301 } | |
| 302 | |
| 303 void CustomFrameViewAsh::HeaderView::ChildPreferredSizeChanged( | |
| 304 views::View* child) { | |
| 305 // FrameCaptionButtonContainerView animates the visibility changes in | |
| 306 // UpdateSizeButtonVisibility(false). Due to this a new size is not available | |
| 307 // until the completion of the animation. Layout in response to the preferred | |
| 308 // size changes. | |
| 309 if (child != caption_button_container_) | |
| 310 return; | |
| 311 parent()->Layout(); | |
| 312 } | |
| 313 | |
| 314 /////////////////////////////////////////////////////////////////////////////// | |
| 315 // CustomFrameViewAsh::HeaderView, ShellObserver overrides: | |
| 316 | |
| 317 void CustomFrameViewAsh::HeaderView::OnOverviewModeStarting() { | |
| 318 if (ash::MaterialDesignController::IsOverviewMaterial()) | |
| 319 caption_button_container_->SetVisible(false); | |
| 320 } | |
| 321 | |
| 322 void CustomFrameViewAsh::HeaderView::OnOverviewModeEnded() { | |
| 323 if (ash::MaterialDesignController::IsOverviewMaterial()) | |
| 324 caption_button_container_->SetVisible(true); | |
| 325 } | |
| 326 | |
| 327 void CustomFrameViewAsh::HeaderView::OnMaximizeModeStarted() { | |
| 328 caption_button_container_->UpdateSizeButtonVisibility(); | |
| 329 parent()->Layout(); | |
| 330 } | |
| 331 | |
| 332 void CustomFrameViewAsh::HeaderView::OnMaximizeModeEnded() { | |
| 333 caption_button_container_->UpdateSizeButtonVisibility(); | |
| 334 parent()->Layout(); | |
| 335 } | |
| 336 | |
| 337 /////////////////////////////////////////////////////////////////////////////// | |
| 338 // CustomFrameViewAsh::HeaderView, | |
| 339 // ImmersiveFullscreenController::Delegate overrides: | |
| 340 | |
| 341 void CustomFrameViewAsh::HeaderView::OnImmersiveRevealStarted() { | |
| 342 fullscreen_visible_fraction_ = 0; | |
| 343 SetPaintToLayer(true); | |
| 344 layer()->SetFillsBoundsOpaquely(false); | |
| 345 parent()->Layout(); | |
| 346 } | |
| 347 | |
| 348 void CustomFrameViewAsh::HeaderView::OnImmersiveRevealEnded() { | |
| 349 fullscreen_visible_fraction_ = 0; | |
| 350 SetPaintToLayer(false); | |
| 351 parent()->Layout(); | |
| 352 } | |
| 353 | |
| 354 void CustomFrameViewAsh::HeaderView::OnImmersiveFullscreenExited() { | |
| 355 fullscreen_visible_fraction_ = 0; | |
| 356 SetPaintToLayer(false); | |
| 357 parent()->Layout(); | |
| 358 } | |
| 359 | |
| 360 void CustomFrameViewAsh::HeaderView::SetVisibleFraction( | |
| 361 double visible_fraction) { | |
| 362 if (fullscreen_visible_fraction_ != visible_fraction) { | |
| 363 fullscreen_visible_fraction_ = visible_fraction; | |
| 364 parent()->Layout(); | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 std::vector<gfx::Rect> | |
| 369 CustomFrameViewAsh::HeaderView::GetVisibleBoundsInScreen() const { | |
| 370 // TODO(pkotwicz): Implement views::View::ConvertRectToScreen(). | |
| 371 gfx::Rect visible_bounds(GetVisibleBounds()); | |
| 372 gfx::Point visible_origin_in_screen(visible_bounds.origin()); | |
| 373 views::View::ConvertPointToScreen(this, &visible_origin_in_screen); | |
| 374 std::vector<gfx::Rect> bounds_in_screen; | |
| 375 bounds_in_screen.push_back( | |
| 376 gfx::Rect(visible_origin_in_screen, visible_bounds.size())); | |
| 377 return bounds_in_screen; | |
| 378 } | |
| 379 | |
| 380 /////////////////////////////////////////////////////////////////////////////// | |
| 381 // CustomFrameViewAsh::OverlayView | |
| 382 | |
| 383 // View which takes up the entire widget and contains the HeaderView. HeaderView | |
| 384 // is a child of OverlayView to avoid creating a larger texture than necessary | |
| 385 // when painting the HeaderView to its own layer. | |
| 386 class CustomFrameViewAsh::OverlayView : public views::View, | |
| 387 public views::ViewTargeterDelegate { | |
| 388 public: | |
| 389 explicit OverlayView(HeaderView* header_view); | |
| 390 ~OverlayView() override; | |
| 391 | |
| 392 // views::View: | |
| 393 void Layout() override; | |
| 394 | |
| 395 private: | |
| 396 // views::ViewTargeterDelegate: | |
| 397 bool DoesIntersectRect(const views::View* target, | |
| 398 const gfx::Rect& rect) const override; | |
| 399 | |
| 400 HeaderView* header_view_; | |
| 401 | |
| 402 DISALLOW_COPY_AND_ASSIGN(OverlayView); | |
| 403 }; | |
| 404 | |
| 405 CustomFrameViewAsh::OverlayView::OverlayView(HeaderView* header_view) | |
| 406 : header_view_(header_view) { | |
| 407 AddChildView(header_view); | |
| 408 SetEventTargeter( | |
| 409 std::unique_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); | |
| 410 } | |
| 411 | |
| 412 CustomFrameViewAsh::OverlayView::~OverlayView() {} | |
| 413 | |
| 414 /////////////////////////////////////////////////////////////////////////////// | |
| 415 // CustomFrameViewAsh::OverlayView, views::View overrides: | |
| 416 | |
| 417 void CustomFrameViewAsh::OverlayView::Layout() { | |
| 418 // Layout |header_view_| because layout affects the result of | |
| 419 // GetPreferredOnScreenHeight(). | |
| 420 header_view_->Layout(); | |
| 421 | |
| 422 int onscreen_height = header_view_->GetPreferredOnScreenHeight(); | |
| 423 if (onscreen_height == 0) { | |
| 424 header_view_->SetVisible(false); | |
| 425 } else { | |
| 426 int height = header_view_->GetPreferredHeight(); | |
| 427 header_view_->SetBounds(0, onscreen_height - height, width(), height); | |
| 428 header_view_->SetVisible(true); | |
| 429 } | |
| 430 } | |
| 431 | |
| 432 /////////////////////////////////////////////////////////////////////////////// | |
| 433 // CustomFrameViewAsh::OverlayView, views::ViewTargeterDelegate overrides: | |
| 434 | |
| 435 bool CustomFrameViewAsh::OverlayView::DoesIntersectRect( | |
| 436 const views::View* target, | |
| 437 const gfx::Rect& rect) const { | |
| 438 CHECK_EQ(target, this); | |
| 439 // Grab events in the header view. Return false for other events so that they | |
| 440 // can be handled by the client view. | |
| 441 return header_view_->HitTestRect(rect); | |
| 442 } | |
| 443 | |
| 444 //////////////////////////////////////////////////////////////////////////////// | |
| 445 // CustomFrameViewAsh, public: | |
| 446 | |
| 447 // static | |
| 448 const char CustomFrameViewAsh::kViewClassName[] = "CustomFrameViewAsh"; | |
| 449 | |
| 450 CustomFrameViewAsh::CustomFrameViewAsh(views::Widget* frame) | |
| 451 : frame_(frame), | |
| 452 header_view_(new HeaderView(frame)), | |
| 453 frame_border_hit_test_controller_( | |
| 454 new FrameBorderHitTestController(frame_)) { | |
| 455 // |header_view_| is set as the non client view's overlay view so that it can | |
| 456 // overlay the web contents in immersive fullscreen. | |
| 457 frame->non_client_view()->SetOverlayView(new OverlayView(header_view_)); | |
| 458 | |
| 459 // A delegate for a more complex way of fullscreening the window may already | |
| 460 // be set. This is the case for packaged apps. | |
| 461 wm::WindowState* window_state = wm::GetWindowState(frame->GetNativeWindow()); | |
| 462 if (!window_state->HasDelegate()) { | |
| 463 window_state->SetDelegate(std::unique_ptr<wm::WindowStateDelegate>( | |
| 464 new CustomFrameViewAshWindowStateDelegate(window_state, this))); | |
| 465 } | |
| 466 } | |
| 467 | |
| 468 CustomFrameViewAsh::~CustomFrameViewAsh() {} | |
| 469 | |
| 470 void CustomFrameViewAsh::InitImmersiveFullscreenControllerForView( | |
| 471 ImmersiveFullscreenController* immersive_fullscreen_controller) { | |
| 472 immersive_fullscreen_controller->Init(header_view_, frame_, header_view_); | |
| 473 } | |
| 474 | |
| 475 void CustomFrameViewAsh::SetFrameColors(SkColor active_frame_color, | |
| 476 SkColor inactive_frame_color) { | |
| 477 header_view_->SetFrameColors(active_frame_color, inactive_frame_color); | |
| 478 } | |
| 479 | |
| 480 //////////////////////////////////////////////////////////////////////////////// | |
| 481 // CustomFrameViewAsh, views::NonClientFrameView overrides: | |
| 482 | |
| 483 gfx::Rect CustomFrameViewAsh::GetBoundsForClientView() const { | |
| 484 gfx::Rect client_bounds = bounds(); | |
| 485 client_bounds.Inset(0, NonClientTopBorderHeight(), 0, 0); | |
| 486 return client_bounds; | |
| 487 } | |
| 488 | |
| 489 gfx::Rect CustomFrameViewAsh::GetWindowBoundsForClientBounds( | |
| 490 const gfx::Rect& client_bounds) const { | |
| 491 gfx::Rect window_bounds = client_bounds; | |
| 492 window_bounds.Inset(0, -NonClientTopBorderHeight(), 0, 0); | |
| 493 return window_bounds; | |
| 494 } | |
| 495 | |
| 496 int CustomFrameViewAsh::NonClientHitTest(const gfx::Point& point) { | |
| 497 return FrameBorderNonClientHitTest( | |
| 498 this, header_view_->caption_button_container(), point); | |
| 499 } | |
| 500 | |
| 501 void CustomFrameViewAsh::GetWindowMask(const gfx::Size& size, | |
| 502 gfx::Path* window_mask) { | |
| 503 // No window masks in Aura. | |
| 504 } | |
| 505 | |
| 506 void CustomFrameViewAsh::ResetWindowControls() { | |
| 507 header_view_->ResetWindowControls(); | |
| 508 } | |
| 509 | |
| 510 void CustomFrameViewAsh::UpdateWindowIcon() {} | |
| 511 | |
| 512 void CustomFrameViewAsh::UpdateWindowTitle() { | |
| 513 header_view_->SchedulePaintForTitle(); | |
| 514 } | |
| 515 | |
| 516 void CustomFrameViewAsh::SizeConstraintsChanged() { | |
| 517 header_view_->SizeConstraintsChanged(); | |
| 518 } | |
| 519 | |
| 520 //////////////////////////////////////////////////////////////////////////////// | |
| 521 // CustomFrameViewAsh, views::View overrides: | |
| 522 | |
| 523 gfx::Size CustomFrameViewAsh::GetPreferredSize() const { | |
| 524 gfx::Size pref = frame_->client_view()->GetPreferredSize(); | |
| 525 gfx::Rect bounds(0, 0, pref.width(), pref.height()); | |
| 526 return frame_->non_client_view() | |
| 527 ->GetWindowBoundsForClientBounds(bounds) | |
| 528 .size(); | |
| 529 } | |
| 530 | |
| 531 void CustomFrameViewAsh::Layout() { | |
| 532 views::NonClientFrameView::Layout(); | |
| 533 frame_->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, | |
| 534 NonClientTopBorderHeight()); | |
| 535 } | |
| 536 | |
| 537 const char* CustomFrameViewAsh::GetClassName() const { | |
| 538 return kViewClassName; | |
| 539 } | |
| 540 | |
| 541 gfx::Size CustomFrameViewAsh::GetMinimumSize() const { | |
| 542 gfx::Size min_client_view_size(frame_->client_view()->GetMinimumSize()); | |
| 543 return gfx::Size( | |
| 544 std::max(header_view_->GetMinimumWidth(), min_client_view_size.width()), | |
| 545 NonClientTopBorderHeight() + min_client_view_size.height()); | |
| 546 } | |
| 547 | |
| 548 gfx::Size CustomFrameViewAsh::GetMaximumSize() const { | |
| 549 gfx::Size max_client_size(frame_->client_view()->GetMaximumSize()); | |
| 550 int width = 0; | |
| 551 int height = 0; | |
| 552 | |
| 553 if (max_client_size.width() > 0) | |
| 554 width = std::max(header_view_->GetMinimumWidth(), max_client_size.width()); | |
| 555 if (max_client_size.height() > 0) | |
| 556 height = NonClientTopBorderHeight() + max_client_size.height(); | |
| 557 | |
| 558 return gfx::Size(width, height); | |
| 559 } | |
| 560 | |
| 561 void CustomFrameViewAsh::SchedulePaintInRect(const gfx::Rect& r) { | |
| 562 // We may end up here before |header_view_| has been added to the Widget. | |
| 563 if (header_view_->GetWidget()) { | |
| 564 // The HeaderView is not a child of CustomFrameViewAsh. Redirect the paint | |
| 565 // to HeaderView instead. | |
| 566 gfx::RectF to_paint(r); | |
| 567 views::View::ConvertRectToTarget(this, header_view_, &to_paint); | |
| 568 header_view_->SchedulePaintInRect(gfx::ToEnclosingRect(to_paint)); | |
| 569 } else { | |
| 570 views::NonClientFrameView::SchedulePaintInRect(r); | |
| 571 } | |
| 572 } | |
| 573 | |
| 574 void CustomFrameViewAsh::VisibilityChanged(views::View* starting_from, | |
| 575 bool is_visible) { | |
| 576 if (is_visible) | |
| 577 header_view_->UpdateAvatarIcon(); | |
| 578 } | |
| 579 | |
| 580 //////////////////////////////////////////////////////////////////////////////// | |
| 581 // CustomFrameViewAsh, views::ViewTargeterDelegate overrides: | |
| 582 | |
| 583 views::View* CustomFrameViewAsh::GetHeaderView() { | |
| 584 return header_view_; | |
| 585 } | |
| 586 | |
| 587 const views::View* CustomFrameViewAsh::GetAvatarIconViewForTest() const { | |
| 588 return header_view_->avatar_icon(); | |
| 589 } | |
| 590 | |
| 591 //////////////////////////////////////////////////////////////////////////////// | |
| 592 // CustomFrameViewAsh, private: | |
| 593 | |
| 594 // views::NonClientFrameView: | |
| 595 bool CustomFrameViewAsh::DoesIntersectRect(const views::View* target, | |
| 596 const gfx::Rect& rect) const { | |
| 597 CHECK_EQ(target, this); | |
| 598 // NonClientView hit tests the NonClientFrameView first instead of going in | |
| 599 // z-order. Return false so that events get to the OverlayView. | |
| 600 return false; | |
| 601 } | |
| 602 | |
| 603 FrameCaptionButtonContainerView* | |
| 604 CustomFrameViewAsh::GetFrameCaptionButtonContainerViewForTest() { | |
| 605 return header_view_->caption_button_container(); | |
| 606 } | |
| 607 | |
| 608 int CustomFrameViewAsh::NonClientTopBorderHeight() const { | |
| 609 return frame_->IsFullscreen() ? 0 : header_view_->GetPreferredHeight(); | |
| 610 } | |
| 611 | |
| 612 } // namespace ash | |
| OLD | NEW |