reworked the functions that allow to specify how JKQTPlotter reacts to mouse single-click actions

This commit is contained in:
Jan W. Krieger 2019-01-27 23:24:12 +01:00
parent dabc061de9
commit 75d8fc8314
5 changed files with 377 additions and 227 deletions

View File

@ -97,20 +97,59 @@ TestUserInteraction::TestUserInteraction(QWidget *parent) :
connect(chkZoomByMouseWheel, SIGNAL(toggled(bool)), plot, SLOT(setZoomByMouseWheel(bool)));
// add a QComboBox that allows to set the left mouse button action for the JKQTPlotter
cmbMouseAction=new QComboBox(this);
layForm->addRow("mouse action:", cmbMouseAction);
cmbMouseAction->addItem("NoMouseAction");
cmbMouseAction->addItem("PanPlotOnMove");
cmbMouseAction->addItem("PanPlotOnRelease");
cmbMouseAction->addItem("ZoomRectangle");
cmbMouseAction->addItem("RectangleEvents");
cmbMouseAction->addItem("CircleEvents");
cmbMouseAction->addItem("EllipseEvents");
cmbMouseAction->addItem("LineEvents");
cmbMouseAction->addItem("ScribbleEvents");
cmbMouseAction->addItem("ClickEvents");
connect(cmbMouseAction, SIGNAL(currentIndexChanged(int)), this, SLOT(setLeftMouseAction(int)));
setLeftMouseAction(cmbMouseAction->currentIndex());
cmbLeftNoModMouseAction=new QComboBox(this);
layForm->addRow("mouse action: left-click, no modifiers", cmbLeftNoModMouseAction);
cmbLeftNoModMouseAction->addItem("PanPlotOnMove");
cmbLeftNoModMouseAction->addItem("PanPlotOnRelease");
cmbLeftNoModMouseAction->addItem("ZoomRectangle");
cmbLeftNoModMouseAction->addItem("RectangleEvents");
cmbLeftNoModMouseAction->addItem("CircleEvents");
cmbLeftNoModMouseAction->addItem("EllipseEvents");
cmbLeftNoModMouseAction->addItem("LineEvents");
cmbLeftNoModMouseAction->addItem("ScribbleEvents");
cmbLeftNoModMouseAction->addItem("NoMouseAction");
cmbLeftNoModMouseAction->setCurrentIndex(2);
connect(cmbLeftNoModMouseAction, SIGNAL(currentIndexChanged(int)), this, SLOT(setLeftMouseAction(int)));
setLeftMouseAction(cmbLeftNoModMouseAction->currentIndex());
// add a QComboBox that allows to set the left mouse button action for the JKQTPlotter
cmbLeftCtrlModMouseAction=new QComboBox(this);
layForm->addRow("mouse action: left-click, Ctrl modifier", cmbLeftCtrlModMouseAction);
cmbLeftCtrlModMouseAction->addItem("PanPlotOnMove");
cmbLeftCtrlModMouseAction->addItem("PanPlotOnRelease");
cmbLeftCtrlModMouseAction->addItem("ZoomRectangle");
cmbLeftCtrlModMouseAction->addItem("RectangleEvents");
cmbLeftCtrlModMouseAction->addItem("CircleEvents");
cmbLeftCtrlModMouseAction->addItem("EllipseEvents");
cmbLeftCtrlModMouseAction->addItem("LineEvents");
cmbLeftCtrlModMouseAction->addItem("ScribbleEvents");
cmbLeftCtrlModMouseAction->addItem("NoMouseAction");
cmbLeftCtrlModMouseAction->setCurrentIndex(0);
connect(cmbLeftCtrlModMouseAction, SIGNAL(currentIndexChanged(int)), this, SLOT(setLeftCtrlMouseAction(int)));
setLeftCtrlMouseAction(cmbLeftCtrlModMouseAction->currentIndex());
// add a QComboBox that allows to set the left mouse button action for the JKQTPlotter
cmbRightNoModMouseAction=new QComboBox(this);
layForm->addRow("mouse action: right-click, no modifiers", cmbRightNoModMouseAction);
cmbRightNoModMouseAction->addItem("PanPlotOnMove");
cmbRightNoModMouseAction->addItem("PanPlotOnRelease");
cmbRightNoModMouseAction->addItem("ZoomRectangle");
cmbRightNoModMouseAction->addItem("RectangleEvents");
cmbRightNoModMouseAction->addItem("CircleEvents");
cmbRightNoModMouseAction->addItem("EllipseEvents");
cmbRightNoModMouseAction->addItem("LineEvents");
cmbRightNoModMouseAction->addItem("ScribbleEvents");
cmbRightNoModMouseAction->addItem("ContextMenu");
cmbRightNoModMouseAction->setCurrentIndex(5);
connect(cmbRightNoModMouseAction, SIGNAL(currentIndexChanged(int)), this, SLOT(setRightMouseAction(int)));
setRightMouseAction(cmbRightNoModMouseAction->currentIndex());
// add a QComboBox that allows to set whether the right mouse button may show the context menu on a single click
chkRightClickShowsContextMenu=new QCheckBox(this);
chkRightClickShowsContextMenu->setChecked(plot->isRightClickShowsContextMenuEnabled());
layForm->addRow("mouse action: right-click shows context menu:", chkRightClickShowsContextMenu);
connect(chkRightClickShowsContextMenu, SIGNAL(toggled(bool)), plot, SLOT(enableRightClickShowsContextMenu(bool)));
// and add a QLabel to show the different events of the JKQTPlotter:
labMouseMoved=new QLabel(this);
layForm->addRow("last mouse moved:", labMouseMoved);
@ -124,7 +163,6 @@ TestUserInteraction::TestUserInteraction(QWidget *parent) :
connect(plot, SIGNAL(plotNewZoomRectangle(double, double, double, double, Qt::KeyboardModifiers)), this, SLOT(plotNewZoomRectangle(double, double, double, double, Qt::KeyboardModifiers)));
connect(plot, SIGNAL(contextMenuOpened(double, double, QMenu*)), this, SLOT(contextMenuOpened(double, double, QMenu*)));
connect(plot, SIGNAL(zoomChangedLocally(double, double, double, double, JKQTPlotter*)), this, SLOT(zoomChangedLocally(double, double, double, double, JKQTPlotter*)));
connect(plot, SIGNAL(userClickFinished(double, double, Qt::KeyboardModifiers)), this, SLOT(userClickFinished(double, double, Qt::KeyboardModifiers)));
connect(plot, SIGNAL(userScribbleClick(double, double, Qt::KeyboardModifiers, bool, bool)), this, SLOT(userScribbleClick(double, double, Qt::KeyboardModifiers, bool, bool)));
connect(plot, SIGNAL(userRectangleFinished(double, double, double, double, Qt::KeyboardModifiers)), this, SLOT(userRectangleFinished(double, double, double, double, Qt::KeyboardModifiers)));
connect(plot, SIGNAL(userLineFinished(double, double, double, double, Qt::KeyboardModifiers)), this, SLOT(userLineFinished(double, double, double, double, Qt::KeyboardModifiers)));
@ -138,7 +176,20 @@ TestUserInteraction::TestUserInteraction(QWidget *parent) :
void TestUserInteraction::setLeftMouseAction(int index)
{
plot->setMouseActionMode(static_cast<JKQTPlotter::MouseActionModes>(index));
if (index==cmbLeftNoModMouseAction->count()-1) plot->deregisterMouseDragAction(Qt::LeftButton, Qt::NoModifier);
else plot->registerMouseDragAction(Qt::LeftButton, Qt::NoModifier, static_cast<JKQTPlotter::MouseActionMode>(index));
}
void TestUserInteraction::setLeftCtrlMouseAction(int index)
{
if (index==cmbLeftCtrlModMouseAction->count()-1) plot->deregisterMouseDragAction(Qt::LeftButton, Qt::ControlModifier);
else plot->registerMouseDragAction(Qt::LeftButton, Qt::ControlModifier, static_cast<JKQTPlotter::MouseActionMode>(index));
}
void TestUserInteraction::setRightMouseAction(int index)
{
if (index==cmbRightNoModMouseAction->count()-1) plot->deregisterMouseDragAction(Qt::RightButton, Qt::NoModifier);
else plot->registerMouseDragAction(Qt::RightButton, Qt::NoModifier, static_cast<JKQTPlotter::MouseActionMode>(index));
}
void TestUserInteraction::setPlotMagnification(int index)
@ -182,11 +233,6 @@ void TestUserInteraction::zoomChangedLocally(double newxmin, double newxmax, dou
labMouseAction->setText(QString("zoomChangedLocally(x=%1..%2, y=%3..%4)").arg(newxmin).arg(newxmax).arg(newymin).arg(newymax));
}
void TestUserInteraction::userClickFinished(double x, double y, Qt::KeyboardModifiers modifiers)
{
labMouseAction->setText(QString("userClickFinished(%1, %2, modifiers=%3)").arg(x).arg(y).arg(KeyboradMod2String(modifiers)));
}
void TestUserInteraction::userScribbleClick(double x, double y, Qt::KeyboardModifiers modifiers, bool first, bool last)
{
static int counter=0;
@ -207,12 +253,12 @@ void TestUserInteraction::userLineFinished(double x1, double y1, double x2, doub
void TestUserInteraction::userCircleFinished(double x, double y, double radius, Qt::KeyboardModifiers modifiers)
{
labMouseAction->setText(QString("userRectangleFinished(x=%1, y=%2, radius=%3, modifiers=%4)").arg(x).arg(y).arg(radius).arg(KeyboradMod2String(modifiers)));
labMouseAction->setText(QString("userCircleFinished(x=%1, y=%2, radius=%3, modifiers=%4)").arg(x).arg(y).arg(radius).arg(KeyboradMod2String(modifiers)));
}
void TestUserInteraction::userEllipseFinished(double x, double y, double radiusX, double radiusY, Qt::KeyboardModifiers modifiers)
{
labMouseAction->setText(QString("userRectangleFinished(x=%1, y=%2, radiusX=%3, radiusY=%4, modifiers=%5)").arg(x).arg(y).arg(radiusX).arg(radiusY).arg(KeyboradMod2String(modifiers)));
labMouseAction->setText(QString("userEllipseFinished(x=%1, y=%2, radiusX=%3, radiusY=%4, modifiers=%5)").arg(x).arg(y).arg(radiusX).arg(radiusY).arg(KeyboradMod2String(modifiers)));
}
QString TestUserInteraction::KeyboradMod2String(Qt::KeyboardModifiers modifiers) {

View File

@ -22,6 +22,8 @@ class TestUserInteraction : public QMainWindow
public slots:
void setLeftMouseAction(int index);
void setLeftCtrlMouseAction(int index);
void setRightMouseAction(int index);
void setPlotMagnification(int index);
void plotMouseMove(double x, double y);
@ -30,7 +32,6 @@ class TestUserInteraction : public QMainWindow
void plotNewZoomRectangle(double mouseDragRectXStart, double mouseDragRectXEnd, double mouseDragRectYStart, double mouseDragRectYEnd, Qt::KeyboardModifiers modifiers);
void contextMenuOpened(double x, double y, QMenu* contextMenu);
void zoomChangedLocally(double newxmin, double newxmax, double newymin, double newymax, JKQTPlotter* sender);
void userClickFinished(double x, double y, Qt::KeyboardModifiers modifiers);
void userScribbleClick(double x, double y, Qt::KeyboardModifiers modifiers, bool first, bool last);
void userRectangleFinished(double x, double y, double width, double height, Qt::KeyboardModifiers modifiers);
void userLineFinished(double x1, double y1, double x2, double y2, Qt::KeyboardModifiers modifiers);
@ -47,7 +48,10 @@ class TestUserInteraction : public QMainWindow
QCheckBox* chkShowToolbar;
QCheckBox* chkToolbarAlwaysOn;
QCheckBox* chkGrid;
QComboBox* cmbMouseAction;
QComboBox* cmbLeftNoModMouseAction;
QComboBox* cmbLeftCtrlModMouseAction;
QComboBox* cmbRightNoModMouseAction;
QCheckBox* chkRightClickShowsContextMenu;
QCheckBox* chkLogX;
QCheckBox* chkLogY;
QCheckBox* chkZoomByMouseWheel;

View File

@ -3390,10 +3390,10 @@ void JKQTMathText::useXITS()
//fontSans=fam;
fontMathRoman=fam;
fontMathSans=fam;
fontTypewriter=fam;
//fontTypewriter=fam;
fontBlackboard=fam;
fontCaligraphic=fam;
fontScript=fam;
//fontCaligraphic=fam;
//fontScript=fam;
fontBraces=fam;
fontSymbol=fam;
fontGreek=fam;

View File

@ -106,8 +106,10 @@ void JKQTPlotter::init(bool datastore_internal, QWidget* parent, JKQTPDatastore*
displayMousePosition=true;
displayToolbar=true;
toolbarAlwaysOn=false;
mouseActionMode=JKQTPlotter::ZoomRectangle;
//zoomByDoubleAndRightMouseClick=true;
rightClickShowsContextMenu=true;
registerMouseDragAction(Qt::LeftButton, Qt::NoModifier, MouseActionMode::ZoomRectangle);
registerMouseDragAction(Qt::LeftButton, Qt::ControlModifier, MouseActionMode::PanPlotOnMove);
zoomByMouseWheel=true;
setMouseTracking(true);
@ -231,18 +233,6 @@ QPainter::CompositionMode JKQTPlotter::getUserActionCompositionMode() const
return this->userActionCompositionMode;
}
void JKQTPlotter::setMouseActionMode(const JKQTPlotter::MouseActionModes &__value)
{
if (this->mouseActionMode != __value) {
this->mouseActionMode = __value;
updateCursor();
}
}
JKQTPlotter::MouseActionModes JKQTPlotter::getMouseActionMode() const
{
return this->mouseActionMode;
}
void JKQTPlotter::loadSettings(const QSettings& settings, const QString& group) {
plotter->loadSettings(settings, group);
@ -265,7 +255,7 @@ void JKQTPlotter::saveSettings(QSettings& settings, const QString& group) const
void JKQTPlotter::paintUserAction() {
if (mouseDragingRectangle) {
if (currentMouseDragAction.isValid() && mouseDragingRectangle) {
image=oldImage;
if (image.width()>0 && image.height()>0 && !image.isNull()) {
JKQTPEnhancedPainter painter(&image);
@ -283,22 +273,22 @@ void JKQTPlotter::paintUserAction() {
double y2=plotter->y2p(mouseDragRectYEnd)*magnification;
double dx=x2-x1;
double dy=y2-y1;
if ((mouseActionMode==JKQTPlotter::ZoomRectangle) || (mouseActionMode==JKQTPlotter::RectangleEvents)) {
if ((currentMouseDragAction.mode==JKQTPlotter::ZoomRectangle) || (currentMouseDragAction.mode==JKQTPlotter::RectangleEvents)) {
painter.setOpacity(0.2);
painter.fillRect(QRectF(x1, y1, x2-x1, y2-y1), QBrush(userActionColor));
painter.setOpacity(1.0);
painter.drawRect(QRectF(x1, y1, x2-x1, y2-y1));
} else if (mouseActionMode==JKQTPlotter::CircleEvents) {
} else if (currentMouseDragAction.mode==JKQTPlotter::CircleEvents) {
QColor zc=userActionColor;
zc.setAlphaF(0.2);
painter.setBrush(QBrush(zc));
painter.drawEllipse(QPointF(x1, y1), qMin(fabs(dx), fabs(dy)), qMin(fabs(dx), fabs(dy)));
} else if (mouseActionMode==JKQTPlotter::EllipseEvents) {
} else if (currentMouseDragAction.mode==JKQTPlotter::EllipseEvents) {
QColor zc=userActionColor;
zc.setAlphaF(0.2);
painter.setBrush(QBrush(zc));
painter.drawEllipse(QPointF(x1, y1), fabs(dx), fabs(dy));
} else if (mouseActionMode==JKQTPlotter::LineEvents) {
} else if (currentMouseDragAction.mode==JKQTPlotter::LineEvents) {
QPen pp=p;
pp.setColor(userActionColor);
painter.setPen(pp);
@ -329,50 +319,52 @@ void JKQTPlotter::mouseMoveEvent ( QMouseEvent * event ) {
if (!displayToolbar) {
toolbar->hide();
}
if (( (mouseActionMode==JKQTPlotter::ZoomRectangle) ||
(mouseActionMode==JKQTPlotter::RectangleEvents) ||
(mouseActionMode==JKQTPlotter::CircleEvents) ||
(mouseActionMode==JKQTPlotter::EllipseEvents) ||
(mouseActionMode==JKQTPlotter::ScribbleEvents) ||
(mouseActionMode==JKQTPlotter::PanPlotOnMove) ||
(mouseActionMode==JKQTPlotter::PanPlotOnRelease) ||
(mouseActionMode==JKQTPlotter::LineEvents) ) &&
mouseDragingRectangle && (event->buttons() & Qt::LeftButton))
{
if (mouseActionMode==JKQTPlotter::ScribbleEvents || mouseActionMode==JKQTPlotter::PanPlotOnMove) {
// start is last event position
mouseDragRectXStart=mouseDragRectXEnd;
mouseDragRectYStart=mouseDragRectYEnd;
mouseDragRectXStartPixel=mouseDragRectXEndPixel;
mouseDragRectYStartPixel=mouseDragRectYEndPixel;
}
mouseDragRectXEnd=plotter->p2x(event->x()/magnification);
mouseDragRectYEnd=plotter->p2y((event->y()-getPlotYOffset())/magnification);
mouseDragRectXEndPixel=event->x();
mouseDragRectYEndPixel=event->y();
paintUserAction();
event->accept();
//std::cout<<mouseZoomingTStart<<" -- "<<mouseZoomingTEnd<<std::endl;
if (mouseActionMode==JKQTPlotter::ZoomRectangle) {
emit plotNewZoomRectangle(mouseDragRectXStart, mouseDragRectXEnd, mouseDragRectYStart, mouseDragRectYEnd, event->modifiers());
}
if ((mouseActionMode==JKQTPlotter::ScribbleEvents) && ((mouseDragRectXStart!=mouseDragRectXEnd) || (mouseDragRectYStart!=mouseDragRectYEnd)) ) {
emit userScribbleClick(mouseDragRectXEnd, mouseDragRectYEnd, event->modifiers(), false, false);
}
if ((mouseActionMode==JKQTPlotter::PanPlotOnMove) && ((mouseDragRectXStart!=mouseDragRectXEnd) || (mouseDragRectYStart!=mouseDragRectYEnd)) ) {
QRectF zoomRect= QRectF(QPointF(plotter->x2p(getXAxis()->getMin()),plotter->y2p(getYAxis()->getMax())), QPointF(plotter->x2p(getXAxis()->getMax()),plotter->y2p(getYAxis()->getMin())));
if ( (mouseLastClickX/magnification<plotter->getInternalPlotBorderLeft()) || (mouseLastClickX/magnification>plotter->getPlotWidth()+plotter->getInternalPlotBorderLeft()) ) {
zoomRect.translate(0, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
} else if (((mouseLastClickY-getPlotYOffset())/magnification<plotter->getInternalPlotBorderTop()) || ((mouseLastClickY-getPlotYOffset())/magnification>plotter->getPlotHeight()+plotter->getInternalPlotBorderTop()) ) {
zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, 0);
} else {
zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
if (currentMouseDragAction.isValid()) {
if (( (currentMouseDragAction.mode==JKQTPlotter::ZoomRectangle) ||
(currentMouseDragAction.mode==JKQTPlotter::RectangleEvents) ||
(currentMouseDragAction.mode==JKQTPlotter::CircleEvents) ||
(currentMouseDragAction.mode==JKQTPlotter::EllipseEvents) ||
(currentMouseDragAction.mode==JKQTPlotter::ScribbleEvents) ||
(currentMouseDragAction.mode==JKQTPlotter::PanPlotOnMove) ||
(currentMouseDragAction.mode==JKQTPlotter::PanPlotOnRelease) ||
(currentMouseDragAction.mode==JKQTPlotter::LineEvents) ) &&
mouseDragingRectangle)
{
if (currentMouseDragAction.mode==JKQTPlotter::ScribbleEvents || currentMouseDragAction.mode==JKQTPlotter::PanPlotOnMove) {
// start is last event position
mouseDragRectXStart=mouseDragRectXEnd;
mouseDragRectYStart=mouseDragRectYEnd;
mouseDragRectXStartPixel=mouseDragRectXEndPixel;
mouseDragRectYStartPixel=mouseDragRectYEndPixel;
}
mouseDragRectXEnd=plotter->p2x(event->x()/magnification);
mouseDragRectYEnd=plotter->p2y((event->y()-getPlotYOffset())/magnification);
mouseDragRectXEndPixel=event->x();
mouseDragRectYEndPixel=event->y();
paintUserAction();
event->accept();
//std::cout<<mouseZoomingTStart<<" -- "<<mouseZoomingTEnd<<std::endl;
if (currentMouseDragAction.mode==JKQTPlotter::ZoomRectangle) {
emit plotNewZoomRectangle(mouseDragRectXStart, mouseDragRectXEnd, mouseDragRectYStart, mouseDragRectYEnd, event->modifiers());
}
setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()));
if ((currentMouseDragAction.mode==JKQTPlotter::ScribbleEvents) && ((mouseDragRectXStart!=mouseDragRectXEnd) || (mouseDragRectYStart!=mouseDragRectYEnd)) ) {
emit userScribbleClick(mouseDragRectXEnd, mouseDragRectYEnd, event->modifiers(), false, false);
}
if ((currentMouseDragAction.mode==JKQTPlotter::PanPlotOnMove) && ((mouseDragRectXStart!=mouseDragRectXEnd) || (mouseDragRectYStart!=mouseDragRectYEnd)) ) {
QRectF zoomRect= QRectF(QPointF(plotter->x2p(getXAxis()->getMin()),plotter->y2p(getYAxis()->getMax())), QPointF(plotter->x2p(getXAxis()->getMax()),plotter->y2p(getYAxis()->getMin())));
if ( (mouseLastClickX/magnification<plotter->getInternalPlotBorderLeft()) || (mouseLastClickX/magnification>plotter->getPlotWidth()+plotter->getInternalPlotBorderLeft()) ) {
zoomRect.translate(0, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
} else if (((mouseLastClickY-getPlotYOffset())/magnification<plotter->getInternalPlotBorderTop()) || ((mouseLastClickY-getPlotYOffset())/magnification>plotter->getPlotHeight()+plotter->getInternalPlotBorderTop()) ) {
zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, 0);
} else {
zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
}
setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()));
}
} else {
event->accept();
/*if (emitSignals)*/ //emit plotMouseMove(x, y);
}
} else {
event->accept();
/*if (emitSignals)*/ //emit plotMouseMove(x, y);
}
// emit clicked signal, if event occured inside plot only
@ -380,54 +372,34 @@ void JKQTPlotter::mouseMoveEvent ( QMouseEvent * event ) {
((event->y()-getPlotYOffset())/magnification>=plotter->getInternalPlotBorderTop()) && ((event->y()-getPlotYOffset())/magnification<=plotter->getPlotHeight()+plotter->getInternalPlotBorderTop()) ) {
emit plotMouseMove(plotter->p2x(event->x()/magnification), plotter->p2y((event->y()-getPlotYOffset())/magnification));
}
updateCursor();
}
void JKQTPlotter::mousePressEvent ( QMouseEvent * event ){
if (event->button()==Qt::LeftButton) {
mouseLastClickX=event->x();
mouseLastClickY=event->y();
if ( (mouseActionMode!=JKQTPlotter::NoMouseAction))
{
mouseDragRectXStart=plotter->p2x(event->x()/magnification);
mouseDragRectYStart=plotter->p2y((event->y()-getPlotYOffset())/magnification);
mouseDragRectXEndPixel=mouseDragRectXStartPixel=event->x();
mouseDragRectYEndPixel=mouseDragRectYStartPixel=event->y();
mouseDragingRectangle=true;
oldImage=image;
event->accept();
if (mouseActionMode==JKQTPlotter::ScribbleEvents) emit userScribbleClick(mouseDragRectXStart, mouseDragRectYStart, event->modifiers(), true, false);
if (mouseActionMode==JKQTPlotter::ClickEvents) emit userClickFinished(mouseDragRectXStart, mouseDragRectYStart, event->modifiers());
}
} else if (event->button()==Qt::RightButton) {
mouseLastClickX=event->x();
mouseLastClickY=event->y();
if (rightMouseButtonAction==JKQTPlotter::RightMouseButtonZoom) {
double xmin=plotter->p2x((long)round(static_cast<double>(plotter->getInternalPlotBorderLeft())-static_cast<double>(plotter->getPlotWidth())/2.0));
double xmax=plotter->p2x((long)round(static_cast<double>(plotter->getInternalPlotBorderLeft())+1.5*static_cast<double>(plotter->getPlotWidth())));
double ymin=plotter->p2y((long)round(static_cast<double>(plotter->getInternalPlotBorderTop())+1.5*static_cast<double>(plotter->getPlotHeight())));
double ymax=plotter->p2y((long)round(static_cast<double>(plotter->getInternalPlotBorderTop())-static_cast<double>(plotter->getPlotHeight())/2.0));
if (plotter->getXAxis()->isLogAxis()) {
if (xmin<=0) xmin=1;
if (xmax<=0) xmax=10;
}
if (plotter->getYAxis()->isLogAxis()) {
if (ymin<=0) ymin=1;
if (ymax<=0) ymax=10;
}
/*plotter->getXAxis->setRange(xmin, xmax);
plotter->getYAxis->setRange(ymin, ymax);*/
//redrawPlot();
/*if (plotter->isEmittingSignalsEnabled())*/ emit zoomChangedLocally(xmin, xmax, ymin, ymax, this);
plotter->setXY(xmin, xmax, ymin, ymax);
//update();
event->accept();
} else if (rightMouseButtonAction==JKQTPlotter::RightMouseButtonContextMenu) {
openContextMenu(event->x(), event->y());
event->accept();
}
void JKQTPlotter::mousePressEvent ( QMouseEvent * event ){
currentMouseDragAction.clear();
auto actionIT=findMatchingMouseDragAction(event->button(), event->modifiers());
if (actionIT!=registeredMouseActionModes.end()) {
// we found a matching action
currentMouseDragAction=MouseDragAction(actionIT.key().first, actionIT.key().second, actionIT.value());
mouseLastClickX=event->x();
mouseLastClickY=event->y();
mouseDragRectXStart=plotter->p2x(event->x()/magnification);
mouseDragRectYStart=plotter->p2y((event->y()-getPlotYOffset())/magnification);
mouseDragRectXEndPixel=mouseDragRectXStartPixel=event->x();
mouseDragRectYEndPixel=mouseDragRectYStartPixel=event->y();
mouseDragingRectangle=true;
oldImage=image;
if (currentMouseDragAction.mode==JKQTPlotter::ScribbleEvents) emit userScribbleClick(mouseDragRectXStart, mouseDragRectYStart, event->modifiers(), true, false);
event->accept();
} else if (event->button()==Qt::RightButton && event->modifiers()==Qt::NoModifier && rightClickShowsContextMenu) {
mouseLastClickX=event->x();
mouseLastClickY=event->y();
openContextMenu(event->x(), event->y());
event->accept();
}
// emit clicked signal, if event occured inside plot only
@ -436,13 +408,14 @@ void JKQTPlotter::mousePressEvent ( QMouseEvent * event ){
emit plotMouseClicked(plotter->p2x(event->x()/magnification), plotter->p2y((event->y()-getPlotYOffset())/magnification), event->modifiers(), event->button());
event->accept();
}
updateCursor();
}
void JKQTPlotter::mouseReleaseEvent ( QMouseEvent * event ){
if ((event->flags()&Qt::MouseEventCreatedDoubleClick)==Qt::MouseEventCreatedDoubleClick) {
return;
}
if (mouseDragingRectangle && event->button()==Qt::LeftButton) {
if (currentMouseDragAction.isValid()) {
mouseDragRectXEnd=plotter->p2x(event->x()/magnification);
mouseDragRectYEnd=plotter->p2y((event->y()-getPlotYOffset())/magnification);
mouseDragRectXEndPixel=event->x();
@ -458,7 +431,7 @@ void JKQTPlotter::mouseReleaseEvent ( QMouseEvent * event ){
double y2=mouseDragRectYEnd;
if ((mouseDragRectXStart!=mouseDragRectXEnd) && (mouseDragRectYStart!=mouseDragRectYEnd)) {
if (mouseActionMode==JKQTPlotter::ZoomRectangle) {
if (currentMouseDragAction.mode==JKQTPlotter::ZoomRectangle) {
double xmin=mouseDragRectXStart;
double xmax=mouseDragRectXEnd;
@ -467,7 +440,7 @@ void JKQTPlotter::mouseReleaseEvent ( QMouseEvent * event ){
emit zoomChangedLocally(xmin, xmax, ymin, ymax, this);
plotter->setXY(xmin, xmax, ymin, ymax);
} else if (mouseActionMode==JKQTPlotter::PanPlotOnRelease) {
} else if (currentMouseDragAction.mode==JKQTPlotter::PanPlotOnRelease) {
QRectF zoomRect= QRectF(QPointF(plotter->x2p(getXAxis()->getMin()),plotter->y2p(getYAxis()->getMax())), QPointF(plotter->x2p(getXAxis()->getMax()),plotter->y2p(getYAxis()->getMin())));
if ( (mouseLastClickX/magnification<plotter->getInternalPlotBorderLeft()) || (mouseLastClickX/magnification>plotter->getPlotWidth()+plotter->getInternalPlotBorderLeft()) ) {
zoomRect.translate(0, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
@ -477,22 +450,23 @@ void JKQTPlotter::mouseReleaseEvent ( QMouseEvent * event ){
zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
}
setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()));
} else if (mouseActionMode==JKQTPlotter::RectangleEvents) {
} else if (currentMouseDragAction.mode==JKQTPlotter::RectangleEvents) {
emit userRectangleFinished(x1, y1, x2-x1, y2-y1, event->modifiers());
} else if (mouseActionMode==JKQTPlotter::CircleEvents) {
} else if (currentMouseDragAction.mode==JKQTPlotter::CircleEvents) {
emit userCircleFinished(x1, y1, qMin(fabs(x2-x1), fabs(y2-y1)), event->modifiers());
} else if (mouseActionMode==JKQTPlotter::EllipseEvents) {
} else if (currentMouseDragAction.mode==JKQTPlotter::EllipseEvents) {
emit userEllipseFinished(x1, y1, fabs(x2-x1), fabs(y2-y1), event->modifiers());
} else if (mouseActionMode==JKQTPlotter::LineEvents) {
} else if (currentMouseDragAction.mode==JKQTPlotter::LineEvents) {
emit userLineFinished(x1, y1, x2, y2, event->modifiers());
} else if (mouseActionMode==JKQTPlotter::ScribbleEvents) {
emit userScribbleClick(x1, y1, event->modifiers(), false, true);
}
}
if (mouseActionMode!=JKQTPlotter::ZoomRectangle) update();
if (currentMouseDragAction.mode!=JKQTPlotter::ZoomRectangle) update();
if (currentMouseDragAction.mode==JKQTPlotter::ScribbleEvents) emit userScribbleClick(x1, y1, event->modifiers(), false, true);
event->accept();
}
currentMouseDragAction.clear();
updateCursor();
}
void JKQTPlotter::mouseDoubleClickEvent ( QMouseEvent * event ){
@ -531,18 +505,22 @@ void JKQTPlotter::mouseDoubleClickEvent ( QMouseEvent * event ){
emit plotMouseDoubleClicked(plotter->p2x(event->x()/magnification), plotter->p2y((event->y()-getPlotYOffset())/magnification), event->modifiers(), event->button());
} else { event->ignore(); }
updateCursor();
currentMouseDragAction.clear();
}
void JKQTPlotter::keyReleaseEvent(QKeyEvent *event) {
QWidget::keyPressEvent(event);
if (event->key()==Qt::Key_Escape && event->modifiers()==Qt::NoModifier) {
if (mouseDragingRectangle) {
if (mouseDragingRectangle || currentMouseDragAction.isValid()) {
mouseDragingRectangle=false;
image=oldImage;
currentMouseDragAction.clear();
update();
event->accept();
}
}
updateCursor();
}
void JKQTPlotter::wheelEvent ( QWheelEvent * event ) {
@ -560,6 +538,8 @@ void JKQTPlotter::wheelEvent ( QWheelEvent * event ) {
} else {
event->ignore();
}
updateCursor();
currentMouseDragAction.clear();
}
int JKQTPlotter::getPlotYOffset() {
@ -644,36 +624,38 @@ void JKQTPlotter::initContextMenu()
void JKQTPlotter::updateCursor() {
if (mouseActionMode==JKQTPlotter::ZoomRectangle) {
QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_zoom.png");
QBitmap mask(":/JKQTPlotter/jkqtp_cursor_zoom_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (mouseActionMode==JKQTPlotter::RectangleEvents) {
QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_rectangle.png");
QBitmap mask(":/JKQTPlotter/jkqtp_cursor_rectangle_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (mouseActionMode==JKQTPlotter::PanPlotOnMove || mouseActionMode==JKQTPlotter::PanPlotOnRelease) {
setCursor(QCursor(Qt::OpenHandCursor));
} else if (mouseActionMode==JKQTPlotter::CircleEvents) {
QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_circle.png");
QBitmap mask(":/JKQTPlotter/jkqtp_cursor_circle_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (mouseActionMode==JKQTPlotter::EllipseEvents) {
QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_ellipse.png");
QBitmap mask(":/JKQTPlotter/jkqtp_cursor_ellipse_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (mouseActionMode==JKQTPlotter::LineEvents) {
QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_line.png");
QBitmap mask(":/JKQTPlotter/jkqtp_cursor_line_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (mouseActionMode==JKQTPlotter::ClickEvents) {
setCursor(QCursor(Qt::CrossCursor));
} else if (mouseActionMode==JKQTPlotter::ScribbleEvents) {
QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_scribble.png");
QBitmap mask(":/JKQTPlotter/jkqtp_cursor_scribble_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else {
if (!currentMouseDragAction.isValid()) {
setCursor(QCursor(Qt::ArrowCursor));
} else {
if (currentMouseDragAction.mode==JKQTPlotter::ZoomRectangle) {
static QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_zoom.png");
static QBitmap mask(":/JKQTPlotter/jkqtp_cursor_zoom_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (currentMouseDragAction.mode==JKQTPlotter::RectangleEvents) {
static QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_rectangle.png");
static QBitmap mask(":/JKQTPlotter/jkqtp_cursor_rectangle_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (currentMouseDragAction.mode==JKQTPlotter::PanPlotOnMove || currentMouseDragAction.mode==JKQTPlotter::PanPlotOnRelease) {
setCursor(QCursor(Qt::ClosedHandCursor));
} else if (currentMouseDragAction.mode==JKQTPlotter::CircleEvents) {
static QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_circle.png");
static QBitmap mask(":/JKQTPlotter/jkqtp_cursor_circle_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (currentMouseDragAction.mode==JKQTPlotter::EllipseEvents) {
static QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_ellipse.png");
static QBitmap mask(":/JKQTPlotter/jkqtp_cursor_ellipse_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (currentMouseDragAction.mode==JKQTPlotter::LineEvents) {
static QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_line.png");
static QBitmap mask(":/JKQTPlotter/jkqtp_cursor_line_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else if (currentMouseDragAction.mode==JKQTPlotter::ScribbleEvents) {
static QBitmap cursor(":/JKQTPlotter/jkqtp_cursor_scribble.png");
static QBitmap mask(":/JKQTPlotter/jkqtp_cursor_scribble_mask.png");
setCursor(QCursor(cursor, mask, 9, 14));
} else {
setCursor(QCursor(Qt::ArrowCursor));
}
}
}
@ -891,16 +873,21 @@ void JKQTPlotter::reactGraphVisible(bool visible)
}
}
void JKQTPlotter::setZoomByMouseRectangle(bool zomByrectangle) {
if (zomByrectangle) mouseActionMode=JKQTPlotter::ZoomRectangle;
else mouseActionMode=JKQTPlotter::NoMouseAction;
}
void JKQTPlotter::setRightMouseButtonAction(const JKQTPlotter::RightMouseButtonAction &__value)
{
this->rightMouseButtonAction = __value;
}
void JKQTPlotter::enableRightClickShowsContextMenu(bool enabled)
{
this->rightClickShowsContextMenu=enabled;
}
void JKQTPlotter::disableRightClickShowsContextMenu(bool disabled)
{
enableRightClickShowsContextMenu(!disabled);
}
JKQTPlotter::RightMouseButtonAction JKQTPlotter::getActionRightMouseButton() const
{
return this->rightMouseButtonAction;
@ -955,16 +942,17 @@ int JKQTPlotter::getMouseLastClickY() const {
return this->mouseLastClickY;
}
bool JKQTPlotter::isRightClickShowsContextMenuEnabled() const
{
return this->rightClickShowsContextMenu;
}
void JKQTPlotter::setMagnification(double m)
{
magnification=m;
redrawPlot();
}
bool JKQTPlotter::getZoomByMouseRectangle() const {
return (mouseActionMode==JKQTPlotter::ZoomRectangle);
}
void JKQTPlotter::modifyContextMenu(QMenu * /*menu*/)
{
}
@ -1034,6 +1022,27 @@ void JKQTPlotter::openSpecialContextMenu(int x, int y)
}
}
QHash<QPair<Qt::MouseButton,Qt::KeyboardModifier>, JKQTPlotter::MouseActionMode>::const_iterator JKQTPlotter::findMatchingMouseDragAction(Qt::MouseButton button, Qt::KeyboardModifiers modifiers) const
{
if (modifiers.testFlag(Qt::ShiftModifier)) {
return registeredMouseActionModes.find(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, Qt::ShiftModifier));
} else if (modifiers.testFlag(Qt::ControlModifier)) {
return registeredMouseActionModes.find(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, Qt::ControlModifier));
} else if (modifiers.testFlag(Qt::AltModifier)) {
return registeredMouseActionModes.find(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, Qt::AltModifier));
} else if (modifiers.testFlag(Qt::MetaModifier)) {
return registeredMouseActionModes.find(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, Qt::MetaModifier));
} else if (modifiers.testFlag(Qt::KeypadModifier)) {
return registeredMouseActionModes.find(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, Qt::KeypadModifier));
} else if (modifiers.testFlag(Qt::GroupSwitchModifier)) {
return registeredMouseActionModes.find(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, Qt::GroupSwitchModifier));
} else {
return registeredMouseActionModes.find(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, Qt::NoModifier));
}
return registeredMouseActionModes.end();
}
void JKQTPlotter::setPlotUpdateEnabled(bool enable)
{
@ -1042,8 +1051,47 @@ void JKQTPlotter::setPlotUpdateEnabled(bool enable)
//qDebug()<<objectName()<<" doDrawing="<<doDrawing;
}
void JKQTPlotter::registerMouseDragAction(Qt::MouseButton button, Qt::KeyboardModifier modifier, JKQTPlotter::MouseActionMode action)
{
registeredMouseActionModes[qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, modifier)]=action;
}
void JKQTPlotter::deregisterMouseDragAction(Qt::MouseButton button, Qt::KeyboardModifier modifier)
{
registeredMouseActionModes.remove(qMakePair<Qt::MouseButton, Qt::KeyboardModifier>(button, modifier));
}
void JKQTPlotter::clearAllRegisteredMouseDragActions()
{
registeredMouseActionModes.clear();
}
void initJKQTPlotterResources()
{
initJKQTBasePlotterResources();
}
JKQTPlotter::MouseDragAction::MouseDragAction():
mode(ZoomRectangle), modifier(Qt::NoModifier), mouseButton(Qt::LeftButton), valid(false)
{
}
JKQTPlotter::MouseDragAction::MouseDragAction(Qt::MouseButton _mouseButton, Qt::KeyboardModifier _modifier, JKQTPlotter::MouseActionMode _mode):
mode(_mode), modifier(_modifier), mouseButton(_mouseButton), valid(true)
{
}
bool JKQTPlotter::MouseDragAction::isValid() const {
return valid;
}
void JKQTPlotter::MouseDragAction::clear()
{
valid=false;
mode=ZoomRectangle;
modifier=Qt::NoModifier;
mouseButton=Qt::LeftButton;
}

View File

@ -156,7 +156,31 @@ LIB_EXPORT void initJKQTPlotterResources();
*
* \subsection JKQTPLOTTER_USERMOUSEINTERACTION Mouse-Interaction in JKQTPlotter
*
* JKQTPlotter offers several methods that allow to customize, how it reacts to mouse actions:
* - registerMouseDragAction() tells JKQTPlotter to perform a certain action (selected from JKQTPlotter::MouseActionMode)
* when a specified mouse button is pushed while a specified (or no) keyborad modifiers (e.g. CTRL,ALT,SHIFT...) is pressed.
* By default JKQTPlotter calls these two registers in its constructors:
* \code
* registerMouseDragAction(Qt::LeftButton, Qt::NoModifier, JKQTPlotter::MouseActionMode::ZoomRectangle);
* registerMouseDragAction(Qt::LeftButton, Qt::ControlModifier, JKQTPlotter::MouseActionMode::PanPlotOnMove);
* \endcode
* Therefore by default you can draw a zoom rectangle with the left mouse button without modifiers
* and you can pan/drag the plot with the left mouse-button while keeping CTRL pressed.
* - deregisterMouseDragAction() deletes a previously defined unser-interaction
* - clearAllRegisteredMouseDragActions() deletes all previously specified user-actions
* .
*
* The right mouse button has a special role: If it is single-clicked and no JKQTPlotter::MouseActionMode is specified
* for the vent, it opens the context menu, unless you call \c enableRightClickShowsContextMenu(false) .
*
* For any mouse-click, one of the following signals is emitted:
* - plotMouseClicked() for any single-click (during the pressDown-Event!)
* - plotMouseDoubleClicked() for any double-click
* .
* In addition the signal plotMouseMove() is called whenever the mouse moves over the plot.
* Additional signals may be emitted, depending on the currently active JKQTPlotter::MouseActionMode.
*
* Pressing the ESC key will stop the current JKQTPlotter::MouseActionMode.
*
* \see \ref JKQTPlotterUserInteraction
*
@ -189,9 +213,8 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
public:
/** \brief availble user-action mode this JKQtPlotter use when mouse events occur.
* This allows you to e.g. draw rectangles or lines over the plot and receive a signal, when the drawing finishes */
enum MouseActionModes {
NoMouseAction=0, /*!< \brief no action is to be performed */
PanPlotOnMove, /*!< \brief the user can drag the current plot window while keeping the left mouse-button pushed down (=panning), the new widow is applied/displayed whenever the mouse moves */
enum MouseActionMode {
PanPlotOnMove=0, /*!< \brief the user can drag the current plot window while keeping the left mouse-button pushed down (=panning), the new widow is applied/displayed whenever the mouse moves */
PanPlotOnRelease, /*!< \brief the user can drag the current plot window while keeping the left mouse-button pushed down (=panning), the new widow is applied/displayed when the left mouse button is released */
ZoomRectangle, /*!< \brief draw a rectangle and when finish zoom to that rectangle */
RectangleEvents, /*!< \brief draw a rectangle and when finished execute the signal userRectangleFinished() */
@ -199,7 +222,6 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
EllipseEvents, /*!< \brief draw an ellipse and when finished execute the signal userEllipseFinished() */
LineEvents, /*!< \brief draw a line and when finished execute the signal userLineFinished() */
ScribbleEvents, /*!< \brief let the user scribble on the plot (left mouse button is kept pressed) and call userScribbleClick() for each new position */
ClickEvents /*!< \brief sinply call userClickFinished() for every single-click of the mouse button */
};
/** \brief options of how to react to a right mouse button click */
@ -209,7 +231,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
RightMouseButtonContextMenu=2 /*!< \brief show the context menu when clicking the right mouse button */
};
/** \brief options of how to react to a left mouse button double-click (single-click events are described by MouseActionModes) */
/** \brief options of how to react to a left mouse button double-click (single-click events are described by MouseActionMode) */
enum LeftDoubleClickAction {
LeftDoubleClickDefault, /*!< \brief */
LeftDoubleClickContextMenu, /*!< \brief open the context menu when the left mouse button is double-clicked */
@ -273,11 +295,6 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
\see userActionCompositionMode for more information */
QPainter::CompositionMode getUserActionCompositionMode() const;
/*! \brief returns the current mouseActionMode.
\details Description of the parameter mouseActionMode is: <BLOCKQUOTE> specifies the user-action mode this JKQtPlotter use when mouse events occur.
* This allows you to e.g. draw rectangles or lines over the plot and receive a signal, when the drawing finishes </BLOCKQUOTE>
\see mouseActionMode for more information */
MouseActionModes getMouseActionMode() const;
/** \brief loads the plot properties from a QSettings object */
void loadSettings(const QSettings &settings, const QString& group=QString("plots"));
@ -350,8 +367,14 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
*/
void setPlotUpdateEnabled(bool enable);
/*! \brief checks whether to \c getMouseActionMode()==JKQTPlotter::ZoomRectangle */
bool getZoomByMouseRectangle() const;
/** \brief registeres a certain mouse action \a action to be executed when a mouse drag operation is
* initialized with the given \a button and \a modifier */
void registerMouseDragAction(Qt::MouseButton button, Qt::KeyboardModifier modifier, MouseActionMode action);
/** \brief deregisteres the mouse action to be executed when a mouse drag operation is
* initialized with the given \a button and \a modifier */
void deregisterMouseDragAction(Qt::MouseButton button, Qt::KeyboardModifier modifier);
/** \brief clear all registeres mouse actions */
void clearAllRegisteredMouseDragActions();
/*! \brief returns the property rightMouseButtonAction ( \copybrief rightMouseButtonAction ).
\details Description of the parameter rightMouseButtonAction is: <BLOCKQUOTE>\copydoc rightMouseButtonAction </BLOCKQUOTE>
\see rightMouseButtonAction for more information */
@ -478,6 +501,13 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
inline double getKeyFontSize() const {
return getConstplotter()->getKeyFontSize();
}
/** \brief checks, whether showing the context menu on a right-button click on the mouse is enabled
* \see enableRightClickShowsContextMenu(), disableRightClickShowsContextMenu(), JKQTPLOTTER_USERMOUSEINTERACTION
*/
bool isRightClickShowsContextMenuEnabled() const;
public slots:
/** \brief set the current plot magnification */
void setMagnification(double m);
@ -579,13 +609,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
\details Description of the parameter userActionCompositionMode is: <BLOCKQUOTE>\copydoc userActionCompositionMode </BLOCKQUOTE>
\see userActionCompositionMode for more information */
void setUserActionCompositionMode(const QPainter::CompositionMode & __value);
/*! \brief sets the current mouseActionMode .
\details Description of the parameter mouseActionMode is: <BLOCKQUOTE> specifies the user-action mode this JKQtPlotter use when mouse events occur.
* This allows you to e.g. draw rectangles or lines over the plot and receive a signal, when the drawing finishes </BLOCKQUOTE>
\see mouseActionMode for more information */
void setMouseActionMode(const MouseActionModes & __value);
/*! \brief equivalent to \c setMouseActionMode(JKQTPlotter::ZoomRectangle) */
void setZoomByMouseRectangle(bool zomByrectangle);
/*! \brief sets the property zoomByMouseWheel ( \copybrief zoomByMouseWheel ) to the specified \a __value.
\details Description of the parameter zoomByMouseWheel is: <BLOCKQUOTE>\copydoc zoomByMouseWheel </BLOCKQUOTE>
@ -602,6 +626,14 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
\see rightMouseButtonAction for more information */
void setRightMouseButtonAction(const RightMouseButtonAction & __value);
/** \brief enables showing the context menu on a right-button click on the mouse
* \see disableRightClickShowsContextMenu(), JKQTPLOTTER_USERMOUSEINTERACTION
*/
void enableRightClickShowsContextMenu(bool enabled=true);
/** \brief disables showing the context menu on a right-button click on the mouse
* \see enableRightClickShowsContextMenu(), JKQTPLOTTER_USERMOUSEINTERACTION
*/
void disableRightClickShowsContextMenu(bool disabled=true);
/** \brief may be connected to zoomChangedLocally() of a different plot and synchronizes the local x-axis to the other x-axis */
void synchronizeXAxis(double newxmin, double newxmax, double newymin, double newymax, JKQTPlotter* sender);
@ -665,7 +697,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
* \param button mouse-button that was used for the click
*/
void plotMouseDoubleClicked(double x, double y, Qt::KeyboardModifiers modifiers, Qt::MouseButton button);
/** \brief emitted when mouseActionMode==JKQTPlotter::ZoomRectangle and the drawing of the new zoom rectangle is finished (=mouse key released)
/** \brief emitted when the mouse action JKQTPlotter::ZoomRectangle and the drawing of the new zoom rectangle is finished (=mouse key released)
*
* \param mouseDragRectXStart start of the selected x-range (in plot coordinates)
* \param mouseDragRectXEnd end of the selected x-range (in plot coordinates)
@ -707,14 +739,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
*/
void zoomChangedLocally(double newxmin, double newxmax, double newymin, double newymax, JKQTPlotter* sender);
/** \brief emitted when mouseActionMode==JKQTPlotter::ClickEvents and a click event from the mouse occurs inside the plot
*
* \param x x-position of the mouse (in plot coordinates)
* \param y y-position of the mouse (in plot coordinates)
* \param modifiers key-modifiers when the click occured
*/
void userClickFinished(double x, double y, Qt::KeyboardModifiers modifiers);
/** \brief emitted when mouseActionMode==JKQTPlotter::ScribbleEvents and a click event from the mouse occurs inside the plot,
/** \brief emitted when the mouse action JKQTPlotter::ScribbleEvents and a click event from the mouse occurs inside the plot,
* or the mouse moved while the left button is pressed down
*
* \param x x-position of the mouse (in plot coordinates)
@ -724,7 +749,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
* \param last if \c true: this is the last event of a series that ends when releasing the mouse-button, within the series, this is \c false
*/
void userScribbleClick(double x, double y, Qt::KeyboardModifiers modifiers, bool first, bool last);
/** \brief emitted when mouseActionMode==JKQTPlotter::RectangleEvents and the drawing of the new rectangle is finished (=mouse key released)
/** \brief emitted when the mouse action JKQTPlotter::RectangleEvents and the drawing of the new rectangle is finished (=mouse key released)
*
* \param x x-coordinate of the bottom left corner of the rectangle (in plot coordinates)
* \param y y-coordinate of the bottom left corner of the rectangle (in plot coordinates)
@ -733,7 +758,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
* \param modifiers key-modifiers when the rectangle was finished
*/
void userRectangleFinished(double x, double y, double width, double height, Qt::KeyboardModifiers modifiers);
/** \brief emitted when mouseActionMode==JKQTPlotter::LineEvents and the drawing of the new line is finished (=mouse key released)
/** \brief emitted when the mouse action JKQTPlotter::LineEvents and the drawing of the new line is finished (=mouse key released)
*
* \param x1 x-coordinate of the start of the line (in plot coordinates)
* \param y1 y-coordinate of the start of the line (in plot coordinates)
@ -742,7 +767,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
* \param modifiers key-modifiers when the rectangle was finished
*/
void userLineFinished(double x1, double y1, double x2, double y2, Qt::KeyboardModifiers modifiers);
/** \brief emitted when mouseActionMode==JKQTPlotter::CircleEvents and the drawing of the new circle is finished (=mouse key released)
/** \brief emitted when the mouse action JKQTPlotter::CircleEvents and the drawing of the new circle is finished (=mouse key released)
*
* \param x x-coordinate of the center of the circle (in plot coordinates)
* \param y y-coordinate of the center of the circle (in plot coordinates)
@ -750,7 +775,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
* \param modifiers key-modifiers when the rectangle was finished
*/
void userCircleFinished(double x, double y, double radius, Qt::KeyboardModifiers modifiers);
/** \brief emitted when mouseActionMode==JKQTPlotter::EllipseEvents and the drawing of the new ellipse is finished (=mouse key released)
/** \brief emitted when the mouse action JKQTPlotter::EllipseEvents and the drawing of the new ellipse is finished (=mouse key released)
*
* \param x x-coordinate of the center of the ellipse (in plot coordinates)
* \param y y-coordinate of the center of the ellipse (in plot coordinates)
@ -763,6 +788,34 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
protected:
/** \brief ties a MouseActionMode to a mouse-button and a keyboard-modifier
* \internal
*/
struct LIB_EXPORT MouseDragAction {
/** \brief constructs an invalid object */
MouseDragAction();
MouseDragAction(Qt::MouseButton _mouseButton, Qt::KeyboardModifier _modifier, MouseActionMode _mode);
MouseActionMode mode;
Qt::KeyboardModifier modifier;
Qt::MouseButton mouseButton;
bool isValid() const;
void clear();
private:
bool valid;
};
/** \brief the currently executed MouseDragAction */
MouseDragAction currentMouseDragAction;
/** \brief lists all availble mouse action modes */
QHash<QPair<Qt::MouseButton,Qt::KeyboardModifier>, MouseActionMode> registeredMouseActionModes;
/** \brief searches registeredMouseActionModes for a matching action */
QHash<QPair<Qt::MouseButton,Qt::KeyboardModifier>, MouseActionMode>::const_iterator findMatchingMouseDragAction(Qt::MouseButton button, Qt::KeyboardModifiers modifiers) const;
/** \brief specifies whether to show the context menu, when the right button of the mouse is clicked */
bool rightClickShowsContextMenu;
/** \brief you may overwrite this method to modify the given context emnu before it is displayed.
*
* The plotter will fill the menu with the default items and then call this method. The default implementation does NOTHING.
@ -771,10 +824,6 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
void init(bool datastore_internal, QWidget* parent, JKQTPDatastore* datast);
/** \brief specifies the user-action mode this JKQtPlotter use when mouse events occur.
* This allows you to e.g. draw rectangles or lines over the plot and receive a signal, when the drawing finishes */
MouseActionModes mouseActionMode;
bool doDrawing;
/** \brief JKQTBasePlotter used to plot */
@ -889,19 +938,14 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
/** \brief event handler for a mouse down event
*
* If the left mouse button is pressed down this starts the drawing of a zoom rectangle with
* the mouse. This method sets mouseZooming to \c true and stores the current time in the private
* property mouseZoomingTStart. All this is only executed when the mouse is inside the coordinate
* system.
*
* If the right mouse button is clicked this zooms out of the coordinate system by a factor of two.
* This event determines the action to be performed from registeredMouseActionModes
* and then sets currentMouseDragAction accordingly and starts the mouse action.
*/
void mousePressEvent ( QMouseEvent * event );
/** \brief event handler for a mouse release event
*
* If the left mouse button is released (and mouseZooming is \c true ) this stops drawing a
* zoom rectangle and emits a tzoomChangedLocally() event.
* this finishes the action, started by mousePressEvent()
*/
void mouseReleaseEvent ( QMouseEvent * event );
@ -916,7 +960,7 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
/** \brief resizes the internal representation (image) of the graphs */
void resizeEvent(QResizeEvent *event);
/** \brief called, when the mouse leaves the widget, hides the toolbar (if visible) */
void leaveEvent ( QEvent * event );
/** \brief specifies whether to display a toolbar with buttons when the mouse is in the upper border of the plot
@ -1007,5 +1051,13 @@ class LIB_EXPORT JKQTPlotter: public QWidget {
};
/** \brief qHash-variant used by JKQTPlotter
* \internal
* \ingroup jkqtpplotterclasses
*/
template<>
inline uint qHash(const QPair<Qt::MouseButton,Qt::KeyboardModifier> &key, uint seed ) noexcept(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed))) {
return static_cast<uint>(key.first)+static_cast<uint>(key.second);
}
#endif // JKQTPLOTTER_H