OLD | NEW |
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(); |
92 } | 339 } |
93 | 340 |
94 //////////////////////////////////////////////////////////////////////////////// | 341 //////////////////////////////////////////////////////////////////////////////// |
95 // CustomFrameViewAsh, views::View overrides: | 342 // CustomFrameViewAsh, views::View overrides: |
96 | 343 |
97 gfx::Size CustomFrameViewAsh::GetPreferredSize() { | 344 gfx::Size CustomFrameViewAsh::GetPreferredSize() { |
98 gfx::Size pref = frame_->client_view()->GetPreferredSize(); | 345 gfx::Size pref = frame_->client_view()->GetPreferredSize(); |
99 gfx::Rect bounds(0, 0, pref.width(), pref.height()); | 346 gfx::Rect bounds(0, 0, pref.width(), pref.height()); |
100 return frame_->non_client_view()->GetWindowBoundsForClientBounds( | 347 return frame_->non_client_view()->GetWindowBoundsForClientBounds( |
101 bounds).size(); | 348 bounds).size(); |
102 } | 349 } |
103 | 350 |
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 { | 351 const char* CustomFrameViewAsh::GetClassName() const { |
139 return kViewClassName; | 352 return kViewClassName; |
140 } | 353 } |
141 | 354 |
142 gfx::Size CustomFrameViewAsh::GetMinimumSize() { | 355 gfx::Size CustomFrameViewAsh::GetMinimumSize() { |
143 gfx::Size min_client_view_size(frame_->client_view()->GetMinimumSize()); | 356 gfx::Size min_client_view_size(frame_->client_view()->GetMinimumSize()); |
144 return gfx::Size( | 357 return gfx::Size( |
145 std::max(header_painter_->GetMinimumHeaderWidth(), | 358 std::max(header_view_->GetMinimumWidth(), min_client_view_size.width()), |
146 min_client_view_size.width()), | |
147 NonClientTopBorderHeight() + min_client_view_size.height()); | 359 NonClientTopBorderHeight() + min_client_view_size.height()); |
148 } | 360 } |
149 | 361 |
150 gfx::Size CustomFrameViewAsh::GetMaximumSize() { | 362 gfx::Size CustomFrameViewAsh::GetMaximumSize() { |
151 return frame_->client_view()->GetMaximumSize(); | 363 return frame_->client_view()->GetMaximumSize(); |
152 } | 364 } |
153 | 365 |
| 366 void CustomFrameViewAsh::SchedulePaintInRect(const gfx::Rect& r) { |
| 367 // The HeaderView is not a child of CustomFrameViewAsh. Redirect the paint to |
| 368 // HeaderView instead. |
| 369 header_view_->set_paint_as_active(ShouldPaintAsActive()); |
| 370 header_view_->SchedulePaint(); |
| 371 } |
| 372 |
| 373 bool CustomFrameViewAsh::HitTestRect(const gfx::Rect& rect) const { |
| 374 // NonClientView hit tests the NonClientFrameView first instead of going in |
| 375 // z-order. Return false so that events get to the OverlayView. |
| 376 return false; |
| 377 } |
| 378 |
154 //////////////////////////////////////////////////////////////////////////////// | 379 //////////////////////////////////////////////////////////////////////////////// |
155 // CustomFrameViewAsh, private: | 380 // CustomFrameViewAsh, private: |
156 | 381 |
157 int CustomFrameViewAsh::NonClientTopBorderHeight() const { | 382 int CustomFrameViewAsh::NonClientTopBorderHeight() const { |
158 if (frame_->IsFullscreen()) | 383 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 } | 384 } |
166 | 385 |
167 } // namespace ash | 386 } // namespace ash |
OLD | NEW |