Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Unified Diff: ui/views/controls/tree/tree_view.cc

Issue 2050813002: MacViews: support backgrounds for selected rows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: placate msvc Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/controls/tree/tree_view.h ('k') | ui/views/style/platform_style.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/controls/tree/tree_view.cc
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc
index 8a10bbdcef7e4aeee9f8940da22c27a8f3f8726a..10a17b05fb8eb37ab73c3f783b1255b04ee11fb2 100644
--- a/ui/views/controls/tree/tree_view.cc
+++ b/ui/views/controls/tree/tree_view.cc
@@ -25,6 +25,7 @@
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/tree/tree_view_controller.h"
#include "ui/views/resources/grit/views_resources.h"
+#include "ui/views/style/platform_style.h"
using ui::TreeModel;
using ui::TreeModelNode;
@@ -68,6 +69,12 @@ ui::NativeTheme::ColorId text_color_id(bool has_focus, bool is_selected) {
return ui::NativeTheme::kColorId_TreeText;
}
+bool EventIsDoubleTapOrClick(const ui::LocatedEvent& event) {
+ if (event.type() == ui::ET_GESTURE_TAP)
+ return event.AsGestureEvent()->details().tap_count() == 2;
+ return !!(event.flags() & ui::EF_IS_DOUBLE_CLICK);
+}
+
} // namespace
TreeView::TreeView()
@@ -243,7 +250,7 @@ void TreeView::SetSelectedNode(TreeModelNode* model_node) {
}
if (selected_node_)
- ScrollRectToVisible(GetBoundsForNode(selected_node_));
+ ScrollRectToVisible(GetForegroundBoundsForNode(selected_node_));
// Notify controller if the old selection was empty to handle the case of
// remove explicitly resetting selected_node_ before invoking this.
@@ -392,13 +399,7 @@ void TreeView::ShowContextMenu(const gfx::Point& p,
// ContextMenuController) if over a node.
gfx::Point local_point(p);
ConvertPointFromScreen(this, &local_point);
- int row = (local_point.y() - kVerticalInset) / row_height_;
- int depth = 0;
- InternalNode* node = GetNodeByRow(row, &depth);
- if (!node)
- return;
- gfx::Rect bounds(GetBoundsForNodeImpl(node, row, depth));
- if (!bounds.Contains(local_point))
+ if (!GetNodeAtPoint(local_point))
return;
}
View::ShowContextMenu(p, source_type);
@@ -536,7 +537,7 @@ base::string16 TreeView::GetTextForRow(int row) {
gfx::Point TreeView::GetKeyboardContextMenuLocation() {
int y = height() / 2;
if (selected_node_) {
- gfx::Rect node_bounds(GetBoundsForNode(selected_node_));
+ gfx::Rect node_bounds(GetForegroundBoundsForNode(selected_node_));
gfx::Rect vis_bounds(GetVisibleBounds());
if (node_bounds.y() >= vis_bounds.y() &&
node_bounds.y() < vis_bounds.bottom()) {
@@ -643,39 +644,19 @@ bool TreeView::OnClickOrTap(const ui::LocatedEvent& event) {
CommitEdit();
RequestFocus();
- int row = (event.y() - kVerticalInset) / row_height_;
- int depth = 0;
- InternalNode* node = GetNodeByRow(row, &depth);
- if (node) {
- gfx::Rect bounds(GetBoundsForNodeImpl(node, row, depth));
- if (bounds.Contains(event.location())) {
- int relative_x = event.x() - bounds.x();
- if (base::i18n::IsRTL())
- relative_x = bounds.width() - relative_x;
- if (relative_x < kArrowRegionSize &&
- model_->GetChildCount(node->model_node())) {
- if (node->is_expanded())
- Collapse(node->model_node());
- else
- Expand(node->model_node());
- } else if (relative_x > kArrowRegionSize) {
- SetSelectedNode(node->model_node());
- bool should_toggle = false;
- if (event.type() == ui::ET_GESTURE_TAP) {
- const ui::GestureEvent& gesture =
- static_cast<const ui::GestureEvent&>(event);
- should_toggle = gesture.details().tap_count() == 2;
- } else {
- should_toggle = (event.flags() & ui::EF_IS_DOUBLE_CLICK) != 0;
- }
- if (should_toggle) {
- if (node->is_expanded())
- Collapse(node->model_node());
- else
- Expand(node->model_node());
- }
- }
- }
+ InternalNode* node = GetNodeAtPoint(event.location());
+ if (!node)
+ return true;
+
+ bool hits_arrow = IsPointInExpandControl(node, event.location());
+ if (!hits_arrow)
+ SetSelectedNode(node->model_node());
+
+ if (hits_arrow || EventIsDoubleTapOrClick(event)) {
+ if (node->is_expanded())
+ Collapse(node->model_node());
+ else
+ Expand(node->model_node());
}
return true;
}
@@ -728,7 +709,7 @@ void TreeView::LayoutEditor() {
DCHECK(selected_node_);
// Position the editor so that its text aligns with the text we drew.
- gfx::Rect row_bounds = GetBoundsForNode(selected_node_);
+ gfx::Rect row_bounds = GetForegroundBoundsForNode(selected_node_);
row_bounds.set_x(
GetMirroredXWithWidthInView(row_bounds.x(), row_bounds.width()));
row_bounds.set_x(row_bounds.x() + text_offset_);
@@ -745,7 +726,7 @@ void TreeView::LayoutEditor() {
void TreeView::SchedulePaintForNode(InternalNode* node) {
if (!node)
return; // Explicitly allow NULL to be passed in.
- SchedulePaintInRect(GetBoundsForNode(node));
+ SchedulePaintInRect(GetBackgroundBoundsForNode(node));
}
void TreeView::PaintRows(gfx::Canvas* canvas,
@@ -771,7 +752,15 @@ void TreeView::PaintRow(gfx::Canvas* canvas,
InternalNode* node,
int row,
int depth) {
- gfx::Rect bounds(GetBoundsForNodeImpl(node, row, depth));
+ gfx::Rect bounds(GetForegroundBoundsForNodeImpl(node, row, depth));
+ const SkColor selected_row_bg_color = GetNativeTheme()->GetSystemColor(
+ text_background_color_id(HasFocus() || editing_));
+
+ // Paint the row background.
+ if (PlatformStyle::kTreeViewSelectionPaintsEntireRow &&
+ selected_node_ == node) {
+ canvas->FillRect(GetBackgroundBoundsForNode(node), selected_row_bg_color);
+ }
if (model_->GetChildCount(node->model_node()))
PaintExpandControl(canvas, bounds, node->is_expanded());
@@ -795,29 +784,34 @@ void TreeView::PaintRow(gfx::Canvas* canvas,
icon, icon_x,
bounds.y() + (bounds.height() - icon.height()) / 2);
- if (!editing_ || node != selected_node_) {
- gfx::Rect text_bounds(bounds.x() + text_offset_, bounds.y(),
- bounds.width() - text_offset_, bounds.height());
- if (base::i18n::IsRTL())
- text_bounds.set_x(bounds.x());
- if (node == selected_node_) {
- const SkColor bg_color = GetNativeTheme()->GetSystemColor(
- text_background_color_id(HasFocus()));
- canvas->FillRect(text_bounds, bg_color);
- if (HasFocus())
- canvas->DrawFocusRect(text_bounds);
- }
- const ui::NativeTheme::ColorId color_id =
- text_color_id(HasFocus(), node == selected_node_);
- const gfx::Rect internal_bounds(
- text_bounds.x() + kTextHorizontalPadding,
- text_bounds.y() + kTextVerticalPadding,
- text_bounds.width() - kTextHorizontalPadding * 2,
- text_bounds.height() - kTextVerticalPadding * 2);
- canvas->DrawStringRect(node->model_node()->GetTitle(), font_list_,
- GetNativeTheme()->GetSystemColor(color_id),
- internal_bounds);
+ // Paint the text background and text. In edit mode, the selected node is a
+ // separate editing control, so it does not need to be painted here.
+ if (editing_ && selected_node_ == node)
+ return;
+
+ gfx::Rect text_bounds(GetTextBoundsForNode(node));
+ if (base::i18n::IsRTL())
+ text_bounds.set_x(bounds.x());
+
+ // Paint the background on the selected row.
+ if (!PlatformStyle::kTreeViewSelectionPaintsEntireRow &&
+ node == selected_node_) {
+ canvas->FillRect(text_bounds, selected_row_bg_color);
+ if (HasFocus())
+ canvas->DrawFocusRect(text_bounds);
}
+
+ // Paint the text.
+ const ui::NativeTheme::ColorId color_id =
+ text_color_id(HasFocus(), node == selected_node_);
+ const gfx::Rect internal_bounds(
+ text_bounds.x() + kTextHorizontalPadding,
+ text_bounds.y() + kTextVerticalPadding,
+ text_bounds.width() - kTextHorizontalPadding * 2,
+ text_bounds.height() - kTextVerticalPadding * 2);
+ canvas->DrawStringRect(node->model_node()->GetTitle(), font_list_,
+ GetNativeTheme()->GetSystemColor(color_id),
+ internal_bounds);
}
void TreeView::PaintExpandControl(gfx::Canvas* canvas,
@@ -868,15 +862,31 @@ TreeView::InternalNode* TreeView::GetInternalNodeForModelNode(
model_->GetIndexOf(parent_internal_node->model_node(), model_node));
}
-gfx::Rect TreeView::GetBoundsForNode(InternalNode* node) {
+gfx::Rect TreeView::GetBackgroundBoundsForNode(InternalNode* node) {
+ if (!PlatformStyle::kTreeViewSelectionPaintsEntireRow)
+ return GetForegroundBoundsForNode(node);
+
+ int row, ignored_depth;
+ row = GetRowForInternalNode(node, &ignored_depth);
+ return gfx::Rect(bounds().x(), row * row_height_ + kVerticalInset,
+ bounds().width(), row_height_);
+}
+
+gfx::Rect TreeView::GetForegroundBoundsForNode(InternalNode* node) {
int row, depth;
row = GetRowForInternalNode(node, &depth);
- return GetBoundsForNodeImpl(node, row, depth);
+ return GetForegroundBoundsForNodeImpl(node, row, depth);
}
-gfx::Rect TreeView::GetBoundsForNodeImpl(InternalNode* node,
- int row,
- int depth) {
+gfx::Rect TreeView::GetTextBoundsForNode(InternalNode* node) {
+ gfx::Rect bounds(GetForegroundBoundsForNode(node));
+ bounds.Inset(text_offset_, 0, 0, 0);
+ return bounds;
+}
+
+gfx::Rect TreeView::GetForegroundBoundsForNodeImpl(InternalNode* node,
+ int row,
+ int depth) {
gfx::Rect rect(depth * kIndent + kHorizontalInset,
row * row_height_ + kVerticalInset,
text_offset_ + node->text_width() +
@@ -906,6 +916,21 @@ int TreeView::GetRowForInternalNode(InternalNode* node, int* depth) {
return row;
}
+TreeView::InternalNode* TreeView::GetNodeAtPoint(const gfx::Point& point) {
+ int row = (point.y() - kVerticalInset) / row_height_;
+ int depth = -1;
+ InternalNode* node = GetNodeByRow(row, &depth);
+ if (!node)
+ return nullptr;
+
+ // If the entire row gets a selected background, clicking anywhere in the row
+ // serves to hit this node.
+ if (PlatformStyle::kTreeViewSelectionPaintsEntireRow)
+ return node;
+ gfx::Rect bounds(GetForegroundBoundsForNodeImpl(node, row, depth));
+ return bounds.Contains(point) ? node : nullptr;
+}
+
TreeView::InternalNode* TreeView::GetNodeByRow(int row, int* depth) {
int current_row = root_row();
*depth = 0;
@@ -1014,6 +1039,23 @@ PrefixSelector* TreeView::GetPrefixSelector() {
return selector_.get();
}
+bool TreeView::IsPointInExpandControl(InternalNode* node,
+ const gfx::Point& point) {
+ if (!model_->GetChildCount(node->model_node()))
+ return false;
+
+ int depth = -1;
+ int row = GetRowForInternalNode(node, &depth);
+
+ int arrow_dx = depth * kIndent + kHorizontalInset;
+ gfx::Rect arrow_bounds(bounds().x() + arrow_dx,
+ row * row_height_ + kVerticalInset, kArrowRegionSize,
+ row_height_);
+ if (base::i18n::IsRTL())
+ arrow_bounds.set_x(bounds().width() - arrow_dx - kArrowRegionSize);
+ return arrow_bounds.Contains(point);
+}
+
// InternalNode ----------------------------------------------------------------
TreeView::InternalNode::InternalNode()
« no previous file with comments | « ui/views/controls/tree/tree_view.h ('k') | ui/views/style/platform_style.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698