 Chromium Code Reviews
 Chromium Code Reviews Issue 2660593002:
  Paint text cursor in LAYER_SOLID_COLOR  (Closed)
    
  
    Issue 2660593002:
  Paint text cursor in LAYER_SOLID_COLOR  (Closed) 
  | 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 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 skip_input_method_cancel_composition_(false), | 267 skip_input_method_cancel_composition_(false), | 
| 268 drop_cursor_visible_(false), | 268 drop_cursor_visible_(false), | 
| 269 initiating_drag_(false), | 269 initiating_drag_(false), | 
| 270 selection_controller_(this), | 270 selection_controller_(this), | 
| 271 drag_start_display_offset_(0), | 271 drag_start_display_offset_(0), | 
| 272 touch_handles_hidden_due_to_scroll_(false), | 272 touch_handles_hidden_due_to_scroll_(false), | 
| 273 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), | 273 use_focus_ring_(ui::MaterialDesignController::IsSecondaryUiMaterial()), | 
| 274 weak_ptr_factory_(this) { | 274 weak_ptr_factory_(this) { | 
| 275 set_context_menu_controller(this); | 275 set_context_menu_controller(this); | 
| 276 set_drag_controller(this); | 276 set_drag_controller(this); | 
| 277 cursor_view_.SetPaintToLayer(ui::LAYER_SOLID_COLOR); | |
| 278 cursor_view_.layer()->SetColor(GetTextColor()); | |
| 279 // |cursor_view_| is owned by TextField view. | |
| 
msw
2017/02/15 22:50:04
nit: 'Textfield' to match the class name.
 | |
| 280 cursor_view_.set_owned_by_client(); | |
| 281 AddChildView(&cursor_view_); | |
| 277 GetRenderText()->SetFontList(GetDefaultFontList()); | 282 GetRenderText()->SetFontList(GetDefaultFontList()); | 
| 278 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); | 283 View::SetBorder(std::unique_ptr<Border>(new FocusableBorder())); | 
| 279 SetFocusBehavior(FocusBehavior::ALWAYS); | 284 SetFocusBehavior(FocusBehavior::ALWAYS); | 
| 280 | 285 | 
| 281 // These allow BrowserView to pass edit commands from the Chrome menu to us | 286 // These allow BrowserView to pass edit commands from the Chrome menu to us | 
| 282 // when we're focused by simply asking the FocusManager to | 287 // when we're focused by simply asking the FocusManager to | 
| 283 // ProcessAccelerator() with the relevant accelerators. | 288 // ProcessAccelerator() with the relevant accelerators. | 
| 284 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); | 289 AddAccelerator(ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN)); | 
| 285 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); | 290 AddAccelerator(ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); | 
| 286 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); | 291 AddAccelerator(ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN)); | 
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 968 } | 973 } | 
| 969 | 974 | 
| 970 void Textfield::OnPaint(gfx::Canvas* canvas) { | 975 void Textfield::OnPaint(gfx::Canvas* canvas) { | 
| 971 OnPaintBackground(canvas); | 976 OnPaintBackground(canvas); | 
| 972 PaintTextAndCursor(canvas); | 977 PaintTextAndCursor(canvas); | 
| 973 OnPaintBorder(canvas); | 978 OnPaintBorder(canvas); | 
| 974 } | 979 } | 
| 975 | 980 | 
| 976 void Textfield::OnFocus() { | 981 void Textfield::OnFocus() { | 
| 977 GetRenderText()->set_focused(true); | 982 GetRenderText()->set_focused(true); | 
| 978 if (ShouldShowCursor()) | 983 if (ShouldShowCursor()) { | 
| 979 GetRenderText()->set_cursor_visible(true); | 984 UpdateCursorView(); | 
| 985 cursor_view_.SetVisible(true); | |
| 986 } | |
| 980 if (GetInputMethod()) | 987 if (GetInputMethod()) | 
| 981 GetInputMethod()->SetFocusedTextInputClient(this); | 988 GetInputMethod()->SetFocusedTextInputClient(this); | 
| 982 OnCaretBoundsChanged(); | 989 OnCaretBoundsChanged(); | 
| 983 if (ShouldBlinkCursor()) | 990 if (ShouldBlinkCursor()) | 
| 984 StartBlinkingCursor(); | 991 StartBlinkingCursor(); | 
| 985 if (use_focus_ring_) { | 992 if (use_focus_ring_) { | 
| 986 FocusRing::Install(this, invalid_ | 993 FocusRing::Install(this, invalid_ | 
| 987 ? ui::NativeTheme::kColorId_AlertSeverityHigh | 994 ? ui::NativeTheme::kColorId_AlertSeverityHigh | 
| 988 : ui::NativeTheme::kColorId_NumColors); | 995 : ui::NativeTheme::kColorId_NumColors); | 
| 989 } | 996 } | 
| 990 SchedulePaint(); | 997 SchedulePaint(); | 
| 991 View::OnFocus(); | 998 View::OnFocus(); | 
| 992 } | 999 } | 
| 993 | 1000 | 
| 994 void Textfield::OnBlur() { | 1001 void Textfield::OnBlur() { | 
| 995 gfx::RenderText* render_text = GetRenderText(); | 1002 gfx::RenderText* render_text = GetRenderText(); | 
| 996 render_text->set_focused(false); | 1003 render_text->set_focused(false); | 
| 997 if (GetInputMethod()) | 1004 if (GetInputMethod()) | 
| 998 GetInputMethod()->DetachTextInputClient(this); | 1005 GetInputMethod()->DetachTextInputClient(this); | 
| 999 StopBlinkingCursor(); | 1006 StopBlinkingCursor(); | 
| 1000 if (render_text->cursor_visible()) { | 1007 cursor_view_.SetVisible(false); | 
| 1001 render_text->set_cursor_visible(false); | |
| 1002 RepaintCursor(); | |
| 1003 } | |
| 1004 | 1008 | 
| 1005 DestroyTouchSelection(); | 1009 DestroyTouchSelection(); | 
| 1006 | 1010 | 
| 1007 if (use_focus_ring_) | 1011 if (use_focus_ring_) | 
| 1008 FocusRing::Uninstall(this); | 1012 FocusRing::Uninstall(this); | 
| 1009 SchedulePaint(); | 1013 SchedulePaint(); | 
| 1010 View::OnBlur(); | 1014 View::OnBlur(); | 
| 1011 } | 1015 } | 
| 1012 | 1016 | 
| 1013 gfx::Point Textfield::GetKeyboardContextMenuLocation() { | 1017 gfx::Point Textfield::GetKeyboardContextMenuLocation() { | 
| 1014 return GetCaretBounds().bottom_right(); | 1018 return GetCaretBounds().bottom_right(); | 
| 1015 } | 1019 } | 
| 1016 | 1020 | 
| 1017 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 1021 void Textfield::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 
| 1018 gfx::RenderText* render_text = GetRenderText(); | 1022 gfx::RenderText* render_text = GetRenderText(); | 
| 1019 render_text->SetColor(GetTextColor()); | 1023 render_text->SetColor(GetTextColor()); | 
| 1020 UpdateBackgroundColor(); | 1024 UpdateBackgroundColor(); | 
| 1021 render_text->set_cursor_color(GetTextColor()); | |
| 1022 render_text->set_selection_color(GetSelectionTextColor()); | 1025 render_text->set_selection_color(GetSelectionTextColor()); | 
| 1023 render_text->set_selection_background_focused_color( | 1026 render_text->set_selection_background_focused_color( | 
| 1024 GetSelectionBackgroundColor()); | 1027 GetSelectionBackgroundColor()); | 
| 1028 cursor_view_.layer()->SetColor(GetTextColor()); | |
| 1025 } | 1029 } | 
| 1026 | 1030 | 
| 1027 //////////////////////////////////////////////////////////////////////////////// | 1031 //////////////////////////////////////////////////////////////////////////////// | 
| 1028 // Textfield, TextfieldModel::Delegate overrides: | 1032 // Textfield, TextfieldModel::Delegate overrides: | 
| 1029 | 1033 | 
| 1030 void Textfield::OnCompositionTextConfirmedOrCleared() { | 1034 void Textfield::OnCompositionTextConfirmedOrCleared() { | 
| 1031 if (!skip_input_method_cancel_composition_) | 1035 if (!skip_input_method_cancel_composition_) | 
| 1032 GetInputMethod()->CancelComposition(this); | 1036 GetInputMethod()->CancelComposition(this); | 
| 1033 } | 1037 } | 
| 1034 | 1038 | 
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1893 View::SetBorder(std::move(border)); | 1897 View::SetBorder(std::move(border)); | 
| 1894 } | 1898 } | 
| 1895 | 1899 | 
| 1896 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { | 1900 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { | 
| 1897 if (text_changed) { | 1901 if (text_changed) { | 
| 1898 if (controller_) | 1902 if (controller_) | 
| 1899 controller_->ContentsChanged(this, text()); | 1903 controller_->ContentsChanged(this, text()); | 
| 1900 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); | 1904 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); | 
| 1901 } | 1905 } | 
| 1902 if (cursor_changed) { | 1906 if (cursor_changed) { | 
| 1903 GetRenderText()->set_cursor_visible(ShouldShowCursor()); | 1907 cursor_view_.SetVisible(ShouldShowCursor()); | 
| 1904 RepaintCursor(); | 1908 UpdateCursorView(); | 
| 1905 if (ShouldBlinkCursor()) | 1909 if (ShouldBlinkCursor()) | 
| 1906 StartBlinkingCursor(); | 1910 StartBlinkingCursor(); | 
| 1907 else | 1911 else | 
| 1908 StopBlinkingCursor(); | 1912 StopBlinkingCursor(); | 
| 1909 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); | 1913 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); | 
| 1910 } | 1914 } | 
| 1911 if (text_changed || cursor_changed) { | 1915 if (text_changed || cursor_changed) { | 
| 1912 OnCaretBoundsChanged(); | 1916 OnCaretBoundsChanged(); | 
| 1913 SchedulePaint(); | 1917 SchedulePaint(); | 
| 1914 } | 1918 } | 
| 1915 } | 1919 } | 
| 1916 | 1920 | 
| 1917 void Textfield::RepaintCursor() { | 1921 void Textfield::UpdateCursorView() { | 
| 1918 gfx::Rect r(GetRenderText()->GetUpdatedCursorBounds()); | 1922 cursor_view_.SetBoundsRect(GetRenderText()->GetUpdatedCursorBounds()); | 
| 1919 r.Inset(-1, -1, -1, -1); | |
| 1920 SchedulePaintInRect(r); | |
| 1921 } | 1923 } | 
| 1922 | 1924 | 
| 1923 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { | 1925 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { | 
| 1924 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); | 1926 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); | 
| 1925 canvas->Save(); | 1927 canvas->Save(); | 
| 1926 | 1928 | 
| 1927 // Draw placeholder text if needed. | 1929 // Draw placeholder text if needed. | 
| 1928 gfx::RenderText* render_text = GetRenderText(); | 1930 gfx::RenderText* render_text = GetRenderText(); | 
| 1929 if (text().empty() && !GetPlaceholderText().empty()) { | 1931 if (text().empty() && !GetPlaceholderText().empty()) { | 
| 1930 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), | 1932 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), | 
| 1931 ui::MaterialDesignController::IsSecondaryUiMaterial() | 1933 ui::MaterialDesignController::IsSecondaryUiMaterial() | 
| 1932 ? SkColorSetA(GetTextColor(), 0x83) | 1934 ? SkColorSetA(GetTextColor(), 0x83) | 
| 1933 : placeholder_text_color_, | 1935 : placeholder_text_color_, | 
| 1934 render_text->display_rect()); | 1936 render_text->display_rect()); | 
| 1935 } | 1937 } | 
| 1936 | 1938 | 
| 1937 render_text->Draw(canvas); | 1939 render_text->Draw(canvas); | 
| 1938 | 1940 | 
| 1939 // Draw the detached drop cursor that marks where the text will be dropped. | 1941 // Draw the detached drop cursor that marks where the text will be dropped. | 
| 1940 if (drop_cursor_visible_) | 1942 if (drop_cursor_visible_) { | 
| 1941 render_text->DrawCursor(canvas, drop_cursor_position_); | 1943 canvas->FillRect(render_text->GetCursorBounds(drop_cursor_position_, true), | 
| 1944 GetTextColor()); | |
| 1945 } | |
| 1942 | 1946 | 
| 1943 canvas->Restore(); | 1947 canvas->Restore(); | 
| 1944 } | 1948 } | 
| 1945 | 1949 | 
| 1946 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { | 1950 void Textfield::MoveCursorTo(const gfx::Point& point, bool select) { | 
| 1947 if (model_->MoveCursorTo(point, select)) | 1951 if (model_->MoveCursorTo(point, select)) | 
| 1948 UpdateAfterChange(false, true); | 1952 UpdateAfterChange(false, true); | 
| 1949 } | 1953 } | 
| 1950 | 1954 | 
| 1951 void Textfield::OnCaretBoundsChanged() { | 1955 void Textfield::OnCaretBoundsChanged() { | 
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2069 Textfield::GetCaretBlinkMs()), | 2073 Textfield::GetCaretBlinkMs()), | 
| 2070 this, &Textfield::OnCursorBlinkTimerFired); | 2074 this, &Textfield::OnCursorBlinkTimerFired); | 
| 2071 } | 2075 } | 
| 2072 | 2076 | 
| 2073 void Textfield::StopBlinkingCursor() { | 2077 void Textfield::StopBlinkingCursor() { | 
| 2074 cursor_blink_timer_.Stop(); | 2078 cursor_blink_timer_.Stop(); | 
| 2075 } | 2079 } | 
| 2076 | 2080 | 
| 2077 void Textfield::OnCursorBlinkTimerFired() { | 2081 void Textfield::OnCursorBlinkTimerFired() { | 
| 2078 DCHECK(ShouldBlinkCursor()); | 2082 DCHECK(ShouldBlinkCursor()); | 
| 2079 gfx::RenderText* render_text = GetRenderText(); | 2083 cursor_view_.SetVisible(!cursor_view_.visible()); | 
| 2080 render_text->set_cursor_visible(!render_text->cursor_visible()); | 2084 UpdateCursorView(); | 
| 2081 RepaintCursor(); | |
| 2082 } | 2085 } | 
| 2083 | 2086 | 
| 2084 } // namespace views | 2087 } // namespace views | 
| OLD | NEW |