• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_CANDIDATE_WINDOW_VIEW_H_
6 #define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_CANDIDATE_WINDOW_VIEW_H_
7 
8 #include "base/gtest_prod_util.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "chromeos/ime/candidate_window.h"
11 #include "ui/views/view.h"
12 
13 namespace gfx {
14 class Font;
15 }
16 
17 namespace chromeos {
18 namespace input_method {
19 
20 class CandidateView;
21 class CandidateWindow;
22 class HidableArea;
23 class InformationTextArea;
24 
25 // CandidateWindowView is the main container of the candidate window UI.
26 class CandidateWindowView : public views::View {
27  public:
28   // The object can be monitored by the observer.
29   class Observer {
30    public:
~Observer()31     virtual ~Observer() {}
32     // The function is called when a candidate is committed.
33     virtual void OnCandidateCommitted(int index) = 0;
34 
35     virtual void OnCandidateWindowOpened() = 0;
36     virtual void OnCandidateWindowClosed() = 0;
37   };
38 
39   explicit CandidateWindowView(views::Widget* parent_frame);
40   virtual ~CandidateWindowView();
41   void Init();
42 
43   // Adds the given observer. The ownership is not transferred.
AddObserver(Observer * observer)44   void AddObserver(Observer* observer) {
45     observers_.AddObserver(observer);
46   }
47 
48   // Removes the given observer.
RemoveObserver(Observer * observer)49   void RemoveObserver(Observer* observer) {
50     observers_.RemoveObserver(observer);
51   }
52 
53   // Selects the candidate specified by the index in the current page
54   // (zero-origin).  Changes the appearance of the selected candidate,
55   // updates the information in the candidate window as needed.
56   void SelectCandidateAt(int index_in_page);
57 
58   // The function is called when a candidate is being dragged. From the
59   // given point, locates the candidate under the mouse cursor, and
60   // selects it.
61   void OnCandidatePressed(const gfx::Point& point);
62 
63   // Commits the candidate currently being selected.
64   void CommitCandidate();
65 
66   // Hides the lookup table.
67   void HideLookupTable();
68 
69   // Hides the auxiliary text.
70   void HideAuxiliaryText();
71 
72   // Hides the preedit text.
73   void HidePreeditText();
74 
75   // Hides whole the candidate window.
76   void HideAll();
77 
78   // Shows the lookup table.
79   void ShowLookupTable();
80 
81   // Shows the auxiliary text.
82   void ShowAuxiliaryText();
83 
84   // Shows the preedit text.
85   void ShowPreeditText();
86 
87   // Updates the auxiliary text.
88   void UpdateAuxiliaryText(const std::string& utf8_text);
89 
90   // Updates the preedit text.
91   void UpdatePreeditText(const std::string& utf8_text);
92 
93   // Returns true if we should update candidate views in the window.  For
94   // instance, if we are going to show the same candidates as before, we
95   // don't have to update candidate views. This happens when the user just
96   // moves the cursor in the same page in the candidate window.
97   static bool ShouldUpdateCandidateViews(
98       const CandidateWindow& old_candidate_window,
99       const CandidateWindow& new_candidate_window);
100 
101   // Updates candidates of the candidate window from |candidate_window|.
102   // Candidates are arranged per |orientation|.
103   void UpdateCandidates(const CandidateWindow& candidate_window);
104 
105   // Resizes and moves the parent frame. The two actions should be
106   // performed consecutively as resizing may require the candidate window
107   // to move. For instance, we may need to move the candidate window from
108   // below the cursor to above the cursor, if the candidate window becomes
109   // too big to be shown near the bottom of the screen.  This function
110   // needs to be called when the visible contents of the candidate window
111   // are modified.
112   void ResizeAndMoveParentFrame();
113 
114   // Returns the horizontal offset used for placing the vertical candidate
115   // window so that the first candidate is aligned with the the text being
116   // converted like:
117   //
118   //      XXX           <- The user is converting XXX
119   //   +-----+
120   //   |1 XXX|
121   //   |2 YYY|
122   //   |3 ZZZ|
123   //
124   // Returns 0 if no candidate is present.
125   int GetHorizontalOffset();
126 
set_cursor_bounds(const gfx::Rect & cursor_bounds)127   void set_cursor_bounds(const gfx::Rect& cursor_bounds) {
128     cursor_bounds_ = cursor_bounds;
129   }
130 
set_composition_head_bounds(const gfx::Rect & composition_head_bounds)131   void set_composition_head_bounds(
132       const gfx::Rect& composition_head_bounds) {
133     composition_head_bounds_ = composition_head_bounds;
134   }
135 
cursor_bounds()136   const gfx::Rect& cursor_bounds() const { return cursor_bounds_; }
composition_head_bounds()137   const gfx::Rect& composition_head_bounds() const {
138     return composition_head_bounds_;
139   }
140 
141  protected:
142   // Override View::VisibilityChanged()
143   virtual void VisibilityChanged(View* starting_from, bool is_visible) OVERRIDE;
144 
145   // Override View::OnBoundsChanged()
146   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
147 
148  private:
149   FRIEND_TEST_ALL_PREFIXES(CandidateWindowViewTest,
150                            UpdateCandidatesTest_CursorVisibility);
151   FRIEND_TEST_ALL_PREFIXES(CandidateWindowViewTest, ShortcutSettingTest);
152   FRIEND_TEST_ALL_PREFIXES(CandidateWindowViewTest,
153                            DoNotChangeRowHeightWithLabelSwitchTest);
154 
155   // Initializes the candidate views if needed.
156   void MaybeInitializeCandidateViews(const CandidateWindow& candidate_window);
157 
158   // Returns the appropriate area (header or footer) to put auxiliary texts.
159   InformationTextArea* GetAuxiliaryTextArea();
160 
161   // Returns true if the candidate window is open.  The suggestion window does
162   // not count as the candidate window.
163   bool IsCandidateWindowOpen() const;
164 
165   // Notifies observers if the candidate window's opened/closed state has
166   // changed from the previous call to this function.
167   void NotifyIfCandidateWindowOpenedOrClosed();
168 
169   // The candidate window.
170   CandidateWindow candidate_window_;
171 
172   // The index in the current page of the candidate currently being selected.
173   int selected_candidate_index_in_page_;
174 
175   // The observers of the object.
176   ObserverList<Observer> observers_;
177 
178   // The parent frame.
179   views::Widget* parent_frame_;
180 
181   // Views created in the class will be part of tree of |this|, so these
182   // child views will be deleted when |this| is deleted.
183 
184   // The preedit area is where the preedit text is shown, if it is needed
185   // in cases such as the focus is on a plugin that doesn't support in-line
186   // preedit drawing.
187   InformationTextArea* preedit_area_;
188   // The header area is where the auxiliary text is shown, if the
189   // orientation is horizontal. If the auxiliary text is not provided, we
190   // show nothing.  For instance, we show pinyin text like "zhong'guo".
191   InformationTextArea* header_area_;
192   // The candidate area is where candidates are rendered.
193   HidableArea* candidate_area_;
194   // The candidate views are used for rendering candidates.
195   std::vector<CandidateView*> candidate_views_;
196   // The footer area is where the auxiliary text is shown, if the
197   // orientation is vertical. Usually the auxiliary text is used for
198   // showing candidate number information like 2/19.
199   InformationTextArea* footer_area_;
200 
201   // Current columns size in |candidate_area_|.
202   gfx::Size previous_shortcut_column_size_;
203   gfx::Size previous_candidate_column_size_;
204   gfx::Size previous_annotation_column_size_;
205 
206   // The last cursor bounds.
207   gfx::Rect cursor_bounds_;
208 
209   // The last compostion head bounds.
210   gfx::Rect composition_head_bounds_;
211 
212   // True if the candidate window should be shown with aligning with composition
213   // text as opposed to the cursor.
214   bool should_show_at_composition_head_;
215 
216   // True if the candidate window should be shonw on the upper side of
217   // composition text.
218   bool should_show_upper_side_;
219 
220   // True if the candidate window was open.  This is used to determine when to
221   // send OnCandidateWindowOpened and OnCandidateWindowClosed events.
222   bool was_candidate_window_open_;
223 
224   // This function judge whether the candidate window should be shown or not,
225   // if should be, shows parent_frame and if not, hides parent_frame.
226   void UpdateParentArea();
227 
228   DISALLOW_COPY_AND_ASSIGN(CandidateWindowView);
229 };
230 
231 }  // namespace input_method
232 }  // namespace chromeos
233 
234 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_CANDIDATE_WINDOW_VIEW_H_
235