15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/candidate_window_view.h" 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/candidate_view.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/candidate_window_constants.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/hidable_area.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/ibus/ibus_lookup_table.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/gfx/color_utils.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/native_theme/native_theme.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace input_method { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VerticalCandidateLabel is used for rendering candidate text in 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the vertical candidate window. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VerticalCandidateLabel : public views::Label { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerticalCandidateLabel() {} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~VerticalCandidateLabel() {} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the preferred size, but guarantees that the width has at 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // least kMinCandidateLabelWidth pixels. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual gfx::Size GetPreferredSize() OVERRIDE { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size size = Label::GetPreferredSize(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hack. +2 is needed to prevent labels from getting elided like 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "abc..." in some cases. TODO(satorux): Figure out why it's 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessary. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.set_width(size.width() + 2); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size.width() < kMinCandidateLabelWidth) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.set_width(kMinCandidateLabelWidth); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size.width() > kMaxCandidateLabelWidth) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.set_width(kMaxCandidateLabelWidth); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VerticalCandidateLabel); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wraps the given view with some padding, and returns it. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* WrapWithPadding(views::View* view, const gfx::Insets& insets) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* wrapper = new views::View; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use GridLayout to give some insets inside. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout* layout = new views::GridLayout(wrapper); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wrapper->SetLayoutManager(layout); // |wrapper| owns |layout|. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->SetInsets(insets); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ColumnSet* column_set = layout->AddColumnSet(0); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, views::GridLayout::FILL, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, views::GridLayout::USE_PREF, 0, 0); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the view contents. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(view); // |view| is owned by |wraper|, not |layout|. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return wrapper; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates shortcut text from the given index and the orientation. 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 CreateShortcutText(size_t index, const IBusLookupTable& table) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index >= table.candidates().size()) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return UTF8ToUTF16(""); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string shortcut_text = table.candidates()[index].label; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shortcut_text.empty() && 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) table.orientation() != IBusLookupTable::VERTICAL) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_text += '.'; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF8ToUTF16(shortcut_text); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates the shortcut label, and returns it (never returns NULL). 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The label text is not set in this function. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Label* CreateShortcutLabel( 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IBusLookupTable::Orientation orientation, const ui::NativeTheme& theme) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the shortcut label. The label will be owned by 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |wrapped_shortcut_label|, hence it's deleted when 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |wrapped_shortcut_label| is deleted. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Label* shortcut_label = new views::Label; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation == IBusLookupTable::VERTICAL) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label->SetFont( 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label->font().DeriveFont(kFontSizeDelta, gfx::Font::BOLD)); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label->SetFont( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label->font().DeriveFont(kFontSizeDelta)); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(satorux): Maybe we need to use language specific fonts for 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // candidate_label, like Chinese font for Chinese input method? 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch shortcut_label->SetEnabledColor(theme.GetSystemColor( 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_LabelEnabledColor)); 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch shortcut_label->SetDisabledColor(theme.GetSystemColor( 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_LabelDisabledColor)); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return shortcut_label; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wraps the shortcut label, then decorates wrapped shortcut label 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and returns it (never returns NULL). 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The label text is not set in this function. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* CreateWrappedShortcutLabel( 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Label* shortcut_label, 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IBusLookupTable::Orientation orientation, 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ui::NativeTheme& theme) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrap it with padding. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Insets insets = 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (orientation == IBusLookupTable::VERTICAL ? 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kVerticalShortcutLabelInsets : 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kHorizontalShortcutLabelInsets); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* wrapped_shortcut_label = 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WrapWithPadding(shortcut_label, insets); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add decoration based on the orientation. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation == IBusLookupTable::VERTICAL) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the background color. 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkColor blackish = color_utils::AlphaBlend( 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SK_ColorBLACK, 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground), 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 0x40); 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SkColor transparent_blakish = color_utils::AlphaBlend( 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SK_ColorTRANSPARENT, blackish, 0xE0); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wrapped_shortcut_label->set_background( 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch views::Background::CreateSolidBackground(transparent_blakish)); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label->SetBackgroundColor( 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wrapped_shortcut_label->background()->get_color()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return wrapped_shortcut_label; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates the candidate label, and returns it (never returns NULL). 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The label text is not set in this function. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Label* CreateCandidateLabel( 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IBusLookupTable::Orientation orientation) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Label* candidate_label = NULL; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the candidate label. The label will be added to |this| as a 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // child view, hence it's deleted when |this| is deleted. 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation == IBusLookupTable::VERTICAL) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label = new VerticalCandidateLabel; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label = new views::Label; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the font size. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label->SetFont( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label->font().DeriveFont(kFontSizeDelta)); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return candidate_label; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates the annotation label, and return it (never returns NULL). 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The label text is not set in this function. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Label* CreateAnnotationLabel( 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IBusLookupTable::Orientation orientation, const ui::NativeTheme& theme) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the annotation label. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Label* annotation_label = new views::Label; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the font size and color. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_label->SetFont( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_label->font().DeriveFont(kFontSizeDelta)); 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch annotation_label->SetEnabledColor(theme.GetSystemColor( 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_LabelDisabledColor)); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return annotation_label; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Computes shortcut column size. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size ComputeShortcutColumnSize( 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IBusLookupTable& lookup_table, 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ui::NativeTheme& theme) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shortcut_column_width = 0; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int shortcut_column_height = 0; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the shortcut label. The label will be owned by 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |wrapped_shortcut_label|, hence it's deleted when 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |wrapped_shortcut_label| is deleted. 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Label* shortcut_label = CreateShortcutLabel( 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch lookup_table.orientation(), theme); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::View> wrapped_shortcut_label( 1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateWrappedShortcutLabel(shortcut_label, 1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch lookup_table.orientation(), 1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch theme)); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the max width and height in shortcut labels. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll create temporary shortcut labels, and choose the largest width and 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // height. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < lookup_table.page_size(); ++i) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label->SetText(CreateShortcutText(i, lookup_table)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size text_size = wrapped_shortcut_label->GetPreferredSize(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_column_width = std::max(shortcut_column_width, text_size.width()); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_column_height = std::max(shortcut_column_height, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size.height()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(shortcut_column_width, shortcut_column_height); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Computes the page index. For instance, if the page size is 9, and the 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cursor is pointing to 13th candidate, the page index will be 1 (2nd 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// page, as the index is zero-origin). Returns -1 on error. 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ComputePageIndex(const IBusLookupTable& lookup_table) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (lookup_table.page_size() > 0) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return lookup_table.cursor_position() / lookup_table.page_size(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Computes candidate column size. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size ComputeCandidateColumnSize( 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IBusLookupTable& lookup_table) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int candidate_column_width = 0; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int candidate_column_height = 0; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::Label> candidate_label( 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateCandidateLabel(lookup_table.orientation())); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the start index of |lookup_table_|. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int current_page_index = ComputePageIndex(lookup_table); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_page_index < 0) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(0, 0); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t start_from = current_page_index * lookup_table.page_size(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the max width and height in candidate labels. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll create temporary candidate labels, and choose the largest width and 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // height. 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i + start_from < lookup_table.candidates().size(); ++i) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t index = start_from + i; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label->SetText( 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UTF8ToUTF16(lookup_table.candidates()[index].value)); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size text_size = candidate_label->GetPreferredSize(); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_column_width = std::max(candidate_column_width, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size.width()); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_column_height = std::max(candidate_column_height, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size.height()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(candidate_column_width, candidate_column_height); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Computes annotation column size. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size ComputeAnnotationColumnSize( 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const IBusLookupTable& lookup_table, const ui::NativeTheme& theme) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int annotation_column_width = 0; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int annotation_column_height = 0; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::Label> annotation_label( 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateAnnotationLabel(lookup_table.orientation(), theme)); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the start index of |lookup_table_|. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int current_page_index = ComputePageIndex(lookup_table); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_page_index < 0) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(0, 0); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t start_from = current_page_index * lookup_table.page_size(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute max width and height in annotation labels. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We'll create temporary annotation labels, and choose the largest width and 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // height. 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i + start_from < lookup_table.candidates().size(); ++i) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t index = start_from + i; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_label->SetText( 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UTF8ToUTF16(lookup_table.candidates()[index].annotation)); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size text_size = annotation_label->GetPreferredSize(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_column_width = std::max(annotation_column_width, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size.width()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_column_height = std::max(annotation_column_height, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_size.height()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(annotation_column_width, annotation_column_height); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InformationTextArea is a HidableArea having a single Label in it. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InformationTextArea : public HidableArea { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Specify the alignment and initialize the control. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InformationTextArea(gfx::HorizontalAlignment align, int minWidth) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : minWidth_(minWidth) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_ = new views::Label; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_->SetHorizontalAlignment(align); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Insets kInsets(2, 2, 2, 4); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* contents = WrapWithPadding(label_, kInsets); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetContents(contents); 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch contents->set_border(views::Border::CreateSolidBorder( 3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1, 3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetNativeTheme()->GetSystemColor( 3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_MenuBorderColor))); 3047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch contents->set_background(views::Background::CreateSolidBackground( 3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch color_utils::AlphaBlend(SK_ColorBLACK, 3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetNativeTheme()->GetSystemColor( 3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_WindowBackground), 3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 0x10))); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_->SetBackgroundColor(contents->background()->get_color()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the displayed text. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetText(const std::string& utf8_text) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label_->SetText(UTF8ToUTF16(utf8_text)); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual gfx::Size GetPreferredSize() OVERRIDE { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size size = HidableArea::GetPreferredSize(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hack. +2 is needed as the same reason as in VerticalCandidateLabel 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.set_width(size.width() + 2); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size.width() < minWidth_) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size.set_width(minWidth_); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Label* label_; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int minWidth_; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(InformationTextArea); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CandidateView::CandidateView( 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateWindowView* parent_candidate_window, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index_in_page, 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IBusLookupTable::Orientation orientation) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : index_in_page_(index_in_page), 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orientation_(orientation), 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_candidate_window_(parent_candidate_window), 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label_(NULL), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label_(NULL), 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_label_(NULL), 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_(NULL), 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_enabled_(false) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::Init(int shortcut_column_width, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int candidate_column_width, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int annotation_column_width, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int column_height) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout* layout = new views::GridLayout(this); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetLayoutManager(layout); // |this| owns |layout|. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create Labels. 3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ui::NativeTheme& theme = *GetNativeTheme(); 3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch shortcut_label_ = CreateShortcutLabel(orientation_, theme); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* wrapped_shortcut_label = 3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateWrappedShortcutLabel(shortcut_label_, orientation_, theme); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label_ = CreateCandidateLabel(orientation_); 3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch annotation_label_ = CreateAnnotationLabel(orientation_, theme); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the column set with three columns. 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ColumnSet* column_set = layout->AddColumnSet(0); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If orientation is vertical, each column width is fixed. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise the width is resizable. 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const views::GridLayout::SizeType column_type = 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) orientation_ == IBusLookupTable::VERTICAL ? 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FIXED : views::GridLayout::USE_PREF; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int padding_column_width = 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) orientation_ == IBusLookupTable::VERTICAL ? 4 : 6; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set shortcut column type and width. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, column_type, shortcut_column_width, 0); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddPaddingColumn(0, padding_column_width); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set candidate column type and width. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, views::GridLayout::USE_PREF, 0, 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) orientation_ == IBusLookupTable::VERTICAL ? 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_column_width : 0); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddPaddingColumn(0, padding_column_width); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set annotation column type and width. 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, column_type, annotation_column_width, 0); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation_ == IBusLookupTable::VERTICAL) { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddPaddingColumn(0, 1); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FIXED, kInfolistIndicatorIconWidth, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddPaddingColumn(0, 2); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddPaddingColumn(0, padding_column_width); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the shortcut label, the candidate label, and annotation label. 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |wrapped_shortcut_label|, |candidate_label_|, and |annotation_label_| 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be owned by |this|. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(wrapped_shortcut_label, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Column span. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Row span. 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, // Horizontal alignment. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, // Vertical alignment. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, // Preferred width, not specified. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_height); // Preferred height. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(candidate_label_, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Column span. 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Row span. 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, // Horizontal alignment. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, // Vertical alignment. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, // Preferred width, not specified. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_height); // Preferred height. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(annotation_label_, 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Column span. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Row span. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, // Horizontal alignment. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, // Vertical alignemnt. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, // Preferred width, not specified. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_height); // Preferred height. 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation_ == IBusLookupTable::VERTICAL) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_ = new views::View; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* infolist_icon_wrapper = new views::View; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout* infolist_icon_layout = 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new views::GridLayout(infolist_icon_wrapper); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |infolist_icon_layout| is owned by |infolist_icon_wrapper|. 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_wrapper->SetLayoutManager(infolist_icon_layout); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_layout->AddColumnSet(0)->AddColumn( 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, views::GridLayout::FILL, 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, views::GridLayout::FIXED, kInfolistIndicatorIconWidth, 0); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_layout->AddPaddingRow(0, kInfolistIndicatorIconPadding); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_layout->StartRow(1.0, 0); // infolist_icon_ is resizable. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |infolist_icon_| is owned by |infolist_icon_wrapper|. 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_layout->AddView(infolist_icon_); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_layout->AddPaddingRow(0, kInfolistIndicatorIconPadding); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |infolist_icon_wrapper| is owned by |this|. 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(infolist_icon_wrapper); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateLabelBackgroundColors(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::SetCandidateText(const string16& text) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label_->SetText(text); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::SetShortcutText(const string16& text) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label_->SetText(text); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::SetAnnotationText(const string16& text) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_label_->SetText(text); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::SetInfolistIcon(bool enable) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!infolist_icon_ || (infolist_icon_enabled_ == enable)) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infolist_icon_enabled_ = enable; 4647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch infolist_icon_->set_background( 4657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch enable ? 4667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor( 4677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_FocusedBorderColor)) : 4687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NULL); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateLabelBackgroundColors(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::Select() { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_background( 4757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor( 4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused))); 4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch set_border(views::Border::CreateSolidBorder( 4787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1, GetNativeTheme()->GetSystemColor( 4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_FocusedBorderColor))); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateLabelBackgroundColors(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need to call SchedulePaint() for background and border color changes. 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::Unselect() { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_background(NULL); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_border(NULL); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateLabelBackgroundColors(); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SchedulePaint(); // See comments at Select(). 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::SetRowEnabled(bool enabled) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label_->SetEnabled(enabled); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point CandidateView::GetCandidateLabelPosition() const { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return candidate_label_->GetMirroredPosition(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CandidateView::OnMousePressed(const ui::MouseEvent& event) { 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(kinaba): On Windows and MacOS, candidate windows typically commits a 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // candidate at OnMouseReleased event. We have chosen OnMousePressed here for 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // working around several obstacle rising from views implementation over GTK. 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See: http://crosbug.com/11423#c11. Since we have moved from GTK to Aura, 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the reasoning should have became obsolete. We might want to reconsider 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // implementing mouse-up selection. 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SelectCandidateAt(event.location()); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CandidateView::OnGestureEvent(ui::GestureEvent* event) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event->type() == ui::ET_GESTURE_TAP) { 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SelectCandidateAt(event->location()); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) View::OnGestureEvent(event); 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CandidateView::SelectCandidateAt(const gfx::Point& location) { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Point location_in_candidate_window = location; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View::ConvertPointToTarget(this, parent_candidate_window_, 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &location_in_candidate_window); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_candidate_window_->OnCandidatePressed(location_in_candidate_window); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_candidate_window_->CommitCandidate(); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateView::UpdateLabelBackgroundColors() { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor color = background() ? 5307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch background()->get_color() : 5317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetNativeTheme()->GetSystemColor( 5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_WindowBackground); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation_ != IBusLookupTable::VERTICAL) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shortcut_label_->SetBackgroundColor(color); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_label_->SetBackgroundColor(color); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_label_->SetBackgroundColor(color); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CandidateWindowView::CandidateWindowView(views::Widget* parent_frame) 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : selected_candidate_index_in_page_(-1), 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_frame_(parent_frame), 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preedit_area_(NULL), 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_(NULL), 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_(NULL), 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_(NULL), 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_shortcut_column_size_(0, 0), 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_candidate_column_size_(0, 0), 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_annotation_column_size_(0, 0), 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_show_at_composition_head_(false), 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_show_upper_side_(false), 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_candidate_window_open_(false) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CandidateWindowView::~CandidateWindowView() { 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::Init() { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the background and the border of the view. 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_background( 5607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor( 5617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_WindowBackground))); 5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch set_border(views::Border::CreateSolidBorder( 5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1, GetNativeTheme()->GetSystemColor( 5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ui::NativeTheme::kColorId_MenuBorderColor))); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create areas. 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preedit_area_ = new InformationTextArea(gfx::ALIGN_LEFT, 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinPreeditAreaWidth); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_ = new InformationTextArea(gfx::ALIGN_LEFT, 0); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_ = new HidableArea; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_->SetContents(new views::View); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_ = new InformationTextArea(gfx::ALIGN_RIGHT, 0); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the window layout of the view 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout* layout = new views::GridLayout(this); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetLayoutManager(layout); // |this| owns |layout|. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ColumnSet* column_set = layout->AddColumnSet(0); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, views::GridLayout::USE_PREF, 0, 0); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the preedit area 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(preedit_area_); // |preedit_area_| is owned by |this|. 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the header area. 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(header_area_); // |header_area_| is owned by |this|. 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the candidate area. 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(candidate_area_); // |candidate_area_| is owned by |this|. 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the footer area. 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(footer_area_); // |footer_area_| is owned by |this|. 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::HideAll() { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_frame_->Hide(); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyIfCandidateWindowOpenedOrClosed(); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::UpdateParentArea() { 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (candidate_area_->IsShown() || 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_->IsShown() || 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_->IsShown() || 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preedit_area_->IsShown()) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResizeAndMoveParentFrame(); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_frame_->Show(); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_frame_->Hide(); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyIfCandidateWindowOpenedOrClosed(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::HideLookupTable() { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_->Hide(); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateParentArea(); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::HideAuxiliaryText() { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_->Hide(); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_->Hide(); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateParentArea(); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::ShowAuxiliaryText() { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If candidate_area is not shown, shows auxiliary text at header_area. 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We expect both header_area_ and footer_area_ contain same value. 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!candidate_area_->IsShown()) { 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_->Show(); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_->Hide(); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If candidate_area is shown, shows auxiliary text with orientation. 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (lookup_table_.orientation() == IBusLookupTable::HORIZONTAL) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_->Show(); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_->Hide(); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_->Show(); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_->Hide(); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateParentArea(); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::UpdateAuxiliaryText(const std::string& utf8_text) { 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header_area_->SetText(utf8_text); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) footer_area_->SetText(utf8_text); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowAuxiliaryText(); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::HidePreeditText() { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preedit_area_->Hide(); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateParentArea(); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::ShowPreeditText() { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preedit_area_->Show(); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateParentArea(); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::UpdatePreeditText(const std::string& utf8_text) { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preedit_area_->SetText(utf8_text); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::ShowLookupTable() { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!candidate_area_->IsShown()) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_show_upper_side_ = false; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_->Show(); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateParentArea(); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::NotifyIfCandidateWindowOpenedOrClosed() { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_open = IsCandidateWindowOpen(); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!was_candidate_window_open_ && is_open) { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowOpened()); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (was_candidate_window_open_ && !is_open) { 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowClosed()); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_candidate_window_open_ = is_open; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CandidateWindowView::ShouldUpdateCandidateViews( 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IBusLookupTable& old_table, 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IBusLookupTable& new_table) { 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !old_table.IsEqual(new_table); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::UpdateCandidates( 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IBusLookupTable& new_lookup_table) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool should_update = ShouldUpdateCandidateViews(lookup_table_, 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_lookup_table); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Updating the candidate views is expensive. We'll skip this if possible. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_update) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize candidate views if necessary. 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeInitializeCandidateViews(new_lookup_table); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) should_show_at_composition_head_ 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) = new_lookup_table.show_window_at_composition(); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the index of the current page. 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int current_page_index = ComputePageIndex(new_lookup_table); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_page_index < 0) { 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the candidates in the current page. 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t start_from = current_page_index * new_lookup_table.page_size(); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In some cases, engines send empty shortcut labels. For instance, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ibus-mozc sends empty labels when they show suggestions. In this 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // case, we should not show shortcut labels. 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool no_shortcut_mode = true; 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < new_lookup_table.candidates().size(); ++i) { 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!new_lookup_table.candidates()[i].label.empty()) { 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) no_shortcut_mode = false; 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < candidate_views_.size(); ++i) { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t index_in_page = i; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t candidate_index = start_from + index_in_page; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateView* candidate_view = candidate_views_[index_in_page]; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the shortcut text. 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (no_shortcut_mode) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_view->SetShortcutText(string16()); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this moment, we don't use labels sent from engines for UX 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reasons. First, we want to show shortcut labels in empty rows 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (ex. show 6, 7, 8, ... in empty rows when the number of 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // candidates is 5). Second, we want to add a period after each 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shortcut label when the candidate window is horizontal. 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_view->SetShortcutText( 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateShortcutText(i, new_lookup_table)); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the candidate text. 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (candidate_index < new_lookup_table.candidates().size()) { 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IBusLookupTable::Entry& entry = 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_lookup_table.candidates()[candidate_index]; 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_view->SetCandidateText(UTF8ToUTF16(entry.value)); 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_view->SetAnnotationText(UTF8ToUTF16(entry.annotation)); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_view->SetRowEnabled(true); 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_view->SetInfolistIcon(!entry.description_title.empty()); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable the empty row. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_view->SetCandidateText(string16()); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_view->SetAnnotationText(string16()); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_view->SetRowEnabled(false); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_view->SetInfolistIcon(false); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the current lookup table. We'll use lookup_table_ from here. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that SelectCandidateAt() uses lookup_table_. 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_table_.CopyFrom(new_lookup_table); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Select the current candidate in the page. 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (lookup_table_.is_cursor_visible()) { 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (lookup_table_.page_size()) { 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int current_candidate_in_page = 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup_table_.cursor_position() % lookup_table_.page_size(); 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SelectCandidateAt(current_candidate_in_page); 763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Unselect the currently selected candidate. 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (0 <= selected_candidate_index_in_page_ && 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<size_t>(selected_candidate_index_in_page_) < 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) candidate_views_.size()) { 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) candidate_views_[selected_candidate_index_in_page_]->Unselect(); 770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) selected_candidate_index_in_page_ = -1; 771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::MaybeInitializeCandidateViews( 7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IBusLookupTable& lookup_table) { 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IBusLookupTable::Orientation orientation = 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_table.orientation(); 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int page_size = lookup_table.page_size(); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* candidate_area_contents = candidate_area_->contents(); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Current column width. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size shortcut_column_size(0, 0); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size candidate_column_size(0,0); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size annotation_column_size(0, 0); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If orientation is horizontal, don't need to compute width, 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because each label is left aligned. 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation == IBusLookupTable::VERTICAL) { 7907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const ui::NativeTheme& theme = *GetNativeTheme(); 7917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch shortcut_column_size = ComputeShortcutColumnSize(lookup_table, theme); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_column_size = ComputeCandidateColumnSize(lookup_table); 7937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch annotation_column_size = ComputeAnnotationColumnSize(lookup_table, theme); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the requested number of views matches the number of current views, and 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // previous and current column width are same, just reuse these. 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the early exit logic is not only useful for improving 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // performance, but also necessary for the horizontal candidate window 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be redrawn properly. If we get rid of the logic, the horizontal 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // candidate window won't get redrawn properly for some reason when 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there is no size change. You can test this by removing "return" here 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and type "ni" with Pinyin input method. 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (static_cast<int>(candidate_views_.size()) == page_size && 8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_table_.orientation() == orientation && 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_shortcut_column_size_ == shortcut_column_size && 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_candidate_column_size_ == candidate_column_size && 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_annotation_column_size_ == annotation_column_size) { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the previous column widths. 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_shortcut_column_size_ = shortcut_column_size; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_candidate_column_size_ = candidate_column_size; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_annotation_column_size_ = annotation_column_size; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the existing candidate_views if any. 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < candidate_views_.size(); ++i) { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_contents->RemoveChildView(candidate_views_[i]); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the view after getting out the current message loop iteration. 82290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, candidate_views_[i]); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_views_.clear(); 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) selected_candidate_index_in_page_ = -1; // Invalidates the index. 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout* layout = new views::GridLayout(candidate_area_contents); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |candidate_area_contents| owns |layout|. 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_contents->SetLayoutManager(layout); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the column set. 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ColumnSet* column_set = layout->AddColumnSet(0); 8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation == IBusLookupTable::VERTICAL) { 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn(views::GridLayout::FILL, 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, views::GridLayout::USE_PREF, 0, 0); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < page_size; ++i) { 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) column_set->AddColumn(views::GridLayout::FILL, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FILL, 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, views::GridLayout::USE_PREF, 0, 0); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set insets so the border of the selected candidate is drawn inside of 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the border of the main candidate window, but we don't have the inset 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at the top and the bottom as we have the borders of the header and 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // footer areas. 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Insets kCandidateAreaInsets(0, 1, 0, 1); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->SetInsets(kCandidateAreaInsets.top(), 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCandidateAreaInsets.left(), 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCandidateAreaInsets.bottom(), 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCandidateAreaInsets.right()); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use maximum height for all rows in candidate area. 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kColumnHeight = std::max(shortcut_column_size.height(), 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(candidate_column_size.height(), 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_column_size.height())); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add views to the candidate area. 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation == IBusLookupTable::HORIZONTAL) { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < page_size; ++i) { 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CandidateView* candidate_row = new CandidateView(this, i, orientation); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_row->Init(shortcut_column_size.width(), 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_column_size.width(), 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) annotation_column_size.width(), 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kColumnHeight); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_views_.push_back(candidate_row); 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (orientation == IBusLookupTable::VERTICAL) { 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |candidate_row| will be owned by |candidate_area_contents|. 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(candidate_row, 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Column span. 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, // Row span. 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Horizontal alignment. 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) orientation == IBusLookupTable::VERTICAL ? 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::GridLayout::FILL : views::GridLayout::CENTER, 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::CENTER, // Vertical alignment. 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, // Preferred width, not specified. 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kColumnHeight); // Preferred height. 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute views size in |layout|. 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't call this function, GetHorizontalOffset() often 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns invalid value (returns 0), then candidate window 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // moves right from the correct position in ResizeAndMoveParentFrame(). 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(nhiroki): Figure out why it returns invalid value. 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It seems that the x-position of the candidate labels is not set. 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->Layout(candidate_area_contents); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CandidateWindowView::IsCandidateWindowOpen() const { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !should_show_at_composition_head_ && 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_area_->visible() && candidate_area_->IsShown(); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::SelectCandidateAt(int index_in_page) { 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int current_page_index = ComputePageIndex(lookup_table_); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_page_index < 0) { 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int cursor_absolute_index = 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_table_.page_size() * current_page_index + index_in_page; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore click on out of range views. 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor_absolute_index < 0 || 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_table_.candidates().size() <= 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<size_t>(cursor_absolute_index)) { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unselect the currently selected candidate. 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (0 <= selected_candidate_index_in_page_ && 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<size_t>(selected_candidate_index_in_page_) < 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_views_.size()) { 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) candidate_views_[selected_candidate_index_in_page_]->Unselect(); 9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remember the currently selected candidate index in the current page. 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_candidate_index_in_page_ = index_in_page; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Select the candidate specified by index_in_page. 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) candidate_views_[index_in_page]->Select(); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the cursor indexes in the model. 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_table_.set_cursor_position(cursor_absolute_index); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::OnCandidatePressed( 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& location) { 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < candidate_views_.size(); ++i) { 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point converted_location = location; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View::ConvertPointToTarget(this, candidate_views_[i], 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &converted_location); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (candidate_views_[i]->HitTestPoint(converted_location)) { 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectCandidateAt(i); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::CommitCandidate() { 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(0 <= selected_candidate_index_in_page_ && 946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<size_t>(selected_candidate_index_in_page_) < 947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) candidate_views_.size())) { 948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; // Out of range, do nothing. 949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, we don't distinguish left and right clicks. 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int button = 1; // Left button. 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int key_modifilers = 0; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCandidateCommitted(selected_candidate_index_in_page_, 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button, 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_modifilers)); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::ResizeAndMoveParentFrame() { 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If rendering operation comes from mozc-engine, uses mozc specific location, 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise lookup table is shown under the cursor. 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int x = should_show_at_composition_head_? 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) composition_head_location_.x() : cursor_location_.x(); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To avoid lookup-table overlapping, uses maximum y-position of mozc specific 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // location and cursor location, because mozc-engine does not consider about 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // multi-line composition. 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int y = should_show_at_composition_head_? 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(composition_head_location_.y(), cursor_location_.y()) : 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor_location_.y(); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int height = cursor_location_.height(); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int horizontal_offset = GetHorizontalOffset(); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect old_bounds = parent_frame_->GetClientAreaBoundsInScreen(); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect screen_bounds = ash::Shell::GetScreen()->GetDisplayMatching( 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor_location_).work_area(); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The size. 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect frame_bounds = old_bounds; 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_bounds.set_size(GetPreferredSize()); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The default position. 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_bounds.set_x(x + horizontal_offset); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_bounds.set_y(y + height); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle overflow at the left and the top. 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_bounds.set_x(std::max(frame_bounds.x(), screen_bounds.x())); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_bounds.set_y(std::max(frame_bounds.y(), screen_bounds.y())); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle overflow at the right. 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int right_overflow = frame_bounds.right() - screen_bounds.right(); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (right_overflow > 0) { 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_bounds.set_x(frame_bounds.x() - right_overflow); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle overflow at the bottom. 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int bottom_overflow = frame_bounds.bottom() - screen_bounds.bottom(); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To avoid flickering window position, the candidate window should be shown 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on upper side of composition string if it was shown there. 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_show_upper_side_ || bottom_overflow > 0) { 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_bounds.set_y(frame_bounds.y() - height - frame_bounds.height()); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) should_show_upper_side_ = true; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(nona): check top_overflow here. 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the window per the cursor location. 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SetBounds() is not cheap. Only call this when it is really changed. 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame_bounds != old_bounds) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_frame_->SetBounds(frame_bounds); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CandidateWindowView::GetHorizontalOffset() { 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute the horizontal offset if the lookup table is vertical. 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!candidate_views_.empty() && 10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_table_.orientation() == IBusLookupTable::VERTICAL) { 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return - candidate_views_[0]->GetCandidateLabelPosition().x(); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::VisibilityChanged(View* starting_from, 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_visible) { 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visible) { 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the visibility of candidate window is changed, 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we should move the frame to the right position. 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResizeAndMoveParentFrame(); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CandidateWindowView::OnBoundsChanged(const gfx::Rect& previous_bounds) { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the bounds(size) of candidate window is changed, 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we should move the frame to the right position. 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View::OnBoundsChanged(previous_bounds); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResizeAndMoveParentFrame(); 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace input_method 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chromeos 1040