15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/ime/candidate_view.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/logging.h"
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/strings/utf_string_conversions.h"
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/window.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/controls/button/button.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/layout/box_layout.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/layout/fill_layout.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/test/views_test_base.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/widget/widget_delegate.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace ash {
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace ime {
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst char* const kDummyCandidates[] = {
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  "candidate1",
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  "candidate2",
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  "candidate3",
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass CandidateViewTest : public views::ViewsTestBase,
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                          public views::ButtonListener {
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public:
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CandidateViewTest() : widget_(NULL), last_pressed_(NULL) {}
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual ~CandidateViewTest() {}
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void SetUp() OVERRIDE {
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    views::ViewsTestBase::SetUp();
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    views::Widget::InitParams init_params(CreateParams(
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        views::Widget::InitParams::TYPE_WINDOW));
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    init_params.delegate = new views::WidgetDelegateView();
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    container_ = init_params.delegate->GetContentsView();
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    container_->SetLayoutManager(
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    for (size_t i = 0; i < arraysize(kDummyCandidates); ++i) {
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      CandidateView* candidate = new CandidateView(
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          this, ui::CandidateWindow::VERTICAL);
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ui::CandidateWindow::Entry entry;
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      entry.value = base::UTF8ToUTF16(kDummyCandidates[i]);
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      candidate->SetEntry(entry);
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      container_->AddChildView(candidate);
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    widget_ = new views::Widget();
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    widget_->Init(init_params);
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    widget_->Show();
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    aura::Window* native_window = widget_->GetNativeWindow();
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    event_generator_.reset(new ui::test::EventGenerator(
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        native_window->GetRootWindow(), native_window));
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void TearDown() OVERRIDE {
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    widget_->Close();
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    views::ViewsTestBase::TearDown();
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu protected:
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CandidateView* GetCandidateAt(int index) {
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return static_cast<CandidateView*>(container_->child_at(index));
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int GetHighlightedIndex(int* highlighted_count) const {
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    *highlighted_count = 0;
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int last_highlighted = -1;
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    for (int i = 0; i < container_->child_count(); ++i) {
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (container_->child_at(i)->background() != NULL) {
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        (*highlighted_count)++;
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        last_highlighted = i;
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      }
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return last_highlighted;
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int GetLastPressedIndexAndReset() {
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    for (int i = 0; i < container_->child_count(); ++i) {
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (last_pressed_ == container_->child_at(i)) {
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        last_pressed_ = NULL;
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        return i;
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      }
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DCHECK(last_pressed_ == NULL);
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    last_pressed_ = NULL;
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return -1;
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator* event_generator() { return event_generator_.get(); }
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private:
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void ButtonPressed(views::Button* sender,
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                             const ui::Event& event) OVERRIDE {
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    last_pressed_ = sender;
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  views::Widget* widget_;
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  views::View* container_;
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ui::test::EventGenerator> event_generator_;
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  views::View* last_pressed_;
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DISALLOW_COPY_AND_ASSIGN(CandidateViewTest);
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(CandidateViewTest, MouseHovers) {
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  GetCandidateAt(0)->SetHighlighted(true);
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int highlighted_count = 0;
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0, GetHighlightedIndex(&highlighted_count));
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Mouse hover shouldn't change the background.
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(0)->GetBoundsInScreen().CenterPoint());
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0, GetHighlightedIndex(&highlighted_count));
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Mouse hover shouldn't change the background.
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(1)->GetBoundsInScreen().CenterPoint());
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0, GetHighlightedIndex(&highlighted_count));
1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Mouse hover shouldn't change the background.
1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(2)->GetBoundsInScreen().CenterPoint());
1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0, GetHighlightedIndex(&highlighted_count));
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(CandidateViewTest, MouseClick) {
1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(1)->GetBoundsInScreen().CenterPoint());
1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->ClickLeftButton();
1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, GetLastPressedIndexAndReset());
1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(CandidateViewTest, ClickAndMove) {
1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  GetCandidateAt(0)->SetHighlighted(true);
1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int highlighted_count = 0;
1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0, GetHighlightedIndex(&highlighted_count));
1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(2)->GetBoundsInScreen().CenterPoint());
1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->PressLeftButton();
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(2, GetHighlightedIndex(&highlighted_count));
1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Highlight follows the drag.
1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(1)->GetBoundsInScreen().CenterPoint());
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, GetHighlightedIndex(&highlighted_count));
1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(0)->GetBoundsInScreen().CenterPoint());
1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0, GetHighlightedIndex(&highlighted_count));
1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->MoveMouseTo(
1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetCandidateAt(1)->GetBoundsInScreen().CenterPoint());
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, GetHighlightedIndex(&highlighted_count));
1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, highlighted_count);
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  event_generator()->ReleaseLeftButton();
1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, GetLastPressedIndexAndReset());
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace ime
1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace ash
184