Home | History | Annotate | Download | only in textfield
      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 UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_
      6 #define UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_
      7 
      8 #include <string>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/strings/string16.h"
     15 #include "base/timer/timer.h"
     16 #include "third_party/skia/include/core/SkColor.h"
     17 #include "ui/base/ime/text_input_client.h"
     18 #include "ui/base/ime/text_input_type.h"
     19 #include "ui/base/models/simple_menu_model.h"
     20 #include "ui/base/touch/touch_editing_controller.h"
     21 #include "ui/events/keycodes/keyboard_codes.h"
     22 #include "ui/gfx/font_list.h"
     23 #include "ui/gfx/range/range.h"
     24 #include "ui/gfx/selection_model.h"
     25 #include "ui/gfx/text_constants.h"
     26 #include "ui/views/context_menu_controller.h"
     27 #include "ui/views/controls/textfield/textfield_model.h"
     28 #include "ui/views/drag_controller.h"
     29 #include "ui/views/view.h"
     30 
     31 namespace views {
     32 
     33 class MenuRunner;
     34 class Painter;
     35 class TextfieldController;
     36 
     37 // A views/skia textfield implementation. No platform-specific code is used.
     38 class VIEWS_EXPORT Textfield : public View,
     39                                public TextfieldModel::Delegate,
     40                                public ContextMenuController,
     41                                public DragController,
     42                                public ui::TouchEditable,
     43                                public ui::TextInputClient {
     44  public:
     45   // The textfield's class name.
     46   static const char kViewClassName[];
     47 
     48   // The preferred size of the padding to be used around textfield text.
     49   static const int kTextPadding;
     50 
     51   // Returns the text cursor blink time in milliseconds, or 0 for no blinking.
     52   static size_t GetCaretBlinkMs();
     53 
     54   Textfield();
     55   virtual ~Textfield();
     56 
     57   // Set the controller for this textfield.
     58   void set_controller(TextfieldController* controller) {
     59     controller_ = controller;
     60   }
     61 
     62   // Gets/Sets whether or not the Textfield is read-only.
     63   bool read_only() const { return read_only_; }
     64   void SetReadOnly(bool read_only);
     65 
     66   // Sets the input type; displays only asterisks for TEXT_INPUT_TYPE_PASSWORD.
     67   void SetTextInputType(ui::TextInputType type);
     68 
     69   // Gets the text currently displayed in the Textfield.
     70   const base::string16& text() const { return model_->text(); }
     71 
     72   // Sets the text currently displayed in the Textfield.  This doesn't
     73   // change the cursor position if the current cursor is within the
     74   // new text's range, or moves the cursor to the end if the cursor is
     75   // out of the new text's range.
     76   void SetText(const base::string16& new_text);
     77 
     78   // Appends the given string to the previously-existing text in the field.
     79   void AppendText(const base::string16& new_text);
     80 
     81   // Inserts |new_text| at the cursor position, replacing any selected text.
     82   void InsertOrReplaceText(const base::string16& new_text);
     83 
     84   // Returns the text direction.
     85   base::i18n::TextDirection GetTextDirection() const;
     86 
     87   // Returns the text that is currently selected.
     88   base::string16 GetSelectedText() const;
     89 
     90   // Select the entire text range. If |reversed| is true, the range will end at
     91   // the logical beginning of the text; this generally shows the leading portion
     92   // of text that overflows its display area.
     93   void SelectAll(bool reversed);
     94 
     95   // A convenience method to select the word closest to |point|.
     96   void SelectWordAt(const gfx::Point& point);
     97 
     98   // Clears the selection within the edit field and sets the caret to the end.
     99   void ClearSelection();
    100 
    101   // Checks if there is any selected text.
    102   bool HasSelection() const;
    103 
    104   // Gets/sets the text color to be used when painting the Textfield.
    105   // Call UseDefaultTextColor() to restore the default system color.
    106   SkColor GetTextColor() const;
    107   void SetTextColor(SkColor color);
    108   void UseDefaultTextColor();
    109 
    110   // Gets/sets the background color to be used when painting the Textfield.
    111   // Call UseDefaultBackgroundColor() to restore the default system color.
    112   SkColor GetBackgroundColor() const;
    113   void SetBackgroundColor(SkColor color);
    114   void UseDefaultBackgroundColor();
    115 
    116   // Gets/sets the selection text color to be used when painting the Textfield.
    117   // Call UseDefaultSelectionTextColor() to restore the default system color.
    118   SkColor GetSelectionTextColor() const;
    119   void SetSelectionTextColor(SkColor color);
    120   void UseDefaultSelectionTextColor();
    121 
    122   // Gets/sets the selection background color to be used when painting the
    123   // Textfield. Call UseDefaultSelectionBackgroundColor() to restore the default
    124   // system color.
    125   SkColor GetSelectionBackgroundColor() const;
    126   void SetSelectionBackgroundColor(SkColor color);
    127   void UseDefaultSelectionBackgroundColor();
    128 
    129   // Set drop shadows underneath the text.
    130   void SetShadows(const gfx::ShadowValues& shadows);
    131 
    132   // Gets/Sets whether or not the cursor is enabled.
    133   bool GetCursorEnabled() const;
    134   void SetCursorEnabled(bool enabled);
    135 
    136   // Gets/Sets the fonts used when rendering the text within the Textfield.
    137   const gfx::FontList& GetFontList() const;
    138   void SetFontList(const gfx::FontList& font_list);
    139 
    140   // Sets the default width of the text control. See default_width_in_chars_.
    141   void set_default_width_in_chars(int default_width) {
    142     default_width_in_chars_ = default_width;
    143   }
    144 
    145   // Sets the text to display when empty.
    146   void set_placeholder_text(const base::string16& text) {
    147     placeholder_text_ = text;
    148   }
    149   virtual base::string16 GetPlaceholderText() const;
    150 
    151   SkColor placeholder_text_color() const { return placeholder_text_color_; }
    152   void set_placeholder_text_color(SkColor color) {
    153     placeholder_text_color_ = color;
    154   }
    155 
    156   // Get or set the horizontal alignment used for the button from the underlying
    157   // RenderText object.
    158   gfx::HorizontalAlignment GetHorizontalAlignment() const;
    159   void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);
    160 
    161   // Displays a virtual keyboard or alternate input view if enabled.
    162   void ShowImeIfNeeded();
    163 
    164   // Returns whether or not an IME is composing text.
    165   bool IsIMEComposing() const;
    166 
    167   // Gets the selected logical text range.
    168   const gfx::Range& GetSelectedRange() const;
    169 
    170   // Selects the specified logical text range.
    171   void SelectRange(const gfx::Range& range);
    172 
    173   // Gets the text selection model.
    174   const gfx::SelectionModel& GetSelectionModel() const;
    175 
    176   // Sets the specified text selection model.
    177   void SelectSelectionModel(const gfx::SelectionModel& sel);
    178 
    179   // Returns the current cursor position.
    180   size_t GetCursorPosition() const;
    181 
    182   // Set the text color over the entire text or a logical character range.
    183   // Empty and invalid ranges are ignored.
    184   void SetColor(SkColor value);
    185   void ApplyColor(SkColor value, const gfx::Range& range);
    186 
    187   // Set various text styles over the entire text or a logical character range.
    188   // The respective |style| is applied if |value| is true, or removed if false.
    189   // Empty and invalid ranges are ignored.
    190   void SetStyle(gfx::TextStyle style, bool value);
    191   void ApplyStyle(gfx::TextStyle style, bool value, const gfx::Range& range);
    192 
    193   // Clears Edit history.
    194   void ClearEditHistory();
    195 
    196   // Set the accessible name of the text field.
    197   void SetAccessibleName(const base::string16& name);
    198 
    199   // Performs the action associated with the specified command id.
    200   void ExecuteCommand(int command_id);
    201 
    202   void SetFocusPainter(scoped_ptr<Painter> focus_painter);
    203 
    204   // Returns whether there is a drag operation originating from the textfield.
    205   bool HasTextBeingDragged();
    206 
    207   // View overrides:
    208   virtual gfx::Insets GetInsets() const OVERRIDE;
    209   virtual int GetBaseline() const OVERRIDE;
    210   virtual gfx::Size GetPreferredSize() const OVERRIDE;
    211   virtual const char* GetClassName() const OVERRIDE;
    212   virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
    213   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
    214   virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
    215   virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
    216   virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
    217   virtual ui::TextInputClient* GetTextInputClient() OVERRIDE;
    218   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
    219   virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE;
    220   virtual bool SkipDefaultKeyEventProcessing(
    221       const ui::KeyEvent& event) OVERRIDE;
    222   virtual bool GetDropFormats(
    223       int* formats,
    224       std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
    225   virtual bool CanDrop(const ui::OSExchangeData& data) OVERRIDE;
    226   virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE;
    227   virtual void OnDragExited() OVERRIDE;
    228   virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE;
    229   virtual void OnDragDone() OVERRIDE;
    230   virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
    231   virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
    232   virtual bool GetNeedsNotificationWhenVisibleBoundsChange() const OVERRIDE;
    233   virtual void OnVisibleBoundsChanged() OVERRIDE;
    234   virtual void OnEnabledChanged() OVERRIDE;
    235   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
    236   virtual void OnFocus() OVERRIDE;
    237   virtual void OnBlur() OVERRIDE;
    238   virtual gfx::Point GetKeyboardContextMenuLocation() OVERRIDE;
    239   virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE;
    240 
    241   // TextfieldModel::Delegate overrides:
    242   virtual void OnCompositionTextConfirmedOrCleared() OVERRIDE;
    243 
    244   // ContextMenuController overrides:
    245   virtual void ShowContextMenuForView(View* source,
    246                                       const gfx::Point& point,
    247                                       ui::MenuSourceType source_type) OVERRIDE;
    248 
    249   // DragController overrides:
    250   virtual void WriteDragDataForView(View* sender,
    251                                     const gfx::Point& press_pt,
    252                                     ui::OSExchangeData* data) OVERRIDE;
    253   virtual int GetDragOperationsForView(View* sender,
    254                                        const gfx::Point& p) OVERRIDE;
    255   virtual bool CanStartDragForView(View* sender,
    256                                    const gfx::Point& press_pt,
    257                                    const gfx::Point& p) OVERRIDE;
    258 
    259   // ui::TouchEditable overrides:
    260   virtual void SelectRect(const gfx::Point& start,
    261                           const gfx::Point& end) OVERRIDE;
    262   virtual void MoveCaretTo(const gfx::Point& point) OVERRIDE;
    263   virtual void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) OVERRIDE;
    264   virtual gfx::Rect GetBounds() OVERRIDE;
    265   virtual gfx::NativeView GetNativeView() const OVERRIDE;
    266   virtual void ConvertPointToScreen(gfx::Point* point) OVERRIDE;
    267   virtual void ConvertPointFromScreen(gfx::Point* point) OVERRIDE;
    268   virtual bool DrawsHandles() OVERRIDE;
    269   virtual void OpenContextMenu(const gfx::Point& anchor) OVERRIDE;
    270   virtual void DestroyTouchSelection() OVERRIDE;
    271 
    272   // ui::SimpleMenuModel::Delegate overrides:
    273   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
    274   virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
    275   virtual bool GetAcceleratorForCommandId(
    276       int command_id,
    277       ui::Accelerator* accelerator) OVERRIDE;
    278   virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
    279 
    280   // ui::TextInputClient overrides:
    281   virtual void SetCompositionText(
    282       const ui::CompositionText& composition) OVERRIDE;
    283   virtual void ConfirmCompositionText() OVERRIDE;
    284   virtual void ClearCompositionText() OVERRIDE;
    285   virtual void InsertText(const base::string16& text) OVERRIDE;
    286   virtual void InsertChar(base::char16 ch, int flags) OVERRIDE;
    287   virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE;
    288   virtual ui::TextInputType GetTextInputType() const OVERRIDE;
    289   virtual ui::TextInputMode GetTextInputMode() const OVERRIDE;
    290   virtual bool CanComposeInline() const OVERRIDE;
    291   virtual gfx::Rect GetCaretBounds() const OVERRIDE;
    292   virtual bool GetCompositionCharacterBounds(uint32 index,
    293                                              gfx::Rect* rect) const OVERRIDE;
    294   virtual bool HasCompositionText() const OVERRIDE;
    295   virtual bool GetTextRange(gfx::Range* range) const OVERRIDE;
    296   virtual bool GetCompositionTextRange(gfx::Range* range) const OVERRIDE;
    297   virtual bool GetSelectionRange(gfx::Range* range) const OVERRIDE;
    298   virtual bool SetSelectionRange(const gfx::Range& range) OVERRIDE;
    299   virtual bool DeleteRange(const gfx::Range& range) OVERRIDE;
    300   virtual bool GetTextFromRange(const gfx::Range& range,
    301                                 base::string16* text) const OVERRIDE;
    302   virtual void OnInputMethodChanged() OVERRIDE;
    303   virtual bool ChangeTextDirectionAndLayoutAlignment(
    304       base::i18n::TextDirection direction) OVERRIDE;
    305   virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE;
    306   virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE;
    307   virtual void OnCandidateWindowShown() OVERRIDE;
    308   virtual void OnCandidateWindowUpdated() OVERRIDE;
    309   virtual void OnCandidateWindowHidden() OVERRIDE;
    310   virtual bool IsEditingCommandEnabled(int command_id) OVERRIDE;
    311   virtual void ExecuteEditingCommand(int command_id) OVERRIDE;
    312 
    313  protected:
    314   // Returns the TextfieldModel's text/cursor/selection rendering model.
    315   gfx::RenderText* GetRenderText() const;
    316 
    317   gfx::Point last_click_location() const { return last_click_location_; }
    318 
    319   // Get the text from the selection clipboard.
    320   virtual base::string16 GetSelectionClipboardText() const;
    321 
    322  private:
    323   friend class TextfieldTestApi;
    324 
    325   // Handles a request to change the value of this text field from software
    326   // using an accessibility API (typically automation software, screen readers
    327   // don't normally use this). Sets the value and clears the selection.
    328   void AccessibilitySetValue(const base::string16& new_value);
    329 
    330   // Updates the painted background color.
    331   void UpdateBackgroundColor();
    332 
    333   // Does necessary updates when the text and/or cursor position changes.
    334   void UpdateAfterChange(bool text_changed, bool cursor_changed);
    335 
    336   // A callback function to periodically update the cursor state.
    337   void UpdateCursor();
    338 
    339   // Repaint the cursor.
    340   void RepaintCursor();
    341 
    342   void PaintTextAndCursor(gfx::Canvas* canvas);
    343 
    344   // Helper function to call MoveCursorTo on the TextfieldModel.
    345   void MoveCursorTo(const gfx::Point& point, bool select);
    346 
    347   // Helper function to update the selection on a mouse drag.
    348   void SelectThroughLastDragLocation();
    349 
    350   // Convenience method to notify the InputMethod and TouchSelectionController.
    351   void OnCaretBoundsChanged();
    352 
    353   // Convenience method to call TextfieldController::OnBeforeUserAction();
    354   void OnBeforeUserAction();
    355 
    356   // Convenience method to call TextfieldController::OnAfterUserAction();
    357   void OnAfterUserAction();
    358 
    359   // Calls |model_->Cut()| and notifies TextfieldController on success.
    360   bool Cut();
    361 
    362   // Calls |model_->Copy()| and notifies TextfieldController on success.
    363   bool Copy();
    364 
    365   // Calls |model_->Paste()| and calls TextfieldController::ContentsChanged()
    366   // explicitly if paste succeeded.
    367   bool Paste();
    368 
    369   // Utility function to prepare the context menu.
    370   void UpdateContextMenu();
    371 
    372   // Tracks the mouse clicks for single/double/triple clicks.
    373   void TrackMouseClicks(const ui::MouseEvent& event);
    374 
    375   // Returns true if the current text input type allows access by the IME.
    376   bool ImeEditingAllowed() const;
    377 
    378   // Reveals the password character at |index| for a set duration.
    379   // If |index| is -1, the existing revealed character will be reset.
    380   void RevealPasswordChar(int index);
    381 
    382   void CreateTouchSelectionControllerAndNotifyIt();
    383 
    384   // Updates the selection clipboard to any non-empty text selection.
    385   void UpdateSelectionClipboard() const;
    386 
    387   // Pastes the selection clipboard for the specified mouse event.
    388   void PasteSelectionClipboard(const ui::MouseEvent& event);
    389 
    390   // The text model.
    391   scoped_ptr<TextfieldModel> model_;
    392 
    393   // This is the current listener for events from this Textfield.
    394   TextfieldController* controller_;
    395 
    396   // True if this Textfield cannot accept input and is read-only.
    397   bool read_only_;
    398 
    399   // The default number of average characters for the width of this text field.
    400   // This will be reported as the "desired size". Defaults to 0.
    401   int default_width_in_chars_;
    402 
    403   scoped_ptr<Painter> focus_painter_;
    404 
    405   // Flags indicating whether various system colors should be used, and if not,
    406   // what overriding color values should be used instead.
    407   bool use_default_text_color_;
    408   bool use_default_background_color_;
    409   bool use_default_selection_text_color_;
    410   bool use_default_selection_background_color_;
    411   SkColor text_color_;
    412   SkColor background_color_;
    413   SkColor selection_text_color_;
    414   SkColor selection_background_color_;
    415 
    416   // Text to display when empty.
    417   base::string16 placeholder_text_;
    418 
    419   // Placeholder text color.
    420   SkColor placeholder_text_color_;
    421 
    422   // The accessible name of the text field.
    423   base::string16 accessible_name_;
    424 
    425   // The input type of this text field.
    426   ui::TextInputType text_input_type_;
    427 
    428   // The duration and timer to reveal the last typed password character.
    429   base::TimeDelta password_reveal_duration_;
    430   base::OneShotTimer<Textfield> password_reveal_timer_;
    431 
    432   // Tracks whether a user action is being performed; i.e. OnBeforeUserAction()
    433   // has been called, but OnAfterUserAction() has not yet been called.
    434   bool performing_user_action_;
    435 
    436   // True if InputMethod::CancelComposition() should not be called.
    437   bool skip_input_method_cancel_composition_;
    438 
    439   // The text editing cursor repaint timer and visibility.
    440   base::RepeatingTimer<Textfield> cursor_repaint_timer_;
    441   bool cursor_visible_;
    442 
    443   // The drop cursor is a visual cue for where dragged text will be dropped.
    444   bool drop_cursor_visible_;
    445   gfx::SelectionModel drop_cursor_position_;
    446 
    447   // Is the user potentially dragging and dropping from this view?
    448   bool initiating_drag_;
    449 
    450   // A timer and point used to modify the selection when dragging.
    451   base::RepeatingTimer<Textfield> drag_selection_timer_;
    452   gfx::Point last_drag_location_;
    453 
    454   // State variables used to track double and triple clicks.
    455   size_t aggregated_clicks_;
    456   base::TimeDelta last_click_time_;
    457   gfx::Point last_click_location_;
    458   gfx::Range double_click_word_;
    459 
    460   scoped_ptr<ui::TouchSelectionController> touch_selection_controller_;
    461 
    462   // Used to track touch drag starting location and offset to enable touch
    463   // scrolling.
    464   gfx::Point drag_start_location_;
    465   int drag_start_display_offset_;
    466 
    467   // Tracks if touch editing handles are hidden because user has started
    468   // scrolling. If |true|, handles are shown after scrolling ends.
    469   bool touch_handles_hidden_due_to_scroll_;
    470 
    471   // Context menu related members.
    472   scoped_ptr<ui::SimpleMenuModel> context_menu_contents_;
    473   scoped_ptr<views::MenuRunner> context_menu_runner_;
    474 
    475   // Used to bind callback functions to this object.
    476   base::WeakPtrFactory<Textfield> weak_ptr_factory_;
    477 
    478   DISALLOW_COPY_AND_ASSIGN(Textfield);
    479 };
    480 
    481 }  // namespace views
    482 
    483 #endif  // UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_H_
    484