12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 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)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/hover_highlight_view.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/fixed_sized_image_view.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/tray_constants.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/system/tray/view_click_listener.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/canvas.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font_list.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/border.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/image_view.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/label.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/layout/box_layout.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/layout/fill_layout.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kCheckLabelPadding = 4;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HoverHighlightView::HoverHighlightView(ViewClickListener* listener)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : listener_(listener),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      text_label_(NULL),
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      highlight_color_(kHoverBackgroundColor),
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default_color_(0),
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      text_highlight_color_(0),
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      text_default_color_(0),
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      hover_(false),
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      expandable_(false),
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      checkable_(false),
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      checked_(false) {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  set_notify_enter_exit_on_child(true);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HoverHighlightView::~HoverHighlightView() {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HoverHighlightView::AddIconAndLabel(const gfx::ImageSkia& image,
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         const base::string16& text,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         gfx::Font::FontStyle style) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetLayoutManager(new views::BoxLayout(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      views::BoxLayout::kHorizontal, 0, 3, kTrayPopupPaddingBetweenItems));
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::ImageView* image_view =
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FixedSizedImageView(kTrayPopupDetailsIconWidth, 0);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  image_view->SetImage(image);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddChildView(image_view);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  text_label_ = new views::Label(text);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  text_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  text_label_->SetFontList(text_label_->font_list().DeriveWithStyle(style));
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (text_default_color_)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    text_label_->SetEnabledColor(text_default_color_);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddChildView(text_label_);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetAccessibleName(text);
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)views::Label* HoverHighlightView::AddLabel(const base::string16& text,
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                           gfx::HorizontalAlignment alignment,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           gfx::Font::FontStyle style) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetLayoutManager(new views::FillLayout());
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  text_label_ = new views::Label(text);
71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int left_margin = kTrayPopupPaddingHorizontal;
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int right_margin = kTrayPopupPaddingHorizontal;
73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (alignment != gfx::ALIGN_CENTER) {
74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (base::i18n::IsRTL())
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      right_margin += kTrayPopupDetailsLabelExtraLeftMargin;
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    else
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      left_margin += kTrayPopupDetailsLabelExtraLeftMargin;
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  text_label_->SetBorder(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      views::Border::CreateEmptyBorder(5, left_margin, 5, right_margin));
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  text_label_->SetHorizontalAlignment(alignment);
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  text_label_->SetFontList(text_label_->font_list().DeriveWithStyle(style));
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do not set alpha value in disable color. It will have issue with elide
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // blending filter in disabled state for rendering label text color.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  text_label_->SetDisabledColor(SkColorSetARGB(255, 127, 127, 127));
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (text_default_color_)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    text_label_->SetEnabledColor(text_default_color_);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddChildView(text_label_);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetAccessibleName(text);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return text_label_;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)views::Label* HoverHighlightView::AddCheckableLabel(const base::string16& text,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                    gfx::Font::FontStyle style,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                    bool checked) {
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  checkable_ = true;
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  checked_ = checked;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (checked) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::ImageSkia* check =
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rb.GetImageNamed(IDR_MENU_CHECK).ToImageSkia();
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int margin = kTrayPopupPaddingHorizontal +
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        kTrayPopupDetailsLabelExtraLeftMargin - kCheckLabelPadding;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetLayoutManager(new views::BoxLayout(
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        views::BoxLayout::kHorizontal, 0, 3, kCheckLabelPadding));
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    views::ImageView* image_view = new FixedSizedImageView(margin, 0);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_view->SetImage(check);
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_view->SetHorizontalAlignment(views::ImageView::TRAILING);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddChildView(image_view);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    text_label_ = new views::Label(text);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    text_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    text_label_->SetFontList(text_label_->font_list().DeriveWithStyle(style));
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    text_label_->SetDisabledColor(SkColorSetARGB(127, 0, 0, 0));
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (text_default_color_)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      text_label_->SetEnabledColor(text_default_color_);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddChildView(text_label_);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetAccessibleName(text);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return text_label_;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return AddLabel(text, gfx::ALIGN_LEFT, style);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HoverHighlightView::SetExpandable(bool expandable) {
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (expandable != expandable_) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expandable_ = expandable;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InvalidateLayout();
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HoverHighlightView::PerformAction(const ui::Event& event) {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!listener_)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  listener_->OnViewClicked(this);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void HoverHighlightView::GetAccessibleState(ui::AXViewState* state) {
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ActionableView::GetAccessibleState(state);
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (checkable_) {
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state->role = ui::AX_ROLE_CHECK_BOX;
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (checked_)
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      state->AddStateFlag(ui::AX_STATE_CHECKED);
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size HoverHighlightView::GetPreferredSize() const {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size size = ActionableView::GetPreferredSize();
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!expandable_ || size.height() < kTrayPopupItemHeight)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size.set_height(kTrayPopupItemHeight);
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return size;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int HoverHighlightView::GetHeightForWidth(int width) const {
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetPreferredSize().height();
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HoverHighlightView::OnMouseEntered(const ui::MouseEvent& event) {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hover_ = true;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (text_highlight_color_ && text_label_)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    text_label_->SetEnabledColor(text_highlight_color_);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulePaint();
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HoverHighlightView::OnMouseExited(const ui::MouseEvent& event) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hover_ = false;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (text_default_color_ && text_label_)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    text_label_->SetEnabledColor(text_default_color_);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulePaint();
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HoverHighlightView::OnEnabledChanged() {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < child_count(); ++i)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_at(i)->SetEnabled(enabled());
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HoverHighlightView::OnPaintBackground(gfx::Canvas* canvas) {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  canvas->DrawColor(hover_ ? highlight_color_ : default_color_);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HoverHighlightView::OnFocus() {
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScrollRectToVisible(gfx::Rect(gfx::Point(), size()));
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ActionableView::OnFocus();
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ash
190