add lazarus source
This commit is contained in:
204
Source/TableComponent.cpp
Normal file
204
Source/TableComponent.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
//
|
||||
// Model.cpp
|
||||
// Lazarus
|
||||
//
|
||||
// Created by Alex Birch on 01/09/2017.
|
||||
//
|
||||
//
|
||||
|
||||
#include "TableComponent.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This class shows how to implement a TableListBoxModel to show in a TableListBox.
|
||||
*/
|
||||
TableComponent::TableComponent(
|
||||
const vector<string> &columns,
|
||||
const vector<vector<string>> &rows,
|
||||
const function<void (int)> &onRowSelected,
|
||||
const function<int (const vector<string>&)> &rowToIDMapper,
|
||||
int initiallySelectedRow
|
||||
)
|
||||
: font (14.0f),
|
||||
columns(columns),
|
||||
rows(rows),
|
||||
onRowSelected(onRowSelected),
|
||||
rowToIDMapper(rowToIDMapper)
|
||||
{
|
||||
// Create our table component and add it to this component..
|
||||
addAndMakeVisible (table);
|
||||
table.setModel (this);
|
||||
|
||||
// give it a border
|
||||
table.setColour (ListBox::outlineColourId, Colours::grey);
|
||||
table.setOutlineThickness (1);
|
||||
|
||||
int columnIx = 1;
|
||||
|
||||
// Add some columns to the table header, based on the column list in our database..
|
||||
for (auto &column : columns) // access by reference to avoid copying
|
||||
{
|
||||
table.getHeader().addColumn (
|
||||
String(column),
|
||||
columnIx++,
|
||||
100, // column width
|
||||
50, // min width
|
||||
400, // max width
|
||||
TableHeaderComponent::defaultFlags
|
||||
);
|
||||
}
|
||||
|
||||
table.setWantsKeyboardFocus(false);
|
||||
|
||||
table.selectRow(initiallySelectedRow);
|
||||
|
||||
// we could now change some initial settings..
|
||||
table.getHeader().setSortColumnId (1, false); // sort ascending by ID column
|
||||
// table.getHeader().setColumnVisible (7, false); // hide the "length" column until the user shows it
|
||||
|
||||
// un-comment this line to have a go of stretch-to-fit mode
|
||||
// table.getHeader().setStretchToFitActive (true);
|
||||
|
||||
// table.setMultipleSelectionEnabled (false);
|
||||
}
|
||||
|
||||
void TableComponent::setRows(const vector<vector<string>>& rows, int initiallySelectedRow) {
|
||||
this->rows = rows;
|
||||
table.deselectAllRows();
|
||||
table.updateContent();
|
||||
table.getHeader().setSortColumnId(0, true);
|
||||
table.selectRow(initiallySelectedRow);
|
||||
}
|
||||
|
||||
// This is overloaded from TableListBoxModel, and must return the total number of rows in our table
|
||||
int TableComponent::getNumRows()
|
||||
{
|
||||
return static_cast<int>(rows.size());
|
||||
}
|
||||
|
||||
// This is overloaded from TableListBoxModel, and should fill in the background of the whole row
|
||||
void TableComponent::paintRowBackground (
|
||||
Graphics& g,
|
||||
int rowNumber,
|
||||
int /*width*/,
|
||||
int /*height*/,
|
||||
bool rowIsSelected
|
||||
) {
|
||||
const Colour alternateColour (getLookAndFeel().findColour (ListBox::backgroundColourId)
|
||||
.interpolatedWith (getLookAndFeel().findColour (ListBox::textColourId), 0.03f));
|
||||
if (rowIsSelected)
|
||||
g.fillAll (Colours::lightblue);
|
||||
else if (rowNumber % 2)
|
||||
g.fillAll (alternateColour);
|
||||
}
|
||||
|
||||
// This is overloaded from TableListBoxModel, and must paint any cells that aren't using custom
|
||||
// components.
|
||||
void TableComponent::paintCell (
|
||||
Graphics& g,
|
||||
int rowNumber,
|
||||
int columnId,
|
||||
int width,
|
||||
int height,
|
||||
bool /*rowIsSelected*/
|
||||
) {
|
||||
g.setColour (getLookAndFeel().findColour (ListBox::textColourId));
|
||||
g.setFont (font);
|
||||
|
||||
g.drawText (rows[rowNumber][columnId-1], 2, 0, width - 4, height, Justification::centredLeft, true);
|
||||
|
||||
g.setColour (getLookAndFeel().findColour (ListBox::backgroundColourId));
|
||||
g.fillRect (width - 1, 0, 1, height);
|
||||
}
|
||||
|
||||
// This is overloaded from TableListBoxModel, and tells us that the user has clicked a table header
|
||||
// to change the sort order.
|
||||
void TableComponent::sortOrderChanged (
|
||||
int newSortColumnId,
|
||||
bool isForwards
|
||||
) {
|
||||
if (newSortColumnId != 0) {
|
||||
int selectedRowIx = table.getSelectedRow();
|
||||
vector<string> selectedRow;
|
||||
if (selectedRowIx >= 0) {
|
||||
selectedRow = rows[selectedRowIx];
|
||||
}
|
||||
|
||||
TableComponent::DataSorter sorter (newSortColumnId, isForwards);
|
||||
sort(rows.begin(), rows.end(), sorter);
|
||||
|
||||
table.updateContent();
|
||||
|
||||
if (selectedRowIx >= 0) {
|
||||
for (auto it = rows.begin(); it != rows.end(); ++it) {
|
||||
if(*it == selectedRow) {
|
||||
int index = static_cast<int>(std::distance(rows.begin(), it));
|
||||
table.selectRow(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is overloaded from TableListBoxModel, and should choose the best width for the specified
|
||||
// column.
|
||||
int TableComponent::getColumnAutoSizeWidth (int columnId) {
|
||||
if (columnId == 5)
|
||||
return 100; // (this is the ratings column, containing a custom combobox component)
|
||||
|
||||
int widest = 32;
|
||||
|
||||
// find the widest bit of text in this column..
|
||||
for (int i = getNumRows(); --i >= 0;) {
|
||||
widest = jmax (widest, font.getStringWidth (rows[i][columnId-1]));
|
||||
}
|
||||
|
||||
return widest + 8;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void TableComponent::resized() {
|
||||
// position our table with a gap around its edge
|
||||
table.setBoundsInset (BorderSize<int> (7));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// A comparator used to sort our data when the user clicks a column header
|
||||
|
||||
TableComponent::DataSorter::DataSorter (
|
||||
int columnByWhichToSort,
|
||||
bool forwards
|
||||
)
|
||||
: columnByWhichToSort (columnByWhichToSort),
|
||||
direction (forwards ? 1 : -1)
|
||||
{}
|
||||
|
||||
bool TableComponent::DataSorter::operator ()(
|
||||
vector<string> first,
|
||||
vector<string> second
|
||||
) {
|
||||
int result = String(first[columnByWhichToSort-1])
|
||||
.compareNatural (String(second[columnByWhichToSort-1]));
|
||||
|
||||
if (result == 0)
|
||||
result = String(first[0])
|
||||
.compareNatural (String(second[0]));
|
||||
|
||||
result *= direction;
|
||||
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
void TableComponent::selectedRowsChanged (int row) {
|
||||
if (row < 0) {
|
||||
return;
|
||||
}
|
||||
onRowSelected(rowToIDMapper(rows[row]));
|
||||
}
|
||||
|
||||
bool TableComponent::keyPressed(const KeyPress &key) {
|
||||
return table.keyPressed(key);
|
||||
}
|
Reference in New Issue
Block a user