1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/system/tray/hover_highlight_view.h"
6
7#include "ash/system/tray/fixed_sized_image_view.h"
8#include "ash/system/tray/tray_constants.h"
9#include "ash/system/tray/view_click_listener.h"
10#include "ui/accessibility/ax_view_state.h"
11#include "ui/base/resource/resource_bundle.h"
12#include "ui/gfx/canvas.h"
13#include "ui/gfx/font_list.h"
14#include "ui/resources/grit/ui_resources.h"
15#include "ui/views/border.h"
16#include "ui/views/controls/image_view.h"
17#include "ui/views/controls/label.h"
18#include "ui/views/layout/box_layout.h"
19#include "ui/views/layout/fill_layout.h"
20
21namespace {
22
23const int kCheckLabelPadding = 4;
24
25}  // namespace
26
27namespace ash {
28
29HoverHighlightView::HoverHighlightView(ViewClickListener* listener)
30    : listener_(listener),
31      text_label_(NULL),
32      highlight_color_(kHoverBackgroundColor),
33      default_color_(0),
34      text_highlight_color_(0),
35      text_default_color_(0),
36      hover_(false),
37      expandable_(false),
38      checkable_(false),
39      checked_(false) {
40  set_notify_enter_exit_on_child(true);
41}
42
43HoverHighlightView::~HoverHighlightView() {
44}
45
46void HoverHighlightView::AddIconAndLabel(const gfx::ImageSkia& image,
47                                         const base::string16& text,
48                                         gfx::Font::FontStyle style) {
49  SetLayoutManager(new views::BoxLayout(
50      views::BoxLayout::kHorizontal, 0, 3, kTrayPopupPaddingBetweenItems));
51  views::ImageView* image_view =
52      new FixedSizedImageView(kTrayPopupDetailsIconWidth, 0);
53  image_view->SetImage(image);
54  AddChildView(image_view);
55
56  text_label_ = new views::Label(text);
57  text_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
58  text_label_->SetFontList(text_label_->font_list().DeriveWithStyle(style));
59  if (text_default_color_)
60    text_label_->SetEnabledColor(text_default_color_);
61  AddChildView(text_label_);
62
63  SetAccessibleName(text);
64}
65
66views::Label* HoverHighlightView::AddLabel(const base::string16& text,
67                                           gfx::HorizontalAlignment alignment,
68                                           gfx::Font::FontStyle style) {
69  SetLayoutManager(new views::FillLayout());
70  text_label_ = new views::Label(text);
71  int left_margin = kTrayPopupPaddingHorizontal;
72  int right_margin = kTrayPopupPaddingHorizontal;
73  if (alignment != gfx::ALIGN_CENTER) {
74    if (base::i18n::IsRTL())
75      right_margin += kTrayPopupDetailsLabelExtraLeftMargin;
76    else
77      left_margin += kTrayPopupDetailsLabelExtraLeftMargin;
78  }
79  text_label_->SetBorder(
80      views::Border::CreateEmptyBorder(5, left_margin, 5, right_margin));
81  text_label_->SetHorizontalAlignment(alignment);
82  text_label_->SetFontList(text_label_->font_list().DeriveWithStyle(style));
83  // Do not set alpha value in disable color. It will have issue with elide
84  // blending filter in disabled state for rendering label text color.
85  text_label_->SetDisabledColor(SkColorSetARGB(255, 127, 127, 127));
86  if (text_default_color_)
87    text_label_->SetEnabledColor(text_default_color_);
88  AddChildView(text_label_);
89
90  SetAccessibleName(text);
91  return text_label_;
92}
93
94views::Label* HoverHighlightView::AddCheckableLabel(const base::string16& text,
95                                                    gfx::Font::FontStyle style,
96                                                    bool checked) {
97  checkable_ = true;
98  checked_ = checked;
99  if (checked) {
100    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
101    const gfx::ImageSkia* check =
102        rb.GetImageNamed(IDR_MENU_CHECK).ToImageSkia();
103    int margin = kTrayPopupPaddingHorizontal +
104        kTrayPopupDetailsLabelExtraLeftMargin - kCheckLabelPadding;
105    SetLayoutManager(new views::BoxLayout(
106        views::BoxLayout::kHorizontal, 0, 3, kCheckLabelPadding));
107    views::ImageView* image_view = new FixedSizedImageView(margin, 0);
108    image_view->SetImage(check);
109    image_view->SetHorizontalAlignment(views::ImageView::TRAILING);
110    AddChildView(image_view);
111
112    text_label_ = new views::Label(text);
113    text_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
114    text_label_->SetFontList(text_label_->font_list().DeriveWithStyle(style));
115    text_label_->SetDisabledColor(SkColorSetARGB(127, 0, 0, 0));
116    if (text_default_color_)
117      text_label_->SetEnabledColor(text_default_color_);
118    AddChildView(text_label_);
119
120    SetAccessibleName(text);
121    return text_label_;
122  }
123  return AddLabel(text, gfx::ALIGN_LEFT, style);
124}
125
126void HoverHighlightView::SetExpandable(bool expandable) {
127  if (expandable != expandable_) {
128    expandable_ = expandable;
129    InvalidateLayout();
130  }
131}
132
133bool HoverHighlightView::PerformAction(const ui::Event& event) {
134  if (!listener_)
135    return false;
136  listener_->OnViewClicked(this);
137  return true;
138}
139
140void HoverHighlightView::GetAccessibleState(ui::AXViewState* state) {
141  ActionableView::GetAccessibleState(state);
142
143  if (checkable_) {
144    state->role = ui::AX_ROLE_CHECK_BOX;
145    if (checked_)
146      state->AddStateFlag(ui::AX_STATE_CHECKED);
147  }
148}
149
150gfx::Size HoverHighlightView::GetPreferredSize() const {
151  gfx::Size size = ActionableView::GetPreferredSize();
152  if (!expandable_ || size.height() < kTrayPopupItemHeight)
153    size.set_height(kTrayPopupItemHeight);
154  return size;
155}
156
157int HoverHighlightView::GetHeightForWidth(int width) const {
158  return GetPreferredSize().height();
159}
160
161void HoverHighlightView::OnMouseEntered(const ui::MouseEvent& event) {
162  hover_ = true;
163  if (text_highlight_color_ && text_label_)
164    text_label_->SetEnabledColor(text_highlight_color_);
165  SchedulePaint();
166}
167
168void HoverHighlightView::OnMouseExited(const ui::MouseEvent& event) {
169  hover_ = false;
170  if (text_default_color_ && text_label_)
171    text_label_->SetEnabledColor(text_default_color_);
172  SchedulePaint();
173}
174
175void HoverHighlightView::OnEnabledChanged() {
176  for (int i = 0; i < child_count(); ++i)
177    child_at(i)->SetEnabled(enabled());
178}
179
180void HoverHighlightView::OnPaintBackground(gfx::Canvas* canvas) {
181  canvas->DrawColor(hover_ ? highlight_color_ : default_color_);
182}
183
184void HoverHighlightView::OnFocus() {
185  ScrollRectToVisible(gfx::Rect(gfx::Point(), size()));
186  ActionableView::OnFocus();
187}
188
189}  // namespace ash
190