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

Side by Side Diff: ui/views/controls/table/table_header.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 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 unified diff | Download patch
« no previous file with comments | « ui/views/controls/table/table_header.h ('k') | ui/views/controls/table/table_utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/views/controls/table/table_header.h"
6
7 #include "third_party/skia/include/core/SkColor.h"
8 #include "ui/base/cursor/cursor.h"
9 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/text_utils.h"
11 #include "ui/native_theme/native_theme.h"
12 #include "ui/views/background.h"
13 #include "ui/views/controls/table/table_utils.h"
14 #include "ui/views/controls/table/table_view.h"
15 #include "ui/views/native_cursor.h"
16
17 namespace views {
18
19 namespace {
20
21 const int kVerticalPadding = 4;
22
23 // The minimum width we allow a column to go down to.
24 const int kMinColumnWidth = 10;
25
26 // Distace from edge columns can be resized by.
27 const int kResizePadding = 5;
28
29 // Amount of space above/below the separator.
30 const int kSeparatorPadding = 4;
31
32 const SkColor kTextColor = SK_ColorBLACK;
33 const SkColor kBackgroundColor1 = SkColorSetRGB(0xF9, 0xF9, 0xF9);
34 const SkColor kBackgroundColor2 = SkColorSetRGB(0xE8, 0xE8, 0xE8);
35 const SkColor kSeparatorColor = SkColorSetRGB(0xAA, 0xAA, 0xAA);
36
37 // Size of the sort indicator (doesn't include padding).
38 const int kSortIndicatorSize = 8;
39
40 } // namespace
41
42 // static
43 const int TableHeader::kHorizontalPadding = 7;
44 // static
45 const int TableHeader::kSortIndicatorWidth = kSortIndicatorSize +
46 TableHeader::kHorizontalPadding * 2;
47
48 typedef std::vector<TableView::VisibleColumn> Columns;
49
50 TableHeader::TableHeader(TableView* table) : table_(table) {
51 set_background(Background::CreateVerticalGradientBackground(
52 kBackgroundColor1, kBackgroundColor2));
53 }
54
55 TableHeader::~TableHeader() {
56 }
57
58 void TableHeader::Layout() {
59 SetBounds(x(), y(), table_->width(), GetPreferredSize().height());
60 }
61
62 void TableHeader::OnPaint(gfx::Canvas* canvas) {
63 // Paint the background and a separator at the bottom. The separator color
64 // matches that of the border around the scrollview.
65 OnPaintBackground(canvas);
66 SkColor border_color = GetNativeTheme()->GetSystemColor(
67 ui::NativeTheme::kColorId_UnfocusedBorderColor);
68 canvas->DrawLine(gfx::Point(0, height() - 1),
69 gfx::Point(width(), height() - 1), border_color);
70
71 const Columns& columns = table_->visible_columns();
72 const int sorted_column_id = table_->sort_descriptors().empty() ? -1 :
73 table_->sort_descriptors()[0].column_id;
74 for (size_t i = 0; i < columns.size(); ++i) {
75 if (columns[i].width >= 2) {
76 const int separator_x = GetMirroredXInView(
77 columns[i].x + columns[i].width - 1);
78 canvas->DrawLine(gfx::Point(separator_x, kSeparatorPadding),
79 gfx::Point(separator_x, height() - kSeparatorPadding),
80 kSeparatorColor);
81 }
82
83 const int x = columns[i].x + kHorizontalPadding;
84 int width = columns[i].width - kHorizontalPadding - kHorizontalPadding;
85 if (width <= 0)
86 continue;
87
88 const int title_width =
89 gfx::GetStringWidth(columns[i].column.title, font_list_);
90 const bool paint_sort_indicator =
91 (columns[i].column.id == sorted_column_id &&
92 title_width + kSortIndicatorWidth <= width);
93
94 if (paint_sort_indicator &&
95 columns[i].column.alignment == ui::TableColumn::RIGHT) {
96 width -= kSortIndicatorWidth;
97 }
98
99 canvas->DrawStringRectWithFlags(
100 columns[i].column.title, font_list_, kTextColor,
101 gfx::Rect(GetMirroredXWithWidthInView(x, width), kVerticalPadding,
102 width, height() - kVerticalPadding * 2),
103 TableColumnAlignmentToCanvasAlignment(columns[i].column.alignment));
104
105 if (paint_sort_indicator) {
106 SkPaint paint;
107 paint.setColor(kTextColor);
108 paint.setStyle(SkPaint::kFill_Style);
109 paint.setAntiAlias(true);
110
111 int indicator_x = 0;
112 ui::TableColumn::Alignment alignment = columns[i].column.alignment;
113 if (base::i18n::IsRTL()) {
114 if (alignment == ui::TableColumn::LEFT)
115 alignment = ui::TableColumn::RIGHT;
116 else if (alignment == ui::TableColumn::RIGHT)
117 alignment = ui::TableColumn::LEFT;
118 }
119 switch (alignment) {
120 case ui::TableColumn::LEFT:
121 indicator_x = x + title_width;
122 break;
123 case ui::TableColumn::CENTER:
124 indicator_x = x + width / 2;
125 break;
126 case ui::TableColumn::RIGHT:
127 indicator_x = x + width;
128 break;
129 }
130
131 const int scale = base::i18n::IsRTL() ? -1 : 1;
132 indicator_x += (kSortIndicatorWidth - kSortIndicatorSize) / 2;
133 indicator_x = GetMirroredXInView(indicator_x);
134 int indicator_y = height() / 2 - kSortIndicatorSize / 2;
135 SkPath indicator_path;
136 if (table_->sort_descriptors()[0].ascending) {
137 indicator_path.moveTo(
138 SkIntToScalar(indicator_x),
139 SkIntToScalar(indicator_y + kSortIndicatorSize));
140 indicator_path.lineTo(
141 SkIntToScalar(indicator_x + kSortIndicatorSize * scale),
142 SkIntToScalar(indicator_y + kSortIndicatorSize));
143 indicator_path.lineTo(
144 SkIntToScalar(indicator_x + kSortIndicatorSize / 2 * scale),
145 SkIntToScalar(indicator_y));
146 } else {
147 indicator_path.moveTo(SkIntToScalar(indicator_x),
148 SkIntToScalar(indicator_y));
149 indicator_path.lineTo(
150 SkIntToScalar(indicator_x + kSortIndicatorSize * scale),
151 SkIntToScalar(indicator_y));
152 indicator_path.lineTo(
153 SkIntToScalar(indicator_x + kSortIndicatorSize / 2 * scale),
154 SkIntToScalar(indicator_y + kSortIndicatorSize));
155 }
156 indicator_path.close();
157 canvas->DrawPath(indicator_path, paint);
158 }
159 }
160 }
161
162 gfx::Size TableHeader::GetPreferredSize() const {
163 return gfx::Size(1, kVerticalPadding * 2 + font_list_.GetHeight());
164 }
165
166 gfx::NativeCursor TableHeader::GetCursor(const ui::MouseEvent& event) {
167 return GetResizeColumn(GetMirroredXInView(event.x())) != -1 ?
168 GetNativeColumnResizeCursor() : View::GetCursor(event);
169 }
170
171 bool TableHeader::OnMousePressed(const ui::MouseEvent& event) {
172 if (event.IsOnlyLeftMouseButton()) {
173 StartResize(event);
174 return true;
175 }
176
177 // Return false so that context menus on ancestors work.
178 return false;
179 }
180
181 bool TableHeader::OnMouseDragged(const ui::MouseEvent& event) {
182 ContinueResize(event);
183 return true;
184 }
185
186 void TableHeader::OnMouseReleased(const ui::MouseEvent& event) {
187 const bool was_resizing = resize_details_ != NULL;
188 resize_details_.reset();
189 if (!was_resizing && event.IsOnlyLeftMouseButton())
190 ToggleSortOrder(event);
191 }
192
193 void TableHeader::OnMouseCaptureLost() {
194 if (is_resizing()) {
195 table_->SetVisibleColumnWidth(resize_details_->column_index,
196 resize_details_->initial_width);
197 }
198 resize_details_.reset();
199 }
200
201 void TableHeader::OnGestureEvent(ui::GestureEvent* event) {
202 switch (event->type()) {
203 case ui::ET_GESTURE_TAP:
204 if (!resize_details_.get())
205 ToggleSortOrder(*event);
206 break;
207 case ui::ET_GESTURE_SCROLL_BEGIN:
208 StartResize(*event);
209 break;
210 case ui::ET_GESTURE_SCROLL_UPDATE:
211 ContinueResize(*event);
212 break;
213 case ui::ET_GESTURE_SCROLL_END:
214 resize_details_.reset();
215 break;
216 default:
217 return;
218 }
219 event->SetHandled();
220 }
221
222 bool TableHeader::StartResize(const ui::LocatedEvent& event) {
223 if (is_resizing())
224 return false;
225
226 const int index = GetResizeColumn(GetMirroredXInView(event.x()));
227 if (index == -1)
228 return false;
229
230 resize_details_.reset(new ColumnResizeDetails);
231 resize_details_->column_index = index;
232 resize_details_->initial_x = event.root_location().x();
233 resize_details_->initial_width = table_->visible_columns()[index].width;
234 return true;
235 }
236
237 void TableHeader::ContinueResize(const ui::LocatedEvent& event) {
238 if (!is_resizing())
239 return;
240
241 const int scale = base::i18n::IsRTL() ? -1 : 1;
242 const int delta = scale *
243 (event.root_location().x() - resize_details_->initial_x);
244 table_->SetVisibleColumnWidth(
245 resize_details_->column_index,
246 std::max(kMinColumnWidth, resize_details_->initial_width + delta));
247 }
248
249 void TableHeader::ToggleSortOrder(const ui::LocatedEvent& event) {
250 if (table_->visible_columns().empty())
251 return;
252
253 const int x = GetMirroredXInView(event.x());
254 const int index = GetClosestVisibleColumnIndex(table_, x);
255 const TableView::VisibleColumn& column(table_->visible_columns()[index]);
256 if (x >= column.x && x < column.x + column.width && event.y() >= 0 &&
257 event.y() < height())
258 table_->ToggleSortOrder(index);
259 }
260
261 int TableHeader::GetResizeColumn(int x) const {
262 const Columns& columns(table_->visible_columns());
263 if (columns.empty())
264 return -1;
265
266 const int index = GetClosestVisibleColumnIndex(table_, x);
267 DCHECK_NE(-1, index);
268 const TableView::VisibleColumn& column(table_->visible_columns()[index]);
269 if (index > 0 && x >= column.x - kResizePadding &&
270 x <= column.x + kResizePadding) {
271 return index - 1;
272 }
273 const int max_x = column.x + column.width;
274 return (x >= max_x - kResizePadding && x <= max_x + kResizePadding) ?
275 index : -1;
276 }
277
278 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/table/table_header.h ('k') | ui/views/controls/table/table_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698