OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 // | 4 // |
5 // TODO(satorux): | 5 // TODO(satorux): |
6 // - Implement a horizontal candidate window. | 6 // - Implement a horizontal candidate window. |
7 // - Implement a scroll bar or an indicator showing where you are in the | 7 // - Implement a scroll bar or an indicator showing where you are in the |
8 // candidate window. | 8 // candidate window. |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 // Resizes the parent frame and schedules painting. This needs to be | 156 // Resizes the parent frame and schedules painting. This needs to be |
157 // called when the visible contents of the candidate window are | 157 // called when the visible contents of the candidate window are |
158 // modified. | 158 // modified. |
159 void ResizeAndSchedulePaint(); | 159 void ResizeAndSchedulePaint(); |
160 | 160 |
161 // The orientation of the candidate window. | 161 // The orientation of the candidate window. |
162 Orientation orientation_; | 162 Orientation orientation_; |
163 | 163 |
164 // The lookup table (candidates). | 164 // The lookup table (candidates). |
165 ImeLookupTable lookup_table_; | 165 ImeLookupTable lookup_table_; |
| 166 |
| 167 // Zero-origin index of the current page. If the cursor is on the first |
| 168 // page, the value will be 0. |
| 169 int current_page_index_; |
| 170 |
166 // The index in the current page of the candidate currently being selected. | 171 // The index in the current page of the candidate currently being selected. |
167 int selected_candidate_index_in_page_; | 172 int selected_candidate_index_in_page_; |
| 173 |
168 // The observers of the object. | 174 // The observers of the object. |
169 ObserverList<Observer> observers_; | 175 ObserverList<Observer> observers_; |
170 | 176 |
171 // The parent frame. | 177 // The parent frame. |
172 views::Widget* parent_frame_; | 178 views::Widget* parent_frame_; |
173 | 179 |
174 // Views created in the class will be part of tree of |this|, so these | 180 // Views created in the class will be part of tree of |this|, so these |
175 // child views will be deleted when |this| is deleted. | 181 // child views will be deleted when |this| is deleted. |
176 | 182 |
177 // The candidate area is where candidates are rendered. | 183 // The candidate area is where candidates are rendered. |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 bool canceled) { | 456 bool canceled) { |
451 // Commit the current candidate unless it's canceled. | 457 // Commit the current candidate unless it's canceled. |
452 if (!canceled) { | 458 if (!canceled) { |
453 parent_candidate_window_->CommitCandidate(); | 459 parent_candidate_window_->CommitCandidate(); |
454 } | 460 } |
455 } | 461 } |
456 | 462 |
457 CandidateWindowView::CandidateWindowView( | 463 CandidateWindowView::CandidateWindowView( |
458 views::Widget* parent_frame) | 464 views::Widget* parent_frame) |
459 : orientation_(kVertical), | 465 : orientation_(kVertical), |
| 466 current_page_index_(0), |
460 selected_candidate_index_in_page_(0), | 467 selected_candidate_index_in_page_(0), |
461 parent_frame_(parent_frame), | 468 parent_frame_(parent_frame), |
462 candidate_area_(NULL), | 469 candidate_area_(NULL), |
463 footer_area_(NULL), | 470 footer_area_(NULL), |
464 header_area_(NULL), | 471 header_area_(NULL), |
465 auxiliary_text_label_(NULL), | 472 auxiliary_text_label_(NULL), |
466 footer_label_(NULL) { | 473 footer_label_(NULL) { |
467 } | 474 } |
468 | 475 |
469 void CandidateWindowView::Init() { | 476 void CandidateWindowView::Init() { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 Orientation orientation = kVertical; | 533 Orientation orientation = kVertical; |
527 if (lookup_table.page_size == 5) { | 534 if (lookup_table.page_size == 5) { |
528 orientation = kHorizontal; | 535 orientation = kHorizontal; |
529 } | 536 } |
530 // Initialize candidate views if necessary. | 537 // Initialize candidate views if necessary. |
531 MaybeInitializeCandidateViews(lookup_table.page_size, | 538 MaybeInitializeCandidateViews(lookup_table.page_size, |
532 orientation); | 539 orientation); |
533 lookup_table_ = lookup_table; | 540 lookup_table_ = lookup_table; |
534 orientation_ = orientation; | 541 orientation_ = orientation; |
535 | 542 |
| 543 // Compute the index of the current page. |
| 544 current_page_index_ = |
| 545 lookup_table.cursor_absolute_index / lookup_table.page_size; |
| 546 |
536 // Update the candidates in the current page. | 547 // Update the candidates in the current page. |
537 const int start_from = (lookup_table_.current_page_index * | 548 const int start_from = current_page_index_ * lookup_table.page_size; |
538 lookup_table_.page_size); | 549 |
539 for (size_t i = 0; i < candidate_views_.size(); ++i) { | 550 for (size_t i = 0; i < candidate_views_.size(); ++i) { |
540 const size_t index_in_page = i; | 551 const size_t index_in_page = i; |
541 const size_t candidate_index = start_from + index_in_page; | 552 const size_t candidate_index = start_from + index_in_page; |
542 if (candidate_index < lookup_table_.candidates.size()) { | 553 if (candidate_index < lookup_table_.candidates.size()) { |
543 candidate_views_[index_in_page]->SetCandidateText( | 554 candidate_views_[index_in_page]->SetCandidateText( |
544 UTF8ToWide(lookup_table_.candidates[candidate_index])); | 555 UTF8ToWide(lookup_table_.candidates[candidate_index])); |
545 } else { | 556 } else { |
546 // Disable the empty row. | 557 // Disable the empty row. |
547 candidate_views_[index_in_page]->Disable(); | 558 candidate_views_[index_in_page]->Disable(); |
548 } | 559 } |
549 } | 560 } |
550 | 561 |
551 // Select the current candidate per the lookup table. | 562 // Select the first candidate candidate in the page. |
552 // TODO(satorux): Rename cursor_row_index to cursor_index_in_page. | 563 const int first_candidate_in_page = |
553 SelectCandidateAt(lookup_table_.cursor_row_index); | 564 lookup_table.cursor_absolute_index % lookup_table.page_size; |
| 565 SelectCandidateAt(first_candidate_in_page); |
554 } | 566 } |
555 | 567 |
556 void CandidateWindowView::MaybeInitializeCandidateViews( | 568 void CandidateWindowView::MaybeInitializeCandidateViews( |
557 int num_views, | 569 int num_views, |
558 Orientation orientation) { | 570 Orientation orientation) { |
559 // If the requested number of views matches the number of current views, | 571 // If the requested number of views matches the number of current views, |
560 // just reuse these. | 572 // just reuse these. |
561 if (num_views == static_cast<int>(candidate_views_.size()) && | 573 if (num_views == static_cast<int>(candidate_views_.size()) && |
562 orientation == orientation_) { | 574 orientation == orientation_) { |
563 return; | 575 return; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 kFooterBottomColor)); | 682 kFooterBottomColor)); |
671 | 683 |
672 views::View* footer_area = new views::View; | 684 views::View* footer_area = new views::View; |
673 footer_area->SetLayoutManager(new views::FillLayout); | 685 footer_area->SetLayoutManager(new views::FillLayout); |
674 // Initialize the footer area with the place holder (i.e. show nothing). | 686 // Initialize the footer area with the place holder (i.e. show nothing). |
675 footer_area->AddChildView(footer_area_place_holder_.get()); | 687 footer_area->AddChildView(footer_area_place_holder_.get()); |
676 return footer_area; | 688 return footer_area; |
677 } | 689 } |
678 | 690 |
679 void CandidateWindowView::SelectCandidateAt(int index_in_page) { | 691 void CandidateWindowView::SelectCandidateAt(int index_in_page) { |
| 692 int cursor_absolute_index = |
| 693 lookup_table_.page_size * current_page_index_ + index_in_page; |
680 // Ignore click on out of range views. | 694 // Ignore click on out of range views. |
681 if (index_in_page >= lookup_table_.num_candidates_in_current_page) { | 695 if (cursor_absolute_index < 0 || |
| 696 cursor_absolute_index >= |
| 697 static_cast<int>(lookup_table_.candidates.size())) { |
682 return; | 698 return; |
683 } | 699 } |
684 | 700 |
685 // Remember the currently selected candidate index in the current page. | 701 // Remember the currently selected candidate index in the current page. |
686 selected_candidate_index_in_page_ = index_in_page; | 702 selected_candidate_index_in_page_ = index_in_page; |
687 | 703 |
688 // Unselect all the candidate first. Theoretically, we could remember | 704 // Unselect all the candidate first. Theoretically, we could remember |
689 // the lastly selected candidate and only unselect it, but unselecting | 705 // the lastly selected candidate and only unselect it, but unselecting |
690 // everything is simpler. | 706 // everything is simpler. |
691 for (size_t i = 0; i < candidate_views_.size(); ++i) { | 707 for (size_t i = 0; i < candidate_views_.size(); ++i) { |
692 candidate_views_[i]->Unselect(); | 708 candidate_views_[i]->Unselect(); |
693 } | 709 } |
694 // Select the candidate specified by index_in_page. | 710 // Select the candidate specified by index_in_page. |
695 candidate_views_[index_in_page]->Select(); | 711 candidate_views_[index_in_page]->Select(); |
696 | 712 |
697 // Update the cursor indexes in the model. | 713 // Update the cursor indexes in the model. |
698 lookup_table_.cursor_row_index = index_in_page; | 714 lookup_table_.cursor_absolute_index = cursor_absolute_index; |
699 lookup_table_.cursor_absolute_index = | |
700 (lookup_table_.page_size * lookup_table_.current_page_index + | |
701 index_in_page); | |
702 | 715 |
703 // Update the footer area. | 716 // Update the footer area. |
704 footer_area_->RemoveAllChildViews(false); // Don't delete child views. | 717 footer_area_->RemoveAllChildViews(false); // Don't delete child views. |
705 if (orientation_ == kVertical) { | 718 if (orientation_ == kVertical) { |
706 // Show information about the cursor and the page in the footer area. | 719 // Show information about the cursor and the page in the footer area. |
| 720 // TODO(satorux): This only works with engines that return all |
| 721 // candidates (i.e. ibus-anthy). |
707 footer_label_->SetText( | 722 footer_label_->SetText( |
708 StringPrintf(L"%d/%d", | 723 StringPrintf(L"%d/%d", |
709 lookup_table_.cursor_absolute_index + 1, | 724 lookup_table_.cursor_absolute_index + 1, |
710 lookup_table_.candidates.size())); | 725 lookup_table_.candidates.size())); |
711 footer_area_->AddChildView(footer_area_contents_.get()); | 726 footer_area_->AddChildView(footer_area_contents_.get()); |
712 } else { | 727 } else { |
713 // Show nothing in the footer area if the orientation is horizontal. | 728 // Show nothing in the footer area if the orientation is horizontal. |
714 footer_area_->AddChildView(footer_area_place_holder_.get()); | 729 footer_area_->AddChildView(footer_area_place_holder_.get()); |
715 } | 730 } |
716 | 731 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 // Create the candidate window controller. | 954 // Create the candidate window controller. |
940 chromeos::CandidateWindowController controller; | 955 chromeos::CandidateWindowController controller; |
941 controller.Init(); | 956 controller.Init(); |
942 | 957 |
943 // Start the main loop. | 958 // Start the main loop. |
944 views::AcceleratorHandler accelerator_handler; | 959 views::AcceleratorHandler accelerator_handler; |
945 MessageLoopForUI::current()->Run(&accelerator_handler); | 960 MessageLoopForUI::current()->Run(&accelerator_handler); |
946 | 961 |
947 return 0; | 962 return 0; |
948 } | 963 } |
OLD | NEW |