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/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 skip_input_method_cancel_composition_(false), | 255 skip_input_method_cancel_composition_(false), |
256 drop_cursor_visible_(false), | 256 drop_cursor_visible_(false), |
257 initiating_drag_(false), | 257 initiating_drag_(false), |
258 selection_controller_(this), | 258 selection_controller_(this), |
259 drag_start_display_offset_(0), | 259 drag_start_display_offset_(0), |
260 touch_handles_hidden_due_to_scroll_(false), | 260 touch_handles_hidden_due_to_scroll_(false), |
261 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), | 261 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), |
262 weak_ptr_factory_(this) { | 262 weak_ptr_factory_(this) { |
263 set_context_menu_controller(this); | 263 set_context_menu_controller(this); |
264 set_drag_controller(this); | 264 set_drag_controller(this); |
265 cursor_view_.SetPaintToLayer(ui::LAYER_SOLID_COLOR); | |
266 cursor_view_.layer()->SetColor(GetTextColor()); | |
267 cursor_view_.set_owned_by_client(); | |
268 AddChildView(&cursor_view_); | |
265 GetRenderText()->SetFontList(GetDefaultFontList()); | 269 GetRenderText()->SetFontList(GetDefaultFontList()); |
266 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); | 270 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); |
267 SetFocusBehavior(FocusBehavior::ALWAYS); | 271 SetFocusBehavior(FocusBehavior::ALWAYS); |
268 | 272 |
269 // These allow BrowserView to pass edit commands from the Chrome menu to us | 273 // These allow BrowserView to pass edit commands from the Chrome menu to us |
270 // when we're focused by simply asking the FocusManager to | 274 // when we're focused by simply asking the FocusManager to |
271 // ProcessAccelerator() with the relevant accelerators. | 275 // ProcessAccelerator() with the relevant accelerators. |
272 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); | 276 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); |
273 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); | 277 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); |
274 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); | 278 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
948 | 952 |
949 void Textfield::OnPaint(gfx::Canvas* canvas) { | 953 void Textfield::OnPaint(gfx::Canvas* canvas) { |
950 OnPaintBackground(canvas); | 954 OnPaintBackground(canvas); |
951 PaintTextAndCursor(canvas); | 955 PaintTextAndCursor(canvas); |
952 OnPaintBorder(canvas); | 956 OnPaintBorder(canvas); |
953 } | 957 } |
954 | 958 |
955 void Textfield::OnFocus() { | 959 void Textfield::OnFocus() { |
956 GetRenderText()->set_focused(true); | 960 GetRenderText()->set_focused(true); |
957 if (ShouldShowCursor()) | 961 if (ShouldShowCursor()) |
958 GetRenderText()->set_cursor_visible(true); | 962 cursor_view_.SetVisible(true); |
sadrul
2017/02/07 04:19:35
Call UpdateCursorView() before calling SetVisible(
yiyix
2017/02/08 19:47:40
Good Call! Cursor should show at the correct posit
| |
959 if (GetInputMethod()) | 963 if (GetInputMethod()) |
960 GetInputMethod()->SetFocusedTextInputClient(this); | 964 GetInputMethod()->SetFocusedTextInputClient(this); |
961 OnCaretBoundsChanged(); | 965 OnCaretBoundsChanged(); |
962 if (ShouldBlinkCursor()) | 966 if (ShouldBlinkCursor()) |
963 StartBlinkingCursor(); | 967 StartBlinkingCursor(); |
964 if (use_focus_ring_) { | 968 if (use_focus_ring_) { |
965 FocusRing::Install(this, invalid_ | 969 FocusRing::Install(this, invalid_ |
966 ? ui::NativeTheme::kColorId_AlertSeverityHigh | 970 ? ui::NativeTheme::kColorId_AlertSeverityHigh |
967 : ui::NativeTheme::kColorId_NumColors); | 971 : ui::NativeTheme::kColorId_NumColors); |
968 } | 972 } |
973 UpdateCursorView(); | |
969 SchedulePaint(); | 974 SchedulePaint(); |
970 View::OnFocus(); | 975 View::OnFocus(); |
971 } | 976 } |
972 | 977 |
973 void Textfield::OnBlur() { | 978 void Textfield::OnBlur() { |
974 gfx::RenderText* render_text = GetRenderText(); | 979 gfx::RenderText* render_text = GetRenderText(); |
975 render_text->set_focused(false); | 980 render_text->set_focused(false); |
976 if (GetInputMethod()) | 981 if (GetInputMethod()) |
977 GetInputMethod()->DetachTextInputClient(this); | 982 GetInputMethod()->DetachTextInputClient(this); |
978 StopBlinkingCursor(); | 983 StopBlinkingCursor(); |
979 if (render_text->cursor_visible()) { | 984 if (cursor_view_.visible()) { |
980 render_text->set_cursor_visible(false); | 985 cursor_view_.SetVisible(false); |
981 RepaintCursor(); | 986 UpdateCursorView(); |
sadrul
2017/02/07 04:19:35
We don't need to call UpdateCursorView() since it'
yiyix
2017/02/08 19:47:40
Right. It doesn't matter where the cursor is as it
| |
982 } | 987 } |
983 | 988 |
984 DestroyTouchSelection(); | 989 DestroyTouchSelection(); |
985 | 990 |
986 if (use_focus_ring_) | 991 if (use_focus_ring_) |
987 FocusRing::Uninstall(this); | 992 FocusRing::Uninstall(this); |
988 SchedulePaint(); | 993 SchedulePaint(); |
989 View::OnBlur(); | 994 View::OnBlur(); |
990 } | 995 } |
991 | 996 |
992 gfx::Point Textfield::GetKeyboardContextMenuLocation() { | 997 gfx::Point Textfield::GetKeyboardContextMenuLocation() { |
993 return GetCaretBounds().bottom_right(); | 998 return GetCaretBounds().bottom_right(); |
994 } | 999 } |
995 | 1000 |
996 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 1001 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
997 gfx::RenderText* render_text = GetRenderText(); | 1002 gfx::RenderText* render_text = GetRenderText(); |
998 render_text->SetColor(GetTextColor()); | 1003 render_text->SetColor(GetTextColor()); |
999 UpdateBackgroundColor(); | 1004 UpdateBackgroundColor(); |
1000 render_text->set_cursor_color(GetTextColor()); | 1005 render_text->set_cursor_color(GetTextColor()); |
1001 render_text->set_selection_color(GetSelectionTextColor()); | 1006 render_text->set_selection_color(GetSelectionTextColor()); |
1002 render_text->set_selection_background_focused_color( | 1007 render_text->set_selection_background_focused_color( |
1003 GetSelectionBackgroundColor()); | 1008 GetSelectionBackgroundColor()); |
1009 cursor_view_.layer()->SetColor(GetTextColor()); | |
1004 } | 1010 } |
1005 | 1011 |
1006 //////////////////////////////////////////////////////////////////////////////// | 1012 //////////////////////////////////////////////////////////////////////////////// |
1007 // Textfield, TextfieldModel::Delegate overrides: | 1013 // Textfield, TextfieldModel::Delegate overrides: |
1008 | 1014 |
1009 void Textfield::OnCompositionTextConfirmedOrCleared() { | 1015 void Textfield::OnCompositionTextConfirmedOrCleared() { |
1010 if (!skip_input_method_cancel_composition_) | 1016 if (!skip_input_method_cancel_composition_) |
1011 GetInputMethod()->CancelComposition(this); | 1017 GetInputMethod()->CancelComposition(this); |
1012 } | 1018 } |
1013 | 1019 |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1871 View::SetBorder(std::move(border)); | 1877 View::SetBorder(std::move(border)); |
1872 } | 1878 } |
1873 | 1879 |
1874 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { | 1880 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { |
1875 if (text_changed) { | 1881 if (text_changed) { |
1876 if (controller_) | 1882 if (controller_) |
1877 controller_->ContentsChanged(this, text()); | 1883 controller_->ContentsChanged(this, text()); |
1878 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); | 1884 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); |
1879 } | 1885 } |
1880 if (cursor_changed) { | 1886 if (cursor_changed) { |
1881 GetRenderText()->set_cursor_visible(ShouldShowCursor()); | 1887 cursor_view_.SetVisible(ShouldShowCursor()); |
1882 RepaintCursor(); | 1888 UpdateCursorView(); |
1883 if (ShouldBlinkCursor()) | 1889 if (ShouldBlinkCursor()) |
1884 StartBlinkingCursor(); | 1890 StartBlinkingCursor(); |
1885 else | 1891 else |
1886 StopBlinkingCursor(); | 1892 StopBlinkingCursor(); |
1887 if (!text_changed) { | 1893 if (!text_changed) { |
1888 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire | 1894 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire |
1889 // this if only the selection changed. | 1895 // this if only the selection changed. |
1890 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); | 1896 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); |
1891 } | 1897 } |
1892 } | 1898 } |
1893 if (text_changed || cursor_changed) { | 1899 if (text_changed || cursor_changed) { |
1894 OnCaretBoundsChanged(); | 1900 OnCaretBoundsChanged(); |
1895 SchedulePaint(); | 1901 SchedulePaint(); |
1896 } | 1902 } |
1897 } | 1903 } |
1898 | 1904 |
1899 void Textfield::RepaintCursor() { | 1905 void Textfield::UpdateCursorView() { |
1900 gfx::Rect r(GetRenderText()->GetUpdatedCursorBounds()); | 1906 cursor_view_.SetBoundsRect(GetRenderText()->GetUpdatedCursorBounds()); |
1901 r.Inset(-1, -1, -1, -1); | |
1902 SchedulePaintInRect(r); | |
1903 } | 1907 } |
1904 | 1908 |
1905 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { | 1909 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { |
1906 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); | 1910 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); |
1907 canvas->Save(); | 1911 canvas->Save(); |
1908 | 1912 |
1909 // Draw placeholder text if needed. | 1913 // Draw placeholder text if needed. |
1910 gfx::RenderText* render_text = GetRenderText(); | 1914 gfx::RenderText* render_text = GetRenderText(); |
1911 if (text().empty() && !GetPlaceholderText().empty()) { | 1915 if (text().empty() && !GetPlaceholderText().empty()) { |
1912 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), | 1916 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), |
1913 ui::MaterialDesignController::IsSecondaryUiMaterial() | 1917 ui::MaterialDesignController::IsSecondaryUiMaterial() |
1914 ? SkColorSetA(GetTextColor(), 0x83) | 1918 ? SkColorSetA(GetTextColor(), 0x83) |
1915 : placeholder_text_color_, | 1919 : placeholder_text_color_, |
1916 render_text->display_rect()); | 1920 render_text->display_rect()); |
1917 } | 1921 } |
1918 | 1922 |
1919 render_text->Draw(canvas); | 1923 render_text->Draw(canvas); |
1920 | 1924 |
1921 // Draw the detached drop cursor that marks where the text will be dropped. | 1925 // Draw the detached drop cursor that marks where the text will be dropped. |
1926 // TODO(yiyix): Use UpdateCursorView to draw drop_cursor instead. | |
1922 if (drop_cursor_visible_) | 1927 if (drop_cursor_visible_) |
1923 render_text->DrawCursor(canvas, drop_cursor_position_); | 1928 render_text->DrawCursor(canvas, drop_cursor_position_); |
1924 | 1929 |
1925 canvas->Restore(); | 1930 canvas->Restore(); |
1926 } | 1931 } |
1927 | 1932 |
1928 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { | 1933 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { |
1929 if (model_->MoveCursorTo(point, select)) | 1934 if (model_->MoveCursorTo(point, select)) |
1930 UpdateAfterChange(false, true); | 1935 UpdateAfterChange(false, true); |
1931 } | 1936 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2051 Textfield::GetCaretBlinkMs()), | 2056 Textfield::GetCaretBlinkMs()), |
2052 this, &Textfield::OnCursorBlinkTimerFired); | 2057 this, &Textfield::OnCursorBlinkTimerFired); |
2053 } | 2058 } |
2054 | 2059 |
2055 void Textfield::StopBlinkingCursor() { | 2060 void Textfield::StopBlinkingCursor() { |
2056 cursor_blink_timer_.Stop(); | 2061 cursor_blink_timer_.Stop(); |
2057 } | 2062 } |
2058 | 2063 |
2059 void Textfield::OnCursorBlinkTimerFired() { | 2064 void Textfield::OnCursorBlinkTimerFired() { |
2060 DCHECK(ShouldBlinkCursor()); | 2065 DCHECK(ShouldBlinkCursor()); |
2061 gfx::RenderText* render_text = GetRenderText(); | 2066 cursor_view_.SetVisible(!cursor_view_.visible()); |
2062 render_text->set_cursor_visible(!render_text->cursor_visible()); | 2067 UpdateCursorView(); |
2063 RepaintCursor(); | |
2064 } | 2068 } |
2065 | 2069 |
2066 } // namespace views | 2070 } // namespace views |
OLD | NEW |