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/tree/tree_view.h" | 5 #include "ui/views/controls/tree/tree_view.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "ui/accessibility/ax_view_state.h" | 12 #include "ui/accessibility/ax_view_state.h" |
| 13 #include "ui/base/ime/input_method.h" | 13 #include "ui/base/ime/input_method.h" |
| 14 #include "ui/base/material_design/material_design_controller.h" | |
| 14 #include "ui/base/resource/resource_bundle.h" | 15 #include "ui/base/resource/resource_bundle.h" |
| 15 #include "ui/events/event.h" | 16 #include "ui/events/event.h" |
| 16 #include "ui/events/keycodes/keyboard_codes.h" | 17 #include "ui/events/keycodes/keyboard_codes.h" |
| 17 #include "ui/gfx/canvas.h" | 18 #include "ui/gfx/canvas.h" |
| 18 #include "ui/gfx/geometry/rect.h" | 19 #include "ui/gfx/geometry/rect.h" |
| 19 #include "ui/gfx/geometry/rect_conversions.h" | 20 #include "ui/gfx/geometry/rect_conversions.h" |
| 20 #include "ui/gfx/image/image.h" | 21 #include "ui/gfx/image/image.h" |
| 21 #include "ui/gfx/skia_util.h" | 22 #include "ui/gfx/skia_util.h" |
| 22 #include "ui/native_theme/native_theme.h" | 23 #include "ui/native_theme/native_theme.h" |
| 23 #include "ui/resources/grit/ui_resources.h" | 24 #include "ui/resources/grit/ui_resources.h" |
| 25 #include "ui/views/controls/focus_ring.h" | |
| 24 #include "ui/views/controls/prefix_selector.h" | 26 #include "ui/views/controls/prefix_selector.h" |
| 25 #include "ui/views/controls/scroll_view.h" | 27 #include "ui/views/controls/scroll_view.h" |
| 26 #include "ui/views/controls/textfield/textfield.h" | 28 #include "ui/views/controls/textfield/textfield.h" |
| 27 #include "ui/views/controls/tree/tree_view_controller.h" | 29 #include "ui/views/controls/tree/tree_view_controller.h" |
| 28 #include "ui/views/resources/grit/views_resources.h" | 30 #include "ui/views/resources/grit/views_resources.h" |
| 29 #include "ui/views/style/platform_style.h" | 31 #include "ui/views/style/platform_style.h" |
| 30 | 32 |
| 31 using ui::TreeModel; | 33 using ui::TreeModel; |
| 32 using ui::TreeModelNode; | 34 using ui::TreeModelNode; |
| 33 | 35 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 int TreeView::GetRowForNode(ui::TreeModelNode* node) { | 350 int TreeView::GetRowForNode(ui::TreeModelNode* node) { |
| 349 InternalNode* internal_node = | 351 InternalNode* internal_node = |
| 350 GetInternalNodeForModelNode(node, DONT_CREATE_IF_NOT_LOADED); | 352 GetInternalNodeForModelNode(node, DONT_CREATE_IF_NOT_LOADED); |
| 351 if (!internal_node) | 353 if (!internal_node) |
| 352 return -1; | 354 return -1; |
| 353 int depth = 0; | 355 int depth = 0; |
| 354 return GetRowForInternalNode(internal_node, &depth); | 356 return GetRowForInternalNode(internal_node, &depth); |
| 355 } | 357 } |
| 356 | 358 |
| 357 void TreeView::Layout() { | 359 void TreeView::Layout() { |
| 358 int width = preferred_size_.width(); | 360 int width = preferred_size_.width(); |
|
sky
2016/10/12 16:13:47
I believe you'll need to force a layout on the foc
Elly Fong-Jones
2016/10/12 19:36:06
Done.
| |
| 359 int height = preferred_size_.height(); | 361 int height = preferred_size_.height(); |
| 360 if (parent()) { | 362 if (parent()) { |
| 361 width = std::max(parent()->width(), width); | 363 width = std::max(parent()->width(), width); |
| 362 height = std::max(parent()->height(), height); | 364 height = std::max(parent()->height(), height); |
| 363 } | 365 } |
| 364 SetBounds(x(), y(), width, height); | 366 SetBounds(x(), y(), width, height); |
| 365 LayoutEditor(); | 367 LayoutEditor(); |
| 366 } | 368 } |
| 367 | 369 |
| 368 gfx::Size TreeView::GetPreferredSize() const { | 370 gfx::Size TreeView::GetPreferredSize() const { |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 | 626 |
| 625 void TreeView::OnFocus() { | 627 void TreeView::OnFocus() { |
| 626 if (GetInputMethod()) | 628 if (GetInputMethod()) |
| 627 GetInputMethod()->SetFocusedTextInputClient(GetPrefixSelector()); | 629 GetInputMethod()->SetFocusedTextInputClient(GetPrefixSelector()); |
| 628 View::OnFocus(); | 630 View::OnFocus(); |
| 629 SchedulePaintForNode(selected_node_); | 631 SchedulePaintForNode(selected_node_); |
| 630 | 632 |
| 631 // Notify the InputMethod so that it knows to query the TextInputClient. | 633 // Notify the InputMethod so that it knows to query the TextInputClient. |
| 632 if (GetInputMethod()) | 634 if (GetInputMethod()) |
| 633 GetInputMethod()->OnCaretBoundsChanged(GetPrefixSelector()); | 635 GetInputMethod()->OnCaretBoundsChanged(GetPrefixSelector()); |
| 636 | |
| 637 if (ui::MaterialDesignController::IsSecondaryUiMaterial() && | |
| 638 PlatformStyle::kTreeViewHasFocusRing) { | |
| 639 View* focus_ring_view = FindFocusRingView(); | |
| 640 FocusRing::Install(focus_ring_view); | |
| 641 focus_ring_view->SchedulePaint(); | |
| 642 } | |
| 634 } | 643 } |
| 635 | 644 |
| 636 void TreeView::OnBlur() { | 645 void TreeView::OnBlur() { |
| 637 if (GetInputMethod()) | 646 if (GetInputMethod()) |
| 638 GetInputMethod()->DetachTextInputClient(GetPrefixSelector()); | 647 GetInputMethod()->DetachTextInputClient(GetPrefixSelector()); |
| 639 SchedulePaintForNode(selected_node_); | 648 SchedulePaintForNode(selected_node_); |
| 640 if (selector_) | 649 if (selector_) |
| 641 selector_->OnViewBlur(); | 650 selector_->OnViewBlur(); |
| 651 if (ui::MaterialDesignController::IsSecondaryUiMaterial() && | |
| 652 PlatformStyle::kTreeViewHasFocusRing) { | |
| 653 View* focus_ring_view = FindFocusRingView(); | |
| 654 FocusRing::Uninstall(focus_ring_view); | |
| 655 focus_ring_view->SchedulePaint(); | |
| 656 } | |
| 642 } | 657 } |
| 643 | 658 |
| 644 bool TreeView::OnClickOrTap(const ui::LocatedEvent& event) { | 659 bool TreeView::OnClickOrTap(const ui::LocatedEvent& event) { |
| 645 CommitEdit(); | 660 CommitEdit(); |
| 646 RequestFocus(); | 661 RequestFocus(); |
| 647 | 662 |
| 648 InternalNode* node = GetNodeAtPoint(event.location()); | 663 InternalNode* node = GetNodeAtPoint(event.location()); |
| 649 if (!node) | 664 if (!node) |
| 650 return true; | 665 return true; |
| 651 | 666 |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1050 | 1065 |
| 1051 int arrow_dx = depth * kIndent + kHorizontalInset; | 1066 int arrow_dx = depth * kIndent + kHorizontalInset; |
| 1052 gfx::Rect arrow_bounds(bounds().x() + arrow_dx, | 1067 gfx::Rect arrow_bounds(bounds().x() + arrow_dx, |
| 1053 row * row_height_ + kVerticalInset, kArrowRegionSize, | 1068 row * row_height_ + kVerticalInset, kArrowRegionSize, |
| 1054 row_height_); | 1069 row_height_); |
| 1055 if (base::i18n::IsRTL()) | 1070 if (base::i18n::IsRTL()) |
| 1056 arrow_bounds.set_x(bounds().width() - arrow_dx - kArrowRegionSize); | 1071 arrow_bounds.set_x(bounds().width() - arrow_dx - kArrowRegionSize); |
| 1057 return arrow_bounds.Contains(point); | 1072 return arrow_bounds.Contains(point); |
| 1058 } | 1073 } |
| 1059 | 1074 |
| 1075 View* TreeView::FindFocusRingView() { | |
| 1076 // If this View is the grandchild of a ScrollView, use the grandparent | |
| 1077 // ScrollView for the focus ring instead of this View so that the focus ring | |
| 1078 // won't be scrolled. Otherwise, fall back to using this View. Since | |
| 1079 // ScrollViews have a single content view, which they wrap in a | |
| 1080 // ScrollView::Viewport, being the grandchild of a ScrollView implies being | |
| 1081 // the sole grandchild, which means it's fine to wrap the focus ring around | |
| 1082 // the grandparent here. | |
| 1083 View* grandparent = parent() ? parent()->parent() : nullptr; | |
| 1084 if (grandparent && grandparent->GetClassName() == ScrollView::kViewClassName) | |
| 1085 return grandparent; | |
| 1086 return this; | |
| 1087 } | |
| 1088 | |
| 1060 // InternalNode ---------------------------------------------------------------- | 1089 // InternalNode ---------------------------------------------------------------- |
| 1061 | 1090 |
| 1062 TreeView::InternalNode::InternalNode() | 1091 TreeView::InternalNode::InternalNode() |
| 1063 : model_node_(NULL), | 1092 : model_node_(NULL), |
| 1064 loaded_children_(false), | 1093 loaded_children_(false), |
| 1065 is_expanded_(false), | 1094 is_expanded_(false), |
| 1066 text_width_(0) { | 1095 text_width_(0) { |
| 1067 } | 1096 } |
| 1068 | 1097 |
| 1069 TreeView::InternalNode::~InternalNode() { | 1098 TreeView::InternalNode::~InternalNode() { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1090 if (!is_expanded_) | 1119 if (!is_expanded_) |
| 1091 return max_width; | 1120 return max_width; |
| 1092 for (int i = 0; i < child_count(); ++i) { | 1121 for (int i = 0; i < child_count(); ++i) { |
| 1093 max_width = std::max(max_width, | 1122 max_width = std::max(max_width, |
| 1094 GetChild(i)->GetMaxWidth(indent, depth + 1)); | 1123 GetChild(i)->GetMaxWidth(indent, depth + 1)); |
| 1095 } | 1124 } |
| 1096 return max_width; | 1125 return max_width; |
| 1097 } | 1126 } |
| 1098 | 1127 |
| 1099 } // namespace views | 1128 } // namespace views |
| OLD | NEW |