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