OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/views/controls/textfield/textfield.h" | 5 #include "ui/views/controls/textfield/textfield.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 use_default_selection_background_color_(true), | 248 use_default_selection_background_color_(true), |
249 text_color_(SK_ColorBLACK), | 249 text_color_(SK_ColorBLACK), |
250 background_color_(SK_ColorWHITE), | 250 background_color_(SK_ColorWHITE), |
251 selection_text_color_(SK_ColorWHITE), | 251 selection_text_color_(SK_ColorWHITE), |
252 selection_background_color_(SK_ColorBLUE), | 252 selection_background_color_(SK_ColorBLUE), |
253 placeholder_text_color_(kDefaultPlaceholderTextColor), | 253 placeholder_text_color_(kDefaultPlaceholderTextColor), |
254 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), | 254 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), |
255 text_input_flags_(0), | 255 text_input_flags_(0), |
256 performing_user_action_(false), | 256 performing_user_action_(false), |
257 skip_input_method_cancel_composition_(false), | 257 skip_input_method_cancel_composition_(false), |
258 cursor_visible_(false), | 258 editing_cursor_visible_(false), |
Peter Kasting
2016/09/16 18:52:27
I still don't really know what "editing cursor vis
| |
259 drop_cursor_visible_(false), | 259 drop_cursor_visible_(false), |
260 initiating_drag_(false), | 260 initiating_drag_(false), |
261 aggregated_clicks_(0), | 261 aggregated_clicks_(0), |
262 drag_start_display_offset_(0), | 262 drag_start_display_offset_(0), |
263 touch_handles_hidden_due_to_scroll_(false), | 263 touch_handles_hidden_due_to_scroll_(false), |
264 weak_ptr_factory_(this) { | 264 weak_ptr_factory_(this) { |
265 set_context_menu_controller(this); | 265 set_context_menu_controller(this); |
266 set_drag_controller(this); | 266 set_drag_controller(this); |
267 GetRenderText()->SetFontList(GetDefaultFontList()); | 267 GetRenderText()->SetFontList(GetDefaultFontList()); |
268 SetBorder(std::unique_ptr<Border>(new FocusableBorder())); | 268 SetBorder(std::unique_ptr<Border>(new FocusableBorder())); |
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
967 } | 967 } |
968 | 968 |
969 void Textfield::OnPaint(gfx::Canvas* canvas) { | 969 void Textfield::OnPaint(gfx::Canvas* canvas) { |
970 OnPaintBackground(canvas); | 970 OnPaintBackground(canvas); |
971 PaintTextAndCursor(canvas); | 971 PaintTextAndCursor(canvas); |
972 OnPaintBorder(canvas); | 972 OnPaintBorder(canvas); |
973 } | 973 } |
974 | 974 |
975 void Textfield::OnFocus() { | 975 void Textfield::OnFocus() { |
976 GetRenderText()->set_focused(true); | 976 GetRenderText()->set_focused(true); |
977 cursor_visible_ = true; | 977 editing_cursor_visible_ = true; |
Peter Kasting
2016/09/16 18:52:27
Why not make this mutually exclusive with HasSelec
| |
978 SchedulePaint(); | 978 SchedulePaint(); |
979 if (GetInputMethod()) | 979 if (GetInputMethod()) |
980 GetInputMethod()->SetFocusedTextInputClient(this); | 980 GetInputMethod()->SetFocusedTextInputClient(this); |
981 OnCaretBoundsChanged(); | 981 OnCaretBoundsChanged(); |
982 | 982 |
983 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); | 983 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); |
984 if (caret_blink_ms != 0) { | 984 if (caret_blink_ms != 0 && !HasSelection()) { |
985 cursor_repaint_timer_.Start(FROM_HERE, | 985 cursor_repaint_timer_.Start(FROM_HERE, |
986 base::TimeDelta::FromMilliseconds(caret_blink_ms), this, | 986 base::TimeDelta::FromMilliseconds(caret_blink_ms), this, |
987 &Textfield::UpdateCursor); | 987 &Textfield::UpdateCursor); |
988 } | 988 } |
989 | 989 |
990 View::OnFocus(); | 990 View::OnFocus(); |
991 SchedulePaint(); | 991 SchedulePaint(); |
992 } | 992 } |
993 | 993 |
994 void Textfield::OnBlur() { | 994 void Textfield::OnBlur() { |
995 GetRenderText()->set_focused(false); | 995 GetRenderText()->set_focused(false); |
996 if (GetInputMethod()) | 996 if (GetInputMethod()) |
997 GetInputMethod()->DetachTextInputClient(this); | 997 GetInputMethod()->DetachTextInputClient(this); |
998 cursor_repaint_timer_.Stop(); | 998 cursor_repaint_timer_.Stop(); |
999 if (cursor_visible_) { | 999 if (editing_cursor_visible_) { |
1000 cursor_visible_ = false; | 1000 editing_cursor_visible_ = false; |
1001 RepaintCursor(); | 1001 RepaintCursor(); |
1002 } | 1002 } |
1003 | 1003 |
1004 DestroyTouchSelection(); | 1004 DestroyTouchSelection(); |
1005 | 1005 |
1006 // Border typically draws focus indicator. | 1006 // Border typically draws focus indicator. |
1007 SchedulePaint(); | 1007 SchedulePaint(); |
1008 } | 1008 } |
1009 | 1009 |
1010 gfx::Point Textfield::GetKeyboardContextMenuLocation() { | 1010 gfx::Point Textfield::GetKeyboardContextMenuLocation() { |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1780 } | 1780 } |
1781 // Disable subpixel rendering when the background color is transparent | 1781 // Disable subpixel rendering when the background color is transparent |
1782 // because it draws incorrect colors around the glyphs in that case. | 1782 // because it draws incorrect colors around the glyphs in that case. |
1783 // See crbug.com/115198 | 1783 // See crbug.com/115198 |
1784 GetRenderText()->set_subpixel_rendering_suppressed( | 1784 GetRenderText()->set_subpixel_rendering_suppressed( |
1785 SkColorGetA(color) != SK_AlphaOPAQUE); | 1785 SkColorGetA(color) != SK_AlphaOPAQUE); |
1786 SchedulePaint(); | 1786 SchedulePaint(); |
1787 } | 1787 } |
1788 | 1788 |
1789 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { | 1789 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { |
1790 DCHECK(HasFocus()); | |
1790 if (text_changed) { | 1791 if (text_changed) { |
1791 if (controller_) | 1792 if (controller_) |
1792 controller_->ContentsChanged(this, text()); | 1793 controller_->ContentsChanged(this, text()); |
1793 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); | 1794 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); |
1794 } | 1795 } |
1795 if (cursor_changed) { | 1796 if (cursor_changed) { |
1796 cursor_visible_ = true; | 1797 editing_cursor_visible_ = false; |
1797 RepaintCursor(); | 1798 RepaintCursor(); |
Peter Kasting
2016/09/16 18:52:27
Nit: Since RepaintCursor() merely schedules a pain
| |
1798 if (cursor_repaint_timer_.IsRunning()) | 1799 |
1800 // If this textfield is not focused, the timer must have been stopped in | |
1801 // |Textfield::OnBlur|, and this method needs to avoid accidentally | |
1802 // restarting it. | |
1803 if (!HasFocus()) | |
1804 DCHECK(!cursor_repaint_timer_.IsRunning()); | |
Peter Kasting
2016/09/16 18:52:27
Nit: Just:
DCHECK(HasFocus() || !cursor_repai
| |
1805 | |
1806 // Cursor repaints are suppressed whenever there is a selection or this view | |
1807 // does not have focus. When the selection changes, the cursor moves, or | |
1808 // this view gains/loses focus, this method will get called with | |
1809 // |cursor_changed| set to true, and the timer will be restarted here. | |
1810 if (HasSelection()) { | |
Peter Kasting
2016/09/16 18:52:27
Nit: Inspired by my suggestion above to move the R
| |
1811 cursor_repaint_timer_.Stop(); | |
1812 } else if (HasFocus() && enabled() && !read_only()) { | |
1813 editing_cursor_visible_ = true; | |
1799 cursor_repaint_timer_.Reset(); | 1814 cursor_repaint_timer_.Reset(); |
1815 } | |
1816 | |
1800 if (!text_changed) { | 1817 if (!text_changed) { |
1801 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire | 1818 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire |
1802 // this if only the selection changed. | 1819 // this if only the selection changed. |
1803 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); | 1820 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); |
1804 } | 1821 } |
1805 } | 1822 } |
1806 if (text_changed || cursor_changed) { | 1823 if (text_changed || cursor_changed) { |
1807 OnCaretBoundsChanged(); | 1824 OnCaretBoundsChanged(); |
1808 SchedulePaint(); | 1825 SchedulePaint(); |
1809 } | 1826 } |
1810 } | 1827 } |
1811 | 1828 |
1812 void Textfield::UpdateCursor() { | 1829 void Textfield::UpdateCursor() { |
1813 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); | 1830 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); |
1814 cursor_visible_ = !cursor_visible_ || (caret_blink_ms == 0); | 1831 editing_cursor_visible_ = !editing_cursor_visible_ || (caret_blink_ms == 0); |
1815 RepaintCursor(); | 1832 RepaintCursor(); |
1816 } | 1833 } |
1817 | 1834 |
1818 void Textfield::RepaintCursor() { | 1835 void Textfield::RepaintCursor() { |
1819 gfx::Rect r(GetRenderText()->GetUpdatedCursorBounds()); | 1836 gfx::Rect r(GetRenderText()->GetUpdatedCursorBounds()); |
1820 r.Inset(-1, -1, -1, -1); | 1837 r.Inset(-1, -1, -1, -1); |
1821 SchedulePaintInRect(r); | 1838 SchedulePaintInRect(r); |
1822 } | 1839 } |
1823 | 1840 |
1824 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { | 1841 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { |
1825 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); | 1842 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); |
1826 canvas->Save(); | 1843 canvas->Save(); |
1827 | 1844 |
1828 // Draw placeholder text if needed. | 1845 // Draw placeholder text if needed. |
1829 gfx::RenderText* render_text = GetRenderText(); | 1846 gfx::RenderText* render_text = GetRenderText(); |
1830 if (text().empty() && !GetPlaceholderText().empty()) { | 1847 if (text().empty() && !GetPlaceholderText().empty()) { |
1831 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), | 1848 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), |
1832 ui::MaterialDesignController::IsSecondaryUiMaterial() | 1849 ui::MaterialDesignController::IsSecondaryUiMaterial() |
1833 ? SkColorSetA(GetTextColor(), 0x83) | 1850 ? SkColorSetA(GetTextColor(), 0x83) |
1834 : placeholder_text_color_, | 1851 : placeholder_text_color_, |
1835 render_text->display_rect()); | 1852 render_text->display_rect()); |
1836 } | 1853 } |
1837 | 1854 |
1838 // Draw the text, cursor, and selection. | 1855 // Draw the text, cursor, and selection. |
1839 render_text->set_cursor_visible(cursor_visible_ && !drop_cursor_visible_ && | 1856 render_text->set_cursor_visible(editing_cursor_visible_ && |
1857 !drop_cursor_visible_ && | |
1840 !HasSelection()); | 1858 !HasSelection()); |
1841 render_text->Draw(canvas); | 1859 render_text->Draw(canvas); |
1842 | 1860 |
1843 // Draw the detached drop cursor that marks where the text will be dropped. | 1861 // Draw the detached drop cursor that marks where the text will be dropped. |
1844 if (drop_cursor_visible_) | 1862 if (drop_cursor_visible_) |
1845 render_text->DrawCursor(canvas, drop_cursor_position_); | 1863 render_text->DrawCursor(canvas, drop_cursor_position_); |
1846 | 1864 |
1847 canvas->Restore(); | 1865 canvas->Restore(); |
1848 } | 1866 } |
1849 | 1867 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2027 RequestFocus(); | 2045 RequestFocus(); |
2028 model_->MoveCursorTo(mouse); | 2046 model_->MoveCursorTo(mouse); |
2029 if (!selection_clipboard_text.empty()) { | 2047 if (!selection_clipboard_text.empty()) { |
2030 model_->InsertText(selection_clipboard_text); | 2048 model_->InsertText(selection_clipboard_text); |
2031 UpdateAfterChange(true, true); | 2049 UpdateAfterChange(true, true); |
2032 } | 2050 } |
2033 OnAfterUserAction(); | 2051 OnAfterUserAction(); |
2034 } | 2052 } |
2035 | 2053 |
2036 } // namespace views | 2054 } // namespace views |
OLD | NEW |