[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] gwc-no-xslfo 4fcbd32 03/12: Import 'wx_table_generat
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] gwc-no-xslfo 4fcbd32 03/12: Import 'wx_table_generator.?pp' changes verbatim from vz-no-xslfo |
Date: |
Sat, 27 Jan 2018 04:23:33 -0500 (EST) |
branch: gwc-no-xslfo
commit 4fcbd3234f1cf592fada52b517de8ab94a7a0387
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Import 'wx_table_generator.?pp' changes verbatim from vz-no-xslfo
---
wx_table_generator.cpp | 168 +++++++++++++++++++++++++++++++++++++++++++------
wx_table_generator.hpp | 59 ++++++++++++++---
2 files changed, 199 insertions(+), 28 deletions(-)
diff --git a/wx_table_generator.cpp b/wx_table_generator.cpp
index 28f8c28..79d57f3 100644
--- a/wx_table_generator.cpp
+++ b/wx_table_generator.cpp
@@ -53,6 +53,7 @@ wx_table_generator::wx_table_generator
,total_width_(total_width)
,char_height_(dc_.GetCharHeight())
,row_height_((4 * char_height_ + 2) / 3) // Arbitrarily use 1.333 line
spacing.
+ ,column_margin_(dc_.GetTextExtent("M").x)
,has_column_widths_(false)
,max_header_lines_(1)
{
@@ -64,6 +65,18 @@ wx_table_generator::wx_table_generator
dc_.SetPen(pen);
}
+void wx_table_generator::use_condensed_style()
+{
+ row_height_ = char_height_;
+ draw_separators_ = false;
+ use_bold_headers_ = false;
+}
+
+void wx_table_generator::align_right()
+{
+ align_right_ = true;
+}
+
void wx_table_generator::add_column
(std::string const& header
,std::string const& widest_text
@@ -77,7 +90,11 @@ void wx_table_generator::add_column
}
else
{
- wxDCFontChanger set_header_font(dc_, get_header_font());
+ wxDCFontChanger set_header_font(dc_);
+ if(use_bold_headers_)
+ {
+ set_header_font.Set(get_header_font());
+ }
// Set width to the special value of 0 for the variable width columns.
width = widest_text.empty() ? 0 : dc_.GetTextExtent(widest_text).x;
@@ -94,8 +111,7 @@ void wx_table_generator::add_column
{
increase_to_if_smaller(width,
dc_.GetMultiLineTextExtent(header).x);
- // Add roughly 1 em margins on both sides.
- width += dc_.GetTextExtent("MM").x;
+ width += 2*column_margin_;
}
}
@@ -157,6 +173,8 @@ void
wx_table_generator::do_compute_column_widths_if_necessary()
return;
}
+ has_column_widths_ = true;
+
int num_expand = 0;
int total_fixed = 0;
@@ -179,7 +197,43 @@ void
wx_table_generator::do_compute_column_widths_if_necessary()
if(total_width_ < total_fixed)
{
- warning() << "Not enough space for all fixed columns." << LMI_FLUSH;
+ auto const overflow = total_fixed - total_width_;
+
+ // If we have only fixed columns, try to make them fit by decreasing
+ // the margins around them if this can help, assuming that we can
+ // reduce them by up to half if really needed.
+ if(!num_expand)
+ {
+ int const num_columns = columns_.size();
+ auto const overflow_per_column =
+ (overflow + num_columns - 1)/num_columns;
+ if(overflow_per_column <= column_margin_)
+ {
+ for(auto& i : columns_)
+ {
+ if(i.is_hidden())
+ {
+ continue;
+ }
+
+ i.width_ -= overflow_per_column;
+ }
+
+ column_margin_ -= (overflow_per_column + 1)/2;
+
+ // We condensed the columns enough to make them fit, so no need
+ // for the warning and we don't have any expanding columns, so
+ // we're done.
+ return;
+ }
+ }
+
+ warning()
+ << "Not enough space for all fixed columns: "
+ << overflow
+ << " more pixels needed."
+ << LMI_FLUSH
+ ;
return;
}
@@ -201,8 +255,6 @@ void
wx_table_generator::do_compute_column_widths_if_necessary()
}
}
}
-
- has_column_widths_ = true;
}
void wx_table_generator::do_output_values
@@ -216,7 +268,10 @@ void wx_table_generator::do_output_values
int const y_text = y + char_height_;
y += row_height_;
- do_output_vert_separator(x, y_top, y);
+ if(draw_separators_)
+ {
+ do_output_vert_separator(x, y_top, y);
+ }
std::size_t const num_columns = columns_.size();
for(std::size_t col = 0; col < num_columns; ++col)
@@ -233,21 +288,31 @@ void wx_table_generator::do_output_values
if(!s.empty())
{
int x_text = x;
- if(ci.is_centered_)
+
+ if(align_right_)
{
- // Centre the text for the columns configured to do it.
- x_text += (width - dc_.GetTextExtent(s).x) / 2;
+ x_text += width - dc_.GetTextExtent(s).x;
}
else
{
- // Otherwise just offset it by ~1 em.
- x_text += dc_.GetTextExtent("M").x;
- }
+ if(ci.is_centered_)
+ {
+ // Centre the text for the columns configured to do it.
+ x_text += (width - dc_.GetTextExtent(s).x) / 2;
+ }
+ else
+ {
+ x_text += column_margin_;
+ }
+ }
dc_.DrawText(s, x_text, y_text);
}
x += width;
- do_output_vert_separator(x, y_top, y);
+ if(draw_separators_)
+ {
+ do_output_vert_separator(x, y_top, y);
+ }
}
}
@@ -269,8 +334,17 @@ void wx_table_generator::output_horz_separator
(std::size_t begin_column
,std::size_t end_column
,int y
+ ,enum_output_mode output_mode
)
{
+ switch(output_mode)
+ {
+ case e_output_normal:
+ break;
+ case e_output_measure_only:
+ return;
+ }
+
LMI_ASSERT(begin_column < end_column);
LMI_ASSERT(end_column <= columns_.size());
@@ -287,11 +361,24 @@ void wx_table_generator::output_horz_separator
do_output_horz_separator(x1, x2, y);
}
-void wx_table_generator::output_header(int* pos_y)
+void wx_table_generator::output_header(int* pos_y, enum_output_mode
output_mode)
{
+ switch(output_mode)
+ {
+ case e_output_normal:
+ break;
+ case e_output_measure_only:
+ *pos_y += max_header_lines_ * row_height_;
+ return;
+ }
+
do_compute_column_widths_if_necessary();
- wxDCFontChanger set_header_font(dc_, get_header_font());
+ wxDCFontChanger set_header_font(dc_);
+ if(use_bold_headers_)
+ {
+ set_header_font.Set(get_header_font());
+ }
// Split headers in single lines and fill up the entire columns*lines 2D
// matrix, using empty strings for the headers with less than the maximal
@@ -328,9 +415,47 @@ void wx_table_generator::output_header(int* pos_y)
}
// Finally draw the separators above and (a double one) below them.
- do_output_horz_separator(left_margin_, x, y_top );
- do_output_horz_separator(left_margin_, x, *pos_y - 1);
- do_output_horz_separator(left_margin_, x, *pos_y );
+ if(draw_separators_)
+ {
+ do_output_horz_separator(left_margin_, x, y_top );
+ do_output_horz_separator(left_margin_, x, *pos_y - 1);
+ do_output_horz_separator(left_margin_, x, *pos_y );
+ }
+}
+
+void wx_table_generator::output_super_header
+ (std::string const& header
+ ,std::size_t begin_column
+ ,std::size_t end_column
+ ,int* pos_y
+ ,enum_output_mode output_mode
+ )
+{
+ std::vector<std::string> const lines(split_into_lines(header));
+
+ switch(output_mode)
+ {
+ case e_output_normal:
+ break;
+ case e_output_measure_only:
+ *pos_y += row_height_*lines.size();
+ return;
+ }
+
+ // We don't have a function for getting the rectangle of a span of columns,
+ // but we can reuse the existing text_rect() if we just increase its width
+ // by the width of all the extra (i.e. not counting the starting one)
+ // columns in this span.
+ auto rect = text_rect(begin_column, *pos_y);
+ rect.width += do_get_cell_x(end_column) - do_get_cell_x(begin_column + 1);
+
+ for(auto const& line : lines)
+ {
+ dc_.DrawLabel(line, rect, wxALIGN_CENTER_HORIZONTAL);
+
+ rect.y += row_height_;
+ *pos_y += row_height_;
+ }
}
void wx_table_generator::output_row
@@ -341,7 +466,10 @@ void wx_table_generator::output_row
int x = left_margin_;
do_output_values(x, *pos_y, values);
- do_output_horz_separator(left_margin_, x, *pos_y);
+ if(draw_separators_)
+ {
+ do_output_horz_separator(left_margin_, x, *pos_y);
+ }
}
void wx_table_generator::output_highlighted_cell
diff --git a/wx_table_generator.hpp b/wx_table_generator.hpp
index 3e3f657..1ba0e58 100644
--- a/wx_table_generator.hpp
+++ b/wx_table_generator.hpp
@@ -24,6 +24,8 @@
#include "config.hpp"
+#include "output_mode.hpp"
+
#include <wx/dc.h>
#include <wx/font.h>
@@ -52,19 +54,34 @@ class wx_table_generator
// Adds a column to the table. The total number of added columns determines
// the number of the expected value in output_row() calls.
//
- // Providing an empty header suppresses the table display, while still
- // taking into account in output_row(), providing a convenient way to hide
- // a single column without changing the data representation.
+ // Providing an empty header suppresses the column display, while still
+ // taking it into account in output_row(), providing a convenient way to
+ // hide a single column without changing the data representation.
//
// Each column must either have a fixed width, specified as the width of
// the longest text that may appear in this column, or be expandable
// meaning that the rest of the page width is allocated to it which will be
// the case if widest_text is empty.
+ //
// Notice that column headers may be multiline strings.
void add_column(std::string const& header, std::string const& widest_text);
// Render the headers at the given position and update it.
- void output_header(int* pos_y);
+ void output_header
+ (int* pos_y
+ ,enum_output_mode output_mode = e_output_normal
+ );
+
+ // Render a super-header, i.e. a header spanning over several columns. The
+ // columns range is specified as a close/open interval, as usual in C++.
+ // The header string may be multiline, just as with normal headers.
+ void output_super_header
+ (std::string const& header
+ ,std::size_t begin_column
+ ,std::size_t end_column
+ ,int* pos_y
+ ,enum_output_mode output_mode = e_output_normal
+ );
// Render a row with the given values at the given position and update it.
// The values here can be single-line only and there must be exactly the
@@ -79,6 +96,9 @@ class wx_table_generator
,std::string const& value
);
+ // Return the number of columns.
+ std::size_t columns_count() const {return columns_.size();}
+
// Return the height of a single table row.
int row_height() const {return row_height_;}
@@ -94,9 +114,10 @@ class wx_table_generator
// Output a horizontal separator line across the specified columns,
// using the usual C++ close/open interval convention.
void output_horz_separator
- (std::size_t begin_column
- ,std::size_t end_column
- ,int y
+ (std::size_t begin_column
+ ,std::size_t end_column
+ ,int y
+ ,enum_output_mode output_mode = e_output_normal
);
// Output a vertical separator line before the given column. Notice that
@@ -104,6 +125,15 @@ class wx_table_generator
// output a separator after the last column.
void output_vert_separator(std::size_t before_column, int y);
+ // Use condensed style: don't draw separators between rows and make them
+ // smaller.
+ void use_condensed_style();
+
+ // By default, columns are centered if they have fixed size or left-aligned
+ // otherwise. By calling this method, this alignment auto-detection is
+ // turned off and all columns are right-aligned.
+ void align_right();
+
private:
// Return the font used for the headers.
wxFont get_header_font() const;
@@ -128,7 +158,8 @@ class wx_table_generator
// These values could be recomputed, but cache them for performance.
int const char_height_;
- int const row_height_;
+ int row_height_;
+ int column_margin_;
struct column_info
{
@@ -160,6 +191,18 @@ class wx_table_generator
// Maximal number of lines in any column header, initially 1 but can be
// higher if multiline headers are used.
std::size_t max_header_lines_;
+
+ // If false, separator lines are not drawn automatically (they can still be
+ // drawn by calling output_horz_separator() or output_vert_separator()
+ // explicitly).
+ bool draw_separators_ = true;
+
+ // If true, headers are drawn in bold.
+ bool use_bold_headers_ = true;
+
+ // If true, force right alignment for all columns instead of centering them
+ // automatically if they have fixed size.
+ bool align_right_ = false;
};
#endif // wx_table_generator_hpp
- [lmi-commits] [lmi] gwc-no-xslfo 1f8c16d 02/12: Restore two deleted object files, (continued)
- [lmi-commits] [lmi] gwc-no-xslfo 1f8c16d 02/12: Restore two deleted object files, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 4a983d0 01/12: Import makefile changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo ec4fcc0 07/12: Restore vz-no-xslfo deletions, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo c216db3 05/12: Allow 'PDF !!' markers, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 90d858b 10/12: Import 'emit_ledger.cpp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo adb7ff0 11/12: Restore a deleted header, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 89df28a 06/12: Import 'ledger.hpp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 88cc286 08/12: Import 'main_wx*.cpp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo f294831 09/12: Mark some deferred PDF issues, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo aec2811 12/12: Enable old and new PDF implementations to coexist, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 4fcbd32 03/12: Import 'wx_table_generator.?pp' changes verbatim from vz-no-xslfo,
Greg Chicares <=
- [lmi-commits] [lmi] gwc-no-xslfo 28d5b17 04/12: Import 'group_quote_pdf_gen_wx.cpp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27