| 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 "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/chromeos/input_method/candidate_view.h" | 10 #include "chrome/browser/chromeos/input_method/candidate_view.h" |
| 11 #include "chrome/browser/chromeos/input_method/candidate_window_constants.h" | 11 #include "chrome/browser/chromeos/input_method/candidate_window_constants.h" |
| 12 #include "chrome/browser/chromeos/input_method/hidable_area.h" | 12 #include "chrome/browser/chromeos/input_method/hidable_area.h" |
| 13 #include "chromeos/dbus/ibus/ibus_lookup_table.h" | 13 #include "chromeos/ime/candidate_window.h" |
| 14 #include "ui/gfx/color_utils.h" | 14 #include "ui/gfx/color_utils.h" |
| 15 #include "ui/native_theme/native_theme.h" | 15 #include "ui/native_theme/native_theme.h" |
| 16 #include "ui/views/controls/label.h" | 16 #include "ui/views/controls/label.h" |
| 17 #include "ui/views/layout/grid_layout.h" | 17 #include "ui/views/layout/grid_layout.h" |
| 18 #include "ui/views/widget/widget.h" | 18 #include "ui/views/widget/widget.h" |
| 19 | 19 |
| 20 namespace chromeos { | 20 namespace chromeos { |
| 21 namespace input_method { | 21 namespace input_method { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 views::GridLayout::FILL, views::GridLayout::FILL, | 63 views::GridLayout::FILL, views::GridLayout::FILL, |
| 64 1, views::GridLayout::USE_PREF, 0, 0); | 64 1, views::GridLayout::USE_PREF, 0, 0); |
| 65 layout->StartRow(0, 0); | 65 layout->StartRow(0, 0); |
| 66 | 66 |
| 67 // Add the view contents. | 67 // Add the view contents. |
| 68 layout->AddView(view); // |view| is owned by |wraper|, not |layout|. | 68 layout->AddView(view); // |view| is owned by |wraper|, not |layout|. |
| 69 return wrapper; | 69 return wrapper; |
| 70 } | 70 } |
| 71 | 71 |
| 72 // Creates shortcut text from the given index and the orientation. | 72 // Creates shortcut text from the given index and the orientation. |
| 73 string16 CreateShortcutText(size_t index, const IBusLookupTable& table) { | 73 string16 CreateShortcutText(size_t index, |
| 74 if (index >= table.candidates().size()) | 74 const CandidateWindow& candidate_window) { |
| 75 if (index >= candidate_window.candidates().size()) |
| 75 return UTF8ToUTF16(""); | 76 return UTF8ToUTF16(""); |
| 76 std::string shortcut_text = table.candidates()[index].label; | 77 std::string shortcut_text = candidate_window.candidates()[index].label; |
| 77 if (!shortcut_text.empty() && | 78 if (!shortcut_text.empty() && |
| 78 table.orientation() != IBusLookupTable::VERTICAL) | 79 candidate_window.orientation() != CandidateWindow::VERTICAL) |
| 79 shortcut_text += '.'; | 80 shortcut_text += '.'; |
| 80 return UTF8ToUTF16(shortcut_text); | 81 return UTF8ToUTF16(shortcut_text); |
| 81 } | 82 } |
| 82 | 83 |
| 83 // Creates the shortcut label, and returns it (never returns NULL). | 84 // Creates the shortcut label, and returns it (never returns NULL). |
| 84 // The label text is not set in this function. | 85 // The label text is not set in this function. |
| 85 views::Label* CreateShortcutLabel( | 86 views::Label* CreateShortcutLabel( |
| 86 IBusLookupTable::Orientation orientation, const ui::NativeTheme& theme) { | 87 CandidateWindow::Orientation orientation, const ui::NativeTheme& theme) { |
| 87 // Create the shortcut label. The label will be owned by | 88 // Create the shortcut label. The label will be owned by |
| 88 // |wrapped_shortcut_label|, hence it's deleted when | 89 // |wrapped_shortcut_label|, hence it's deleted when |
| 89 // |wrapped_shortcut_label| is deleted. | 90 // |wrapped_shortcut_label| is deleted. |
| 90 views::Label* shortcut_label = new views::Label; | 91 views::Label* shortcut_label = new views::Label; |
| 91 | 92 |
| 92 if (orientation == IBusLookupTable::VERTICAL) { | 93 if (orientation == CandidateWindow::VERTICAL) { |
| 93 shortcut_label->SetFont( | 94 shortcut_label->SetFont( |
| 94 shortcut_label->font().DeriveFont(kFontSizeDelta, gfx::Font::BOLD)); | 95 shortcut_label->font().DeriveFont(kFontSizeDelta, gfx::Font::BOLD)); |
| 95 } else { | 96 } else { |
| 96 shortcut_label->SetFont( | 97 shortcut_label->SetFont( |
| 97 shortcut_label->font().DeriveFont(kFontSizeDelta)); | 98 shortcut_label->font().DeriveFont(kFontSizeDelta)); |
| 98 } | 99 } |
| 99 // TODO(satorux): Maybe we need to use language specific fonts for | 100 // TODO(satorux): Maybe we need to use language specific fonts for |
| 100 // candidate_label, like Chinese font for Chinese input method? | 101 // candidate_label, like Chinese font for Chinese input method? |
| 101 shortcut_label->SetEnabledColor(theme.GetSystemColor( | 102 shortcut_label->SetEnabledColor(theme.GetSystemColor( |
| 102 ui::NativeTheme::kColorId_LabelEnabledColor)); | 103 ui::NativeTheme::kColorId_LabelEnabledColor)); |
| 103 shortcut_label->SetDisabledColor(theme.GetSystemColor( | 104 shortcut_label->SetDisabledColor(theme.GetSystemColor( |
| 104 ui::NativeTheme::kColorId_LabelDisabledColor)); | 105 ui::NativeTheme::kColorId_LabelDisabledColor)); |
| 105 | 106 |
| 106 return shortcut_label; | 107 return shortcut_label; |
| 107 } | 108 } |
| 108 | 109 |
| 109 // Wraps the shortcut label, then decorates wrapped shortcut label | 110 // Wraps the shortcut label, then decorates wrapped shortcut label |
| 110 // and returns it (never returns NULL). | 111 // and returns it (never returns NULL). |
| 111 // The label text is not set in this function. | 112 // The label text is not set in this function. |
| 112 views::View* CreateWrappedShortcutLabel( | 113 views::View* CreateWrappedShortcutLabel( |
| 113 views::Label* shortcut_label, | 114 views::Label* shortcut_label, |
| 114 IBusLookupTable::Orientation orientation, | 115 CandidateWindow::Orientation orientation, |
| 115 const ui::NativeTheme& theme) { | 116 const ui::NativeTheme& theme) { |
| 116 // Wrap it with padding. | 117 // Wrap it with padding. |
| 117 const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6); | 118 const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6); |
| 118 const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0); | 119 const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0); |
| 119 const gfx::Insets insets = | 120 const gfx::Insets insets = |
| 120 (orientation == IBusLookupTable::VERTICAL ? | 121 (orientation == CandidateWindow::VERTICAL ? |
| 121 kVerticalShortcutLabelInsets : | 122 kVerticalShortcutLabelInsets : |
| 122 kHorizontalShortcutLabelInsets); | 123 kHorizontalShortcutLabelInsets); |
| 123 views::View* wrapped_shortcut_label = | 124 views::View* wrapped_shortcut_label = |
| 124 WrapWithPadding(shortcut_label, insets); | 125 WrapWithPadding(shortcut_label, insets); |
| 125 | 126 |
| 126 // Add decoration based on the orientation. | 127 // Add decoration based on the orientation. |
| 127 if (orientation == IBusLookupTable::VERTICAL) { | 128 if (orientation == CandidateWindow::VERTICAL) { |
| 128 // Set the background color. | 129 // Set the background color. |
| 129 SkColor blackish = color_utils::AlphaBlend( | 130 SkColor blackish = color_utils::AlphaBlend( |
| 130 SK_ColorBLACK, | 131 SK_ColorBLACK, |
| 131 theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground), | 132 theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground), |
| 132 0x40); | 133 0x40); |
| 133 SkColor transparent_blakish = color_utils::AlphaBlend( | 134 SkColor transparent_blakish = color_utils::AlphaBlend( |
| 134 SK_ColorTRANSPARENT, blackish, 0xE0); | 135 SK_ColorTRANSPARENT, blackish, 0xE0); |
| 135 wrapped_shortcut_label->set_background( | 136 wrapped_shortcut_label->set_background( |
| 136 views::Background::CreateSolidBackground(transparent_blakish)); | 137 views::Background::CreateSolidBackground(transparent_blakish)); |
| 137 shortcut_label->SetBackgroundColor( | 138 shortcut_label->SetBackgroundColor( |
| 138 wrapped_shortcut_label->background()->get_color()); | 139 wrapped_shortcut_label->background()->get_color()); |
| 139 } | 140 } |
| 140 | 141 |
| 141 return wrapped_shortcut_label; | 142 return wrapped_shortcut_label; |
| 142 } | 143 } |
| 143 | 144 |
| 144 // Creates the candidate label, and returns it (never returns NULL). | 145 // Creates the candidate label, and returns it (never returns NULL). |
| 145 // The label text is not set in this function. | 146 // The label text is not set in this function. |
| 146 views::Label* CreateCandidateLabel( | 147 views::Label* CreateCandidateLabel( |
| 147 IBusLookupTable::Orientation orientation) { | 148 CandidateWindow::Orientation orientation) { |
| 148 views::Label* candidate_label = NULL; | 149 views::Label* candidate_label = NULL; |
| 149 | 150 |
| 150 // Create the candidate label. The label will be added to |this| as a | 151 // Create the candidate label. The label will be added to |this| as a |
| 151 // child view, hence it's deleted when |this| is deleted. | 152 // child view, hence it's deleted when |this| is deleted. |
| 152 if (orientation == IBusLookupTable::VERTICAL) { | 153 if (orientation == CandidateWindow::VERTICAL) { |
| 153 candidate_label = new VerticalCandidateLabel; | 154 candidate_label = new VerticalCandidateLabel; |
| 154 } else { | 155 } else { |
| 155 candidate_label = new views::Label; | 156 candidate_label = new views::Label; |
| 156 } | 157 } |
| 157 | 158 |
| 158 // Change the font size. | 159 // Change the font size. |
| 159 candidate_label->SetFont( | 160 candidate_label->SetFont( |
| 160 candidate_label->font().DeriveFont(kFontSizeDelta)); | 161 candidate_label->font().DeriveFont(kFontSizeDelta)); |
| 161 candidate_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 162 candidate_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 162 | 163 |
| 163 return candidate_label; | 164 return candidate_label; |
| 164 } | 165 } |
| 165 | 166 |
| 166 // Creates the annotation label, and return it (never returns NULL). | 167 // Creates the annotation label, and return it (never returns NULL). |
| 167 // The label text is not set in this function. | 168 // The label text is not set in this function. |
| 168 views::Label* CreateAnnotationLabel( | 169 views::Label* CreateAnnotationLabel( |
| 169 IBusLookupTable::Orientation orientation, const ui::NativeTheme& theme) { | 170 CandidateWindow::Orientation orientation, const ui::NativeTheme& theme) { |
| 170 // Create the annotation label. | 171 // Create the annotation label. |
| 171 views::Label* annotation_label = new views::Label; | 172 views::Label* annotation_label = new views::Label; |
| 172 | 173 |
| 173 // Change the font size and color. | 174 // Change the font size and color. |
| 174 annotation_label->SetFont( | 175 annotation_label->SetFont( |
| 175 annotation_label->font().DeriveFont(kFontSizeDelta)); | 176 annotation_label->font().DeriveFont(kFontSizeDelta)); |
| 176 annotation_label->SetEnabledColor(theme.GetSystemColor( | 177 annotation_label->SetEnabledColor(theme.GetSystemColor( |
| 177 ui::NativeTheme::kColorId_LabelDisabledColor)); | 178 ui::NativeTheme::kColorId_LabelDisabledColor)); |
| 178 annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 179 annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 179 | 180 |
| 180 return annotation_label; | 181 return annotation_label; |
| 181 } | 182 } |
| 182 | 183 |
| 183 // Computes shortcut column size. | 184 // Computes shortcut column size. |
| 184 gfx::Size ComputeShortcutColumnSize( | 185 gfx::Size ComputeShortcutColumnSize( |
| 185 const IBusLookupTable& lookup_table, | 186 const CandidateWindow& candidate_window, |
| 186 const ui::NativeTheme& theme) { | 187 const ui::NativeTheme& theme) { |
| 187 int shortcut_column_width = 0; | 188 int shortcut_column_width = 0; |
| 188 int shortcut_column_height = 0; | 189 int shortcut_column_height = 0; |
| 189 // Create the shortcut label. The label will be owned by | 190 // Create the shortcut label. The label will be owned by |
| 190 // |wrapped_shortcut_label|, hence it's deleted when | 191 // |wrapped_shortcut_label|, hence it's deleted when |
| 191 // |wrapped_shortcut_label| is deleted. | 192 // |wrapped_shortcut_label| is deleted. |
| 192 views::Label* shortcut_label = CreateShortcutLabel( | 193 views::Label* shortcut_label = CreateShortcutLabel( |
| 193 lookup_table.orientation(), theme); | 194 candidate_window.orientation(), theme); |
| 194 scoped_ptr<views::View> wrapped_shortcut_label( | 195 scoped_ptr<views::View> wrapped_shortcut_label( |
| 195 CreateWrappedShortcutLabel(shortcut_label, | 196 CreateWrappedShortcutLabel(shortcut_label, |
| 196 lookup_table.orientation(), | 197 candidate_window.orientation(), |
| 197 theme)); | 198 theme)); |
| 198 | 199 |
| 199 // Compute the max width and height in shortcut labels. | 200 // Compute the max width and height in shortcut labels. |
| 200 // We'll create temporary shortcut labels, and choose the largest width and | 201 // We'll create temporary shortcut labels, and choose the largest width and |
| 201 // height. | 202 // height. |
| 202 for (size_t i = 0; i < lookup_table.page_size(); ++i) { | 203 for (size_t i = 0; i < candidate_window.page_size(); ++i) { |
| 203 shortcut_label->SetText(CreateShortcutText(i, lookup_table)); | 204 shortcut_label->SetText(CreateShortcutText(i, candidate_window)); |
| 204 gfx::Size text_size = wrapped_shortcut_label->GetPreferredSize(); | 205 gfx::Size text_size = wrapped_shortcut_label->GetPreferredSize(); |
| 205 shortcut_column_width = std::max(shortcut_column_width, text_size.width()); | 206 shortcut_column_width = std::max(shortcut_column_width, text_size.width()); |
| 206 shortcut_column_height = std::max(shortcut_column_height, | 207 shortcut_column_height = std::max(shortcut_column_height, |
| 207 text_size.height()); | 208 text_size.height()); |
| 208 } | 209 } |
| 209 | 210 |
| 210 return gfx::Size(shortcut_column_width, shortcut_column_height); | 211 return gfx::Size(shortcut_column_width, shortcut_column_height); |
| 211 } | 212 } |
| 212 | 213 |
| 213 // Computes the page index. For instance, if the page size is 9, and the | 214 // Computes the page index. For instance, if the page size is 9, and the |
| 214 // cursor is pointing to 13th candidate, the page index will be 1 (2nd | 215 // cursor is pointing to 13th candidate, the page index will be 1 (2nd |
| 215 // page, as the index is zero-origin). Returns -1 on error. | 216 // page, as the index is zero-origin). Returns -1 on error. |
| 216 int ComputePageIndex(const IBusLookupTable& lookup_table) { | 217 int ComputePageIndex(const CandidateWindow& candidate_window) { |
| 217 if (lookup_table.page_size() > 0) | 218 if (candidate_window.page_size() > 0) |
| 218 return lookup_table.cursor_position() / lookup_table.page_size(); | 219 return candidate_window.cursor_position() / candidate_window.page_size(); |
| 219 return -1; | 220 return -1; |
| 220 } | 221 } |
| 221 | 222 |
| 222 // Computes candidate column size. | 223 // Computes candidate column size. |
| 223 gfx::Size ComputeCandidateColumnSize( | 224 gfx::Size ComputeCandidateColumnSize( |
| 224 const IBusLookupTable& lookup_table) { | 225 const CandidateWindow& candidate_window) { |
| 225 int candidate_column_width = 0; | 226 int candidate_column_width = 0; |
| 226 int candidate_column_height = 0; | 227 int candidate_column_height = 0; |
| 227 scoped_ptr<views::Label> candidate_label( | 228 scoped_ptr<views::Label> candidate_label( |
| 228 CreateCandidateLabel(lookup_table.orientation())); | 229 CreateCandidateLabel(candidate_window.orientation())); |
| 229 | 230 |
| 230 // Compute the start index of |lookup_table_|. | 231 // Compute the start index of |candidate_window_|. |
| 231 const int current_page_index = ComputePageIndex(lookup_table); | 232 const int current_page_index = ComputePageIndex(candidate_window); |
| 232 if (current_page_index < 0) | 233 if (current_page_index < 0) |
| 233 return gfx::Size(0, 0); | 234 return gfx::Size(0, 0); |
| 234 const size_t start_from = current_page_index * lookup_table.page_size(); | 235 const size_t start_from = current_page_index * candidate_window.page_size(); |
| 235 | 236 |
| 236 // Compute the max width and height in candidate labels. | 237 // Compute the max width and height in candidate labels. |
| 237 // We'll create temporary candidate labels, and choose the largest width and | 238 // We'll create temporary candidate labels, and choose the largest width and |
| 238 // height. | 239 // height. |
| 239 for (size_t i = 0; i + start_from < lookup_table.candidates().size(); ++i) { | 240 for (size_t i = 0; |
| 241 i + start_from < candidate_window.candidates().size(); |
| 242 ++i) { |
| 240 const size_t index = start_from + i; | 243 const size_t index = start_from + i; |
| 241 | 244 |
| 242 candidate_label->SetText( | 245 candidate_label->SetText( |
| 243 UTF8ToUTF16(lookup_table.candidates()[index].value)); | 246 UTF8ToUTF16(candidate_window.candidates()[index].value)); |
| 244 gfx::Size text_size = candidate_label->GetPreferredSize(); | 247 gfx::Size text_size = candidate_label->GetPreferredSize(); |
| 245 candidate_column_width = std::max(candidate_column_width, | 248 candidate_column_width = std::max(candidate_column_width, |
| 246 text_size.width()); | 249 text_size.width()); |
| 247 candidate_column_height = std::max(candidate_column_height, | 250 candidate_column_height = std::max(candidate_column_height, |
| 248 text_size.height()); | 251 text_size.height()); |
| 249 } | 252 } |
| 250 | 253 |
| 251 return gfx::Size(candidate_column_width, candidate_column_height); | 254 return gfx::Size(candidate_column_width, candidate_column_height); |
| 252 } | 255 } |
| 253 | 256 |
| 254 // Computes annotation column size. | 257 // Computes annotation column size. |
| 255 gfx::Size ComputeAnnotationColumnSize( | 258 gfx::Size ComputeAnnotationColumnSize( |
| 256 const IBusLookupTable& lookup_table, const ui::NativeTheme& theme) { | 259 const CandidateWindow& candidate_window, const ui::NativeTheme& theme) { |
| 257 int annotation_column_width = 0; | 260 int annotation_column_width = 0; |
| 258 int annotation_column_height = 0; | 261 int annotation_column_height = 0; |
| 259 scoped_ptr<views::Label> annotation_label( | 262 scoped_ptr<views::Label> annotation_label( |
| 260 CreateAnnotationLabel(lookup_table.orientation(), theme)); | 263 CreateAnnotationLabel(candidate_window.orientation(), theme)); |
| 261 | 264 |
| 262 // Compute the start index of |lookup_table_|. | 265 // Compute the start index of |candidate_window_|. |
| 263 const int current_page_index = ComputePageIndex(lookup_table); | 266 const int current_page_index = ComputePageIndex(candidate_window); |
| 264 if (current_page_index < 0) | 267 if (current_page_index < 0) |
| 265 return gfx::Size(0, 0); | 268 return gfx::Size(0, 0); |
| 266 const size_t start_from = current_page_index * lookup_table.page_size(); | 269 const size_t start_from = current_page_index * candidate_window.page_size(); |
| 267 | 270 |
| 268 // Compute max width and height in annotation labels. | 271 // Compute max width and height in annotation labels. |
| 269 // We'll create temporary annotation labels, and choose the largest width and | 272 // We'll create temporary annotation labels, and choose the largest width and |
| 270 // height. | 273 // height. |
| 271 for (size_t i = 0; i + start_from < lookup_table.candidates().size(); ++i) { | 274 for (size_t i = 0; |
| 275 i + start_from < candidate_window.candidates().size(); |
| 276 ++i) { |
| 272 const size_t index = start_from + i; | 277 const size_t index = start_from + i; |
| 273 | 278 |
| 274 annotation_label->SetText( | 279 annotation_label->SetText( |
| 275 UTF8ToUTF16(lookup_table.candidates()[index].annotation)); | 280 UTF8ToUTF16(candidate_window.candidates()[index].annotation)); |
| 276 gfx::Size text_size = annotation_label->GetPreferredSize(); | 281 gfx::Size text_size = annotation_label->GetPreferredSize(); |
| 277 annotation_column_width = std::max(annotation_column_width, | 282 annotation_column_width = std::max(annotation_column_width, |
| 278 text_size.width()); | 283 text_size.width()); |
| 279 annotation_column_height = std::max(annotation_column_height, | 284 annotation_column_height = std::max(annotation_column_height, |
| 280 text_size.height()); | 285 text_size.height()); |
| 281 } | 286 } |
| 282 | 287 |
| 283 return gfx::Size(annotation_column_width, annotation_column_height); | 288 return gfx::Size(annotation_column_width, annotation_column_height); |
| 284 } | 289 } |
| 285 | 290 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 private: | 333 private: |
| 329 views::Label* label_; | 334 views::Label* label_; |
| 330 int minWidth_; | 335 int minWidth_; |
| 331 | 336 |
| 332 DISALLOW_COPY_AND_ASSIGN(InformationTextArea); | 337 DISALLOW_COPY_AND_ASSIGN(InformationTextArea); |
| 333 }; | 338 }; |
| 334 | 339 |
| 335 CandidateView::CandidateView( | 340 CandidateView::CandidateView( |
| 336 CandidateWindowView* parent_candidate_window, | 341 CandidateWindowView* parent_candidate_window, |
| 337 int index_in_page, | 342 int index_in_page, |
| 338 IBusLookupTable::Orientation orientation) | 343 CandidateWindow::Orientation orientation) |
| 339 : index_in_page_(index_in_page), | 344 : index_in_page_(index_in_page), |
| 340 orientation_(orientation), | 345 orientation_(orientation), |
| 341 parent_candidate_window_(parent_candidate_window), | 346 parent_candidate_window_(parent_candidate_window), |
| 342 shortcut_label_(NULL), | 347 shortcut_label_(NULL), |
| 343 candidate_label_(NULL), | 348 candidate_label_(NULL), |
| 344 annotation_label_(NULL), | 349 annotation_label_(NULL), |
| 345 infolist_icon_(NULL), | 350 infolist_icon_(NULL), |
| 346 infolist_icon_enabled_(false) { | 351 infolist_icon_enabled_(false) { |
| 347 } | 352 } |
| 348 | 353 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 360 CreateWrappedShortcutLabel(shortcut_label_, orientation_, theme); | 365 CreateWrappedShortcutLabel(shortcut_label_, orientation_, theme); |
| 361 candidate_label_ = CreateCandidateLabel(orientation_); | 366 candidate_label_ = CreateCandidateLabel(orientation_); |
| 362 annotation_label_ = CreateAnnotationLabel(orientation_, theme); | 367 annotation_label_ = CreateAnnotationLabel(orientation_, theme); |
| 363 | 368 |
| 364 // Initialize the column set with three columns. | 369 // Initialize the column set with three columns. |
| 365 views::ColumnSet* column_set = layout->AddColumnSet(0); | 370 views::ColumnSet* column_set = layout->AddColumnSet(0); |
| 366 | 371 |
| 367 // If orientation is vertical, each column width is fixed. | 372 // If orientation is vertical, each column width is fixed. |
| 368 // Otherwise the width is resizable. | 373 // Otherwise the width is resizable. |
| 369 const views::GridLayout::SizeType column_type = | 374 const views::GridLayout::SizeType column_type = |
| 370 orientation_ == IBusLookupTable::VERTICAL ? | 375 orientation_ == CandidateWindow::VERTICAL ? |
| 371 views::GridLayout::FIXED : views::GridLayout::USE_PREF; | 376 views::GridLayout::FIXED : views::GridLayout::USE_PREF; |
| 372 | 377 |
| 373 const int padding_column_width = | 378 const int padding_column_width = |
| 374 orientation_ == IBusLookupTable::VERTICAL ? 4 : 6; | 379 orientation_ == CandidateWindow::VERTICAL ? 4 : 6; |
| 375 | 380 |
| 376 // Set shortcut column type and width. | 381 // Set shortcut column type and width. |
| 377 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | 382 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
| 378 0, column_type, shortcut_column_width, 0); | 383 0, column_type, shortcut_column_width, 0); |
| 379 column_set->AddPaddingColumn(0, padding_column_width); | 384 column_set->AddPaddingColumn(0, padding_column_width); |
| 380 | 385 |
| 381 // Set candidate column type and width. | 386 // Set candidate column type and width. |
| 382 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | 387 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
| 383 1, views::GridLayout::USE_PREF, 0, | 388 1, views::GridLayout::USE_PREF, 0, |
| 384 orientation_ == IBusLookupTable::VERTICAL ? | 389 orientation_ == CandidateWindow::VERTICAL ? |
| 385 candidate_column_width : 0); | 390 candidate_column_width : 0); |
| 386 column_set->AddPaddingColumn(0, padding_column_width); | 391 column_set->AddPaddingColumn(0, padding_column_width); |
| 387 | 392 |
| 388 // Set annotation column type and width. | 393 // Set annotation column type and width. |
| 389 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | 394 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
| 390 0, column_type, annotation_column_width, 0); | 395 0, column_type, annotation_column_width, 0); |
| 391 | 396 |
| 392 if (orientation_ == IBusLookupTable::VERTICAL) { | 397 if (orientation_ == CandidateWindow::VERTICAL) { |
| 393 column_set->AddPaddingColumn(0, 1); | 398 column_set->AddPaddingColumn(0, 1); |
| 394 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, | 399 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, |
| 395 views::GridLayout::FIXED, kInfolistIndicatorIconWidth, | 400 views::GridLayout::FIXED, kInfolistIndicatorIconWidth, |
| 396 0); | 401 0); |
| 397 column_set->AddPaddingColumn(0, 2); | 402 column_set->AddPaddingColumn(0, 2); |
| 398 } else { | 403 } else { |
| 399 column_set->AddPaddingColumn(0, padding_column_width); | 404 column_set->AddPaddingColumn(0, padding_column_width); |
| 400 } | 405 } |
| 401 | 406 |
| 402 // Add the shortcut label, the candidate label, and annotation label. | 407 // Add the shortcut label, the candidate label, and annotation label. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 417 views::GridLayout::FILL, // Vertical alignment. | 422 views::GridLayout::FILL, // Vertical alignment. |
| 418 -1, // Preferred width, not specified. | 423 -1, // Preferred width, not specified. |
| 419 column_height); // Preferred height. | 424 column_height); // Preferred height. |
| 420 layout->AddView(annotation_label_, | 425 layout->AddView(annotation_label_, |
| 421 1, // Column span. | 426 1, // Column span. |
| 422 1, // Row span. | 427 1, // Row span. |
| 423 views::GridLayout::FILL, // Horizontal alignment. | 428 views::GridLayout::FILL, // Horizontal alignment. |
| 424 views::GridLayout::FILL, // Vertical alignemnt. | 429 views::GridLayout::FILL, // Vertical alignemnt. |
| 425 -1, // Preferred width, not specified. | 430 -1, // Preferred width, not specified. |
| 426 column_height); // Preferred height. | 431 column_height); // Preferred height. |
| 427 if (orientation_ == IBusLookupTable::VERTICAL) { | 432 if (orientation_ == CandidateWindow::VERTICAL) { |
| 428 infolist_icon_ = new views::View; | 433 infolist_icon_ = new views::View; |
| 429 views::View* infolist_icon_wrapper = new views::View; | 434 views::View* infolist_icon_wrapper = new views::View; |
| 430 views::GridLayout* infolist_icon_layout = | 435 views::GridLayout* infolist_icon_layout = |
| 431 new views::GridLayout(infolist_icon_wrapper); | 436 new views::GridLayout(infolist_icon_wrapper); |
| 432 // |infolist_icon_layout| is owned by |infolist_icon_wrapper|. | 437 // |infolist_icon_layout| is owned by |infolist_icon_wrapper|. |
| 433 infolist_icon_wrapper->SetLayoutManager(infolist_icon_layout); | 438 infolist_icon_wrapper->SetLayoutManager(infolist_icon_layout); |
| 434 infolist_icon_layout->AddColumnSet(0)->AddColumn( | 439 infolist_icon_layout->AddColumnSet(0)->AddColumn( |
| 435 views::GridLayout::FILL, views::GridLayout::FILL, | 440 views::GridLayout::FILL, views::GridLayout::FILL, |
| 436 0, views::GridLayout::FIXED, kInfolistIndicatorIconWidth, 0); | 441 0, views::GridLayout::FIXED, kInfolistIndicatorIconWidth, 0); |
| 437 infolist_icon_layout->AddPaddingRow(0, kInfolistIndicatorIconPadding); | 442 infolist_icon_layout->AddPaddingRow(0, kInfolistIndicatorIconPadding); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 &location_in_candidate_window); | 528 &location_in_candidate_window); |
| 524 parent_candidate_window_->OnCandidatePressed(location_in_candidate_window); | 529 parent_candidate_window_->OnCandidatePressed(location_in_candidate_window); |
| 525 parent_candidate_window_->CommitCandidate(); | 530 parent_candidate_window_->CommitCandidate(); |
| 526 } | 531 } |
| 527 | 532 |
| 528 void CandidateView::UpdateLabelBackgroundColors() { | 533 void CandidateView::UpdateLabelBackgroundColors() { |
| 529 SkColor color = background() ? | 534 SkColor color = background() ? |
| 530 background()->get_color() : | 535 background()->get_color() : |
| 531 GetNativeTheme()->GetSystemColor( | 536 GetNativeTheme()->GetSystemColor( |
| 532 ui::NativeTheme::kColorId_WindowBackground); | 537 ui::NativeTheme::kColorId_WindowBackground); |
| 533 if (orientation_ != IBusLookupTable::VERTICAL) | 538 if (orientation_ != CandidateWindow::VERTICAL) |
| 534 shortcut_label_->SetBackgroundColor(color); | 539 shortcut_label_->SetBackgroundColor(color); |
| 535 candidate_label_->SetBackgroundColor(color); | 540 candidate_label_->SetBackgroundColor(color); |
| 536 annotation_label_->SetBackgroundColor(color); | 541 annotation_label_->SetBackgroundColor(color); |
| 537 } | 542 } |
| 538 | 543 |
| 539 CandidateWindowView::CandidateWindowView(views::Widget* parent_frame) | 544 CandidateWindowView::CandidateWindowView(views::Widget* parent_frame) |
| 540 : selected_candidate_index_in_page_(-1), | 545 : selected_candidate_index_in_page_(-1), |
| 541 parent_frame_(parent_frame), | 546 parent_frame_(parent_frame), |
| 542 preedit_area_(NULL), | 547 preedit_area_(NULL), |
| 543 header_area_(NULL), | 548 header_area_(NULL), |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 } | 630 } |
| 626 | 631 |
| 627 void CandidateWindowView::ShowAuxiliaryText() { | 632 void CandidateWindowView::ShowAuxiliaryText() { |
| 628 // If candidate_area is not shown, shows auxiliary text at header_area. | 633 // If candidate_area is not shown, shows auxiliary text at header_area. |
| 629 // We expect both header_area_ and footer_area_ contain same value. | 634 // We expect both header_area_ and footer_area_ contain same value. |
| 630 if (!candidate_area_->IsShown()) { | 635 if (!candidate_area_->IsShown()) { |
| 631 header_area_->Show(); | 636 header_area_->Show(); |
| 632 footer_area_->Hide(); | 637 footer_area_->Hide(); |
| 633 } else { | 638 } else { |
| 634 // If candidate_area is shown, shows auxiliary text with orientation. | 639 // If candidate_area is shown, shows auxiliary text with orientation. |
| 635 if (lookup_table_.orientation() == IBusLookupTable::HORIZONTAL) { | 640 if (candidate_window_.orientation() == CandidateWindow::HORIZONTAL) { |
| 636 header_area_->Show(); | 641 header_area_->Show(); |
| 637 footer_area_->Hide(); | 642 footer_area_->Hide(); |
| 638 } else { | 643 } else { |
| 639 footer_area_->Show(); | 644 footer_area_->Show(); |
| 640 header_area_->Hide(); | 645 header_area_->Hide(); |
| 641 } | 646 } |
| 642 } | 647 } |
| 643 UpdateParentArea(); | 648 UpdateParentArea(); |
| 644 } | 649 } |
| 645 | 650 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 674 bool is_open = IsCandidateWindowOpen(); | 679 bool is_open = IsCandidateWindowOpen(); |
| 675 if (!was_candidate_window_open_ && is_open) { | 680 if (!was_candidate_window_open_ && is_open) { |
| 676 FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowOpened()); | 681 FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowOpened()); |
| 677 } else if (was_candidate_window_open_ && !is_open) { | 682 } else if (was_candidate_window_open_ && !is_open) { |
| 678 FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowClosed()); | 683 FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowClosed()); |
| 679 } | 684 } |
| 680 was_candidate_window_open_ = is_open; | 685 was_candidate_window_open_ = is_open; |
| 681 } | 686 } |
| 682 | 687 |
| 683 bool CandidateWindowView::ShouldUpdateCandidateViews( | 688 bool CandidateWindowView::ShouldUpdateCandidateViews( |
| 684 const IBusLookupTable& old_table, | 689 const CandidateWindow& old_candidate_window, |
| 685 const IBusLookupTable& new_table) { | 690 const CandidateWindow& new_candidate_window) { |
| 686 return !old_table.IsEqual(new_table); | 691 return !old_candidate_window.IsEqual(new_candidate_window); |
| 687 } | 692 } |
| 688 | 693 |
| 689 void CandidateWindowView::UpdateCandidates( | 694 void CandidateWindowView::UpdateCandidates( |
| 690 const IBusLookupTable& new_lookup_table) { | 695 const CandidateWindow& new_candidate_window) { |
| 691 const bool should_update = ShouldUpdateCandidateViews(lookup_table_, | 696 const bool should_update = ShouldUpdateCandidateViews(candidate_window_, |
| 692 new_lookup_table); | 697 new_candidate_window); |
| 693 // Updating the candidate views is expensive. We'll skip this if possible. | 698 // Updating the candidate views is expensive. We'll skip this if possible. |
| 694 if (should_update) { | 699 if (should_update) { |
| 695 // Initialize candidate views if necessary. | 700 // Initialize candidate views if necessary. |
| 696 MaybeInitializeCandidateViews(new_lookup_table); | 701 MaybeInitializeCandidateViews(new_candidate_window); |
| 697 | 702 |
| 698 should_show_at_composition_head_ | 703 should_show_at_composition_head_ |
| 699 = new_lookup_table.show_window_at_composition(); | 704 = new_candidate_window.show_window_at_composition(); |
| 700 // Compute the index of the current page. | 705 // Compute the index of the current page. |
| 701 const int current_page_index = ComputePageIndex(new_lookup_table); | 706 const int current_page_index = ComputePageIndex(new_candidate_window); |
| 702 if (current_page_index < 0) { | 707 if (current_page_index < 0) { |
| 703 return; | 708 return; |
| 704 } | 709 } |
| 705 | 710 |
| 706 // Update the candidates in the current page. | 711 // Update the candidates in the current page. |
| 707 const size_t start_from = current_page_index * new_lookup_table.page_size(); | 712 const size_t start_from = |
| 713 current_page_index * new_candidate_window.page_size(); |
| 708 | 714 |
| 709 // In some cases, engines send empty shortcut labels. For instance, | 715 // In some cases, engines send empty shortcut labels. For instance, |
| 710 // ibus-mozc sends empty labels when they show suggestions. In this | 716 // ibus-mozc sends empty labels when they show suggestions. In this |
| 711 // case, we should not show shortcut labels. | 717 // case, we should not show shortcut labels. |
| 712 bool no_shortcut_mode = true; | 718 bool no_shortcut_mode = true; |
| 713 for (size_t i = 0; i < new_lookup_table.candidates().size(); ++i) { | 719 for (size_t i = 0; i < new_candidate_window.candidates().size(); ++i) { |
| 714 if (!new_lookup_table.candidates()[i].label.empty()) { | 720 if (!new_candidate_window.candidates()[i].label.empty()) { |
| 715 no_shortcut_mode = false; | 721 no_shortcut_mode = false; |
| 716 break; | 722 break; |
| 717 } | 723 } |
| 718 } | 724 } |
| 719 | 725 |
| 720 for (size_t i = 0; i < candidate_views_.size(); ++i) { | 726 for (size_t i = 0; i < candidate_views_.size(); ++i) { |
| 721 const size_t index_in_page = i; | 727 const size_t index_in_page = i; |
| 722 const size_t candidate_index = start_from + index_in_page; | 728 const size_t candidate_index = start_from + index_in_page; |
| 723 CandidateView* candidate_view = candidate_views_[index_in_page]; | 729 CandidateView* candidate_view = candidate_views_[index_in_page]; |
| 724 // Set the shortcut text. | 730 // Set the shortcut text. |
| 725 if (no_shortcut_mode) { | 731 if (no_shortcut_mode) { |
| 726 candidate_view->SetShortcutText(string16()); | 732 candidate_view->SetShortcutText(string16()); |
| 727 } else { | 733 } else { |
| 728 // At this moment, we don't use labels sent from engines for UX | 734 // At this moment, we don't use labels sent from engines for UX |
| 729 // reasons. First, we want to show shortcut labels in empty rows | 735 // reasons. First, we want to show shortcut labels in empty rows |
| 730 // (ex. show 6, 7, 8, ... in empty rows when the number of | 736 // (ex. show 6, 7, 8, ... in empty rows when the number of |
| 731 // candidates is 5). Second, we want to add a period after each | 737 // candidates is 5). Second, we want to add a period after each |
| 732 // shortcut label when the candidate window is horizontal. | 738 // shortcut label when the candidate window is horizontal. |
| 733 candidate_view->SetShortcutText( | 739 candidate_view->SetShortcutText( |
| 734 CreateShortcutText(i, new_lookup_table)); | 740 CreateShortcutText(i, new_candidate_window)); |
| 735 } | 741 } |
| 736 // Set the candidate text. | 742 // Set the candidate text. |
| 737 if (candidate_index < new_lookup_table.candidates().size()) { | 743 if (candidate_index < new_candidate_window.candidates().size()) { |
| 738 const IBusLookupTable::Entry& entry = | 744 const CandidateWindow::Entry& entry = |
| 739 new_lookup_table.candidates()[candidate_index]; | 745 new_candidate_window.candidates()[candidate_index]; |
| 740 candidate_view->SetCandidateText(UTF8ToUTF16(entry.value)); | 746 candidate_view->SetCandidateText(UTF8ToUTF16(entry.value)); |
| 741 candidate_view->SetAnnotationText(UTF8ToUTF16(entry.annotation)); | 747 candidate_view->SetAnnotationText(UTF8ToUTF16(entry.annotation)); |
| 742 candidate_view->SetRowEnabled(true); | 748 candidate_view->SetRowEnabled(true); |
| 743 candidate_view->SetInfolistIcon(!entry.description_title.empty()); | 749 candidate_view->SetInfolistIcon(!entry.description_title.empty()); |
| 744 } else { | 750 } else { |
| 745 // Disable the empty row. | 751 // Disable the empty row. |
| 746 candidate_view->SetCandidateText(string16()); | 752 candidate_view->SetCandidateText(string16()); |
| 747 candidate_view->SetAnnotationText(string16()); | 753 candidate_view->SetAnnotationText(string16()); |
| 748 candidate_view->SetRowEnabled(false); | 754 candidate_view->SetRowEnabled(false); |
| 749 candidate_view->SetInfolistIcon(false); | 755 candidate_view->SetInfolistIcon(false); |
| 750 } | 756 } |
| 751 } | 757 } |
| 752 } | 758 } |
| 753 // Update the current lookup table. We'll use lookup_table_ from here. | 759 // Update the current candidate window. We'll use candidate_window_ from here. |
| 754 // Note that SelectCandidateAt() uses lookup_table_. | 760 // Note that SelectCandidateAt() uses candidate_window_. |
| 755 lookup_table_.CopyFrom(new_lookup_table); | 761 candidate_window_.CopyFrom(new_candidate_window); |
| 756 | 762 |
| 757 // Select the current candidate in the page. | 763 // Select the current candidate in the page. |
| 758 if (lookup_table_.is_cursor_visible()) { | 764 if (candidate_window_.is_cursor_visible()) { |
| 759 if (lookup_table_.page_size()) { | 765 if (candidate_window_.page_size()) { |
| 760 const int current_candidate_in_page = | 766 const int current_candidate_in_page = |
| 761 lookup_table_.cursor_position() % lookup_table_.page_size(); | 767 candidate_window_.cursor_position() % candidate_window_.page_size(); |
| 762 SelectCandidateAt(current_candidate_in_page); | 768 SelectCandidateAt(current_candidate_in_page); |
| 763 } | 769 } |
| 764 } else { | 770 } else { |
| 765 // Unselect the currently selected candidate. | 771 // Unselect the currently selected candidate. |
| 766 if (0 <= selected_candidate_index_in_page_ && | 772 if (0 <= selected_candidate_index_in_page_ && |
| 767 static_cast<size_t>(selected_candidate_index_in_page_) < | 773 static_cast<size_t>(selected_candidate_index_in_page_) < |
| 768 candidate_views_.size()) { | 774 candidate_views_.size()) { |
| 769 candidate_views_[selected_candidate_index_in_page_]->Unselect(); | 775 candidate_views_[selected_candidate_index_in_page_]->Unselect(); |
| 770 selected_candidate_index_in_page_ = -1; | 776 selected_candidate_index_in_page_ = -1; |
| 771 } | 777 } |
| 772 } | 778 } |
| 773 } | 779 } |
| 774 | 780 |
| 775 void CandidateWindowView::MaybeInitializeCandidateViews( | 781 void CandidateWindowView::MaybeInitializeCandidateViews( |
| 776 const IBusLookupTable& lookup_table) { | 782 const CandidateWindow& candidate_window) { |
| 777 const IBusLookupTable::Orientation orientation = | 783 const CandidateWindow::Orientation orientation = |
| 778 lookup_table.orientation(); | 784 candidate_window.orientation(); |
| 779 const int page_size = lookup_table.page_size(); | 785 const int page_size = candidate_window.page_size(); |
| 780 views::View* candidate_area_contents = candidate_area_->contents(); | 786 views::View* candidate_area_contents = candidate_area_->contents(); |
| 781 | 787 |
| 782 // Current column width. | 788 // Current column width. |
| 783 gfx::Size shortcut_column_size(0, 0); | 789 gfx::Size shortcut_column_size(0, 0); |
| 784 gfx::Size candidate_column_size(0,0); | 790 gfx::Size candidate_column_size(0,0); |
| 785 gfx::Size annotation_column_size(0, 0); | 791 gfx::Size annotation_column_size(0, 0); |
| 786 | 792 |
| 787 // If orientation is horizontal, don't need to compute width, | 793 // If orientation is horizontal, don't need to compute width, |
| 788 // because each label is left aligned. | 794 // because each label is left aligned. |
| 789 if (orientation == IBusLookupTable::VERTICAL) { | 795 if (orientation == CandidateWindow::VERTICAL) { |
| 790 const ui::NativeTheme& theme = *GetNativeTheme(); | 796 const ui::NativeTheme& theme = *GetNativeTheme(); |
| 791 shortcut_column_size = ComputeShortcutColumnSize(lookup_table, theme); | 797 shortcut_column_size = ComputeShortcutColumnSize(candidate_window, theme); |
| 792 candidate_column_size = ComputeCandidateColumnSize(lookup_table); | 798 candidate_column_size = ComputeCandidateColumnSize(candidate_window); |
| 793 annotation_column_size = ComputeAnnotationColumnSize(lookup_table, theme); | 799 annotation_column_size = ComputeAnnotationColumnSize(candidate_window, |
| 800 theme); |
| 794 } | 801 } |
| 795 | 802 |
| 796 // If the requested number of views matches the number of current views, and | 803 // If the requested number of views matches the number of current views, and |
| 797 // previous and current column width are same, just reuse these. | 804 // previous and current column width are same, just reuse these. |
| 798 // | 805 // |
| 799 // Note that the early exit logic is not only useful for improving | 806 // Note that the early exit logic is not only useful for improving |
| 800 // performance, but also necessary for the horizontal candidate window | 807 // performance, but also necessary for the horizontal candidate window |
| 801 // to be redrawn properly. If we get rid of the logic, the horizontal | 808 // to be redrawn properly. If we get rid of the logic, the horizontal |
| 802 // candidate window won't get redrawn properly for some reason when | 809 // candidate window won't get redrawn properly for some reason when |
| 803 // there is no size change. You can test this by removing "return" here | 810 // there is no size change. You can test this by removing "return" here |
| 804 // and type "ni" with Pinyin input method. | 811 // and type "ni" with Pinyin input method. |
| 805 if (static_cast<int>(candidate_views_.size()) == page_size && | 812 if (static_cast<int>(candidate_views_.size()) == page_size && |
| 806 lookup_table_.orientation() == orientation && | 813 candidate_window_.orientation() == orientation && |
| 807 previous_shortcut_column_size_ == shortcut_column_size && | 814 previous_shortcut_column_size_ == shortcut_column_size && |
| 808 previous_candidate_column_size_ == candidate_column_size && | 815 previous_candidate_column_size_ == candidate_column_size && |
| 809 previous_annotation_column_size_ == annotation_column_size) { | 816 previous_annotation_column_size_ == annotation_column_size) { |
| 810 return; | 817 return; |
| 811 } | 818 } |
| 812 | 819 |
| 813 // Update the previous column widths. | 820 // Update the previous column widths. |
| 814 previous_shortcut_column_size_ = shortcut_column_size; | 821 previous_shortcut_column_size_ = shortcut_column_size; |
| 815 previous_candidate_column_size_ = candidate_column_size; | 822 previous_candidate_column_size_ = candidate_column_size; |
| 816 previous_annotation_column_size_ = annotation_column_size; | 823 previous_annotation_column_size_ = annotation_column_size; |
| 817 | 824 |
| 818 // Clear the existing candidate_views if any. | 825 // Clear the existing candidate_views if any. |
| 819 for (size_t i = 0; i < candidate_views_.size(); ++i) { | 826 for (size_t i = 0; i < candidate_views_.size(); ++i) { |
| 820 candidate_area_contents->RemoveChildView(candidate_views_[i]); | 827 candidate_area_contents->RemoveChildView(candidate_views_[i]); |
| 821 // Delete the view after getting out the current message loop iteration. | 828 // Delete the view after getting out the current message loop iteration. |
| 822 base::MessageLoop::current()->DeleteSoon(FROM_HERE, candidate_views_[i]); | 829 base::MessageLoop::current()->DeleteSoon(FROM_HERE, candidate_views_[i]); |
| 823 } | 830 } |
| 824 candidate_views_.clear(); | 831 candidate_views_.clear(); |
| 825 selected_candidate_index_in_page_ = -1; // Invalidates the index. | 832 selected_candidate_index_in_page_ = -1; // Invalidates the index. |
| 826 | 833 |
| 827 views::GridLayout* layout = new views::GridLayout(candidate_area_contents); | 834 views::GridLayout* layout = new views::GridLayout(candidate_area_contents); |
| 828 // |candidate_area_contents| owns |layout|. | 835 // |candidate_area_contents| owns |layout|. |
| 829 candidate_area_contents->SetLayoutManager(layout); | 836 candidate_area_contents->SetLayoutManager(layout); |
| 830 // Initialize the column set. | 837 // Initialize the column set. |
| 831 views::ColumnSet* column_set = layout->AddColumnSet(0); | 838 views::ColumnSet* column_set = layout->AddColumnSet(0); |
| 832 if (orientation == IBusLookupTable::VERTICAL) { | 839 if (orientation == CandidateWindow::VERTICAL) { |
| 833 column_set->AddColumn(views::GridLayout::FILL, | 840 column_set->AddColumn(views::GridLayout::FILL, |
| 834 views::GridLayout::FILL, | 841 views::GridLayout::FILL, |
| 835 1, views::GridLayout::USE_PREF, 0, 0); | 842 1, views::GridLayout::USE_PREF, 0, 0); |
| 836 } else { | 843 } else { |
| 837 for (int i = 0; i < page_size; ++i) { | 844 for (int i = 0; i < page_size; ++i) { |
| 838 column_set->AddColumn(views::GridLayout::FILL, | 845 column_set->AddColumn(views::GridLayout::FILL, |
| 839 views::GridLayout::FILL, | 846 views::GridLayout::FILL, |
| 840 0, views::GridLayout::USE_PREF, 0, 0); | 847 0, views::GridLayout::USE_PREF, 0, 0); |
| 841 } | 848 } |
| 842 } | 849 } |
| 843 | 850 |
| 844 // Set insets so the border of the selected candidate is drawn inside of | 851 // Set insets so the border of the selected candidate is drawn inside of |
| 845 // the border of the main candidate window, but we don't have the inset | 852 // the border of the main candidate window, but we don't have the inset |
| 846 // at the top and the bottom as we have the borders of the header and | 853 // at the top and the bottom as we have the borders of the header and |
| 847 // footer areas. | 854 // footer areas. |
| 848 const gfx::Insets kCandidateAreaInsets(0, 1, 0, 1); | 855 const gfx::Insets kCandidateAreaInsets(0, 1, 0, 1); |
| 849 layout->SetInsets(kCandidateAreaInsets.top(), | 856 layout->SetInsets(kCandidateAreaInsets.top(), |
| 850 kCandidateAreaInsets.left(), | 857 kCandidateAreaInsets.left(), |
| 851 kCandidateAreaInsets.bottom(), | 858 kCandidateAreaInsets.bottom(), |
| 852 kCandidateAreaInsets.right()); | 859 kCandidateAreaInsets.right()); |
| 853 | 860 |
| 854 // Use maximum height for all rows in candidate area. | 861 // Use maximum height for all rows in candidate area. |
| 855 const int kColumnHeight = std::max(shortcut_column_size.height(), | 862 const int kColumnHeight = std::max(shortcut_column_size.height(), |
| 856 std::max(candidate_column_size.height(), | 863 std::max(candidate_column_size.height(), |
| 857 annotation_column_size.height())); | 864 annotation_column_size.height())); |
| 858 | 865 |
| 859 // Add views to the candidate area. | 866 // Add views to the candidate area. |
| 860 if (orientation == IBusLookupTable::HORIZONTAL) { | 867 if (orientation == CandidateWindow::HORIZONTAL) { |
| 861 layout->StartRow(0, 0); | 868 layout->StartRow(0, 0); |
| 862 } | 869 } |
| 863 | 870 |
| 864 for (int i = 0; i < page_size; ++i) { | 871 for (int i = 0; i < page_size; ++i) { |
| 865 CandidateView* candidate_row = new CandidateView(this, i, orientation); | 872 CandidateView* candidate_row = new CandidateView(this, i, orientation); |
| 866 candidate_row->Init(shortcut_column_size.width(), | 873 candidate_row->Init(shortcut_column_size.width(), |
| 867 candidate_column_size.width(), | 874 candidate_column_size.width(), |
| 868 annotation_column_size.width(), | 875 annotation_column_size.width(), |
| 869 kColumnHeight); | 876 kColumnHeight); |
| 870 candidate_views_.push_back(candidate_row); | 877 candidate_views_.push_back(candidate_row); |
| 871 if (orientation == IBusLookupTable::VERTICAL) { | 878 if (orientation == CandidateWindow::VERTICAL) { |
| 872 layout->StartRow(0, 0); | 879 layout->StartRow(0, 0); |
| 873 } | 880 } |
| 874 // |candidate_row| will be owned by |candidate_area_contents|. | 881 // |candidate_row| will be owned by |candidate_area_contents|. |
| 875 layout->AddView(candidate_row, | 882 layout->AddView(candidate_row, |
| 876 1, // Column span. | 883 1, // Column span. |
| 877 1, // Row span. | 884 1, // Row span. |
| 878 // Horizontal alignment. | 885 // Horizontal alignment. |
| 879 orientation == IBusLookupTable::VERTICAL ? | 886 orientation == CandidateWindow::VERTICAL ? |
| 880 views::GridLayout::FILL : views::GridLayout::CENTER, | 887 views::GridLayout::FILL : views::GridLayout::CENTER, |
| 881 views::GridLayout::CENTER, // Vertical alignment. | 888 views::GridLayout::CENTER, // Vertical alignment. |
| 882 -1, // Preferred width, not specified. | 889 -1, // Preferred width, not specified. |
| 883 kColumnHeight); // Preferred height. | 890 kColumnHeight); // Preferred height. |
| 884 } | 891 } |
| 885 | 892 |
| 886 // Compute views size in |layout|. | 893 // Compute views size in |layout|. |
| 887 // If we don't call this function, GetHorizontalOffset() often | 894 // If we don't call this function, GetHorizontalOffset() often |
| 888 // returns invalid value (returns 0), then candidate window | 895 // returns invalid value (returns 0), then candidate window |
| 889 // moves right from the correct position in ResizeAndMoveParentFrame(). | 896 // moves right from the correct position in ResizeAndMoveParentFrame(). |
| 890 // TODO(nhiroki): Figure out why it returns invalid value. | 897 // TODO(nhiroki): Figure out why it returns invalid value. |
| 891 // It seems that the x-position of the candidate labels is not set. | 898 // It seems that the x-position of the candidate labels is not set. |
| 892 layout->Layout(candidate_area_contents); | 899 layout->Layout(candidate_area_contents); |
| 893 } | 900 } |
| 894 | 901 |
| 895 bool CandidateWindowView::IsCandidateWindowOpen() const { | 902 bool CandidateWindowView::IsCandidateWindowOpen() const { |
| 896 return !should_show_at_composition_head_ && | 903 return !should_show_at_composition_head_ && |
| 897 candidate_area_->visible() && candidate_area_->IsShown(); | 904 candidate_area_->visible() && candidate_area_->IsShown(); |
| 898 } | 905 } |
| 899 | 906 |
| 900 void CandidateWindowView::SelectCandidateAt(int index_in_page) { | 907 void CandidateWindowView::SelectCandidateAt(int index_in_page) { |
| 901 const int current_page_index = ComputePageIndex(lookup_table_); | 908 const int current_page_index = ComputePageIndex(candidate_window_); |
| 902 if (current_page_index < 0) { | 909 if (current_page_index < 0) { |
| 903 return; | 910 return; |
| 904 } | 911 } |
| 905 | 912 |
| 906 const int cursor_absolute_index = | 913 const int cursor_absolute_index = |
| 907 lookup_table_.page_size() * current_page_index + index_in_page; | 914 candidate_window_.page_size() * current_page_index + index_in_page; |
| 908 // Ignore click on out of range views. | 915 // Ignore click on out of range views. |
| 909 if (cursor_absolute_index < 0 || | 916 if (cursor_absolute_index < 0 || |
| 910 lookup_table_.candidates().size() <= | 917 candidate_window_.candidates().size() <= |
| 911 static_cast<size_t>(cursor_absolute_index)) { | 918 static_cast<size_t>(cursor_absolute_index)) { |
| 912 return; | 919 return; |
| 913 } | 920 } |
| 914 | 921 |
| 915 // Unselect the currently selected candidate. | 922 // Unselect the currently selected candidate. |
| 916 if (0 <= selected_candidate_index_in_page_ && | 923 if (0 <= selected_candidate_index_in_page_ && |
| 917 static_cast<size_t>(selected_candidate_index_in_page_) < | 924 static_cast<size_t>(selected_candidate_index_in_page_) < |
| 918 candidate_views_.size()) { | 925 candidate_views_.size()) { |
| 919 candidate_views_[selected_candidate_index_in_page_]->Unselect(); | 926 candidate_views_[selected_candidate_index_in_page_]->Unselect(); |
| 920 } | 927 } |
| 921 // Remember the currently selected candidate index in the current page. | 928 // Remember the currently selected candidate index in the current page. |
| 922 selected_candidate_index_in_page_ = index_in_page; | 929 selected_candidate_index_in_page_ = index_in_page; |
| 923 | 930 |
| 924 // Select the candidate specified by index_in_page. | 931 // Select the candidate specified by index_in_page. |
| 925 candidate_views_[index_in_page]->Select(); | 932 candidate_views_[index_in_page]->Select(); |
| 926 | 933 |
| 927 // Update the cursor indexes in the model. | 934 // Update the cursor indexes in the model. |
| 928 lookup_table_.set_cursor_position(cursor_absolute_index); | 935 candidate_window_.set_cursor_position(cursor_absolute_index); |
| 929 } | 936 } |
| 930 | 937 |
| 931 void CandidateWindowView::OnCandidatePressed( | 938 void CandidateWindowView::OnCandidatePressed( |
| 932 const gfx::Point& location) { | 939 const gfx::Point& location) { |
| 933 for (size_t i = 0; i < candidate_views_.size(); ++i) { | 940 for (size_t i = 0; i < candidate_views_.size(); ++i) { |
| 934 gfx::Point converted_location = location; | 941 gfx::Point converted_location = location; |
| 935 views::View::ConvertPointToTarget(this, candidate_views_[i], | 942 views::View::ConvertPointToTarget(this, candidate_views_[i], |
| 936 &converted_location); | 943 &converted_location); |
| 937 if (candidate_views_[i]->HitTestPoint(converted_location)) { | 944 if (candidate_views_[i]->HitTestPoint(converted_location)) { |
| 938 SelectCandidateAt(i); | 945 SelectCandidateAt(i); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 952 const int button = 1; // Left button. | 959 const int button = 1; // Left button. |
| 953 const int key_modifilers = 0; | 960 const int key_modifilers = 0; |
| 954 FOR_EACH_OBSERVER(Observer, observers_, | 961 FOR_EACH_OBSERVER(Observer, observers_, |
| 955 OnCandidateCommitted(selected_candidate_index_in_page_, | 962 OnCandidateCommitted(selected_candidate_index_in_page_, |
| 956 button, | 963 button, |
| 957 key_modifilers)); | 964 key_modifilers)); |
| 958 } | 965 } |
| 959 | 966 |
| 960 void CandidateWindowView::ResizeAndMoveParentFrame() { | 967 void CandidateWindowView::ResizeAndMoveParentFrame() { |
| 961 // If rendering operation comes from mozc-engine, uses mozc specific location, | 968 // If rendering operation comes from mozc-engine, uses mozc specific location, |
| 962 // otherwise lookup table is shown under the cursor. | 969 // otherwise candidate window is shown under the cursor. |
| 963 const int x = should_show_at_composition_head_? | 970 const int x = should_show_at_composition_head_? |
| 964 composition_head_location_.x() : cursor_location_.x(); | 971 composition_head_location_.x() : cursor_location_.x(); |
| 965 // To avoid lookup-table overlapping, uses maximum y-position of mozc specific | 972 // To avoid candidate-window overlapping, uses maximum y-position of mozc |
| 966 // location and cursor location, because mozc-engine does not consider about | 973 // specific location and cursor location, because mozc-engine does not |
| 967 // multi-line composition. | 974 // consider about multi-line composition. |
| 968 const int y = should_show_at_composition_head_? | 975 const int y = should_show_at_composition_head_? |
| 969 std::max(composition_head_location_.y(), cursor_location_.y()) : | 976 std::max(composition_head_location_.y(), cursor_location_.y()) : |
| 970 cursor_location_.y(); | 977 cursor_location_.y(); |
| 971 const int height = cursor_location_.height(); | 978 const int height = cursor_location_.height(); |
| 972 const int horizontal_offset = GetHorizontalOffset(); | 979 const int horizontal_offset = GetHorizontalOffset(); |
| 973 | 980 |
| 974 gfx::Rect old_bounds = parent_frame_->GetClientAreaBoundsInScreen(); | 981 gfx::Rect old_bounds = parent_frame_->GetClientAreaBoundsInScreen(); |
| 975 gfx::Rect screen_bounds = ash::Shell::GetScreen()->GetDisplayMatching( | 982 gfx::Rect screen_bounds = ash::Shell::GetScreen()->GetDisplayMatching( |
| 976 cursor_location_).work_area(); | 983 cursor_location_).work_area(); |
| 977 // The size. | 984 // The size. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1004 | 1011 |
| 1005 // TODO(nona): check top_overflow here. | 1012 // TODO(nona): check top_overflow here. |
| 1006 | 1013 |
| 1007 // Move the window per the cursor location. | 1014 // Move the window per the cursor location. |
| 1008 // SetBounds() is not cheap. Only call this when it is really changed. | 1015 // SetBounds() is not cheap. Only call this when it is really changed. |
| 1009 if (frame_bounds != old_bounds) | 1016 if (frame_bounds != old_bounds) |
| 1010 parent_frame_->SetBounds(frame_bounds); | 1017 parent_frame_->SetBounds(frame_bounds); |
| 1011 } | 1018 } |
| 1012 | 1019 |
| 1013 int CandidateWindowView::GetHorizontalOffset() { | 1020 int CandidateWindowView::GetHorizontalOffset() { |
| 1014 // Compute the horizontal offset if the lookup table is vertical. | 1021 // Compute the horizontal offset if the candidate window is vertical. |
| 1015 if (!candidate_views_.empty() && | 1022 if (!candidate_views_.empty() && |
| 1016 lookup_table_.orientation() == IBusLookupTable::VERTICAL) { | 1023 candidate_window_.orientation() == CandidateWindow::VERTICAL) { |
| 1017 return - candidate_views_[0]->GetCandidateLabelPosition().x(); | 1024 return - candidate_views_[0]->GetCandidateLabelPosition().x(); |
| 1018 } | 1025 } |
| 1019 return 0; | 1026 return 0; |
| 1020 } | 1027 } |
| 1021 | 1028 |
| 1022 void CandidateWindowView::VisibilityChanged(View* starting_from, | 1029 void CandidateWindowView::VisibilityChanged(View* starting_from, |
| 1023 bool is_visible) { | 1030 bool is_visible) { |
| 1024 if (is_visible) { | 1031 if (is_visible) { |
| 1025 // If the visibility of candidate window is changed, | 1032 // If the visibility of candidate window is changed, |
| 1026 // we should move the frame to the right position. | 1033 // we should move the frame to the right position. |
| 1027 ResizeAndMoveParentFrame(); | 1034 ResizeAndMoveParentFrame(); |
| 1028 } | 1035 } |
| 1029 } | 1036 } |
| 1030 | 1037 |
| 1031 void CandidateWindowView::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 1038 void CandidateWindowView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 1032 // If the bounds(size) of candidate window is changed, | 1039 // If the bounds(size) of candidate window is changed, |
| 1033 // we should move the frame to the right position. | 1040 // we should move the frame to the right position. |
| 1034 View::OnBoundsChanged(previous_bounds); | 1041 View::OnBoundsChanged(previous_bounds); |
| 1035 ResizeAndMoveParentFrame(); | 1042 ResizeAndMoveParentFrame(); |
| 1036 } | 1043 } |
| 1037 | 1044 |
| 1038 } // namespace input_method | 1045 } // namespace input_method |
| 1039 } // namespace chromeos | 1046 } // namespace chromeos |
| OLD | NEW |