mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
added possibility to register custom symbols for JKQTPPlotSymbol()
This commit is contained in:
parent
f6def4b9d1
commit
bf1416d5a6
@ -44,6 +44,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>NEW: made it's delay a global static variable that can be set and red with JKQTPlotter::setGlobalResizeDelay() and JKQTPlotter::getGlobalResizeDelay()</li>
|
||||
<li>NEW: Using JKQTMathText::useGuiFonts() for FONT rendering by default</li>
|
||||
<li>NEW: added the option to draw a character from a font as symbol (<code>JKQTPCharacterSymbol+QChar('C').unicode()</code> and <code>JKQTPFilledCharacterSymbol+QChar('C').unicode()</code>)</li>
|
||||
<li>NEW: added the option to register a custom symbol using JKQTPRegisterCustomGraphSymbol() </li>
|
||||
</ul></li>
|
||||
|
||||
<li>JKQTMathText:<ul>
|
||||
|
BIN
doc/images/symbols/symbol_custom.png
Normal file
BIN
doc/images/symbols/symbol_custom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -93,6 +93,7 @@ QString JKQTPGraphSymbols2String(JKQTPGraphSymbols pos) {
|
||||
case JKQTPSymbolCount: JKQTPGraphSymbols2String(JKQTPMaxSymbolID);
|
||||
case JKQTPCharacterSymbol:
|
||||
case JKQTPFilledCharacterSymbol:
|
||||
case JKQTPFirstCustomSymbol:
|
||||
break;
|
||||
}
|
||||
if (pos>=JKQTPCharacterSymbol && pos<=JKQTPCharacterSymbol+0xFFFF) {
|
||||
@ -105,6 +106,10 @@ QString JKQTPGraphSymbols2String(JKQTPGraphSymbols pos) {
|
||||
while (s.size()<4) s="0"+s;
|
||||
return "symbol_filled_char"+s;
|
||||
}
|
||||
if (pos>=JKQTPFirstCustomSymbol) {
|
||||
QString s=QString::number(pos-JKQTPFirstCustomSymbol);
|
||||
return "symbol_custom"+s;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -177,6 +182,7 @@ QString JKQTPGraphSymbols2NameString(JKQTPGraphSymbols pos) {
|
||||
case JKQTPSymbolCount: JKQTPGraphSymbols2NameString(JKQTPMaxSymbolID);
|
||||
case JKQTPCharacterSymbol:
|
||||
case JKQTPFilledCharacterSymbol:
|
||||
case JKQTPFirstCustomSymbol:
|
||||
break;
|
||||
}
|
||||
if (pos>=JKQTPCharacterSymbol && pos<=JKQTPCharacterSymbol+0xFFFF) {
|
||||
@ -185,6 +191,9 @@ QString JKQTPGraphSymbols2NameString(JKQTPGraphSymbols pos) {
|
||||
if (pos>=JKQTPFilledCharacterSymbol && pos<=JKQTPFilledCharacterSymbol+0xFFFF) {
|
||||
return QObject::tr("filled character")+" '"+QChar(static_cast<uint16_t>(pos-JKQTPFilledCharacterSymbol))+"'";
|
||||
}
|
||||
if (pos>=JKQTPFirstCustomSymbol) {
|
||||
return QObject::tr("custom symbol %1").arg(static_cast<uint64_t>(pos-JKQTPFirstCustomSymbol));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos) {
|
||||
@ -279,6 +288,9 @@ JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos) {
|
||||
if (posT.startsWith("symbol_filled_char")) {
|
||||
return JKQTPFilledCharacterSymbol+posT.mid(18).toUInt(nullptr,16);
|
||||
}
|
||||
if (posT.startsWith("symbol_custom")) {
|
||||
return JKQTPFirstCustomSymbol+posT.mid(13).toUInt();
|
||||
}
|
||||
return JKQTPNoSymbol;
|
||||
}
|
||||
|
||||
@ -538,3 +550,18 @@ QList<QPolygonF> JKQTPSimplifyPolyLines(const QList<QPolygonF> &lines_in, double
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
QVector<JKQTPCustomGraphSymbolFunctor> JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore=QVector<JKQTPCustomGraphSymbolFunctor>();
|
||||
|
||||
JKQTPGraphSymbols JKQTPRegisterCustomGraphSymbol(JKQTPCustomGraphSymbolFunctor&& f)
|
||||
{
|
||||
JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore.emplace_back(std::move(f));
|
||||
return JKQTPFirstCustomSymbol+(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore.size()-1);
|
||||
}
|
||||
|
||||
JKQTPGraphSymbols JKQTPRegisterCustomGraphSymbol(const JKQTPCustomGraphSymbolFunctor& f)
|
||||
{
|
||||
JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore.emplace_back(f);
|
||||
return JKQTPFirstCustomSymbol+(JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore.size()-1);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include <QDebug>
|
||||
#include <QVector>
|
||||
#include <QGuiApplication>
|
||||
#include "jkqtcommon/jkqtpmathtools.h"
|
||||
#include "jkqtcommon/jkqtpcodestructuring.h"
|
||||
@ -46,6 +47,31 @@ class JKQTPEnhancedPainter; // forward
|
||||
|
||||
|
||||
|
||||
/** \brief functor used to draw a custom JKQTPGraphSymbols
|
||||
* \ingroup jkqtptools_drawing
|
||||
*
|
||||
* Draw the symbol with these properties:
|
||||
* - center at (0,0)
|
||||
* - width 1, i.e. x=-0.5...0.5
|
||||
* - height 1, i.e. y=-0.5...0.5
|
||||
* - you can assume that a proper pen and brush is set with the correct properties
|
||||
* - scaling to the final size is donw by JKQTPPlotSymbol()
|
||||
* - drawing is protected by surronding \c p.save(); and \c p.restore(); in JKQTPPlotSymbol()
|
||||
* .
|
||||
*
|
||||
* As an example, the following code-snippet:
|
||||
* \code
|
||||
* [](QPainter& p) {
|
||||
* p.drawEllipse(QPointF(-0.2, -0.2), 0.3, 0.3);
|
||||
* p.setBrush(Qt::NoBrush);
|
||||
* p.drawEllipse(QPointF(0.2, -0.2), 0.3, 0.3);
|
||||
* p.drawEllipse(QPointF(0, 0.2), 0.3, 0.3);
|
||||
* };
|
||||
* \endcode
|
||||
* generates this symbol: \image html symbols/symbol_custom.png
|
||||
*/
|
||||
typedef std::function<void(QPainter& p)> JKQTPCustomGraphSymbolFunctor;
|
||||
|
||||
/*! \brief tool class with static values used by JKQTPlotter/JKQTBasePlotter
|
||||
\ingroup jkqtptools_drawing
|
||||
*/
|
||||
@ -53,6 +79,11 @@ struct JKQTPlotterDrawingTools {
|
||||
/** \brief smallest linewidth any line in JKQTPlotter/JKQTBasePlotter may have
|
||||
*/
|
||||
static JKQTCOMMON_LIB_EXPORT const double ABS_MIN_LINEWIDTH;
|
||||
/** \brief stores all custom JKQTPGraphSymbols registered using JKQTPRegisterCustomGraphSymbol
|
||||
* \ingroup jkqtptools_drawing
|
||||
* \internal
|
||||
*/
|
||||
static JKQTCOMMON_LIB_EXPORT QVector<JKQTPCustomGraphSymbolFunctor> JKQTPCustomGraphSymbolStore;
|
||||
};
|
||||
|
||||
|
||||
@ -142,9 +173,11 @@ enum JKQTPGraphSymbols: uint64_t {
|
||||
\image html symbols/symbol_char_at.png "generated by JKQTPCharacterSymbol+QChar('@').unicode()"
|
||||
\image html symbols/symbol_char_club.png "generated by JKQTPCharacterSymbol+QChar(0x2663).unicode()" */
|
||||
JKQTPFilledCharacterSymbol=JKQTPCharacterSymbol+0xFFFF+0xF, /*!< \brief draw a font-character as symbol with defined outline-pen and fill-brush, you can use any character from a QFont by supplying \c JKQTPFilledCharacterSymbol+QChar('').unicode() as JKQTPGraphSymbols
|
||||
\image html symbols/symbol_filled_char_at.png "generated by JKQTPFilledCharacterSymbol+QChar('@').unicode()"
|
||||
\image html symbols/symbol_filled_char_club.png "generated by JKQTPFilledCharacterSymbol+QChar(0x2663).unicode()"
|
||||
*/
|
||||
\image html symbols/symbol_filled_char_at.png "generated by JKQTPFilledCharacterSymbol+QChar('@').unicode()"
|
||||
\image html symbols/symbol_filled_char_club.png "generated by JKQTPFilledCharacterSymbol+QChar(0x2663).unicode()"
|
||||
*/
|
||||
JKQTPFirstCustomSymbol=JKQTPFilledCharacterSymbol+0xFFFF+0xF, /*!< \brief draw a completely custom symbol, defined by supplying a functor to JKQTPRegisterCustomGraphSymbol()
|
||||
\image html symbols/symbol_custom.png "generated by <code>[](QPainter& p) { p.drawEllipse(QPointF(-0.2, -0.2), 0.3, 0.3); p.setBrush(Qt::NoBrush); p.drawEllipse(QPointF(0.2, -0.2), 0.3, 0.3); p.drawEllipse(QPointF(0, 0.2), 0.3, 0.3); };</code>" */
|
||||
};
|
||||
|
||||
inline JKQTPGraphSymbols operator+(JKQTPGraphSymbols a, uint8_t b) {
|
||||
@ -179,6 +212,25 @@ inline JKQTPGraphSymbols operator+(JKQTPGraphSymbols a, int64_t b) {
|
||||
return static_cast<JKQTPGraphSymbols>(static_cast<uint64_t>(a)+b);
|
||||
}
|
||||
|
||||
/** \brief register a JKQTPCustomGraphSymbolFunctor that draws a custom symbol.Returns an ID that allows to access the symbol!
|
||||
* \ingroup jkqtptools_drawing
|
||||
*
|
||||
* The functor is stored in the global/static store JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore, i.e. these are available throughout the runtime of the program
|
||||
*
|
||||
* \see JKQTPCustomGraphSymbolFunctor for an example
|
||||
*/
|
||||
JKQTCOMMON_LIB_EXPORT JKQTPGraphSymbols JKQTPRegisterCustomGraphSymbol(JKQTPCustomGraphSymbolFunctor&&);
|
||||
|
||||
/** \brief register a JKQTPCustomGraphSymbolFunctor that draws a custom symbol.Returns an ID that allows to access the symbol!
|
||||
* \ingroup jkqtptools_drawing
|
||||
*
|
||||
* The functor is stored in the global/static store JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore, i.e. these are available throughout the runtime of the program
|
||||
*
|
||||
* \see JKQTPCustomGraphSymbolFunctor for an example
|
||||
*/
|
||||
JKQTCOMMON_LIB_EXPORT JKQTPGraphSymbols JKQTPRegisterCustomGraphSymbol(const JKQTPCustomGraphSymbolFunctor&);
|
||||
|
||||
|
||||
/** \brief converts a JKQTPGraphSymbols variable into a identifier string
|
||||
* \ingroup jkqtptools_drawing
|
||||
*/
|
||||
@ -193,6 +245,40 @@ JKQTCOMMON_LIB_EXPORT QString JKQTPGraphSymbols2NameString(JKQTPGraphSymbols pos
|
||||
*/
|
||||
JKQTCOMMON_LIB_EXPORT JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos);
|
||||
|
||||
/*! \brief plot the specified symbol at pixel position x,y
|
||||
\ingroup jkqtptools_drawing
|
||||
|
||||
\tparam TPainter Type of \a painter: A class like JKQTPEnhancedPainter or <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
|
||||
\param painter the <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> to draw to
|
||||
\param x x-coordinate of the symbol center
|
||||
\param y y-coordinate of the symbol center
|
||||
\param symbol type of the symbol to plot, see JKQTPGraphSymbols
|
||||
\param size size (width/height) of the symbol around (\a x , \a y)
|
||||
\param symbolLineWidth width of the lines used to draw the symbol
|
||||
\param color color of the symbol lines
|
||||
\param fillColor color of the symbol filling
|
||||
\param symbolFont font used to draw symbols like \c JKQTPCharacterSymbol+QChar('@').unicode()
|
||||
|
||||
*/
|
||||
template <class TPainter>
|
||||
inline void JKQTPPlotSymbol(TPainter& painter, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor, QFont symbolFont);
|
||||
|
||||
/*! \brief plot the specified symbol at pixel position x,y
|
||||
\ingroup jkqtptools_drawing
|
||||
|
||||
\param paintDevice the paint device to draw on
|
||||
\param x x-coordinate of the symbol center
|
||||
\param y y-coordinate of the symbol center
|
||||
\param symbol type of the symbol to plot, see JKQTPGraphSymbols
|
||||
\param size size (width/height) of the symbol around (\a x , \a y)
|
||||
\param symbolLineWidth width of the lines used to draw the symbol
|
||||
\param color color of the symbol lines
|
||||
\param fillColor color of the symbol filling
|
||||
\param symbolFont font used to draw symbols like \c JKQTPCharacterSymbol+QChar('@').unicode()
|
||||
|
||||
*/
|
||||
JKQTCOMMON_LIB_EXPORT void JKQTPPlotSymbol(QPaintDevice& paintDevice, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor, const QFont &symbolFont);
|
||||
|
||||
|
||||
|
||||
|
||||
@ -286,40 +372,6 @@ inline void JKQTPPlotDecoratedLine(TPainter& painter, const QLineF& l, JKQTPLine
|
||||
/** \brief calculates the tail decorator size from the line width \a line_width, using decoratorSizeFactor and a non-linear scaling function that levels off towards small \a line_width and increases sub-linearly for large ones, so the arrow heads to not grow too much */
|
||||
JKQTCOMMON_LIB_EXPORT double JKQTPLineDecoratorStyleCalcDecoratorSize(double line_width, double decoratorSizeFactor);
|
||||
|
||||
/*! \brief plot the specified symbol at pixel position x,y
|
||||
\ingroup jkqtptools_drawing
|
||||
|
||||
\tparam TPainter Type of \a painter: A class like JKQTPEnhancedPainter or <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
|
||||
\param painter the <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> to draw to
|
||||
\param x x-coordinate of the symbol center
|
||||
\param y y-coordinate of the symbol center
|
||||
\param symbol type of the symbol to plot, see JKQTPGraphSymbols
|
||||
\param size size (width/height) of the symbol around (\a x , \a y)
|
||||
\param symbolLineWidth width of the lines used to draw the symbol
|
||||
\param color color of the symbol lines
|
||||
\param fillColor color of the symbol filling
|
||||
\param symbolFont font used to draw symbols like \c JKQTPCharacterSymbol+QChar('@').unicode()
|
||||
|
||||
*/
|
||||
template <class TPainter>
|
||||
inline void JKQTPPlotSymbol(TPainter& painter, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor, QFont symbolFont);
|
||||
|
||||
/*! \brief plot the specified symbol at pixel position x,y
|
||||
\ingroup jkqtptools_drawing
|
||||
|
||||
\param paintDevice the paint device to draw on
|
||||
\param x x-coordinate of the symbol center
|
||||
\param y y-coordinate of the symbol center
|
||||
\param symbol type of the symbol to plot, see JKQTPGraphSymbols
|
||||
\param size size (width/height) of the symbol around (\a x , \a y)
|
||||
\param symbolLineWidth width of the lines used to draw the symbol
|
||||
\param color color of the symbol lines
|
||||
\param fillColor color of the symbol filling
|
||||
\param symbolFont font used to draw symbols like \c JKQTPCharacterSymbol+QChar('@').unicode()
|
||||
|
||||
*/
|
||||
JKQTCOMMON_LIB_EXPORT void JKQTPPlotSymbol(QPaintDevice& paintDevice, double x, double y, JKQTPGraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor, const QFont &symbolFont);
|
||||
|
||||
|
||||
|
||||
|
||||
@ -873,6 +925,7 @@ inline void JKQTPPlotSymbol(TPainter& painter, double x, double y, JKQTPGraphSym
|
||||
case JKQTPSymbolCount:
|
||||
case JKQTPCharacterSymbol:
|
||||
case JKQTPFilledCharacterSymbol:
|
||||
case JKQTPFirstCustomSymbol:
|
||||
break;
|
||||
}
|
||||
if (symbol>=JKQTPCharacterSymbol && symbol<=JKQTPCharacterSymbol+0xFFFF) {
|
||||
@ -913,6 +966,17 @@ inline void JKQTPPlotSymbol(TPainter& painter, double x, double y, JKQTPGraphSym
|
||||
path.addText(0,0,symbolFont, ch),
|
||||
painter.drawPath(path);
|
||||
}
|
||||
if (symbol>=JKQTPFirstCustomSymbol) {
|
||||
const int idx(static_cast<int>(symbol-JKQTPFirstCustomSymbol));
|
||||
if (idx>=0 && idx<JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore.size()) {
|
||||
painter.setPen(p);
|
||||
painter.translate(QPointF(x,y));
|
||||
painter.scale(symbolSize,symbolSize);
|
||||
painter.setBrush(b);
|
||||
painter.setPen(pDescaled);
|
||||
JKQTPlotterDrawingTools::JKQTPCustomGraphSymbolStore[idx].operator()(painter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class TPainter>
|
||||
|
@ -105,6 +105,18 @@ int main(int argc, char* argv[])
|
||||
p.setPen(QPen(QColor("green"),0.5));
|
||||
//p.drawRect(2,2,iconsize-4,iconsize-4);
|
||||
stopPaintingAndSave(img, p, outputDir.absoluteFilePath("symbol_filled_char_club.png"));
|
||||
|
||||
JKQTPCustomGraphSymbolFunctor f=[](QPainter& p) {
|
||||
p.drawEllipse(QPointF(-0.2, -0.2), 0.3, 0.3);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawEllipse(QPointF(0.2, -0.2), 0.3, 0.3);
|
||||
p.drawEllipse(QPointF(0, 0.2), 0.3, 0.3);
|
||||
};
|
||||
JKQTPGraphSymbols customs=JKQTPRegisterCustomGraphSymbol(f);
|
||||
startPainting(img, p, iconsize, backgroundColor);
|
||||
JKQTPPlotSymbol(p, iconsize/2,iconsize/2,customs,iconsize-4,2,QColor("blue"), QColor("salmon").lighter(120),QGuiApplication::font().family());
|
||||
p.setPen(QPen(QColor("green"),0.5));
|
||||
stopPaintingAndSave(img, p, outputDir.absoluteFilePath("symbol_custom.png"));
|
||||
}
|
||||
|
||||
if (listlinedecorators) {
|
||||
|
Loading…
Reference in New Issue
Block a user