| 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/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 // Padding before/after the image. | 37 // Padding before/after the image. |
| 38 static const int kImagePadding = 4; | 38 static const int kImagePadding = 4; |
| 39 // Size of the arrow region. | 39 // Size of the arrow region. |
| 40 static const int kArrowRegionSize = 12; | 40 static const int kArrowRegionSize = 12; |
| 41 // Padding around the text (on each side). | 41 // Padding around the text (on each side). |
| 42 static const int kTextVerticalPadding = 3; | 42 static const int kTextVerticalPadding = 3; |
| 43 static const int kTextHorizontalPadding = 2; | 43 static const int kTextHorizontalPadding = 2; |
| 44 // How much children are indented from their parent. | 44 // How much children are indented from their parent. |
| 45 static const int kIndent = 20; | 45 static const int kIndent = 20; |
| 46 | 46 |
| 47 #if defined(OS_MACOSX) |
| 48 static const bool kSelectionFillsRow = true; |
| 49 #else |
| 50 static const bool kSelectionFillsRow = false; |
| 51 #endif |
| 52 |
| 47 // static | 53 // static |
| 48 const char TreeView::kViewClassName[] = "TreeView"; | 54 const char TreeView::kViewClassName[] = "TreeView"; |
| 49 | 55 |
| 50 namespace { | 56 namespace { |
| 51 | 57 |
| 52 // Returns the color id for the background of selected text. |has_focus| | 58 // Returns the color id for a row. |has_focus| indicates if the tree has focus. |
| 53 // indicates if the tree has focus. | 59 ui::NativeTheme::ColorId text_background_color_id(bool is_selected_row, |
| 54 ui::NativeTheme::ColorId text_background_color_id(bool has_focus) { | 60 bool has_focus) { |
| 61 if (!is_selected_row) |
| 62 return ui::NativeTheme::kColorId_TreeBackground; |
| 55 return has_focus ? | 63 return has_focus ? |
| 56 ui::NativeTheme::kColorId_TreeSelectionBackgroundFocused : | 64 ui::NativeTheme::kColorId_TreeSelectionBackgroundFocused : |
| 57 ui::NativeTheme::kColorId_TreeSelectionBackgroundUnfocused; | 65 ui::NativeTheme::kColorId_TreeSelectionBackgroundUnfocused; |
| 58 } | 66 } |
| 59 | 67 |
| 60 // Returns the color id for text. |has_focus| indicates if the tree has focus | 68 // Returns the color id for text. |has_focus| indicates if the tree has focus |
| 61 // and |is_selected| is true if the item is selected. | 69 // and |is_selected| is true if the item is selected. |
| 62 ui::NativeTheme::ColorId text_color_id(bool has_focus, bool is_selected) { | 70 ui::NativeTheme::ColorId text_color_id(bool has_focus, bool is_selected) { |
| 63 if (is_selected) { | 71 if (is_selected) { |
| 64 if (has_focus) | 72 if (has_focus) |
| (...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 for (int i = 0; i < node->child_count() && *row < max_row; ++i) | 771 for (int i = 0; i < node->child_count() && *row < max_row; ++i) |
| 764 PaintRows(canvas, min_row, max_row, node->GetChild(i), depth, row); | 772 PaintRows(canvas, min_row, max_row, node->GetChild(i), depth, row); |
| 765 } | 773 } |
| 766 | 774 |
| 767 void TreeView::PaintRow(gfx::Canvas* canvas, | 775 void TreeView::PaintRow(gfx::Canvas* canvas, |
| 768 InternalNode* node, | 776 InternalNode* node, |
| 769 int row, | 777 int row, |
| 770 int depth) { | 778 int depth) { |
| 771 gfx::Rect bounds(GetBoundsForNodeImpl(node, row, depth)); | 779 gfx::Rect bounds(GetBoundsForNodeImpl(node, row, depth)); |
| 772 | 780 |
| 781 const SkColor bg_color = GetNativeTheme()->GetSystemColor( |
| 782 text_background_color_id(node == selected_node_, HasFocus())); |
| 783 if (kSelectionFillsRow) { |
| 784 canvas->FillRect(bounds, bg_color); |
| 785 bounds.set_x(depth * kIndent + kHorizontalInset); |
| 786 } |
| 787 |
| 773 if (model_->GetChildCount(node->model_node())) | 788 if (model_->GetChildCount(node->model_node())) |
| 774 PaintExpandControl(canvas, bounds, node->is_expanded()); | 789 PaintExpandControl(canvas, bounds, node->is_expanded()); |
| 775 | 790 |
| 776 // Paint the icon. | 791 // Paint the icon. |
| 777 gfx::ImageSkia icon; | 792 gfx::ImageSkia icon; |
| 778 int icon_index = model_->GetIconIndex(node->model_node()); | 793 int icon_index = model_->GetIconIndex(node->model_node()); |
| 779 if (icon_index != -1) | 794 if (icon_index != -1) |
| 780 icon = icons_[icon_index]; | 795 icon = icons_[icon_index]; |
| 781 else if (node == selected_node_) | 796 else if (node == selected_node_) |
| 782 icon = open_icon_; | 797 icon = open_icon_; |
| 783 else | 798 else |
| 784 icon = closed_icon_; | 799 icon = closed_icon_; |
| 785 int icon_x = kArrowRegionSize + kImagePadding + | 800 int icon_x = kArrowRegionSize + kImagePadding + |
| 786 (open_icon_.width() - icon.width()) / 2; | 801 (open_icon_.width() - icon.width()) / 2; |
| 787 if (base::i18n::IsRTL()) | 802 if (base::i18n::IsRTL()) |
| 788 icon_x = bounds.right() - icon_x - open_icon_.width(); | 803 icon_x = bounds.right() - icon_x - open_icon_.width(); |
| 789 else | 804 else |
| 790 icon_x += bounds.x(); | 805 icon_x += bounds.x(); |
| 791 canvas->DrawImageInt( | 806 canvas->DrawImageInt( |
| 792 icon, icon_x, | 807 icon, icon_x, |
| 793 bounds.y() + (bounds.height() - icon.height()) / 2); | 808 bounds.y() + (bounds.height() - icon.height()) / 2); |
| 794 | 809 |
| 795 if (!editing_ || node != selected_node_) { | 810 if (!editing_ || node != selected_node_) { |
| 796 gfx::Rect text_bounds(bounds.x() + text_offset_, bounds.y(), | 811 gfx::Rect text_bounds(bounds.x() + text_offset_, bounds.y(), |
| 797 bounds.width() - text_offset_, bounds.height()); | 812 bounds.width() - text_offset_, bounds.height()); |
| 798 if (base::i18n::IsRTL()) | 813 if (base::i18n::IsRTL()) |
| 799 text_bounds.set_x(bounds.x()); | 814 text_bounds.set_x(bounds.x()); |
| 800 if (node == selected_node_) { | 815 if (!kSelectionFillsRow && node == selected_node_) { |
| 801 const SkColor bg_color = GetNativeTheme()->GetSystemColor( | |
| 802 text_background_color_id(HasFocus())); | |
| 803 canvas->FillRect(text_bounds, bg_color); | 816 canvas->FillRect(text_bounds, bg_color); |
| 804 if (HasFocus()) | 817 if (HasFocus()) |
| 805 canvas->DrawFocusRect(text_bounds); | 818 canvas->DrawFocusRect(text_bounds); |
| 806 } | 819 } |
| 807 const ui::NativeTheme::ColorId color_id = | 820 const ui::NativeTheme::ColorId color_id = |
| 808 text_color_id(HasFocus(), node == selected_node_); | 821 text_color_id(HasFocus(), node == selected_node_); |
| 809 const gfx::Rect internal_bounds( | 822 const gfx::Rect internal_bounds( |
| 810 text_bounds.x() + kTextHorizontalPadding, | 823 text_bounds.x() + kTextHorizontalPadding, |
| 811 text_bounds.y() + kTextVerticalPadding, | 824 text_bounds.y() + kTextVerticalPadding, |
| 812 text_bounds.width() - kTextHorizontalPadding * 2, | 825 text_bounds.width() - kTextHorizontalPadding * 2, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 | 880 |
| 868 gfx::Rect TreeView::GetBoundsForNode(InternalNode* node) { | 881 gfx::Rect TreeView::GetBoundsForNode(InternalNode* node) { |
| 869 int row, depth; | 882 int row, depth; |
| 870 row = GetRowForInternalNode(node, &depth); | 883 row = GetRowForInternalNode(node, &depth); |
| 871 return GetBoundsForNodeImpl(node, row, depth); | 884 return GetBoundsForNodeImpl(node, row, depth); |
| 872 } | 885 } |
| 873 | 886 |
| 874 gfx::Rect TreeView::GetBoundsForNodeImpl(InternalNode* node, | 887 gfx::Rect TreeView::GetBoundsForNodeImpl(InternalNode* node, |
| 875 int row, | 888 int row, |
| 876 int depth) { | 889 int depth) { |
| 877 gfx::Rect rect(depth * kIndent + kHorizontalInset, | 890 int row_x = kSelectionFillsRow ? 0 : depth * kIndent + kHorizontalInset; |
| 878 row * row_height_ + kVerticalInset, | 891 int row_width = kSelectionFillsRow ? width() : text_offset_ + |
| 879 text_offset_ + node->text_width() + | 892 node->text_width() + |
| 880 kTextHorizontalPadding * 2, | 893 kTextHorizontalPadding * 2; |
| 894 gfx::Rect rect(row_x, row * row_height_ + kVerticalInset, row_width, |
| 881 row_height_); | 895 row_height_); |
| 882 rect.set_x(GetMirroredXWithWidthInView(rect.x(), rect.width())); | 896 rect.set_x(GetMirroredXWithWidthInView(rect.x(), rect.width())); |
| 883 return rect; | 897 return rect; |
| 884 } | 898 } |
| 885 | 899 |
| 886 int TreeView::GetRowForInternalNode(InternalNode* node, int* depth) { | 900 int TreeView::GetRowForInternalNode(InternalNode* node, int* depth) { |
| 887 DCHECK(!node->parent() || IsExpanded(node->parent()->model_node())); | 901 DCHECK(!node->parent() || IsExpanded(node->parent()->model_node())); |
| 888 *depth = -1; | 902 *depth = -1; |
| 889 int row = -1; | 903 int row = -1; |
| 890 InternalNode* tmp_node = node; | 904 InternalNode* tmp_node = node; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 if (!is_expanded_) | 1058 if (!is_expanded_) |
| 1045 return max_width; | 1059 return max_width; |
| 1046 for (int i = 0; i < child_count(); ++i) { | 1060 for (int i = 0; i < child_count(); ++i) { |
| 1047 max_width = std::max(max_width, | 1061 max_width = std::max(max_width, |
| 1048 GetChild(i)->GetMaxWidth(indent, depth + 1)); | 1062 GetChild(i)->GetMaxWidth(indent, depth + 1)); |
| 1049 } | 1063 } |
| 1050 return max_width; | 1064 return max_width; |
| 1051 } | 1065 } |
| 1052 | 1066 |
| 1053 } // namespace views | 1067 } // namespace views |
| OLD | NEW |