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_.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 |