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