summaryrefslogtreecommitdiff
path: root/wx+
diff options
context:
space:
mode:
Diffstat (limited to 'wx+')
-rw-r--r--wx+/button.cpp10
-rw-r--r--wx+/button.h8
-rw-r--r--wx+/context_menu.h8
-rw-r--r--wx+/file_drop.h4
-rw-r--r--wx+/format_unit.cpp12
-rw-r--r--wx+/format_unit.h2
-rw-r--r--wx+/graph.cpp26
-rw-r--r--wx+/graph.h22
-rw-r--r--wx+/grid.cpp466
-rw-r--r--wx+/grid.h64
-rw-r--r--wx+/mouse_move_dlg.cpp2
-rw-r--r--wx+/no_flicker.h4
-rw-r--r--wx+/pch.h2
-rw-r--r--wx+/serialize.h95
-rw-r--r--wx+/shell_execute.h6
-rw-r--r--wx+/timespan.h10
-rw-r--r--wx+/tooltip.cpp9
-rw-r--r--wx+/tooltip.h2
18 files changed, 366 insertions, 386 deletions
diff --git a/wx+/button.cpp b/wx+/button.cpp
index 9efdf071..1e9cb7f0 100644
--- a/wx+/button.cpp
+++ b/wx+/button.cpp
@@ -38,12 +38,12 @@ BitmapButton::BitmapButton(wxWindow* parent,
}
-void BitmapButton::setBitmapFront(const wxBitmap& bitmap, unsigned spaceAfter)
+void BitmapButton::setBitmapFront(const wxBitmap& bitmap, size_t spaceAfter)
{
if (!isEqual(bitmap, bitmapFront) || spaceAfter != m_spaceAfter) //avoid flicker
{
bitmapFront = bitmap;
- m_spaceAfter = spaceAfter;
+ m_spaceAfter = static_cast<unsigned int>(spaceAfter);
refreshButtonLabel();
}
}
@@ -60,12 +60,12 @@ void BitmapButton::setTextLabel(const wxString& text)
}
-void BitmapButton::setBitmapBack(const wxBitmap& bitmap, unsigned spaceBefore)
+void BitmapButton::setBitmapBack(const wxBitmap& bitmap, size_t spaceBefore)
{
if (!isEqual(bitmap, bitmapBack) || spaceBefore != m_spaceBefore) //avoid flicker
{
bitmapBack = bitmap;
- m_spaceBefore = spaceBefore;
+ m_spaceBefore = static_cast<unsigned int>(spaceBefore);
refreshButtonLabel();
}
}
@@ -106,7 +106,7 @@ wxSize getSizeNeeded(const wxString& text, wxFont& font)
wxString textFormatted = text;
textFormatted.Replace(wxT("&"), wxT(""), false); //remove accelerator
- dc.GetMultiLineTextExtent(textFormatted, &width, &height , NULL, &font);
+ dc.GetMultiLineTextExtent(textFormatted, &width, &height, nullptr, &font);
return wxSize(width, height);
}
diff --git a/wx+/button.h b/wx+/button.h
index 471a5b5a..bf741945 100644
--- a/wx+/button.h
+++ b/wx+/button.h
@@ -24,18 +24,18 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxButtonNameStr);
- void setBitmapFront(const wxBitmap& bitmap, unsigned spaceAfter = 0);
+ void setBitmapFront(const wxBitmap& bitmap, size_t spaceAfter = 0);
void setTextLabel( const wxString& text);
- void setBitmapBack( const wxBitmap& bitmap, unsigned spaceBefore = 0);
+ void setBitmapBack( const wxBitmap& bitmap, size_t spaceBefore = 0);
private:
wxBitmap createBitmapFromText(const wxString& text);
void refreshButtonLabel();
wxBitmap bitmapFront;
- unsigned m_spaceAfter;
+ unsigned int m_spaceAfter;
wxString textLabel;
- unsigned m_spaceBefore;
+ unsigned int m_spaceBefore;
wxBitmap bitmapBack;
};
diff --git a/wx+/context_menu.h b/wx+/context_menu.h
index 894da832..8f80fac2 100644
--- a/wx+/context_menu.h
+++ b/wx+/context_menu.h
@@ -27,12 +27,12 @@ namespace zen
class ContextMenu : private wxEvtHandler
{
public:
- void addItem(const wxString& label, const std::function<void()>& command, const wxBitmap* bmp = NULL, bool enabled = true)
+ void addItem(const wxString& label, const std::function<void()>& command, const wxBitmap* bmp = nullptr, bool enabled = true)
{
wxMenuItem* newItem = new wxMenuItem(&menu, wxID_ANY, label);
- if (bmp) newItem->SetBitmap(*bmp);
- if (!enabled) newItem->Enable(false);
- menu.Append(newItem); //do NOT append item before setting bitmap! wxWidgets screws up for yet another crappy reason
+ if (bmp) newItem->SetBitmap(*bmp); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason
+ menu.Append(newItem);
+ if (!enabled) newItem->Enable(false); //do not enable BEFORE appending item! wxWidgets screws up for yet another crappy reason
menu.Connect(newItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ContextMenu::onSelection), new GenericCommand(command), /*pass ownership*/ this);
}
diff --git a/wx+/file_drop.h b/wx+/file_drop.h
index c2a14423..0e9ba538 100644
--- a/wx+/file_drop.h
+++ b/wx+/file_drop.h
@@ -18,8 +18,8 @@ namespace zen
void setupFileDrop(wxWindow& wnd);
//2. register events:
-//wnd.Connect (EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), NULL, this);
-//wnd.Disconnect(EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), NULL, this);
+//wnd.Connect (EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), nullptr, this);
+//wnd.Disconnect(EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), nullptr, this);
//3. do something:
//void MyDlg::OnFilesDropped(FileDropEvent& event);
diff --git a/wx+/format_unit.cpp b/wx+/format_unit.cpp
index 0a054534..f6d2e5c2 100644
--- a/wx+/format_unit.cpp
+++ b/wx+/format_unit.cpp
@@ -35,7 +35,7 @@ std::wstring zen::filesizeToShortString(Int64 size)
if (numeric::abs(size) <= 999)
return replaceCpy(_P("1 Byte", "%x Bytes", to<int>(size)),
L"%x",
- toString<std::wstring>(size));
+ numberTo<std::wstring>(size));
else
{
double filesize = to<double>(size);
@@ -131,7 +131,7 @@ std::wstring zen::remainingTimeToShortString(double timeInSec)
output = _P("1 day", "%x days", formattedTime);
break;
}
- return replaceCpy(output, L"%x", zen::toString<std::wstring>(formattedTime));
+ return replaceCpy(output, L"%x", zen::numberTo<std::wstring>(formattedTime));
}
@@ -151,7 +151,7 @@ std::wstring zen::ffs_Impl::includeNumberSeparator(const std::wstring& number)
if (i <= 3)
break;
i -= 3;
- if (!cStringIsDigit(output[i - 1]))
+ if (!isDigit(output[i - 1]))
break;
output.insert(i, zen::getThousandsSeparator());
}
@@ -164,10 +164,10 @@ std::wstring zen::ffs_Impl::includeNumberSeparator(const std::wstring& number)
void zen::scrollToBottom(wxScrolledWindow* scrWindow)
{
int height = 0;
- scrWindow->GetClientSize(NULL, &height);
+ scrWindow->GetClientSize(nullptr, &height);
int pixelPerLine = 0;
- scrWindow->GetScrollPixelsPerUnit(NULL, &pixelPerLine);
+ scrWindow->GetScrollPixelsPerUnit(nullptr, &pixelPerLine);
if (height > 0 && pixelPerLine > 0)
{
@@ -203,7 +203,7 @@ std::wstring zen::utcToLocalTimeString(Int64 utcTime)
&systemTimeUtc)) //__out LPSYSTEMTIME lpSystemTime
return _("Error");
- if (!::SystemTimeToTzSpecificLocalTime(NULL, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone,
+ if (!::SystemTimeToTzSpecificLocalTime(nullptr, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone,
&systemTimeUtc, //__in LPSYSTEMTIME lpUniversalTime,
&systemTimeLocal)) //__out LPSYSTEMTIME lpLocalTime
return _("Error");
diff --git a/wx+/format_unit.h b/wx+/format_unit.h
index 361818cc..71501db7 100644
--- a/wx+/format_unit.h
+++ b/wx+/format_unit.h
@@ -57,7 +57,7 @@ std::wstring includeNumberSeparator(const std::wstring& number);
template <class NumberType> inline
std::wstring toStringSep(NumberType number)
{
- return ffs_Impl::includeNumberSeparator(zen::toString<std::wstring>(number));
+ return ffs_Impl::includeNumberSeparator(zen::numberTo<std::wstring>(number));
}
}
diff --git a/wx+/graph.cpp b/wx+/graph.cpp
index 7bbfa805..185121f1 100644
--- a/wx+/graph.cpp
+++ b/wx+/graph.cpp
@@ -20,6 +20,8 @@ using namespace numeric;
const wxEventType zen::wxEVT_GRAPH_SELECTION = wxNewEventType();
+const std::shared_ptr<LabelFormatter> Graph2D::GraphAttributes::defaultFormat = std::make_shared<DecimalNumberFormatter>(); //for some buggy reason MSVC isn't able to use a temporary as a default argument instead
+
namespace
{
inline
@@ -239,10 +241,10 @@ Graph2D::Graph2D(wxWindow* parent,
const wxString& name) :
wxPanel(parent, winid, pos, size, style, name)
{
- Connect(wxEVT_PAINT, wxPaintEventHandler(Graph2D::onPaintEvent), NULL, this);
- Connect(wxEVT_SIZE, wxEventHandler(Graph2D::onRefreshRequired), NULL, this);
+ Connect(wxEVT_PAINT, wxPaintEventHandler(Graph2D::onPaintEvent), nullptr, this);
+ Connect(wxEVT_SIZE, wxEventHandler(Graph2D::onRefreshRequired), nullptr, this);
//http://wiki.wxwidgets.org/Flicker-Free_Drawing
- Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Graph2D::onEraseBackGround), NULL, this);
+ Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Graph2D::onEraseBackGround), nullptr, this);
//SetDoubleBuffered(true); slow as hell!
@@ -252,10 +254,10 @@ Graph2D::Graph2D(wxWindow* parent,
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
#endif
- Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Graph2D::OnMouseLeftDown), NULL, this);
- Connect(wxEVT_MOTION, wxMouseEventHandler(Graph2D::OnMouseMovement), NULL, this);
- Connect(wxEVT_LEFT_UP, wxMouseEventHandler(Graph2D::OnMouseLeftUp), NULL, this);
- Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(Graph2D::OnMouseCaptureLost), NULL, this);
+ Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Graph2D::OnMouseLeftDown), nullptr, this);
+ Connect(wxEVT_MOTION, wxMouseEventHandler(Graph2D::OnMouseMovement), nullptr, this);
+ Connect(wxEVT_LEFT_UP, wxMouseEventHandler(Graph2D::OnMouseLeftUp), nullptr, this);
+ Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(Graph2D::OnMouseCaptureLost), nullptr, this);
}
@@ -483,11 +485,11 @@ void Graph2D::render(wxDC& dc) const
wxPoint currentPos = activeSel->refCurrentPos() - dataOrigin;
//normalize positions
- restrict(startPos .x, 0, dataArea.width); //allow for one past the end(!) to enable "full range selections"
- restrict(currentPos.x, 0, dataArea.width); //
+ confine(startPos .x, 0, dataArea.width); //allow for one past the end(!) to enable "full range selections"
+ confine(currentPos.x, 0, dataArea.width); //
- restrict(startPos .y, 0, dataArea.height); //
- restrict(currentPos.y, 0, dataArea.height); //
+ confine(startPos .y, 0, dataArea.height); //
+ confine(currentPos.y, 0, dataArea.height); //
//save current selection as double coordinates
activeSel->refSelection().from = SelectionBlock::Point(cvrtX.screenToReal(startPos.x + 0.5), //+0.5 start selection in the middle of a pixel
@@ -547,7 +549,7 @@ void Graph2D::render(wxDC& dc) const
if (!curve.empty())
{
dc.SetPen(wxPen(j->second.color, j->second.lineWidth));
- dc.DrawLines(curve.size(), &curve[0]);
+ dc.DrawLines(static_cast<int>(curve.size()), &curve[0]);
}
}
}
diff --git a/wx+/graph.h b/wx+/graph.h
index 19de4869..db52753b 100644
--- a/wx+/graph.h
+++ b/wx+/graph.h
@@ -93,12 +93,12 @@ double nextNiceNumber(double blockSize); //round to next number which is conveni
struct DecimalNumberFormatter : public LabelFormatter
{
virtual double getOptimalBlockSize(double sizeProposed) const { return nextNiceNumber(sizeProposed); }
- virtual wxString formatText(double value, double optimalBlockSize) const { return zen::toString<wxString>(value); }
+ virtual wxString formatText(double value, double optimalBlockSize) const { return zen::numberTo<wxString>(value); }
};
//------------------------------------------------------------------------------------------------------------
//emit data selection event
-//Usage: wnd.Connect(wxEVT_GRAPH_SELECTION, GraphSelectEventHandler(MyDlg::OnGraphSelection), NULL, this);
+//Usage: wnd.Connect(wxEVT_GRAPH_SELECTION, GraphSelectEventHandler(MyDlg::OnGraphSelection), nullptr, this);
// void MyDlg::OnGraphSelection(GraphSelectEvent& event);
@@ -154,14 +154,14 @@ public:
LineAttributes() : autoColor(true), lineWidth(2) {}
LineAttributes& setColor(const wxColour& col) { color = col; autoColor = false; return *this; }
- LineAttributes& setLineWidth(size_t width) { lineWidth = width; return *this; }
+ LineAttributes& setLineWidth(size_t width) { lineWidth = static_cast<int>(width); return *this; }
private:
friend class Graph2D;
bool autoColor;
wxColour color;
- size_t lineWidth;
+ int lineWidth;
};
void setData(const std::shared_ptr<GraphData>& data, const LineAttributes& attr = LineAttributes());
@@ -218,17 +218,19 @@ public:
GraphAttributes& setAutoSize() { minXauto = true; maxXauto = true; minYauto = true; maxYauto = true; return *this; }
- GraphAttributes& setLabelX(PosLabelX posX, size_t height = 25, const std::shared_ptr<LabelFormatter>& newLabelFmt = std::shared_ptr<LabelFormatter>(new DecimalNumberFormatter()))
+ static const std::shared_ptr<LabelFormatter> defaultFormat;
+
+ GraphAttributes& setLabelX(PosLabelX posX, size_t height = 25, const std::shared_ptr<LabelFormatter>& newLabelFmt = defaultFormat)
{
labelposX = posX;
- labelHeightX = height;
+ labelHeightX = static_cast<int>(height);
labelFmtX = newLabelFmt;
return *this;
}
- GraphAttributes& setLabelY(PosLabelY posY, size_t width = 60, const std::shared_ptr<LabelFormatter>& newLabelFmt = std::shared_ptr<LabelFormatter>(new DecimalNumberFormatter()))
+ GraphAttributes& setLabelY(PosLabelY posY, size_t width = 60, const std::shared_ptr<LabelFormatter>& newLabelFmt = defaultFormat)
{
labelposY = posY;
- labelWidthY = width;
+ labelWidthY = static_cast<int>(width);
labelFmtY = newLabelFmt;
return *this;
}
@@ -249,11 +251,11 @@ public:
double maxY;
PosLabelX labelposX;
- size_t labelHeightX;
+ int labelHeightX;
std::shared_ptr<LabelFormatter> labelFmtX;
PosLabelY labelposY;
- size_t labelWidthY;
+ int labelWidthY;
std::shared_ptr<LabelFormatter> labelFmtY;
SelMode mouseSelMode;
diff --git a/wx+/grid.cpp b/wx+/grid.cpp
index bfb08eb1..10e427ef 100644
--- a/wx+/grid.cpp
+++ b/wx+/grid.cpp
@@ -105,7 +105,7 @@ private:
//another fix for yet another poor wxWidgets implementation (wxDCClipper does *not* stack)
-hash_map<wxDC*, wxRect> clippingAreas;
+hash_map<wxDC*, wxRect> clippingAreas; //associate "active" clipping area with each DC
class DcClipper
{
@@ -132,7 +132,7 @@ public:
~DcClipper()
{
dc_.DestroyClippingRegion();
- if (oldRect.get() != NULL)
+ if (oldRect.get() != nullptr)
{
dc_.SetClippingRegion(*oldRect);
clippingAreas[&dc_] = *oldRect;
@@ -159,13 +159,13 @@ 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, int row, bool enabled, bool selected, bool hasFocus)
+void GridData::renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus)
{
drawCellBackground(dc, rect, enabled, selected, hasFocus, getColorMainWinBackground());
}
-void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, ColumnType colType)
+void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType)
{
wxRect rectTmp = drawCellBorder(dc, rect);
@@ -175,7 +175,7 @@ void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, Col
}
-size_t GridData::getBestSize(wxDC& dc, int row, ColumnType colType)
+size_t 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
}
@@ -283,10 +283,10 @@ public:
wxWindow(&parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBORDER_NONE, wxPanelNameStr),
parent_(parent)
{
- Connect(wxEVT_PAINT, wxPaintEventHandler(SubWindow::onPaintEvent), NULL, this);
- Connect(wxEVT_SIZE, wxEventHandler(SubWindow::onSizeEvent), NULL, this);
+ Connect(wxEVT_PAINT, wxPaintEventHandler(SubWindow::onPaintEvent), nullptr, this);
+ Connect(wxEVT_SIZE, wxEventHandler(SubWindow::onSizeEvent), nullptr, this);
//http://wiki.wxwidgets.org/Flicker-Free_Drawing
- Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(SubWindow::onEraseBackGround), NULL, this);
+ Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(SubWindow::onEraseBackGround), nullptr, this);
//SetDoubleBuffered(true); slow as hell!
@@ -296,28 +296,29 @@ public:
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
#endif
- Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(SubWindow::onFocus), NULL, this);
- Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(SubWindow::onFocus), NULL, this);
-
- Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(SubWindow::onMouseLeftDown ), NULL, this);
- Connect(wxEVT_LEFT_UP, wxMouseEventHandler(SubWindow::onMouseLeftUp ), NULL, this);
- Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(SubWindow::onMouseLeftDouble), NULL, this);
- Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(SubWindow::onMouseRightDown ), NULL, this);
- Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(SubWindow::onMouseRightUp ), NULL, this);
- Connect(wxEVT_MOTION, wxMouseEventHandler(SubWindow::onMouseMovement ), NULL, this);
- Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(SubWindow::onLeaveWindow ), NULL, this);
- Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(SubWindow::onMouseCaptureLost), NULL, this);
-
- Connect(wxEVT_CHAR, wxKeyEventHandler(SubWindow::onChar ), NULL, this);
- Connect(wxEVT_KEY_UP, wxKeyEventHandler(SubWindow::onKeyUp ), NULL, this);
- Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(SubWindow::onKeyDown), NULL, this);
+ Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(SubWindow::onFocus), nullptr, this);
+ Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(SubWindow::onFocus), nullptr, this);
+ Connect(wxEVT_CHILD_FOCUS, wxEventHandler(SubWindow::onChildFocus), nullptr, this);
+
+ Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(SubWindow::onMouseLeftDown ), nullptr, this);
+ Connect(wxEVT_LEFT_UP, wxMouseEventHandler(SubWindow::onMouseLeftUp ), nullptr, this);
+ Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(SubWindow::onMouseLeftDouble), nullptr, this);
+ Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(SubWindow::onMouseRightDown ), nullptr, this);
+ Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(SubWindow::onMouseRightUp ), nullptr, this);
+ Connect(wxEVT_MOTION, wxMouseEventHandler(SubWindow::onMouseMovement ), nullptr, this);
+ Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(SubWindow::onLeaveWindow ), nullptr, this);
+ Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(SubWindow::onMouseCaptureLost), nullptr, this);
+
+ Connect(wxEVT_CHAR, wxKeyEventHandler(SubWindow::onChar ), nullptr, this);
+ Connect(wxEVT_KEY_UP, wxKeyEventHandler(SubWindow::onKeyUp ), nullptr, this);
+ Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(SubWindow::onKeyDown), nullptr, this);
}
Grid& refParent() { return parent_; }
const Grid& refParent() const { return parent_; }
template <class T>
- bool sendEventNow(T& event) //return "true" if a suitable event handler function was found and executed, and the function did not call wxEvent::Skip.
+ bool sendEventNow(T&& event) //take both "rvalue + lvalues", return "true" if a suitable event handler function was found and executed, and the function did not call wxEvent::Skip.
{
if (wxEvtHandler* evtHandler = parent_.GetEventHandler())
return evtHandler->ProcessEvent(event);
@@ -333,7 +334,7 @@ protected:
if (text != oldText)
{
if (text.IsEmpty())
- SetToolTip(NULL); //wxGTK doesn't allow wxToolTip with empty text!
+ SetToolTip(nullptr); //wxGTK doesn't allow wxToolTip with empty text!
else
{
//wxWidgets bug: tooltip multiline property is defined by first tooltip text containing newlines or not (same is true for maximum width)
@@ -351,6 +352,7 @@ private:
virtual void render(wxDC& dc, const wxRect& rect) = 0;
virtual void onFocus(wxFocusEvent& event) { event.Skip(); }
+ virtual void onChildFocus(wxEvent& event) {} //wxGTK::wxScrolledWindow automatically scrolls to child window when child gets focus -> prevent!
virtual void onMouseLeftDown (wxMouseEvent& event) { event.Skip(); }
virtual void onMouseLeftUp (wxMouseEvent& event) { event.Skip(); }
@@ -437,51 +439,49 @@ public:
SubWindow(parent),
rowHeight(DEFAULT_ROW_HEIGHT) {}
- int getBestWidth(int rowFrom, int rowTo)
+ int getBestWidth(ptrdiff_t rowFrom, ptrdiff_t rowTo)
{
wxClientDC dc(this);
int bestWidth = 0;
- for (int i = rowFrom; i <= rowTo; ++i)
+ for (ptrdiff_t i = rowFrom; i <= rowTo; ++i)
bestWidth = std::max(bestWidth, dc.GetTextExtent(formatRow(i)).GetWidth() + 2 * ROW_LABEL_BORDER);
return bestWidth;
}
- int getLogicalHeight() const { return refParent().getRowCount() * rowHeight; }
+ size_t getLogicalHeight() const { return refParent().getRowCount() * rowHeight; }
- int getRowAtPos(int posY) const //returns < 0 if row not found
+ ptrdiff_t getRowAtPos(ptrdiff_t posY) const //returns < 0 if row not found
{
if (posY >= 0 && rowHeight > 0)
{
- const int row = posY / rowHeight;
- if (row < static_cast<int>(refParent().getRowCount()))
+ const size_t row = posY / rowHeight;
+ if (row < refParent().getRowCount())
return row;
}
return -1;
}
- int getRowHeight() const { return rowHeight; }
- void setRowHeight(int height) { rowHeight = height; }
+ ptrdiff_t getRowHeight() const { return std::max<ptrdiff_t>(1, rowHeight); } //guarantees to return size >= 1 !
+ void setRowHeight(size_t height) { rowHeight = height; }
- wxRect getRowLabelArea(int row) const //returns empty rect if row not found
+ wxRect getRowLabelArea(ptrdiff_t row) const
{
return wxRect(wxPoint(0, rowHeight * row),
wxSize(GetClientSize().GetWidth(), rowHeight));
}
- std::pair<int, int> getRowsOnClient(const wxRect& clientRect) const //returns range [begin, end)
+ std::pair<ptrdiff_t, ptrdiff_t> getRowsOnClient(const wxRect& clientRect) const //returns range [begin, end)
{
const int yFrom = refParent().CalcUnscrolledPosition(clientRect.GetTopLeft ()).y;
const int yTo = refParent().CalcUnscrolledPosition(clientRect.GetBottomRight()).y;
- const int rowBegin = std::max(yFrom / rowHeight, 0);
- const int rowEnd = std::min((yTo / rowHeight) + 1, static_cast<int>(refParent().getRowCount()));
-
- return std::make_pair(rowBegin, rowEnd);
+ return std::make_pair(std::max<ptrdiff_t>(yFrom / rowHeight, 0),
+ std::min<ptrdiff_t>((yTo / rowHeight) + 1, refParent().getRowCount()));
}
private:
- static wxString formatRow(int row) { return toStringSep(row + 1); } //convert number to std::wstring including thousands separator
+ static wxString formatRow(size_t row) { return toStringSep(row + 1); } //convert number to std::wstring including thousands separator
virtual bool AcceptsFocus() const { return false; }
@@ -497,9 +497,8 @@ private:
dc.SetFont(labelFont);
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
- const std::pair<int, int> rowRange = getRowsOnClient(rect); //returns range [begin, end)
-
- for (int row = rowRange.first; row < rowRange.second; ++row)
+ auto rowRange = getRowsOnClient(rect); //returns range [begin, end)
+ for (auto row = rowRange.first; row < rowRange.second; ++row)
{
wxRect singleLabelArea = getRowLabelArea(row);
if (singleLabelArea.GetHeight() > 0)
@@ -510,7 +509,7 @@ private:
}
}
- void drawRowLabel(wxDC& dc, const wxRect& rect, int row)
+ 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
@@ -540,7 +539,7 @@ private:
virtual void onMouseMovement(wxMouseEvent& event) { refParent().redirectRowLabelEvent(event); }
virtual void onMouseLeftUp (wxMouseEvent& event) { refParent().redirectRowLabelEvent(event); }
- int rowHeight;
+ ptrdiff_t rowHeight;
};
@@ -549,7 +548,7 @@ namespace
class ColumnResizing
{
public:
- ColumnResizing(wxWindow& wnd, int col, size_t compPos, int startWidth, int clientPosX) :
+ ColumnResizing(wxWindow& wnd, size_t col, size_t compPos, ptrdiff_t startWidth, int clientPosX) :
wnd_(wnd),
col_(col),
compPos_(compPos),
@@ -557,24 +556,24 @@ public:
clientPosX_(clientPosX) { wnd_.CaptureMouse(); }
~ColumnResizing() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); }
- int getColumn () const { return col_; }
- size_t getComponentPos() const { return compPos_; }
- int getStartWidth () const { return startWidth_; }
- int getStartPosX () const { return clientPosX_; }
+ size_t getColumn () const { return col_; }
+ size_t getComponentPos() const { return compPos_; }
+ ptrdiff_t getStartWidth () const { return startWidth_; }
+ int getStartPosX () const { return clientPosX_; }
private:
wxWindow& wnd_;
- const int col_;
- const size_t compPos_;
- const int startWidth_;
- const int clientPosX_;
+ const size_t col_;
+ const size_t compPos_;
+ const ptrdiff_t startWidth_;
+ const int clientPosX_;
};
class ColumnMove
{
public:
- ColumnMove(wxWindow& wnd, int colFrom, size_t compPos, int clientPosX) :
+ ColumnMove(wxWindow& wnd, size_t colFrom, size_t compPos, int clientPosX) :
wnd_(wnd),
colFrom_(colFrom),
compPos_(compPos),
@@ -583,19 +582,19 @@ public:
singleClick_(true) { wnd_.CaptureMouse(); }
~ColumnMove() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); }
- int getColumnFrom() const { return colFrom_; }
- int& refColumnTo() { return colTo_; }
- size_t getComponentPos() const { return compPos_; }
- int getStartPosX () const { return clientPosX_; }
+ size_t getColumnFrom() const { return colFrom_; }
+ size_t& refColumnTo() { return colTo_; }
+ size_t getComponentPos() const { return compPos_; }
+ int getStartPosX () const { return clientPosX_; }
bool isRealMove() const { return !singleClick_; }
- bool setRealMove() { return singleClick_ = false; }
+ void setRealMove() { singleClick_ = false; }
private:
wxWindow& wnd_;
- const int colFrom_;
+ const size_t colFrom_;
const size_t compPos_;
- int colTo_;
+ size_t colTo_;
const int clientPosX_;
bool singleClick_;
};
@@ -607,7 +606,7 @@ private:
class Grid::ColLabelWin : public SubWindow
{
public:
- ColLabelWin(Grid& parent) : SubWindow(parent), highlight(-1, 0) {}
+ ColLabelWin(Grid& parent) : SubWindow(parent) {}
private:
virtual bool AcceptsFocus() const { return false; }
@@ -643,13 +642,14 @@ private:
}
}
- void drawColumnLabel(wxDC& dc, const wxRect& rect, int col, ColumnType colType, size_t compPos)
+ void drawColumnLabel(wxDC& dc, const wxRect& rect, size_t col, ColumnType colType, size_t compPos)
{
if (auto dataView = refParent().getDataProvider(compPos))
{
const bool isHighlighted = activeResizing ? col == activeResizing->getColumn () && compPos == activeResizing->getComponentPos() : //highlight column on mouse-over
activeMove ? col == activeMove ->getColumnFrom() && compPos == activeMove ->getComponentPos() :
- /**/ col == highlight.first && compPos == highlight.second;
+ highlight ? col == highlight->first && compPos == highlight->second :
+ false;
DcClipper clip(dc, rect);
dataView->renderColumnLabel(refParent(), dc, rect, colType, isHighlighted);
@@ -680,9 +680,9 @@ private:
{
if (event.LeftDClick()) //auto-size visible range on double-click
{
- const int bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error
+ const auto bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error
if (bestWidth >= 0)
- refParent().setColWidth(action->col, action->compPos, std::max(COLUMN_MIN_WIDTH, bestWidth));
+ refParent().setColWidth(action->col, action->compPos, std::max<ptrdiff_t>(COLUMN_MIN_WIDTH, bestWidth));
}
else
{
@@ -707,8 +707,8 @@ private:
{
if (refParent().columnMoveAllowed(compPos))
{
- const int colFrom = activeMove->getColumnFrom();
- int colTo = activeMove->refColumnTo();
+ const auto colFrom = activeMove->getColumnFrom();
+ auto colTo = activeMove->refColumnTo();
if (colTo > colFrom) //simulate "colFrom" deletion
--colTo;
@@ -718,12 +718,8 @@ private:
}
else //notify single label click
{
- const Opt<ColumnType> colType = refParent().colToType(activeMove->getColumnFrom(), compPos);
- if (colType)
- {
- GridClickEvent clickEvent(EVENT_GRID_COL_LABEL_MOUSE_LEFT, event, -1, *colType, compPos);
- sendEventNow(clickEvent);
- }
+ if (const Opt<ColumnType> colType = refParent().colToType(activeMove->getColumnFrom(), compPos))
+ sendEventNow(GridClickEvent(EVENT_GRID_COL_LABEL_MOUSE_LEFT, event, -1, *colType, compPos));
}
activeMove.reset();
}
@@ -747,19 +743,14 @@ private:
if (action && action->wantResize)
{
//auto-size visible range on double-click
- const int bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error
+ const auto bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error
if (bestWidth >= 0)
{
- const size_t newWidth = std::max(COLUMN_MIN_WIDTH, bestWidth);
+ const auto newWidth = std::max<ptrdiff_t>(COLUMN_MIN_WIDTH, bestWidth);
refParent().setColWidth(action->col, action->compPos, newWidth);
- const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos);
- if (colType)
- {
- //notify column resize
- GridColumnResizeEvent sizeEvent(newWidth, *colType, action->compPos);
- sendEventNow(sizeEvent);
- }
+ if (const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos))
+ sendEventNow(GridColumnResizeEvent(newWidth, *colType, action->compPos)); //notify column resize
}
}
event.Skip();
@@ -769,23 +760,18 @@ private:
{
if (activeResizing)
{
- const int col = activeResizing->getColumn();
- const size_t compPos = activeResizing->getComponentPos();
+ const auto col = activeResizing->getColumn();
+ const auto compPos = activeResizing->getComponentPos();
if (Opt<size_t> colWidth = refParent().getAbsoluteWidth(col, compPos))
{
- const int newWidth = std::max(COLUMN_MIN_WIDTH, activeResizing->getStartWidth() + event.GetPosition().x - activeResizing->getStartPosX());
- if (newWidth != static_cast<int>(*colWidth))
+ const size_t newWidth = std::max<ptrdiff_t>(COLUMN_MIN_WIDTH, activeResizing->getStartWidth() + event.GetPosition().x - activeResizing->getStartPosX());
+ if (newWidth != *colWidth)
{
refParent().setColWidth(col, compPos, newWidth);
- const Opt<ColumnType> colType = refParent().colToType(col, compPos);
- if (colType)
- {
- //notify column resize
- GridColumnResizeEvent sizeEvent(newWidth, *colType, compPos);
- sendEventNow(sizeEvent);
- }
+ if (const Opt<ColumnType> colType = refParent().colToType(col, compPos))
+ sendEventNow(GridColumnResizeEvent(static_cast<int>(newWidth), *colType, compPos)); //notify column resize
refParent().Refresh();
}
@@ -798,18 +784,16 @@ private:
{
activeMove->setRealMove();
- const int col = refParent().clientPosToMoveTargetColumn(event.GetPosition(), activeMove->getComponentPos());
+ const auto col = refParent().clientPosToMoveTargetColumn(event.GetPosition(), activeMove->getComponentPos());
if (col >= 0)
activeMove->refColumnTo() = col;
}
}
else
{
- const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition());
- if (action)
+ if (const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition()))
{
- highlight.first = action->col;
- highlight.second = action->compPos;
+ highlight.reset(new std::pair<size_t, size_t>(action->col, action->compPos));
if (action->wantResize)
SetCursor(wxCURSOR_SIZEWE); //set window-local only! :)
@@ -818,21 +802,18 @@ private:
}
else
{
- highlight.first = -1;
+ highlight.reset();
SetCursor(*wxSTANDARD_CURSOR);
}
}
- //change tooltip
+ //update tooltip
const wxString toolTip = [&]() -> wxString
{
const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition());
-
- const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found
- if (colInfo)
+ if (const auto colInfo = refParent().getColumnAtPos(absPos.x)) //returns (column type, compPos)
{
- auto prov = refParent().getDataProvider(colInfo->second);
- if (prov)
+ if (auto prov = refParent().getDataProvider(colInfo->second))
return prov->getToolTip(colInfo->first);
}
return wxString();
@@ -845,30 +826,24 @@ private:
virtual void onLeaveWindow(wxMouseEvent& event)
{
- highlight.first = -1; //onLeaveWindow() does not respect mouse capture! -> however highlight is drawn unconditionally during move/resize!
+ highlight.reset(); //onLeaveWindow() does not respect mouse capture! -> however highlight is drawn unconditionally during move/resize!
Refresh();
event.Skip();
}
virtual void onMouseRightDown(wxMouseEvent& event)
{
- const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition());
- if (action)
+ if (const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition()))
{
- const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos);
- if (colType)
- {
- //notify right click
- GridClickEvent clickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, event, -1, *colType, action->compPos);
- sendEventNow(clickEvent);
- }
+ if (const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos))
+ sendEventNow(GridClickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, event, -1, *colType, action->compPos)); //notify right click
}
event.Skip();
}
std::unique_ptr<ColumnResizing> activeResizing;
std::unique_ptr<ColumnMove> activeMove;
- std::pair<int, size_t> highlight; //(column, component) mouse-over, row < 0 if none
+ std::unique_ptr<std::pair<size_t, size_t>> highlight; //(column, component) mouse-over
};
//----------------------------------------------------------------------------------------------------------------
@@ -882,19 +857,18 @@ public:
ColLabelWin& colLabelWin) : SubWindow(parent),
rowLabelWin_(rowLabelWin),
colLabelWin_(colLabelWin),
- cursor(-1, -1),
- selectionAnchor(-1) {}
+ selectionAnchor(0) {}
- void makeRowVisible(int row)
+ void makeRowVisible(size_t row)
{
const wxRect labelRect = rowLabelWin_.getRowLabelArea(row); //returns empty rect if column not found
if (labelRect.height > 0)
{
int scrollPosX = 0;
- refParent().GetViewStart(&scrollPosX, NULL);
+ refParent().GetViewStart(&scrollPosX, nullptr);
int pixelsPerUnitY = 0;
- refParent().GetScrollPixelsPerUnit(NULL, &pixelsPerUnitY);
+ refParent().GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY);
if (pixelsPerUnitY <= 0) return;
const int clientPosY = refParent().CalcScrolledPosition(labelRect.GetTopLeft()).y;
@@ -925,12 +899,12 @@ public:
}
}
- void setCursor(int row, size_t compPos)
+ void setCursor(size_t row, size_t compPos)
{
cursor = std::make_pair(row, compPos);
selectionAnchor = row;
}
- std::pair<int, size_t> getCursor() const { return cursor; } // (row, component position)
+ std::pair<size_t, size_t> getCursor() const { return cursor; } // (row, component position)
private:
virtual void render(wxDC& dc, const wxRect& rect)
@@ -956,8 +930,8 @@ private:
std::vector<std::vector<VisibleColumn>> compAbsWidths = refParent().getAbsoluteWidths(); //resolve negative/stretched widths
for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp)
{
- const int compWidth = std::accumulate(iterComp->begin(), iterComp->end(), 0,
- [](int val, const VisibleColumn& vc) { return val + vc.width_; });
+ const ptrdiff_t compWidth = std::accumulate(iterComp->begin(), iterComp->end(), static_cast<ptrdiff_t>(0),
+ [](ptrdiff_t sum, const VisibleColumn& vc) { return sum + vc.width_; });
const size_t compPos = iterComp - compAbsWidths.begin();
if (auto prov = refParent().getDataProvider(compPos))
@@ -1017,14 +991,9 @@ private:
virtual void onMouseLeftDouble(wxMouseEvent& event)
{
const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition());
- const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
- const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found
- if (colInfo)
- {
- //notify event
- GridClickEvent mouseEvent(EVENT_GRID_MOUSE_LEFT_DOUBLE, event, row, colInfo->first, colInfo->second);
- sendEventNow(mouseEvent);
- }
+ const auto row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
+ if (const auto colInfo = refParent().getColumnAtPos(absPos.x)) //returns (column type, compPos)
+ sendEventNow(GridClickEvent(EVENT_GRID_MOUSE_LEFT_DOUBLE, event, row, colInfo->first, colInfo->second));
event.Skip();
}
@@ -1035,10 +1004,10 @@ private:
const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition());
- const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
- const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found
+ const ptrdiff_t row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
+ const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos)
const ColumnType colType = colInfo ? colInfo->first : DUMMY_COLUMN_TYPE;
- const int compPos = colInfo ? colInfo->second : -1;
+ const ptrdiff_t compPos = colInfo ? colInfo->second : -1;
//notify event
GridClickEvent mouseEvent(event.RightDown() ? EVENT_GRID_MOUSE_RIGHT_DOWN : EVENT_GRID_MOUSE_LEFT_DOWN, event, row, colType, compPos);
@@ -1053,26 +1022,28 @@ private:
{
if (row >= 0 && compPos >= 0)
activeSelection.reset(new MouseSelection(*this, row, compPos, !refParent().isSelected(row, compPos)));
- selectionAnchor = row;
+ selectionAnchor = cursor.first; //[!] anchor is coupled with cursor, *not* row
}
else if (event.ShiftDown())
{
if (row >= 0 && compPos >= 0)
activeSelection.reset(new MouseSelection(*this, selectionAnchor, compPos, true));
+ else
+ selectionAnchor = cursor.first;
refParent().clearSelectionAll();
}
else
{
if (row >= 0 && compPos >= 0)
activeSelection.reset(new MouseSelection(*this, row, compPos, true));
- selectionAnchor = row;
+ selectionAnchor = cursor.first;
refParent().clearSelectionAll();
}
}
Refresh();
}
- event.Skip(); //allow changin focus
+ event.Skip(); //allow changing focus
}
void onMouseUp(wxMouseEvent& event)
@@ -1081,10 +1052,10 @@ private:
if (activeSelection)
{
- const int rowFrom = activeSelection->getStartRow();
- const int rowTo = activeSelection->getCurrentRow();
- const size_t compPos = activeSelection->getComponentPos();
- const bool positive = activeSelection->isPositiveSelect();
+ const auto rowFrom = activeSelection->getStartRow();
+ const auto rowTo = activeSelection->getCurrentRow();
+ const auto compPos = activeSelection->getComponentPos();
+ const bool positive = activeSelection->isPositiveSelect();
refParent().selectRange(rowFrom, rowTo, compPos, positive);
cursor.first = activeSelection->getCurrentRow(); //slight deviation from Explorer: change cursor while dragging mouse! -> unify behavior with shift + direction keys
@@ -1095,15 +1066,14 @@ private:
//this one may point to row which is not in visible area!
const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition());
- const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
- const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found
+ const auto row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
+ const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns optional pair (column type, compPos)
const ColumnType colType = colInfo ? colInfo->first : DUMMY_COLUMN_TYPE; //we probably should notify even if colInfo is invalid!
- const int compPos = colInfo ? colInfo->second : 0;
+ const size_t compPos = colInfo ? colInfo->second : 0;
//notify event
- GridClickEvent mouseEvent(event.RightUp() ? EVENT_GRID_MOUSE_RIGHT_UP : EVENT_GRID_MOUSE_LEFT_UP, event, row, colType, compPos);
- sendEventNow(mouseEvent);
+ sendEventNow(GridClickEvent(event.RightUp() ? EVENT_GRID_MOUSE_RIGHT_UP : EVENT_GRID_MOUSE_LEFT_UP, event, row, colType, compPos));
Refresh();
event.Skip(); //allow changing focus
@@ -1126,12 +1096,11 @@ private:
{
const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition());
- const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
- const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found
+ const auto row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
+ const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos)
if (colInfo && row >= 0)
{
- auto prov = refParent().getDataProvider(colInfo->second);
- if (prov)
+ if (auto prov = refParent().getDataProvider(colInfo->second))
return prov->getToolTip(row, colInfo->first);
}
return wxString();
@@ -1157,27 +1126,33 @@ private:
keyCode = WXK_NUMPAD_LEFT;
}
- const int rowCount = refParent().getRowCount();
+ const ptrdiff_t rowCount = refParent().getRowCount();
+ if (rowCount <= 0 || refParent().comp.empty())
+ {
+ event.Skip();
+ return;
+ }
- auto setSingleSelection = [&](int row, int compPos)
+ auto setSingleSelection = [&](ptrdiff_t row, ptrdiff_t compPos)
{
- numeric::restrict(row, 0, rowCount - 1);
- numeric::restrict(compPos, 0, static_cast<int>(refParent().comp.size()) - 1);
- refParent().setGridCursor(row, compPos);
+ numeric::confine<ptrdiff_t>(row, 0, rowCount - 1);
+ numeric::confine<ptrdiff_t>(compPos, 0, refParent().comp.size() - 1);
+ refParent().setGridCursor(row, compPos); //behave like an "external" set cursor!
};
- auto setSelectionRange = [&](int row)
+ auto setSelectionRange = [&](ptrdiff_t row)
{
- numeric::restrict(row, 0, rowCount - 1);
+ //unlike "setSingleSelection" this function doesn't seem to belong into Grid: management of selectionAnchor should be local
- cursor.first = row;
- if (selectionAnchor < 0)
- selectionAnchor = row;
- this->makeRowVisible(row);
+ numeric::confine<ptrdiff_t>(row, 0, rowCount - 1);
auto& comp = refParent().comp;
std::for_each(comp.begin(), comp.end(), [](Grid::Component& c) { c.selection.clear(); }); //clear selection, do NOT fire event
refParent().selectRange(selectionAnchor, row, cursor.second); //set new selection + fire event
+
+ cursor.first = row; //don't call setCursor() since it writes to "selectionAnchor"!
+ this->makeRowVisible(row);
+ refParent().Refresh();
};
switch (keyCode)
@@ -1190,7 +1165,7 @@ private:
refParent().scrollDelta(0, -1);
else
setSingleSelection(cursor.first - 1, cursor.second);
- break;
+ return; //swallow event: wxScrolledWindow, wxWidgets 2.9.3 on Kubuntu x64 processes arrow keys: prevent this!
case WXK_DOWN:
case WXK_NUMPAD_DOWN:
@@ -1200,7 +1175,7 @@ private:
refParent().scrollDelta(0, 1);
else
setSingleSelection(cursor.first + 1, cursor.second);
- break;
+ return; //swallow event
case WXK_LEFT:
case WXK_NUMPAD_LEFT:
@@ -1210,7 +1185,7 @@ private:
;
else
setSingleSelection(cursor.first, cursor.second - 1);
- break;
+ return;
case WXK_RIGHT:
case WXK_NUMPAD_RIGHT:
@@ -1220,7 +1195,7 @@ private:
;
else
setSingleSelection(cursor.first, cursor.second + 1);
- break;
+ return;
case WXK_HOME:
case WXK_NUMPAD_HOME:
@@ -1230,7 +1205,7 @@ private:
setSingleSelection(0, 0);
else
setSingleSelection(0, cursor.second);
- break;
+ return;
case WXK_END:
case WXK_NUMPAD_END:
@@ -1240,7 +1215,7 @@ private:
setSingleSelection(rowCount - 1, refParent().comp.size() - 1);
else
setSingleSelection(rowCount - 1, cursor.second);
- break;
+ return;
case WXK_PAGEUP:
case WXK_NUMPAD_PAGEUP:
@@ -1250,7 +1225,7 @@ private:
;
else
setSingleSelection(cursor.first - GetClientSize().GetHeight() / rowLabelWin_.getRowHeight(), cursor.second);
- break;
+ return;
case WXK_PAGEDOWN:
case WXK_NUMPAD_PAGEDOWN:
@@ -1260,7 +1235,7 @@ private:
;
else
setSingleSelection(cursor.first + GetClientSize().GetHeight() / rowLabelWin_.getRowHeight(), cursor.second);
- break;
+ return;
case 'A': //Ctrl + A - select all
if (event.ControlDown())
@@ -1270,10 +1245,9 @@ private:
case WXK_NUMPAD_ADD: //CTRL + '+' - auto-size all
if (event.ControlDown())
refParent().autoSizeColumns(cursor.second);
- break;
+ return;
}
- Refresh();
event.Skip();
}
@@ -1282,26 +1256,24 @@ private:
class MouseSelection : private wxEvtHandler
{
public:
- MouseSelection(MainWin& wnd,
- int rowStart,
- size_t compPos,
- bool positiveSelect) : wnd_(wnd), rowStart_(rowStart), compPos_(compPos), rowCurrent_(rowStart), positiveSelect_(positiveSelect), toScrollX(0), toScrollY(0), tickCountLast(clock())
+ MouseSelection(MainWin& wnd, ptrdiff_t rowStart, size_t compPos, bool positiveSelect) :
+ wnd_(wnd), rowStart_(rowStart), compPos_(compPos), rowCurrent_(rowStart), positiveSelect_(positiveSelect), toScrollX(0), toScrollY(0), tickCountLast(clock())
{
wnd_.CaptureMouse();
- timer.Connect(wxEVT_TIMER, wxEventHandler(MouseSelection::onTimer), NULL, this);
+ timer.Connect(wxEVT_TIMER, wxEventHandler(MouseSelection::onTimer), nullptr, this);
timer.Start(100); //timer interval in ms
evalMousePos();
}
~MouseSelection() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); }
- int getStartRow () const { return rowStart_; }
- size_t getComponentPos () const { return compPos_; }
- int getCurrentRow () const { return rowCurrent_; }
- bool isPositiveSelect() const { return positiveSelect_; } //are we selecting or unselecting?
+ ptrdiff_t getStartRow () const { return rowStart_; }
+ size_t getComponentPos () const { return compPos_; }
+ ptrdiff_t getCurrentRow () const { return rowCurrent_; }
+ bool isPositiveSelect() const { return positiveSelect_; } //are we selecting or unselecting?
void evalMousePos()
{
- const clock_t now = clock();
+ const clock_t now = std::clock();
const double deltaTime = static_cast<double>(now - tickCountLast) / CLOCKS_PER_SEC; //unit: [sec]
tickCountLast = now;
@@ -1316,7 +1288,7 @@ private:
clientPos.x >= clientSize.GetWidth() ? clientPos.x - (clientSize.GetWidth() - 1) : 0;
int pixelsPerUnitY = 0;
- wnd_.refParent().GetScrollPixelsPerUnit(NULL, &pixelsPerUnitY);
+ wnd_.refParent().GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY);
if (pixelsPerUnitY <= 0) return;
const double mouseDragSpeedIncScrollU = pixelsPerUnitY > 0 ? MOUSE_DRAG_ACCELERATION * wnd_.rowLabelWin_.getRowHeight() / pixelsPerUnitY : 0; //unit: [scroll units / (pixel * sec)]
@@ -1345,14 +1317,14 @@ private:
{
//select current row *after* scrolling
wxPoint clientPosTrimmed = clientPos;
- numeric::restrict(clientPosTrimmed.y, 0, clientSize.GetHeight() - 1); //do not select row outside client window!
+ numeric::confine(clientPosTrimmed.y, 0, clientSize.GetHeight() - 1); //do not select row outside client window!
wxPoint absPos = wnd_.refParent().CalcUnscrolledPosition(clientPosTrimmed);
- int currentRow = wnd_.rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
//make sure "current row" is always at a valid position while moving!
+ ptrdiff_t currentRow = wnd_.rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position
if (currentRow < 0)
- currentRow = static_cast<int>(wnd_.refParent().getRowCount()) - 1; //seems, we hit the empty space at the end
+ currentRow = wnd_.refParent().getRowCount() - 1; //seems, we hit the empty space at the end: empty size covered!
if (currentRow >= 0 && rowCurrent_ != currentRow)
{
@@ -1366,9 +1338,9 @@ private:
void onTimer(wxEvent& event) { evalMousePos(); }
MainWin& wnd_;
- const int rowStart_;
+ const ptrdiff_t rowStart_;
const size_t compPos_;
- int rowCurrent_;
+ ptrdiff_t rowCurrent_;
const bool positiveSelect_;
wxTimer timer;
double toScrollX; //count outstanding scroll units to scroll while dragging mouse
@@ -1391,8 +1363,8 @@ private:
std::unique_ptr<MouseSelection> activeSelection; //bound while user is selecting with mouse
- std::pair<int, int> cursor; //(row, component position) -1 if none
- int selectionAnchor; //-1 if none
+ std::pair<ptrdiff_t, ptrdiff_t> cursor; //(row, component position), always valid! still unsigned type to facilitate "onKeyDown()"
+ size_t selectionAnchor;
};
//----------------------------------------------------------------------------------------------------------------
@@ -1411,9 +1383,9 @@ Grid::Grid(wxWindow* parent,
comp(1),
colSizeOld(0)
{
- Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), NULL, this);
- Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), NULL, this);
- Connect(wxEVT_SIZE, wxEventHandler (Grid::onSizeEvent ), NULL, this);
+ Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), nullptr, this);
+ Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), nullptr, this);
+ Connect(wxEVT_SIZE, wxEventHandler (Grid::onSizeEvent ), nullptr, this);
cornerWin_ = new CornerWin (*this); //
rowLabelWin_ = new RowLabelWin(*this); //owership handled by "this"
@@ -1440,7 +1412,6 @@ void Grid::updateWindowSizes(bool updateScrollbar)
GetClientRect(); -> possibly trimmed by scrollbars
/|\
mainWin_->GetClientSize() -> also trimmed, since it's a sub-window !
-
*/
//update scrollbars: showing/hiding scrollbars changes client size!
@@ -1454,7 +1425,7 @@ void Grid::updateWindowSizes(bool updateScrollbar)
int scrollPosY = 0;
GetViewStart(&scrollPosX, &scrollPosY); //preserve current scroll position
- const int pixPerScrollUnitY = std::max(1, rowLabelWin_->getRowHeight());
+ const int pixPerScrollUnitY = rowLabelWin_->getRowHeight();
const int pixPerScrollUnitX = pixPerScrollUnitY;
const int scrollUnitsX = std::ceil(static_cast<double>( getMinAbsoluteWidthTotal()) / pixPerScrollUnitX);
@@ -1462,7 +1433,7 @@ void Grid::updateWindowSizes(bool updateScrollbar)
SetScrollbars(pixPerScrollUnitX, pixPerScrollUnitY, //another abysmal wxWidgets design decision: why is precision needlessly reduced to "pixelsPerUnit"????
scrollUnitsX, scrollUnitsY,
- scrollPosX, scrollPosY);
+ scrollPosX, scrollPosY);
}
const wxRect clientRect = GetClientRect();
@@ -1472,16 +1443,16 @@ void Grid::updateWindowSizes(bool updateScrollbar)
int rowLabelWidth = 0; //calculate optimal row label width
if (drawRowLabel)
{
- const int heightTotal = rowLabelWin_->getLogicalHeight();
+ const auto heightTotal = rowLabelWin_->getLogicalHeight();
if (heightTotal > 0)
{
- int yFrom = CalcUnscrolledPosition(wxPoint(0, 0)).y;
- int yTo = CalcUnscrolledPosition(wxPoint(0, mainWinHeight - 1)).y ;
- numeric::restrict(yFrom, 0, heightTotal - 1);
- numeric::restrict(yTo, 0, heightTotal - 1);
+ ptrdiff_t yFrom = CalcUnscrolledPosition(wxPoint(0, 0)).y;
+ ptrdiff_t yTo = CalcUnscrolledPosition(wxPoint(0, mainWinHeight - 1)).y ;
+ numeric::confine<ptrdiff_t>(yFrom, 0, heightTotal - 1);
+ numeric::confine<ptrdiff_t>(yTo, 0, heightTotal - 1);
- const int rowFrom = rowLabelWin_->getRowAtPos(yFrom);
- const int rowTo = rowLabelWin_->getRowAtPos(yTo);
+ const ptrdiff_t rowFrom = rowLabelWin_->getRowAtPos(yFrom);
+ const ptrdiff_t rowTo = rowLabelWin_->getRowAtPos(yTo);
if (rowFrom >= 0 && rowTo >= 0)
rowLabelWidth = rowLabelWin_->getBestWidth(rowFrom, rowTo);
}
@@ -1513,9 +1484,9 @@ void Grid::showRowLabel(bool show)
}
-std::vector<int> Grid::getSelectedRows(size_t compPos) const
+std::vector<size_t> Grid::getSelectedRows(size_t compPos) const
{
- return compPos < comp.size() ? comp[compPos].selection.get() : std::vector<int>();
+ return compPos < comp.size() ? comp[compPos].selection.get() : std::vector<size_t>();
}
@@ -1532,8 +1503,8 @@ void Grid::scrollDelta(int deltaX, int deltaY)
//const int unitsTotalY = GetScrollLines(wxVERTICAL);
//if (unitsTotalX <= 0 || unitsTotalY <= 0) return; -> premature
- //numeric::restrict(scrollPosX, 0, unitsTotalX - 1); //make sure scroll target is in valid range
- //numeric::restrict(scrollPosY, 0, unitsTotalY - 1); //
+ //numeric::confine(scrollPosX, 0, unitsTotalX - 1); //make sure scroll target is in valid range
+ //numeric::confine(scrollPosY, 0, unitsTotalY - 1); //
Scroll(scrollPosX, scrollPosY);
updateWindowSizes(); //may show horizontal scroll bar
@@ -1543,7 +1514,8 @@ void Grid::scrollDelta(int deltaX, int deltaY)
void Grid::redirectRowLabelEvent(wxMouseEvent& event)
{
event.m_x = 0;
- mainWin_->ProcessEvent(event);
+ if (wxEvtHandler* evtHandler = mainWin_->GetEventHandler())
+ evtHandler->ProcessEvent(event);
if (event.ButtonDown() && wxWindow::FindFocus() != mainWin_)
mainWin_->SetFocus();
@@ -1569,7 +1541,7 @@ void Grid::Refresh(bool eraseBackground, const wxRect* rect)
}
-void Grid::setRowHeight(int height)
+void Grid::setRowHeight(size_t height)
{
rowLabelWin_->setRowHeight(height);
updateWindowSizes();
@@ -1707,13 +1679,15 @@ wxRect Grid::getColumnLabelArea(ColumnType colType, size_t compPos) const
auto iterCol = std::find_if(iterComp->begin(), iterComp->end(), [&](const VisibleColumn& vc) { return vc.type_ == colType; });
if (iterCol != iterComp->end())
{
- int posX = std::accumulate(compAbsWidths.begin(), iterComp, 0,
- [](int val, const std::vector<VisibleColumn>& cols)
+ ptrdiff_t posX = std::accumulate(compAbsWidths.begin(), iterComp, static_cast<ptrdiff_t>(0),
+ [](ptrdiff_t sum, const std::vector<VisibleColumn>& cols)
{
- return val + std::accumulate(cols.begin(), cols.end(), 0, [](int val2, const VisibleColumn& vc) { return val2 + vc.width_; });
+ return sum + std::accumulate(cols.begin(), cols.end(), static_cast<ptrdiff_t>(0),
+ [](ptrdiff_t val2, const VisibleColumn& vc) { return val2 + vc.width_; });
});
- posX += std::accumulate(iterComp->begin(), iterCol, 0, [](int val, const VisibleColumn& vc) { return val + vc.width_; });
+ posX += std::accumulate(iterComp->begin(), iterCol, static_cast<ptrdiff_t>(0),
+ [](ptrdiff_t sum, const VisibleColumn& vc) { return sum + vc.width_; });
return wxRect(wxPoint(posX, 0), wxSize(iterCol->width_, colLabelHeight));
}
@@ -1727,7 +1701,7 @@ Opt<Grid::ColAction> Grid::clientPosToColumnAction(const wxPoint& pos) const
const int absPosX = CalcUnscrolledPosition(pos).x;
if (absPosX >= 0)
{
- int accuWidth = 0;
+ ptrdiff_t accuWidth = 0;
std::vector<std::vector<VisibleColumn>> compAbsWidths = getAbsoluteWidths(); //resolve negative/stretched widths
for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp)
@@ -1780,7 +1754,7 @@ void Grid::moveColumn(size_t colFrom, size_t colTo, size_t compPos)
}
-int Grid::clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const
+ptrdiff_t Grid::clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const
{
std::vector<std::vector<VisibleColumn>> compAbsWidths = getAbsoluteWidths(); //resolve negative/stretched widths
if (compPos < compAbsWidths.size())
@@ -1788,16 +1762,16 @@ int Grid::clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const
auto iterComp = compAbsWidths.begin() + compPos;
const int absPosX = CalcUnscrolledPosition(pos).x;
- int accuWidth = std::accumulate(compAbsWidths.begin(), iterComp, 0,
- [](int val, const std::vector<VisibleColumn>& cols)
+ ptrdiff_t accuWidth = std::accumulate(compAbsWidths.begin(), iterComp, static_cast<ptrdiff_t>(0),
+ [](ptrdiff_t sum, const std::vector<VisibleColumn>& cols)
{
- return val + std::accumulate(cols.begin(), cols.end(), 0,
- [](int val2, const VisibleColumn& vc) { return val2 + vc.width_; });
+ return sum + std::accumulate(cols.begin(), cols.end(), static_cast<ptrdiff_t>(0),
+ [](ptrdiff_t sum2, const VisibleColumn& vc) { return sum2 + vc.width_; });
});
for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol)
{
- const int width = iterCol->width_; //beware dreaded unsigned conversions!
+ const ptrdiff_t width = iterCol->width_; //beware dreaded unsigned conversions!
accuWidth += width;
if (absPosX < accuWidth - width / 2)
@@ -1821,7 +1795,7 @@ Opt<ColumnType> Grid::colToType(size_t col, size_t compPos) const
}
-int Grid::getRowAtPos(int posY) const { return rowLabelWin_->getRowAtPos(posY); }
+ptrdiff_t Grid::getRowAtPos(int posY) const { return rowLabelWin_->getRowAtPos(posY); }
Opt<std::pair<ColumnType, size_t>> Grid::getColumnAtPos(int posX) const
@@ -1830,7 +1804,7 @@ Opt<std::pair<ColumnType, size_t>> Grid::getColumnAtPos(int posX) const
{
std::vector<std::vector<VisibleColumn>> compAbsWidths = getAbsoluteWidths(); //resolve negative/stretched widths
- int accWidth = 0;
+ ptrdiff_t accWidth = 0;
for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp)
for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol)
{
@@ -1846,7 +1820,7 @@ Opt<std::pair<ColumnType, size_t>> Grid::getColumnAtPos(int posX) const
}
-wxRect Grid::getCellArea(int row, ColumnType colType, size_t compPos) const
+wxRect Grid::getCellArea(size_t row, ColumnType colType, size_t compPos) const
{
const wxRect& colArea = getColumnLabelArea(colType, compPos);
const wxRect& rowArea = rowLabelWin_->getRowLabelArea(row);
@@ -1854,7 +1828,7 @@ wxRect Grid::getCellArea(int row, ColumnType colType, size_t compPos) const
}
-void Grid::setGridCursor(int row, size_t compPos)
+void Grid::setGridCursor(size_t row, size_t compPos)
{
if (compPos < comp.size())
{
@@ -1864,11 +1838,12 @@ void Grid::setGridCursor(int row, size_t compPos)
mainWin_->setCursor(row, compPos);
mainWin_->makeRowVisible(row);
mainWin_->Refresh();
+ rowLabelWin_->Refresh(); //row labels! (Kubuntu)
}
}
-void Grid::selectRange(int rowFrom, int rowTo, size_t compPos, bool positive)
+void Grid::selectRange(ptrdiff_t rowFrom, ptrdiff_t rowTo, size_t compPos, bool positive)
{
if (compPos < comp.size())
{
@@ -1893,17 +1868,17 @@ void Grid::clearSelectionAll()
}
-void Grid::scrollTo(int row)
+void Grid::scrollTo(size_t row)
{
const wxRect labelRect = rowLabelWin_->getRowLabelArea(row); //returns empty rect if column not found
if (labelRect.height > 0)
{
int pixelsPerUnitY = 0;
- GetScrollPixelsPerUnit(NULL, &pixelsPerUnitY);
- if (pixelsPerUnitY >= 0)
+ GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY);
+ if (pixelsPerUnitY > 0)
{
int scrollPosX = 0;
- GetViewStart(&scrollPosX, NULL);
+ GetViewStart(&scrollPosX, nullptr);
int scrollPosY = labelRect.GetTopLeft().y / pixelsPerUnitY;
Scroll(scrollPosX, scrollPosY);
@@ -1914,13 +1889,13 @@ void Grid::scrollTo(int row)
}
-std::pair<int, size_t> Grid::getGridCursor() const
+std::pair<size_t, size_t> Grid::getGridCursor() const
{
return mainWin_->getCursor();
}
-int Grid::getBestColumnSize(size_t col, size_t compPos) const
+ptrdiff_t Grid::getBestColumnSize(size_t col, size_t compPos) const
{
if (compPos < comp.size())
{
@@ -1934,9 +1909,9 @@ int Grid::getBestColumnSize(size_t col, size_t compPos) const
dc.SetFont(mainWin_->GetFont());
size_t maxSize = 0;
- const std::pair<int, int> rowRange = rowLabelWin_->getRowsOnClient(mainWin_->GetClientRect()); //returns range [begin, end)
- for (int row = rowRange.first; row < rowRange.second; ++row)
+ auto rowRange = rowLabelWin_->getRowsOnClient(mainWin_->GetClientRect()); //returns range [begin, end)
+ for (auto row = rowRange.first; row < rowRange.second; ++row)
maxSize = std::max(maxSize, dataView->getBestSize(dc, row, type));
return maxSize;
@@ -1957,13 +1932,12 @@ void Grid::autoSizeColumns(size_t compPos)
const int bestWidth = getBestColumnSize(col, compPos); //return -1 on error
if (bestWidth >= 0)
{
- const size_t newWidth = std::max(COLUMN_MIN_WIDTH, bestWidth);
+ const auto newWidth = std::max(COLUMN_MIN_WIDTH, bestWidth);
iter->width_ = newWidth;
//notify column resize (asynchronously!)
GridColumnResizeEvent sizeEvent(newWidth, iter->type_, compPos);
- wxEvtHandler* evtHandler = GetEventHandler();
- if (evtHandler)
+ if (wxEvtHandler* evtHandler = GetEventHandler())
evtHandler->AddPendingEvent(sizeEvent);
}
}
@@ -1973,9 +1947,9 @@ void Grid::autoSizeColumns(size_t compPos)
}
-int Grid::getMinAbsoluteWidthTotal() const
+ptrdiff_t Grid::getMinAbsoluteWidthTotal() const
{
- int minWidthTotal = 0;
+ ptrdiff_t minWidthTotal = 0;
//bool haveStretchedCols = false;
std::for_each(comp.begin(), comp.end(),
[&](const Component& c)
@@ -2000,9 +1974,9 @@ std::vector<std::vector<Grid::VisibleColumn>> Grid::getAbsoluteWidths() const //
{
std::vector<std::vector<VisibleColumn>> output;
- std::vector<std::pair<int, VisibleColumn*>> stretchedCols; //(factor, column to stretch)
- int factorTotal = 0;
- int minWidthTotal = 0;
+ std::vector<std::pair<ptrdiff_t, VisibleColumn*>> stretchedCols; //(factor, column to stretch)
+ ptrdiff_t factorTotal = 0;
+ ptrdiff_t minWidthTotal = 0;
output.reserve(comp.size());
std::for_each(comp.begin(), comp.end(),
@@ -2033,13 +2007,13 @@ std::vector<std::vector<Grid::VisibleColumn>> Grid::getAbsoluteWidths() const //
if (!stretchedCols.empty())
{
- const int widthToFill = mainWin_->GetClientSize().GetWidth() - minWidthTotal;
+ const ptrdiff_t widthToFill = mainWin_->GetClientSize().GetWidth() - minWidthTotal;
if (widthToFill > 0)
{
int widthRemaining = widthToFill;
for (auto iter = stretchedCols.begin(); iter != stretchedCols.end(); ++iter)
{
- const int addWidth = (widthToFill * iter->first) / factorTotal; //round down
+ const ptrdiff_t addWidth = (widthToFill * iter->first) / factorTotal; //round down
iter->second->width_ += addWidth;
widthRemaining -= addWidth;
}
diff --git a/wx+/grid.h b/wx+/grid.h
index 8833dd77..4f89bd9d 100644
--- a/wx+/grid.h
+++ b/wx+/grid.h
@@ -35,7 +35,7 @@ extern const wxEventType EVENT_GRID_SELECT_RANGE; //generates: GridRangeSelectEv
//NOTE: neither first nor second row need to match EVENT_GRID_MOUSE_LEFT_DOWN/EVENT_GRID_MOUSE_LEFT_UP: user holding SHIFT; moving out of window...
//=> range always specifies *valid* rows
-//example: wnd.Connect(EVENT_GRID_COL_LABEL_LEFT_CLICK, GridClickEventHandler(MyDlg::OnLeftClick), NULL, this);
+//example: wnd.Connect(EVENT_GRID_COL_LABEL_LEFT_CLICK, GridClickEventHandler(MyDlg::OnLeftClick), nullptr, this);
struct GridClickEvent : public wxMouseEvent
@@ -96,11 +96,11 @@ public:
virtual size_t getRowCount() const = 0; //if there are multiple grid components, only the first one will be polled for row count!
//grid area
- virtual wxString getValue(int row, ColumnType colType) const = 0;
- virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, int row, bool enabled, bool selected, bool hasFocus); //default implementation
- virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, ColumnType colType); //
- virtual size_t getBestSize(wxDC& dc, int row, ColumnType colType); //must correspond to renderCell()!
- virtual wxString getToolTip(int row, ColumnType colType) const { return wxString(); }
+ virtual wxString getValue(size_t row, ColumnType colType) const = 0;
+ virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus); //default implementation
+ virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType); //
+ virtual size_t getBestSize(wxDC& dc, size_t row, ColumnType colType); //must correspond to renderCell()!
+ virtual wxString getToolTip(size_t row, ColumnType colType) const { return wxString(); }
//label area
virtual wxString getColumnLabel(ColumnType colType) const = 0;
@@ -130,7 +130,7 @@ public:
size_t getRowCount() const;
- void setRowHeight(int height);
+ void setRowHeight(size_t height);
//grid component := a grid is divided into multiple components each of which is essentially a set of connected columns
void setComponentCount(size_t count) { comp.resize(count); updateWindowSizes(); }
@@ -148,8 +148,8 @@ public:
std::vector<ColumnAttribute> getColumnConfig(size_t compPos = 0) const;
void setDataProvider(const std::shared_ptr<GridData>& dataView, size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].dataView_ = dataView; }
- /**/ GridData* getDataProvider(size_t compPos = 0) { return compPos < comp.size() ? comp[compPos].dataView_.get() : NULL; }
- const GridData* getDataProvider(size_t compPos = 0) const { return compPos < comp.size() ? comp[compPos].dataView_.get() : NULL; }
+ /**/ GridData* getDataProvider(size_t compPos = 0) { return compPos < comp.size() ? comp[compPos].dataView_.get() : nullptr; }
+ const GridData* getDataProvider(size_t compPos = 0) const { return compPos < comp.size() ? comp[compPos].dataView_.get() : nullptr; }
//-----------------------------------------------------------------------------
void setColumnLabelHeight(int height);
@@ -157,7 +157,7 @@ public:
void showScrollBars(bool horizontal, bool vertical);
- std::vector<int> getSelectedRows(size_t compPos = 0) const;
+ std::vector<size_t> getSelectedRows(size_t compPos = 0) const;
void clearSelection(size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].selection.clear(); }
void scrollDelta(int deltaX, int deltaY); //in scroll units
@@ -167,20 +167,20 @@ public:
wxWindow& getColLabelWin();
wxWindow& getMainWin ();
- int getRowAtPos(int posY) const; //returns < 0 if column not found; absolute coordinates!
+ ptrdiff_t getRowAtPos(int posY) const; //returns < 0 if column not found; absolute coordinates!
Opt<std::pair<ColumnType, size_t>> getColumnAtPos(int posX) const; //returns (column type, component pos)
- wxRect getCellArea(int row, ColumnType colType, size_t compPos = 0) const; //returns empty rect if column not found; absolute coordinates!
+ wxRect getCellArea(size_t row, ColumnType colType, size_t compPos = 0) const; //returns empty rect if column not found; absolute coordinates!
void enableColumnMove (bool value, size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].allowColumnMove = value; }
void enableColumnResize(bool value, size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].allowColumnResize = value; }
- void setGridCursor(int row, size_t compPos = 0); //set + show + select cursor
- std::pair<int, size_t> getGridCursor() const; //(row, component pos) row == -1 if none
+ void setGridCursor(size_t row, size_t compPos = 0); //set + show + select cursor
+ std::pair<size_t, size_t> getGridCursor() const; //(row, component pos)
- void scrollTo(int row);
+ void scrollTo(size_t row);
- virtual void Refresh(bool eraseBackground = true, const wxRect* rect = NULL);
+ virtual void Refresh(bool eraseBackground = true, const wxRect* rect = nullptr);
virtual bool Enable( bool enable = true) { Refresh(); return wxScrolledWindow::Enable(enable); }
void autoSizeColumns(size_t compPos = 0);
@@ -198,7 +198,7 @@ private:
void SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh); //get rid of scrollbars, but preserve scrolling behavior!
#endif
- int getBestColumnSize(size_t col, size_t compPos) const; //return -1 on error
+ ptrdiff_t getBestColumnSize(size_t col, size_t compPos) const; //return -1 on error
friend class GridData;
class SubWindow;
@@ -212,9 +212,9 @@ private:
public:
void init(size_t rowCount) { rowSelectionValue.resize(rowCount); clear(); }
- std::vector<int> get() const
+ std::vector<size_t> get() const
{
- std::vector<int> selection;
+ std::vector<size_t> selection;
for (auto iter = rowSelectionValue.begin(); iter != rowSelectionValue.end(); ++iter)
if (*iter != 0)
selection.push_back(iter - rowSelectionValue.begin());
@@ -225,13 +225,13 @@ private:
bool isSelected(size_t row) const { return row < rowSelectionValue.size() ? rowSelectionValue[row] != 0 : false; }
- void selectRange(int rowFrom, int rowTo, bool positive = true) //select [rowFrom, rowTo], very tolerant: trims and swaps if required!
+ void selectRange(ptrdiff_t rowFrom, ptrdiff_t rowTo, bool positive = true) //select [rowFrom, rowTo], very tolerant: trims and swaps if required!
{
- int rowFirst = std::min(rowFrom, rowTo);
- int rowLast = std::max(rowFrom, rowTo) + 1;
+ auto rowFirst = std::min(rowFrom, rowTo);
+ auto rowLast = std::max(rowFrom, rowTo) + 1;
- numeric::restrict(rowFirst, 0, static_cast<int>(rowSelectionValue.size()));
- numeric::restrict(rowLast, 0, static_cast<int>(rowSelectionValue.size()));
+ numeric::confine<ptrdiff_t>(rowFirst, 0, rowSelectionValue.size());
+ numeric::confine<ptrdiff_t>(rowLast, 0, rowSelectionValue.size());
std::fill(rowSelectionValue.begin() + rowFirst, rowSelectionValue.begin() + rowLast, positive);
}
@@ -242,9 +242,9 @@ private:
struct VisibleColumn
{
- VisibleColumn(ColumnType type, int width) : type_(type), width_(width) {}
+ VisibleColumn(ColumnType type, ptrdiff_t width) : type_(type), width_(width) {}
ColumnType type_;
- int width_; //may be NEGATIVE => treat as proportional stretch! use getAbsoluteWidths() to evaluate!!!
+ ptrdiff_t width_; //may be NEGATIVE => treat as proportional stretch! use getAbsoluteWidths() to evaluate!!!
};
struct Component
@@ -260,7 +260,7 @@ private:
std::vector<ColumnAttribute> oldColAttributes; //visible + nonvisible columns; use for conversion in setColumnConfig()/getColumnConfig() *only*!
};
- int getMinAbsoluteWidthTotal() const; //assigns minimum width to stretched columns
+ ptrdiff_t getMinAbsoluteWidthTotal() const; //assigns minimum width to stretched columns
std::vector<std::vector<VisibleColumn>> getAbsoluteWidths() const; //evaluate negative widths as stretched absolute values! structure matches "comp"
Opt<size_t> getAbsoluteWidth(size_t col, size_t compPos) const //resolve stretched columns
@@ -271,7 +271,7 @@ private:
return NoValue();
}
- void setColWidth(size_t col, size_t compPos, int width) //width may be >= 0: absolute, or < 0: stretched
+ void setColWidth(size_t col, size_t compPos, ptrdiff_t width) //width may be >= 0: absolute, or < 0: stretched
{
if (compPos < comp.size() && col < comp[compPos].visibleCols.size())
comp[compPos].visibleCols[col].width_ = width;
@@ -279,10 +279,11 @@ private:
wxRect getColumnLabelArea(ColumnType colType, size_t compPos) const; //returns empty rect if column not found
- void selectRange(int rowFrom, int rowTo, size_t compPos, bool positive = true); //select range + notify event!
+ void selectRange(ptrdiff_t rowFrom, ptrdiff_t rowTo, size_t compPos, bool positive = true); //select range + notify event!
+
void clearSelectionAll(); //clear selection + notify event
- bool isSelected(int row, size_t compPos) const { return compPos < comp.size() ? comp[compPos].selection.isSelected(row) : false; }
+ bool isSelected(size_t row, size_t compPos) const { return compPos < comp.size() ? comp[compPos].selection.isSelected(row) : false; }
bool columnMoveAllowed (size_t compPos) const { return compPos < comp.size() ? comp[compPos].allowColumnMove : false; }
bool columnResizeAllowed(size_t compPos) const { return compPos < comp.size() ? comp[compPos].allowColumnResize : false; }
@@ -295,11 +296,10 @@ private:
};
Opt<ColAction> clientPosToColumnAction(const wxPoint& pos) const;
void moveColumn(size_t colFrom, size_t colTo, size_t compPos);
- int clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const;
+ ptrdiff_t clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const; //return < 0 on error
Opt<ColumnType> colToType(size_t col, size_t compPos) const;
-
/*
Visual layout:
------------------------------------------------
diff --git a/wx+/mouse_move_dlg.cpp b/wx+/mouse_move_dlg.cpp
index 20e6d420..697a5d47 100644
--- a/wx+/mouse_move_dlg.cpp
+++ b/wx+/mouse_move_dlg.cpp
@@ -49,7 +49,7 @@ MouseMoveWindow::MouseMoveWindow(wxWindow& parent, bool includeParent) : wxWindo
dynamic_cast<wxPanel*> (&wnd) ||
dynamic_cast<wxFrame*> (&wnd) ||
dynamic_cast<wxDialog*> (&wnd))
- wnd.Connect(wxEVT_LEFT_DOWN, memFunMouseDown, NULL, this);
+ wnd.Connect(wxEVT_LEFT_DOWN, memFunMouseDown, nullptr, this);
};
if (includeParent)
diff --git a/wx+/no_flicker.h b/wx+/no_flicker.h
index f745a12a..22952977 100644
--- a/wx+/no_flicker.h
+++ b/wx+/no_flicker.h
@@ -12,7 +12,7 @@
namespace zen
{
inline
-void setText(wxTextCtrl& control, const wxString& newText, bool* additionalLayoutChange = NULL)
+void setText(wxTextCtrl& control, const wxString& newText, bool* additionalLayoutChange = nullptr)
{
if (additionalLayoutChange && !*additionalLayoutChange) //never revert from true to false!
*additionalLayoutChange = control.GetValue().length() != newText.length(); //avoid screen flicker: update layout only when necessary
@@ -22,7 +22,7 @@ void setText(wxTextCtrl& control, const wxString& newText, bool* additionalLayou
}
inline
-void setText(wxStaticText& control, const wxString& newText, bool* additionalLayoutChange = NULL)
+void setText(wxStaticText& control, const wxString& newText, bool* additionalLayoutChange = nullptr)
{
if (additionalLayoutChange && !*additionalLayoutChange)
*additionalLayoutChange = control.GetLabel().length() != newText.length(); //avoid screen flicker: update layout only when necessary
diff --git a/wx+/pch.h b/wx+/pch.h
index 6c3393b2..93244b1d 100644
--- a/wx+/pch.h
+++ b/wx+/pch.h
@@ -101,6 +101,6 @@
#include <stdexcept>
//Boost
-#include <boost/scoped_array.hpp>
+
#endif //FFS_PRECOMPILED_HEADER
diff --git a/wx+/serialize.h b/wx+/serialize.h
index 4a06c001..b6a478cd 100644
--- a/wx+/serialize.h
+++ b/wx+/serialize.h
@@ -51,43 +51,54 @@ private:
};
-//wxInputStream proxy throwing FileError on error
-class CheckedReader
+class CheckedIo
+{
+protected:
+ CheckedIo(wxStreamBase& stream) : stream_(stream) {}
+
+ void check() const
+ {
+ if (stream_.GetLastError() != wxSTREAM_NO_ERROR)
+ throwException();
+ }
+ virtual void throwException() const = 0;
+
+private:
+ wxStreamBase& stream_;
+};
+
+
+//wxInputStream proxy throwing exception on error
+class CheckedReader : private CheckedIo
{
public:
- CheckedReader(wxInputStream& stream, const Zstring& errorObjName) : stream_(stream), errorObjName_(errorObjName) {}
+ CheckedReader(wxInputStream& stream) : CheckedIo(stream), stream_(stream) {}
template <class T>
- T readNumberC() const; //throw FileError, checked read operation
+ T readPOD() const; //throw!
template <class S>
- S readStringC() const; //throw FileError, checked read operation
+ S readString() const; //throw!
private:
- void check() const;
-
wxInputStream& stream_;
- const Zstring& errorObjName_; //used for error text only
};
//wxOutputStream proxy throwing FileError on error
-class CheckedWriter
+class CheckedWriter : private CheckedIo
{
public:
- CheckedWriter(wxOutputStream& stream, const Zstring& errorObjName) : stream_(stream), errorObjName_(errorObjName) {}
+ CheckedWriter(wxOutputStream& stream) : CheckedIo(stream), stream_(stream) {}
template <class T>
- void writeNumberC(T number) const; //throw FileError, checked write operation
+ void writePOD(T number) const; //throw!
template <class S>
- void writeStringC(const S& str) const; //throw FileError, checked write operation
+ void writeString(const S& str) const; //throw!
private:
- void check() const;
-
wxOutputStream& stream_;
- const Zstring& errorObjName_; //used for error text only!
};
@@ -139,8 +150,11 @@ S readString(wxInputStream& stream)
const auto strLength = readPOD<std::uint32_t>(stream);
S output;
- output.resize(strLength); //throw std::bad_alloc
- stream.Read(&*output.begin(), sizeof(CharType) * strLength);
+ if (strLength > 0)
+ {
+ output.resize(strLength); //throw std::bad_alloc
+ stream.Read(&*output.begin(), sizeof(CharType) * strLength);
+ }
return output;
}
@@ -153,68 +167,49 @@ void writeString(wxOutputStream& stream, const S& str)
}
-inline
-void CheckedReader::check() const
-{
- if (stream_.GetLastError() != wxSTREAM_NO_ERROR)
- throw zen::FileError(_("Error reading from synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\"");
-}
-
-
template <class T>
inline
-T CheckedReader::readNumberC() const //checked read operation
+T CheckedReader::readPOD() const //checked read operation
{
- T output = readPOD<T>(stream_);
+ T output = zen::readPOD<T>(stream_);
check();
return output;
}
template <class S> inline
-S CheckedReader::readStringC() const //checked read operation
+S CheckedReader::readString() const //checked read operation
{
S output;
try
{
- output = readString<S>(stream_); //throw std::bad_alloc
- check();
- if (stream_.LastRead() != output.length() * sizeof(typename S::value_type)) //some additional check
- throw FileError(_("Error reading from synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\"");
- }
- catch (std::exception&)
- {
- throw FileError(_("Error reading from synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\"");
+ output = zen::readString<S>(stream_); //throw std::bad_alloc
}
+ catch (std::exception&) { throwException(); }
+
+ check();
+ if (stream_.LastRead() != output.length() * sizeof(typename S::value_type)) //some additional check
+ throwException();
return output;
}
template <class T> inline
-void CheckedWriter::writeNumberC(T number) const //checked write operation
+void CheckedWriter::writePOD(T number) const //checked write operation
{
- writePOD<T>(stream_, number);
+ zen::writePOD<T>(stream_, number);
check();
}
template <class S> inline
-void CheckedWriter::writeStringC(const S& str) const //checked write operation
+void CheckedWriter::writeString(const S& str) const //checked write operation
{
- writeString(stream_, str);
+ zen::writeString(stream_, str);
check();
if (stream_.LastWrite() != str.length() * sizeof(typename S::value_type)) //some additional check
- throw FileError(_("Error writing to synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\"");
+ throwException();
}
-
-
-inline
-void CheckedWriter::check() const
-{
- if (stream_.GetLastError() != wxSTREAM_NO_ERROR)
- throw FileError(_("Error writing to synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\"");
-}
-
}
#endif //SERIALIZE_H_INCLUDED
diff --git a/wx+/shell_execute.h b/wx+/shell_execute.h
index 310fe88c..3468a1c8 100644
--- a/wx+/shell_execute.h
+++ b/wx+/shell_execute.h
@@ -51,9 +51,9 @@ void shellExecute(const wxString& command, ExecutionType type = EXEC_TYPE_ASYNC)
if (!argv.empty())
{
filename = argv[0];
- for (std::vector<std::wstring>::const_iterator i = argv.begin() + 1; i != argv.end(); ++i)
- arguments += (i != argv.begin() ? L" " : L"") +
- (i->empty() || std::find_if(i->begin(), i->end(), &cStringIsWhiteSpace<wchar_t>) != i->end() ? L"\"" + *i + L"\"" : *i);
+ for (auto iter = argv.begin() + 1; iter != argv.end(); ++iter)
+ arguments += (iter != argv.begin() ? L" " : L"") +
+ (iter->empty() || std::any_of(iter->begin(), iter->end(), &isWhiteSpace<wchar_t>) ? L"\"" + *iter + L"\"" : *iter);
}
SHELLEXECUTEINFO execInfo = {};
diff --git a/wx+/timespan.h b/wx+/timespan.h
index 241a029e..58d5df4e 100644
--- a/wx+/timespan.h
+++ b/wx+/timespan.h
@@ -52,10 +52,10 @@ public:
Layout();
//connect events
- m_spinBtn ->Connect(wxEVT_SCROLL_LINEUP, wxEventHandler (TimeSpanCtrl::OnSpinUp), NULL, this);
- m_spinBtn ->Connect(wxEVT_SCROLL_LINEDOWN, wxEventHandler (TimeSpanCtrl::OnSpinDown), NULL, this);
- m_textCtrl->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (TimeSpanCtrl::OnKeyPress), NULL, this);
- m_textCtrl->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(TimeSpanCtrl::OnMouseAction), NULL, this);
+ m_spinBtn ->Connect(wxEVT_SCROLL_LINEUP, wxEventHandler (TimeSpanCtrl::OnSpinUp), nullptr, this);
+ m_spinBtn ->Connect(wxEVT_SCROLL_LINEDOWN, wxEventHandler (TimeSpanCtrl::OnSpinDown), nullptr, this);
+ m_textCtrl->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (TimeSpanCtrl::OnKeyPress), nullptr, this);
+ m_textCtrl->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(TimeSpanCtrl::OnMouseAction), nullptr, this);
setValue(0);
}
@@ -94,7 +94,7 @@ public:
textVal.Trim(false);
wxDateTime tmp(time_t(0));
- if (tmp.ParseFormat(textVal, FORMAT_TIMESPAN, wxDateTime(tmp)) == NULL)
+ if (tmp.ParseFormat(textVal, FORMAT_TIMESPAN, wxDateTime(tmp)) == nullptr)
return 0;
return (isNegative ? -1 : 1) *
diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp
index 7b4c51e0..6d81cdae 100644
--- a/wx+/tooltip.cpp
+++ b/wx+/tooltip.cpp
@@ -48,7 +48,7 @@ public:
};
-Tooltip::Tooltip() : tipWindow(new PopupFrameGenerated(NULL))
+Tooltip::Tooltip() : tipWindow(new PopupFrameGenerated(nullptr))
{
#ifdef FFS_WIN //neither looks good nor works at all on Linux
tipWindow->Disable(); //prevent window stealing focus!
@@ -94,5 +94,12 @@ void Tooltip::show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp)
void Tooltip::hide()
{
+#ifdef FFS_LINUX
+ //on wxGTK the tip window occassionally goes blank and stays that way. This is somehow triggered by wxWindow::Hide() and doesn't seem to be a wxWidgets bug (=> GTK?)
+ //apply brute force:
+ tipWindow->Destroy();
+ tipWindow = new PopupFrameGenerated(nullptr);
+#endif
+
tipWindow->Hide();
}
diff --git a/wx+/tooltip.h b/wx+/tooltip.h
index 7babe3c3..195ceaf7 100644
--- a/wx+/tooltip.h
+++ b/wx+/tooltip.h
@@ -17,7 +17,7 @@ public:
Tooltip();
~Tooltip();
- void show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp = NULL); //absolute screen coordinates
+ void show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp = nullptr); //absolute screen coordinates
void hide();
private:
bgstack15