Home | History | Annotate | Download | only in textfield
      1 // Copyright (c) 2013 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 UI_VIEWS_CONTROLS_TEXTFIELD_NATIVE_TEXTFIELD_VIEWS_H_
      6 #define UI_VIEWS_CONTROLS_TEXTFIELD_NATIVE_TEXTFIELD_VIEWS_H_
      7 
      8 #include "base/memory/weak_ptr.h"
      9 #include "base/strings/string16.h"
     10 #include "base/timer/timer.h"
     11 #include "ui/base/ime/text_input_client.h"
     12 #include "ui/base/models/simple_menu_model.h"
     13 #include "ui/base/touch/touch_editing_controller.h"
     14 #include "ui/events/event_constants.h"
     15 #include "ui/gfx/font.h"
     16 #include "ui/views/border.h"
     17 #include "ui/views/context_menu_controller.h"
     18 #include "ui/views/controls/textfield/native_textfield_wrapper.h"
     19 #include "ui/views/controls/textfield/textfield_views_model.h"
     20 #include "ui/views/drag_controller.h"
     21 #include "ui/views/view.h"
     22 
     23 namespace base {
     24 class Time;
     25 }
     26 
     27 namespace gfx {
     28 class Canvas;
     29 }
     30 
     31 namespace views {
     32 
     33 class FocusableBorder;
     34 class MenuModelAdapter;
     35 class MenuRunner;
     36 
     37 // A views/skia only implementation of NativeTextfieldWrapper.
     38 // No platform specific code is used.
     39 // Following features are not yet supported.
     40 // * BIDI/Complex script.
     41 // * Support surrogate pair, or maybe we should just use UTF32 internally.
     42 // * X selection (only if we want to support).
     43 // Once completed, this will replace Textfield, NativeTextfieldWin and
     44 // NativeTextfieldGtk.
     45 class VIEWS_EXPORT NativeTextfieldViews : public View,
     46                                           public ui::TouchEditable,
     47                                           public ContextMenuController,
     48                                           public DragController,
     49                                           public NativeTextfieldWrapper,
     50                                           public ui::TextInputClient,
     51                                           public TextfieldViewsModel::Delegate {
     52  public:
     53   explicit NativeTextfieldViews(Textfield* parent);
     54   virtual ~NativeTextfieldViews();
     55 
     56   // View overrides:
     57   virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
     58   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
     59   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
     60   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
     61   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
     62   virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
     63   virtual bool GetDropFormats(
     64       int* formats,
     65       std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
     66   virtual bool CanDrop(const ui::OSExchangeData& data) OVERRIDE;
     67   virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE;
     68   virtual void OnDragExited() OVERRIDE;
     69   virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE;
     70   virtual void OnDragDone() OVERRIDE;
     71   virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE;
     72   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
     73   virtual void OnFocus() OVERRIDE;
     74   virtual void OnBlur() OVERRIDE;
     75   virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
     76 
     77   // ui::TouchEditable overrides:
     78   virtual void SelectRect(const gfx::Point& start,
     79                           const gfx::Point& end) OVERRIDE;
     80   virtual void MoveCaretTo(const gfx::Point& point) OVERRIDE;
     81   virtual void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) OVERRIDE;
     82   virtual gfx::Rect GetBounds() OVERRIDE;
     83   virtual gfx::NativeView GetNativeView() OVERRIDE;
     84   virtual void ConvertPointToScreen(gfx::Point* point) OVERRIDE;
     85   virtual void ConvertPointFromScreen(gfx::Point* point) OVERRIDE;
     86   virtual bool DrawsHandles() OVERRIDE;
     87   virtual void OpenContextMenu(const gfx::Point& anchor) OVERRIDE;
     88 
     89   // ContextMenuController overrides:
     90   virtual void ShowContextMenuForView(View* source,
     91                                       const gfx::Point& point,
     92                                       ui::MenuSourceType source_type) OVERRIDE;
     93 
     94   // Overridden from DragController:
     95   virtual void WriteDragDataForView(View* sender,
     96                                     const gfx::Point& press_pt,
     97                                     ui::OSExchangeData* data) OVERRIDE;
     98   virtual int GetDragOperationsForView(View* sender,
     99                                        const gfx::Point& p) OVERRIDE;
    100   virtual bool CanStartDragForView(View* sender,
    101                                    const gfx::Point& press_pt,
    102                                    const gfx::Point& p) OVERRIDE;
    103 
    104   // NativeTextfieldWrapper overrides:
    105   virtual string16 GetText() const OVERRIDE;
    106   virtual void UpdateText() OVERRIDE;
    107   virtual void AppendText(const string16& text) OVERRIDE;
    108   virtual void InsertOrReplaceText(const string16& text) OVERRIDE;
    109   virtual base::i18n::TextDirection GetTextDirection() const OVERRIDE;
    110   virtual string16 GetSelectedText() const OVERRIDE;
    111   virtual void SelectAll(bool reversed) OVERRIDE;
    112   virtual void ClearSelection() OVERRIDE;
    113   virtual void UpdateBorder() OVERRIDE;
    114   virtual void UpdateTextColor() OVERRIDE;
    115   virtual void UpdateBackgroundColor() OVERRIDE;
    116   virtual void UpdateReadOnly() OVERRIDE;
    117   virtual void UpdateFont() OVERRIDE;
    118   virtual void UpdateIsObscured() OVERRIDE;
    119   virtual void UpdateEnabled() OVERRIDE;
    120   virtual gfx::Insets CalculateInsets() OVERRIDE;
    121   virtual void UpdateHorizontalMargins() OVERRIDE;
    122   virtual void UpdateVerticalMargins() OVERRIDE;
    123   virtual bool SetFocus() OVERRIDE;
    124   virtual View* GetView() OVERRIDE;
    125   virtual gfx::NativeView GetTestingHandle() const OVERRIDE;
    126   virtual bool IsIMEComposing() const OVERRIDE;
    127   virtual gfx::Range GetSelectedRange() const OVERRIDE;
    128   virtual void SelectRange(const gfx::Range& range) OVERRIDE;
    129   virtual gfx::SelectionModel GetSelectionModel() const OVERRIDE;
    130   virtual void SelectSelectionModel(const gfx::SelectionModel& sel) OVERRIDE;
    131   virtual size_t GetCursorPosition() const OVERRIDE;
    132   virtual bool GetCursorEnabled() const OVERRIDE;
    133   virtual void SetCursorEnabled(bool enabled) OVERRIDE;
    134   virtual bool HandleKeyPressed(const ui::KeyEvent& e) OVERRIDE;
    135   virtual bool HandleKeyReleased(const ui::KeyEvent& e) OVERRIDE;
    136   virtual void HandleFocus() OVERRIDE;
    137   virtual void HandleBlur() OVERRIDE;
    138   virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
    139   virtual void SetColor(SkColor value) OVERRIDE;
    140   virtual void ApplyColor(SkColor value, const gfx::Range& range) OVERRIDE;
    141   virtual void SetStyle(gfx::TextStyle style, bool value) OVERRIDE;
    142   virtual void ApplyStyle(gfx::TextStyle style,
    143                           bool value,
    144                           const gfx::Range& range) OVERRIDE;
    145   virtual void ClearEditHistory() OVERRIDE;
    146   virtual int GetFontHeight() OVERRIDE;
    147   virtual int GetTextfieldBaseline() const OVERRIDE;
    148   virtual int GetWidthNeededForText() const OVERRIDE;
    149   virtual void ExecuteTextCommand(int command_id) OVERRIDE;
    150   virtual bool HasTextBeingDragged() OVERRIDE;
    151   virtual gfx::Point GetContextMenuLocation() OVERRIDE;
    152 
    153   // ui::SimpleMenuModel::Delegate overrides
    154   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
    155   virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
    156   virtual bool GetAcceleratorForCommandId(
    157       int command_id,
    158       ui::Accelerator* accelerator) OVERRIDE;
    159   virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
    160   virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE;
    161   virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
    162 
    163   // class name of internal
    164   static const char kViewClassName[];
    165 
    166  protected:
    167   // View override.
    168   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
    169 
    170  private:
    171   friend class NativeTextfieldViewsTest;
    172   friend class TouchSelectionControllerImplTest;
    173 
    174   // Overridden from ui::TextInputClient:
    175   virtual void SetCompositionText(
    176       const ui::CompositionText& composition) OVERRIDE;
    177   virtual void ConfirmCompositionText() OVERRIDE;
    178   virtual void ClearCompositionText() OVERRIDE;
    179   virtual void InsertText(const string16& text) OVERRIDE;
    180   virtual void InsertChar(char16 ch, int flags) OVERRIDE;
    181   virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE;
    182   virtual ui::TextInputType GetTextInputType() const OVERRIDE;
    183   virtual ui::TextInputMode GetTextInputMode() const OVERRIDE;
    184   virtual bool CanComposeInline() const OVERRIDE;
    185   virtual gfx::Rect GetCaretBounds() const OVERRIDE;
    186   virtual bool GetCompositionCharacterBounds(uint32 index,
    187                                              gfx::Rect* rect) const OVERRIDE;
    188   virtual bool HasCompositionText() const OVERRIDE;
    189   virtual bool GetTextRange(gfx::Range* range) const OVERRIDE;
    190   virtual bool GetCompositionTextRange(gfx::Range* range) const OVERRIDE;
    191   virtual bool GetSelectionRange(gfx::Range* range) const OVERRIDE;
    192   virtual bool SetSelectionRange(const gfx::Range& range) OVERRIDE;
    193   virtual bool DeleteRange(const gfx::Range& range) OVERRIDE;
    194   virtual bool GetTextFromRange(const gfx::Range& range,
    195                                 string16* text) const OVERRIDE;
    196   virtual void OnInputMethodChanged() OVERRIDE;
    197   virtual bool ChangeTextDirectionAndLayoutAlignment(
    198       base::i18n::TextDirection direction) OVERRIDE;
    199   virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE;
    200   virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE;
    201   virtual void OnCandidateWindowShown() OVERRIDE;
    202   virtual void OnCandidateWindowUpdated() OVERRIDE;
    203   virtual void OnCandidateWindowHidden() OVERRIDE;
    204 
    205   // Overridden from TextfieldViewsModel::Delegate:
    206   virtual void OnCompositionTextConfirmedOrCleared() OVERRIDE;
    207 
    208   // Returns the TextfieldViewsModel's text/cursor/selection rendering model.
    209   gfx::RenderText* GetRenderText() const;
    210 
    211   // Converts |text| according to textfield style, e.g. lower case if
    212   // |textfield_| has STYLE_LOWERCASE style.
    213   string16 GetTextForDisplay(const string16& text);
    214 
    215   // Updates any colors that have not been explicitly set from the theme.
    216   void UpdateColorsFromTheme(const ui::NativeTheme* theme);
    217 
    218   // A callback function to periodically update the cursor state.
    219   void UpdateCursor();
    220 
    221   // Repaint the cursor.
    222   void RepaintCursor();
    223 
    224   // Update the cursor_bounds and text_offset.
    225   void UpdateCursorBoundsAndTextOffset(size_t cursor_pos, bool insert_mode);
    226 
    227   void PaintTextAndCursor(gfx::Canvas* canvas);
    228 
    229   // Handle the keyevent.
    230   bool HandleKeyEvent(const ui::KeyEvent& key_event);
    231 
    232   // Helper function to call MoveCursorTo on the TextfieldViewsModel.
    233   bool MoveCursorTo(const gfx::Point& point, bool select);
    234 
    235   // Utility function to inform the parent textfield (and its controller if any)
    236   // that the text in the textfield has changed.
    237   void PropagateTextChange();
    238 
    239   // Does necessary updates when the text and/or the position of the cursor
    240   // changed.
    241   void UpdateAfterChange(bool text_changed, bool cursor_changed);
    242 
    243   // Utility function to prepare the context menu.
    244   void UpdateContextMenu();
    245 
    246   // Convenience method to call InputMethod::OnTextInputTypeChanged();
    247   void OnTextInputTypeChanged();
    248 
    249   // Convenience method to call InputMethod::OnCaretBoundsChanged();
    250   void OnCaretBoundsChanged();
    251 
    252   // Convenience method to call TextfieldController::OnBeforeUserAction();
    253   void OnBeforeUserAction();
    254 
    255   // Convenience method to call TextfieldController::OnAfterUserAction();
    256   void OnAfterUserAction();
    257 
    258   // Calls |model_->Cut()| and notifies TextfieldController on success.
    259   bool Cut();
    260 
    261   // Calls |model_->Copy()| and notifies TextfieldController on success.
    262   bool Copy();
    263 
    264   // Calls |model_->Paste()| and calls TextfieldController::ContentsChanged()
    265   // explicitly if paste succeeded.
    266   bool Paste();
    267 
    268   // Tracks the mouse clicks for single/double/triple clicks.
    269   void TrackMouseClicks(const ui::MouseEvent& event);
    270 
    271   // Handles mouse press events.
    272   void HandleMousePressEvent(const ui::MouseEvent& event);
    273 
    274   // Returns true if the current text input type allows access by the IME.
    275   bool ImeEditingAllowed() const;
    276 
    277   // Returns true if distance between |event| and |last_click_location_|
    278   // exceeds the drag threshold.
    279   bool ExceededDragThresholdFromLastClickLocation(const ui::MouseEvent& event);
    280 
    281   // Checks if a char is ok to be inserted into the textfield. The |ch| is a
    282   // modified character, i.e., modifiers took effect when generating this char.
    283   static bool ShouldInsertChar(char16 ch, int flags);
    284 
    285   void CreateTouchSelectionControllerAndNotifyIt();
    286 
    287   // Platform specific gesture event handling.
    288   void PlatformGestureEventHandling(const ui::GestureEvent* event);
    289 
    290   // Reveals the obscured char at |index| for the given |duration|. If |index|
    291   // is -1, existing revealed index will be cleared.
    292   void RevealObscuredChar(int index, const base::TimeDelta& duration);
    293 
    294   // The parent textfield, the owner of this object.
    295   Textfield* textfield_;
    296 
    297   // The text model.
    298   scoped_ptr<TextfieldViewsModel> model_;
    299 
    300   // The focusable border.  This is always non-NULL, but may not actually be
    301   // drawn.  If it is not drawn, then by default it's also zero-sized unless the
    302   // Textfield has explicitly-set margins.
    303   FocusableBorder* text_border_;
    304 
    305   // The textfield's text and drop cursor visibility.
    306   bool is_cursor_visible_;
    307 
    308   // The drop cursor is a visual cue for where dragged text will be dropped.
    309   bool is_drop_cursor_visible_;
    310   // Position of the drop cursor, if it is visible.
    311   gfx::SelectionModel drop_cursor_position_;
    312 
    313   // True if InputMethod::CancelComposition() should not be called.
    314   bool skip_input_method_cancel_composition_;
    315 
    316   // Is the user potentially dragging and dropping from this view?
    317   bool initiating_drag_;
    318 
    319   // A runnable method factory for callback to update the cursor.
    320   base::WeakPtrFactory<NativeTextfieldViews> cursor_timer_;
    321 
    322   // State variables used to track double and triple clicks.
    323   size_t aggregated_clicks_;
    324   base::TimeDelta last_click_time_;
    325   gfx::Point last_click_location_;
    326   gfx::Range double_click_word_;
    327 
    328   // Context menu and its content list for the textfield.
    329   scoped_ptr<ui::SimpleMenuModel> context_menu_contents_;
    330   scoped_ptr<views::MenuModelAdapter> context_menu_delegate_;
    331   scoped_ptr<views::MenuRunner> context_menu_runner_;
    332 
    333   scoped_ptr<ui::TouchSelectionController> touch_selection_controller_;
    334 
    335   // A timer to control the duration of showing the last typed char in
    336   // obscured text. When the timer is running, the last typed char is shown
    337   // and when the time expires, the last typed char is obscured.
    338   base::OneShotTimer<NativeTextfieldViews> obscured_reveal_timer_;
    339 
    340   DISALLOW_COPY_AND_ASSIGN(NativeTextfieldViews);
    341 };
    342 
    343 }  // namespace views
    344 
    345 #endif  // UI_VIEWS_CONTROLS_TEXTFIELD_NATIVE_TEXTFIELD_VIEWS_H_
    346