Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4757)

Unified Diff: chrome/browser/chromeos/input_method/candidate_window_view.cc

Issue 121163003: Cleanup CandidateWindowView. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/input_method/candidate_window_view.cc
diff --git a/chrome/browser/chromeos/input_method/candidate_window_view.cc b/chrome/browser/chromeos/input_method/candidate_window_view.cc
index bd97f6ea069fbf9a50e3b22226cd011ca65bf0c8..23acaa922c54ad65a5d1d5af3928e1f926c410c2 100644
--- a/chrome/browser/chromeos/input_method/candidate_window_view.cc
+++ b/chrome/browser/chromeos/input_method/candidate_window_view.cc
@@ -5,216 +5,72 @@
#include <string>
-#include "ash/shell.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/input_method/candidate_view.h"
#include "chrome/browser/chromeos/input_method/candidate_window_constants.h"
-#include "chrome/browser/chromeos/input_method/hidable_area.h"
#include "chromeos/ime/candidate_window.h"
#include "ui/gfx/color_utils.h"
+#include "ui/gfx/screen.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
+#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/label.h"
-#include "ui/views/layout/grid_layout.h"
-#include "ui/views/widget/widget.h"
+#include "ui/views/corewm/window_animations.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/fill_layout.h"
namespace chromeos {
namespace input_method {
namespace {
-// VerticalCandidateLabel is used for rendering candidate text in
-// the vertical candidate window.
-class VerticalCandidateLabel : public views::Label {
- public:
- VerticalCandidateLabel() {}
-
- private:
- virtual ~VerticalCandidateLabel() {}
- // Returns the preferred size, but guarantees that the width has at
- // least kMinCandidateLabelWidth pixels.
- virtual gfx::Size GetPreferredSize() OVERRIDE {
- gfx::Size size = Label::GetPreferredSize();
- // Hack. +2 is needed to prevent labels from getting elided like
- // "abc..." in some cases. TODO(satorux): Figure out why it's
- // necessary.
- size.set_width(size.width() + 2);
- if (size.width() < kMinCandidateLabelWidth) {
- size.set_width(kMinCandidateLabelWidth);
- }
- if (size.width() > kMaxCandidateLabelWidth) {
- size.set_width(kMaxCandidateLabelWidth);
- }
- return size;
+class CandidateWindowBorder : public views::BubbleBorder {
+ public:
+ explicit CandidateWindowBorder(gfx::NativeView parent)
+ : views::BubbleBorder(views::BubbleBorder::TOP_CENTER,
+ views::BubbleBorder::NO_SHADOW,
+ SK_ColorTRANSPARENT),
+ parent_(parent),
+ offset_(0) {
+ set_paint_arrow(views::BubbleBorder::PAINT_NONE);
}
+ virtual ~CandidateWindowBorder() {}
- DISALLOW_COPY_AND_ASSIGN(VerticalCandidateLabel);
-};
-
-// Wraps the given view with some padding, and returns it.
-views::View* WrapWithPadding(views::View* view, const gfx::Insets& insets) {
- views::View* wrapper = new views::View;
- // Use GridLayout to give some insets inside.
- views::GridLayout* layout = new views::GridLayout(wrapper);
- wrapper->SetLayoutManager(layout); // |wrapper| owns |layout|.
- layout->SetInsets(insets);
-
- views::ColumnSet* column_set = layout->AddColumnSet(0);
- column_set->AddColumn(
- views::GridLayout::FILL, views::GridLayout::FILL,
- 1, views::GridLayout::USE_PREF, 0, 0);
- layout->StartRow(0, 0);
-
- // Add the view contents.
- layout->AddView(view); // |view| is owned by |wraper|, not |layout|.
- return wrapper;
-}
-
-// Creates shortcut text from the given index and the orientation.
-base::string16 CreateShortcutText(size_t index,
- const CandidateWindow& candidate_window) {
- if (index >= candidate_window.candidates().size())
- return base::string16();
- std::string shortcut_text = candidate_window.candidates()[index].label;
- if (!shortcut_text.empty() &&
- candidate_window.orientation() != CandidateWindow::VERTICAL)
- shortcut_text += '.';
- return base::UTF8ToUTF16(shortcut_text);
-}
-
-// Creates the shortcut label, and returns it (never returns NULL).
-// The label text is not set in this function.
-views::Label* CreateShortcutLabel(
- CandidateWindow::Orientation orientation, const ui::NativeTheme& theme) {
- // Create the shortcut label. The label will be owned by
- // |wrapped_shortcut_label|, hence it's deleted when
- // |wrapped_shortcut_label| is deleted.
- views::Label* shortcut_label = new views::Label;
-
- if (orientation == CandidateWindow::VERTICAL) {
- shortcut_label->SetFontList(
- shortcut_label->font_list().DeriveFontListWithSizeDeltaAndStyle(
- kFontSizeDelta, gfx::Font::BOLD));
- } else {
- shortcut_label->SetFontList(
- shortcut_label->font_list().DeriveFontListWithSizeDelta(
- kFontSizeDelta));
- }
- // TODO(satorux): Maybe we need to use language specific fonts for
- // candidate_label, like Chinese font for Chinese input method?
- shortcut_label->SetEnabledColor(theme.GetSystemColor(
- ui::NativeTheme::kColorId_LabelEnabledColor));
- shortcut_label->SetDisabledColor(theme.GetSystemColor(
- ui::NativeTheme::kColorId_LabelDisabledColor));
+ void set_offset(int offset) { offset_ = offset; }
- return shortcut_label;
-}
+ private:
+ // Overridden from views::BubbleBorder:
+ virtual gfx::Rect GetBounds(const gfx::Rect& anchor_rect,
+ const gfx::Size& content_size) const OVERRIDE {
+ gfx::Rect bounds(content_size);
+ bounds.set_origin(gfx::Point(
+ anchor_rect.x() - offset_,
+ is_arrow_on_top(arrow()) ?
+ anchor_rect.bottom() : anchor_rect.y() - content_size.height()));
-// Wraps the shortcut label, then decorates wrapped shortcut label
-// and returns it (never returns NULL).
-// The label text is not set in this function.
-views::View* CreateWrappedShortcutLabel(
- views::Label* shortcut_label,
- CandidateWindow::Orientation orientation,
- const ui::NativeTheme& theme) {
- // Wrap it with padding.
- const gfx::Insets kVerticalShortcutLabelInsets(1, 6, 1, 6);
- const gfx::Insets kHorizontalShortcutLabelInsets(1, 3, 1, 0);
- const gfx::Insets insets =
- (orientation == CandidateWindow::VERTICAL ?
- kVerticalShortcutLabelInsets :
- kHorizontalShortcutLabelInsets);
- views::View* wrapped_shortcut_label =
- WrapWithPadding(shortcut_label, insets);
+ // It cannot use the normal logic of arrow offset for horizontal offscreen,
+ // because the arrow must be in the content's edge. But CandidateWindow has
+ // to be visible even when |anchor_rect| is out of the screen.
+ gfx::Rect work_area = gfx::Screen::GetNativeScreen()->
+ GetDisplayNearestWindow(parent_).work_area();
+ if (bounds.right() > work_area.right())
+ bounds.set_x(work_area.right() - bounds.width());
+ if (bounds.x() < work_area.x())
+ bounds.set_x(work_area.x());
- // Add decoration based on the orientation.
- if (orientation == CandidateWindow::VERTICAL) {
- // Set the background color.
- SkColor blackish = color_utils::AlphaBlend(
- SK_ColorBLACK,
- theme.GetSystemColor(ui::NativeTheme::kColorId_WindowBackground),
- 0x40);
- SkColor transparent_blakish = color_utils::AlphaBlend(
- SK_ColorTRANSPARENT, blackish, 0xE0);
- wrapped_shortcut_label->set_background(
- views::Background::CreateSolidBackground(transparent_blakish));
- shortcut_label->SetBackgroundColor(
- wrapped_shortcut_label->background()->get_color());
+ return bounds;
}
- return wrapped_shortcut_label;
-}
-
-// Creates the candidate label, and returns it (never returns NULL).
-// The label text is not set in this function.
-views::Label* CreateCandidateLabel(
- CandidateWindow::Orientation orientation) {
- views::Label* candidate_label = NULL;
-
- // Create the candidate label. The label will be added to |this| as a
- // child view, hence it's deleted when |this| is deleted.
- if (orientation == CandidateWindow::VERTICAL) {
- candidate_label = new VerticalCandidateLabel;
- } else {
- candidate_label = new views::Label;
+ virtual gfx::Insets GetInsets() const OVERRIDE {
+ return gfx::Insets();
}
- // Change the font size.
- candidate_label->SetFontList(
- candidate_label->font_list().DeriveFontListWithSizeDelta(kFontSizeDelta));
- candidate_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
- return candidate_label;
-}
-
-// Creates the annotation label, and return it (never returns NULL).
-// The label text is not set in this function.
-views::Label* CreateAnnotationLabel(
- CandidateWindow::Orientation orientation, const ui::NativeTheme& theme) {
- // Create the annotation label.
- views::Label* annotation_label = new views::Label;
-
- // Change the font size and color.
- annotation_label->SetFontList(
- annotation_label->font_list().DeriveFontListWithSizeDelta(
- kFontSizeDelta));
- annotation_label->SetEnabledColor(theme.GetSystemColor(
- ui::NativeTheme::kColorId_LabelDisabledColor));
- annotation_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-
- return annotation_label;
-}
-
-// Computes shortcut column size.
-gfx::Size ComputeShortcutColumnSize(
- const CandidateWindow& candidate_window,
- const ui::NativeTheme& theme) {
- int shortcut_column_width = 0;
- int shortcut_column_height = 0;
- // Create the shortcut label. The label will be owned by
- // |wrapped_shortcut_label|, hence it's deleted when
- // |wrapped_shortcut_label| is deleted.
- views::Label* shortcut_label = CreateShortcutLabel(
- candidate_window.orientation(), theme);
- scoped_ptr<views::View> wrapped_shortcut_label(
- CreateWrappedShortcutLabel(shortcut_label,
- candidate_window.orientation(),
- theme));
-
- // Compute the max width and height in shortcut labels.
- // We'll create temporary shortcut labels, and choose the largest width and
- // height.
- for (size_t i = 0; i < candidate_window.page_size(); ++i) {
- shortcut_label->SetText(CreateShortcutText(i, candidate_window));
- gfx::Size text_size = wrapped_shortcut_label->GetPreferredSize();
- shortcut_column_width = std::max(shortcut_column_width, text_size.width());
- shortcut_column_height = std::max(shortcut_column_height,
- text_size.height());
- }
+ gfx::NativeView parent_;
+ int offset_;
- return gfx::Size(shortcut_column_width, shortcut_column_height);
-}
+ DISALLOW_COPY_AND_ASSIGN(CandidateWindowBorder);
+};
// Computes the page index. For instance, if the page size is 9, and the
// cursor is pointing to 13th candidate, the page index will be 1 (2nd
@@ -225,467 +81,178 @@ int ComputePageIndex(const CandidateWindow& candidate_window) {
return -1;
}
-// Computes candidate column size.
-gfx::Size ComputeCandidateColumnSize(
- const CandidateWindow& candidate_window) {
- int candidate_column_width = 0;
- int candidate_column_height = 0;
- scoped_ptr<views::Label> candidate_label(
- CreateCandidateLabel(candidate_window.orientation()));
-
- // Compute the start index of |candidate_window_|.
- const int current_page_index = ComputePageIndex(candidate_window);
- if (current_page_index < 0)
- return gfx::Size(0, 0);
- const size_t start_from = current_page_index * candidate_window.page_size();
-
- // Compute the max width and height in candidate labels.
- // We'll create temporary candidate labels, and choose the largest width and
- // height.
- for (size_t i = 0;
- i + start_from < candidate_window.candidates().size();
- ++i) {
- const size_t index = start_from + i;
-
- candidate_label->SetText(
- base::UTF8ToUTF16(candidate_window.candidates()[index].value));
- gfx::Size text_size = candidate_label->GetPreferredSize();
- candidate_column_width = std::max(candidate_column_width,
- text_size.width());
- candidate_column_height = std::max(candidate_column_height,
- text_size.height());
- }
-
- return gfx::Size(candidate_column_width, candidate_column_height);
-}
-
-// Computes annotation column size.
-gfx::Size ComputeAnnotationColumnSize(
- const CandidateWindow& candidate_window, const ui::NativeTheme& theme) {
- int annotation_column_width = 0;
- int annotation_column_height = 0;
- scoped_ptr<views::Label> annotation_label(
- CreateAnnotationLabel(candidate_window.orientation(), theme));
-
- // Compute the start index of |candidate_window_|.
- const int current_page_index = ComputePageIndex(candidate_window);
- if (current_page_index < 0)
- return gfx::Size(0, 0);
- const size_t start_from = current_page_index * candidate_window.page_size();
-
- // Compute max width and height in annotation labels.
- // We'll create temporary annotation labels, and choose the largest width and
- // height.
- for (size_t i = 0;
- i + start_from < candidate_window.candidates().size();
- ++i) {
- const size_t index = start_from + i;
-
- annotation_label->SetText(
- base::UTF8ToUTF16(candidate_window.candidates()[index].annotation));
- gfx::Size text_size = annotation_label->GetPreferredSize();
- annotation_column_width = std::max(annotation_column_width,
- text_size.width());
- annotation_column_height = std::max(annotation_column_height,
- text_size.height());
- }
-
- return gfx::Size(annotation_column_width, annotation_column_height);
-}
-
} // namespace
-// InformationTextArea is a HidableArea having a single Label in it.
-class InformationTextArea : public HidableArea {
+class InformationTextArea : public views::View {
public:
+ // InformationTextArea's border is drawn as a separator, it should appear
+ // at either top or bottom.
+ enum BorderPosition {
+ TOP,
+ BOTTOM
+ };
+
// Specify the alignment and initialize the control.
- InformationTextArea(gfx::HorizontalAlignment align, int minWidth)
- : minWidth_(minWidth) {
+ InformationTextArea(gfx::HorizontalAlignment align, int min_width)
+ : min_width_(min_width) {
label_ = new views::Label;
label_->SetHorizontalAlignment(align);
+ label_->set_border(views::Border::CreateEmptyBorder(2, 2, 2, 4));
- const gfx::Insets kInsets(2, 2, 2, 4);
- views::View* contents = WrapWithPadding(label_, kInsets);
- SetContents(contents);
- contents->set_border(views::Border::CreateSolidBorder(
- 1,
- GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_MenuBorderColor)));
- contents->set_background(views::Background::CreateSolidBackground(
+ SetLayoutManager(new views::FillLayout());
+ AddChildView(label_);
+ set_background(views::Background::CreateSolidBackground(
color_utils::AlphaBlend(SK_ColorBLACK,
GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_WindowBackground),
0x10)));
- label_->SetBackgroundColor(contents->background()->get_color());
}
- // Set the displayed text.
+ // Sets the text alignment.
+ void SetAlignment(gfx::HorizontalAlignment alignment) {
+ label_->SetHorizontalAlignment(alignment);
+ }
+
+ // Sets the displayed text.
void SetText(const std::string& utf8_text) {
label_->SetText(base::UTF8ToUTF16(utf8_text));
}
+ // Sets the border thickness for top/bottom.
+ void SetBorder(BorderPosition position) {
+ set_border(views::Border::CreateSolidSidedBorder(
+ (position == TOP) ? 1 : 0, 0, (position == BOTTOM) ? 1 : 0, 0,
+ GetNativeTheme()->GetSystemColor(
+ ui::NativeTheme::kColorId_MenuBorderColor)));
+ }
+
protected:
virtual gfx::Size GetPreferredSize() OVERRIDE {
- gfx::Size size = HidableArea::GetPreferredSize();
- // Hack. +2 is needed as the same reason as in VerticalCandidateLabel
- size.set_width(size.width() + 2);
- if (size.width() < minWidth_) {
- size.set_width(minWidth_);
- }
+ gfx::Size size = views::View::GetPreferredSize();
+ size.SetToMax(gfx::Size(min_width_, 0));
return size;
}
private:
views::Label* label_;
- int minWidth_;
+ int min_width_;
DISALLOW_COPY_AND_ASSIGN(InformationTextArea);
};
-CandidateView::CandidateView(
- CandidateWindowView* parent_candidate_window,
- int index_in_page,
- CandidateWindow::Orientation orientation)
- : index_in_page_(index_in_page),
- orientation_(orientation),
- parent_candidate_window_(parent_candidate_window),
- shortcut_label_(NULL),
- candidate_label_(NULL),
- annotation_label_(NULL),
- infolist_icon_(NULL),
- infolist_icon_enabled_(false) {
-}
-
-void CandidateView::Init(int shortcut_column_width,
- int candidate_column_width,
- int annotation_column_width,
- int column_height) {
- views::GridLayout* layout = new views::GridLayout(this);
- SetLayoutManager(layout); // |this| owns |layout|.
-
- // Create Labels.
- const ui::NativeTheme& theme = *GetNativeTheme();
- shortcut_label_ = CreateShortcutLabel(orientation_, theme);
- views::View* wrapped_shortcut_label =
- CreateWrappedShortcutLabel(shortcut_label_, orientation_, theme);
- candidate_label_ = CreateCandidateLabel(orientation_);
- annotation_label_ = CreateAnnotationLabel(orientation_, theme);
-
- // Initialize the column set with three columns.
- views::ColumnSet* column_set = layout->AddColumnSet(0);
-
- // If orientation is vertical, each column width is fixed.
- // Otherwise the width is resizable.
- const views::GridLayout::SizeType column_type =
- orientation_ == CandidateWindow::VERTICAL ?
- views::GridLayout::FIXED : views::GridLayout::USE_PREF;
-
- const int padding_column_width =
- orientation_ == CandidateWindow::VERTICAL ? 4 : 6;
-
- // Set shortcut column type and width.
- column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
- 0, column_type, shortcut_column_width, 0);
- column_set->AddPaddingColumn(0, padding_column_width);
-
- // Set candidate column type and width.
- column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
- 1, views::GridLayout::USE_PREF, 0,
- orientation_ == CandidateWindow::VERTICAL ?
- candidate_column_width : 0);
- column_set->AddPaddingColumn(0, padding_column_width);
-
- // Set annotation column type and width.
- column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
- 0, column_type, annotation_column_width, 0);
-
- if (orientation_ == CandidateWindow::VERTICAL) {
- column_set->AddPaddingColumn(0, 1);
- column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 0,
- views::GridLayout::FIXED, kInfolistIndicatorIconWidth,
- 0);
- column_set->AddPaddingColumn(0, 2);
- } else {
- column_set->AddPaddingColumn(0, padding_column_width);
- }
-
- // Add the shortcut label, the candidate label, and annotation label.
- layout->StartRow(0, 0);
- // |wrapped_shortcut_label|, |candidate_label_|, and |annotation_label_|
- // will be owned by |this|.
- layout->AddView(wrapped_shortcut_label,
- 1, // Column span.
- 1, // Row span.
- views::GridLayout::FILL, // Horizontal alignment.
- views::GridLayout::FILL, // Vertical alignment.
- -1, // Preferred width, not specified.
- column_height); // Preferred height.
- layout->AddView(candidate_label_,
- 1, // Column span.
- 1, // Row span.
- views::GridLayout::FILL, // Horizontal alignment.
- views::GridLayout::FILL, // Vertical alignment.
- -1, // Preferred width, not specified.
- column_height); // Preferred height.
- layout->AddView(annotation_label_,
- 1, // Column span.
- 1, // Row span.
- views::GridLayout::FILL, // Horizontal alignment.
- views::GridLayout::FILL, // Vertical alignemnt.
- -1, // Preferred width, not specified.
- column_height); // Preferred height.
- if (orientation_ == CandidateWindow::VERTICAL) {
- infolist_icon_ = new views::View;
- views::View* infolist_icon_wrapper = new views::View;
- views::GridLayout* infolist_icon_layout =
- new views::GridLayout(infolist_icon_wrapper);
- // |infolist_icon_layout| is owned by |infolist_icon_wrapper|.
- infolist_icon_wrapper->SetLayoutManager(infolist_icon_layout);
- infolist_icon_layout->AddColumnSet(0)->AddColumn(
- views::GridLayout::FILL, views::GridLayout::FILL,
- 0, views::GridLayout::FIXED, kInfolistIndicatorIconWidth, 0);
- infolist_icon_layout->AddPaddingRow(0, kInfolistIndicatorIconPadding);
- infolist_icon_layout->StartRow(1.0, 0); // infolist_icon_ is resizable.
- // |infolist_icon_| is owned by |infolist_icon_wrapper|.
- infolist_icon_layout->AddView(infolist_icon_);
- infolist_icon_layout->AddPaddingRow(0, kInfolistIndicatorIconPadding);
- // |infolist_icon_wrapper| is owned by |this|.
- layout->AddView(infolist_icon_wrapper);
- }
- UpdateLabelBackgroundColors();
-}
-
-void CandidateView::SetCandidateText(const base::string16& text) {
- candidate_label_->SetText(text);
-}
-
-void CandidateView::SetShortcutText(const base::string16& text) {
- shortcut_label_->SetText(text);
-}
-
-void CandidateView::SetAnnotationText(const base::string16& text) {
- annotation_label_->SetText(text);
-}
-
-void CandidateView::SetInfolistIcon(bool enable) {
- if (!infolist_icon_ || (infolist_icon_enabled_ == enable))
- return;
- infolist_icon_enabled_ = enable;
- infolist_icon_->set_background(
- enable ?
- views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_FocusedBorderColor)) :
- NULL);
- UpdateLabelBackgroundColors();
- SchedulePaint();
-}
-
-void CandidateView::Select() {
- set_background(
- views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_TextfieldSelectionBackgroundFocused)));
- set_border(views::Border::CreateSolidBorder(
- 1, GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_FocusedBorderColor)));
- UpdateLabelBackgroundColors();
- // Need to call SchedulePaint() for background and border color changes.
- SchedulePaint();
-}
-
-void CandidateView::Unselect() {
- set_background(NULL);
- set_border(NULL);
- UpdateLabelBackgroundColors();
- SchedulePaint(); // See comments at Select().
-}
-
-void CandidateView::SetRowEnabled(bool enabled) {
- shortcut_label_->SetEnabled(enabled);
-}
-
-gfx::Point CandidateView::GetCandidateLabelPosition() const {
- return candidate_label_->GetMirroredPosition();
-}
-
-bool CandidateView::OnMousePressed(const ui::MouseEvent& event) {
- // TODO(kinaba): On Windows and MacOS, candidate windows typically commits a
- // candidate at OnMouseReleased event. We have chosen OnMousePressed here for
- // working around several obstacle rising from views implementation over GTK.
- // See: http://crosbug.com/11423#c11. Since we have moved from GTK to Aura,
- // the reasoning should have became obsolete. We might want to reconsider
- // implementing mouse-up selection.
- SelectCandidateAt(event.location());
- return false;
-}
-
-void CandidateView::OnGestureEvent(ui::GestureEvent* event) {
- if (event->type() == ui::ET_GESTURE_TAP) {
- SelectCandidateAt(event->location());
- event->SetHandled();
- return;
- }
- View::OnGestureEvent(event);
-}
-
-void CandidateView::SelectCandidateAt(const gfx::Point& location) {
- gfx::Point location_in_candidate_window = location;
- views::View::ConvertPointToTarget(this, parent_candidate_window_,
- &location_in_candidate_window);
- parent_candidate_window_->OnCandidatePressed(location_in_candidate_window);
- parent_candidate_window_->CommitCandidate();
-}
-
-void CandidateView::UpdateLabelBackgroundColors() {
- SkColor color = background() ?
- background()->get_color() :
- GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_WindowBackground);
- if (orientation_ != CandidateWindow::VERTICAL)
- shortcut_label_->SetBackgroundColor(color);
- candidate_label_->SetBackgroundColor(color);
- annotation_label_->SetBackgroundColor(color);
-}
-
-CandidateWindowView::CandidateWindowView(views::Widget* parent_frame)
+CandidateWindowView::CandidateWindowView(gfx::NativeView parent)
: selected_candidate_index_in_page_(-1),
- parent_frame_(parent_frame),
- preedit_area_(NULL),
- header_area_(NULL),
- candidate_area_(NULL),
- footer_area_(NULL),
- previous_shortcut_column_size_(0, 0),
- previous_candidate_column_size_(0, 0),
- previous_annotation_column_size_(0, 0),
should_show_at_composition_head_(false),
should_show_upper_side_(false),
was_candidate_window_open_(false) {
-}
-
-CandidateWindowView::~CandidateWindowView() {
-}
+ set_parent_window(parent);
+ set_margins(gfx::Insets());
-void CandidateWindowView::Init() {
// Set the background and the border of the view.
+ ui::NativeTheme* theme = GetNativeTheme();
set_background(
- views::Background::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
+ views::Background::CreateSolidBackground(theme->GetSystemColor(
ui::NativeTheme::kColorId_WindowBackground)));
set_border(views::Border::CreateSolidBorder(
- 1, GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_MenuBorderColor)));
-
- // Create areas.
- preedit_area_ = new InformationTextArea(gfx::ALIGN_LEFT,
- kMinPreeditAreaWidth);
- header_area_ = new InformationTextArea(gfx::ALIGN_LEFT, 0);
- candidate_area_ = new HidableArea;
- candidate_area_->SetContents(new views::View);
- footer_area_ = new InformationTextArea(gfx::ALIGN_RIGHT, 0);
-
- // Set the window layout of the view
- views::GridLayout* layout = new views::GridLayout(this);
- SetLayoutManager(layout); // |this| owns |layout|.
- views::ColumnSet* column_set = layout->AddColumnSet(0);
- column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
- 0, views::GridLayout::USE_PREF, 0, 0);
-
- // Add the preedit area
- layout->StartRow(0, 0);
- layout->AddView(preedit_area_); // |preedit_area_| is owned by |this|.
+ 1, theme->GetSystemColor(ui::NativeTheme::kColorId_MenuBorderColor)));
+
+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
+ auxiliary_text_ = new InformationTextArea(gfx::ALIGN_RIGHT, 0);
+ preedit_ = new InformationTextArea(gfx::ALIGN_LEFT, kMinPreeditAreaWidth);
+ candidate_area_ = new views::View;
+ auxiliary_text_->SetVisible(false);
+ preedit_->SetVisible(false);
+ candidate_area_->SetVisible(false);
+ preedit_->SetBorder(InformationTextArea::BOTTOM);
+ if (candidate_window_.orientation() == CandidateWindow::VERTICAL) {
+ AddChildView(preedit_);
+ AddChildView(candidate_area_);
+ AddChildView(auxiliary_text_);
+ auxiliary_text_->SetBorder(InformationTextArea::TOP);
+ candidate_area_->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kVertical, 0, 0, 0));
+ } else {
+ AddChildView(preedit_);
+ AddChildView(auxiliary_text_);
+ AddChildView(candidate_area_);
+ auxiliary_text_->SetAlignment(gfx::ALIGN_LEFT);
+ auxiliary_text_->SetBorder(InformationTextArea::BOTTOM);
+ candidate_area_->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kHorizontal, 0, 0, 0));
+ }
+}
- // Add the header area.
- layout->StartRow(0, 0);
- layout->AddView(header_area_); // |header_area_| is owned by |this|.
+CandidateWindowView::~CandidateWindowView() {
+}
- // Add the candidate area.
- layout->StartRow(0, 0);
- layout->AddView(candidate_area_); // |candidate_area_| is owned by |this|.
+views::Widget* CandidateWindowView::InitWidget() {
+ views::Widget* widget = BubbleDelegateView::CreateBubble(this);
- // Add the footer area.
- layout->StartRow(0, 0);
- layout->AddView(footer_area_); // |footer_area_| is owned by |this|.
-}
+ views::corewm::SetWindowVisibilityAnimationType(
+ widget->GetNativeView(),
+ views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
-void CandidateWindowView::HideAll() {
- parent_frame_->Hide();
- NotifyIfCandidateWindowOpenedOrClosed();
+ GetBubbleFrameView()->SetBubbleBorder(
+ new CandidateWindowBorder(parent_window()));
+ return widget;
}
-void CandidateWindowView::UpdateParentArea() {
- if (candidate_area_->IsShown() ||
- header_area_->IsShown() ||
- footer_area_->IsShown() ||
- preedit_area_->IsShown()) {
- ResizeAndMoveParentFrame();
- parent_frame_->Show();
+void CandidateWindowView::UpdateVisibility() {
+ if (candidate_area_->visible() || auxiliary_text_->visible() ||
+ preedit_->visible()) {
+ SizeToContents();
} else {
- parent_frame_->Hide();
+ GetWidget()->Close();
}
- NotifyIfCandidateWindowOpenedOrClosed();
}
void CandidateWindowView::HideLookupTable() {
- candidate_area_->Hide();
- header_area_->Hide();
- footer_area_->Hide();
- UpdateParentArea();
+ candidate_area_->SetVisible(false);
+ UpdateVisibility();
}
void CandidateWindowView::HidePreeditText() {
- preedit_area_->Hide();
- UpdateParentArea();
+ preedit_->SetVisible(false);
+ UpdateVisibility();
}
void CandidateWindowView::ShowPreeditText() {
- preedit_area_->Show();
- UpdateParentArea();
+ preedit_->SetVisible(true);
+ UpdateVisibility();
}
void CandidateWindowView::UpdatePreeditText(const std::string& utf8_text) {
- preedit_area_->SetText(utf8_text);
+ preedit_->SetText(utf8_text);
}
void CandidateWindowView::ShowLookupTable() {
- if (!candidate_area_->IsShown())
- should_show_upper_side_ = false;
- candidate_area_->Show();
-
- // Show auxiliary text.
- if (!candidate_window_.is_auxiliary_text_visible()) {
- header_area_->Hide();
- footer_area_->Hide();
- } else if (candidate_window_.orientation() == CandidateWindow::HORIZONTAL) {
- header_area_->Show();
- footer_area_->Hide();
- } else {
- header_area_->Hide();
- footer_area_->Show();
- }
-
- UpdateParentArea();
-}
-
-void CandidateWindowView::NotifyIfCandidateWindowOpenedOrClosed() {
- bool is_open = IsCandidateWindowOpen();
- if (!was_candidate_window_open_ && is_open) {
- FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowOpened());
- } else if (was_candidate_window_open_ && !is_open) {
- FOR_EACH_OBSERVER(Observer, observers_, OnCandidateWindowClosed());
- }
- was_candidate_window_open_ = is_open;
-}
-
-bool CandidateWindowView::ShouldUpdateCandidateViews(
- const CandidateWindow& old_candidate_window,
- const CandidateWindow& new_candidate_window) {
- return !old_candidate_window.IsEqual(new_candidate_window);
+ candidate_area_->SetVisible(true);
+ auxiliary_text_->SetVisible(candidate_window_.is_auxiliary_text_visible());
+ UpdateVisibility();
}
void CandidateWindowView::UpdateCandidates(
const CandidateWindow& new_candidate_window) {
- const bool should_update = ShouldUpdateCandidateViews(candidate_window_,
- new_candidate_window);
// Updating the candidate views is expensive. We'll skip this if possible.
- if (should_update) {
+ if (!candidate_window_.IsEqual(new_candidate_window)) {
+ if (candidate_window_.orientation() != new_candidate_window.orientation()) {
+ // If the new layout is vertical, the aux text should appear at the
+ // bottom. If horizontal, it should appear between preedit and candidates.
+ if (new_candidate_window.orientation() == CandidateWindow::VERTICAL) {
+ ReorderChildView(auxiliary_text_, -1);
+ auxiliary_text_->SetAlignment(gfx::ALIGN_RIGHT);
+ auxiliary_text_->SetBorder(InformationTextArea::TOP);
+ candidate_area_->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kVertical, 0, 0, 0));
+ } else {
+ ReorderChildView(auxiliary_text_, 1);
+ auxiliary_text_->SetAlignment(gfx::ALIGN_LEFT);
+ auxiliary_text_->SetBorder(InformationTextArea::BOTTOM);
+ candidate_area_->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kHorizontal, 0, 0, 0));
+ }
+ }
+
// Initialize candidate views if necessary.
MaybeInitializeCandidateViews(new_candidate_window);
@@ -693,57 +260,52 @@ void CandidateWindowView::UpdateCandidates(
= new_candidate_window.show_window_at_composition();
// Compute the index of the current page.
const int current_page_index = ComputePageIndex(new_candidate_window);
- if (current_page_index < 0) {
+ if (current_page_index < 0)
return;
- }
// Update the candidates in the current page.
const size_t start_from =
current_page_index * new_candidate_window.page_size();
- // In some cases, engines send empty shortcut labels. For instance,
- // ibus-mozc sends empty labels when they show suggestions. In this
- // case, we should not show shortcut labels.
- bool no_shortcut_mode = true;
- for (size_t i = 0; i < new_candidate_window.candidates().size(); ++i) {
- if (!new_candidate_window.candidates()[i].label.empty()) {
- no_shortcut_mode = false;
- break;
- }
- }
-
+ int max_shortcut_width = 0;
+ int max_candidate_width = 0;
for (size_t i = 0; i < candidate_views_.size(); ++i) {
const size_t index_in_page = i;
const size_t candidate_index = start_from + index_in_page;
CandidateView* candidate_view = candidate_views_[index_in_page];
- // Set the shortcut text.
- if (no_shortcut_mode) {
- candidate_view->SetShortcutText(base::string16());
- } else {
- // At this moment, we don't use labels sent from engines for UX
- // reasons. First, we want to show shortcut labels in empty rows
- // (ex. show 6, 7, 8, ... in empty rows when the number of
- // candidates is 5). Second, we want to add a period after each
- // shortcut label when the candidate window is horizontal.
- candidate_view->SetShortcutText(
- CreateShortcutText(i, new_candidate_window));
- }
// Set the candidate text.
- if (candidate_index < new_candidate_window.candidates().size()) {
- const CandidateWindow::Entry& entry =
- new_candidate_window.candidates()[candidate_index];
- candidate_view->SetCandidateText(base::UTF8ToUTF16(entry.value));
- candidate_view->SetAnnotationText(base::UTF8ToUTF16(entry.annotation));
- candidate_view->SetRowEnabled(true);
- candidate_view->SetInfolistIcon(!entry.description_title.empty());
+ if (candidate_index < new_candidate_window.candidates().size()) {
+ const CandidateWindow::Entry& entry =
+ new_candidate_window.candidates()[candidate_index];
+ candidate_view->SetEntry(entry);
+ candidate_view->SetState(views::Button::STATE_NORMAL);
+ candidate_view->SetInfolistIcon(!entry.description_title.empty());
} else {
// Disable the empty row.
- candidate_view->SetCandidateText(base::string16());
- candidate_view->SetAnnotationText(base::string16());
- candidate_view->SetRowEnabled(false);
+ candidate_view->SetEntry(CandidateWindow::Entry());
+ candidate_view->SetState(views::Button::STATE_DISABLED);
candidate_view->SetInfolistIcon(false);
}
+ if (new_candidate_window.orientation() == CandidateWindow::VERTICAL) {
+ int shortcut_width = 0;
+ int candidate_width = 0;
+ candidate_views_[i]->GetPreferredWidths(
+ &shortcut_width, &candidate_width);
+ max_shortcut_width = std::max(max_shortcut_width, shortcut_width);
+ max_candidate_width = std::max(max_candidate_width, candidate_width);
+ }
+ }
+ if (new_candidate_window.orientation() == CandidateWindow::VERTICAL) {
+ for (size_t i = 0; i < candidate_views_.size(); ++i)
+ candidate_views_[i]->SetWidths(max_shortcut_width, max_candidate_width);
}
+
+ CandidateWindowBorder* border = static_cast<CandidateWindowBorder*>(
+ GetBubbleFrameView()->bubble_border());
+ if (new_candidate_window.orientation() == CandidateWindow::VERTICAL)
+ border->set_offset(max_shortcut_width);
+ else
+ border->set_offset(0);
}
// Update the current candidate window. We'll use candidate_window_ from here.
// Note that SelectCandidateAt() uses candidate_window_.
@@ -761,142 +323,44 @@ void CandidateWindowView::UpdateCandidates(
if (0 <= selected_candidate_index_in_page_ &&
static_cast<size_t>(selected_candidate_index_in_page_) <
candidate_views_.size()) {
- candidate_views_[selected_candidate_index_in_page_]->Unselect();
+ candidate_views_[selected_candidate_index_in_page_]->SetState(
+ views::Button::STATE_NORMAL);
selected_candidate_index_in_page_ = -1;
}
}
// Updates auxiliary text
- if (candidate_window_.is_auxiliary_text_visible()) {
- header_area_->SetText(candidate_window_.auxiliary_text());
- footer_area_->SetText(candidate_window_.auxiliary_text());
- }
+ auxiliary_text_->SetVisible(candidate_window_.is_auxiliary_text_visible());
+ auxiliary_text_->SetText(candidate_window_.auxiliary_text());
+}
+
+void CandidateWindowView::SetCursorBounds(const gfx::Rect& cursor_bounds,
+ const gfx::Rect& composition_head) {
+ if (candidate_window_.show_window_at_composition())
+ SetAnchorRect(composition_head);
+ else
+ SetAnchorRect(cursor_bounds);
}
void CandidateWindowView::MaybeInitializeCandidateViews(
const CandidateWindow& candidate_window) {
const CandidateWindow::Orientation orientation =
candidate_window.orientation();
- const int page_size = candidate_window.page_size();
- views::View* candidate_area_contents = candidate_area_->contents();
-
- // Current column width.
- gfx::Size shortcut_column_size(0, 0);
- gfx::Size candidate_column_size(0,0);
- gfx::Size annotation_column_size(0, 0);
-
- // If orientation is horizontal, don't need to compute width,
- // because each label is left aligned.
- if (orientation == CandidateWindow::VERTICAL) {
- const ui::NativeTheme& theme = *GetNativeTheme();
- shortcut_column_size = ComputeShortcutColumnSize(candidate_window, theme);
- candidate_column_size = ComputeCandidateColumnSize(candidate_window);
- annotation_column_size = ComputeAnnotationColumnSize(candidate_window,
- theme);
- }
-
- // If the requested number of views matches the number of current views, and
- // previous and current column width are same, just reuse these.
- //
- // Note that the early exit logic is not only useful for improving
- // performance, but also necessary for the horizontal candidate window
- // to be redrawn properly. If we get rid of the logic, the horizontal
- // candidate window won't get redrawn properly for some reason when
- // there is no size change. You can test this by removing "return" here
- // and type "ni" with Pinyin input method.
- if (static_cast<int>(candidate_views_.size()) == page_size &&
- candidate_window_.orientation() == orientation &&
- previous_shortcut_column_size_ == shortcut_column_size &&
- previous_candidate_column_size_ == candidate_column_size &&
- previous_annotation_column_size_ == annotation_column_size) {
- return;
- }
-
- // Update the previous column widths.
- previous_shortcut_column_size_ = shortcut_column_size;
- previous_candidate_column_size_ = candidate_column_size;
- previous_annotation_column_size_ = annotation_column_size;
-
- // Clear the existing candidate_views if any.
- for (size_t i = 0; i < candidate_views_.size(); ++i) {
- candidate_area_contents->RemoveChildView(candidate_views_[i]);
- // Delete the view after getting out the current message loop iteration.
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, candidate_views_[i]);
- }
- candidate_views_.clear();
- selected_candidate_index_in_page_ = -1; // Invalidates the index.
-
- views::GridLayout* layout = new views::GridLayout(candidate_area_contents);
- // |candidate_area_contents| owns |layout|.
- candidate_area_contents->SetLayoutManager(layout);
- // Initialize the column set.
- views::ColumnSet* column_set = layout->AddColumnSet(0);
- if (orientation == CandidateWindow::VERTICAL) {
- column_set->AddColumn(views::GridLayout::FILL,
- views::GridLayout::FILL,
- 1, views::GridLayout::USE_PREF, 0, 0);
- } else {
- for (int i = 0; i < page_size; ++i) {
- column_set->AddColumn(views::GridLayout::FILL,
- views::GridLayout::FILL,
- 0, views::GridLayout::USE_PREF, 0, 0);
- }
- }
+ const size_t page_size = candidate_window.page_size();
- // Set insets so the border of the selected candidate is drawn inside of
- // the border of the main candidate window, but we don't have the inset
- // at the top and the bottom as we have the borders of the header and
- // footer areas.
- const gfx::Insets kCandidateAreaInsets(0, 1, 0, 1);
- layout->SetInsets(kCandidateAreaInsets.top(),
- kCandidateAreaInsets.left(),
- kCandidateAreaInsets.bottom(),
- kCandidateAreaInsets.right());
+ // Reset all candidate_views_ when orientation changes.
+ if (orientation != candidate_window_.orientation())
+ STLDeleteElements(&candidate_views_);
- // Use maximum height for all rows in candidate area.
- const int kColumnHeight = std::max(shortcut_column_size.height(),
- std::max(candidate_column_size.height(),
- annotation_column_size.height()));
-
- // Add views to the candidate area.
- if (orientation == CandidateWindow::HORIZONTAL) {
- layout->StartRow(0, 0);
+ while (page_size < candidate_views_.size()) {
+ delete candidate_views_.back();
+ candidate_views_.pop_back();
}
-
- for (int i = 0; i < page_size; ++i) {
- CandidateView* candidate_row = new CandidateView(this, i, orientation);
- candidate_row->Init(shortcut_column_size.width(),
- candidate_column_size.width(),
- annotation_column_size.width(),
- kColumnHeight);
- candidate_views_.push_back(candidate_row);
- if (orientation == CandidateWindow::VERTICAL) {
- layout->StartRow(0, 0);
- }
- // |candidate_row| will be owned by |candidate_area_contents|.
- layout->AddView(candidate_row,
- 1, // Column span.
- 1, // Row span.
- // Horizontal alignment.
- orientation == CandidateWindow::VERTICAL ?
- views::GridLayout::FILL : views::GridLayout::CENTER,
- views::GridLayout::CENTER, // Vertical alignment.
- -1, // Preferred width, not specified.
- kColumnHeight); // Preferred height.
+ while (page_size > candidate_views_.size()) {
+ CandidateView* new_candidate = new CandidateView(this, orientation);
+ candidate_area_->AddChildView(new_candidate);
+ candidate_views_.push_back(new_candidate);
}
-
- // Compute views size in |layout|.
- // If we don't call this function, GetHorizontalOffset() often
- // returns invalid value (returns 0), then candidate window
- // moves right from the correct position in ResizeAndMoveParentFrame().
- // TODO(nhiroki): Figure out why it returns invalid value.
- // It seems that the x-position of the candidate labels is not set.
- layout->Layout(candidate_area_contents);
-}
-
-bool CandidateWindowView::IsCandidateWindowOpen() const {
- return !should_show_at_composition_head_ &&
- candidate_area_->visible() && candidate_area_->IsShown();
}
void CandidateWindowView::SelectCandidateAt(int index_in_page) {
@@ -914,123 +378,25 @@ void CandidateWindowView::SelectCandidateAt(int index_in_page) {
return;
}
- // Unselect the currently selected candidate.
- if (0 <= selected_candidate_index_in_page_ &&
- static_cast<size_t>(selected_candidate_index_in_page_) <
- candidate_views_.size()) {
- candidate_views_[selected_candidate_index_in_page_]->Unselect();
- }
// Remember the currently selected candidate index in the current page.
selected_candidate_index_in_page_ = index_in_page;
// Select the candidate specified by index_in_page.
- candidate_views_[index_in_page]->Select();
+ candidate_views_[index_in_page]->SetState(views::Button::STATE_PRESSED);
// Update the cursor indexes in the model.
candidate_window_.set_cursor_position(cursor_absolute_index);
}
-void CandidateWindowView::OnCandidatePressed(
- const gfx::Point& location) {
+void CandidateWindowView::ButtonPressed(views::Button* sender,
+ const ui::Event& event) {
for (size_t i = 0; i < candidate_views_.size(); ++i) {
- gfx::Point converted_location = location;
- views::View::ConvertPointToTarget(this, candidate_views_[i],
- &converted_location);
- if (candidate_views_[i]->HitTestPoint(converted_location)) {
- SelectCandidateAt(i);
- break;
+ if (sender == candidate_views_[i]) {
+ FOR_EACH_OBSERVER(Observer, observers_, OnCandidateCommitted(i));
+ return;
}
}
}
-void CandidateWindowView::CommitCandidate() {
- if (!(0 <= selected_candidate_index_in_page_ &&
- static_cast<size_t>(selected_candidate_index_in_page_) <
- candidate_views_.size())) {
- return; // Out of range, do nothing.
- }
-
- FOR_EACH_OBSERVER(Observer, observers_,
- OnCandidateCommitted(selected_candidate_index_in_page_));
-}
-
-void CandidateWindowView::ResizeAndMoveParentFrame() {
- // If rendering operation comes from mozc-engine, uses mozc specific bounds,
- // otherwise candidate window is shown under the cursor.
- const int x = should_show_at_composition_head_?
- composition_head_bounds_.x() : cursor_bounds_.x();
- // To avoid candidate-window overlapping, uses maximum y-position of mozc
- // specific bounds and cursor bounds, because mozc-engine does not
- // consider about multi-line composition.
- const int y = should_show_at_composition_head_?
- std::max(composition_head_bounds_.y(), cursor_bounds_.y()) :
- cursor_bounds_.y();
- const int height = cursor_bounds_.height();
- const int horizontal_offset = GetHorizontalOffset();
-
- gfx::Rect old_bounds = parent_frame_->GetClientAreaBoundsInScreen();
- gfx::Rect screen_bounds = ash::Shell::GetScreen()->GetDisplayMatching(
- cursor_bounds_).work_area();
- // The size.
- gfx::Rect frame_bounds = old_bounds;
- frame_bounds.set_size(GetPreferredSize());
-
- // The default position.
- frame_bounds.set_x(x + horizontal_offset);
- frame_bounds.set_y(y + height);
-
- // Handle overflow at the left and the top.
- frame_bounds.set_x(std::max(frame_bounds.x(), screen_bounds.x()));
- frame_bounds.set_y(std::max(frame_bounds.y(), screen_bounds.y()));
-
- // Handle overflow at the right.
- const int right_overflow = frame_bounds.right() - screen_bounds.right();
- if (right_overflow > 0) {
- frame_bounds.set_x(frame_bounds.x() - right_overflow);
- }
-
- // Handle overflow at the bottom.
- const int bottom_overflow = frame_bounds.bottom() - screen_bounds.bottom();
-
- // To avoid flickering window position, the candidate window should be shown
- // on upper side of composition string if it was shown there.
- if (should_show_upper_side_ || bottom_overflow > 0) {
- frame_bounds.set_y(frame_bounds.y() - height - frame_bounds.height());
- should_show_upper_side_ = true;
- }
-
- // TODO(nona): check top_overflow here.
-
- // Move the window per the cursor bounds.
- // SetBounds() is not cheap. Only call this when it is really changed.
- if (frame_bounds != old_bounds)
- parent_frame_->SetBounds(frame_bounds);
-}
-
-int CandidateWindowView::GetHorizontalOffset() {
- // Compute the horizontal offset if the candidate window is vertical.
- if (!candidate_views_.empty() &&
- candidate_window_.orientation() == CandidateWindow::VERTICAL) {
- return - candidate_views_[0]->GetCandidateLabelPosition().x();
- }
- return 0;
-}
-
-void CandidateWindowView::VisibilityChanged(View* starting_from,
- bool is_visible) {
- if (is_visible) {
- // If the visibility of candidate window is changed,
- // we should move the frame to the right position.
- ResizeAndMoveParentFrame();
- }
-}
-
-void CandidateWindowView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
- // If the bounds(size) of candidate window is changed,
- // we should move the frame to the right position.
- View::OnBoundsChanged(previous_bounds);
- ResizeAndMoveParentFrame();
-}
-
} // namespace input_method
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698