diff options
author | Daniel Wilhelm <shieldwed@outlook.com> | 2017-04-20 16:55:28 -0600 |
---|---|---|
committer | Daniel Wilhelm <shieldwed@outlook.com> | 2017-04-20 16:59:56 -0600 |
commit | 823740e1ffa2b3bd39f8dea8062f5c5a0d9c741b (patch) | |
tree | 63222010af3b90a36f29c1c9c360116973cdff38 /wx+/graph.h | |
parent | add .gitattributes for less line ending hassles (diff) | |
download | FreeFileSync-823740e1ffa2b3bd39f8dea8062f5c5a0d9c741b.tar.gz FreeFileSync-823740e1ffa2b3bd39f8dea8062f5c5a0d9c741b.tar.bz2 FreeFileSync-823740e1ffa2b3bd39f8dea8062f5c5a0d9c741b.zip |
normalize most lineendings
Diffstat (limited to 'wx+/graph.h')
-rwxr-xr-x | wx+/graph.h | 708 |
1 files changed, 354 insertions, 354 deletions
diff --git a/wx+/graph.h b/wx+/graph.h index 3b2d390d..84927b6d 100755 --- a/wx+/graph.h +++ b/wx+/graph.h @@ -1,354 +1,354 @@ -// *****************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
-// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
-// *****************************************************************************
-
-#ifndef GRAPH_H_234425245936567345799
-#define GRAPH_H_234425245936567345799
-
-#include <map>
-#include <vector>
-#include <memory>
-#include <wx/panel.h>
-#include <wx/settings.h>
-#include <wx/bitmap.h>
-#include <zen/string_tools.h>
-#include <zen/optional.h>
-
-//elegant 2D graph as wxPanel specialization
-
-namespace zen
-{
-/*
-Example:
- //init graph (optional)
- m_panelGraph->setAttributes(Graph2D::MainAttributes().
- setLabelX(Graph2D::LABEL_X_BOTTOM, 20, std::make_shared<LabelFormatterTimeElapsed>()).
- setLabelY(Graph2D::LABEL_Y_RIGHT, 60, std::make_shared<LabelFormatterBytes>()));
- //set graph data
- std::shared_ptr<CurveData> curveDataBytes = ...
- m_panelGraph->setCurve(curveDataBytes, Graph2D::CurveAttributes().setLineWidth(2).setColor(wxColor(0, 192, 0)));
-*/
-
-struct CurvePoint
-{
- CurvePoint() {}
- CurvePoint(double xVal, double yVal) : x(xVal), y(yVal) {}
- double x = 0;
- double y = 0;
-};
-inline bool operator==(const CurvePoint& lhs, const CurvePoint& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; }
-inline bool operator!=(const CurvePoint& lhs, const CurvePoint& rhs) { return !(lhs == rhs); }
-
-
-struct CurveData
-{
- virtual ~CurveData() {}
-
- virtual std::pair<double, double> getRangeX() const = 0;
- virtual std::vector<CurvePoint> getPoints(double minX, double maxX, int pixelWidth) const = 0; //points outside the draw area are automatically trimmed!
-};
-
-//special curve types:
-struct ContinuousCurveData : public CurveData
-{
- virtual double getValue(double x) const = 0;
-
-private:
- std::vector<CurvePoint> getPoints(double minX, double maxX, int pixelWidth) const override;
-};
-
-struct SparseCurveData : public CurveData
-{
- SparseCurveData(bool addSteps = false) : addSteps_(addSteps) {} //addSteps: add points to get a staircase effect or connect points via a direct line
-
- virtual Opt<CurvePoint> getLessEq (double x) const = 0;
- virtual Opt<CurvePoint> getGreaterEq(double x) const = 0;
-
-private:
- std::vector<CurvePoint> getPoints(double minX, double maxX, int pixelWidth) const override;
- const bool addSteps_;
-};
-
-
-struct ArrayCurveData : public SparseCurveData
-{
- virtual double getValue(size_t pos) const = 0;
- virtual size_t getSize () const = 0;
-
-private:
- std::pair<double, double> getRangeX() const override { const size_t sz = getSize(); return std::make_pair(0.0, sz == 0 ? 0.0 : sz - 1.0); }
-
- Opt<CurvePoint> getLessEq(double x) const override
- {
- const size_t sz = getSize();
- const size_t pos = std::min<ptrdiff_t>(std::floor(x), sz - 1); //[!] expect unsigned underflow if empty!
- if (pos < sz)
- return CurvePoint(pos, getValue(pos));
- return NoValue();
- }
-
- Opt<CurvePoint> getGreaterEq(double x) const override
- {
- const size_t pos = std::max<ptrdiff_t>(std::ceil(x), 0); //[!] use std::max with signed type!
- if (pos < getSize())
- return CurvePoint(pos, getValue(pos));
- return NoValue();
- }
-};
-
-
-struct VectorCurveData : public ArrayCurveData
-{
- std::vector<double>& refData() { return data; }
-private:
- double getValue(size_t pos) const override { return pos < data.size() ? data[pos] : 0; }
- size_t getSize() const override { return data.size(); }
-
- std::vector<double> data;
-};
-
-//------------------------------------------------------------------------------------------------------------
-
-struct LabelFormatter
-{
- virtual ~LabelFormatter() {}
-
- //determine convenient graph label block size in unit of data: usually some small deviation on "sizeProposed"
- virtual double getOptimalBlockSize(double sizeProposed) const = 0;
-
- //create human-readable text for x or y-axis position
- virtual wxString formatText(double value, double optimalBlockSize) const = 0;
-};
-
-
-double nextNiceNumber(double blockSize); //round to next number which is convenient to read, e.g. 2.13 -> 2; 2.7 -> 2.5
-
-struct DecimalNumberFormatter : public LabelFormatter
-{
- double getOptimalBlockSize(double sizeProposed ) const override { return nextNiceNumber(sizeProposed); }
- wxString formatText (double value, double optimalBlockSize) const override { return zen::numberTo<wxString>(value); }
-};
-
-//------------------------------------------------------------------------------------------------------------
-
-//emit data selection event
-//Usage: wnd.Connect(wxEVT_GRAPH_SELECTION, GraphSelectEventHandler(MyDlg::OnGraphSelection), nullptr, this);
-// void MyDlg::OnGraphSelection(GraphSelectEvent& event);
-
-extern const wxEventType wxEVT_GRAPH_SELECTION;
-
-struct SelectionBlock
-{
- CurvePoint from;
- CurvePoint to;
-};
-
-class GraphSelectEvent : public wxCommandEvent
-{
-public:
- GraphSelectEvent(const SelectionBlock& selBlock) : wxCommandEvent(wxEVT_GRAPH_SELECTION), selBlock_(selBlock) {}
- wxEvent* Clone() const override { return new GraphSelectEvent(selBlock_); }
-
- SelectionBlock getSelection() { return selBlock_; }
-
-private:
- SelectionBlock selBlock_;
-};
-
-using GraphSelectEventFunction = void (wxEvtHandler::*)(GraphSelectEvent&);
-
-#define GraphSelectEventHandler(func) \
- (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(GraphSelectEventFunction, &func)
-
-//------------------------------------------------------------------------------------------------------------
-
-class Graph2D : public wxPanel
-{
-public:
- Graph2D(wxWindow* parent,
- wxWindowID winid = wxID_ANY,
- const wxPoint& pos = wxDefaultPosition,
- const wxSize& size = wxDefaultSize,
- long style = wxTAB_TRAVERSAL | wxNO_BORDER,
- const wxString& name = wxPanelNameStr);
-
- class CurveAttributes
- {
- public:
- CurveAttributes() {} //required by GCC
- CurveAttributes& setColor (const wxColor& col) { color = col; autoColor = false; return *this; }
- CurveAttributes& fillCurveArea (const wxColor& col) { fillColor = col; fillMode = FILL_CURVE; return *this; }
- CurveAttributes& fillPolygonArea(const wxColor& col) { fillColor = col; fillMode = FILL_POLYGON; return *this; }
- CurveAttributes& setLineWidth(size_t width) { lineWidth = static_cast<int>(width); return *this; }
-
- private:
- friend class Graph2D;
-
- bool autoColor = true;
- wxColor color;
-
- enum FillMode
- {
- FILL_NONE,
- FILL_CURVE,
- FILL_POLYGON
- };
-
- FillMode fillMode = FILL_NONE;
- wxColor fillColor;
-
- int lineWidth = 2;
- };
-
- void setCurve(const std::shared_ptr<CurveData>& data, const CurveAttributes& ca = CurveAttributes());
- void addCurve(const std::shared_ptr<CurveData>& data, const CurveAttributes& ca = CurveAttributes());
-
- static wxColor getBorderColor() { return { 130, 135, 144 }; } //medium grey, the same Win7 uses for other frame borders => not accessible! but no big deal...
-
- enum PosLabelY
- {
- LABEL_Y_LEFT,
- LABEL_Y_RIGHT,
- LABEL_Y_NONE
- };
-
- enum PosLabelX
- {
- LABEL_X_TOP,
- LABEL_X_BOTTOM,
- LABEL_X_NONE
- };
-
- enum PosCorner
- {
- CORNER_TOP_LEFT,
- CORNER_TOP_RIGHT,
- CORNER_BOTTOM_LEFT,
- CORNER_BOTTOM_RIGHT,
- };
-
- enum SelMode
- {
- SELECT_NONE,
- SELECT_RECTANGLE,
- SELECT_X_AXIS,
- SELECT_Y_AXIS,
- };
-
- class MainAttributes
- {
- public:
- MainAttributes& setMinX(double newMinX) { minX = newMinX; minXauto = false; return *this; }
- MainAttributes& setMaxX(double newMaxX) { maxX = newMaxX; maxXauto = false; return *this; }
-
- MainAttributes& setMinY(double newMinY) { minY = newMinY; minYauto = false; return *this; }
- MainAttributes& setMaxY(double newMaxY) { maxY = newMaxY; maxYauto = false; return *this; }
-
- MainAttributes& setAutoSize() { minXauto = maxXauto = minYauto = maxYauto = true; return *this; }
-
- MainAttributes& setLabelX(PosLabelX posX, size_t height = 25, std::shared_ptr<LabelFormatter> newLabelFmt = std::make_shared<DecimalNumberFormatter>())
- {
- labelposX = posX;
- xLabelHeight = static_cast<int>(height);
- labelFmtX = newLabelFmt;
- return *this;
- }
- MainAttributes& setLabelY(PosLabelY posY, size_t width = 60, std::shared_ptr<LabelFormatter> newLabelFmt = std::make_shared<DecimalNumberFormatter>())
- {
- labelposY = posY;
- yLabelWidth = static_cast<int>(width);
- labelFmtY = newLabelFmt;
- return *this;
- }
-
- MainAttributes& setCornerText(const wxString& txt, PosCorner pos) { cornerTexts[pos] = txt; return *this; }
-
- MainAttributes& setBackgroundColor(const wxColor& col) { backgroundColor = col; return *this; }
-
- MainAttributes& setSelectionMode(SelMode mode) { mouseSelMode = mode; return *this; }
-
- private:
- friend class Graph2D;
-
- bool minXauto = true; //autodetect range for X value
- bool maxXauto = true;
- double minX = 0; //x-range to visualize
- double maxX = 0; //
-
- bool minYauto = true; //autodetect range for Y value
- bool maxYauto = true;
- double minY = 0; //y-range to visualize
- double maxY = 0; //
-
- PosLabelX labelposX = LABEL_X_BOTTOM;
- int xLabelHeight = 25;
- std::shared_ptr<LabelFormatter> labelFmtX = std::make_shared<DecimalNumberFormatter>();
-
- PosLabelY labelposY = LABEL_Y_LEFT;
- int yLabelWidth = 60;
- std::shared_ptr<LabelFormatter> labelFmtY = std::make_shared<DecimalNumberFormatter>();
-
- std::map<PosCorner, wxString> cornerTexts;
-
- wxColor backgroundColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
- SelMode mouseSelMode = SELECT_RECTANGLE;
- };
- void setAttributes(const MainAttributes& newAttr) { attr = newAttr; Refresh(); }
- MainAttributes getAttributes() const { return attr; }
-
- std::vector<SelectionBlock> getSelections() const { return oldSel; }
- void setSelections(const std::vector<SelectionBlock>& sel)
- {
- oldSel = sel;
- activeSel.reset();
- Refresh();
- }
- void clearSelection() { oldSel.clear(); Refresh(); }
-
-private:
- void OnMouseLeftDown(wxMouseEvent& event);
- void OnMouseMovement(wxMouseEvent& event);
- void OnMouseLeftUp (wxMouseEvent& event);
- void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
-
- void onPaintEvent(wxPaintEvent& event);
- void onSizeEvent(wxSizeEvent& event) { Refresh(); event.Skip(); }
- void onEraseBackGround(wxEraseEvent& event) {}
-
- void render(wxDC& dc) const;
-
- class MouseSelection
- {
- public:
- MouseSelection(wxWindow& wnd, const wxPoint& posDragStart) : wnd_(wnd), posDragStart_(posDragStart), posDragCurrent(posDragStart) { wnd_.CaptureMouse(); }
- ~MouseSelection() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); }
-
- wxPoint getStartPos() const { return posDragStart_; }
- wxPoint& refCurrentPos() { return posDragCurrent; }
-
- SelectionBlock& refSelection() { return selBlock; } //updated in Graph2d::render(): this is fine, since only what's shown is selected!
-
- private:
- wxWindow& wnd_;
- const wxPoint posDragStart_;
- wxPoint posDragCurrent;
- SelectionBlock selBlock;
- };
- std::vector<SelectionBlock> oldSel; //applied selections
- std::shared_ptr<MouseSelection> activeSel; //set during mouse selection
-
- MainAttributes attr; //global attributes
-
- Opt<wxBitmap> doubleBuffer;
-
- using CurveList = std::vector<std::pair<std::shared_ptr<CurveData>, CurveAttributes>>;
- CurveList curves_;
-
- //perf!!! generating the font is *very* expensive! don't do this repeatedly in Graph2D::render()!
- const wxFont labelFont { wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Arial" };
-};
-}
-
-#endif //GRAPH_H_234425245936567345799
+// ***************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * +// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * +// ***************************************************************************** + +#ifndef GRAPH_H_234425245936567345799 +#define GRAPH_H_234425245936567345799 + +#include <map> +#include <vector> +#include <memory> +#include <wx/panel.h> +#include <wx/settings.h> +#include <wx/bitmap.h> +#include <zen/string_tools.h> +#include <zen/optional.h> + +//elegant 2D graph as wxPanel specialization + +namespace zen +{ +/* +Example: + //init graph (optional) + m_panelGraph->setAttributes(Graph2D::MainAttributes(). + setLabelX(Graph2D::LABEL_X_BOTTOM, 20, std::make_shared<LabelFormatterTimeElapsed>()). + setLabelY(Graph2D::LABEL_Y_RIGHT, 60, std::make_shared<LabelFormatterBytes>())); + //set graph data + std::shared_ptr<CurveData> curveDataBytes = ... + m_panelGraph->setCurve(curveDataBytes, Graph2D::CurveAttributes().setLineWidth(2).setColor(wxColor(0, 192, 0))); +*/ + +struct CurvePoint +{ + CurvePoint() {} + CurvePoint(double xVal, double yVal) : x(xVal), y(yVal) {} + double x = 0; + double y = 0; +}; +inline bool operator==(const CurvePoint& lhs, const CurvePoint& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } +inline bool operator!=(const CurvePoint& lhs, const CurvePoint& rhs) { return !(lhs == rhs); } + + +struct CurveData +{ + virtual ~CurveData() {} + + virtual std::pair<double, double> getRangeX() const = 0; + virtual std::vector<CurvePoint> getPoints(double minX, double maxX, int pixelWidth) const = 0; //points outside the draw area are automatically trimmed! +}; + +//special curve types: +struct ContinuousCurveData : public CurveData +{ + virtual double getValue(double x) const = 0; + +private: + std::vector<CurvePoint> getPoints(double minX, double maxX, int pixelWidth) const override; +}; + +struct SparseCurveData : public CurveData +{ + SparseCurveData(bool addSteps = false) : addSteps_(addSteps) {} //addSteps: add points to get a staircase effect or connect points via a direct line + + virtual Opt<CurvePoint> getLessEq (double x) const = 0; + virtual Opt<CurvePoint> getGreaterEq(double x) const = 0; + +private: + std::vector<CurvePoint> getPoints(double minX, double maxX, int pixelWidth) const override; + const bool addSteps_; +}; + + +struct ArrayCurveData : public SparseCurveData +{ + virtual double getValue(size_t pos) const = 0; + virtual size_t getSize () const = 0; + +private: + std::pair<double, double> getRangeX() const override { const size_t sz = getSize(); return std::make_pair(0.0, sz == 0 ? 0.0 : sz - 1.0); } + + Opt<CurvePoint> getLessEq(double x) const override + { + const size_t sz = getSize(); + const size_t pos = std::min<ptrdiff_t>(std::floor(x), sz - 1); //[!] expect unsigned underflow if empty! + if (pos < sz) + return CurvePoint(pos, getValue(pos)); + return NoValue(); + } + + Opt<CurvePoint> getGreaterEq(double x) const override + { + const size_t pos = std::max<ptrdiff_t>(std::ceil(x), 0); //[!] use std::max with signed type! + if (pos < getSize()) + return CurvePoint(pos, getValue(pos)); + return NoValue(); + } +}; + + +struct VectorCurveData : public ArrayCurveData +{ + std::vector<double>& refData() { return data; } +private: + double getValue(size_t pos) const override { return pos < data.size() ? data[pos] : 0; } + size_t getSize() const override { return data.size(); } + + std::vector<double> data; +}; + +//------------------------------------------------------------------------------------------------------------ + +struct LabelFormatter +{ + virtual ~LabelFormatter() {} + + //determine convenient graph label block size in unit of data: usually some small deviation on "sizeProposed" + virtual double getOptimalBlockSize(double sizeProposed) const = 0; + + //create human-readable text for x or y-axis position + virtual wxString formatText(double value, double optimalBlockSize) const = 0; +}; + + +double nextNiceNumber(double blockSize); //round to next number which is convenient to read, e.g. 2.13 -> 2; 2.7 -> 2.5 + +struct DecimalNumberFormatter : public LabelFormatter +{ + double getOptimalBlockSize(double sizeProposed ) const override { return nextNiceNumber(sizeProposed); } + wxString formatText (double value, double optimalBlockSize) const override { return zen::numberTo<wxString>(value); } +}; + +//------------------------------------------------------------------------------------------------------------ + +//emit data selection event +//Usage: wnd.Connect(wxEVT_GRAPH_SELECTION, GraphSelectEventHandler(MyDlg::OnGraphSelection), nullptr, this); +// void MyDlg::OnGraphSelection(GraphSelectEvent& event); + +extern const wxEventType wxEVT_GRAPH_SELECTION; + +struct SelectionBlock +{ + CurvePoint from; + CurvePoint to; +}; + +class GraphSelectEvent : public wxCommandEvent +{ +public: + GraphSelectEvent(const SelectionBlock& selBlock) : wxCommandEvent(wxEVT_GRAPH_SELECTION), selBlock_(selBlock) {} + wxEvent* Clone() const override { return new GraphSelectEvent(selBlock_); } + + SelectionBlock getSelection() { return selBlock_; } + +private: + SelectionBlock selBlock_; +}; + +using GraphSelectEventFunction = void (wxEvtHandler::*)(GraphSelectEvent&); + +#define GraphSelectEventHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(GraphSelectEventFunction, &func) + +//------------------------------------------------------------------------------------------------------------ + +class Graph2D : public wxPanel +{ +public: + Graph2D(wxWindow* parent, + wxWindowID winid = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL | wxNO_BORDER, + const wxString& name = wxPanelNameStr); + + class CurveAttributes + { + public: + CurveAttributes() {} //required by GCC + CurveAttributes& setColor (const wxColor& col) { color = col; autoColor = false; return *this; } + CurveAttributes& fillCurveArea (const wxColor& col) { fillColor = col; fillMode = FILL_CURVE; return *this; } + CurveAttributes& fillPolygonArea(const wxColor& col) { fillColor = col; fillMode = FILL_POLYGON; return *this; } + CurveAttributes& setLineWidth(size_t width) { lineWidth = static_cast<int>(width); return *this; } + + private: + friend class Graph2D; + + bool autoColor = true; + wxColor color; + + enum FillMode + { + FILL_NONE, + FILL_CURVE, + FILL_POLYGON + }; + + FillMode fillMode = FILL_NONE; + wxColor fillColor; + + int lineWidth = 2; + }; + + void setCurve(const std::shared_ptr<CurveData>& data, const CurveAttributes& ca = CurveAttributes()); + void addCurve(const std::shared_ptr<CurveData>& data, const CurveAttributes& ca = CurveAttributes()); + + static wxColor getBorderColor() { return { 130, 135, 144 }; } //medium grey, the same Win7 uses for other frame borders => not accessible! but no big deal... + + enum PosLabelY + { + LABEL_Y_LEFT, + LABEL_Y_RIGHT, + LABEL_Y_NONE + }; + + enum PosLabelX + { + LABEL_X_TOP, + LABEL_X_BOTTOM, + LABEL_X_NONE + }; + + enum PosCorner + { + CORNER_TOP_LEFT, + CORNER_TOP_RIGHT, + CORNER_BOTTOM_LEFT, + CORNER_BOTTOM_RIGHT, + }; + + enum SelMode + { + SELECT_NONE, + SELECT_RECTANGLE, + SELECT_X_AXIS, + SELECT_Y_AXIS, + }; + + class MainAttributes + { + public: + MainAttributes& setMinX(double newMinX) { minX = newMinX; minXauto = false; return *this; } + MainAttributes& setMaxX(double newMaxX) { maxX = newMaxX; maxXauto = false; return *this; } + + MainAttributes& setMinY(double newMinY) { minY = newMinY; minYauto = false; return *this; } + MainAttributes& setMaxY(double newMaxY) { maxY = newMaxY; maxYauto = false; return *this; } + + MainAttributes& setAutoSize() { minXauto = maxXauto = minYauto = maxYauto = true; return *this; } + + MainAttributes& setLabelX(PosLabelX posX, size_t height = 25, std::shared_ptr<LabelFormatter> newLabelFmt = std::make_shared<DecimalNumberFormatter>()) + { + labelposX = posX; + xLabelHeight = static_cast<int>(height); + labelFmtX = newLabelFmt; + return *this; + } + MainAttributes& setLabelY(PosLabelY posY, size_t width = 60, std::shared_ptr<LabelFormatter> newLabelFmt = std::make_shared<DecimalNumberFormatter>()) + { + labelposY = posY; + yLabelWidth = static_cast<int>(width); + labelFmtY = newLabelFmt; + return *this; + } + + MainAttributes& setCornerText(const wxString& txt, PosCorner pos) { cornerTexts[pos] = txt; return *this; } + + MainAttributes& setBackgroundColor(const wxColor& col) { backgroundColor = col; return *this; } + + MainAttributes& setSelectionMode(SelMode mode) { mouseSelMode = mode; return *this; } + + private: + friend class Graph2D; + + bool minXauto = true; //autodetect range for X value + bool maxXauto = true; + double minX = 0; //x-range to visualize + double maxX = 0; // + + bool minYauto = true; //autodetect range for Y value + bool maxYauto = true; + double minY = 0; //y-range to visualize + double maxY = 0; // + + PosLabelX labelposX = LABEL_X_BOTTOM; + int xLabelHeight = 25; + std::shared_ptr<LabelFormatter> labelFmtX = std::make_shared<DecimalNumberFormatter>(); + + PosLabelY labelposY = LABEL_Y_LEFT; + int yLabelWidth = 60; + std::shared_ptr<LabelFormatter> labelFmtY = std::make_shared<DecimalNumberFormatter>(); + + std::map<PosCorner, wxString> cornerTexts; + + wxColor backgroundColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + SelMode mouseSelMode = SELECT_RECTANGLE; + }; + void setAttributes(const MainAttributes& newAttr) { attr = newAttr; Refresh(); } + MainAttributes getAttributes() const { return attr; } + + std::vector<SelectionBlock> getSelections() const { return oldSel; } + void setSelections(const std::vector<SelectionBlock>& sel) + { + oldSel = sel; + activeSel.reset(); + Refresh(); + } + void clearSelection() { oldSel.clear(); Refresh(); } + +private: + void OnMouseLeftDown(wxMouseEvent& event); + void OnMouseMovement(wxMouseEvent& event); + void OnMouseLeftUp (wxMouseEvent& event); + void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); + + void onPaintEvent(wxPaintEvent& event); + void onSizeEvent(wxSizeEvent& event) { Refresh(); event.Skip(); } + void onEraseBackGround(wxEraseEvent& event) {} + + void render(wxDC& dc) const; + + class MouseSelection + { + public: + MouseSelection(wxWindow& wnd, const wxPoint& posDragStart) : wnd_(wnd), posDragStart_(posDragStart), posDragCurrent(posDragStart) { wnd_.CaptureMouse(); } + ~MouseSelection() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); } + + wxPoint getStartPos() const { return posDragStart_; } + wxPoint& refCurrentPos() { return posDragCurrent; } + + SelectionBlock& refSelection() { return selBlock; } //updated in Graph2d::render(): this is fine, since only what's shown is selected! + + private: + wxWindow& wnd_; + const wxPoint posDragStart_; + wxPoint posDragCurrent; + SelectionBlock selBlock; + }; + std::vector<SelectionBlock> oldSel; //applied selections + std::shared_ptr<MouseSelection> activeSel; //set during mouse selection + + MainAttributes attr; //global attributes + + Opt<wxBitmap> doubleBuffer; + + using CurveList = std::vector<std::pair<std::shared_ptr<CurveData>, CurveAttributes>>; + CurveList curves_; + + //perf!!! generating the font is *very* expensive! don't do this repeatedly in Graph2D::render()! + const wxFont labelFont { wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Arial" }; +}; +} + +#endif //GRAPH_H_234425245936567345799 |