OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "chrome/browser/chromeos/input_method/candidate_window_view.h" | 4 #include "chrome/browser/chromeos/input_method/candidate_window_view.h" |
5 | 5 |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "chrome/browser/chromeos/input_method/candidate_view.h" | 9 #include "chrome/browser/chromeos/input_method/candidate_view.h" |
10 #include "chrome/browser/chromeos/input_method/candidate_window_constants.h" | 10 #include "chrome/browser/chromeos/input_method/candidate_window_constants.h" |
| 11 #include "chromeos/ime/candidate_window.h" |
11 #include "ui/gfx/color_utils.h" | 12 #include "ui/gfx/color_utils.h" |
12 #include "ui/gfx/screen.h" | 13 #include "ui/gfx/screen.h" |
13 #include "ui/native_theme/native_theme.h" | 14 #include "ui/native_theme/native_theme.h" |
14 #include "ui/views/background.h" | 15 #include "ui/views/background.h" |
15 #include "ui/views/border.h" | 16 #include "ui/views/border.h" |
16 #include "ui/views/bubble/bubble_frame_view.h" | 17 #include "ui/views/bubble/bubble_frame_view.h" |
17 #include "ui/views/controls/label.h" | 18 #include "ui/views/controls/label.h" |
18 #include "ui/views/corewm/window_animations.h" | 19 #include "ui/views/corewm/window_animations.h" |
19 #include "ui/views/layout/box_layout.h" | 20 #include "ui/views/layout/box_layout.h" |
20 #include "ui/views/layout/fill_layout.h" | 21 #include "ui/views/layout/fill_layout.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 | 68 |
68 gfx::NativeView parent_; | 69 gfx::NativeView parent_; |
69 int offset_; | 70 int offset_; |
70 | 71 |
71 DISALLOW_COPY_AND_ASSIGN(CandidateWindowBorder); | 72 DISALLOW_COPY_AND_ASSIGN(CandidateWindowBorder); |
72 }; | 73 }; |
73 | 74 |
74 // Computes the page index. For instance, if the page size is 9, and the | 75 // Computes the page index. For instance, if the page size is 9, and the |
75 // cursor is pointing to 13th candidate, the page index will be 1 (2nd | 76 // cursor is pointing to 13th candidate, the page index will be 1 (2nd |
76 // page, as the index is zero-origin). Returns -1 on error. | 77 // page, as the index is zero-origin). Returns -1 on error. |
77 int ComputePageIndex(const ui::CandidateWindow& candidate_window) { | 78 int ComputePageIndex(const CandidateWindow& candidate_window) { |
78 if (candidate_window.page_size() > 0) | 79 if (candidate_window.page_size() > 0) |
79 return candidate_window.cursor_position() / candidate_window.page_size(); | 80 return candidate_window.cursor_position() / candidate_window.page_size(); |
80 return -1; | 81 return -1; |
81 } | 82 } |
82 | 83 |
83 } // namespace | 84 } // namespace |
84 | 85 |
85 class InformationTextArea : public views::View { | 86 class InformationTextArea : public views::View { |
86 public: | 87 public: |
87 // InformationTextArea's border is drawn as a separator, it should appear | 88 // InformationTextArea's border is drawn as a separator, it should appear |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 1, theme->GetSystemColor(ui::NativeTheme::kColorId_MenuBorderColor))); | 157 1, theme->GetSystemColor(ui::NativeTheme::kColorId_MenuBorderColor))); |
157 | 158 |
158 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 159 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); |
159 auxiliary_text_ = new InformationTextArea(gfx::ALIGN_RIGHT, 0); | 160 auxiliary_text_ = new InformationTextArea(gfx::ALIGN_RIGHT, 0); |
160 preedit_ = new InformationTextArea(gfx::ALIGN_LEFT, kMinPreeditAreaWidth); | 161 preedit_ = new InformationTextArea(gfx::ALIGN_LEFT, kMinPreeditAreaWidth); |
161 candidate_area_ = new views::View; | 162 candidate_area_ = new views::View; |
162 auxiliary_text_->SetVisible(false); | 163 auxiliary_text_->SetVisible(false); |
163 preedit_->SetVisible(false); | 164 preedit_->SetVisible(false); |
164 candidate_area_->SetVisible(false); | 165 candidate_area_->SetVisible(false); |
165 preedit_->SetBorder(InformationTextArea::BOTTOM); | 166 preedit_->SetBorder(InformationTextArea::BOTTOM); |
166 if (candidate_window_.orientation() == ui::CandidateWindow::VERTICAL) { | 167 if (candidate_window_.orientation() == CandidateWindow::VERTICAL) { |
167 AddChildView(preedit_); | 168 AddChildView(preedit_); |
168 AddChildView(candidate_area_); | 169 AddChildView(candidate_area_); |
169 AddChildView(auxiliary_text_); | 170 AddChildView(auxiliary_text_); |
170 auxiliary_text_->SetBorder(InformationTextArea::TOP); | 171 auxiliary_text_->SetBorder(InformationTextArea::TOP); |
171 candidate_area_->SetLayoutManager(new views::BoxLayout( | 172 candidate_area_->SetLayoutManager(new views::BoxLayout( |
172 views::BoxLayout::kVertical, 0, 0, 0)); | 173 views::BoxLayout::kVertical, 0, 0, 0)); |
173 } else { | 174 } else { |
174 AddChildView(preedit_); | 175 AddChildView(preedit_); |
175 AddChildView(auxiliary_text_); | 176 AddChildView(auxiliary_text_); |
176 AddChildView(candidate_area_); | 177 AddChildView(candidate_area_); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 preedit_->SetText(utf8_text); | 225 preedit_->SetText(utf8_text); |
225 } | 226 } |
226 | 227 |
227 void CandidateWindowView::ShowLookupTable() { | 228 void CandidateWindowView::ShowLookupTable() { |
228 candidate_area_->SetVisible(true); | 229 candidate_area_->SetVisible(true); |
229 auxiliary_text_->SetVisible(candidate_window_.is_auxiliary_text_visible()); | 230 auxiliary_text_->SetVisible(candidate_window_.is_auxiliary_text_visible()); |
230 UpdateVisibility(); | 231 UpdateVisibility(); |
231 } | 232 } |
232 | 233 |
233 void CandidateWindowView::UpdateCandidates( | 234 void CandidateWindowView::UpdateCandidates( |
234 const ui::CandidateWindow& new_candidate_window) { | 235 const CandidateWindow& new_candidate_window) { |
235 // Updating the candidate views is expensive. We'll skip this if possible. | 236 // Updating the candidate views is expensive. We'll skip this if possible. |
236 if (!candidate_window_.IsEqual(new_candidate_window)) { | 237 if (!candidate_window_.IsEqual(new_candidate_window)) { |
237 if (candidate_window_.orientation() != new_candidate_window.orientation()) { | 238 if (candidate_window_.orientation() != new_candidate_window.orientation()) { |
238 // If the new layout is vertical, the aux text should appear at the | 239 // If the new layout is vertical, the aux text should appear at the |
239 // bottom. If horizontal, it should appear between preedit and candidates. | 240 // bottom. If horizontal, it should appear between preedit and candidates. |
240 if (new_candidate_window.orientation() == ui::CandidateWindow::VERTICAL) { | 241 if (new_candidate_window.orientation() == CandidateWindow::VERTICAL) { |
241 ReorderChildView(auxiliary_text_, -1); | 242 ReorderChildView(auxiliary_text_, -1); |
242 auxiliary_text_->SetAlignment(gfx::ALIGN_RIGHT); | 243 auxiliary_text_->SetAlignment(gfx::ALIGN_RIGHT); |
243 auxiliary_text_->SetBorder(InformationTextArea::TOP); | 244 auxiliary_text_->SetBorder(InformationTextArea::TOP); |
244 candidate_area_->SetLayoutManager(new views::BoxLayout( | 245 candidate_area_->SetLayoutManager(new views::BoxLayout( |
245 views::BoxLayout::kVertical, 0, 0, 0)); | 246 views::BoxLayout::kVertical, 0, 0, 0)); |
246 } else { | 247 } else { |
247 ReorderChildView(auxiliary_text_, 1); | 248 ReorderChildView(auxiliary_text_, 1); |
248 auxiliary_text_->SetAlignment(gfx::ALIGN_LEFT); | 249 auxiliary_text_->SetAlignment(gfx::ALIGN_LEFT); |
249 auxiliary_text_->SetBorder(InformationTextArea::BOTTOM); | 250 auxiliary_text_->SetBorder(InformationTextArea::BOTTOM); |
250 candidate_area_->SetLayoutManager(new views::BoxLayout( | 251 candidate_area_->SetLayoutManager(new views::BoxLayout( |
(...skipping 16 matching lines...) Expand all Loading... |
267 current_page_index * new_candidate_window.page_size(); | 268 current_page_index * new_candidate_window.page_size(); |
268 | 269 |
269 int max_shortcut_width = 0; | 270 int max_shortcut_width = 0; |
270 int max_candidate_width = 0; | 271 int max_candidate_width = 0; |
271 for (size_t i = 0; i < candidate_views_.size(); ++i) { | 272 for (size_t i = 0; i < candidate_views_.size(); ++i) { |
272 const size_t index_in_page = i; | 273 const size_t index_in_page = i; |
273 const size_t candidate_index = start_from + index_in_page; | 274 const size_t candidate_index = start_from + index_in_page; |
274 CandidateView* candidate_view = candidate_views_[index_in_page]; | 275 CandidateView* candidate_view = candidate_views_[index_in_page]; |
275 // Set the candidate text. | 276 // Set the candidate text. |
276 if (candidate_index < new_candidate_window.candidates().size()) { | 277 if (candidate_index < new_candidate_window.candidates().size()) { |
277 const ui::CandidateWindow::Entry& entry = | 278 const CandidateWindow::Entry& entry = |
278 new_candidate_window.candidates()[candidate_index]; | 279 new_candidate_window.candidates()[candidate_index]; |
279 candidate_view->SetEntry(entry); | 280 candidate_view->SetEntry(entry); |
280 candidate_view->SetState(views::Button::STATE_NORMAL); | 281 candidate_view->SetState(views::Button::STATE_NORMAL); |
281 candidate_view->SetInfolistIcon(!entry.description_title.empty()); | 282 candidate_view->SetInfolistIcon(!entry.description_title.empty()); |
282 } else { | 283 } else { |
283 // Disable the empty row. | 284 // Disable the empty row. |
284 candidate_view->SetEntry(ui::CandidateWindow::Entry()); | 285 candidate_view->SetEntry(CandidateWindow::Entry()); |
285 candidate_view->SetState(views::Button::STATE_DISABLED); | 286 candidate_view->SetState(views::Button::STATE_DISABLED); |
286 candidate_view->SetInfolistIcon(false); | 287 candidate_view->SetInfolistIcon(false); |
287 } | 288 } |
288 if (new_candidate_window.orientation() == ui::CandidateWindow::VERTICAL) { | 289 if (new_candidate_window.orientation() == CandidateWindow::VERTICAL) { |
289 int shortcut_width = 0; | 290 int shortcut_width = 0; |
290 int candidate_width = 0; | 291 int candidate_width = 0; |
291 candidate_views_[i]->GetPreferredWidths( | 292 candidate_views_[i]->GetPreferredWidths( |
292 &shortcut_width, &candidate_width); | 293 &shortcut_width, &candidate_width); |
293 max_shortcut_width = std::max(max_shortcut_width, shortcut_width); | 294 max_shortcut_width = std::max(max_shortcut_width, shortcut_width); |
294 max_candidate_width = std::max(max_candidate_width, candidate_width); | 295 max_candidate_width = std::max(max_candidate_width, candidate_width); |
295 } | 296 } |
296 } | 297 } |
297 if (new_candidate_window.orientation() == ui::CandidateWindow::VERTICAL) { | 298 if (new_candidate_window.orientation() == CandidateWindow::VERTICAL) { |
298 for (size_t i = 0; i < candidate_views_.size(); ++i) | 299 for (size_t i = 0; i < candidate_views_.size(); ++i) |
299 candidate_views_[i]->SetWidths(max_shortcut_width, max_candidate_width); | 300 candidate_views_[i]->SetWidths(max_shortcut_width, max_candidate_width); |
300 } | 301 } |
301 | 302 |
302 CandidateWindowBorder* border = static_cast<CandidateWindowBorder*>( | 303 CandidateWindowBorder* border = static_cast<CandidateWindowBorder*>( |
303 GetBubbleFrameView()->bubble_border()); | 304 GetBubbleFrameView()->bubble_border()); |
304 if (new_candidate_window.orientation() == ui::CandidateWindow::VERTICAL) | 305 if (new_candidate_window.orientation() == CandidateWindow::VERTICAL) |
305 border->set_offset(max_shortcut_width); | 306 border->set_offset(max_shortcut_width); |
306 else | 307 else |
307 border->set_offset(0); | 308 border->set_offset(0); |
308 } | 309 } |
309 // Update the current candidate window. We'll use candidate_window_ from here. | 310 // Update the current candidate window. We'll use candidate_window_ from here. |
310 // Note that SelectCandidateAt() uses candidate_window_. | 311 // Note that SelectCandidateAt() uses candidate_window_. |
311 candidate_window_.CopyFrom(new_candidate_window); | 312 candidate_window_.CopyFrom(new_candidate_window); |
312 | 313 |
313 // Select the current candidate in the page. | 314 // Select the current candidate in the page. |
314 if (candidate_window_.is_cursor_visible()) { | 315 if (candidate_window_.is_cursor_visible()) { |
(...skipping 20 matching lines...) Expand all Loading... |
335 | 336 |
336 void CandidateWindowView::SetCursorBounds(const gfx::Rect& cursor_bounds, | 337 void CandidateWindowView::SetCursorBounds(const gfx::Rect& cursor_bounds, |
337 const gfx::Rect& composition_head) { | 338 const gfx::Rect& composition_head) { |
338 if (candidate_window_.show_window_at_composition()) | 339 if (candidate_window_.show_window_at_composition()) |
339 SetAnchorRect(composition_head); | 340 SetAnchorRect(composition_head); |
340 else | 341 else |
341 SetAnchorRect(cursor_bounds); | 342 SetAnchorRect(cursor_bounds); |
342 } | 343 } |
343 | 344 |
344 void CandidateWindowView::MaybeInitializeCandidateViews( | 345 void CandidateWindowView::MaybeInitializeCandidateViews( |
345 const ui::CandidateWindow& candidate_window) { | 346 const CandidateWindow& candidate_window) { |
346 const ui::CandidateWindow::Orientation orientation = | 347 const CandidateWindow::Orientation orientation = |
347 candidate_window.orientation(); | 348 candidate_window.orientation(); |
348 const size_t page_size = candidate_window.page_size(); | 349 const size_t page_size = candidate_window.page_size(); |
349 | 350 |
350 // Reset all candidate_views_ when orientation changes. | 351 // Reset all candidate_views_ when orientation changes. |
351 if (orientation != candidate_window_.orientation()) | 352 if (orientation != candidate_window_.orientation()) |
352 STLDeleteElements(&candidate_views_); | 353 STLDeleteElements(&candidate_views_); |
353 | 354 |
354 while (page_size < candidate_views_.size()) { | 355 while (page_size < candidate_views_.size()) { |
355 delete candidate_views_.back(); | 356 delete candidate_views_.back(); |
356 candidate_views_.pop_back(); | 357 candidate_views_.pop_back(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 for (size_t i = 0; i < candidate_views_.size(); ++i) { | 393 for (size_t i = 0; i < candidate_views_.size(); ++i) { |
393 if (sender == candidate_views_[i]) { | 394 if (sender == candidate_views_[i]) { |
394 FOR_EACH_OBSERVER(Observer, observers_, OnCandidateCommitted(i)); | 395 FOR_EACH_OBSERVER(Observer, observers_, OnCandidateCommitted(i)); |
395 return; | 396 return; |
396 } | 397 } |
397 } | 398 } |
398 } | 399 } |
399 | 400 |
400 } // namespace input_method | 401 } // namespace input_method |
401 } // namespace chromeos | 402 } // namespace chromeos |
OLD | NEW |