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"
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"
27 namespace input_method
{
29 // InfolistRow renderes a row of a infolist.
30 class InfolistEntryView
: public views::View
{
33 virtual ~InfolistEntryView() {}
35 void Init(const gfx::Font
& title_font
, const gfx::Font
& description_font
);
37 // Sets title text and description text.
38 void Relayout(const InfolistWindowView::Entry
& entry
);
40 // Selects the infolist row. Changes the appearance to make it look
41 // like a selected candidate.
44 // Unselects the infolist row. Changes the appearance to make it look
45 // like an unselected candidate.
49 virtual gfx::Size
GetPreferredSize() OVERRIDE
{
50 return title_and_description_size_
;
54 // Notifies labels of their new background colors. Called whenever the view's
55 // background color changes.
56 void UpdateLabelBackgroundColors();
58 // The parent candidate window that contains this view.
59 InfolistWindowView
* parent_infolist_window_
;
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.
65 views::Label
* title_label_
;
66 // The description label.
67 views::Label
* description_label_
;
68 // Whether the item is selected.
70 // The size of the area which contains the title and the description.
71 gfx::Size title_and_description_size_
;
73 DISALLOW_COPY_AND_ASSIGN(InfolistEntryView
);
76 InfolistEntryView::InfolistEntryView()
78 description_label_(NULL
),
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));
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();
103 void InfolistEntryView::Relayout(const InfolistWindowView::Entry
& entry
) {
104 const string16 title
= UTF8ToUTF16(entry
.title
);
105 const string16 description
= UTF8ToUTF16(entry
.body
);
107 if ((title_label_
->text() == title
) &&
108 (description_label_
->text() == description
)) {
112 title_label_
->SetText(title
);
113 const gfx::Size title_size
= title_label_
->GetPreferredSize();
114 title_label_
->SetSize(title_size
);
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()));
121 title_and_description_size_
=
122 gfx::Size(200, description_size
.height() + title_size
.height());
125 void InfolistEntryView::Select() {
130 views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
131 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused
)));
133 views::Border::CreateSolidBorder(1, GetNativeTheme()->GetSystemColor(
134 ui::NativeTheme::kColorId_FocusedBorderColor
)));
135 UpdateLabelBackgroundColors();
138 void InfolistEntryView::Unselect() {
142 set_background(NULL
);
143 set_border(views::Border::CreateEmptyBorder(1, 1, 1, 1));
144 UpdateLabelBackgroundColors();
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
);
156 ///////////////////////////////////////////////////////////////////////////////
157 // InfolistWindowView
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)) {
165 InfolistWindowView::~InfolistWindowView() {
166 infolist_area_
->RemoveAllChildViews(false);
169 void InfolistWindowView::Init() {
171 views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
172 ui::NativeTheme::kColorId_WindowBackground
)));
174 views::Border::CreateSolidBorder(1, GetNativeTheme()->GetSystemColor(
175 ui::NativeTheme::kColorId_MenuBorderColor
)));
177 views::BoxLayout
* layout
= new views::BoxLayout(views::BoxLayout::kVertical
,
179 SetLayoutManager(layout
); // |this| owns |layout|.
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
),
194 caption_label
->SetBackgroundColor(caption_label
->background()->get_color());
196 AddChildView(caption_label
);
197 AddChildView(infolist_area_
);
200 void InfolistWindowView::Relayout(const std::vector
<Entry
>& entries
,
201 size_t focused_index
) {
202 infolist_area_
->RemoveAllChildViews(false);
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
);
212 views::BoxLayout
* layout
= new views::BoxLayout(views::BoxLayout::kVertical
,
214 // |infolist_area_| owns |layout|.
215 infolist_area_
->SetLayoutManager(layout
);
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
);
223 if (focused_index
< infolist_views_
.size())
224 infolist_views_
[focused_index
]->Select();
225 infolist_area_
->SchedulePaint();
229 const size_t InfolistWindowView::InvalidFocusIndex() {
230 return std::numeric_limits
<size_t>::max();
233 } // namespace input_method
234 } // namespace chromeos