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