Chromium Code Reviews| 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 |