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_.reset(new views::View()); | |
266 cursor_view_->SetPaintToLayer(ui::LAYER_SOLID_COLOR); | |
267 cursor_view_->layer()->SetColor(GetTextColor()); | |
268 cursor_view_->set_owned_by_client(); | |
269 AddChildView(cursor_view_.get()); | |
265 GetRenderText()->SetFontList(GetDefaultFontList()); | 270 GetRenderText()->SetFontList(GetDefaultFontList()); |
266 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); | 271 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); |
267 SetFocusBehavior(FocusBehavior::ALWAYS); | 272 SetFocusBehavior(FocusBehavior::ALWAYS); |
268 | 273 |
269 // These allow BrowserView to pass edit commands from the Chrome menu to us | 274 // These allow BrowserView to pass edit commands from the Chrome menu to us |
270 // when we're focused by simply asking the FocusManager to | 275 // when we're focused by simply asking the FocusManager to |
271 // ProcessAccelerator() with the relevant accelerators. | 276 // ProcessAccelerator() with the relevant accelerators. |
272 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); | 277 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); |
273 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); | 278 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); |
274 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); | 279 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 model_->SelectSelectionModel(sel); | 494 model_->SelectSelectionModel(sel); |
490 UpdateAfterChange(false, true); | 495 UpdateAfterChange(false, true); |
491 } | 496 } |
492 | 497 |
493 size_t Textfield::GetCursorPosition() const { | 498 size_t Textfield::GetCursorPosition() const { |
494 return model_->GetCursorPosition(); | 499 return model_->GetCursorPosition(); |
495 } | 500 } |
496 | 501 |
497 void Textfield::SetColor(SkColor value) { | 502 void Textfield::SetColor(SkColor value) { |
498 GetRenderText()->SetColor(value); | 503 GetRenderText()->SetColor(value); |
499 SchedulePaint(); | 504 SchedulePaint(); |
sadrul
2017/02/02 17:15:32
We should update the layer color here too.
yiyix
2017/02/06 21:36:18
I was not sure if the cursor color has to be the s
| |
500 } | 505 } |
501 | 506 |
502 void Textfield::ApplyColor(SkColor value, const gfx::Range& range) { | 507 void Textfield::ApplyColor(SkColor value, const gfx::Range& range) { |
503 GetRenderText()->ApplyColor(value, range); | 508 GetRenderText()->ApplyColor(value, range); |
504 SchedulePaint(); | 509 SchedulePaint(); |
505 } | 510 } |
506 | 511 |
507 void Textfield::SetStyle(gfx::TextStyle style, bool value) { | 512 void Textfield::SetStyle(gfx::TextStyle style, bool value) { |
508 GetRenderText()->SetStyle(style, value); | 513 GetRenderText()->SetStyle(style, value); |
509 SchedulePaint(); | 514 SchedulePaint(); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
948 | 953 |
949 void Textfield::OnPaint(gfx::Canvas* canvas) { | 954 void Textfield::OnPaint(gfx::Canvas* canvas) { |
950 OnPaintBackground(canvas); | 955 OnPaintBackground(canvas); |
951 PaintTextAndCursor(canvas); | 956 PaintTextAndCursor(canvas); |
952 OnPaintBorder(canvas); | 957 OnPaintBorder(canvas); |
953 } | 958 } |
954 | 959 |
955 void Textfield::OnFocus() { | 960 void Textfield::OnFocus() { |
956 GetRenderText()->set_focused(true); | 961 GetRenderText()->set_focused(true); |
957 if (ShouldShowCursor()) | 962 if (ShouldShowCursor()) |
958 GetRenderText()->set_cursor_visible(true); | 963 cursor_view_->SetVisible(true); |
959 if (GetInputMethod()) | 964 if (GetInputMethod()) |
960 GetInputMethod()->SetFocusedTextInputClient(this); | 965 GetInputMethod()->SetFocusedTextInputClient(this); |
961 OnCaretBoundsChanged(); | 966 OnCaretBoundsChanged(); |
962 if (ShouldBlinkCursor()) | 967 if (ShouldBlinkCursor()) |
963 StartBlinkingCursor(); | 968 StartBlinkingCursor(); |
964 if (use_focus_ring_) { | 969 if (use_focus_ring_) { |
965 FocusRing::Install(this, invalid_ | 970 FocusRing::Install(this, invalid_ |
966 ? ui::NativeTheme::kColorId_AlertSeverityHigh | 971 ? ui::NativeTheme::kColorId_AlertSeverityHigh |
967 : ui::NativeTheme::kColorId_NumColors); | 972 : ui::NativeTheme::kColorId_NumColors); |
968 } | 973 } |
974 RepaintCursor(); | |
969 SchedulePaint(); | 975 SchedulePaint(); |
970 View::OnFocus(); | 976 View::OnFocus(); |
971 } | 977 } |
972 | 978 |
973 void Textfield::OnBlur() { | 979 void Textfield::OnBlur() { |
974 gfx::RenderText* render_text = GetRenderText(); | 980 gfx::RenderText* render_text = GetRenderText(); |
975 render_text->set_focused(false); | 981 render_text->set_focused(false); |
976 if (GetInputMethod()) | 982 if (GetInputMethod()) |
977 GetInputMethod()->DetachTextInputClient(this); | 983 GetInputMethod()->DetachTextInputClient(this); |
978 StopBlinkingCursor(); | 984 StopBlinkingCursor(); |
979 if (render_text->cursor_visible()) { | 985 if (cursor_view_->visible()) { |
980 render_text->set_cursor_visible(false); | 986 cursor_view_->SetVisible(false); |
981 RepaintCursor(); | 987 RepaintCursor(); |
982 } | 988 } |
983 | 989 |
984 DestroyTouchSelection(); | 990 DestroyTouchSelection(); |
985 | 991 |
986 if (use_focus_ring_) | 992 if (use_focus_ring_) |
987 FocusRing::Uninstall(this); | 993 FocusRing::Uninstall(this); |
988 SchedulePaint(); | 994 SchedulePaint(); |
989 View::OnBlur(); | 995 View::OnBlur(); |
990 } | 996 } |
991 | 997 |
992 gfx::Point Textfield::GetKeyboardContextMenuLocation() { | 998 gfx::Point Textfield::GetKeyboardContextMenuLocation() { |
993 return GetCaretBounds().bottom_right(); | 999 return GetCaretBounds().bottom_right(); |
994 } | 1000 } |
995 | 1001 |
996 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 1002 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
997 gfx::RenderText* render_text = GetRenderText(); | 1003 gfx::RenderText* render_text = GetRenderText(); |
998 render_text->SetColor(GetTextColor()); | 1004 render_text->SetColor(GetTextColor()); |
999 UpdateBackgroundColor(); | 1005 UpdateBackgroundColor(); |
1000 render_text->set_cursor_color(GetTextColor()); | 1006 render_text->set_cursor_color(GetTextColor()); |
1001 render_text->set_selection_color(GetSelectionTextColor()); | 1007 render_text->set_selection_color(GetSelectionTextColor()); |
1002 render_text->set_selection_background_focused_color( | 1008 render_text->set_selection_background_focused_color( |
1003 GetSelectionBackgroundColor()); | 1009 GetSelectionBackgroundColor()); |
1010 cursor_view_->layer()->SetColor(GetTextColor()); | |
1004 } | 1011 } |
1005 | 1012 |
1006 //////////////////////////////////////////////////////////////////////////////// | 1013 //////////////////////////////////////////////////////////////////////////////// |
1007 // Textfield, TextfieldModel::Delegate overrides: | 1014 // Textfield, TextfieldModel::Delegate overrides: |
1008 | 1015 |
1009 void Textfield::OnCompositionTextConfirmedOrCleared() { | 1016 void Textfield::OnCompositionTextConfirmedOrCleared() { |
1010 if (!skip_input_method_cancel_composition_) | 1017 if (!skip_input_method_cancel_composition_) |
1011 GetInputMethod()->CancelComposition(this); | 1018 GetInputMethod()->CancelComposition(this); |
1012 } | 1019 } |
1013 | 1020 |
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1871 View::SetBorder(std::move(border)); | 1878 View::SetBorder(std::move(border)); |
1872 } | 1879 } |
1873 | 1880 |
1874 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { | 1881 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { |
1875 if (text_changed) { | 1882 if (text_changed) { |
1876 if (controller_) | 1883 if (controller_) |
1877 controller_->ContentsChanged(this, text()); | 1884 controller_->ContentsChanged(this, text()); |
1878 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); | 1885 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); |
1879 } | 1886 } |
1880 if (cursor_changed) { | 1887 if (cursor_changed) { |
1881 GetRenderText()->set_cursor_visible(ShouldShowCursor()); | 1888 cursor_view_->SetVisible(ShouldShowCursor()); |
1882 RepaintCursor(); | 1889 RepaintCursor(); |
1883 if (ShouldBlinkCursor()) | 1890 if (ShouldBlinkCursor()) |
1884 StartBlinkingCursor(); | 1891 StartBlinkingCursor(); |
1885 else | 1892 else |
1886 StopBlinkingCursor(); | 1893 StopBlinkingCursor(); |
1887 if (!text_changed) { | 1894 if (!text_changed) { |
1888 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire | 1895 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire |
1889 // this if only the selection changed. | 1896 // this if only the selection changed. |
1890 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); | 1897 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); |
1891 } | 1898 } |
1892 } | 1899 } |
1893 if (text_changed || cursor_changed) { | 1900 if (text_changed || cursor_changed) { |
1894 OnCaretBoundsChanged(); | 1901 OnCaretBoundsChanged(); |
1895 SchedulePaint(); | 1902 SchedulePaint(); |
1896 } | 1903 } |
1897 } | 1904 } |
1898 | 1905 |
1899 void Textfield::RepaintCursor() { | 1906 void Textfield::RepaintCursor() { |
1900 gfx::Rect r(GetRenderText()->GetUpdatedCursorBounds()); | 1907 cursor_view_->SetBoundsRect(GetRenderText()->GetUpdatedCursorBounds()); |
1901 r.Inset(-1, -1, -1, -1); | 1908 SchedulePaint(); |
sadrul
2017/02/02 17:15:32
You shouldn't reschedule a paint here, because the
yiyix
2017/02/06 21:36:17
Done.
| |
1902 SchedulePaintInRect(r); | |
1903 } | 1909 } |
1904 | 1910 |
1905 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { | 1911 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { |
1906 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); | 1912 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); |
1907 canvas->Save(); | 1913 canvas->Save(); |
1908 | 1914 |
1909 // Draw placeholder text if needed. | 1915 // Draw placeholder text if needed. |
1910 gfx::RenderText* render_text = GetRenderText(); | 1916 gfx::RenderText* render_text = GetRenderText(); |
1911 if (text().empty() && !GetPlaceholderText().empty()) { | 1917 if (text().empty() && !GetPlaceholderText().empty()) { |
1912 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), | 1918 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), |
1913 ui::MaterialDesignController::IsSecondaryUiMaterial() | 1919 ui::MaterialDesignController::IsSecondaryUiMaterial() |
1914 ? SkColorSetA(GetTextColor(), 0x83) | 1920 ? SkColorSetA(GetTextColor(), 0x83) |
1915 : placeholder_text_color_, | 1921 : placeholder_text_color_, |
1916 render_text->display_rect()); | 1922 render_text->display_rect()); |
1917 } | 1923 } |
1918 | 1924 |
1919 render_text->Draw(canvas); | 1925 render_text->Draw(canvas); |
1920 | 1926 |
1921 // Draw the detached drop cursor that marks where the text will be dropped. | 1927 // Draw the detached drop cursor that marks where the text will be dropped. |
1922 if (drop_cursor_visible_) | 1928 if (drop_cursor_visible_) |
1923 render_text->DrawCursor(canvas, drop_cursor_position_); | 1929 render_text->DrawCursor(canvas, drop_cursor_position_); |
sadrul
2017/02/02 17:15:31
Add a TODO.
yiyix
2017/02/06 21:36:18
Done.
| |
1924 | 1930 |
1925 canvas->Restore(); | 1931 canvas->Restore(); |
1926 } | 1932 } |
1927 | 1933 |
1928 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { | 1934 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { |
1929 if (model_->MoveCursorTo(point, select)) | 1935 if (model_->MoveCursorTo(point, select)) |
1930 UpdateAfterChange(false, true); | 1936 UpdateAfterChange(false, true); |
1931 } | 1937 } |
1932 | 1938 |
1933 void Textfield::OnCaretBoundsChanged() { | 1939 void Textfield::OnCaretBoundsChanged() { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2051 Textfield::GetCaretBlinkMs()), | 2057 Textfield::GetCaretBlinkMs()), |
2052 this, &Textfield::OnCursorBlinkTimerFired); | 2058 this, &Textfield::OnCursorBlinkTimerFired); |
2053 } | 2059 } |
2054 | 2060 |
2055 void Textfield::StopBlinkingCursor() { | 2061 void Textfield::StopBlinkingCursor() { |
2056 cursor_blink_timer_.Stop(); | 2062 cursor_blink_timer_.Stop(); |
2057 } | 2063 } |
2058 | 2064 |
2059 void Textfield::OnCursorBlinkTimerFired() { | 2065 void Textfield::OnCursorBlinkTimerFired() { |
2060 DCHECK(ShouldBlinkCursor()); | 2066 DCHECK(ShouldBlinkCursor()); |
2061 gfx::RenderText* render_text = GetRenderText(); | 2067 cursor_view_->SetVisible(!cursor_view_->visible()); |
sadrul
2017/02/02 17:15:32
If you update the visibility in UpdateCursorView()
yiyix
2017/02/06 21:36:17
As we have discussed offline, keep the set visibil
| |
2062 render_text->set_cursor_visible(!render_text->cursor_visible()); | |
2063 RepaintCursor(); | 2068 RepaintCursor(); |
2064 } | 2069 } |
2065 | 2070 |
2066 } // namespace views | 2071 } // namespace views |
OLD | NEW |