15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "apps/ui/views/app_window_frame_view.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "extensions/browser/app_window/native_app_window.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/draggable_region.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/theme_resources.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "third_party/skia/include/core/SkRegion.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/hit_test.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/canvas.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/gfx/color_utils.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/path.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/strings/grit/ui_strings.h"  // Accessibility names
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/button/image_button.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/layout/grid_layout.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/views_delegate.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/views/widget/widget_delegate.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst int kDefaultResizeInsideBoundsSize = 5;
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst int kDefaultResizeAreaCornerSize = 16;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kCaptionHeight = 25;
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace apps {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char AppWindowFrameView::kViewClassName[] =
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "browser/ui/views/extensions/AppWindowFrameView";
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuAppWindowFrameView::AppWindowFrameView(views::Widget* widget,
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       extensions::NativeAppWindow* window,
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                       bool draw_frame,
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                       const SkColor& active_frame_color,
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                       const SkColor& inactive_frame_color)
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    : widget_(widget),
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      window_(window),
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      draw_frame_(draw_frame),
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      active_frame_color_(active_frame_color),
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      inactive_frame_color_(inactive_frame_color),
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      close_button_(NULL),
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      maximize_button_(NULL),
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      restore_button_(NULL),
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      minimize_button_(NULL),
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      resize_inside_bounds_size_(kDefaultResizeInsideBoundsSize),
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resize_outside_bounds_size_(0),
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      resize_area_corner_size_(kDefaultResizeAreaCornerSize) {
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AppWindowFrameView::~AppWindowFrameView() {}
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AppWindowFrameView::Init() {
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (draw_frame_) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    close_button_ = new views::ImageButton(this);
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    close_button_->SetImage(
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia());
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    close_button_->SetImage(
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_HOVERED,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_H).ToImageSkia());
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    close_button_->SetImage(
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_PRESSED,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_P).ToImageSkia());
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    close_button_->SetAccessibleName(
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddChildView(close_button_);
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // STATE_NORMAL images are set in SetButtonImagesForFrame, not here.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    maximize_button_ = new views::ImageButton(this);
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    maximize_button_->SetImage(
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_HOVERED,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_H).ToImageSkia());
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    maximize_button_->SetImage(
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_PRESSED,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_P).ToImageSkia());
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    maximize_button_->SetImage(
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_DISABLED,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_D).ToImageSkia());
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    maximize_button_->SetAccessibleName(
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddChildView(maximize_button_);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    restore_button_ = new views::ImageButton(this);
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    restore_button_->SetImage(
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_HOVERED,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_H).ToImageSkia());
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    restore_button_->SetImage(
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_PRESSED,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_P).ToImageSkia());
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    restore_button_->SetAccessibleName(
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_RESTORE));
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddChildView(restore_button_);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    minimize_button_ = new views::ImageButton(this);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    minimize_button_->SetImage(
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_HOVERED,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_H).ToImageSkia());
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    minimize_button_->SetImage(
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_PRESSED,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_P).ToImageSkia());
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    minimize_button_->SetAccessibleName(
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddChildView(minimize_button_);
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SetButtonImagesForFrame();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AppWindowFrameView::SetResizeSizes(int resize_inside_bounds_size,
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                        int resize_outside_bounds_size,
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                        int resize_area_corner_size) {
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  resize_inside_bounds_size_ = resize_inside_bounds_size;
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  resize_outside_bounds_size_ = resize_outside_bounds_size;
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  resize_area_corner_size_ = resize_area_corner_size;
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// views::NonClientFrameView implementation.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::Rect AppWindowFrameView::GetBoundsForClientView() const {
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!draw_frame_ || widget_->IsFullscreen())
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return bounds();
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return gfx::Rect(
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      0, kCaptionHeight, width(), std::max(0, height() - kCaptionHeight));
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::Rect AppWindowFrameView::GetWindowBoundsForClientBounds(
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Rect& client_bounds) const {
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gfx::Rect window_bounds = client_bounds;
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Get the difference between the widget's client area bounds and window
138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // bounds, and grow |window_bounds| by that amount.
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gfx::Insets native_frame_insets =
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      widget_->GetClientAreaBoundsInScreen().InsetsFrom(
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          widget_->GetWindowBoundsInScreen());
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  window_bounds.Inset(native_frame_insets);
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!draw_frame_) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Enforce minimum size (1, 1) in case that client_bounds is passed with
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // empty size. This could occur when the frameless window is being
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // initialized.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (window_bounds.IsEmpty()) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_bounds.set_width(1);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_bounds.set_height(1);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return window_bounds;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int closeButtonOffsetX = (kCaptionHeight - close_button_->height()) / 2;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int header_width = close_button_->width() + closeButtonOffsetX * 2;
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return gfx::Rect(window_bounds.x(),
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   window_bounds.y() - kCaptionHeight,
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   std::max(header_width, window_bounds.width()),
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   window_bounds.height() + kCaptionHeight);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int AppWindowFrameView::NonClientHitTest(const gfx::Point& point) {
16423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (widget_->IsFullscreen())
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return HTCLIENT;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Rect expanded_bounds = bounds();
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (resize_outside_bounds_size_) {
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    expanded_bounds.Inset(gfx::Insets(-resize_outside_bounds_size_,
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      -resize_outside_bounds_size_,
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      -resize_outside_bounds_size_,
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      -resize_outside_bounds_size_));
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Points outside the (possibly expanded) bounds can be discarded.
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!expanded_bounds.Contains(point))
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return HTNOWHERE;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check the frame first, as we allow a small area overlapping the contents
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to be used for resize handles.
18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool can_ever_resize = widget_->widget_delegate()
18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                             ? widget_->widget_delegate()->CanResize()
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             : false;
183ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Don't allow overlapping resize handles when the window is maximized or
184ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // fullscreen, as it can't be resized in those states.
18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int resize_border = (widget_->IsMaximized() || widget_->IsFullscreen())
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          ? 0
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          : resize_inside_bounds_size_;
188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int frame_component = GetHTComponentForFrame(point,
189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                               resize_border,
190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                               resize_border,
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                               resize_area_corner_size_,
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                               resize_area_corner_size_,
193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                               can_ever_resize);
194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (frame_component != HTNOWHERE)
195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return frame_component;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check for possible draggable region in the client area for the frameless
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // window.
199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  SkRegion* draggable_region = window_->GetDraggableRegion();
200e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (draggable_region && draggable_region->contains(point.x(), point.y()))
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return HTCAPTION;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int client_component = widget_->client_view()->NonClientHitTest(point);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (client_component != HTNOWHERE)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return client_component;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Then see if the point is within any of the window controls.
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (close_button_ && close_button_->visible() &&
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      close_button_->GetMirroredBounds().Contains(point)) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return HTCLOSE;
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if ((maximize_button_ && maximize_button_->visible() &&
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       maximize_button_->GetMirroredBounds().Contains(point)) ||
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (restore_button_ && restore_button_->visible() &&
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       restore_button_->GetMirroredBounds().Contains(point))) {
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return HTMAXBUTTON;
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (minimize_button_ && minimize_button_->visible() &&
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      minimize_button_->GetMirroredBounds().Contains(point)) {
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return HTMINBUTTON;
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Caption is a safe default.
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return HTCAPTION;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowFrameView::GetWindowMask(const gfx::Size& size,
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       gfx::Path* window_mask) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We got nothing to say about no window mask.
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppWindowFrameView::SizeConstraintsChanged() {
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (draw_frame_) {
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    maximize_button_->SetEnabled(widget_->widget_delegate() &&
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 widget_->widget_delegate()->CanMaximize());
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size AppWindowFrameView::GetPreferredSize() const {
24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  gfx::Size pref = widget_->client_view()->GetPreferredSize();
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds(0, 0, pref.width(), pref.height());
24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return widget_->non_client_view()
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ->GetWindowBoundsForClientBounds(bounds)
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .size();
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowFrameView::Layout() {
248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!draw_frame_)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size close_size = close_button_->GetPreferredSize();
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kButtonOffsetY = 0;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kButtonSpacing = 1;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kRightMargin = 3;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  close_button_->SetBounds(width() - kRightMargin - close_size.width(),
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           kButtonOffsetY,
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           close_size.width(),
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           close_size.height());
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  maximize_button_->SetEnabled(widget_->widget_delegate() &&
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               widget_->widget_delegate()->CanMaximize());
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size maximize_size = maximize_button_->GetPreferredSize();
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  maximize_button_->SetBounds(
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      close_button_->x() - kButtonSpacing - maximize_size.width(),
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kButtonOffsetY,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      maximize_size.width(),
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      maximize_size.height());
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size restore_size = restore_button_->GetPreferredSize();
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restore_button_->SetBounds(
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      close_button_->x() - kButtonSpacing - restore_size.width(),
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kButtonOffsetY,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      restore_size.width(),
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      restore_size.height());
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool maximized = widget_->IsMaximized();
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  maximize_button_->SetVisible(!maximized);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restore_button_->SetVisible(maximized);
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (maximized)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    maximize_button_->SetState(views::CustomButton::STATE_NORMAL);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    restore_button_->SetState(views::CustomButton::STATE_NORMAL);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size minimize_size = minimize_button_->GetPreferredSize();
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  minimize_button_->SetState(views::CustomButton::STATE_NORMAL);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  minimize_button_->SetBounds(
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      maximize_button_->x() - kButtonSpacing - minimize_size.width(),
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kButtonOffsetY,
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      minimize_size.width(),
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      minimize_size.height());
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowFrameView::OnPaint(gfx::Canvas* canvas) {
293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!draw_frame_)
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldPaintAsActive()) {
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    close_button_->SetImage(
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia());
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    close_button_->SetImage(
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_U).ToImageSkia());
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetButtonImagesForFrame();
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(benwells): different look for inactive by default.
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkPaint paint;
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setAntiAlias(false);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  paint.setColor(CurrentFrameColor());
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Path path;
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  path.moveTo(0, 0);
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  path.lineTo(width(), 0);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  path.lineTo(width(), kCaptionHeight);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  path.lineTo(0, kCaptionHeight);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  path.close();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->DrawPath(path, paint);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char* AppWindowFrameView::GetClassName() const { return kViewClassName; }
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size AppWindowFrameView::GetMinimumSize() const {
32523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  gfx::Size min_size = widget_->client_view()->GetMinimumSize();
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!draw_frame_) {
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    min_size.SetToMax(gfx::Size(1, 1));
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return min_size;
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure we can display the top of the caption area.
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect client_bounds = GetBoundsForClientView();
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  min_size.Enlarge(0, client_bounds.y());
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure we have enough space for the window icon and buttons.  We allow
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the title string to collapse to zero width.
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int closeButtonOffsetX = (kCaptionHeight - close_button_->height()) / 2;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int header_width = close_button_->width() + closeButtonOffsetX * 2;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (header_width > min_size.width())
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    min_size.set_width(header_width);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return min_size;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size AppWindowFrameView::GetMaximumSize() const {
34423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  gfx::Size max_size = widget_->client_view()->GetMaximumSize();
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Add to the client maximum size the height of any title bar and borders.
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  gfx::Size client_size = GetBoundsForClientView().size();
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (max_size.width())
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    max_size.Enlarge(width() - client_size.width(), 0);
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (max_size.height())
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    max_size.Enlarge(0, height() - client_size.height());
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return max_size;
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppWindowFrameView::ButtonPressed(views::Button* sender,
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       const ui::Event& event) {
358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(draw_frame_);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (sender == close_button_)
36023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    widget_->Close();
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (sender == maximize_button_)
36223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    widget_->Maximize();
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (sender == restore_button_)
36423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    widget_->Restore();
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (sender == minimize_button_)
36623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    widget_->Minimize();
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SkColor AppWindowFrameView::CurrentFrameColor() {
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return widget_->IsActive() ? active_frame_color_ : inactive_frame_color_;
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AppWindowFrameView::SetButtonImagesForFrame() {
374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(draw_frame_);
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the frame is dark, we should use the light images so they have
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // some contrast.
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  unsigned char frame_luma =
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      color_utils::GetLuminanceForColor(CurrentFrameColor());
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const unsigned char kLuminanceThreshold = 100;
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool use_light = frame_luma < kLuminanceThreshold;
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (use_light) {
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    maximize_button_->SetImage(
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_L).ToImageSkia());
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    restore_button_->SetImage(
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_L).ToImageSkia());
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    minimize_button_->SetImage(
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_L).ToImageSkia());
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    maximize_button_->SetImage(
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE).ToImageSkia());
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    restore_button_->SetImage(
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE).ToImageSkia());
401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    minimize_button_->SetImage(
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        views::CustomButton::STATE_NORMAL,
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE).ToImageSkia());
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace apps
408