12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/table/table_utils.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/canvas.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font_list.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/text_utils.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/table/table_view.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace views { 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kUnspecifiedColumnWidth = 90; 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int WidthForContent(const gfx::FontList& header_font_list, 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::FontList& content_font_list, 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int padding, 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int header_padding, 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ui::TableColumn& column, 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::TableModel* model) { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width = header_padding; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!column.title.empty()) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) width = gfx::GetStringWidth(column.title, header_font_list) + 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) header_padding; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0, row_count = model->RowCount(); i < row_count; ++i) { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int cell_width = 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::GetStringWidth(model->GetText(i, column.id), content_font_list); 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) width = std::max(width, cell_width); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return width + padding; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<int> CalculateTableColumnSizes( 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int width, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int first_column_padding, 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::FontList& header_font_list, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::FontList& content_font_list, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int padding, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int header_padding, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<ui::TableColumn>& columns, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::TableModel* model) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float total_percent = 0; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int non_percent_width = 0; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<int> content_widths(columns.size(), 0); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < columns.size(); ++i) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ui::TableColumn& column(columns[i]); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (column.width <= 0) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (column.percent > 0) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_percent += column.percent; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure there is at least enough room for the header. 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content_widths[i] = gfx::GetStringWidth(column.title, header_font_list) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) + padding + header_padding; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content_widths[i] = WidthForContent(header_font_list, content_font_list, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) padding, header_padding, column, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i == 0) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_widths[i] += first_column_padding; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_percent_width += content_widths[i]; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_widths[i] = column.width; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_percent_width += column.width; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<int> widths; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int available_width = width - non_percent_width; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < columns.size(); ++i) { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ui::TableColumn& column = columns[i]; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int column_width = content_widths[i]; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (column.width <= 0 && column.percent > 0 && available_width > 0) { 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) column_width += static_cast<int>(available_width * 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (column.percent / total_percent)); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widths.push_back(column_width == 0 ? kUnspecifiedColumnWidth : 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) column_width); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If no columns have specified a percent give the last column all the extra 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // space. 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!columns.empty() && total_percent == 0.f && available_width > 0 && 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) columns.back().width <= 0 && columns.back().percent == 0.f) { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widths.back() += available_width; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return widths; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int TableColumnAlignmentToCanvasAlignment( 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::TableColumn::Alignment alignment) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (alignment) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::TableColumn::LEFT: 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Canvas::TEXT_ALIGN_LEFT; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::TableColumn::CENTER: 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Canvas::TEXT_ALIGN_CENTER; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::TableColumn::RIGHT: 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Canvas::TEXT_ALIGN_RIGHT; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Canvas::TEXT_ALIGN_LEFT; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int GetClosestVisibleColumnIndex(const TableView* table, int x) { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<TableView::VisibleColumn>& columns( 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) table->visible_columns()); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < columns.size(); ++i) { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (x <= columns[i].x + columns[i].width) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<int>(i); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<int>(columns.size()) - 1; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace views 118