Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: chrome/browser/chromeos/input_method/candidate_view.cc

Issue 121163003: Cleanup CandidateWindowView. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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 "chrome/browser/chromeos/input_method/candidate_view.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/chromeos/input_method/candidate_window_constants.h"
9 #include "chromeos/ime/candidate_window.h"
10 #include "ui/gfx/color_utils.h"
11 #include "ui/native_theme/native_theme.h"
12 #include "ui/views/background.h"
13 #include "ui/views/border.h"
14 #include "ui/views/controls/label.h"
15 #include "ui/views/widget/widget.h"
16
17 namespace chromeos {
18 namespace input_method {
19
20 namespace {
21
22 // VerticalCandidateLabel is used for rendering candidate text in
23 // the vertical candidate window.
24 class VerticalCandidateLabel : public views::Label {
25 public:
26 VerticalCandidateLabel() {}
27
28 private:
29 virtual ~VerticalCandidateLabel() {}
30
31 // Returns the preferred size, but guarantees that the width has at
32 // least kMinCandidateLabelWidth pixels.
33 virtual gfx::Size GetPreferredSize() OVERRIDE {
34 gfx::Size size = Label::GetPreferredSize();
35 size.SetToMax(gfx::Size(kMinCandidateLabelWidth, 0));
36 size.SetToMin(gfx::Size(kMaxCandidateLabelWidth, size.height()));
37 return size;
38 }
39
40 DISALLOW_COPY_AND_ASSIGN(VerticalCandidateLabel);
41 };
42
43 // Creates the shortcut label, and returns it (never returns NULL).
44 // The label text is not set in this function.
45 views::Label* CreateShortcutLabel(
46 CandidateWindow::Orientation orientation,
47 const ui::NativeTheme& theme) {
48 // Create the shortcut label. The label will be owned by
49 // |wrapped_shortcut_label|, hence it's deleted when
50 // |wrapped_shortcut_label| is deleted.
51 views::Label* shortcut_label = new views::Label;
52
53 if (orientation == CandidateWindow::VERTICAL) {
54 shortcut_label->SetFontList(
55 shortcut_label->font_list().DeriveFontListWithSizeDeltaAndStyle(
56 kFontSizeDelta, gfx::Font::BOLD));
57 } else {
58 shortcut_label->SetFontList(
59 shortcut_label->font_list().DeriveFontListWithSizeDelta(
60 kFontSizeDelta));
61 }
62 // TODO(satorux): Maybe we need to use language specific fonts for
63 // candidate_label, like Chinese font for Chinese input method?
64 shortcut_label->SetEnabledColor(theme.GetSystemColor(
65 ui::NativeTheme::kColorId_LabelEnabledColor));
66 shortcut_label->SetDisabledColor(theme.GetSystemColor(
67 ui::NativeTheme::kColorId_LabelDisabledColor));
68
69 // Setup paddings.
70 const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6);
71 const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0);
72 const gfx::Insets insets =
73 (orientation == CandidateWindow::VERTICAL ?
74 kVerticalShortcutLabelInsets :
75 kHorizontalShortcutLabelInsets);
76 shortcut_label->set_border(views::Border::CreateEmptyBorder(
77 insets.top(), insets.left(), insets.bottom(), insets.right()));
78
79 // Add decoration based on the orientation.
80 if (orientation == CandidateWindow::VERTICAL) {
81 // Set the background color.
82 SkColor blackish = color_utils::AlphaBlend(
83 SK_ColorBLACK,
84 theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground),
85 0x40);
86 SkColor transparent_blakish = color_utils::AlphaBlend(
87 SK_ColorTRANSPARENT, blackish, 0xE0);
88 shortcut_label->set_background(
89 views::Background::CreateSolidBackground(transparent_blakish));
90 }
91
92 return shortcut_label;
93 }
94
95 // Creates the candidate label, and returns it (never returns NULL).
96 // The label text is not set in this function.
97 views::Label* CreateCandidateLabel(
98 CandidateWindow::Orientation orientation) {
99 views::Label* candidate_label = NULL;
100
101 // Create the candidate label. The label will be added to |this| as a
102 // child view, hence it's deleted when |this| is deleted.
103 if (orientation == CandidateWindow::VERTICAL) {
104 candidate_label = new VerticalCandidateLabel;
105 } else {
106 candidate_label = new views::Label;
107 }
108
109 // Change the font size.
110 candidate_label->SetFontList(
111 candidate_label->font_list().DeriveFontListWithSizeDelta(kFontSizeDelta));
112 candidate_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
113
114 return candidate_label;
115 }
116
117 // Creates the annotation label, and return it (never returns NULL).
118 // The label text is not set in this function.
119 views::Label* CreateAnnotationLabel(
120 CandidateWindow::Orientation orientation, const ui::NativeTheme& theme) {
121 // Create the annotation label.
122 views::Label* annotation_label = new views::Label;
123
124 // Change the font size and color.
125 annotation_label->SetFontList(
126 annotation_label->font_list().DeriveFontListWithSizeDelta(
127 kFontSizeDelta));
128 annotation_label->SetEnabledColor(theme.GetSystemColor(
129 ui::NativeTheme::kColorId_LabelDisabledColor));
130 annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
131
132 return annotation_label;
133 }
134
135 } // namespace
136
137 CandidateView::CandidateView(
138 views::ButtonListener* listener,
139 CandidateWindow::Orientation orientation)
140 : views::CustomButton(listener),
141 orientation_(orientation),
142 shortcut_label_(NULL),
143 candidate_label_(NULL),
144 annotation_label_(NULL),
145 infolist_icon_(NULL) {
146 set_border(views::Border::CreateEmptyBorder(1, 1, 1, 1));
147
148 const ui::NativeTheme& theme = *GetNativeTheme();
149 shortcut_label_ = CreateShortcutLabel(orientation, theme);
150 candidate_label_ = CreateCandidateLabel(orientation);
151 annotation_label_ = CreateAnnotationLabel(orientation, theme);
152
153 AddChildView(shortcut_label_);
154 AddChildView(candidate_label_);
155 AddChildView(annotation_label_);
156
157 if (orientation == CandidateWindow::VERTICAL) {
158 infolist_icon_ = new views::View;
159 infolist_icon_->set_background(
160 views::Background::CreateSolidBackground(theme.GetSystemColor(
161 ui::NativeTheme::kColorId_FocusedBorderColor)));
162 AddChildView(infolist_icon_);
163 }
164 }
165
166 void CandidateView::GetPreferredWidths(int* shortcut_width,
167 int* candidate_width) {
168 *shortcut_width = shortcut_label_->GetPreferredSize().width();
169 *candidate_width = candidate_label_->GetPreferredSize().width();
170 }
171
172 void CandidateView::SetWidths(int shortcut_width, int candidate_width) {
173 shortcut_width_ = shortcut_width;
174 shortcut_label_->SetVisible(shortcut_width_ != 0);
175 candidate_width_ = candidate_width;
176 }
177
178 void CandidateView::SetEntry(const CandidateWindow::Entry& entry) {
179 std::string label = entry.label;
180 if (!label.empty() && orientation_ != CandidateWindow::VERTICAL)
181 label += '.';
182 shortcut_label_->SetText(base::UTF8ToUTF16(label));
183 candidate_label_->SetText(base::UTF8ToUTF16(entry.value));
184 annotation_label_->SetText(base::UTF8ToUTF16(entry.annotation));
185 }
186
187 void CandidateView::SetInfolistIcon(bool enable) {
188 if (infolist_icon_)
189 infolist_icon_->SetVisible(enable);
190 SchedulePaint();
191 }
192
193 void CandidateView::StateChanged() {
194 shortcut_label_->SetEnabled(state() != STATE_DISABLED);
195 if (state() == STATE_PRESSED) {
196 ui::NativeTheme* theme = GetNativeTheme();
197 set_background(
198 views::Background::CreateSolidBackground(theme->GetSystemColor(
199 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused)));
200 set_border(views::Border::CreateSolidBorder(
201 1, theme->GetSystemColor(
202 ui::NativeTheme::kColorId_FocusedBorderColor)));
203
204 // Cancel currently focused one.
205 for (int i = 0; i < parent()->child_count(); ++i) {
206 CandidateView* view =
207 static_cast<CandidateView*>((parent()->child_at(i)));
208 if (view != this && view->state() == STATE_PRESSED)
209 view->SetState(STATE_NORMAL);
210 }
211 } else {
212 set_background(NULL);
213 set_border(views::Border::CreateEmptyBorder(1, 1, 1, 1));
214 }
215 }
216
217 bool CandidateView::OnMouseDragged(const ui::MouseEvent& event) {
218 if (!HitTestPoint(event.location())) {
219 // Moves the drag target to the sibling view.
220 gfx::Point location_in_widget(event.location());
221 ConvertPointToWidget(this, &location_in_widget);
222 for (int i = 0; i < parent()->child_count(); ++i) {
223 views::View* sibling = parent()->child_at(i);
224 if (sibling == this)
225 continue;
226 gfx::Point location_in_sibling(location_in_widget);
227 ConvertPointFromWidget(sibling, &location_in_sibling);
228 if (sibling->HitTestPoint(location_in_sibling)) {
229 GetWidget()->GetRootView()->SetMouseHandler(sibling);
230 return sibling->OnMouseDragged(event);
231 }
232 }
233
234 return false;
235 }
236
237 return views::CustomButton::OnMouseDragged(event);
238 }
239
240 void CandidateView::Layout() {
241 const int padding_width =
242 orientation_ == CandidateWindow::VERTICAL ? 4 : 6;
243 int x = 0;
244 shortcut_label_->SetBounds(x, 0, shortcut_width_, height());
245 if (shortcut_width_ > 0)
246 x += shortcut_width_ + padding_width;
247 candidate_label_->SetBounds(x, 0, candidate_width_, height());
248 x += candidate_width_ + padding_width;
249
250 int right = bounds().right();
251 if (infolist_icon_ && infolist_icon_->visible()) {
252 infolist_icon_->SetBounds(
253 right - kInfolistIndicatorIconWidth - kInfolistIndicatorIconPadding,
254 kInfolistIndicatorIconPadding,
255 kInfolistIndicatorIconWidth,
256 height() - kInfolistIndicatorIconPadding * 2);
257 right -= kInfolistIndicatorIconWidth + kInfolistIndicatorIconPadding * 2;
258 }
259 annotation_label_->SetBounds(x, 0, right - x, height());
260 }
261
262 gfx::Size CandidateView::GetPreferredSize() {
263 const int padding_width =
264 orientation_ == CandidateWindow::VERTICAL ? 4 : 6;
265 gfx::Size size;
266 if (shortcut_label_->visible()) {
267 size = shortcut_label_->GetPreferredSize();
268 size.Enlarge(padding_width, 0);
269 }
270 gfx::Size candidate_size = candidate_label_->GetPreferredSize();
271 size.Enlarge(candidate_size.width() + padding_width, 0);
272 size.SetToMax(candidate_size);
273 if (annotation_label_->visible()) {
274 gfx::Size annotation_size = annotation_label_->GetPreferredSize();
275 size.Enlarge(annotation_size.width() + padding_width, 0);
276 size.SetToMax(annotation_size);
277 }
278
279 // Reserves the margin for infolist_icon even if it's not visible.
280 size.Enlarge(
281 kInfolistIndicatorIconWidth + kInfolistIndicatorIconPadding * 2, 0);
282 return size;
283 }
284
285 } // namespace input_method
286 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698