- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / input_method / infolist_window_view.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #include "chrome/browser/chromeos/input_method/infolist_window_view.h"
5
6 #include <limits>
7 #include <string>
8 #include <vector>
9
10 #include "ash/shell.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/chromeos/input_method/candidate_window_constants.h"
15 #include "chrome/browser/chromeos/input_method/hidable_area.h"
16 #include "grit/generated_resources.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/gfx/color_utils.h"
19 #include "ui/gfx/font.h"
20 #include "ui/native_theme/native_theme.h"
21 #include "ui/views/controls/label.h"
22 #include "ui/views/layout/box_layout.h"
23 #include "ui/views/layout/grid_layout.h"
24 #include "ui/views/widget/widget.h"
25
26 namespace chromeos {
27 namespace input_method {
28
29 // InfolistRow renderes a row of a infolist.
30 class InfolistEntryView : public views::View {
31  public:
32   InfolistEntryView();
33   virtual ~InfolistEntryView() {}
34
35   void Init(const gfx::Font& title_font, const gfx::Font& description_font);
36
37   // Sets title text and description text.
38   void Relayout(const InfolistWindowView::Entry& entry);
39
40   // Selects the infolist row. Changes the appearance to make it look
41   // like a selected candidate.
42   void Select();
43
44   // Unselects the infolist row. Changes the appearance to make it look
45   // like an unselected candidate.
46   void Unselect();
47
48  protected:
49   virtual gfx::Size GetPreferredSize() OVERRIDE {
50     return title_and_description_size_;
51   }
52
53  private:
54   // Notifies labels of their new background colors.  Called whenever the view's
55   // background color changes.
56   void UpdateLabelBackgroundColors();
57
58   // The parent candidate window that contains this view.
59   InfolistWindowView* parent_infolist_window_;
60
61   // Views created in the class will be part of tree of |this|, so these
62   // child views will be deleted when |this| is deleted.
63
64   // The title label.
65   views::Label* title_label_;
66   // The description label.
67   views::Label* description_label_;
68   // Whether the item is selected.
69   bool selected_;
70   // The size of the area which contains the title and the description.
71   gfx::Size title_and_description_size_;
72
73   DISALLOW_COPY_AND_ASSIGN(InfolistEntryView);
74 };
75
76 InfolistEntryView::InfolistEntryView()
77     : title_label_(NULL),
78       description_label_(NULL),
79       selected_(false) {
80 }
81
82 void InfolistEntryView::Init(const gfx::Font& title_font,
83                              const gfx::Font& description_font) {
84   title_label_ = new views::Label;
85   title_label_->SetPosition(gfx::Point(0, 0));
86   title_label_->SetFont(title_font);
87   title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
88   title_label_->set_border(
89       views::Border::CreateEmptyBorder(4, 7, 2, 4));
90
91   description_label_ = new views::Label;
92   description_label_->SetPosition(gfx::Point(0, 0));
93   description_label_->SetFont(description_font);
94   description_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
95   description_label_->SetMultiLine(true);
96   description_label_->set_border(
97       views::Border::CreateEmptyBorder(2, 17, 4, 4));
98   AddChildView(title_label_);
99   AddChildView(description_label_);
100   UpdateLabelBackgroundColors();
101 }
102
103 void InfolistEntryView::Relayout(const InfolistWindowView::Entry& entry) {
104   const string16 title = UTF8ToUTF16(entry.title);
105   const string16 description = UTF8ToUTF16(entry.body);
106
107   if ((title_label_->text() == title) &&
108       (description_label_->text() == description)) {
109     return;
110   }
111
112   title_label_->SetText(title);
113   const gfx::Size title_size = title_label_->GetPreferredSize();
114   title_label_->SetSize(title_size);
115
116   description_label_->SetText(description);
117   description_label_->SizeToFit(200);
118   const gfx::Size description_size = description_label_->size();
119   description_label_->SetPosition(gfx::Point(0, title_size.height()));
120
121   title_and_description_size_ =
122       gfx::Size(200, description_size.height() + title_size.height());
123 }
124
125 void InfolistEntryView::Select() {
126   if (selected_)
127     return;
128   selected_ = true;
129   set_background(
130       views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
131           ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused)));
132   set_border(
133       views::Border::CreateSolidBorder(1, GetNativeTheme()->GetSystemColor(
134           ui::NativeTheme::kColorId_FocusedBorderColor)));
135   UpdateLabelBackgroundColors();
136 }
137
138 void InfolistEntryView::Unselect() {
139   if (!selected_)
140     return;
141   selected_ = false;
142   set_background(NULL);
143   set_border(views::Border::CreateEmptyBorder(1, 1, 1, 1));
144   UpdateLabelBackgroundColors();
145 }
146
147 void InfolistEntryView::UpdateLabelBackgroundColors() {
148   SkColor color = background() ?
149       background()->get_color() :
150       GetNativeTheme()->GetSystemColor(
151           ui::NativeTheme::kColorId_WindowBackground);
152   title_label_->SetBackgroundColor(color);
153   description_label_->SetBackgroundColor(color);
154 }
155
156 ///////////////////////////////////////////////////////////////////////////////
157 // InfolistWindowView
158
159 InfolistWindowView::InfolistWindowView()
160     : infolist_area_(new views::View),
161       title_font_(new gfx::Font(kJapaneseFontName, kFontSizeDelta + 15)),
162       description_font_(new gfx::Font(kJapaneseFontName, kFontSizeDelta + 11)) {
163 }
164
165 InfolistWindowView::~InfolistWindowView() {
166   infolist_area_->RemoveAllChildViews(false);
167 }
168
169 void InfolistWindowView::Init() {
170   set_background(
171       views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
172           ui::NativeTheme::kColorId_WindowBackground)));
173   set_border(
174       views::Border::CreateSolidBorder(1, GetNativeTheme()->GetSystemColor(
175           ui::NativeTheme::kColorId_MenuBorderColor)));
176
177   views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
178                                                   0, 0, 0);
179   SetLayoutManager(layout);  // |this| owns |layout|.
180
181   views::Label* caption_label = new views::Label;
182   caption_label->SetFont(caption_label->font().DeriveFont(kFontSizeDelta - 2));
183   caption_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
184   caption_label->SetText(
185       l10n_util::GetStringUTF16(IDS_INPUT_METHOD_INFOLIST_WINDOW_TITLE));
186   caption_label->SetEnabledColor(GetNativeTheme()->GetSystemColor(
187       ui::NativeTheme::kColorId_LabelEnabledColor));
188   caption_label->set_border(views::Border::CreateEmptyBorder(2, 2, 2, 2));
189   caption_label->set_background(views::Background::CreateSolidBackground(
190       color_utils::AlphaBlend(SK_ColorBLACK,
191                               GetNativeTheme()->GetSystemColor(
192                                   ui::NativeTheme::kColorId_WindowBackground),
193                               0x10)));
194   caption_label->SetBackgroundColor(caption_label->background()->get_color());
195
196   AddChildView(caption_label);
197   AddChildView(infolist_area_);
198 }
199
200 void InfolistWindowView::Relayout(const std::vector<Entry>& entries,
201                                   size_t focused_index) {
202   infolist_area_->RemoveAllChildViews(false);
203   if (entries.empty())
204     return;
205
206   for (size_t i = infolist_views_.size(); i < entries.size(); ++i) {
207     InfolistEntryView* infolist_row = new InfolistEntryView();
208     infolist_row->Init(*title_font_.get(), *description_font_.get());
209     infolist_views_.push_back(infolist_row);
210   }
211
212   views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
213                                                   0, 0, 0);
214   // |infolist_area_| owns |layout|.
215   infolist_area_->SetLayoutManager(layout);
216
217   for (size_t i = 0; i < entries.size(); ++i) {
218     InfolistEntryView* infolist_row = infolist_views_[i];
219     infolist_row->Relayout(entries[i]);
220     infolist_row->Unselect();
221     infolist_area_->AddChildView(infolist_row);
222   }
223   if (focused_index < infolist_views_.size())
224     infolist_views_[focused_index]->Select();
225   infolist_area_->SchedulePaint();
226 }
227
228 // static
229 const size_t InfolistWindowView::InvalidFocusIndex() {
230   return std::numeric_limits<size_t>::max();
231 }
232
233 }  // namespace input_method
234 }  // namespace chromeos