13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file.
43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <cmath>
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <map>
93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ash/ash_switches.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/frame/caption_buttons/frame_caption_button.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/frame/caption_buttons/frame_size_button.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/metrics/user_metrics_recorder.h"
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/shell.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ash/wm/maximize_mode/maximize_mode_controller.h"
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/base/hit_test.h"
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/compositor/scoped_animation_duration_scale_mode.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gfx/animation/tween.h"
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/gfx/canvas.h"
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/insets.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/point.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/strings/grit/ui_strings.h"  // Accessibility names
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/widget/widget.h"
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/views/widget/widget_delegate.h"
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace ash {
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Duration of the animation of the position of |minimize_button_|.
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kPositionAnimationDurationMs = 500;
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Duration of the animation of the alpha of |size_button_|.
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kAlphaAnimationDurationMs = 250;
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Delay during |maximize_mode_animation_| hide to wait before beginning to
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// animate the position of |minimize_button_|.
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kHidePositionDelayMs = 100;
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Duration of |maximize_mode_animation_| hiding.
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Hiding size button 250
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |------------------------|
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Delay 100      Slide minimize button 500
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |---------|-------------------------------------------------|
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kHideAnimationDurationMs =
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    kHidePositionDelayMs + kPositionAnimationDurationMs;
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Delay during |maximize_mode_animation_| show to wait before beginning to
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// animate the alpha of |size_button_|.
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kShowAnimationAlphaDelayMs = 100;
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Duration of |maximize_mode_animation_| showing.
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Slide minimize button 500
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |-------------------------------------------------|
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Delay 100   Show size button 250
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |---------|-----------------------|
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kShowAnimationDurationMs = kPositionAnimationDurationMs;
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Value of |maximize_mode_animation_| showing to begin animating alpha of
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |size_button_|.
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)float SizeButtonShowStartValue() {
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return static_cast<float>(kShowAnimationAlphaDelayMs)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      / kShowAnimationDurationMs;
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Amount of |maximize_mode_animation_| showing to animate the alpha of
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |size_button_|.
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)float SizeButtonShowDuration() {
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return static_cast<float>(kAlphaAnimationDurationMs)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      / kShowAnimationDurationMs;
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Amount of |maximize_mode_animation_| hiding to animate the alpha of
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |size_button_|.
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)float SizeButtonHideDuration() {
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return static_cast<float>(kAlphaAnimationDurationMs)
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      / kHideAnimationDurationMs;
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Value of |maximize_mode_animation_| hiding to begin animating the position of
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |minimize_button_|.
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)float HidePositionStartValue() {
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return 1.0f - static_cast<float>(kHidePositionDelayMs)
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      / kHideAnimationDurationMs;
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Converts |point| from |src| to |dst| and hittests against |dst|.
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ConvertPointToViewAndHitTest(const views::View* src,
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  const views::View* dst,
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  const gfx::Point& point) {
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  gfx::Point converted(point);
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::View::ConvertPointToTarget(src, dst, &converted);
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return dst->HitTestPoint(converted);
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Bounds animation values to the range 0.0 - 1.0. Allows for mapping of offset
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// animations to the expected range so that gfx::Tween::CalculateValue() can be
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// used.
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)double CapAnimationValue(double value) {
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return std::min(1.0, std::max(0.0, value));
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// static
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char FrameCaptionButtonContainerView::kViewClassName[] =
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "FrameCaptionButtonContainerView";
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FrameCaptionButtonContainerView::FrameCaptionButtonContainerView(
112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    views::Widget* frame,
113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    MinimizeAllowed minimize_allowed)
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    : frame_(frame),
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      minimize_button_(NULL),
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      size_button_(NULL),
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      close_button_(NULL) {
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool size_button_visibility = ShouldSizeButtonBeVisible();
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  maximize_mode_animation_.reset(new gfx::SlideAnimation(this));
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  maximize_mode_animation_->SetTweenType(gfx::Tween::LINEAR);
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Ensure animation tracks visibility of size button.
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (size_button_visibility)
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    maximize_mode_animation_->Reset(1.0f);
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Insert the buttons left to right.
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  minimize_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_MINIMIZE);
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  minimize_button_->SetAccessibleName(
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  minimize_button_->SetVisible(minimize_allowed == MINIMIZE_ALLOWED);
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  AddChildView(minimize_button_);
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  size_button_ = new FrameSizeButton(this, frame, this);
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  size_button_->SetAccessibleName(
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  size_button_->SetVisible(size_button_visibility);
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AddChildView(size_button_);
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  close_button_ = new FrameCaptionButton(this, CAPTION_BUTTON_ICON_CLOSE);
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  close_button_->SetAccessibleName(
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  AddChildView(close_button_);
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FrameCaptionButtonContainerView::~FrameCaptionButtonContainerView() {
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FrameCaptionButtonContainerView::TestApi::EndAnimations() {
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  container_view_->maximize_mode_animation_->End();
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void FrameCaptionButtonContainerView::SetButtonImages(
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CaptionButtonIcon icon,
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int icon_image_id,
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int inactive_icon_image_id,
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int hovered_background_image_id,
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int pressed_background_image_id) {
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  button_icon_id_map_[icon] = ButtonIconIds(icon_image_id,
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                            inactive_icon_image_id,
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                            hovered_background_image_id,
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                            pressed_background_image_id);
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FrameCaptionButton* buttons[] = {
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    minimize_button_, size_button_, close_button_
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < arraysize(buttons); ++i) {
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (buttons[i]->icon() == icon) {
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      buttons[i]->SetImages(icon,
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            FrameCaptionButton::ANIMATE_NO,
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            icon_image_id,
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            inactive_icon_image_id,
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            hovered_background_image_id,
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            pressed_background_image_id);
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void FrameCaptionButtonContainerView::SetPaintAsActive(bool paint_as_active) {
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  minimize_button_->set_paint_as_active(paint_as_active);
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_button_->set_paint_as_active(paint_as_active);
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  close_button_->set_paint_as_active(paint_as_active);
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FrameCaptionButtonContainerView::ResetWindowControls() {
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetButtonsToNormal(ANIMATE_NO);
1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int FrameCaptionButtonContainerView::NonClientHitTest(
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const gfx::Point& point) const {
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (close_button_->visible() &&
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ConvertPointToViewAndHitTest(this, close_button_, point)) {
191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return HTCLOSE;
192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else if (size_button_->visible() &&
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)             ConvertPointToViewAndHitTest(this, size_button_, point)) {
194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return HTMAXBUTTON;
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else if (minimize_button_->visible() &&
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)             ConvertPointToViewAndHitTest(this, minimize_button_, point)) {
197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return HTMINBUTTON;
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return HTNOWHERE;
200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void FrameCaptionButtonContainerView::UpdateSizeButtonVisibility() {
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool visible = ShouldSizeButtonBeVisible();
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (visible) {
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_button_->SetVisible(true);
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    maximize_mode_animation_->SetSlideDuration(kShowAnimationDurationMs);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    maximize_mode_animation_->Show();
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    maximize_mode_animation_->SetSlideDuration(kHideAnimationDurationMs);
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    maximize_mode_animation_->Hide();
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size FrameCaptionButtonContainerView::GetPreferredSize() const {
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int width = 0;
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (int i = 0; i < child_count(); ++i) {
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const views::View* child = child_at(i);
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (child->visible())
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      width += child_at(i)->GetPreferredSize().width();
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return gfx::Size(width, close_button_->GetPreferredSize().height());
2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FrameCaptionButtonContainerView::Layout() {
2256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int x = 0;
2266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  for (int i = 0; i < child_count(); ++i) {
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    views::View* child = child_at(i);
2286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (!child->visible())
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      continue;
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    gfx::Size size = child->GetPreferredSize();
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    child->SetBounds(x, 0, size.width(), size.height());
2336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    x += size.width();
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (maximize_mode_animation_->is_animating()) {
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    AnimationProgressed(maximize_mode_animation_.get());
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char* FrameCaptionButtonContainerView::GetClassName() const {
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return kViewClassName;
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FrameCaptionButtonContainerView::AnimationEnded(
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const gfx::Animation* animation) {
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Ensure that position is calculated at least once.
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AnimationProgressed(animation);
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  double current_value = maximize_mode_animation_->GetCurrentValue();
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (current_value == 0.0) {
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_button_->SetVisible(false);
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    PreferredSizeChanged();
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FrameCaptionButtonContainerView::AnimationProgressed(
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const gfx::Animation* animation) {
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  double current_value = animation->GetCurrentValue();
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int size_alpha = 0;
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int minimize_x = 0;
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (maximize_mode_animation_->IsShowing()) {
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    double scaled_value = CapAnimationValue(
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        (current_value - SizeButtonShowStartValue())
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            / SizeButtonShowDuration());
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    double tweened_value_alpha =
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        gfx::Tween::CalculateValue(gfx::Tween::EASE_OUT,scaled_value);
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_alpha = gfx::Tween::LinearIntValueBetween(tweened_value_alpha, 0, 255);
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    double tweened_value_slide =
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        gfx::Tween::CalculateValue(gfx::Tween::EASE_OUT, current_value);
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    minimize_x = gfx::Tween::LinearIntValueBetween(tweened_value_slide,
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                   size_button_->x(), 0);
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    double scaled_value_alpha = CapAnimationValue(
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        (1.0f - current_value) / SizeButtonHideDuration());
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    double tweened_value_alpha =
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        gfx::Tween::CalculateValue(gfx::Tween::EASE_IN, scaled_value_alpha);
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    size_alpha = gfx::Tween::LinearIntValueBetween(tweened_value_alpha, 255, 0);
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    double scaled_value_position = CapAnimationValue(
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        (HidePositionStartValue() - current_value)
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            / HidePositionStartValue());
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    double tweened_value_position =
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        gfx::Tween::CalculateValue(gfx::Tween::EASE_OUT, scaled_value_position);
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    minimize_x = gfx::Tween::LinearIntValueBetween(tweened_value_position, 0,
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                   size_button_->x());
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  size_button_->SetAlpha(size_alpha);
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  minimize_button_->SetX(minimize_x);
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void FrameCaptionButtonContainerView::SetButtonIcon(FrameCaptionButton* button,
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                    CaptionButtonIcon icon,
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                    Animate animate) {
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The early return is dependant on |animate| because callers use
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // SetButtonIcon() with ANIMATE_NO to progress |button|'s crossfade animation
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // to the end.
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (button->icon() == icon &&
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      (animate == ANIMATE_YES || !button->IsAnimatingImageSwap())) {
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FrameCaptionButton::Animate fcb_animate = (animate == ANIMATE_YES) ?
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FrameCaptionButton::ANIMATE_YES : FrameCaptionButton::ANIMATE_NO;
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::map<CaptionButtonIcon, ButtonIconIds>::const_iterator it =
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      button_icon_id_map_.find(icon);
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (it != button_icon_id_map_.end()) {
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    button->SetImages(icon,
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      fcb_animate,
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      it->second.icon_image_id,
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      it->second.inactive_icon_image_id,
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      it->second.hovered_background_image_id,
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      it->second.pressed_background_image_id);
314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool FrameCaptionButtonContainerView::ShouldSizeButtonBeVisible() const {
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return !Shell::GetInstance()->maximize_mode_controller()->
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IsMaximizeModeWindowManagerEnabled() &&
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame_->widget_delegate()->CanMaximize();
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FrameCaptionButtonContainerView::ButtonPressed(views::Button* sender,
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                    const ui::Event& event) {
325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Abort any animations of the button icons.
326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetButtonsToNormal(ANIMATE_NO);
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ash::UserMetricsAction action =
329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MINIMIZE;
330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (sender == minimize_button_) {
331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    frame_->Minimize();
332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else if (sender == size_button_) {
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (frame_->IsFullscreen()) {  // Can be clicked in immersive fullscreen.
33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      frame_->Restore();
335424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_EXIT_FULLSCREEN;
336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    } else if (frame_->IsMaximized()) {
337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      frame_->Restore();
338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_RESTORE;
339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    } else {
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      frame_->Maximize();
341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      action = ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE;
342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else if (sender == close_button_) {
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    frame_->Close();
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    action = ash::UMA_WINDOW_CLOSE_BUTTON_CLICK;
3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(action);
3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool FrameCaptionButtonContainerView::IsMinimizeButtonVisible() const {
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return minimize_button_->visible();
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void FrameCaptionButtonContainerView::SetButtonsToNormal(Animate animate) {
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetButtonIcons(CAPTION_BUTTON_ICON_MINIMIZE, CAPTION_BUTTON_ICON_CLOSE,
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      animate);
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  minimize_button_->SetState(views::Button::STATE_NORMAL);
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_button_->SetState(views::Button::STATE_NORMAL);
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  close_button_->SetState(views::Button::STATE_NORMAL);
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void FrameCaptionButtonContainerView::SetButtonIcons(
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    CaptionButtonIcon minimize_button_icon,
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    CaptionButtonIcon close_button_icon,
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Animate animate) {
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetButtonIcon(minimize_button_, minimize_button_icon, animate);
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetButtonIcon(close_button_, close_button_icon, animate);
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const FrameCaptionButton* FrameCaptionButtonContainerView::GetButtonClosestTo(
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const gfx::Point& position_in_screen) const {
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Since the buttons all have the same size, the closest button is the button
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // with the center point closest to |position_in_screen|.
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(pkotwicz): Make the caption buttons not overlap.
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Point position(position_in_screen);
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  views::View::ConvertPointFromScreen(this, &position);
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FrameCaptionButton* buttons[] = {
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    minimize_button_, size_button_, close_button_
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  };
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int min_squared_distance = INT_MAX;
384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FrameCaptionButton* closest_button = NULL;
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (size_t i = 0; i < arraysize(buttons); ++i) {
386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FrameCaptionButton* button = buttons[i];
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!button->visible())
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      continue;
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gfx::Point center_point = button->GetLocalBounds().CenterPoint();
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    views::View::ConvertPointToTarget(button, this, &center_point);
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int squared_distance = static_cast<int>(
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        pow(static_cast<double>(position.x() - center_point.x()), 2) +
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        pow(static_cast<double>(position.y() - center_point.y()), 2));
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (squared_distance < min_squared_distance) {
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      min_squared_distance = squared_distance;
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      closest_button = button;
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return closest_button;
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void FrameCaptionButtonContainerView::SetHoveredAndPressedButtons(
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const FrameCaptionButton* to_hover,
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const FrameCaptionButton* to_press) {
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FrameCaptionButton* buttons[] = {
407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    minimize_button_, size_button_, close_button_
408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (size_t i = 0; i < arraysize(buttons); ++i) {
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FrameCaptionButton* button = buttons[i];
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    views::Button::ButtonState new_state = views::Button::STATE_NORMAL;
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (button == to_hover)
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new_state = views::Button::STATE_HOVERED;
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    else if (button == to_press)
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new_state = views::Button::STATE_PRESSED;
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    button->SetState(new_state);
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds()
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : icon_image_id(-1),
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      inactive_icon_image_id(-1),
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      hovered_background_image_id(-1),
424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pressed_background_image_id(-1) {
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)FrameCaptionButtonContainerView::ButtonIconIds::ButtonIconIds(
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int icon_id,
429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int inactive_icon_id,
430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int hovered_background_id,
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int pressed_background_id)
432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : icon_image_id(icon_id),
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      inactive_icon_image_id(inactive_icon_id),
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      hovered_background_image_id(hovered_background_id),
435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      pressed_background_image_id(pressed_background_id) {
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)FrameCaptionButtonContainerView::ButtonIconIds::~ButtonIconIds() {
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace ash
442