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

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

Issue 9187027: Attempt 2 at: Adds a trivial views based table implementation (only supports single (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « ui/views/controls/table/table_view_views.h ('k') | ui/views/controls/table/table_view_win.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_view_views.h"
6
7 #include "base/i18n/rtl.h"
8 #include "third_party/skia/include/core/SkBitmap.h"
9 #include "ui/base/models/table_model.h"
10 #include "ui/gfx/canvas_skia.h"
11 #include "ui/gfx/native_theme.h"
12 #include "ui/gfx/skia_util.h"
13 #include "ui/views/border.h"
14 #include "ui/views/controls/scroll_view.h"
15 #include "ui/views/controls/table/table_view_observer.h"
16
17 // Padding around the text (on each side).
18 static const int kTextVerticalPadding = 3;
19 static const int kTextHorizontalPadding = 2;
20
21 // TODO: these should come from native theme or something.
22 static const SkColor kSelectedBackgroundColor = SkColorSetRGB(0xEE, 0xEE, 0xEE);
23 static const SkColor kTextColor = SK_ColorBLACK;
24
25 // Size of images.
26 static const int kImageSize = 16;
27
28 // Padding between the image and text.
29 static const int kImageToTextPadding = 4;
30
31 namespace views {
32
33
34 TableView::TableView(ui::TableModel* model,
35 const std::vector<ui::TableColumn>& columns,
36 TableTypes table_type,
37 bool single_selection,
38 bool resizable_columns,
39 bool autosize_columns)
40 : model_(model),
41 table_type_(table_type),
42 table_view_observer_(NULL),
43 selected_row_(-1),
44 row_height_(font_.GetHeight() + kTextVerticalPadding * 2) {
45 // This implementation only shows a single column.
46 DCHECK_EQ(1u, columns.size());
47 // CHECK_BOX_AND_TEXT is not supported.
48 DCHECK(table_type == TEXT_ONLY || table_type == ICON_AND_TEXT);
49 set_focusable(true);
50 set_background(Background::CreateSolidBackground(SK_ColorWHITE));
51 }
52
53 TableView::~TableView() {
54 if (model_)
55 model_->SetObserver(NULL);
56 }
57
58 void TableView::SetModel(ui::TableModel* model) {
59 if (model == model_)
60 return;
61
62 if (model_)
63 model_->SetObserver(NULL);
64 model_ = model;
65 if (RowCount())
66 selected_row_ = 0;
67 if (model_)
68 model_->SetObserver(this);
69 }
70
71 View* TableView::CreateParentIfNecessary() {
72 ScrollView* scroll_view = new ScrollView;
73 scroll_view->SetContents(this);
74 scroll_view->set_border(Border::CreateSolidBorder(
75 1, gfx::NativeTheme::instance()->GetSystemColor(
76 gfx::NativeTheme::kColorId_UnfocusedBorderColor)));
77 return scroll_view;
78 }
79
80 int TableView::RowCount() const {
81 return model_ ? model_->RowCount() : 0;
82 }
83
84 int TableView::SelectedRowCount() {
85 return selected_row_ != -1 ? 1 : 0;
86 }
87
88 void TableView::Select(int model_row) {
89 if (!model_)
90 return;
91
92 if (model_row == selected_row_)
93 return;
94
95 DCHECK(model_row >= 0 && model_row < RowCount());
96 selected_row_ = model_row;
97 if (selected_row_ != -1)
98 ScrollRectToVisible(GetRowBounds(selected_row_));
99 SchedulePaint();
100 if (table_view_observer_)
101 table_view_observer_->OnSelectionChanged();
102 }
103
104 int TableView::FirstSelectedRow() {
105 return selected_row_;
106 }
107
108 void TableView::Layout() {
109 // We have to override Layout like this since we're contained in a ScrollView.
110 gfx::Size pref = GetPreferredSize();
111 int width = pref.width();
112 int height = pref.height();
113 if (parent()) {
114 width = std::max(parent()->width(), width);
115 height = std::max(parent()->height(), height);
116 }
117 SetBounds(x(), y(), width, height);
118 }
119
120 gfx::Size TableView::GetPreferredSize() {
121 return gfx::Size(50, RowCount() * row_height_);
122 }
123
124 bool TableView::OnKeyPressed(const KeyEvent& event) {
125 if (!HasFocus())
126 return false;
127
128 switch (event.key_code()) {
129 case ui::VKEY_UP:
130 if (selected_row_ > 0)
131 Select(selected_row_ - 1);
132 else if (selected_row_ == -1 && RowCount())
133 Select(RowCount() - 1);
134 return true;
135
136 case ui::VKEY_DOWN:
137 if (selected_row_ == -1) {
138 if (RowCount())
139 Select(0);
140 } else if (selected_row_ + 1 < RowCount()) {
141 Select(selected_row_ + 1);
142 }
143 return true;
144
145 default:
146 break;
147 }
148 return false;
149 }
150
151 bool TableView::OnMousePressed(const MouseEvent& event) {
152 RequestFocus();
153 int row = event.y() / row_height_;
154 if (row >= 0 && row < RowCount()) {
155 Select(row);
156 if (table_view_observer_ && event.flags() & ui::EF_IS_DOUBLE_CLICK)
157 table_view_observer_->OnDoubleClick();
158 }
159 return true;
160 }
161
162 void TableView::OnModelChanged() {
163 if (RowCount())
164 selected_row_ = 0;
165 else
166 selected_row_ = -1;
167 NumRowsChanged();
168 }
169
170 void TableView::OnItemsChanged(int start, int length) {
171 SchedulePaint();
172 }
173
174 void TableView::OnItemsAdded(int start, int length) {
175 if (selected_row_ >= start)
176 selected_row_ += length;
177 NumRowsChanged();
178 }
179
180 void TableView::OnItemsRemoved(int start, int length) {
181 bool notify_selection_changed = false;
182 if (selected_row_ >= (start + length)) {
183 selected_row_ -= length;
184 if (selected_row_ == 0 && RowCount() == 0) {
185 selected_row_ = -1;
186 notify_selection_changed = true;
187 }
188 } else if (selected_row_ >= start) {
189 selected_row_ = start;
190 if (selected_row_ == RowCount())
191 selected_row_--;
192 notify_selection_changed = true;
193 }
194 if (table_view_observer_ && notify_selection_changed)
195 table_view_observer_->OnSelectionChanged();
196 }
197
198 gfx::Point TableView::GetKeyboardContextMenuLocation() {
199 int first_selected = FirstSelectedRow();
200 gfx::Rect vis_bounds(GetVisibleBounds());
201 int y = vis_bounds.height() / 2;
202 if (first_selected != -1) {
203 gfx::Rect cell_bounds(GetRowBounds(first_selected));
204 if (cell_bounds.bottom() >= vis_bounds.y() &&
205 cell_bounds.bottom() < vis_bounds.bottom()) {
206 y = cell_bounds.bottom();
207 }
208 }
209 gfx::Point screen_loc(0, y);
210 if (base::i18n::IsRTL())
211 screen_loc.set_x(width());
212 ConvertPointToScreen(this, &screen_loc);
213 return screen_loc;
214 }
215
216 void TableView::OnPaint(gfx::Canvas* canvas) {
217 // Don't invoke View::OnPaint so that we can render our own focus border.
218 OnPaintBackground(canvas);
219
220 if (!RowCount())
221 return;
222
223 int min_y, max_y;
224 {
225 SkRect sk_clip_rect;
226 if (canvas->GetSkCanvas()->getClipBounds(&sk_clip_rect)) {
227 gfx::Rect clip_rect = gfx::SkRectToRect(sk_clip_rect);
228 min_y = clip_rect.y();
229 max_y = clip_rect.bottom();
230 } else {
231 gfx::Rect vis_bounds = GetVisibleBounds();
232 min_y = vis_bounds.y();
233 max_y = vis_bounds.bottom();
234 }
235 }
236
237 int min_row = std::min(RowCount() - 1, std::max(0, min_y / row_height_));
238 int max_row = max_y / row_height_;
239 if (max_y % row_height_ != 0)
240 max_row++;
241 max_row = std::min(max_row, RowCount());
242 for (int i = min_row; i < max_row; ++i) {
243 gfx::Rect row_bounds(GetRowBounds(i));
244 if (i == selected_row_) {
245 canvas->FillRect(kSelectedBackgroundColor, row_bounds);
246 if (HasFocus())
247 canvas->DrawFocusRect(row_bounds);
248 }
249 int text_x = kTextHorizontalPadding;
250 if (table_type_ == ICON_AND_TEXT) {
251 SkBitmap image = model_->GetIcon(i);
252 if (!image.isNull()) {
253 canvas->DrawBitmapInt(
254 image, 0, 0, image.width(), image.height(),
255 text_x, row_bounds.y() + (row_bounds.height() - kImageSize) / 2,
256 kImageSize, kImageSize, true);
257 }
258 text_x += kImageSize + kImageToTextPadding;
259 }
260 canvas->DrawStringInt(model_->GetText(i, 0), font_, kTextColor,
261 text_x,
262 row_bounds.y() + kTextVerticalPadding,
263 row_bounds.width() - text_x,
264 row_bounds.height() - kTextVerticalPadding * 2);
265 }
266 }
267
268 void TableView::OnFocus() {
269 if (selected_row_ != -1)
270 SchedulePaintInRect(GetRowBounds(selected_row_));
271 }
272
273 void TableView::OnBlur() {
274 if (selected_row_ != -1)
275 SchedulePaintInRect(GetRowBounds(selected_row_));
276 }
277
278 void TableView::NumRowsChanged() {
279 PreferredSizeChanged();
280 SchedulePaint();
281 }
282
283 gfx::Rect TableView::GetRowBounds(int row) {
284 return gfx::Rect(0, row * row_height_, width(), row_height_);
285 }
286
287 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/table/table_view_views.h ('k') | ui/views/controls/table/table_view_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698