Home | History | Annotate | Download | only in table
      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_utils.h"
      6 
      7 #include "base/logging.h"
      8 #include "ui/gfx/canvas.h"
      9 #include "ui/gfx/font_list.h"
     10 #include "ui/gfx/text_utils.h"
     11 #include "ui/views/controls/table/table_view.h"
     12 
     13 namespace views {
     14 
     15 const int kUnspecifiedColumnWidth = 90;
     16 
     17 int WidthForContent(const gfx::FontList& header_font_list,
     18                     const gfx::FontList& content_font_list,
     19                     int padding,
     20                     int header_padding,
     21                     const ui::TableColumn& column,
     22                     ui::TableModel* model) {
     23   int width = header_padding;
     24   if (!column.title.empty())
     25     width = gfx::GetStringWidth(column.title, header_font_list) +
     26         header_padding;
     27 
     28   for (int i = 0, row_count = model->RowCount(); i < row_count; ++i) {
     29     const int cell_width =
     30         gfx::GetStringWidth(model->GetText(i, column.id), content_font_list);
     31     width = std::max(width, cell_width);
     32   }
     33   return width + padding;
     34 }
     35 
     36 std::vector<int> CalculateTableColumnSizes(
     37     int width,
     38     int first_column_padding,
     39     const gfx::FontList& header_font_list,
     40     const gfx::FontList& content_font_list,
     41     int padding,
     42     int header_padding,
     43     const std::vector<ui::TableColumn>& columns,
     44     ui::TableModel* model) {
     45   float total_percent = 0;
     46   int non_percent_width = 0;
     47   std::vector<int> content_widths(columns.size(), 0);
     48   for (size_t i = 0; i < columns.size(); ++i) {
     49     const ui::TableColumn& column(columns[i]);
     50     if (column.width <= 0) {
     51       if (column.percent > 0) {
     52         total_percent += column.percent;
     53         // Make sure there is at least enough room for the header.
     54         content_widths[i] = gfx::GetStringWidth(column.title, header_font_list)
     55             + padding + header_padding;
     56       } else {
     57         content_widths[i] = WidthForContent(header_font_list, content_font_list,
     58                                             padding, header_padding, column,
     59                                             model);
     60         if (i == 0)
     61           content_widths[i] += first_column_padding;
     62       }
     63       non_percent_width += content_widths[i];
     64     } else {
     65       content_widths[i] = column.width;
     66       non_percent_width += column.width;
     67     }
     68   }
     69 
     70   std::vector<int> widths;
     71   const int available_width = width - non_percent_width;
     72   for (size_t i = 0; i < columns.size(); ++i) {
     73     const ui::TableColumn& column = columns[i];
     74     int column_width = content_widths[i];
     75     if (column.width <= 0 && column.percent > 0 && available_width > 0) {
     76       column_width += static_cast<int>(available_width *
     77                                        (column.percent / total_percent));
     78     }
     79     widths.push_back(column_width == 0 ? kUnspecifiedColumnWidth :
     80                      column_width);
     81   }
     82 
     83   // If no columns have specified a percent give the last column all the extra
     84   // space.
     85   if (!columns.empty() && total_percent == 0.f && available_width > 0 &&
     86       columns.back().width <= 0 && columns.back().percent == 0.f) {
     87     widths.back() += available_width;
     88   }
     89 
     90   return widths;
     91 }
     92 
     93 int TableColumnAlignmentToCanvasAlignment(
     94     ui::TableColumn::Alignment alignment) {
     95   switch (alignment) {
     96     case ui::TableColumn::LEFT:
     97       return gfx::Canvas::TEXT_ALIGN_LEFT;
     98     case ui::TableColumn::CENTER:
     99       return gfx::Canvas::TEXT_ALIGN_CENTER;
    100     case ui::TableColumn::RIGHT:
    101       return gfx::Canvas::TEXT_ALIGN_RIGHT;
    102   }
    103   NOTREACHED();
    104   return gfx::Canvas::TEXT_ALIGN_LEFT;
    105 }
    106 
    107 int GetClosestVisibleColumnIndex(const TableView* table, int x) {
    108   const std::vector<TableView::VisibleColumn>& columns(
    109       table->visible_columns());
    110   for (size_t i = 0; i < columns.size(); ++i) {
    111     if (x <= columns[i].x + columns[i].width)
    112       return static_cast<int>(i);
    113   }
    114   return static_cast<int>(columns.size()) - 1;
    115 }
    116 
    117 }  // namespace views
    118