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

Side by Side Diff: ui/chromeos/ime/candidate_view.cc

Issue 727143002: Moves code from chromeos/ime to ui/base/ime/chromeos. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nit Created 6 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "base/strings/utf_string_conversions.h"
6 #include "ui/base/ime/candidate_window.h"
7 #include "ui/chromeos/ime/candidate_view.h"
8 #include "ui/chromeos/ime/candidate_window_constants.h"
9 #include "ui/gfx/color_utils.h"
10 #include "ui/native_theme/native_theme.h"
11 #include "ui/views/background.h"
12 #include "ui/views/border.h"
13 #include "ui/views/controls/label.h"
14 #include "ui/views/widget/widget.h"
15
16 namespace ui {
17 namespace ime {
18
19 namespace {
20
21 // VerticalCandidateLabel is used for rendering candidate text in
22 // the vertical candidate window.
23 class VerticalCandidateLabel : public views::Label {
24 public:
25 VerticalCandidateLabel() {}
26
27 private:
28 ~VerticalCandidateLabel() override {}
29
30 // Returns the preferred size, but guarantees that the width has at
31 // least kMinCandidateLabelWidth pixels.
32 gfx::Size GetPreferredSize() const override {
33 gfx::Size size = Label::GetPreferredSize();
34 size.SetToMax(gfx::Size(kMinCandidateLabelWidth, 0));
35 size.SetToMin(gfx::Size(kMaxCandidateLabelWidth, size.height()));
36 return size;
37 }
38
39 DISALLOW_COPY_AND_ASSIGN(VerticalCandidateLabel);
40 };
41
42 // Creates the shortcut label, and returns it (never returns NULL).
43 // The label text is not set in this function.
44 views::Label* CreateShortcutLabel(
45 ui::CandidateWindow::Orientation orientation,
46 const ui::NativeTheme& theme) {
47 // Create the shortcut label. The label will be owned by
48 // |wrapped_shortcut_label|, hence it's deleted when
49 // |wrapped_shortcut_label| is deleted.
50 views::Label* shortcut_label = new views::Label;
51
52 if (orientation == ui::CandidateWindow::VERTICAL) {
53 shortcut_label->SetFontList(
54 shortcut_label->font_list().Derive(kFontSizeDelta, gfx::Font::BOLD));
55 } else {
56 shortcut_label->SetFontList(
57 shortcut_label->font_list().DeriveWithSizeDelta(kFontSizeDelta));
58 }
59 // TODO(satorux): Maybe we need to use language specific fonts for
60 // candidate_label, like Chinese font for Chinese input method?
61 shortcut_label->SetEnabledColor(theme.GetSystemColor(
62 ui::NativeTheme::kColorId_LabelEnabledColor));
63 shortcut_label->SetDisabledColor(theme.GetSystemColor(
64 ui::NativeTheme::kColorId_LabelDisabledColor));
65
66 // Setup paddings.
67 const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6);
68 const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0);
69 const gfx::Insets insets =
70 (orientation == ui::CandidateWindow::VERTICAL ?
71 kVerticalShortcutLabelInsets :
72 kHorizontalShortcutLabelInsets);
73 shortcut_label->SetBorder(views::Border::CreateEmptyBorder(
74 insets.top(), insets.left(), insets.bottom(), insets.right()));
75
76 // Add decoration based on the orientation.
77 if (orientation == ui::CandidateWindow::VERTICAL) {
78 // Set the background color.
79 SkColor blackish = color_utils::AlphaBlend(
80 SK_ColorBLACK,
81 theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground),
82 0x40);
83 SkColor transparent_blakish = color_utils::AlphaBlend(
84 SK_ColorTRANSPARENT, blackish, 0xE0);
85 shortcut_label->set_background(
86 views::Background::CreateSolidBackground(transparent_blakish));
87 }
88
89 return shortcut_label;
90 }
91
92 // Creates the candidate label, and returns it (never returns NULL).
93 // The label text is not set in this function.
94 views::Label* CreateCandidateLabel(
95 ui::CandidateWindow::Orientation orientation) {
96 views::Label* candidate_label = NULL;
97
98 // Create the candidate label. The label will be added to |this| as a
99 // child view, hence it's deleted when |this| is deleted.
100 if (orientation == ui::CandidateWindow::VERTICAL) {
101 candidate_label = new VerticalCandidateLabel;
102 } else {
103 candidate_label = new views::Label;
104 }
105
106 // Change the font size.
107 candidate_label->SetFontList(
108 candidate_label->font_list().DeriveWithSizeDelta(kFontSizeDelta));
109 candidate_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
110
111 return candidate_label;
112 }
113
114 // Creates the annotation label, and return it (never returns NULL).
115 // The label text is not set in this function.
116 views::Label* CreateAnnotationLabel(
117 ui::CandidateWindow::Orientation orientation,
118 const ui::NativeTheme& theme) {
119 // Create the annotation label.
120 views::Label* annotation_label = new views::Label;
121
122 // Change the font size and color.
123 annotation_label->SetFontList(
124 annotation_label->font_list().DeriveWithSizeDelta(kFontSizeDelta));
125 annotation_label->SetEnabledColor(theme.GetSystemColor(
126 ui::NativeTheme::kColorId_LabelDisabledColor));
127 annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
128
129 return annotation_label;
130 }
131
132 } // namespace
133
134 CandidateView::CandidateView(
135 views::ButtonListener* listener,
136 ui::CandidateWindow::Orientation orientation)
137 : views::CustomButton(listener),
138 orientation_(orientation),
139 shortcut_label_(NULL),
140 candidate_label_(NULL),
141 annotation_label_(NULL),
142 infolist_icon_(NULL),
143 shortcut_width_(0),
144 candidate_width_(0),
145 highlighted_(false) {
146 SetBorder(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 == ui::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 ui::CandidateWindow::Entry& entry) {
179 base::string16 label = entry.label;
180 if (!label.empty() && orientation_ != ui::CandidateWindow::VERTICAL)
181 label += base::ASCIIToUTF16(".");
182 shortcut_label_->SetText(label);
183 candidate_label_->SetText(entry.value);
184 annotation_label_->SetText(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::SetHighlighted(bool highlighted) {
194 if (highlighted_ == highlighted)
195 return;
196
197 highlighted_ = highlighted;
198 if (highlighted) {
199 ui::NativeTheme* theme = GetNativeTheme();
200 set_background(
201 views::Background::CreateSolidBackground(theme->GetSystemColor(
202 ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused)));
203 SetBorder(views::Border::CreateSolidBorder(
204 1,
205 theme->GetSystemColor(ui::NativeTheme::kColorId_FocusedBorderColor)));
206
207 // Cancel currently focused one.
208 for (int i = 0; i < parent()->child_count(); ++i) {
209 CandidateView* view =
210 static_cast<CandidateView*>((parent()->child_at(i)));
211 if (view != this)
212 view->SetHighlighted(false);
213 }
214 } else {
215 set_background(NULL);
216 SetBorder(views::Border::CreateEmptyBorder(1, 1, 1, 1));
217 }
218 SchedulePaint();
219 }
220
221 void CandidateView::StateChanged() {
222 shortcut_label_->SetEnabled(state() != STATE_DISABLED);
223 if (state() == STATE_PRESSED)
224 SetHighlighted(true);
225 }
226
227 bool CandidateView::OnMouseDragged(const ui::MouseEvent& event) {
228 if (!HitTestPoint(event.location())) {
229 // Moves the drag target to the sibling view.
230 gfx::Point location_in_widget(event.location());
231 ConvertPointToWidget(this, &location_in_widget);
232 for (int i = 0; i < parent()->child_count(); ++i) {
233 CandidateView* sibling =
234 static_cast<CandidateView*>(parent()->child_at(i));
235 if (sibling == this)
236 continue;
237 gfx::Point location_in_sibling(location_in_widget);
238 ConvertPointFromWidget(sibling, &location_in_sibling);
239 if (sibling->HitTestPoint(location_in_sibling)) {
240 GetWidget()->GetRootView()->SetMouseHandler(sibling);
241 sibling->SetHighlighted(true);
242 return sibling->OnMouseDragged(ui::MouseEvent(event, this, sibling));
243 }
244 }
245
246 return false;
247 }
248
249 return views::CustomButton::OnMouseDragged(event);
250 }
251
252 void CandidateView::Layout() {
253 const int padding_width =
254 orientation_ == ui::CandidateWindow::VERTICAL ? 4 : 6;
255 int x = 0;
256 shortcut_label_->SetBounds(x, 0, shortcut_width_, height());
257 if (shortcut_width_ > 0)
258 x += shortcut_width_ + padding_width;
259 candidate_label_->SetBounds(x, 0, candidate_width_, height());
260 x += candidate_width_ + padding_width;
261
262 int right = bounds().right();
263 if (infolist_icon_ && infolist_icon_->visible()) {
264 infolist_icon_->SetBounds(
265 right - kInfolistIndicatorIconWidth - kInfolistIndicatorIconPadding,
266 kInfolistIndicatorIconPadding,
267 kInfolistIndicatorIconWidth,
268 height() - kInfolistIndicatorIconPadding * 2);
269 right -= kInfolistIndicatorIconWidth + kInfolistIndicatorIconPadding * 2;
270 }
271 annotation_label_->SetBounds(x, 0, right - x, height());
272 }
273
274 gfx::Size CandidateView::GetPreferredSize() const {
275 const int padding_width =
276 orientation_ == ui::CandidateWindow::VERTICAL ? 4 : 6;
277 gfx::Size size;
278 if (shortcut_label_->visible()) {
279 size = shortcut_label_->GetPreferredSize();
280 size.SetToMax(gfx::Size(shortcut_width_, 0));
281 size.Enlarge(padding_width, 0);
282 }
283 gfx::Size candidate_size = candidate_label_->GetPreferredSize();
284 candidate_size.SetToMax(gfx::Size(candidate_width_, 0));
285 size.Enlarge(candidate_size.width() + padding_width, 0);
286 size.SetToMax(candidate_size);
287 if (annotation_label_->visible()) {
288 gfx::Size annotation_size = annotation_label_->GetPreferredSize();
289 size.Enlarge(annotation_size.width() + padding_width, 0);
290 size.SetToMax(annotation_size);
291 }
292
293 // Reserves the margin for infolist_icon even if it's not visible.
294 size.Enlarge(
295 kInfolistIndicatorIconWidth + kInfolistIndicatorIconPadding * 2, 0);
296 return size;
297 }
298
299 } // namespace ime
300 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698