// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/views/controls/table/table_utils.h" #include "base/logging.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font_list.h" #include "ui/gfx/text_utils.h" #include "ui/views/controls/table/table_view.h" namespace views { const int kUnspecifiedColumnWidth = 90; int WidthForContent(const gfx::FontList& header_font_list, const gfx::FontList& content_font_list, int padding, int header_padding, const ui::TableColumn& column, ui::TableModel* model) { int width = header_padding; if (!column.title.empty()) width = gfx::GetStringWidth(column.title, header_font_list) + header_padding; for (int i = 0, row_count = model->RowCount(); i < row_count; ++i) { const int cell_width = gfx::GetStringWidth(model->GetText(i, column.id), content_font_list); width = std::max(width, cell_width); } return width + padding; } std::vector<int> CalculateTableColumnSizes( int width, int first_column_padding, const gfx::FontList& header_font_list, const gfx::FontList& content_font_list, int padding, int header_padding, const std::vector<ui::TableColumn>& columns, ui::TableModel* model) { float total_percent = 0; int non_percent_width = 0; std::vector<int> content_widths(columns.size(), 0); for (size_t i = 0; i < columns.size(); ++i) { const ui::TableColumn& column(columns[i]); if (column.width <= 0) { if (column.percent > 0) { total_percent += column.percent; // Make sure there is at least enough room for the header. content_widths[i] = gfx::GetStringWidth(column.title, header_font_list) + padding + header_padding; } else { content_widths[i] = WidthForContent(header_font_list, content_font_list, padding, header_padding, column, model); if (i == 0) content_widths[i] += first_column_padding; } non_percent_width += content_widths[i]; } else { content_widths[i] = column.width; non_percent_width += column.width; } } std::vector<int> widths; const int available_width = width - non_percent_width; for (size_t i = 0; i < columns.size(); ++i) { const ui::TableColumn& column = columns[i]; int column_width = content_widths[i]; if (column.width <= 0 && column.percent > 0 && available_width > 0) { column_width += static_cast<int>(available_width * (column.percent / total_percent)); } widths.push_back(column_width == 0 ? kUnspecifiedColumnWidth : column_width); } // If no columns have specified a percent give the last column all the extra // space. if (!columns.empty() && total_percent == 0.f && available_width > 0 && columns.back().width <= 0 && columns.back().percent == 0.f) { widths.back() += available_width; } return widths; } int TableColumnAlignmentToCanvasAlignment( ui::TableColumn::Alignment alignment) { switch (alignment) { case ui::TableColumn::LEFT: return gfx::Canvas::TEXT_ALIGN_LEFT; case ui::TableColumn::CENTER: return gfx::Canvas::TEXT_ALIGN_CENTER; case ui::TableColumn::RIGHT: return gfx::Canvas::TEXT_ALIGN_RIGHT; } NOTREACHED(); return gfx::Canvas::TEXT_ALIGN_LEFT; } int GetClosestVisibleColumnIndex(const TableView* table, int x) { const std::vector<TableView::VisibleColumn>& columns( table->visible_columns()); for (size_t i = 0; i < columns.size(); ++i) { if (x <= columns[i].x + columns[i].width) return static_cast<int>(i); } return static_cast<int>(columns.size()) - 1; } } // namespace views