browser_non_client_frame_view_ash.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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 "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h"
6
7#include "ash/ash_switches.h"
8#include "ash/wm/caption_buttons/frame_caption_button_container_view.h"
9#include "ash/wm/frame_painter.h"
10#include "chrome/browser/themes/theme_properties.h"
11#include "chrome/browser/ui/browser.h"
12#include "chrome/browser/ui/immersive_fullscreen_configuration.h"
13#include "chrome/browser/ui/views/avatar_label.h"
14#include "chrome/browser/ui/views/avatar_menu_button.h"
15#include "chrome/browser/ui/views/frame/browser_frame.h"
16#include "chrome/browser/ui/views/frame/browser_view.h"
17#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
18#include "chrome/browser/ui/views/tab_icon_view.h"
19#include "chrome/browser/ui/views/tabs/tab_strip.h"
20#include "content/public/browser/web_contents.h"
21#include "grit/ash_resources.h"
22#include "grit/theme_resources.h"
23#include "ui/aura/client/aura_constants.h"
24#include "ui/aura/window.h"
25#include "ui/base/accessibility/accessible_view_state.h"
26#include "ui/base/hit_test.h"
27#include "ui/base/l10n/l10n_util.h"
28#include "ui/base/layout.h"
29#include "ui/base/resource/resource_bundle.h"
30#include "ui/base/theme_provider.h"
31#include "ui/compositor/layer_animator.h"
32#include "ui/gfx/canvas.h"
33#include "ui/gfx/image/image_skia.h"
34#include "ui/views/controls/label.h"
35#include "ui/views/layout/layout_constants.h"
36#include "ui/views/widget/widget.h"
37#include "ui/views/widget/widget_delegate.h"
38
39namespace {
40
41// The avatar ends 2 px above the bottom of the tabstrip (which, given the
42// way the tabstrip draws its bottom edge, will appear like a 1 px gap to the
43// user).
44const int kAvatarBottomSpacing = 2;
45// There are 2 px on each side of the avatar (between the frame border and
46// it on the left, and between it and the tabstrip on the right).
47const int kAvatarSideSpacing = 2;
48// Space between left edge of window and tabstrip.
49const int kTabstripLeftSpacing = 0;
50// Space between right edge of tabstrip and maximize button.
51const int kTabstripRightSpacing = 10;
52// Height of the shadow of the content area, at the top of the toolbar.
53const int kContentShadowHeight = 1;
54// Space between top of window and top of tabstrip for tall headers, such as
55// for restored windows, apps, etc.
56const int kTabstripTopSpacingTall = 7;
57// Space between top of window and top of tabstrip for short headers, such as
58// for maximized windows, pop-ups, etc.
59const int kTabstripTopSpacingShort = 0;
60// Height of the shadow in the tab image, used to ensure clicks in the shadow
61// area still drag restored windows.  This keeps the clickable area large enough
62// to hit easily.
63const int kTabShadowHeight = 4;
64
65// Space between right edge of tabstrip and caption buttons when using the
66// alternate caption button style.
67const int kTabstripRightSpacingAlternateCaptionButtonStyle = 0;
68// Space between top of window and top of tabstrip for short headers when using
69// the alternate caption button style.
70const int kTabstripTopSpacingShortAlternateCaptionButtonStyle = 4;
71
72}  // namespace
73
74///////////////////////////////////////////////////////////////////////////////
75// BrowserNonClientFrameViewAsh, public:
76
77// static
78const char BrowserNonClientFrameViewAsh::kViewClassName[] =
79    "BrowserNonClientFrameViewAsh";
80
81BrowserNonClientFrameViewAsh::BrowserNonClientFrameViewAsh(
82    BrowserFrame* frame, BrowserView* browser_view)
83    : BrowserNonClientFrameView(frame, browser_view),
84      caption_button_container_(NULL),
85      window_icon_(NULL),
86      frame_painter_(new ash::FramePainter) {
87}
88
89BrowserNonClientFrameViewAsh::~BrowserNonClientFrameViewAsh() {
90}
91
92void BrowserNonClientFrameViewAsh::Init() {
93  caption_button_container_ = new ash::FrameCaptionButtonContainerView(frame(),
94      ash::FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
95  AddChildView(caption_button_container_);
96
97  // Initializing the TabIconView is expensive, so only do it if we need to.
98  if (browser_view()->ShouldShowWindowIcon()) {
99    window_icon_ = new TabIconView(this);
100    window_icon_->set_is_light(true);
101    AddChildView(window_icon_);
102    window_icon_->Update();
103  }
104
105  // Create incognito icon if necessary.
106  UpdateAvatarInfo();
107
108  // Frame painter handles layout.
109  frame_painter_->Init(frame(), window_icon_, caption_button_container_);
110}
111
112///////////////////////////////////////////////////////////////////////////////
113// BrowserNonClientFrameView overrides:
114
115gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForTabStrip(
116    views::View* tabstrip) const {
117  if (!tabstrip)
118    return gfx::Rect();
119
120  // When the tab strip is painted in the immersive fullscreen light bar style,
121  // the caption buttons and the avatar button are not visible. However, their
122  // bounds are still used to compute the tab strip bounds so that the tabs have
123  // the same horizontal position when the tab strip is painted in the immersive
124  // light bar style as when the top-of-window views are revealed.
125  TabStripInsets insets(GetTabStripInsets(false));
126  return gfx::Rect(insets.left, insets.top,
127                   std::max(0, width() - insets.left - insets.right),
128                   tabstrip->GetPreferredSize().height());
129}
130
131BrowserNonClientFrameView::TabStripInsets
132BrowserNonClientFrameViewAsh::GetTabStripInsets(bool force_restored) const {
133  int left = avatar_button() ? kAvatarSideSpacing +
134      browser_view()->GetOTRAvatarIcon().width() + kAvatarSideSpacing :
135      kTabstripLeftSpacing;
136  int extra_right = ash::switches::UseAlternateFrameCaptionButtonStyle() ?
137      kTabstripRightSpacingAlternateCaptionButtonStyle :
138      kTabstripRightSpacing;
139  int right = frame_painter_->GetRightInset() + extra_right;
140  return TabStripInsets(NonClientTopBorderHeight(force_restored), left, right);
141}
142
143int BrowserNonClientFrameViewAsh::GetThemeBackgroundXInset() const {
144  return frame_painter_->GetThemeBackgroundXInset();
145}
146
147void BrowserNonClientFrameViewAsh::UpdateThrobber(bool running) {
148  if (window_icon_)
149    window_icon_->Update();
150}
151
152///////////////////////////////////////////////////////////////////////////////
153// views::NonClientFrameView overrides:
154
155gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForClientView() const {
156  int top_height = NonClientTopBorderHeight(false);
157  return frame_painter_->GetBoundsForClientView(top_height, bounds());
158}
159
160gfx::Rect BrowserNonClientFrameViewAsh::GetWindowBoundsForClientBounds(
161    const gfx::Rect& client_bounds) const {
162  int top_height = NonClientTopBorderHeight(false);
163  return frame_painter_->GetWindowBoundsForClientBounds(top_height,
164                                                        client_bounds);
165}
166
167int BrowserNonClientFrameViewAsh::NonClientHitTest(const gfx::Point& point) {
168  int hit_test = frame_painter_->NonClientHitTest(this, point);
169
170  // See if the point is actually within the avatar menu button or within
171  // the avatar label.
172  if (hit_test == HTCAPTION && ((avatar_button() &&
173       avatar_button()->GetMirroredBounds().Contains(point)) ||
174      (avatar_label() && avatar_label()->GetMirroredBounds().Contains(point))))
175      return HTCLIENT;
176
177  // When the window is restored we want a large click target above the tabs
178  // to drag the window, so redirect clicks in the tab's shadow to caption.
179  if (hit_test == HTCLIENT &&
180      !(frame()->IsMaximized() || frame()->IsFullscreen())) {
181    // Convert point to client coordinates.
182    gfx::Point client_point(point);
183    View::ConvertPointToTarget(this, frame()->client_view(), &client_point);
184    // Report hits in shadow at top of tabstrip as caption.
185    gfx::Rect tabstrip_bounds(browser_view()->tabstrip()->bounds());
186    if (client_point.y() < tabstrip_bounds.y() + kTabShadowHeight)
187      hit_test = HTCAPTION;
188  }
189  return hit_test;
190}
191
192void BrowserNonClientFrameViewAsh::GetWindowMask(const gfx::Size& size,
193                                                  gfx::Path* window_mask) {
194  // Aura does not use window masks.
195}
196
197void BrowserNonClientFrameViewAsh::ResetWindowControls() {
198  // Hide the caption buttons in immersive fullscreen when the tab light bar
199  // is visible because it's confusing when the user hovers or clicks in the
200  // top-right of the screen and hits one.
201  bool button_visibility = !UseImmersiveLightbarHeaderStyle();
202  caption_button_container_->SetVisible(button_visibility);
203
204  caption_button_container_->ResetWindowControls();
205}
206
207void BrowserNonClientFrameViewAsh::UpdateWindowIcon() {
208  if (window_icon_)
209    window_icon_->SchedulePaint();
210}
211
212void BrowserNonClientFrameViewAsh::UpdateWindowTitle() {
213  if (!frame()->IsFullscreen())
214    frame_painter_->SchedulePaintForTitle(BrowserFrame::GetTitleFont());
215}
216
217///////////////////////////////////////////////////////////////////////////////
218// views::View overrides:
219
220void BrowserNonClientFrameViewAsh::OnPaint(gfx::Canvas* canvas) {
221  if (!ShouldPaint())
222    return;
223
224  if (UseImmersiveLightbarHeaderStyle()) {
225    PaintImmersiveLightbarStyleHeader(canvas);
226    return;
227  }
228
229  // The primary header image changes based on window activation state and
230  // theme, so we look it up for each paint.
231  int theme_frame_image_id = GetThemeFrameImageId();
232  int theme_frame_overlay_image_id = GetThemeFrameOverlayImageId();
233
234  ui::ThemeProvider* theme_provider = GetThemeProvider();
235  ash::FramePainter::Themed header_themed = ash::FramePainter::THEMED_NO;
236  if (theme_provider->HasCustomImage(theme_frame_image_id) ||
237      (theme_frame_overlay_image_id != 0 &&
238       theme_provider->HasCustomImage(theme_frame_overlay_image_id))) {
239    header_themed = ash::FramePainter::THEMED_YES;
240  }
241
242  if (frame_painter_->ShouldUseMinimalHeaderStyle(header_themed))
243    theme_frame_image_id = IDR_AURA_WINDOW_HEADER_BASE_MINIMAL;
244
245  frame_painter_->PaintHeader(
246      this,
247      canvas,
248      ShouldPaintAsActive() ?
249          ash::FramePainter::ACTIVE : ash::FramePainter::INACTIVE,
250      theme_frame_image_id,
251      theme_frame_overlay_image_id);
252  if (browser_view()->ShouldShowWindowTitle())
253    frame_painter_->PaintTitleBar(this, canvas, BrowserFrame::GetTitleFont());
254  if (browser_view()->IsToolbarVisible())
255    PaintToolbarBackground(canvas);
256  else
257    PaintContentEdge(canvas);
258}
259
260void BrowserNonClientFrameViewAsh::Layout() {
261  frame_painter_->LayoutHeader(this, UseShortHeader());
262  if (avatar_button())
263    LayoutAvatar();
264  BrowserNonClientFrameView::Layout();
265}
266
267const char* BrowserNonClientFrameViewAsh::GetClassName() const {
268  return kViewClassName;
269}
270
271bool BrowserNonClientFrameViewAsh::HitTestRect(const gfx::Rect& rect) const {
272  if (!views::View::HitTestRect(rect)) {
273    // |rect| is outside BrowserNonClientFrameViewAsh's bounds.
274    return false;
275  }
276  // If the rect is outside the bounds of the client area, claim it.
277  // TODO(tdanderson): Implement View::ConvertRectToTarget().
278  gfx::Point rect_in_client_view_coords_origin(rect.origin());
279  View::ConvertPointToTarget(this, frame()->client_view(),
280      &rect_in_client_view_coords_origin);
281  gfx::Rect rect_in_client_view_coords(
282      rect_in_client_view_coords_origin, rect.size());
283  if (!frame()->client_view()->HitTestRect(rect_in_client_view_coords))
284    return true;
285
286  // Otherwise, claim |rect| only if it is above the bottom of the tabstrip in
287  // a non-tab portion.
288  TabStrip* tabstrip = browser_view()->tabstrip();
289  if (!tabstrip || !browser_view()->IsTabStripVisible())
290    return false;
291
292  gfx::Point rect_in_tabstrip_coords_origin(rect.origin());
293  View::ConvertPointToTarget(this, tabstrip,
294      &rect_in_tabstrip_coords_origin);
295  gfx::Rect rect_in_tabstrip_coords(rect_in_tabstrip_coords_origin,
296      rect.size());
297
298  if (rect_in_tabstrip_coords.bottom() > tabstrip->GetLocalBounds().bottom()) {
299    // |rect| is below the tabstrip.
300    return false;
301  }
302
303  if (tabstrip->HitTestRect(rect_in_tabstrip_coords)) {
304    // Claim |rect| if it is in a non-tab portion of the tabstrip.
305    // TODO(tdanderson): Pass |rect_in_tabstrip_coords| instead of its center
306    // point to TabStrip::IsPositionInWindowCaption() once
307    // GetEventHandlerForRect() is implemented.
308    return tabstrip->IsPositionInWindowCaption(
309        rect_in_tabstrip_coords.CenterPoint());
310  }
311
312  // We claim |rect| because it is above the bottom of the tabstrip, but
313  // not in the tabstrip. In particular, the window controls are right of
314  // the tabstrip.
315  return true;
316}
317
318void BrowserNonClientFrameViewAsh::GetAccessibleState(
319    ui::AccessibleViewState* state) {
320  state->role = ui::AccessibilityTypes::ROLE_TITLEBAR;
321}
322
323gfx::Size BrowserNonClientFrameViewAsh::GetMinimumSize() {
324  return frame_painter_->GetMinimumSize(this);
325}
326
327void BrowserNonClientFrameViewAsh::OnThemeChanged() {
328  BrowserNonClientFrameView::OnThemeChanged();
329  frame_painter_->OnThemeChanged();
330}
331
332///////////////////////////////////////////////////////////////////////////////
333// chrome::TabIconViewModel overrides:
334
335bool BrowserNonClientFrameViewAsh::ShouldTabIconViewAnimate() const {
336  // This function is queried during the creation of the window as the
337  // TabIconView we host is initialized, so we need to NULL check the selected
338  // WebContents because in this condition there is not yet a selected tab.
339  content::WebContents* current_tab = browser_view()->GetActiveWebContents();
340  return current_tab ? current_tab->IsLoading() : false;
341}
342
343gfx::ImageSkia BrowserNonClientFrameViewAsh::GetFaviconForTabIconView() {
344  views::WidgetDelegate* delegate = frame()->widget_delegate();
345  if (!delegate)
346    return gfx::ImageSkia();
347  return delegate->GetWindowIcon();
348}
349
350///////////////////////////////////////////////////////////////////////////////
351// BrowserNonClientFrameViewAsh, private:
352
353int BrowserNonClientFrameViewAsh::NonClientTopBorderHeight(
354    bool force_restored) const {
355  if (force_restored)
356    return kTabstripTopSpacingTall;
357  if (!ShouldPaint() || UseImmersiveLightbarHeaderStyle())
358    return 0;
359  // Windows with tab strips need a smaller non-client area.
360  if (browser_view()->IsTabStripVisible()) {
361    if (UseShortHeader()) {
362      if (ash::switches::UseAlternateFrameCaptionButtonStyle())
363        return kTabstripTopSpacingShortAlternateCaptionButtonStyle;
364      return kTabstripTopSpacingShort;
365    }
366    return kTabstripTopSpacingTall;
367  }
368  // For windows without a tab strip (popups, etc.) ensure we have enough space
369  // to see the window caption buttons.
370  return caption_button_container_->bounds().bottom() - kContentShadowHeight;
371}
372
373bool BrowserNonClientFrameViewAsh::UseShortHeader() const {
374  // Restored browser -> tall header
375  // Maximized browser -> short header
376  // Fullscreen browser, no immersive reveal -> hidden or super short light bar
377  // Fullscreen browser, immersive reveal -> short header
378  // Popup&App window -> tall header
379  // Panels use short header and are handled via ash::PanelFrameView.
380  // Dialogs use short header and are handled via ash::CustomFrameViewAsh.
381  Browser* browser = browser_view()->browser();
382  switch (browser->type()) {
383    case Browser::TYPE_TABBED:
384      return frame()->IsMaximized() || frame()->IsFullscreen();
385    case Browser::TYPE_POPUP:
386      return false;
387    default:
388      NOTREACHED();
389      return false;
390  }
391}
392
393bool BrowserNonClientFrameViewAsh::UseImmersiveLightbarHeaderStyle() const {
394  ImmersiveModeController* immersive_controller =
395      browser_view()->immersive_mode_controller();
396  return immersive_controller->IsEnabled() &&
397      !immersive_controller->IsRevealed() &&
398      !immersive_controller->ShouldHideTabIndicators();
399}
400
401void BrowserNonClientFrameViewAsh::LayoutAvatar() {
402  DCHECK(avatar_button());
403  gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon();
404
405  int avatar_bottom = GetTabStripInsets(false).top +
406      browser_view()->GetTabStripHeight() - kAvatarBottomSpacing;
407  int avatar_restored_y = avatar_bottom - incognito_icon.height();
408  int avatar_y = (frame()->IsMaximized() || frame()->IsFullscreen()) ?
409      NonClientTopBorderHeight(false) + kContentShadowHeight :
410      avatar_restored_y;
411
412  // Hide the incognito icon in immersive fullscreen when the tab light bar is
413  // visible because the header is too short for the icognito icon to be
414  // recognizable.
415  bool avatar_visible = !UseImmersiveLightbarHeaderStyle();
416  int avatar_height = avatar_visible ? avatar_bottom - avatar_y : 0;
417
418  gfx::Rect avatar_bounds(kAvatarSideSpacing,
419                          avatar_y,
420                          incognito_icon.width(),
421                          avatar_height);
422  avatar_button()->SetBoundsRect(avatar_bounds);
423  avatar_button()->SetVisible(avatar_visible);
424}
425
426bool BrowserNonClientFrameViewAsh::ShouldPaint() const {
427  if (!frame()->IsFullscreen())
428    return true;
429
430  // There is nothing to paint for traditional (tab) fullscreen.
431  ImmersiveModeController* immersive_controller =
432      browser_view()->immersive_mode_controller();
433  if (!immersive_controller->IsEnabled())
434    return false;
435
436  // Need to paint during an immersive fullscreen reveal or when the immersive
437  // light bar is visible.
438  return immersive_controller->IsRevealed() ||
439      !immersive_controller->ShouldHideTabIndicators();
440}
441
442void BrowserNonClientFrameViewAsh::PaintImmersiveLightbarStyleHeader(
443    gfx::Canvas* canvas) {
444  // The light bar header is not themed because theming it does not look good.
445  gfx::ImageSkia* frame_image = GetThemeProvider()->GetImageSkiaNamed(
446      IDR_AURA_WINDOW_HEADER_BASE_MINIMAL);
447  canvas->TileImageInt(*frame_image, 0, 0, width(), frame_image->height());
448}
449
450void BrowserNonClientFrameViewAsh::PaintToolbarBackground(gfx::Canvas* canvas) {
451  gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds());
452  if (toolbar_bounds.IsEmpty())
453    return;
454  gfx::Point toolbar_origin(toolbar_bounds.origin());
455  View::ConvertPointToTarget(browser_view(), this, &toolbar_origin);
456  toolbar_bounds.set_origin(toolbar_origin);
457
458  int x = toolbar_bounds.x();
459  int w = toolbar_bounds.width();
460  int y = toolbar_bounds.y();
461  int h = toolbar_bounds.height();
462
463  // Gross hack: We split the toolbar images into two pieces, since sometimes
464  // (popup mode) the toolbar isn't tall enough to show the whole image.  The
465  // split happens between the top shadow section and the bottom gradient
466  // section so that we never break the gradient.
467  int split_point = kFrameShadowThickness * 2;
468  int bottom_y = y + split_point;
469  ui::ThemeProvider* tp = GetThemeProvider();
470  int bottom_edge_height = h - split_point;
471
472  canvas->FillRect(gfx::Rect(x, bottom_y, w, bottom_edge_height),
473                   tp->GetColor(ThemeProperties::COLOR_TOOLBAR));
474
475  // Paint the main toolbar image.  Since this image is also used to draw the
476  // tab background, we must use the tab strip offset to compute the image
477  // source y position.  If you have to debug this code use an image editor
478  // to paint a diagonal line through the toolbar image and ensure it lines up
479  // across the tab and toolbar.
480  gfx::ImageSkia* theme_toolbar = tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR);
481  canvas->TileImageInt(
482      *theme_toolbar,
483      x + GetThemeBackgroundXInset(),
484      bottom_y - GetTabStripInsets(false).top,
485      x, bottom_y,
486      w, theme_toolbar->height());
487
488  // The content area line has a shadow that extends a couple of pixels above
489  // the toolbar bounds.
490  const int kContentShadowHeight = 2;
491  gfx::ImageSkia* toolbar_top = tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_TOP);
492  canvas->TileImageInt(*toolbar_top,
493                       0, 0,
494                       x, y - kContentShadowHeight,
495                       w, split_point + kContentShadowHeight + 1);
496
497  // Draw the "lightening" shade line around the edges of the toolbar.
498  gfx::ImageSkia* toolbar_left = tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_LEFT);
499  canvas->TileImageInt(*toolbar_left,
500                       0, 0,
501                       x + kClientEdgeThickness,
502                       y + kClientEdgeThickness + kContentShadowHeight,
503                       toolbar_left->width(), theme_toolbar->height());
504  gfx::ImageSkia* toolbar_right =
505      tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_RIGHT);
506  canvas->TileImageInt(*toolbar_right,
507                       0, 0,
508                       w - toolbar_right->width() - 2 * kClientEdgeThickness,
509                       y + kClientEdgeThickness + kContentShadowHeight,
510                       toolbar_right->width(), theme_toolbar->height());
511
512  // Draw the content/toolbar separator.
513  canvas->FillRect(
514      gfx::Rect(x + kClientEdgeThickness,
515                toolbar_bounds.bottom() - kClientEdgeThickness,
516                w - (2 * kClientEdgeThickness),
517                kClientEdgeThickness),
518      ThemeProperties::GetDefaultColor(
519          ThemeProperties::COLOR_TOOLBAR_SEPARATOR));
520}
521
522void BrowserNonClientFrameViewAsh::PaintContentEdge(gfx::Canvas* canvas) {
523  canvas->FillRect(gfx::Rect(0, caption_button_container_->bounds().bottom(),
524                             width(), kClientEdgeThickness),
525      ThemeProperties::GetDefaultColor(
526          ThemeProperties::COLOR_TOOLBAR_SEPARATOR));
527}
528
529int BrowserNonClientFrameViewAsh::GetThemeFrameImageId() const {
530  bool is_incognito = browser_view()->IsOffTheRecord() &&
531                      !browser_view()->IsGuestSession();
532  if (browser_view()->IsBrowserTypeNormal()) {
533    // Use the standard resource ids to allow users to theme the frames.
534    if (ShouldPaintAsActive()) {
535      return is_incognito ?
536          IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
537    }
538    return is_incognito ?
539        IDR_THEME_FRAME_INCOGNITO_INACTIVE : IDR_THEME_FRAME_INACTIVE;
540  }
541  // Never theme app and popup windows.
542  if (ShouldPaintAsActive()) {
543    return is_incognito ?
544        IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_ACTIVE :
545        IDR_AURA_WINDOW_HEADER_BASE_ACTIVE;
546  }
547  return is_incognito ?
548      IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_INACTIVE :
549      IDR_AURA_WINDOW_HEADER_BASE_INACTIVE;
550}
551
552int BrowserNonClientFrameViewAsh::GetThemeFrameOverlayImageId() const {
553  ui::ThemeProvider* tp = GetThemeProvider();
554  if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) &&
555      browser_view()->IsBrowserTypeNormal() &&
556      !browser_view()->IsOffTheRecord()) {
557    return ShouldPaintAsActive() ?
558        IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE;
559  }
560  return 0;
561}
562