summaryrefslogtreecommitdiff
path: root/wx+/grid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'wx+/grid.cpp')
-rw-r--r--wx+/grid.cpp137
1 files changed, 76 insertions, 61 deletions
diff --git a/wx+/grid.cpp b/wx+/grid.cpp
index c9dfbbe9..184302bf 100644
--- a/wx+/grid.cpp
+++ b/wx+/grid.cpp
@@ -36,30 +36,25 @@ void zen::clearArea(wxDC& dc, const wxRect& rect, const wxColor& col)
dc.DrawRectangle(rect);
}
+const int GridData::COLUMN_GAP_LEFT = 4;
+
namespace
{
//------------ Grid Constants --------------------------------
const double MOUSE_DRAG_ACCELERATION = 1.5; //unit: [rows / (pixel * sec)] -> same value as Explorer!
-const int DEFAULT_COL_LABEL_HEIGHT = 24;
-const int COLUMN_BORDER_LEFT = 4; //for left-aligned text
-const int COLUMN_LABEL_BORDER = COLUMN_BORDER_LEFT;
+const int DEFAULT_COL_LABEL_BORDER = 6; //top + bottom border in addition to label height
+const int COLUMN_LABEL_BORDER = GridData::COLUMN_GAP_LEFT;
const int COLUMN_MOVE_DELAY = 5; //unit: [pixel] (from Explorer)
const int COLUMN_MIN_WIDTH = 40; //only honored when resizing manually!
const int ROW_LABEL_BORDER = 3;
const int COLUMN_RESIZE_TOLERANCE = 6; //unit [pixel]
const int COLUMN_FILL_GAP_TOLERANCE = 10; //enlarge column to fill full width when resizing
-const wxColor COLOR_SELECTION_GRADIENT_NO_FOCUS_FROM = wxColour(192, 192, 192); //light grey wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
-const wxColor COLOR_SELECTION_GRADIENT_NO_FOCUS_TO = wxColour(228, 228, 228);
-
-const wxColor COLOR_LABEL_GRADIENT_FROM = wxColour(200, 200, 200); //light grey
-const wxColor COLOR_LABEL_GRADIENT_TO = *wxWHITE;
+const wxColor COLOR_LABEL_GRADIENT_FROM = *wxWHITE;
+const wxColor COLOR_LABEL_GRADIENT_TO = wxColour(200, 200, 200); //light grey
-const wxColor COLOR_LABEL_GRADIENT_FROM_FOCUS = getColorSelectionGradientFrom();
-const wxColor COLOR_LABEL_GRADIENT_TO_FOCUS = COLOR_LABEL_GRADIENT_TO;
-
-//wxColor getColorRowLabel () { return wxPanel::GetClassDefaultAttributes ().colBg; } //
-wxColor getColorMainWinBackground() { return wxListBox::GetClassDefaultAttributes().colBg; } //cannot be initialized statically on wxGTK!
+const wxColor COLOR_LABEL_GRADIENT_FROM_FOCUS = COLOR_LABEL_GRADIENT_FROM;
+const wxColor COLOR_LABEL_GRADIENT_TO_FOCUS = getColorSelectionGradientFrom();
const wxColor colorGridLine = wxColour(192, 192, 192); //light grey
}
@@ -76,25 +71,25 @@ const wxEventType zen::EVENT_GRID_MOUSE_RIGHT_UP = wxNewEventType();
const wxEventType zen::EVENT_GRID_SELECT_RANGE = wxNewEventType();
//----------------------------------------------------------------------------------------------------------------
-void GridData::renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus)
+void GridData::renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected)
{
- drawCellBackground(dc, rect, enabled, selected, hasFocus, getColorMainWinBackground());
+ drawCellBackground(dc, rect, enabled, selected, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
}
-void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType)
+void GridData::renderCell(wxDC& dc, const wxRect& rect, size_t row, ColumnType colType, bool selected)
{
wxRect rectTmp = drawCellBorder(dc, rect);
- rectTmp.x += COLUMN_BORDER_LEFT;
- rectTmp.width -= COLUMN_BORDER_LEFT;
+ rectTmp.x += COLUMN_GAP_LEFT;
+ rectTmp.width -= COLUMN_GAP_LEFT;
drawCellText(dc, rectTmp, getValue(row, colType), true);
}
int GridData::getBestSize(wxDC& dc, size_t row, ColumnType colType)
{
- return dc.GetTextExtent(getValue(row, colType)).GetWidth() + 2 * COLUMN_BORDER_LEFT; //some border on left and right side
+ return dc.GetTextExtent(getValue(row, colType)).GetWidth() + 2 * COLUMN_GAP_LEFT + 1; //gap on left and right side + border
}
@@ -108,17 +103,12 @@ wxRect GridData::drawCellBorder(wxDC& dc, const wxRect& rect) //returns remainin
}
-void GridData::drawCellBackground(wxDC& dc, const wxRect& rect, bool enabled, bool selected, bool hasFocus, const wxColor& backgroundColor)
+void GridData::drawCellBackground(wxDC& dc, const wxRect& rect, bool enabled, bool selected, const wxColor& backgroundColor)
{
if (enabled)
{
if (selected)
- {
- //if (hasFocus)
dc.GradientFillLinear(rect, getColorSelectionGradientFrom(), getColorSelectionGradientTo(), wxEAST);
- //else -> doesn't look too good...
- // dc.GradientFillLinear(rect, COLOR_SELECTION_GRADIENT_NO_FOCUS_FROM, COLOR_SELECTION_GRADIENT_NO_FOCUS_TO, wxEAST);
- }
else
clearArea(dc, rect, backgroundColor);
}
@@ -193,8 +183,8 @@ void GridData::renderColumnLabel(Grid& grid, wxDC& dc, const wxRect& rect, Colum
wxRect rectTmp = drawColumnLabelBorder(dc, rect);
drawColumnLabelBackground(dc, rectTmp, highlighted);
- rectTmp.x += COLUMN_BORDER_LEFT;
- rectTmp.width -= COLUMN_BORDER_LEFT;
+ rectTmp.x += COLUMN_GAP_LEFT;
+ rectTmp.width -= COLUMN_GAP_LEFT;
drawColumnLabelText(dc, rectTmp, getColumnLabel(colType));
}
@@ -210,7 +200,7 @@ wxRect GridData::drawColumnLabelBorder(wxDC& dc, const wxRect& rect) //returns r
//draw border (with gradient)
{
wxDCPenChanger dummy(dc, wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID));
- dc.GradientFillLinear(wxRect(rect.GetTopRight(), rect.GetBottomRight()), dc.GetPen().GetColour(), COLOR_LABEL_GRADIENT_TO, wxNORTH);
+ dc.GradientFillLinear(wxRect(rect.GetTopRight(), rect.GetBottomRight()), COLOR_LABEL_GRADIENT_FROM, dc.GetPen().GetColour(), wxSOUTH);
dc.DrawLine(rect.GetBottomLeft(), rect.GetBottomRight() + wxPoint(1, 0));
}
@@ -221,9 +211,9 @@ wxRect GridData::drawColumnLabelBorder(wxDC& dc, const wxRect& rect) //returns r
void GridData::drawColumnLabelBackground(wxDC& dc, const wxRect& rect, bool highlighted)
{
if (highlighted)
- dc.GradientFillLinear(rect, COLOR_LABEL_GRADIENT_FROM_FOCUS, COLOR_LABEL_GRADIENT_TO_FOCUS, wxNORTH);
+ dc.GradientFillLinear(rect, COLOR_LABEL_GRADIENT_FROM_FOCUS, COLOR_LABEL_GRADIENT_TO_FOCUS, wxSOUTH);
else //regular background gradient
- dc.GradientFillLinear(rect, COLOR_LABEL_GRADIENT_FROM, COLOR_LABEL_GRADIENT_TO, wxNORTH); //clear overlapping cells
+ dc.GradientFillLinear(rect, COLOR_LABEL_GRADIENT_FROM, COLOR_LABEL_GRADIENT_TO, wxSOUTH); //clear overlapping cells
}
@@ -386,17 +376,17 @@ private:
{
const wxRect& clientRect = GetClientRect();
- dc.GradientFillLinear(clientRect, COLOR_LABEL_GRADIENT_FROM, COLOR_LABEL_GRADIENT_TO, wxNORTH);
+ dc.GradientFillLinear(clientRect, COLOR_LABEL_GRADIENT_FROM, COLOR_LABEL_GRADIENT_TO, wxSOUTH);
dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID));
{
- wxDCPenChanger dummy(dc, COLOR_LABEL_GRADIENT_TO);
+ wxDCPenChanger dummy(dc, COLOR_LABEL_GRADIENT_FROM);
dc.DrawLine(clientRect.GetTopLeft(), clientRect.GetTopRight());
}
- dc.GradientFillLinear(wxRect(clientRect.GetBottomLeft (), clientRect.GetTopLeft ()), dc.GetPen().GetColour(), COLOR_LABEL_GRADIENT_TO, wxNORTH);
- dc.GradientFillLinear(wxRect(clientRect.GetBottomRight(), clientRect.GetTopRight()), dc.GetPen().GetColour(), COLOR_LABEL_GRADIENT_TO, wxNORTH);
+ dc.GradientFillLinear(wxRect(clientRect.GetBottomLeft (), clientRect.GetTopLeft ()), COLOR_LABEL_GRADIENT_FROM, dc.GetPen().GetColour(), wxSOUTH);
+ dc.GradientFillLinear(wxRect(clientRect.GetBottomRight(), clientRect.GetTopRight()), COLOR_LABEL_GRADIENT_FROM, dc.GetPen().GetColour(), wxSOUTH);
dc.DrawLine(clientRect.GetBottomLeft(), clientRect.GetBottomRight());
@@ -492,7 +482,7 @@ private:
(Similar problem on Win 7: e.g. directly click sync button without comparing first)
*/
if (IsThisEnabled())
- clearArea(dc, rect, getColorMainWinBackground());
+ clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
else
clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
@@ -515,7 +505,7 @@ private:
void drawRowLabel(wxDC& dc, const wxRect& rect, size_t row)
{
//clearArea(dc, rect, getColorRowLabel());
- dc.GradientFillLinear(rect, COLOR_LABEL_GRADIENT_FROM, COLOR_LABEL_GRADIENT_TO, wxWEST); //clear overlapping cells
+ dc.GradientFillLinear(rect, COLOR_LABEL_GRADIENT_FROM, COLOR_LABEL_GRADIENT_TO, wxEAST); //clear overlapping cells
wxDCTextColourChanger dummy3(dc, *wxBLACK); //accessibility: always set both foreground AND background colors!
//label text
@@ -620,10 +610,11 @@ private:
virtual void render(wxDC& dc, const wxRect& rect)
{
if (IsThisEnabled())
- clearArea(dc, rect, getColorMainWinBackground());
+ clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
else
clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
+ //coordinate with "colLabelHeight" in Grid constructor:
wxFont labelFont = GetFont();
labelFont.SetWeight(wxFONTWEIGHT_BOLD);
dc.SetFont(labelFont);
@@ -666,9 +657,9 @@ private:
if (activeMove && activeMove->isRealMove() && activeMove->getComponentPos() == compPos)
{
if (col + 1 == activeMove->refColumnTo()) //handle pos 1, 2, .. up to "at end" position
- dc.GradientFillLinear(wxRect(rect.GetTopRight(), rect.GetBottomRight() + wxPoint(-2, 0)), *wxBLUE, COLOR_LABEL_GRADIENT_TO, wxNORTH);
+ dc.GradientFillLinear(wxRect(rect.GetTopRight(), rect.GetBottomRight() + wxPoint(-2, 0)), COLOR_LABEL_GRADIENT_FROM, *wxBLUE, wxSOUTH);
else if (col == activeMove->refColumnTo() && col == 0) //pos 0
- dc.GradientFillLinear(wxRect(rect.GetTopLeft(), rect.GetBottomLeft() + wxPoint(2, 0)), *wxBLUE, COLOR_LABEL_GRADIENT_TO, wxNORTH);
+ dc.GradientFillLinear(wxRect(rect.GetTopLeft(), rect.GetBottomLeft() + wxPoint(2, 0)), COLOR_LABEL_GRADIENT_FROM, *wxBLUE, wxSOUTH);
}
}
}
@@ -914,7 +905,7 @@ private:
virtual void render(wxDC& dc, const wxRect& rect)
{
if (IsThisEnabled())
- clearArea(dc, rect, getColorMainWinBackground());
+ clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
else
clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
@@ -944,10 +935,12 @@ private:
if (auto prov = refParent().getDataProvider(compPos))
{
//draw background lines
+ for (int row = rowFirst; row < rowLast; ++row)
{
- RecursiveDcClipper dummy2(dc, rect); //solve issues with drawBackground() painting in area outside of rect (which is not also refreshed by renderCell()) -> keep small scope!
- for (int row = rowFirst; row < rowLast; ++row)
- drawBackground(*prov, dc, wxRect(cellAreaTL + wxPoint(0, row * rowHeight), wxSize(compWidth, rowHeight)), row, compPos);
+ const wxRect rowRect(cellAreaTL + wxPoint(0, row * rowHeight), wxSize(compWidth, rowHeight));
+ RecursiveDcClipper dummy2(dc, rowRect); //solve issues with drawBackground() painting in area outside of rect
+ //(which is not also refreshed by renderCell()) -> keep small scope!
+ prov->renderRowBackgound(dc, rowRect, row, refParent().IsThisEnabled(), drawAsSelected(row, compPos));
}
//draw single cells, column by column
@@ -959,9 +952,10 @@ private:
if (cellAreaTL.x + cw.width_ > rect.x)
for (int row = rowFirst; row < rowLast; ++row)
{
- const wxRect& cellRect = wxRect(cellAreaTL.x, cellAreaTL.y + row * rowHeight, cw.width_, rowHeight);
+ const wxRect cellRect(cellAreaTL.x, cellAreaTL.y + row * rowHeight, cw.width_, rowHeight);
RecursiveDcClipper clip(dc, cellRect);
- prov->renderCell(refParent(), dc, cellRect, row, cw.type_);
+
+ prov->renderCell(dc, cellRect, row, cw.type_, drawAsSelected(row, compPos));
}
cellAreaTL.x += cw.width_;
}
@@ -971,21 +965,17 @@ private:
}
}
- void drawBackground(GridData& prov, wxDC& dc, const wxRect& rect, size_t row, size_t compPos)
+ bool drawAsSelected(size_t row, size_t compPos) const
{
- Grid& grid = refParent();
- //check if user is currently selecting with mouse
- bool drawSelection = grid.isSelected(row, compPos);
- if (activeSelection)
+ if (activeSelection) //check if user is currently selecting with mouse
{
const size_t rowFrom = std::min(activeSelection->getStartRow(), activeSelection->getCurrentRow());
const size_t rowTo = std::max(activeSelection->getStartRow(), activeSelection->getCurrentRow());
if (compPos == activeSelection->getComponentPos() && rowFrom <= row && row <= rowTo)
- drawSelection = activeSelection->isPositiveSelect(); //overwrite default
+ return activeSelection->isPositiveSelect(); //overwrite default
}
-
- prov.renderRowBackgound(dc, rect, row, grid.IsThisEnabled(), drawSelection, wxWindow::FindFocus() == &grid.getMainWin());
+ return refParent().isSelected(row, compPos);
}
virtual void onMouseLeftDown (wxMouseEvent& event) { onMouseDown(event); }
@@ -1423,20 +1413,28 @@ Grid::Grid(wxWindow* parent,
const wxString& name) : wxScrolledWindow(parent, id, pos, size, style | wxWANTS_CHARS, name),
showScrollbarX(SB_SHOW_AUTOMATIC),
showScrollbarY(SB_SHOW_AUTOMATIC),
- colLabelHeight(DEFAULT_COL_LABEL_HEIGHT),
+ colLabelHeight(0), //dummy init
drawRowLabel(true),
comp(1),
rowCountOld(0)
{
- Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), nullptr, this);
- Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), nullptr, this);
- Connect(wxEVT_SIZE, wxSizeEventHandler (Grid::onSizeEvent ), nullptr, this);
-
cornerWin_ = new CornerWin (*this); //
rowLabelWin_ = new RowLabelWin(*this); //owership handled by "this"
colLabelWin_ = new ColLabelWin(*this); //
mainWin_ = new MainWin (*this, *rowLabelWin_, *colLabelWin_); //
+ colLabelHeight = 2 * DEFAULT_COL_LABEL_BORDER + [&]() -> int
+ {
+ //coordinate with ColLabelWin::render():
+ wxFont labelFont = colLabelWin_->GetFont();
+ labelFont.SetWeight(wxFONTWEIGHT_BOLD);
+ return labelFont.GetPixelSize().GetHeight();
+ }();
+
+ Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), nullptr, this);
+ Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), nullptr, this);
+ Connect(wxEVT_SIZE, wxSizeEventHandler (Grid::onSizeEvent ), nullptr, this);
+
SetTargetWindow(mainWin_);
SetInitialSize(size); //"Most controls will use this to set their initial size" -> why not
@@ -1621,7 +1619,21 @@ void Grid::showRowLabel(bool show)
std::vector<size_t> Grid::getSelectedRows(size_t compPos) const
{
- return compPos < comp.size() ? comp[compPos].selection.get() : std::vector<size_t>();
+ if (compPos < comp.size())
+ return comp[compPos].selection.get();
+ assert(false);
+ return std::vector<size_t>();
+}
+
+
+void Grid::setSelectedRows(const std::vector<size_t>& sel, size_t compPos)
+{
+ if (compPos < comp.size())
+ {
+ comp[compPos].selection.set(sel);
+ Refresh();
+ }
+ else assert(false);
}
@@ -1665,10 +1677,13 @@ void Grid::Refresh(bool eraseBackground, const wxRect* rect)
if (rowCountOld != rowCountNew)
{
rowCountOld = rowCountNew;
- for (Component& c : comp)
- c.selection.init(rowCountNew);
updateWindowSizes();
}
+
+ for (Component& c : comp)
+ if (c.selection.size() != rowCountNew) //clear selection only when needed (consider setSelectedRows())
+ c.selection.init(rowCountNew);
+
wxScrolledWindow::Refresh(eraseBackground, rect);
}
bgstack15