2015-07-11 18:56:02 +08:00
/*
2024-02-06 21:50:49 +08:00
Copyright ( c ) 2008 - 2024 Jan W . Krieger ( < jan @ jkrieger . de > )
2015-07-11 18:56:02 +08:00
2015-07-12 22:34:27 +08:00
2015-07-11 18:56:02 +08:00
This software is free software : you can redistribute it and / or modify
it under the terms of the GNU Lesser General Public License ( LGPL ) as published by
2019-02-08 00:24:46 +08:00
the Free Software Foundation , either version 2.1 of the License , or
2015-07-11 18:56:02 +08:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Lesser General Public License ( LGPL ) for more details .
You should have received a copy of the GNU Lesser General Public License ( LGPL )
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <QFileInfo>
# if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
# include <QtGlobal>
# include <QtWidgets>
# else
# include <QtGui>
# endif
2018-11-26 03:25:44 +08:00
# include "jkqtplotter/jkqtplotter.h"
2022-05-15 20:15:15 +08:00
# include "jkqtplotter.h"
2015-07-11 18:56:02 +08:00
2023-07-22 16:45:11 +08:00
std : : atomic < int > JKQTPlotter : : jkqtp_RESIZE_DELAY ( 100 ) ;
2015-07-11 18:56:02 +08:00
2022-08-29 04:47:46 +08:00
void JKQTPlotter : : setGlobalResizeDelay ( int delayMS )
{
jkqtp_RESIZE_DELAY = delayMS ;
}
int JKQTPlotter : : getGlobalResizeDelay ( )
{
return jkqtp_RESIZE_DELAY ;
}
2015-07-11 18:56:02 +08:00
/**************************************************************************************************************************
2019-01-20 23:15:10 +08:00
* JKQTPlotter
2015-07-11 18:56:02 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-08-29 04:47:46 +08:00
2019-01-20 23:15:10 +08:00
JKQTPlotter : : JKQTPlotter ( bool datastore_internal , QWidget * parent , JKQTPDatastore * datast ) :
2019-02-08 00:24:46 +08:00
QWidget ( parent , Qt : : Widget ) ,
2019-06-21 21:46:53 +08:00
currentMouseDragAction ( ) ,
2023-06-18 21:13:24 +08:00
lastWheelActionType ( WheelActionType : : None ) ,
lastWheelActionTimestamp ( 0 ) ,
maxWheelEventSeriesTimestampDifference ( 300 ) ,
2019-06-21 21:46:53 +08:00
doDrawing ( false ) ,
plotter ( nullptr ) ,
mouseDragingRectangle ( false ) ,
mouseDragRectXStart ( 0 ) , mouseDragRectXStartPixel ( 0 ) , mouseDragRectXEndPixel ( 0 ) ,
mouseDragRectYEndPixel ( 0 ) , mouseDragRectXEnd ( 0 ) , mouseDragRectYStart ( 0 ) ,
mouseDragRectYStartPixel ( 0 ) , mouseDragRectYEnd ( 0 ) ,
mouseDragMarkers ( ) ,
2020-09-09 17:26:04 +08:00
image ( ) , oldImage ( ) ,
2019-06-21 21:46:53 +08:00
menuSpecialContextMenu ( nullptr ) , toolbar ( nullptr ) , masterPlotterX ( nullptr ) , masterPlotterY ( nullptr ) ,
mousePosX ( 0 ) , mousePosY ( 0 ) ,
magnification ( 1 ) ,
minSize ( ) ,
contextMenu ( nullptr ) ,
contextMenuMode ( JKQTPContextMenuModes : : jkqtpcmmStandardContextMenu ) ,
mouseContextX ( 0 ) , mouseContextY ( 0 ) , mouseLastClickX ( 0 ) , mouseLastClickY ( 0 ) ,
contextSubMenus ( ) ,
plotterStyle ( JKQTPGetSystemDefaultStyle ( ) ) ,
resizeTimer ( ) , registeredOverrideMouseDragActionModes ( ) ,
2022-05-15 20:15:15 +08:00
actgrpMouseLeft ( nullptr ) , actMouseLeftAsDefault ( nullptr ) , actMouseLeftAsRuler ( nullptr ) , actMouseMoveToolTip ( nullptr ) , actMouseLeftAsZoomRect ( nullptr ) , actMouseLeftAsPanView ( nullptr )
2018-12-03 01:30:12 +08:00
{
2019-01-20 23:15:10 +08:00
initJKQTPlotterResources ( ) ;
2019-01-25 05:49:10 +08:00
2015-07-11 18:56:02 +08:00
setParent ( parent ) ;
connect ( & resizeTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( delayedResizeEvent ( ) ) ) ;
2019-06-21 21:46:53 +08:00
2019-01-20 17:49:29 +08:00
plotter = new JKQTBasePlotter ( datastore_internal , this , datast ) ;
2019-01-26 03:16:04 +08:00
plotter - > setEmittingSignalsEnabled ( false ) ;
2019-02-08 00:24:46 +08:00
fixBasePlotterSettings ( ) ;
2015-07-11 18:56:02 +08:00
2019-01-26 19:28:44 +08:00
connect ( plotter , SIGNAL ( plotUpdated ( ) ) , this , SLOT ( redrawPlot ( ) ) ) ;
2015-07-11 18:56:02 +08:00
connect ( plotter , SIGNAL ( beforePlotScalingRecalculate ( ) ) , this , SLOT ( intBeforePlotScalingRecalculate ( ) ) ) ;
2019-01-20 17:49:29 +08:00
connect ( plotter , SIGNAL ( zoomChangedLocally ( double , double , double , double , JKQTBasePlotter * ) ) , this , SLOT ( pzoomChangedLocally ( double , double , double , double , JKQTBasePlotter * ) ) ) ;
2015-07-11 18:56:02 +08:00
2023-07-22 01:19:50 +08:00
image = createImageBuffer ( ) ;
2015-07-11 18:56:02 +08:00
oldImage = image ;
2019-01-28 06:24:12 +08:00
2019-01-29 00:05:03 +08:00
// enable mouse-tracking, so mouseMoved-Events can be caught
2015-07-11 18:56:02 +08:00
setMouseTracking ( true ) ;
2019-01-29 00:05:03 +08:00
2015-07-11 18:56:02 +08:00
setSizePolicy ( QSizePolicy : : Expanding , QSizePolicy : : Expanding ) ;
2019-05-06 01:31:20 +08:00
actgrpMouseLeft = new QActionGroup ( this ) ;
actMouseLeftAsDefault = actgrpMouseLeft - > addAction ( QIcon ( " :/JKQTPlotter/jkqtp_mouseact_default.png " ) , tr ( " Default Tool " ) ) ;
actMouseLeftAsDefault - > setToolTip ( tr ( " switch back to the default mouse action/tool (left button, no modifiers) " ) ) ;
actMouseLeftAsDefault - > setCheckable ( true ) ;
actMouseLeftAsPanView = actgrpMouseLeft - > addAction ( QIcon ( " :/JKQTPlotter/jkqtp_mouseact_drag.png " ) , tr ( " Pan View Tool " ) ) ;
actMouseLeftAsPanView - > setToolTip ( tr ( " switch on the pan view tool (left button, no modifiers) " ) ) ;
actMouseLeftAsPanView - > setCheckable ( true ) ;
actMouseLeftAsZoomRect = actgrpMouseLeft - > addAction ( QIcon ( " :/JKQTPlotter/jkqtp_mouseact_zoomrect.png " ) , tr ( " Zoom Rectangle Tool " ) ) ;
actMouseLeftAsZoomRect - > setToolTip ( tr ( " switch on the zoom rectangle tool (left button, no modifiers) " ) ) ;
actMouseLeftAsZoomRect - > setCheckable ( true ) ;
actMouseLeftAsRuler = actgrpMouseLeft - > addAction ( QIcon ( " :/JKQTPlotter/jkqtp_mouseact_ruler.png " ) , tr ( " Ruler Tool " ) ) ;
actMouseLeftAsRuler - > setToolTip ( tr ( " switch on the ruler tool (left button, no modifiers) " ) ) ;
actMouseLeftAsRuler - > setCheckable ( true ) ;
2022-05-15 20:15:15 +08:00
//actMouseLeftAsToolTip=actgrpMouseLeft->addAction(QIcon(":/JKQTPlotter/jkqtp_mouseact_tooltip.png"), tr("Data Tooltip Tool"));
//actMouseLeftAsToolTip->setToolTip(tr("switch on the data tooltip tool when moving the mouse (no modifiers)"));
//actMouseLeftAsToolTip->setCheckable(true);
2019-05-06 01:31:20 +08:00
actgrpMouseLeft - > setExclusive ( true ) ;
actMouseLeftAsDefault - > setChecked ( true ) ;
2022-05-15 20:15:15 +08:00
actMouseMoveToolTip = new QAction ( QIcon ( " :/JKQTPlotter/jkqtp_mouseact_tooltip.png " ) , tr ( " Data Tooltip Tool " ) ) ;
actMouseMoveToolTip - > setToolTip ( tr ( " switch on the data tooltip tool when moving the mouse (no modifiers) " ) ) ;
actMouseMoveToolTip - > setCheckable ( true ) ;
actMouseMoveToolTip - > setChecked ( false ) ;
2019-05-06 01:31:20 +08:00
connect ( actMouseLeftAsDefault , SIGNAL ( triggered ( ) ) , this , SLOT ( resetMouseLeftAction ( ) ) ) ;
connect ( actMouseLeftAsRuler , SIGNAL ( triggered ( ) ) , this , SLOT ( setMouseLeftActionAsRuler ( ) ) ) ;
connect ( actMouseLeftAsPanView , SIGNAL ( triggered ( ) ) , this , SLOT ( setMouseLeftActionAsPanView ( ) ) ) ;
connect ( actMouseLeftAsZoomRect , SIGNAL ( triggered ( ) ) , this , SLOT ( setMouseLeftActionAsZoomRect ( ) ) ) ;
2022-05-15 20:15:15 +08:00
connect ( actMouseMoveToolTip , SIGNAL ( toggled ( bool ) ) , this , SLOT ( setMouseMoveActionAsToolTip ( bool ) ) ) ;
2019-05-06 01:31:20 +08:00
2015-07-11 18:56:02 +08:00
toolbar = new JKVanishQToolBar ( this ) ;
toolbar - > clear ( ) ;
toolbar - > move ( 1 , 1 ) ;
toolbar - > hide ( ) ;
toolbar - > setAutoFillBackground ( true ) ;
toolbar - > addSeparator ( ) ;
toolbar - > addSeparator ( ) ;
populateToolbar ( toolbar ) ;
2019-02-08 00:24:46 +08:00
QSize s = QSize ( plotterStyle . toolbarIconSize , plotterStyle . toolbarIconSize ) ;
2015-07-11 18:56:02 +08:00
toolbar - > setIconSize ( s ) ;
2019-05-06 01:31:20 +08:00
contextMenu = nullptr ; //new QMenu(this);
2015-07-11 18:56:02 +08:00
//move(32,32);
resize ( 400 , 300 ) ;
doDrawing = true ;
2019-01-26 03:16:04 +08:00
plotter - > setEmittingSignalsEnabled ( true ) ;
2019-01-26 19:28:44 +08:00
redrawPlot ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-02-08 00:24:46 +08:00
JKQTPlotter : : JKQTPlotter ( JKQTPDatastore * datast , QWidget * parent ) :
JKQTPlotter ( false , parent , datast )
{
}
JKQTPlotter : : JKQTPlotter ( QWidget * parent ) :
JKQTPlotter ( true , parent , nullptr )
{
}
2015-07-11 18:56:02 +08:00
2019-01-20 23:15:10 +08:00
JKQTPlotter : : ~ JKQTPlotter ( ) {
2019-05-01 18:46:17 +08:00
resetContextMenu ( false ) ;
2019-01-26 19:28:44 +08:00
disconnect ( plotter , SIGNAL ( plotUpdated ( ) ) , this , SLOT ( redrawPlot ( ) ) ) ;
2015-07-11 18:56:02 +08:00
disconnect ( plotter , SIGNAL ( beforePlotScalingRecalculate ( ) ) , this , SLOT ( intBeforePlotScalingRecalculate ( ) ) ) ;
2019-01-20 17:49:29 +08:00
disconnect ( plotter , SIGNAL ( zoomChangedLocally ( double , double , double , double , JKQTBasePlotter * ) ) , this , SLOT ( pzoomChangedLocally ( double , double , double , double , JKQTBasePlotter * ) ) ) ;
2015-07-11 18:56:02 +08:00
delete plotter ;
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : fixBasePlotterSettings ( )
{
if ( plotterStyle . usePaletteColors ) {
plotter - > setBackgroundColor ( palette ( ) . color ( QPalette : : Window ) ) ;
}
}
2023-07-22 01:19:50 +08:00
JKQTPlotter : : InternalBufferImageType JKQTPlotter : : createImageBuffer ( ) const
{
float scale = 1.0 ;
auto img = InternalBufferImageType ( getImageBufferSize ( & scale ) ) ;
img . setDevicePixelRatio ( scale ) ;
return img ;
}
QSize JKQTPlotter : : getImageBufferSize ( float * scale_out ) const
{
float imagewidth = width ( ) ;
float imageheight = height ( ) - getPlotYOffset ( ) ;
/*
* The following code is to avoid low quality blur pixmap created via
* QPainter , sample code is found in QAbstractItemViewPrivate : : renderToPixmap method
*/
qreal scale = 1.0 ;
const QWidget * window = this - > window ( ) ;
if ( window ) {
const QWindow * windowHandle = window - > windowHandle ( ) ;
if ( windowHandle ) {
scale = windowHandle - > devicePixelRatio ( ) ;
}
}
2023-07-22 04:01:45 +08:00
//qDebug()<<"scale="<<scale<<", dprF="<<devicePixelRatioF()<<", dpr="<<devicePixelRatio()<<" widgetsize="<<QSize(width(),height())<<" img:deviceindependensize="<<QSize(imagewidth,imageheight)<<" img.size.raw="<<QSize(width()*scale, height()*scale);
2023-07-22 01:19:50 +08:00
if ( scale_out ) * scale_out = scale ;
return QSize ( imagewidth * scale , imageheight * scale ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : updateToolbarActions ( )
2015-07-11 18:56:02 +08:00
{
toolbar - > clear ( ) ;
toolbar - > setAutoFillBackground ( true ) ;
toolbar - > addSeparator ( ) ;
toolbar - > addSeparator ( ) ;
populateToolbar ( toolbar ) ;
}
2019-01-26 03:16:04 +08:00
void JKQTPlotter : : setToolbarIconSize ( int value ) {
2019-02-08 00:24:46 +08:00
plotterStyle . toolbarIconSize = value ;
QSize s = QSize ( plotterStyle . toolbarIconSize , plotterStyle . toolbarIconSize ) ;
2019-01-25 05:49:10 +08:00
toolbar - > setIconSize ( s ) ;
}
2023-07-22 01:19:50 +08:00
int JKQTPlotter : : getToolbarIconSize ( ) const {
2019-02-08 00:24:46 +08:00
return plotterStyle . toolbarIconSize ;
2019-01-25 05:49:10 +08:00
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : setToolbarEnabled ( bool __value )
2019-01-25 05:49:10 +08:00
{
2019-02-08 00:24:46 +08:00
if ( plotterStyle . toolbarEnabled ! = __value ) {
plotterStyle . toolbarEnabled = __value ;
2019-01-25 05:49:10 +08:00
updateToolbar ( ) ;
}
}
2019-02-08 00:24:46 +08:00
bool JKQTPlotter : : isToolbarEnabled ( ) const
2019-01-25 05:49:10 +08:00
{
2019-02-08 00:24:46 +08:00
return plotterStyle . toolbarEnabled ;
2019-01-25 05:49:10 +08:00
}
2019-01-26 03:16:04 +08:00
void JKQTPlotter : : setToolbarAlwaysOn ( bool __value )
2019-01-25 05:49:10 +08:00
{
2019-02-08 00:24:46 +08:00
if ( plotterStyle . toolbarAlwaysOn ! = __value ) {
plotterStyle . toolbarAlwaysOn = __value ;
2019-01-25 05:49:10 +08:00
updateToolbar ( ) ;
}
}
2019-01-26 03:16:04 +08:00
bool JKQTPlotter : : isToolbarAlwaysOn ( ) const
2019-01-25 05:49:10 +08:00
{
2019-02-08 00:24:46 +08:00
return plotterStyle . toolbarAlwaysOn ;
2019-01-25 05:49:10 +08:00
}
2019-01-26 03:16:04 +08:00
void JKQTPlotter : : setMousePositionShown ( bool __value )
2019-01-25 05:49:10 +08:00
{
2019-02-08 00:24:46 +08:00
plotterStyle . displayMousePosition = __value ;
2019-01-25 05:49:10 +08:00
}
2019-01-26 03:16:04 +08:00
bool JKQTPlotter : : isMousePositionShown ( ) const
2019-01-25 05:49:10 +08:00
{
2019-02-08 00:24:46 +08:00
return plotterStyle . displayMousePosition ;
2019-01-25 05:49:10 +08:00
}
2019-05-06 01:31:20 +08:00
void JKQTPlotter : : setUserActionOverlayPen ( const QPen & __value )
{
if ( plotterStyle . userActionOverlayPen ! = __value ) {
plotterStyle . userActionOverlayPen = __value ;
update ( ) ;
}
}
QPen JKQTPlotter : : getUserActionOverlayPen ( ) const
{
return plotterStyle . userActionOverlayPen ;
}
void JKQTPlotter : : setUserActionOverlayBrush ( const QBrush & __value )
{
if ( plotterStyle . userActionOverlayBrush ! = __value ) {
plotterStyle . userActionOverlayBrush = __value ;
update ( ) ;
}
}
QBrush JKQTPlotter : : getUserActionOverlayBrush ( ) const
{
return plotterStyle . userActionOverlayBrush ;
}
void JKQTPlotter : : setUserActionOpaquePen ( const QPen & __value )
2019-01-25 05:49:10 +08:00
{
2019-05-06 01:31:20 +08:00
if ( plotterStyle . userActionOpaquePen ! = __value ) {
plotterStyle . userActionOpaquePen = __value ;
2019-01-25 05:49:10 +08:00
update ( ) ;
}
}
2019-05-06 01:31:20 +08:00
QPen JKQTPlotter : : getUserActionOpaquePen ( ) const
2019-01-25 05:49:10 +08:00
{
2019-05-06 01:31:20 +08:00
return plotterStyle . userActionOpaquePen ;
2019-01-25 05:49:10 +08:00
}
2019-05-06 01:31:20 +08:00
void JKQTPlotter : : setUserActionOpaqueBrush ( const QBrush & __value )
2019-01-25 05:49:10 +08:00
{
2019-05-06 01:31:20 +08:00
if ( plotterStyle . userActionOpaqueBrush ! = __value ) {
plotterStyle . userActionOpaqueBrush = __value ;
2019-01-25 05:49:10 +08:00
update ( ) ;
}
}
2019-05-06 01:31:20 +08:00
QBrush JKQTPlotter : : getUserActionOpaqueBrush ( ) const
{
return plotterStyle . userActionOpaqueBrush ;
}
void JKQTPlotter : : setUserActionMarkerPen ( const QPen & __value )
{
if ( plotterStyle . userActionMarkerPen ! = __value ) {
plotterStyle . userActionMarkerPen = __value ;
update ( ) ;
}
}
QPen JKQTPlotter : : getUserActionMarkerPen ( ) const
{
return plotterStyle . userActionMarkerPen ;
}
void JKQTPlotter : : setUserActionMarkerBrush ( const QBrush & __value )
{
if ( plotterStyle . userActionMarkerBrush ! = __value ) {
plotterStyle . userActionMarkerBrush = __value ;
update ( ) ;
}
}
QBrush JKQTPlotter : : getUserActionMarkerBrush ( ) const
{
return plotterStyle . userActionMarkerBrush ;
}
void JKQTPlotter : : setMaxTooltipDistance ( int v )
{
plotterStyle . maxTooltipDistance = v ;
}
int JKQTPlotter : : getMaxTooltipDistance ( ) const
{
return plotterStyle . maxTooltipDistance ;
}
void JKQTPlotter : : setUserActionCatchSensitivity ( int v )
{
plotterStyle . userActionCatchSensitivity = v ;
}
int JKQTPlotter : : getUserActionCatchSensitivity ( ) const
{
return plotterStyle . userActionCatchSensitivity ;
}
void JKQTPlotter : : setUserActionMarkerDiameter ( int v )
{
plotterStyle . userActionMarkerDiameter = v ;
}
void JKQTPlotter : : setUserActionMarkerType ( JKQTPUserActionMarkerType v )
{
plotterStyle . userActionMarkerType = v ;
}
int JKQTPlotter : : getUserActionMarkerDiameter ( ) const
{
return plotterStyle . userActionMarkerDiameter ;
}
JKQTPUserActionMarkerType JKQTPlotter : : getUserActionMarkerType ( ) const
{
return plotterStyle . userActionMarkerType ;
}
2019-01-29 00:05:03 +08:00
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : registerMouseWheelAction ( Qt : : KeyboardModifiers modifier , JKQTPMouseWheelActions action )
2019-01-29 00:05:03 +08:00
{
2019-11-18 15:15:07 +08:00
//qDebug()<<"registerMouseWheelAction("<<modifier<<","<<action<<"): "<<plotterStyle.registeredMouseWheelActions;
2019-02-08 00:24:46 +08:00
plotterStyle . registeredMouseWheelActions [ modifier ] = action ;
2019-11-18 15:15:07 +08:00
//qDebug()<<"registerMouseWheelAction("<<modifier<<","<<action<<"): "<<plotterStyle.registeredMouseWheelActions;
2019-01-29 00:05:03 +08:00
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : deregisterMouseWheelAction ( Qt : : KeyboardModifiers modifier )
2019-01-29 00:05:03 +08:00
{
2019-11-18 15:15:07 +08:00
//qDebug()<<"deregisterMouseWheelAction("<<modifier<<"): "<<plotterStyle.registeredMouseWheelActions;
2019-02-08 00:24:46 +08:00
plotterStyle . registeredMouseWheelActions . remove ( modifier ) ;
2019-11-18 15:15:07 +08:00
//qDebug()<<"deregisterMouseWheelAction("<<modifier<<"): "<<plotterStyle.registeredMouseWheelActions;
2019-01-29 00:05:03 +08:00
}
void JKQTPlotter : : clearAllMouseWheelActions ( )
{
2019-11-18 15:15:07 +08:00
//qDebug()<<"clearAllMouseWheelActions(): "<<plotterStyle.registeredMouseWheelActions;
2019-02-08 00:24:46 +08:00
plotterStyle . registeredMouseWheelActions . clear ( ) ;
2019-11-18 15:15:07 +08:00
//qDebug()<<"clearAllMouseWheelActions(): "<<plotterStyle.registeredMouseWheelActions;
2019-01-29 00:05:03 +08:00
}
2022-05-15 20:15:15 +08:00
void JKQTPlotter : : registerMouseMoveAction ( Qt : : KeyboardModifiers modifier , JKQTPMouseMoveActions action )
{
//qDebug()<<"registerMouseMoveAction("<<modifier<<","<<action<<"): "<<plotterStyle.registeredMouseMoveActions;
plotterStyle . registeredMouseMoveActions [ modifier ] = action ;
//qDebug()<<"registerMouseMoveAction("<<modifier<<","<<action<<"): "<<plotterStyle.registeredMouseMoveActions;
}
void JKQTPlotter : : deregisterMouseMoveAction ( Qt : : KeyboardModifiers modifier )
{
//qDebug()<<"deregisterMouseMoveAction("<<modifier<<"): "<<plotterStyle.registeredMouseMoveActions;
plotterStyle . registeredMouseMoveActions . remove ( modifier ) ;
//qDebug()<<"deregisterMouseMoveAction("<<modifier<<"): "<<plotterStyle.registeredMouseMoveActions;
}
void JKQTPlotter : : clearAllMouseMoveActions ( )
{
//qDebug()<<"clearAllMouseMoveActions(): "<<plotterStyle.registeredMouseMoveActions;
plotterStyle . registeredMouseMoveActions . clear ( ) ;
//qDebug()<<"clearAllMouseMoveActions(): "<<plotterStyle.registeredMouseMoveActions;
}
2019-01-29 00:05:03 +08:00
2019-01-25 05:49:10 +08:00
2019-01-26 19:28:44 +08:00
void JKQTPlotter : : loadSettings ( const QSettings & settings , const QString & group ) {
2015-07-11 18:56:02 +08:00
plotter - > loadSettings ( settings , group ) ;
2019-02-08 00:24:46 +08:00
plotterStyle . loadSettings ( settings , group , JKQTPGetSystemDefaultStyle ( ) ) ;
2015-07-11 18:56:02 +08:00
2019-02-08 00:24:46 +08:00
updateToolbar ( ) ;
2019-01-26 19:28:44 +08:00
redrawPlot ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-26 19:28:44 +08:00
void JKQTPlotter : : saveSettings ( QSettings & settings , const QString & group ) const {
2019-02-08 00:24:46 +08:00
plotterStyle . saveSettings ( settings , group ) ;
2015-07-11 18:56:02 +08:00
plotter - > saveSettings ( settings , group ) ;
}
2019-05-06 01:31:20 +08:00
void JKQTPlotter : : fillInternalStructForToolTipOfClosestDataPoint ( double x0 , double y0 , bool emitEvent ) {
bool foundAll = false ;
QList < QString > labels , titles ;
QList < QColor > colors ;
QList < QPointF > posSyss ;
QList < QImage > keymarkers ;
QList < JKQTPPlotElement * > graphs ;
QList < double > ds ;
double dbest = 0 ;
for ( size_t i = 0 ; i < getPlotter ( ) - > getGraphCount ( ) ; i + + ) {
JKQTPPlotElement * g = getPlotter ( ) - > getGraph ( i ) ;
bool found = false ;
QString label ;
QPointF posSys ;
double d = 0 ;
if ( g & & g - > isVisible ( ) ) {
QPointF pp ;
QString ll ;
double dist = g - > hitTest ( QPointF ( x0 , y0 ) , & pp , & ll , JKQTPPlotElement : : HitTestXY ) ;
if ( JKQTPIsOKFloat ( dist ) ) {
if ( ! found | | dist < d ) {
d = dist ;
posSys = pp ;
label = ll ;
found = true ;
}
}
}
if ( found & & g ) {
if ( ! foundAll ) {
dbest = d ;
labels . clear ( ) ;
labels < < label ;
titles . clear ( ) ;
titles < < g - > getTitle ( ) ;
colors . clear ( ) ;
colors < < g - > getKeyLabelColor ( ) ;
posSyss . clear ( ) ;
posSyss < < posSys ;
ds . clear ( ) ;
ds < < d ;
keymarkers . clear ( ) ;
keymarkers < < g - > generateKeyMarker ( ) ;
graphs . clear ( ) ;
graphs < < g ;
} else {
if ( fabs ( dbest - d ) < = plotterStyle . userActionCatchSensitivity ) {
labels < < label ;
titles < < g - > getTitle ( ) ;
colors < < g - > getKeyLabelColor ( ) ;
posSyss < < posSys ;
ds < < d ;
keymarkers < < g - > generateKeyMarker ( ) ;
graphs < < g ;
} else {
if ( d < dbest ) {
labels . clear ( ) ;
labels < < label ;
titles . clear ( ) ;
titles < < g - > getTitle ( ) ;
colors . clear ( ) ;
colors < < g - > getKeyLabelColor ( ) ;
posSyss . clear ( ) ;
posSyss < < posSys ;
ds . clear ( ) ;
ds < < d ;
keymarkers . clear ( ) ;
keymarkers < < g - > generateKeyMarker ( ) ;
graphs . clear ( ) ;
graphs < < g ;
}
}
if ( d < dbest ) dbest = d ;
}
foundAll = true ;
}
}
2022-05-15 20:15:15 +08:00
mouseDragMarkers . clear ( ) ;
2019-05-06 01:31:20 +08:00
if ( foundAll & & dbest < getCurrentPlotterStyle ( ) . maxTooltipDistance ) {
QStringList entries ;
for ( int i = 0 ; i < posSyss . size ( ) ; i + + ) {
const QPoint posPix = QPointF ( getXAxis ( ) - > x2p ( posSyss [ i ] . x ( ) ) * magnification , getYAxis ( ) - > x2p ( posSyss [ i ] . y ( ) ) * magnification ) . toPoint ( ) ;
entries < < ( titles [ i ] + " : " + labels [ i ] ) ;
mouseDragMarkers < < MouseDragMarker ( posPix , labels [ i ] , titles [ i ] , colors [ i ] , keymarkers [ i ] , graphs [ i ] ) ;
}
//const QPoint globalPosPix=mapToGlobal(posPix);
//const int rectsize=24;
//qDebug()<<graph->getTitle()<<" clicked("<<event->pos()<<") ==> posSys="<<posSys<<" / posPix="<<posPix<<" globalPosPix="<<globalPosPix<<", label="<<label<<", distance="<<d;
//QToolTip::showText(globalPosPix, graph->getTitle()+":\n"+label, this);//, QRect(posPix.x()-rectsize/2, posPix.y()-rectsize/2, rectsize, rectsize));
if ( emitEvent ) {
if ( mouseDragMarkers . size ( ) > 0 ) {
emit tooltipDisplayed ( posSyss [ 0 ] . x ( ) , posSyss [ 0 ] . y ( ) , entries , graphs ) ;
}
}
}
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : paintUserAction ( ) {
2022-05-15 20:15:15 +08:00
if ( ( currentMouseDragAction . isValid ( ) & & mouseDragingRectangle ) | | ( ! currentMouseMoveAction . isEmpty ( ) ) ) {
2015-07-11 18:56:02 +08:00
image = oldImage ;
if ( image . width ( ) > 0 & & image . height ( ) > 0 & & ! image . isNull ( ) ) {
JKQTPEnhancedPainter painter ( & image ) ;
2022-04-22 19:27:31 +08:00
# if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
2019-05-06 01:31:20 +08:00
painter . setRenderHint ( JKQTPEnhancedPainter : : NonCosmeticDefaultPen , true ) ;
2022-04-22 19:27:31 +08:00
# endif
2019-05-06 01:31:20 +08:00
painter . setRenderHint ( JKQTPEnhancedPainter : : Antialiasing , true ) ;
painter . setRenderHint ( JKQTPEnhancedPainter : : TextAntialiasing , true ) ;
painter . setPen ( plotterStyle . userActionOverlayPen ) ;
2019-06-21 21:46:53 +08:00
if ( jkqtp_approximatelyUnequal ( mouseDragRectXEnd , mouseDragRectXStart ) & & jkqtp_approximatelyUnequal ( mouseDragRectYEnd , mouseDragRectYStart ) ) {
2020-09-12 05:19:31 +08:00
const double x1 = plotter - > x2p ( mouseDragRectXStart ) * magnification ;
const double y1 = plotter - > y2p ( mouseDragRectYStart ) * magnification ;
const double x2 = plotter - > x2p ( mouseDragRectXEnd ) * magnification ;
const double y2 = plotter - > y2p ( mouseDragRectYEnd ) * magnification ;
const double dx = x2 - x1 ;
const double dy = y2 - y1 ;
2022-05-15 20:15:15 +08:00
if ( currentMouseDragAction . isValid ( ) & & mouseDragingRectangle ) {
if ( currentMouseDragAction . mode = = jkqtpmdaDrawRectangleForEvent ) {
painter . fillRect ( QRectF ( x1 , y1 , x2 - x1 , y2 - y1 ) , plotterStyle . userActionOverlayBrush ) ;
painter . setPen ( plotterStyle . userActionOverlayPen ) ;
painter . drawRect ( QRectF ( x1 , y1 , x2 - x1 , y2 - y1 ) ) ;
} else if ( currentMouseDragAction . mode = = jkqtpmdaZoomByRectangle ) {
double xmin = mouseDragRectXStart ;
double xmax = mouseDragRectXEnd ;
double ymin = mouseDragRectYStart ;
double ymax = mouseDragRectYEnd ;
plotter - > correctXYRangeForAspectRatio ( xmin , xmax , ymin , ymax ) ;
const double xz1 = plotter - > x2p ( xmin ) * magnification ;
const double yz1 = plotter - > y2p ( ymin ) * magnification ;
const double xz2 = plotter - > x2p ( xmax ) * magnification ;
const double yz2 = plotter - > y2p ( ymax ) * magnification ;
painter . fillRect ( QRectF ( xz1 , yz1 , xz2 - xz1 , yz2 - yz1 ) , plotterStyle . userActionOverlayBrush ) ;
painter . setPen ( plotterStyle . userActionOverlayPen ) ;
painter . drawRect ( QRectF ( xz1 , yz1 , xz2 - xz1 , yz2 - yz1 ) ) ;
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawCircleForEvent ) {
painter . setPen ( plotterStyle . userActionOverlayPen ) ;
painter . setBrush ( plotterStyle . userActionOverlayBrush ) ;
painter . drawEllipse ( QPointF ( x1 , y1 ) , qMin ( fabs ( dx ) , fabs ( dy ) ) , qMin ( fabs ( dx ) , fabs ( dy ) ) ) ;
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawEllipseForEvent ) {
painter . setPen ( plotterStyle . userActionOverlayPen ) ;
painter . setBrush ( plotterStyle . userActionOverlayBrush ) ;
painter . drawEllipse ( QPointF ( x1 , y1 ) , fabs ( dx ) , fabs ( dy ) ) ;
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawLineForEvent ) {
painter . setPen ( plotterStyle . userActionOverlayPen ) ;
painter . setBrush ( plotterStyle . userActionOverlayBrush ) ;
painter . drawLine ( QPointF ( x1 , y1 ) , QPointF ( x2 , y2 ) ) ;
} else if ( currentMouseDragAction . mode = = jkqtpmdaRuler ) {
painter . setPen ( plotterStyle . userActionOpaquePen ) ;
painter . setBrush ( plotterStyle . userActionOpaqueBrush ) ;
painter . drawLine ( QPointF ( x1 , y1 ) , QPointF ( x2 , y1 ) ) ;
painter . drawLine ( QPointF ( x2 , y1 ) , QPointF ( x2 , y2 ) ) ;
painter . drawLine ( QPointF ( x1 , y1 ) , QPointF ( x2 , y2 ) ) ;
const double dxy = sqrt ( jkqtp_sqr ( mouseDragRectXEnd - mouseDragRectXStart ) + jkqtp_sqr ( mouseDragRectYEnd - mouseDragRectYStart ) ) ;
const double alpha = atan2 ( ( mouseDragRectYEnd - mouseDragRectYStart ) , ( mouseDragRectXEnd - mouseDragRectXStart ) ) / JKQTPSTATISTICS_PI * 180.0 ;
const double dx = fabs ( mouseDragRectXEnd - mouseDragRectXStart ) ;
const double dy = fabs ( mouseDragRectYEnd - mouseDragRectYStart ) ;
2019-05-06 01:31:20 +08:00
2022-05-15 20:15:15 +08:00
painter . setBrush ( plotterStyle . userActionOpaqueBrush ) ;
QString txt ;
double a = 0 , d = 0 , so = 0 , w = 0 ;
getPlotter ( ) - > getMathText ( ) - > setFontSize ( plotterStyle . userActionFontSize ) ;
2022-09-01 20:36:34 +08:00
getPlotter ( ) - > getMathText ( ) - > setFontSpecial ( plotterStyle . userActionFontName ) ;
2019-05-06 01:31:20 +08:00
2022-05-15 20:15:15 +08:00
txt = QString : : fromStdString ( " \\ delta_{x}= " + jkqtp_floattolatexstr ( dx , 3 ) ) ;
getPlotter ( ) - > getMathText ( ) - > parse ( txt ) ;
getPlotter ( ) - > getMathText ( ) - > getSizeDetail ( painter , w , a , d , so ) ;
if ( y1 > y2 ) {
QRectF rec ( ( x1 + x2 ) / 2.0 - w / 2.0 , y1 + 2 , w , a + d ) ;
painter . fillRect ( rec , plotterStyle . userActionOpaqueBrush ) ;
2022-06-03 05:05:58 +08:00
getPlotter ( ) - > getMathText ( ) - > draw ( painter , Qt : : AlignTop , rec , getPlotter ( ) - > getCurrentPlotterStyle ( ) . debugShowTextBoxes ) ;
2022-05-15 20:15:15 +08:00
} else {
QRectF rec ( ( x1 + x2 ) / 2.0 - w / 2.0 , y1 - 2 - a - d , w , a + d ) ;
painter . fillRect ( rec , plotterStyle . userActionOpaqueBrush ) ;
2022-06-03 05:05:58 +08:00
getPlotter ( ) - > getMathText ( ) - > draw ( painter , Qt : : AlignBottom , rec , getPlotter ( ) - > getCurrentPlotterStyle ( ) . debugShowTextBoxes ) ;
2022-05-15 20:15:15 +08:00
}
2019-05-06 01:31:20 +08:00
2022-05-15 20:15:15 +08:00
txt = jkqtp_floattolatexqstr ( dy , 3 ) ;
getPlotter ( ) - > getMathText ( ) - > parse ( " \\ delta_{y}= " + txt ) ;
getPlotter ( ) - > getMathText ( ) - > getSizeDetail ( painter , w , a , d , so ) ;
//double dyh=a+d;
if ( x2 > x1 ) {
QRectF rec ( x2 + 2 , ( y1 + y2 ) / 2.0 - ( a + d ) / 2.0 , w , a + d ) ;
painter . fillRect ( rec , plotterStyle . userActionOpaqueBrush ) ;
2022-06-03 05:05:58 +08:00
getPlotter ( ) - > getMathText ( ) - > draw ( painter , Qt : : AlignVCenter | Qt : : AlignLeft , rec , getPlotter ( ) - > getCurrentPlotterStyle ( ) . debugShowTextBoxes ) ;
2022-05-15 20:15:15 +08:00
} else {
QRectF rec ( x2 - 2 - w , ( y1 + y2 ) / 2.0 - ( a + d ) / 2.0 , w , a + d ) ;
painter . fillRect ( rec , plotterStyle . userActionOpaqueBrush ) ;
2022-06-03 05:05:58 +08:00
getPlotter ( ) - > getMathText ( ) - > draw ( painter , Qt : : AlignVCenter | Qt : : AlignRight , rec , getPlotter ( ) - > getCurrentPlotterStyle ( ) . debugShowTextBoxes ) ;
2022-05-15 20:15:15 +08:00
}
2019-05-06 01:31:20 +08:00
2022-05-15 20:15:15 +08:00
txt = QString : : fromStdString ( " \\ delta_{x,y}= " + jkqtp_floattolatexstr ( dxy ) + " , \\ alpha= " + jkqtp_floattolatexstr ( alpha , 1 ) + " \\ degree, \\ stfrac{ \\ mathrm{d}y}{ \\ mathrm{d}x}= " + jkqtp_floattolatexstr ( dy / dx , 1 ) ) ;
getPlotter ( ) - > getMathText ( ) - > parse ( txt ) ;
getPlotter ( ) - > getMathText ( ) - > getSizeDetail ( painter , w , a , d , so ) ;
if ( x2 < x1 ) {
QRectF rec ( ( x1 + x2 ) / 2.0 , ( y1 + y2 ) / 2.0 - ( a + d ) / 2.0 , w , a + d ) ;
painter . fillRect ( rec , plotterStyle . userActionOpaqueBrush ) ;
2022-06-03 05:05:58 +08:00
getPlotter ( ) - > getMathText ( ) - > draw ( painter , Qt : : AlignTop | Qt : : AlignLeft , rec , getPlotter ( ) - > getCurrentPlotterStyle ( ) . debugShowTextBoxes ) ;
2022-05-15 20:15:15 +08:00
} else {
QRectF rec ( ( x1 + x2 ) / 2.0 - w , ( y1 + y2 ) / 2.0 - ( a + d ) / 2.0 , w , a + d ) ;
painter . fillRect ( rec , plotterStyle . userActionOpaqueBrush ) ;
2022-06-03 05:05:58 +08:00
getPlotter ( ) - > getMathText ( ) - > draw ( painter , Qt : : AlignTop | Qt : : AlignRight , rec , getPlotter ( ) - > getCurrentPlotterStyle ( ) . debugShowTextBoxes ) ;
2022-05-15 20:15:15 +08:00
}
}
}
if ( ( currentMouseDragAction . isValid ( ) & & currentMouseDragAction . mode = = jkqtpmdaToolTipForClosestDataPoint ) | | currentMouseMoveAction . contains ( jkqtpmmaToolTipForClosestDataPoint ) ) {
2019-05-06 01:31:20 +08:00
if ( mouseDragMarkers . size ( ) > 0 ) {
const int markerD = getCurrentPlotterStyle ( ) . userActionMarkerDiameter ;
if ( getCurrentPlotterStyle ( ) . userActionMarkerType = = jkqtpuamtCircle ) {
painter . setBrush ( plotterStyle . userActionMarkerBrush ) ;
painter . setPen ( plotterStyle . userActionMarkerPen ) ;
painter . drawEllipse ( QRectF ( mouseDragMarkers [ 0 ] . pos . x ( ) - markerD / 2 , mouseDragMarkers [ 0 ] . pos . y ( ) - markerD / 2 , markerD , markerD ) ) ;
} else if ( getCurrentPlotterStyle ( ) . userActionMarkerType = = jkqtpuamtCrossHair ) {
painter . setBrush ( plotterStyle . userActionMarkerBrush ) ;
painter . setPen ( plotterStyle . userActionMarkerPen ) ;
painter . drawLine ( QLineF ( plotter - > getInternalPlotBorderLeft ( ) , mouseDragMarkers [ 0 ] . pos . y ( ) , image . width ( ) - plotter - > getInternalPlotBorderRight ( ) , mouseDragMarkers [ 0 ] . pos . y ( ) ) ) ;
painter . drawLine ( QLineF ( mouseDragMarkers [ 0 ] . pos . x ( ) , plotter - > getInternalPlotBorderTop ( ) , mouseDragMarkers [ 0 ] . pos . x ( ) , image . height ( ) - plotter - > getInternalPlotBorderBottom ( ) ) ) ;
} else if ( getCurrentPlotterStyle ( ) . userActionMarkerType = = jkqtpuamtCircleAndCrossHair ) {
painter . setBrush ( plotterStyle . userActionMarkerBrush ) ;
painter . setPen ( plotterStyle . userActionMarkerPen ) ;
painter . drawEllipse ( QRectF ( mouseDragMarkers [ 0 ] . pos . x ( ) - markerD / 2 , mouseDragMarkers [ 0 ] . pos . y ( ) - markerD / 2 , markerD , markerD ) ) ;
painter . drawLine ( QLineF ( plotter - > getInternalPlotBorderLeft ( ) , mouseDragMarkers [ 0 ] . pos . y ( ) , mouseDragMarkers [ 0 ] . pos . x ( ) - markerD / 2 , mouseDragMarkers [ 0 ] . pos . y ( ) ) ) ;
painter . drawLine ( QLineF ( image . width ( ) - plotter - > getInternalPlotBorderRight ( ) , mouseDragMarkers [ 0 ] . pos . y ( ) , mouseDragMarkers [ 0 ] . pos . x ( ) + markerD / 2 , mouseDragMarkers [ 0 ] . pos . y ( ) ) ) ;
painter . drawLine ( QLineF ( mouseDragMarkers [ 0 ] . pos . x ( ) , plotter - > getInternalPlotBorderTop ( ) , mouseDragMarkers [ 0 ] . pos . x ( ) , mouseDragMarkers [ 0 ] . pos . y ( ) - markerD / 2 ) ) ;
painter . drawLine ( QLineF ( mouseDragMarkers [ 0 ] . pos . x ( ) , image . height ( ) - plotter - > getInternalPlotBorderBottom ( ) , mouseDragMarkers [ 0 ] . pos . x ( ) , mouseDragMarkers [ 0 ] . pos . y ( ) + markerD / 2 ) ) ;
}
const int xoffset = qMax < int > ( markerD * 3 / 2 , 16 ) ;
const int x0 = mouseDragMarkers [ 0 ] . pos . x ( ) + xoffset ;
QRectF rall ( 0 , 0 , 0 , 0 ) ;
double y = mouseDragMarkers [ 0 ] . pos . y ( ) ;
QVector < QRectF > rects ;
QVector < QString > txts ;
QVector < QColor > colors ;
const int txtoffset = 4 ;
double ascent = 0 , descent = 0 , strikeout = 0 , width = 0 ;
getPlotter ( ) - > getMathText ( ) - > setFontSize ( plotterStyle . userActionFontSize ) ;
2022-09-01 20:36:34 +08:00
getPlotter ( ) - > getMathText ( ) - > setFontSpecial ( plotterStyle . userActionFontName ) ;
2019-05-06 01:31:20 +08:00
for ( auto & m : mouseDragMarkers ) {
QString txt = " \\ textcolor{ " + jkqtp_QColor2String ( m . color ) + " }{ " + m . title + " : " + m . label + " } " ;
getPlotter ( ) - > getMathText ( ) - > parse ( txt ) ;
getPlotter ( ) - > getMathText ( ) - > getSizeDetail ( painter , width , ascent , descent , strikeout ) ;
double txtheight = ascent + descent ;
QRectF rec ( x0 + txtoffset , y , width + 1 , txtheight + 1 ) ;
if ( rall . width ( ) * rall . height ( ) < = 0 ) {
rall = rec . toRect ( ) ;
} else {
rall . setBottom ( rall . bottom ( ) + txtheight + ascent / 4 ) ;
rall . setRight ( qMax ( rall . right ( ) , rec . right ( ) ) ) ;
}
rects < < rec ;
txts < < txt ;
colors < < m . color ;
//qDebug()<<y<<txt<<rall;
y = y + txtheight + ascent / 4 ;
}
rall . setLeft ( rall . left ( ) - txtoffset ) ;
rall . setRight ( rall . right ( ) + txtoffset ) ;
rall . setTop ( rall . top ( ) - txtoffset ) ;
rall . setBottom ( rall . bottom ( ) + txtoffset ) ;
if ( rall . right ( ) > image . width ( ) ) {
rall . moveLeft ( mouseDragMarkers [ 0 ] . pos . x ( ) - rall . width ( ) - xoffset ) ;
for ( auto & r : rects ) {
r . moveLeft ( rall . left ( ) + txtoffset ) ;
}
}
if ( rall . bottom ( ) > image . height ( ) ) {
double oldY = rall . y ( ) ;
rall . moveTop ( image . height ( ) - rall . height ( ) ) ;
for ( auto & r : rects ) {
r . moveTop ( r . y ( ) - ( oldY - rall . y ( ) ) ) ;
}
}
//qDebug()<<"rall="<<rall;
painter . setBrush ( plotterStyle . userActionOpaqueBrush ) ;
painter . setPen ( plotterStyle . userActionOpaquePen ) ;
JKQTPDrawTooltip ( painter , mouseDragMarkers [ 0 ] . pos . x ( ) , mouseDragMarkers [ 0 ] . pos . y ( ) , rall ) ;
for ( int i = 0 ; i < txts . size ( ) ; i + + ) {
getPlotter ( ) - > getMathText ( ) - > parse ( txts [ i ] ) ;
2022-06-03 05:05:58 +08:00
getPlotter ( ) - > getMathText ( ) - > draw ( painter , Qt : : AlignTop | Qt : : AlignLeft , rects [ i ] , getPlotter ( ) - > getCurrentPlotterStyle ( ) . debugShowTextBoxes ) ;
2019-05-06 01:31:20 +08:00
QStringList el = getPlotter ( ) - > getMathText ( ) - > getErrorList ( ) ;
if ( el . size ( ) > 0 ) {
qDebug ( ) < < " error parsing LaTeX string fo tooltip ( " < < txts [ i ] < < " ): \n - " < < el . join ( " \n - " ) ;
// } else {
// qDebug()<<txts[i];
}
}
}
2015-07-11 18:56:02 +08:00
}
}
}
update ( ) ;
}
}
2023-12-21 22:10:20 +08:00
void JKQTPlotter : : correctZoomRectForPanning ( QRectF & zoomRect ) const
{
zoomRect = zoomRect . normalized ( ) ;
// this code corrects for cases, where you pan over getAbsoluteXY().
// without this correction, the zoom rectangle size will be changed, instead of jus stopping at the absolute size
auto correctForAbsoluteLeft = [ ] ( double pos , double absPos ) {
if ( ! JKQTPIsOKFloat ( absPos ) ) return pos ;
if ( pos < absPos ) return absPos ;
return pos ;
} ;
auto correctForAbsoluteRight = [ ] ( double pos , double absPos ) {
if ( ! JKQTPIsOKFloat ( absPos ) ) return pos ;
if ( pos > absPos ) return absPos ;
return pos ;
} ;
2023-12-22 19:56:09 +08:00
const double absLeft = plotter - > x2p ( ( plotter - > getXAxis ( ) - > getInverted ( ) ) ? plotter - > getAbsoluteXMax ( ) : plotter - > getAbsoluteXMin ( ) ) ;
const double absTop = plotter - > y2p ( ( plotter - > getYAxis ( ) - > getInverted ( ) ) ? plotter - > getAbsoluteYMin ( ) : plotter - > getAbsoluteYMax ( ) ) ;
const double absRight = plotter - > x2p ( ( plotter - > getXAxis ( ) - > getInverted ( ) ) ? plotter - > getAbsoluteXMin ( ) : plotter - > getAbsoluteXMax ( ) ) ;
const double absBottom = plotter - > y2p ( ( plotter - > getYAxis ( ) - > getInverted ( ) ) ? plotter - > getAbsoluteYMax ( ) : plotter - > getAbsoluteYMin ( ) ) ;
if ( JKQTPIsOKFloat ( absLeft ) ) zoomRect . moveLeft ( correctForAbsoluteLeft ( zoomRect . left ( ) , absLeft ) ) ;
if ( JKQTPIsOKFloat ( absTop ) ) zoomRect . moveTop ( correctForAbsoluteLeft ( zoomRect . top ( ) , absTop ) ) ;
if ( JKQTPIsOKFloat ( absRight ) ) zoomRect . moveRight ( correctForAbsoluteRight ( zoomRect . right ( ) , absRight ) ) ;
if ( JKQTPIsOKFloat ( absBottom ) ) zoomRect . moveBottom ( correctForAbsoluteRight ( zoomRect . bottom ( ) , absBottom ) ) ;
2023-12-21 22:10:20 +08:00
}
2015-07-11 18:56:02 +08:00
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : mouseMoveEvent ( QMouseEvent * event ) {
2019-02-08 00:24:46 +08:00
if ( plotterStyle . displayMousePosition ) {
2022-06-03 03:44:58 +08:00
mousePosX = plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) ;
mousePosY = plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ;
2015-07-11 18:56:02 +08:00
update ( ) ;
}
2019-02-08 00:24:46 +08:00
if ( plotterStyle . toolbarEnabled & & ( ! plotterStyle . toolbarAlwaysOn ) & & ( ! toolbar - > isVisible ( ) ) ) { // decide whether to display toolbar
2015-07-11 18:56:02 +08:00
int y1 = 10 ;
2022-06-03 03:44:58 +08:00
if ( event - > pos ( ) . y ( ) / magnification > = 0 & & event - > pos ( ) . y ( ) / magnification < = y1 ) {
2015-07-11 18:56:02 +08:00
toolbar - > show ( ) ;
toolbar - > move ( 1 , 1 ) ;
}
}
2019-02-08 00:24:46 +08:00
if ( ! plotterStyle . toolbarEnabled ) {
2015-07-11 18:56:02 +08:00
toolbar - > hide ( ) ;
}
2022-05-15 20:15:15 +08:00
currentMouseMoveAction . clear ( ) ;
2019-01-28 06:24:12 +08:00
if ( currentMouseDragAction . isValid ( ) ) {
2019-02-08 00:24:46 +08:00
if ( ( ( currentMouseDragAction . mode = = jkqtpmdaZoomByRectangle ) | |
( currentMouseDragAction . mode = = jkqtpmdaDrawRectangleForEvent ) | |
( currentMouseDragAction . mode = = jkqtpmdaDrawCircleForEvent ) | |
( currentMouseDragAction . mode = = jkqtpmdaDrawEllipseForEvent ) | |
( currentMouseDragAction . mode = = jkqtpmdaScribbleForEvents ) | |
2019-05-06 01:31:20 +08:00
( currentMouseDragAction . mode = = jkqtpmdaToolTipForClosestDataPoint ) | |
( currentMouseDragAction . mode = = jkqtpmdaRuler ) | |
2019-02-08 00:24:46 +08:00
( currentMouseDragAction . mode = = jkqtpmdaPanPlotOnMove ) | |
( currentMouseDragAction . mode = = jkqtpmdaPanPlotOnRelease ) | |
( currentMouseDragAction . mode = = jkqtpmdaDrawLineForEvent ) ) & &
2019-01-28 06:24:12 +08:00
mouseDragingRectangle )
{
2019-02-08 00:24:46 +08:00
if ( currentMouseDragAction . mode = = jkqtpmdaScribbleForEvents | | currentMouseDragAction . mode = = jkqtpmdaPanPlotOnMove ) {
2019-01-28 06:24:12 +08:00
// start is last event position
mouseDragRectXStart = mouseDragRectXEnd ;
mouseDragRectYStart = mouseDragRectYEnd ;
mouseDragRectXStartPixel = mouseDragRectXEndPixel ;
mouseDragRectYStartPixel = mouseDragRectYEndPixel ;
}
2022-06-03 03:44:58 +08:00
mouseDragRectXEnd = plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) ;
mouseDragRectYEnd = plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ;
mouseDragRectXEndPixel = event - > pos ( ) . x ( ) ;
mouseDragRectYEndPixel = event - > pos ( ) . y ( ) ;
2019-05-06 01:31:20 +08:00
if ( currentMouseDragAction . mode = = jkqtpmdaToolTipForClosestDataPoint ) {
fillInternalStructForToolTipOfClosestDataPoint ( mouseDragRectXEnd , mouseDragRectYEnd ) ;
}
if ( currentMouseDragAction . mode = = jkqtpmdaRuler ) {
emit rulerDisplayed ( mouseDragRectXStart , mouseDragRectYStart , mouseDragRectXEnd , mouseDragRectYEnd , event - > modifiers ( ) ) ;
}
2019-01-28 06:24:12 +08:00
paintUserAction ( ) ;
event - > accept ( ) ;
//std::cout<<mouseZoomingTStart<<" -- "<<mouseZoomingTEnd<<std::endl;
2019-02-08 00:24:46 +08:00
if ( currentMouseDragAction . mode = = jkqtpmdaZoomByRectangle ) {
2020-09-12 05:19:31 +08:00
double xmin = mouseDragRectXStart ;
double xmax = mouseDragRectXEnd ;
double ymin = mouseDragRectYStart ;
double ymax = mouseDragRectYEnd ;
plotter - > correctXYRangeForAspectRatio ( xmin , xmax , ymin , ymax ) ;
emit plotNewZoomRectangle ( xmin , xmax , ymin , ymax , event - > modifiers ( ) ) ;
//emit plotNewZoomRectangle(mouseDragRectXStart, mouseDragRectXEnd, mouseDragRectYStart, mouseDragRectYEnd, event->modifiers());
2019-01-28 06:24:12 +08:00
}
2019-06-21 21:46:53 +08:00
if ( ( currentMouseDragAction . mode = = jkqtpmdaScribbleForEvents ) & & ( jkqtp_approximatelyUnequal ( mouseDragRectXStart , mouseDragRectXEnd ) | | jkqtp_approximatelyUnequal ( mouseDragRectYStart , mouseDragRectYEnd ) ) ) {
2019-01-28 06:24:12 +08:00
emit userScribbleClick ( mouseDragRectXEnd , mouseDragRectYEnd , event - > modifiers ( ) , false , false ) ;
2019-01-27 05:22:46 +08:00
}
2019-06-21 21:46:53 +08:00
if ( ( currentMouseDragAction . mode = = jkqtpmdaPanPlotOnMove ) & & ( jkqtp_approximatelyUnequal ( mouseDragRectXStart , mouseDragRectXEnd ) | | jkqtp_approximatelyUnequal ( mouseDragRectYStart , mouseDragRectYEnd ) ) ) {
2019-01-28 06:24:12 +08:00
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 ) ;
}
2023-12-21 22:10:20 +08:00
correctZoomRectForPanning ( zoomRect ) ;
2023-03-23 20:55:18 +08:00
setXY ( plotter - > p2x ( zoomRect . left ( ) ) , plotter - > p2x ( zoomRect . right ( ) ) , plotter - > p2y ( zoomRect . bottom ( ) ) , plotter - > p2y ( zoomRect . top ( ) ) , true ) ;
2019-01-28 06:24:12 +08:00
}
2019-05-06 01:31:20 +08:00
2019-01-28 06:24:12 +08:00
} else {
event - > accept ( ) ;
/*if (emitSignals)*/ //emit plotMouseMove(x, y);
2019-01-27 05:22:46 +08:00
}
2022-05-15 20:15:15 +08:00
} else if ( event - > buttons ( ) = = Qt : : NoButton ) {
bool foundIT = false ;
auto actionIT = findMatchingMouseMoveAction ( event - > modifiers ( ) , & foundIT ) ;
if ( foundIT ) {
// we found a matching action
currentMouseMoveAction . insert ( actionIT . value ( ) ) ;
if ( actionIT . value ( ) = = jkqtpmmaToolTipForClosestDataPoint ) {
2022-06-03 03:44:58 +08:00
mouseDragRectXStart = plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) ;
mouseDragRectYStart = plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ;
mouseDragRectXStartPixel = event - > pos ( ) . x ( ) ;
mouseDragRectYStartPixel = event - > pos ( ) . y ( ) ;
fillInternalStructForToolTipOfClosestDataPoint ( plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) , plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ) ;
2022-05-15 20:15:15 +08:00
}
paintUserAction ( ) ;
}
2015-07-11 18:56:02 +08:00
}
2019-05-06 01:31:20 +08:00
// emit move signal, if event occured inside plot only
2022-06-03 03:44:58 +08:00
if ( ( event - > pos ( ) . x ( ) / magnification > = plotter - > getInternalPlotBorderLeft ( ) ) & & ( event - > pos ( ) . x ( ) / magnification < = plotter - > getPlotWidth ( ) + plotter - > getInternalPlotBorderLeft ( ) ) & &
( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification > = plotter - > getInternalPlotBorderTop ( ) ) & & ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification < = plotter - > getPlotHeight ( ) + plotter - > getInternalPlotBorderTop ( ) ) ) {
emit plotMouseMove ( plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) , plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-28 06:24:12 +08:00
updateCursor ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : mousePressEvent ( QMouseEvent * event ) {
2024-10-16 19:24:50 +08:00
MouseDragAction prevAction = currentMouseDragAction ;
2019-01-28 06:24:12 +08:00
currentMouseDragAction . clear ( ) ;
2019-05-06 01:31:20 +08:00
mouseDragMarkers . clear ( ) ;
2019-01-28 06:24:12 +08:00
2019-05-06 01:31:20 +08:00
bool foundIT = false ;
auto actionIT = findMatchingMouseDragAction ( event - > button ( ) , event - > modifiers ( ) , & foundIT ) ;
if ( foundIT ) {
2019-01-28 06:24:12 +08:00
// we found a matching action
2022-06-03 03:44:58 +08:00
mouseLastClickX = event - > pos ( ) . x ( ) ;
mouseLastClickY = event - > pos ( ) . y ( ) ;
mouseDragRectXStart = plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) ;
mouseDragRectYStart = plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ;
mouseDragRectXEndPixel = mouseDragRectXStartPixel = event - > pos ( ) . x ( ) ;
mouseDragRectYEndPixel = mouseDragRectYStartPixel = event - > pos ( ) . y ( ) ;
2019-05-06 01:31:20 +08:00
currentMouseDragAction = MouseDragAction ( actionIT . key ( ) . first , actionIT . key ( ) . second , actionIT . value ( ) ) ;
2019-01-28 06:24:12 +08:00
mouseDragingRectangle = true ;
oldImage = image ;
2019-02-08 00:24:46 +08:00
if ( currentMouseDragAction . mode = = jkqtpmdaScribbleForEvents ) emit userScribbleClick ( mouseDragRectXStart , mouseDragRectYStart , event - > modifiers ( ) , true , false ) ;
2019-01-28 06:24:12 +08:00
event - > accept ( ) ;
2024-10-16 19:24:50 +08:00
} else if ( event - > button ( ) = = Qt : : RightButton ) {
if ( prevAction . mode = = jkqtpmdaScribbleForEvents ) {
mouseDragRectXStart = plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) ;
mouseDragRectYStart = plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ;
emit userScribbleClick ( mouseDragRectXStart , mouseDragRectYStart , event - > modifiers ( ) , false , true ) ;
}
if ( event - > modifiers ( ) = = Qt : : NoModifier & & contextMenuMode ! = jkqtpcmmNoContextMenu ) {
mouseLastClickX = event - > pos ( ) . x ( ) ;
mouseLastClickY = event - > pos ( ) . y ( ) ;
openContextMenu ( event - > pos ( ) . x ( ) , event - > pos ( ) . y ( ) ) ;
event - > accept ( ) ;
}
2015-07-11 18:56:02 +08:00
}
// emit clicked signal, if event occured inside plot only
2022-06-03 03:44:58 +08:00
if ( ( event - > pos ( ) . x ( ) / magnification > = plotter - > getInternalPlotBorderLeft ( ) ) & & ( event - > pos ( ) . x ( ) / magnification < = plotter - > getPlotWidth ( ) + plotter - > getInternalPlotBorderLeft ( ) ) & &
( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification > = plotter - > getInternalPlotBorderTop ( ) ) & & ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification < = plotter - > getPlotHeight ( ) + plotter - > getInternalPlotBorderTop ( ) ) ) {
emit plotMouseClicked ( plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) , plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) , event - > modifiers ( ) , event - > button ( ) ) ;
2015-07-11 18:56:02 +08:00
event - > accept ( ) ;
}
2019-01-28 06:24:12 +08:00
updateCursor ( ) ;
2022-05-15 20:15:15 +08:00
if ( foundIT & & actionIT . value ( ) = = jkqtpmdaToolTipForClosestDataPoint ) {
2019-05-06 01:31:20 +08:00
fillInternalStructForToolTipOfClosestDataPoint ( mouseDragRectXStart , mouseDragRectYStart ) ;
paintUserAction ( ) ;
}
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : mouseReleaseEvent ( QMouseEvent * event ) {
2015-10-12 23:05:15 +08:00
if ( ( event - > flags ( ) & Qt : : MouseEventCreatedDoubleClick ) = = Qt : : MouseEventCreatedDoubleClick ) {
return ;
}
2019-01-28 06:24:12 +08:00
if ( currentMouseDragAction . isValid ( ) ) {
2022-06-03 03:44:58 +08:00
mouseDragRectXEnd = plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) ;
mouseDragRectYEnd = plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) ;
mouseDragRectXEndPixel = event - > pos ( ) . x ( ) ;
mouseDragRectYEndPixel = event - > pos ( ) . y ( ) ;
2015-07-11 18:56:02 +08:00
image = oldImage ;
//update();
mouseDragingRectangle = false ;
double x1 = mouseDragRectXStart ;
double y1 = mouseDragRectYStart ;
double x2 = mouseDragRectXEnd ;
double y2 = mouseDragRectYEnd ;
2019-06-21 21:46:53 +08:00
if ( jkqtp_approximatelyUnequal ( mouseDragRectXStart , mouseDragRectXEnd ) & & jkqtp_approximatelyUnequal ( mouseDragRectYStart , mouseDragRectYEnd ) ) {
2019-02-08 00:24:46 +08:00
if ( currentMouseDragAction . mode = = jkqtpmdaZoomByRectangle ) {
2015-07-11 18:56:02 +08:00
double xmin = mouseDragRectXStart ;
double xmax = mouseDragRectXEnd ;
double ymin = mouseDragRectYStart ;
double ymax = mouseDragRectYEnd ;
2020-09-12 05:19:31 +08:00
plotter - > correctXYRangeForAspectRatio ( xmin , xmax , ymin , ymax ) ;
2015-07-11 18:56:02 +08:00
emit zoomChangedLocally ( xmin , xmax , ymin , ymax , this ) ;
2023-03-23 20:55:18 +08:00
plotter - > setXY ( xmin , xmax , ymin , ymax , true ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaPanPlotOnRelease ) {
2019-01-27 05:22:46 +08:00
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 ) ;
}
2023-12-21 22:10:20 +08:00
correctZoomRectForPanning ( zoomRect ) ;
2023-03-23 20:55:18 +08:00
setXY ( plotter - > p2x ( zoomRect . left ( ) ) , plotter - > p2x ( zoomRect . right ( ) ) , plotter - > p2y ( zoomRect . bottom ( ) ) , plotter - > p2y ( zoomRect . top ( ) ) , true ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawRectangleForEvent ) {
2015-07-11 18:56:02 +08:00
emit userRectangleFinished ( x1 , y1 , x2 - x1 , y2 - y1 , event - > modifiers ( ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawCircleForEvent ) {
2015-07-11 18:56:02 +08:00
emit userCircleFinished ( x1 , y1 , qMin ( fabs ( x2 - x1 ) , fabs ( y2 - y1 ) ) , event - > modifiers ( ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawEllipseForEvent ) {
2015-07-11 18:56:02 +08:00
emit userEllipseFinished ( x1 , y1 , fabs ( x2 - x1 ) , fabs ( y2 - y1 ) , event - > modifiers ( ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawLineForEvent ) {
2015-07-11 18:56:02 +08:00
emit userLineFinished ( x1 , y1 , x2 , y2 , event - > modifiers ( ) ) ;
}
}
2019-05-06 01:31:20 +08:00
if ( currentMouseDragAction . mode ! = jkqtpmdaZoomByRectangle & & currentMouseDragAction . mode ! = jkqtpmdaRuler & & currentMouseDragAction . mode ! = jkqtpmdaToolTipForClosestDataPoint ) {
update ( ) ;
}
if ( currentMouseDragAction . mode = = jkqtpmdaScribbleForEvents ) {
emit userScribbleClick ( x1 , y1 , event - > modifiers ( ) , false , true ) ;
}
2015-07-11 18:56:02 +08:00
event - > accept ( ) ;
}
2019-05-06 01:31:20 +08:00
resetCurrentMouseDragAction ( ) ;
}
2019-01-28 06:24:12 +08:00
2019-05-06 01:31:20 +08:00
void JKQTPlotter : : resetCurrentMouseDragAction ( ) {
mouseDragingRectangle = false ;
2019-01-28 06:24:12 +08:00
currentMouseDragAction . clear ( ) ;
updateCursor ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : mouseDoubleClickEvent ( QMouseEvent * event ) {
2022-04-21 19:33:22 +08:00
bool foundIT = false ;
JKQTPMouseDoubleClickActionsHashMapIterator itAction = findMatchingMouseDoubleClickAction ( event - > button ( ) , event - > modifiers ( ) , & foundIT ) ;
if ( foundIT ) {
2019-01-29 00:05:03 +08:00
// we found an action to perform on this double-click
2019-02-08 00:24:46 +08:00
if ( itAction . value ( ) = = JKQTPMouseDoubleClickActions : : jkqtpdcaClickOpensContextMenu ) {
2022-06-03 03:44:58 +08:00
openStandardContextMenu ( event - > pos ( ) . x ( ) , event - > pos ( ) . y ( ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( itAction . value ( ) = = JKQTPMouseDoubleClickActions : : jkqtpdcaClickOpensSpecialContextMenu ) {
2022-06-03 03:44:58 +08:00
openSpecialContextMenu ( event - > pos ( ) . x ( ) , event - > pos ( ) . y ( ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( itAction . value ( ) = = JKQTPMouseDoubleClickActions : : jkqtpdcaClickZoomsIn | | itAction . value ( ) = = JKQTPMouseDoubleClickActions : : jkqtpdcaClickZoomsOut ) {
2019-01-29 00:05:03 +08:00
double factor = 4.0 ;
2019-02-08 00:24:46 +08:00
if ( itAction . value ( ) = = JKQTPMouseDoubleClickActions : : jkqtpdcaClickZoomsOut ) factor = 1 ;
2019-01-29 00:05:03 +08:00
2022-06-03 03:44:58 +08:00
double xmin = plotter - > p2x ( static_cast < double > ( event - > pos ( ) . x ( ) ) / magnification - static_cast < double > ( plotter - > getPlotWidth ( ) ) / factor ) ;
double xmax = plotter - > p2x ( static_cast < double > ( event - > pos ( ) . x ( ) ) / magnification + static_cast < double > ( plotter - > getPlotWidth ( ) ) / factor ) ;
double ymin = plotter - > p2y ( static_cast < double > ( event - > pos ( ) . y ( ) ) / magnification - static_cast < double > ( getPlotYOffset ( ) ) + static_cast < double > ( plotter - > getPlotHeight ( ) ) / factor ) ;
double ymax = plotter - > p2y ( static_cast < double > ( event - > pos ( ) . y ( ) ) / magnification - static_cast < double > ( getPlotYOffset ( ) ) - static_cast < double > ( plotter - > getPlotHeight ( ) ) / factor ) ;
if ( ( event - > pos ( ) . x ( ) / magnification < plotter - > getInternalPlotBorderLeft ( ) ) | | ( event - > pos ( ) . x ( ) / magnification > plotter - > getPlotWidth ( ) + plotter - > getInternalPlotBorderLeft ( ) ) ) {
2019-01-29 00:05:03 +08:00
xmin = getXMin ( ) ;
xmax = getXMax ( ) ;
2022-06-03 03:44:58 +08:00
} else if ( ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification < plotter - > getInternalPlotBorderTop ( ) ) | | ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification > plotter - > getPlotHeight ( ) + plotter - > getInternalPlotBorderTop ( ) ) ) {
2019-01-29 00:05:03 +08:00
ymin = getYMin ( ) ;
ymax = getYMax ( ) ;
}
2023-03-23 20:55:18 +08:00
plotter - > setXY ( xmin , xmax , ymin , ymax , true ) ;
2019-01-29 00:05:03 +08:00
update ( ) ;
2019-02-08 00:24:46 +08:00
} else if ( itAction . value ( ) = = JKQTPMouseDoubleClickActions : : jkqtpdcaClickMovesViewport ) {
2019-01-29 00:05:03 +08:00
QRectF zoomRect = QRectF ( QPointF ( plotter - > x2p ( getXAxis ( ) - > getMin ( ) ) , plotter - > y2p ( getYAxis ( ) - > getMax ( ) ) ) , QPointF ( plotter - > x2p ( getXAxis ( ) - > getMax ( ) ) , plotter - > y2p ( getYAxis ( ) - > getMin ( ) ) ) ) ;
2022-06-03 03:44:58 +08:00
if ( ( event - > pos ( ) . x ( ) / magnification < plotter - > getInternalPlotBorderLeft ( ) ) | | ( event - > pos ( ) . x ( ) / magnification > plotter - > getPlotWidth ( ) + plotter - > getInternalPlotBorderLeft ( ) ) ) {
zoomRect . moveCenter ( QPointF ( zoomRect . center ( ) . x ( ) , event - > pos ( ) . y ( ) ) ) ;
} else if ( ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification < plotter - > getInternalPlotBorderTop ( ) ) | | ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification > plotter - > getPlotHeight ( ) + plotter - > getInternalPlotBorderTop ( ) ) ) {
zoomRect . moveCenter ( QPointF ( event - > pos ( ) . x ( ) , zoomRect . center ( ) . y ( ) ) ) ;
2019-01-29 00:05:03 +08:00
} else {
2022-06-03 03:44:58 +08:00
zoomRect . moveCenter ( QPointF ( event - > pos ( ) . x ( ) , event - > pos ( ) . y ( ) ) ) ;
2019-01-29 00:05:03 +08:00
}
2023-03-23 20:55:18 +08:00
setXY ( plotter - > p2x ( zoomRect . left ( ) ) , plotter - > p2x ( zoomRect . right ( ) ) , plotter - > p2y ( zoomRect . bottom ( ) ) , plotter - > p2y ( zoomRect . top ( ) ) , true ) ;
2019-01-29 00:05:03 +08:00
}
}
2015-07-11 18:56:02 +08:00
// only react on double clicks inside the widget
2022-06-03 03:44:58 +08:00
if ( ( event - > pos ( ) . x ( ) / magnification > = plotter - > getInternalPlotBorderLeft ( ) ) & & ( event - > pos ( ) . x ( ) / magnification < = plotter - > getPlotWidth ( ) + plotter - > getInternalPlotBorderLeft ( ) ) & &
( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification > = plotter - > getInternalPlotBorderTop ( ) ) & & ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification < = plotter - > getPlotHeight ( ) + plotter - > getInternalPlotBorderTop ( ) ) ) {
2015-07-11 18:56:02 +08:00
2022-06-03 03:44:58 +08:00
mouseLastClickX = event - > pos ( ) . x ( ) ;
mouseLastClickY = event - > pos ( ) . y ( ) ;
2015-07-11 18:56:02 +08:00
2022-06-03 03:44:58 +08:00
emit plotMouseDoubleClicked ( plotter - > p2x ( event - > pos ( ) . x ( ) / magnification ) , plotter - > p2y ( ( event - > pos ( ) . y ( ) - getPlotYOffset ( ) ) / magnification ) , event - > modifiers ( ) , event - > button ( ) ) ;
2015-07-11 18:56:02 +08:00
2019-01-29 00:05:03 +08:00
}
event - > accept ( ) ;
2019-01-28 06:24:12 +08:00
updateCursor ( ) ;
currentMouseDragAction . clear ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : keyReleaseEvent ( QKeyEvent * event ) {
2015-07-11 18:56:02 +08:00
QWidget : : keyPressEvent ( event ) ;
if ( event - > key ( ) = = Qt : : Key_Escape & & event - > modifiers ( ) = = Qt : : NoModifier ) {
2019-01-28 06:24:12 +08:00
if ( mouseDragingRectangle | | currentMouseDragAction . isValid ( ) ) {
2015-07-11 18:56:02 +08:00
mouseDragingRectangle = false ;
image = oldImage ;
2019-01-28 06:24:12 +08:00
currentMouseDragAction . clear ( ) ;
2015-07-11 18:56:02 +08:00
update ( ) ;
event - > accept ( ) ;
}
}
2019-01-28 06:24:12 +08:00
updateCursor ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : wheelEvent ( QWheelEvent * event ) {
2020-09-12 05:19:31 +08:00
# if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
const double wheel_x = event - > position ( ) . x ( ) ;
const double wheel_y = event - > position ( ) . y ( ) ;
# else
2023-06-16 19:41:47 +08:00
const double wheel_x = event - > pos ( ) . x ( ) ;
const double wheel_y = event - > pos ( ) . y ( ) ;
2020-09-12 05:19:31 +08:00
# endif
2023-06-16 19:41:47 +08:00
const QPoint angleDelta = event - > angleDelta ( ) ;
QRectF zoomRect = QRectF ( QPointF ( plotter - > x2p ( getXAxis ( ) - > getMin ( ) ) , plotter - > y2p ( getYAxis ( ) - > getMax ( ) ) ) , QPointF ( plotter - > x2p ( getXAxis ( ) - > getMax ( ) ) , plotter - > y2p ( getYAxis ( ) - > getMin ( ) ) ) ) ;
2023-06-18 21:13:24 +08:00
# if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
//qDebug()<<"wheelEvent: "<<event->type()<<"["<<event->deviceType()<<", "<<event->device()->name()<<", "<<event->device()->seatName()<<", "<<event->device()->capabilities()<<", "<<event->pointingDevice()->pointerType()<<", "<<event->timestamp()<<"], "<<event->phase()<<", "<<event->modifiers()<<", "<<angleDelta<<", "<<event->pixelDelta()<<", "<<event->inverted()<<", "<<event->source()<<", "<<event->buttons();
# else
//qDebug()<<"wheelEvent: "<<event->type()<<", "<<event->timestamp()<<", "<<event->phase()<<", "<<event->modifiers()<<", "<<angleDelta<<", "<<event->pixelDelta()<<", "<<event->inverted()<<", "<<event->source()<<", "<<event->buttons();
# endif
2022-04-21 19:33:22 +08:00
bool foundIT = false ;
auto itAction = findMatchingMouseWheelAction ( event - > modifiers ( ) , & foundIT ) ;
2023-06-16 19:41:47 +08:00
2023-06-18 21:13:24 +08:00
WheelActionType acTodo = WheelActionType : : None ;
2023-06-16 19:41:47 +08:00
QPointF d ( 0 , 0 ) ; // for acPan, the shift of the ROI
double factor = 1 ; // for zooming, the zoom-factor
2019-06-21 21:46:53 +08:00
2022-04-21 19:33:22 +08:00
if ( foundIT ) {
2019-02-08 00:24:46 +08:00
if ( itAction . value ( ) = = JKQTPMouseWheelActions : : jkqtpmwaZoomByWheel ) {
2023-06-18 21:13:24 +08:00
acTodo = WheelActionType : : Zoom ;
2023-06-16 19:41:47 +08:00
if ( abs ( angleDelta . y ( ) ) > 30 & & angleDelta . x ( ) = = 0 ) {
factor = pow ( 2.0 , 1.0 * static_cast < double > ( angleDelta . y ( ) ) / 120.0 ) ;
} else if ( abs ( angleDelta . x ( ) ) > 30 & & angleDelta . y ( ) = = 0 ) {
factor = pow ( 2.0 , 1.0 * static_cast < double > ( angleDelta . x ( ) ) / 120.0 ) ;
2019-01-29 00:05:03 +08:00
}
2023-06-16 19:41:47 +08:00
} else if ( itAction . value ( ) = = JKQTPMouseWheelActions : : jkqtpmwaZoomByWheelAndTrackpadPan ) {
2023-06-18 21:13:24 +08:00
// this heuristics recognizes pan-gestures on a track-pad.
// These are converted by Qt to wheelEvents with small angleDelta()-Values
// typical angleDelta values are 120 (1/10 degree) or above, here we use 30
// to accomodate for finer resolved mouse-wheels
//
// unfortunately there is no other way to distinguish these cases, as Qt does not transport
// the source of the QWheelEvent!
const bool doPan = ( abs ( angleDelta . x ( ) ) < 30 & & abs ( angleDelta . y ( ) ) < 30 ) ;
// in addition when the last wheelEvent was a pan-Event and the current is close in time (less than maxWheelEventSeriesTimestampDifference Milliseconds),
// but now we classify a zoom-event we assume there was an acceleration in panning, that leads to angleDelta() larger than the
// limit of 30 above ... in this we still force another PANNING!
const bool forcePan = ( ! doPan & & lastWheelActionType = = WheelActionType : : Pan
& & ( event - > timestamp ( ) - lastWheelActionTimestamp ) < maxWheelEventSeriesTimestampDifference ) ;
if ( forcePan | | doPan ) {
acTodo = WheelActionType : : Pan ;
2023-06-16 19:41:47 +08:00
d = angleDelta ;
2019-01-29 00:05:03 +08:00
} else {
2023-06-18 21:13:24 +08:00
acTodo = WheelActionType : : Zoom ;
2023-06-16 19:41:47 +08:00
if ( abs ( angleDelta . y ( ) ) > 30 & & angleDelta . x ( ) = = 0 ) {
factor = pow ( 2.0 , 1.0 * static_cast < double > ( angleDelta . y ( ) ) / 120.0 ) ;
} else if ( abs ( angleDelta . x ( ) ) > 30 & & angleDelta . y ( ) = = 0 ) {
factor = pow ( 2.0 , 1.0 * static_cast < double > ( angleDelta . x ( ) ) / 120.0 ) ;
}
2019-01-29 00:05:03 +08:00
}
2023-06-16 19:41:47 +08:00
} else if ( itAction . value ( ) = = JKQTPMouseWheelActions : : jkqtpmwaPanByWheel ) {
2023-06-18 21:13:24 +08:00
acTodo = WheelActionType : : Pan ;
2023-06-16 19:41:47 +08:00
d = QPointF ( angleDelta . x ( ) / 120.0 * zoomRect . width ( ) / 10.0 ,
angleDelta . y ( ) / 120.0 * zoomRect . height ( ) / 10.0 ) ;
2023-12-21 22:10:20 +08:00
// maximum shift is 100 Pixels in either direction
2023-06-16 19:41:47 +08:00
d . setX ( jkqtp_bounded < double > ( - 100 , d . x ( ) , 100 ) ) ;
d . setY ( jkqtp_bounded < double > ( - 100 , d . y ( ) , 100 ) ) ;
// minimmum shift is 10 pixels, unles |shift|<1
if ( d . x ( ) > = 1 & & d . x ( ) < 10 ) d . setX ( 10 ) ;
if ( d . x ( ) < = - 1 & & d . x ( ) > - 10 ) d . setX ( - 10 ) ;
if ( d . y ( ) > = 1 & & d . y ( ) < 10 ) d . setY ( 10 ) ;
if ( d . y ( ) < = - 1 & & d . y ( ) > - 10 ) d . setY ( - 10 ) ;
2019-01-29 00:05:03 +08:00
}
2019-01-26 19:28:44 +08:00
}
2019-01-29 00:05:03 +08:00
2023-06-16 19:41:47 +08:00
//qDebug()<<" action: "<<acTodo<<" factor="<<factor<<" d="<<d;
2023-06-18 21:13:24 +08:00
if ( acTodo = = WheelActionType : : Zoom & & factor ! = 1.0 ) {
2023-06-16 19:41:47 +08:00
double xmin = plotter - > p2x ( static_cast < double > ( wheel_x ) / magnification - static_cast < double > ( plotter - > getPlotWidth ( ) * 0.5 ) / factor ) ;
double xmax = plotter - > p2x ( static_cast < double > ( wheel_x ) / magnification + static_cast < double > ( plotter - > getPlotWidth ( ) * 0.5 ) / factor ) ;
double ymin = plotter - > p2y ( static_cast < double > ( wheel_y ) / magnification - static_cast < double > ( getPlotYOffset ( ) ) + static_cast < double > ( plotter - > getPlotHeight ( ) * 0.5 ) / factor ) ;
double ymax = plotter - > p2y ( static_cast < double > ( wheel_y ) / magnification - static_cast < double > ( getPlotYOffset ( ) ) - static_cast < double > ( plotter - > getPlotHeight ( ) * 0.5 ) / factor ) ;
if ( ( wheel_x / magnification < plotter - > getInternalPlotBorderLeft ( ) ) | | ( wheel_x / magnification > plotter - > getPlotWidth ( ) + plotter - > getInternalPlotBorderLeft ( ) ) ) {
xmin = getXMin ( ) ;
xmax = getXMax ( ) ;
} else if ( ( ( wheel_y - getPlotYOffset ( ) ) / magnification < plotter - > getInternalPlotBorderTop ( ) ) | | ( ( wheel_y - getPlotYOffset ( ) ) / magnification > plotter - > getPlotHeight ( ) + plotter - > getInternalPlotBorderTop ( ) ) ) {
ymin = getYMin ( ) ;
ymax = getYMax ( ) ;
}
//qDebug()<<" zoom: factor="<<factor;
plotter - > setXY ( xmin , xmax , ymin , ymax , true ) ;
2023-06-18 21:13:24 +08:00
} else if ( acTodo = = WheelActionType : : Pan & & ( d . x ( ) ! = 0 | | d . y ( ) ! = 0 ) ) {
2023-06-16 19:41:47 +08:00
//qDebug()<<" pan: d="<<d;
if ( ( wheel_x / magnification < plotter - > getInternalPlotBorderLeft ( ) ) | | ( wheel_x / magnification > plotter - > getPlotWidth ( ) + plotter - > getInternalPlotBorderLeft ( ) ) ) {
zoomRect . translate ( 0 , d . y ( ) ) ;
} else if ( ( ( wheel_y - getPlotYOffset ( ) ) / magnification < plotter - > getInternalPlotBorderTop ( ) ) | | ( ( wheel_y - getPlotYOffset ( ) ) / magnification > plotter - > getPlotHeight ( ) + plotter - > getInternalPlotBorderTop ( ) ) ) {
zoomRect . translate ( d . x ( ) , 0 ) ;
} else {
zoomRect . translate ( d . x ( ) , d . y ( ) ) ;
}
2023-12-21 22:10:20 +08:00
correctZoomRectForPanning ( zoomRect ) ;
// now apply the new range
2023-06-16 19:41:47 +08:00
setXY ( plotter - > p2x ( zoomRect . left ( ) ) , plotter - > p2x ( zoomRect . right ( ) ) , plotter - > p2y ( zoomRect . bottom ( ) ) , plotter - > p2y ( zoomRect . top ( ) ) , true ) ;
}
2019-01-29 00:05:03 +08:00
event - > accept ( ) ;
2023-06-16 19:41:47 +08:00
emit plotMouseWheelOperated ( plotter - > p2x ( wheel_x / magnification ) , plotter - > p2y ( ( wheel_y - getPlotYOffset ( ) ) / magnification ) , event - > modifiers ( ) , angleDelta . x ( ) , angleDelta . y ( ) ) ;
2019-01-29 00:05:03 +08:00
2019-01-28 06:24:12 +08:00
updateCursor ( ) ;
currentMouseDragAction . clear ( ) ;
2023-06-18 21:13:24 +08:00
lastWheelActionType = acTodo ;
lastWheelActionTimestamp = event - > timestamp ( ) ;
2015-07-11 18:56:02 +08:00
}
2023-06-16 19:41:47 +08:00
bool JKQTPlotter : : event ( QEvent * event ) {
//qDebug()<<"event: "<<event->type()<<", "<<event->isAccepted();
return QWidget : : event ( event ) ;
}
2023-07-22 01:19:50 +08:00
int JKQTPlotter : : getPlotYOffset ( ) const {
2015-07-11 18:56:02 +08:00
int plotYOffset = 0 ;
2019-02-08 00:24:46 +08:00
if ( plotterStyle . displayMousePosition ) {
2015-07-11 18:56:02 +08:00
plotYOffset = plotYOffset + QFontMetrics ( font ( ) ) . height ( ) + 2 ;
}
2019-02-08 00:24:46 +08:00
if ( plotterStyle . toolbarEnabled & & plotterStyle . toolbarAlwaysOn ) {
2015-07-11 18:56:02 +08:00
plotYOffset = plotYOffset + toolbar - > height ( ) ;
}
return plotYOffset ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : initContextMenu ( )
2015-07-11 18:56:02 +08:00
{
2019-05-01 18:46:17 +08:00
resetContextMenu ( true ) ;
2015-07-11 18:56:02 +08:00
2019-01-26 03:16:04 +08:00
contextMenu - > addAction ( plotter - > getActionSaveData ( ) ) ;
contextMenu - > addAction ( plotter - > getActionSavePlot ( ) ) ;
2022-07-19 05:33:20 +08:00
# ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
2019-01-26 03:16:04 +08:00
contextMenu - > addAction ( plotter - > getActionPrint ( ) ) ;
2022-07-19 05:33:20 +08:00
# endif
2015-07-11 18:56:02 +08:00
contextMenu - > addSeparator ( ) ;
2019-01-26 03:16:04 +08:00
contextMenu - > addAction ( plotter - > getActionCopyPixelImage ( ) ) ;
contextMenu - > addAction ( plotter - > getActionCopyData ( ) ) ;
contextMenu - > addAction ( plotter - > getActionCopyMatlab ( ) ) ;
2015-07-11 18:56:02 +08:00
contextMenu - > addSeparator ( ) ;
2019-01-26 03:16:04 +08:00
contextMenu - > addAction ( plotter - > getActionShowPlotData ( ) ) ;
2019-05-06 01:31:20 +08:00
contextMenu - > addSection ( tr ( " Zooming " ) ) ;
2019-01-26 03:16:04 +08:00
contextMenu - > addAction ( plotter - > getActionZoomAll ( ) ) ;
contextMenu - > addAction ( plotter - > getActionZoomIn ( ) ) ;
contextMenu - > addAction ( plotter - > getActionZoomOut ( ) ) ;
2022-05-15 20:15:15 +08:00
contextMenu - > addSeparator ( ) ;
contextMenu - > addAction ( actMouseMoveToolTip ) ;
2019-05-06 01:31:20 +08:00
contextMenu - > addSection ( tr ( " left mouse button tool " ) ) ;
contextMenu - > addAction ( actMouseLeftAsDefault ) ;
contextMenu - > addAction ( actMouseLeftAsPanView ) ;
contextMenu - > addAction ( actMouseLeftAsZoomRect ) ;
contextMenu - > addAction ( actMouseLeftAsRuler ) ;
2018-08-20 00:17:18 +08:00
contextMenu - > addSeparator ( ) ;
QMenu * menVisibleGroup = new QMenu ( tr ( " Graph Visibility " ) , contextMenu ) ;
2019-01-26 03:16:04 +08:00
for ( size_t i = 0 ; i < getPlotter ( ) - > getGraphCount ( ) ; i + + ) {
2019-01-26 20:00:40 +08:00
QString tit = getPlotter ( ) - > getGraph ( i ) - > getTitle ( ) ;
2018-08-20 00:17:18 +08:00
if ( tit . isEmpty ( ) ) tit = tr ( " Graph %1 " ) . arg ( static_cast < int > ( i ) ) ;
QAction * act = new QAction ( tit , menVisibleGroup ) ;
act - > setCheckable ( true ) ;
2019-02-03 21:04:48 +08:00
act - > setChecked ( getPlotter ( ) - > getGraph ( i ) - > isVisible ( ) ) ;
2022-09-02 03:37:50 +08:00
const qreal dpr = devicePixelRatioF ( ) ;
QPixmap pix = QPixmap : : fromImage ( getPlotter ( ) - > getGraph ( i ) - > generateKeyMarker ( QSize ( 16 , 16 ) * dpr ) ) ;
pix . setDevicePixelRatio ( dpr ) ;
act - > setIcon ( QIcon ( pix ) ) ;
2018-08-20 00:17:18 +08:00
act - > setData ( static_cast < int > ( i ) ) ;
connect ( act , SIGNAL ( toggled ( bool ) ) , this , SLOT ( reactGraphVisible ( bool ) ) ) ;
menVisibleGroup - > addAction ( act ) ;
}
contextMenu - > addMenu ( menVisibleGroup ) ;
2015-07-11 18:56:02 +08:00
if ( actions ( ) . size ( ) > 0 ) {
contextMenu - > addSeparator ( ) ;
contextMenu - > addActions ( actions ( ) ) ;
}
bool hasSep = false ;
2019-01-26 03:16:04 +08:00
JKQTBasePlotter : : AdditionalActionsMap lst = getPlotter ( ) - > getLstAdditionalPlotterActions ( ) ;
2019-01-20 17:49:29 +08:00
JKQTBasePlotter : : AdditionalActionsMapIterator it ( lst ) ;
2015-07-11 18:56:02 +08:00
while ( it . hasNext ( ) ) {
it . next ( ) ;
if ( it . value ( ) . size ( ) > 0 ) {
bool hasMenu = false ;
for ( int i = 0 ; i < it . value ( ) . size ( ) ; i + + ) {
if ( it . value ( ) . at ( i ) ) {
if ( ! hasMenu ) {
contextSubMenus . append ( new QMenu ( it . key ( ) , this ) ) ;
if ( ! hasSep ) {
contextMenu - > addSeparator ( ) ;
hasSep = true ;
}
hasMenu = true ;
}
contextSubMenus . last ( ) - > addAction ( it . value ( ) . at ( i ) ) ;
}
}
if ( hasMenu ) {
contextMenu - > addMenu ( contextSubMenus . last ( ) ) ;
}
}
}
modifyContextMenu ( contextMenu ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : updateCursor ( ) {
2019-01-28 06:24:12 +08:00
if ( ! currentMouseDragAction . isValid ( ) ) {
2022-05-15 20:15:15 +08:00
if ( currentMouseMoveAction . contains ( jkqtpmmaToolTipForClosestDataPoint ) ) {
setCursor ( QCursor ( Qt : : CrossCursor ) ) ;
} else {
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
}
2019-01-28 06:24:12 +08:00
} else {
2019-02-08 00:24:46 +08:00
if ( currentMouseDragAction . mode = = jkqtpmdaZoomByRectangle ) {
2019-01-28 06:24:12 +08:00
static QBitmap cursor ( " :/JKQTPlotter/jkqtp_cursor_zoom.png " ) ;
static QBitmap mask ( " :/JKQTPlotter/jkqtp_cursor_zoom_mask.png " ) ;
setCursor ( QCursor ( cursor , mask , 9 , 14 ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawRectangleForEvent ) {
2019-01-28 06:24:12 +08:00
static QBitmap cursor ( " :/JKQTPlotter/jkqtp_cursor_rectangle.png " ) ;
static QBitmap mask ( " :/JKQTPlotter/jkqtp_cursor_rectangle_mask.png " ) ;
setCursor ( QCursor ( cursor , mask , 9 , 14 ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaPanPlotOnMove | | currentMouseDragAction . mode = = jkqtpmdaPanPlotOnRelease ) {
2019-01-28 06:24:12 +08:00
setCursor ( QCursor ( Qt : : ClosedHandCursor ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawCircleForEvent ) {
2019-01-28 06:24:12 +08:00
static QBitmap cursor ( " :/JKQTPlotter/jkqtp_cursor_circle.png " ) ;
static QBitmap mask ( " :/JKQTPlotter/jkqtp_cursor_circle_mask.png " ) ;
setCursor ( QCursor ( cursor , mask , 9 , 14 ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawEllipseForEvent ) {
2019-01-28 06:24:12 +08:00
static QBitmap cursor ( " :/JKQTPlotter/jkqtp_cursor_ellipse.png " ) ;
static QBitmap mask ( " :/JKQTPlotter/jkqtp_cursor_ellipse_mask.png " ) ;
setCursor ( QCursor ( cursor , mask , 9 , 14 ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaDrawLineForEvent ) {
2019-01-28 06:24:12 +08:00
static QBitmap cursor ( " :/JKQTPlotter/jkqtp_cursor_line.png " ) ;
static QBitmap mask ( " :/JKQTPlotter/jkqtp_cursor_line_mask.png " ) ;
setCursor ( QCursor ( cursor , mask , 9 , 14 ) ) ;
2019-02-08 00:24:46 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaScribbleForEvents ) {
2019-01-28 06:24:12 +08:00
static QBitmap cursor ( " :/JKQTPlotter/jkqtp_cursor_scribble.png " ) ;
static QBitmap mask ( " :/JKQTPlotter/jkqtp_cursor_scribble_mask.png " ) ;
setCursor ( QCursor ( cursor , mask , 9 , 14 ) ) ;
2019-05-06 01:31:20 +08:00
} else if ( currentMouseDragAction . mode = = jkqtpmdaToolTipForClosestDataPoint ) {
setCursor ( QCursor ( Qt : : CrossCursor ) ) ;
} else if ( currentMouseDragAction . mode = = jkqtpmdaRuler ) {
static QBitmap cursor ( " :/JKQTPlotter/jkqtp_cursor_line.png " ) ;
static QBitmap mask ( " :/JKQTPlotter/jkqtp_cursor_line_mask.png " ) ;
setCursor ( QCursor ( cursor , mask , 9 , 14 ) ) ;
2019-01-28 06:24:12 +08:00
} else {
setCursor ( QCursor ( Qt : : ArrowCursor ) ) ;
}
2015-07-11 18:56:02 +08:00
}
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : synchronizeXAxis ( double newxmin , double newxmax , double /*newymin*/ , double /*newymax*/ , JKQTPlotter * /*sender*/ ) {
2015-07-11 18:56:02 +08:00
setX ( newxmin , newxmax ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : synchronizeYAxis ( double /*newxmin*/ , double /*newxmax*/ , double newymin , double newymax , JKQTPlotter * /*sender*/ ) {
2015-07-11 18:56:02 +08:00
setY ( newymin , newymax ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : synchronizeXYAxis ( double newxmin , double newxmax , double newymin , double newymax , JKQTPlotter * /*sender*/ ) {
2015-07-11 18:56:02 +08:00
setXY ( newxmin , newxmax , newymin , newymax ) ;
}
2019-05-06 01:31:20 +08:00
2019-01-26 19:28:44 +08:00
void JKQTPlotter : : redrawPlot ( ) {
2015-07-11 18:56:02 +08:00
# ifdef JKQTBP_AUTOTIMER
2019-01-26 19:28:44 +08:00
JKQTPAutoOutputTimer jkaaot ( QString ( " JKQTPlotter::redrawPlot() " )) ;
2015-07-11 18:56:02 +08:00
# endif
if ( ! doDrawing ) return ;
2019-01-26 19:28:44 +08:00
disconnect ( plotter , SIGNAL ( plotUpdated ( ) ) , this , SLOT ( redrawPlot ( ) ) ) ;
2019-06-21 21:46:53 +08:00
plotter - > setWidgetSize ( jkqtp_roundTo < int > ( width ( ) / magnification ) , jkqtp_roundTo < int > ( height ( ) / magnification - getPlotYOffset ( ) ) ) ;
2015-07-11 18:56:02 +08:00
JKQTPEnhancedPainter painter ( & image ) ;
if ( painter . isActive ( ) ) {
painter . scale ( magnification , magnification ) ;
//QTime t;
//t.start();
2020-09-09 17:26:04 +08:00
plotter - > drawNonGrid ( painter , QPoint ( 0 , 0 ) ) ; //, QRect(QPoint(0,0), QSize(plotter->getPlotWidth(), plotter->getPlotHeight())));
2015-07-11 18:56:02 +08:00
//qDebug()<<"drawNonGrid"<<objectName()<<": "<<t.elapsed()<<"ms";
}
oldImage = image ;
2019-01-26 19:28:44 +08:00
connect ( plotter , SIGNAL ( plotUpdated ( ) ) , this , SLOT ( redrawPlot ( ) ) ) ;
2015-07-11 18:56:02 +08:00
update ( ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : paintEvent ( QPaintEvent * event ) {
2015-07-11 18:56:02 +08:00
# ifdef JKQTBP_AUTOTIMER
2019-01-20 23:15:10 +08:00
JKQTPAutoOutputTimer jkaaot ( QString ( " JKQTPlotter::paintEvent() " )) ;
2015-07-11 18:56:02 +08:00
# endif
// draw the saved image of the plot
JKQTPEnhancedPainter * p = new JKQTPEnhancedPainter ( this ) ;
if ( p - > isActive ( ) ) {
//std::cout<<"getPlotYOffset()="<<getPlotYOffset()<<std::endl;
p - > save ( ) ;
p - > setBrush ( palette ( ) . brush ( QPalette : : Window ) ) ;
p - > setPen ( palette ( ) . color ( QPalette : : Window ) ) ;
p - > drawRect ( geometry ( ) ) ;
p - > restore ( ) ;
2019-02-08 00:24:46 +08:00
if ( plotterStyle . displayMousePosition ) {
2019-06-21 21:46:53 +08:00
p - > drawText ( QPointF ( plotter - > getInternalPlotBorderLeft ( ) , getPlotYOffset ( ) - 1 ) , plotterStyle . mousePositionTemplate . arg ( mousePosX ) . arg ( mousePosY ) ) ;
2015-07-11 18:56:02 +08:00
}
2023-07-22 01:19:50 +08:00
const QSize plotImageSize = getImageBufferSize ( ) ;
2015-07-11 18:56:02 +08:00
2023-07-22 01:19:50 +08:00
if ( image . size ( ) ! = plotImageSize ) {
p - > drawPixmap ( QRect ( QPoint ( 0 , getPlotYOffset ( ) ) , plotImageSize ) , image ) ;
2015-07-11 18:56:02 +08:00
} else {
2023-07-22 01:19:50 +08:00
p - > drawPixmap ( QPoint ( 0 , getPlotYOffset ( ) ) , image ) ;
2015-07-11 18:56:02 +08:00
}
}
delete p ;
event - > accept ( ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : resizeEvent ( QResizeEvent * event ) {
2015-07-11 18:56:02 +08:00
# ifdef JKQTBP_AUTOTIMER
2019-01-20 23:15:10 +08:00
JKQTPAutoOutputTimer jkaaot ( QString ( " JKQTPlotter::resizeEvent() " )) ;
2015-07-11 18:56:02 +08:00
# endif
//qDebug()<<"resizeEvent old="<<size()<<" new="<<event->size();
QWidget : : resizeEvent ( event ) ;
event - > accept ( ) ;
bool sizeChanged = false ;
int plotImageWidth = width ( ) ;
int plotImageHeight = height ( ) ;
plotImageHeight = plotImageHeight - getPlotYOffset ( ) ;
if ( plotImageWidth ! = image . width ( ) | | plotImageHeight ! = image . height ( ) ) {
sizeChanged = true ;
}
if ( sizeChanged ) {
2023-10-25 01:32:26 +08:00
if ( jkqtp_RESIZE_DELAY = = 0 ) {
// Do this now
delayedResizeEvent ( ) ;
} else {
resizeTimer . setSingleShot ( true ) ;
resizeTimer . start ( jkqtp_RESIZE_DELAY ) ;
}
2015-07-11 18:56:02 +08:00
}
//updateGeometry();
2019-06-21 21:46:53 +08:00
//qDebug()<<"resize DONE width()="<<width()<<" height()="<<height()<<" plotImageWidth="<<plotImageWidth<<" plotImageHeight="<<plotImageHeight<<" sizeChanged="<<sizeChanged<<"\n";
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : delayedResizeEvent ( )
2015-07-11 18:56:02 +08:00
{
2023-07-22 01:19:50 +08:00
if ( getImageBufferSize ( ) ! = image . size ( ) ) {
image = createImageBuffer ( ) ;
2020-09-11 19:48:07 +08:00
emit widgetResized ( width ( ) , height ( ) , this ) ;
redrawPlot ( ) ;
}
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : leaveEvent ( QEvent * /*event*/ ) {
2019-02-08 00:24:46 +08:00
if ( ! plotterStyle . toolbarAlwaysOn ) toolbar - > hide ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : updateToolbar ( )
2015-07-11 18:56:02 +08:00
{
2019-02-08 00:24:46 +08:00
toolbar - > setIconSize ( QSize ( plotterStyle . toolbarIconSize , plotterStyle . toolbarIconSize ) ) ;
if ( plotterStyle . toolbarEnabled ) {
if ( plotterStyle . toolbarAlwaysOn ) {
2019-01-26 20:00:40 +08:00
toolbar - > setToolbarVanishesEnabled ( false ) ;
2015-07-11 18:56:02 +08:00
toolbar - > show ( ) ;
toolbar - > move ( 1 , 1 ) ;
} else {
2019-01-26 20:00:40 +08:00
toolbar - > setToolbarVanishesEnabled ( true ) ;
2015-07-11 18:56:02 +08:00
}
} else {
toolbar - > hide ( ) ;
}
update ( ) ;
}
2019-01-20 23:15:10 +08:00
QSize JKQTPlotter : : minimumSizeHint ( ) const {
2015-07-11 18:56:02 +08:00
QSize m = QWidget : : minimumSizeHint ( ) ;
if ( minSize . width ( ) > m . width ( ) ) m . setWidth ( minSize . width ( ) ) ;
if ( minSize . height ( ) > m . height ( ) ) m . setHeight ( minSize . height ( ) ) ;
2019-01-26 20:00:40 +08:00
return m ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
QSize JKQTPlotter : : sizeHint ( ) const {
2019-01-26 20:00:40 +08:00
return QWidget : : sizeHint ( ) ;
2015-07-11 18:56:02 +08:00
}
2022-08-29 04:47:46 +08:00
bool JKQTPlotter : : isResizeTimerRunning ( ) const
{
return resizeTimer . isActive ( ) ;
}
2019-02-03 21:04:48 +08:00
void JKQTPlotter : : synchronizeToMaster ( JKQTPlotter * master , JKQTBasePlotter : : SynchronizationDirection synchronizeDirection , bool synchronizeAxisLength , bool synchronizeZoomingMasterToSlave , bool synchronizeZoomingSlaveToMaster )
{
if ( masterPlotterX ) disconnect ( masterPlotterX - > getPlotter ( ) , SIGNAL ( plotScalingRecalculated ( ) ) , this , SLOT ( masterPlotScalingRecalculated ( ) ) ) ;
if ( masterPlotterY ) disconnect ( masterPlotterY - > getPlotter ( ) , SIGNAL ( plotScalingRecalculated ( ) ) , this , SLOT ( masterPlotScalingRecalculated ( ) ) ) ;
2015-07-11 18:56:02 +08:00
2022-11-03 22:48:48 +08:00
if ( master ) plotter - > synchronizeToMaster ( master - > getPlotter ( ) , synchronizeDirection , synchronizeAxisLength , synchronizeZoomingMasterToSlave , synchronizeZoomingSlaveToMaster ) ;
2015-07-11 18:56:02 +08:00
2019-02-03 21:04:48 +08:00
if ( synchronizeDirection = = JKQTBasePlotter : : sdXAxis | | synchronizeDirection = = JKQTBasePlotter : : sdXYAxes ) {
masterPlotterX = master ;
if ( masterPlotterX ) connect ( masterPlotterX - > getPlotter ( ) , SIGNAL ( plotScalingRecalculated ( ) ) , this , SLOT ( masterPlotScalingRecalculated ( ) ) ) ;
2015-07-11 18:56:02 +08:00
}
2019-02-03 21:04:48 +08:00
if ( synchronizeDirection = = JKQTBasePlotter : : sdYAxis | | synchronizeDirection = = JKQTBasePlotter : : sdXYAxes ) {
masterPlotterY = master ;
if ( masterPlotterY ) connect ( masterPlotterY - > getPlotter ( ) , SIGNAL ( plotScalingRecalculated ( ) ) , this , SLOT ( masterPlotScalingRecalculated ( ) ) ) ;
2015-07-11 18:56:02 +08:00
}
2019-02-03 21:04:48 +08:00
2019-01-26 19:28:44 +08:00
redrawPlot ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-02-03 21:04:48 +08:00
void JKQTPlotter : : synchronizeXToMaster ( JKQTPlotter * master , bool synchronizeAxisLength , bool synchronizeZoomingMasterToSlave , bool synchronizeZoomingSlaveToMaster )
{
synchronizeToMaster ( master , JKQTBasePlotter : : sdXAxis , synchronizeAxisLength , synchronizeZoomingMasterToSlave , synchronizeZoomingSlaveToMaster ) ;
}
void JKQTPlotter : : synchronizeYToMaster ( JKQTPlotter * master , bool synchronizeAxisLength , bool synchronizeZoomingMasterToSlave , bool synchronizeZoomingSlaveToMaster )
{
synchronizeToMaster ( master , JKQTBasePlotter : : sdYAxis , synchronizeAxisLength , synchronizeZoomingMasterToSlave , synchronizeZoomingSlaveToMaster ) ;
}
void JKQTPlotter : : resetMasterSynchronization ( JKQTBasePlotter : : SynchronizationDirection synchronizeDirection )
{
synchronizeToMaster ( nullptr , synchronizeDirection , false , false , false ) ;
}
void JKQTPlotter : : masterPlotScalingRecalculated ( ) {
//qDebug()<<"this="<<this<<", sender="<<sender()<<" --> masterPlotScalingRecalculated()";
2019-01-26 19:28:44 +08:00
redrawPlot ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-29 05:14:27 +08:00
void JKQTPlotter : : setGridPrinting ( bool enabled )
{
plotter - > setGridPrinting ( enabled ) ;
}
void JKQTPlotter : : addGridPrintingPlotter ( size_t x , size_t y , JKQTPlotter * plotterOther )
{
plotter - > addGridPrintingPlotter ( x , y , plotterOther - > getPlotter ( ) ) ;
}
void JKQTPlotter : : clearGridPrintingPlotters ( )
{
plotter - > clearGridPrintingPlotters ( ) ;
}
void JKQTPlotter : : setGridPrintingCurrentX ( size_t x )
{
plotter - > setGridPrintingCurrentX ( x ) ;
}
void JKQTPlotter : : setGridPrintingCurrentY ( size_t y )
{
plotter - > setGridPrintingCurrentY ( y ) ;
}
void JKQTPlotter : : setGridPrintingCurrentPos ( size_t x , size_t y )
{
plotter - > setGridPrintingCurrentPos ( x , y ) ;
}
2019-01-26 03:16:04 +08:00
bool JKQTPlotter : : isPlotUpdateEnabled ( ) const {
2019-01-25 05:49:10 +08:00
return doDrawing ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : pzoomChangedLocally ( double newxmin , double newxmax , double newymin , double newymax , JKQTBasePlotter * /*sender*/ ) {
2015-07-11 18:56:02 +08:00
emit zoomChangedLocally ( newxmin , newxmax , newymin , newymax , this ) ;
2019-06-21 21:46:53 +08:00
minSize = QSizeF ( plotter - > getInternalPlotBorderLeft ( ) + plotter - > getInternalPlotBorderRight ( ) + 10 , plotter - > getInternalPlotBorderTop ( ) + plotter - > getInternalPlotBorderBottom ( ) + 10 ) . toSize ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : intBeforePlotScalingRecalculate ( ) {
2015-07-11 18:56:02 +08:00
emit beforePlotScalingRecalculate ( ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : reactGraphVisible ( bool visible )
2018-08-20 00:17:18 +08:00
{
QAction * act = dynamic_cast < QAction * > ( sender ( ) ) ;
if ( act ) {
2019-01-26 03:16:04 +08:00
getPlotter ( ) - > setGraphVisible ( act - > data ( ) . toInt ( ) , visible ) ;
2018-08-20 00:17:18 +08:00
}
}
2019-05-06 01:31:20 +08:00
void JKQTPlotter : : setMouseLeftActionAsPanView ( )
{
setOverrideMouseDragAction ( Qt : : LeftButton , Qt : : NoModifier , JKQTPMouseDragActions : : jkqtpmdaPanPlotOnMove ) ;
}
void JKQTPlotter : : setMouseLeftActionAsZoomRect ( )
{
setOverrideMouseDragAction ( Qt : : LeftButton , Qt : : NoModifier , JKQTPMouseDragActions : : jkqtpmdaZoomByRectangle ) ;
}
void JKQTPlotter : : setMouseLeftActionAsRuler ( )
{
setOverrideMouseDragAction ( Qt : : LeftButton , Qt : : NoModifier , JKQTPMouseDragActions : : jkqtpmdaRuler ) ;
}
2022-05-15 20:15:15 +08:00
void JKQTPlotter : : setMouseLeftDragActionAsToolTip ( )
2019-05-06 01:31:20 +08:00
{
setOverrideMouseDragAction ( Qt : : LeftButton , Qt : : NoModifier , JKQTPMouseDragActions : : jkqtpmdaToolTipForClosestDataPoint ) ;
}
void JKQTPlotter : : resetMouseLeftAction ( )
{
resetOverrideMouseDragAction ( Qt : : LeftButton , Qt : : NoModifier ) ;
}
2022-05-15 20:15:15 +08:00
void JKQTPlotter : : setMouseMoveActionAsToolTip ( bool enabled )
{
if ( enabled ) {
registerMouseMoveAction ( Qt : : NoModifier , JKQTPMouseMoveActions : : jkqtpmmaToolTipForClosestDataPoint ) ;
} else {
deregisterMouseMoveAction ( Qt : : NoModifier ) ;
}
}
2019-05-06 01:31:20 +08:00
void JKQTPlotter : : setMouseActionToolbarActionsActive ( bool __value )
{
actgrpMouseLeft - > setVisible ( __value ) ;
2022-05-15 20:15:15 +08:00
actMouseMoveToolTip - > setVisible ( __value ) ;
2019-05-06 01:31:20 +08:00
}
2022-05-15 20:15:15 +08:00
QAction * JKQTPlotter : : getActMouseLeftAsDefault ( ) {
2019-05-06 01:31:20 +08:00
return actMouseLeftAsDefault ;
}
2022-05-15 20:15:15 +08:00
QAction * JKQTPlotter : : getActMouseLeftAsZoomRect ( )
2019-05-06 01:31:20 +08:00
{
return actMouseLeftAsZoomRect ;
}
2022-05-15 20:15:15 +08:00
QAction * JKQTPlotter : : getActMouseLeftAsPanView ( )
2019-05-06 01:31:20 +08:00
{
return actMouseLeftAsPanView ;
}
2022-05-15 20:15:15 +08:00
QAction * JKQTPlotter : : getActMouseLeftAsRuler ( ) {
2019-05-06 01:31:20 +08:00
return actMouseLeftAsRuler ;
}
2022-05-15 20:15:15 +08:00
const QAction * JKQTPlotter : : getActMouseLeftAsDefault ( ) const {
return actMouseLeftAsDefault ;
}
const QAction * JKQTPlotter : : getActMouseLeftAsZoomRect ( ) const
{
return actMouseLeftAsZoomRect ;
}
const QAction * JKQTPlotter : : getActMouseLeftAsPanView ( ) const
{
return actMouseLeftAsPanView ;
}
const QAction * JKQTPlotter : : getActMouseLeftAsRuler ( ) const {
return actMouseLeftAsRuler ;
}
const QAction * JKQTPlotter : : getActMouseMoveToolTip ( ) const {
return actMouseMoveToolTip ;
}
QAction * JKQTPlotter : : getActMouseMoveToolTip ( ) {
return actMouseMoveToolTip ;
2019-05-06 01:31:20 +08:00
}
void JKQTPlotter : : setOverrideMouseDragAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifier , JKQTPMouseDragActions action )
{
2022-04-22 19:27:31 +08:00
registeredOverrideMouseDragActionModes . insert ( QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifier ) , action ) ;
2019-05-06 01:31:20 +08:00
}
void JKQTPlotter : : resetOverrideMouseDragAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifier )
{
2022-04-22 19:27:31 +08:00
registeredOverrideMouseDragActionModes . remove ( QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifier ) ) ;
2019-05-06 01:31:20 +08:00
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : setContextMenuMode ( JKQTPContextMenuModes mode ) {
2019-01-28 17:46:38 +08:00
contextMenuMode = mode ;
2019-01-28 06:24:12 +08:00
}
2019-01-28 17:46:38 +08:00
QMenu * JKQTPlotter : : getSpecialContextMenu ( ) const {
2019-05-01 18:46:17 +08:00
return this - > menuSpecialContextMenu ;
2019-01-25 05:49:10 +08:00
}
2019-01-28 17:46:38 +08:00
void JKQTPlotter : : setSpecialContextMenu ( QMenu * menu )
2015-10-12 23:05:15 +08:00
{
2019-05-01 18:46:17 +08:00
menuSpecialContextMenu = menu ;
if ( menuSpecialContextMenu ) {
menuSpecialContextMenu - > setParent ( this ) ;
menuSpecialContextMenu - > close ( ) ;
2015-10-12 23:05:15 +08:00
}
}
2019-01-26 03:16:04 +08:00
double JKQTPlotter : : getMouseContextX ( ) const {
2019-01-25 05:49:10 +08:00
return this - > mouseContextX ;
}
2019-01-26 03:16:04 +08:00
double JKQTPlotter : : getMouseContextY ( ) const {
2019-01-25 05:49:10 +08:00
return this - > mouseContextY ;
}
2019-01-26 03:16:04 +08:00
int JKQTPlotter : : getMouseLastClickX ( ) const {
2019-01-25 05:49:10 +08:00
return this - > mouseLastClickX ;
}
2019-01-26 03:16:04 +08:00
int JKQTPlotter : : getMouseLastClickY ( ) const {
2019-01-25 05:49:10 +08:00
return this - > mouseLastClickY ;
}
2019-02-08 00:24:46 +08:00
JKQTPContextMenuModes JKQTPlotter : : getContextMenuMode ( ) const {
2019-01-28 17:46:38 +08:00
return contextMenuMode ;
2019-01-28 06:24:12 +08:00
}
2019-02-08 00:24:46 +08:00
const JKQTPlotterStyle & JKQTPlotter : : getCurrentPlotterStyle ( ) const
{
return plotterStyle ;
}
void JKQTPlotter : : setCurrentPlotterStyle ( const JKQTPlotterStyle & style )
{
plotterStyle = style ;
updateToolbar ( ) ;
redrawPlot ( ) ;
}
void JKQTPlotter : : setCurrentPlotterStyle ( const JKQTPlotterStyle & style , const JKQTBasePlotterStyle & baseStyle )
{
plotterStyle = style ;
plotter - > setCurrentPlotterStyle ( baseStyle ) ;
updateToolbar ( ) ;
redrawPlot ( ) ;
}
void JKQTPlotter : : loadCurrentPlotterStyle ( const QSettings & settings , const QString & group , bool alsoLoadBaseStyle )
{
plotterStyle . loadSettings ( settings , group ) ;
if ( alsoLoadBaseStyle ) plotter - > loadCurrentPlotterStyle ( settings , group ) ;
updateToolbar ( ) ;
redrawPlot ( ) ;
}
void JKQTPlotter : : saveCurrentPlotterStyle ( QSettings & settings , const QString & group , bool alsoSaveBaseStyle ) const
{
plotterStyle . saveSettings ( settings , group ) ;
if ( alsoSaveBaseStyle ) plotter - > saveCurrentPlotterStyle ( settings , group ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : setMagnification ( double m )
2015-07-11 18:56:02 +08:00
{
magnification = m ;
2019-01-26 19:28:44 +08:00
redrawPlot ( ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : modifyContextMenu ( QMenu * /*menu*/ )
2015-07-11 18:56:02 +08:00
{
}
2019-02-08 00:24:46 +08:00
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : populateToolbar ( QToolBar * toolbar ) const
2015-07-11 18:56:02 +08:00
{
2019-01-26 03:16:04 +08:00
toolbar - > addAction ( plotter - > getActionSaveData ( ) ) ;
toolbar - > addAction ( plotter - > getActionSavePlot ( ) ) ;
2022-07-19 05:33:20 +08:00
# ifndef JKQTPLOTTER_COMPILE_WITHOUT_PRINTSUPPORT
2019-01-26 03:16:04 +08:00
toolbar - > addAction ( plotter - > getActionPrint ( ) ) ;
2022-07-19 05:33:20 +08:00
# endif
2015-07-11 18:56:02 +08:00
toolbar - > addSeparator ( ) ;
2019-01-26 03:16:04 +08:00
toolbar - > addAction ( plotter - > getActionCopyPixelImage ( ) ) ;
toolbar - > addAction ( plotter - > getActionCopyData ( ) ) ;
toolbar - > addAction ( plotter - > getActionCopyMatlab ( ) ) ;
2015-07-11 18:56:02 +08:00
toolbar - > addSeparator ( ) ;
2019-01-26 03:16:04 +08:00
toolbar - > addAction ( plotter - > getActionShowPlotData ( ) ) ;
2015-07-11 18:56:02 +08:00
toolbar - > addSeparator ( ) ;
2019-01-26 03:16:04 +08:00
toolbar - > addAction ( plotter - > getActionZoomAll ( ) ) ;
toolbar - > addAction ( plotter - > getActionZoomIn ( ) ) ;
toolbar - > addAction ( plotter - > getActionZoomOut ( ) ) ;
2019-05-06 01:31:20 +08:00
toolbar - > addSeparator ( ) ;
2022-05-15 20:15:15 +08:00
toolbar - > addAction ( actMouseMoveToolTip ) ;
toolbar - > addSeparator ( ) ;
2019-05-06 01:31:20 +08:00
toolbar - > addAction ( actMouseLeftAsDefault ) ;
toolbar - > addAction ( actMouseLeftAsPanView ) ;
toolbar - > addAction ( actMouseLeftAsZoomRect ) ;
toolbar - > addAction ( actMouseLeftAsRuler ) ;
2015-07-11 18:56:02 +08:00
if ( actions ( ) . size ( ) > 0 ) {
toolbar - > addSeparator ( ) ;
toolbar - > addActions ( actions ( ) ) ;
}
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : openContextMenu ( )
2015-10-12 23:05:15 +08:00
{
openContextMenu ( mouseLastClickX , mouseLastClickY ) ;
2019-01-28 17:46:38 +08:00
2015-10-12 23:05:15 +08:00
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : openContextMenu ( int x , int y )
2019-01-28 17:46:38 +08:00
{
2019-02-08 00:24:46 +08:00
if ( contextMenuMode = = JKQTPContextMenuModes : : jkqtpcmmStandardContextMenu ) {
2019-01-28 17:46:38 +08:00
openStandardContextMenu ( x , y ) ;
2019-02-08 00:24:46 +08:00
} else if ( contextMenuMode = = JKQTPContextMenuModes : : jkqtpcmmSpecialContextMenu ) {
2019-01-28 17:46:38 +08:00
openSpecialContextMenu ( x , y ) ;
2019-02-08 00:24:46 +08:00
} else if ( contextMenuMode = = JKQTPContextMenuModes : : jkqtpcmmStandardAndSpecialContextMenu ) {
2019-01-28 17:46:38 +08:00
openStandardAndSpecialContextMenu ( x , y ) ;
}
}
void JKQTPlotter : : openStandardContextMenu ( )
{
openStandardContextMenu ( mouseLastClickX , mouseLastClickY ) ;
}
2019-05-01 18:46:17 +08:00
void JKQTPlotter : : resetContextMenu ( bool createnew )
{
if ( contextMenu ) {
contextMenu - > close ( ) ;
contextMenu - > clear ( ) ;
qDeleteAll ( contextSubMenus ) ;
contextSubMenus . clear ( ) ;
delete contextMenu ;
2019-05-06 01:31:20 +08:00
}
if ( createnew ) {
contextMenu = new QMenu ( this ) ;
} else {
contextMenu = nullptr ;
2019-05-01 18:46:17 +08:00
}
}
2019-01-28 17:46:38 +08:00
void JKQTPlotter : : openStandardContextMenu ( int x , int y )
2015-10-12 23:05:15 +08:00
{
//qDebug()<<"openContextMenu("<<x<<y<<contextMenu<<")";
mouseContextX = plotter - > p2x ( x / magnification ) ;
mouseContextY = plotter - > p2y ( ( y - getPlotYOffset ( ) ) / magnification ) ;
initContextMenu ( ) ;
contextMenu - > popup ( mapToGlobal ( QPoint ( x , y ) ) ) ;
2015-10-14 19:24:10 +08:00
//qDebug()<<" -> "<<mapToGlobal(QPoint(x,y))<<contextMenu->size()<<contextMenu->pos()<<contextMenu->parent();
2015-10-12 23:05:15 +08:00
emit contextMenuOpened ( mouseContextX , mouseContextY , contextMenu ) ;
//qDebug()<<"openContextMenu("<<x<<y<<contextMenu<<") ... DONE";
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : openSpecialContextMenu ( )
2015-10-12 23:05:15 +08:00
{
openSpecialContextMenu ( mouseLastClickX , mouseLastClickY ) ;
}
2019-01-20 23:15:10 +08:00
void JKQTPlotter : : openSpecialContextMenu ( int x , int y )
2015-10-12 23:05:15 +08:00
{
2019-05-01 18:46:17 +08:00
//qDebug()<<"openSpecialContextMenu("<<x<<y<<menuSpecialContextMenu<<")";
if ( menuSpecialContextMenu ) {
2015-10-12 23:05:15 +08:00
mouseContextX = plotter - > p2x ( x / magnification ) ;
mouseContextY = plotter - > p2y ( ( y - getPlotYOffset ( ) ) / magnification ) ;
2019-05-01 18:46:17 +08:00
menuSpecialContextMenu - > close ( ) ;
menuSpecialContextMenu - > popup ( mapToGlobal ( QPoint ( x , y ) ) ) ;
menuSpecialContextMenu - > resize ( menuSpecialContextMenu - > sizeHint ( ) ) ;
//qDebug()<<" -> "<<mapToGlobal(QPoint(x,y))<<menuSpecialContextMenu->size()<<menuSpecialContextMenu->pos()<<menuSpecialContextMenu->parent();
emit contextMenuOpened ( mouseContextX , mouseContextY , menuSpecialContextMenu ) ;
//qDebug()<<"openSpecialContextMenu("<<x<<y<<menuSpecialContextMenu<<") ... DONE";
2015-10-12 23:05:15 +08:00
}
}
2019-01-28 17:46:38 +08:00
void JKQTPlotter : : openStandardAndSpecialContextMenu ( )
{
openStandardAndSpecialContextMenu ( mouseLastClickX , mouseLastClickY ) ;
}
void JKQTPlotter : : openStandardAndSpecialContextMenu ( int x , int y )
{
//qDebug()<<"openContextMenu("<<x<<y<<contextMenu<<")";
mouseContextX = plotter - > p2x ( x / magnification ) ;
mouseContextY = plotter - > p2y ( ( y - getPlotYOffset ( ) ) / magnification ) ;
initContextMenu ( ) ;
2019-05-01 18:46:17 +08:00
if ( menuSpecialContextMenu ) {
2019-01-28 17:46:38 +08:00
contextMenu - > addSeparator ( ) ;
2019-05-01 18:46:17 +08:00
for ( QAction * act : menuSpecialContextMenu - > actions ( ) ) {
2019-01-28 17:46:38 +08:00
contextMenu - > addAction ( act ) ;
}
}
contextMenu - > popup ( mapToGlobal ( QPoint ( x , y ) ) ) ;
//qDebug()<<" -> "<<mapToGlobal(QPoint(x,y))<<contextMenu->size()<<contextMenu->pos()<<contextMenu->parent();
emit contextMenuOpened ( mouseContextX , mouseContextY , contextMenu ) ;
//qDebug()<<"openContextMenu("<<x<<y<<contextMenu<<") ... DONE";
}
2019-05-06 01:31:20 +08:00
JKQTPMouseDragActionsHashMapIterator JKQTPlotter : : findMatchingMouseDragAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifiers , bool * found ) const
2019-01-28 06:24:12 +08:00
{
2022-04-21 19:33:22 +08:00
if ( found ) * found = false ;
JKQTPMouseDragActionsHashMapIterator it = registeredOverrideMouseDragActionModes . cbegin ( ) ;
while ( it ! = registeredOverrideMouseDragActionModes . cend ( ) ) {
2022-04-22 19:27:31 +08:00
if ( it . key ( ) = = QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifiers ) ) {
2019-06-21 21:46:53 +08:00
if ( found ) * found = true ;
return it ;
}
+ + it ;
2019-05-06 01:31:20 +08:00
}
2022-04-21 19:33:22 +08:00
it = plotterStyle . registeredMouseDragActionModes . cbegin ( ) ;
while ( it ! = plotterStyle . registeredMouseDragActionModes . cend ( ) ) {
2022-04-22 19:27:31 +08:00
if ( it . key ( ) = = QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifiers ) ) {
2019-06-21 21:46:53 +08:00
if ( found ) * found = true ;
return it ;
}
+ + it ;
}
2022-04-21 19:33:22 +08:00
return plotterStyle . registeredMouseDragActionModes . cend ( ) ;
2019-01-29 00:05:03 +08:00
}
2019-01-28 06:24:12 +08:00
2022-04-21 19:33:22 +08:00
JKQTPMouseDoubleClickActionsHashMapIterator JKQTPlotter : : findMatchingMouseDoubleClickAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifiers , bool * found ) const
2019-01-29 00:05:03 +08:00
{
2022-04-21 19:33:22 +08:00
if ( found ) * found = false ;
for ( JKQTPMouseDoubleClickActionsHashMapIterator it = plotterStyle . registeredMouseDoubleClickActions . cbegin ( ) ; it ! = plotterStyle . registeredMouseDoubleClickActions . cend ( ) ; + + it ) {
2022-04-22 19:27:31 +08:00
if ( it . key ( ) = = QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifiers ) ) {
2022-04-21 19:33:22 +08:00
if ( found ) * found = true ;
2019-06-21 21:46:53 +08:00
return it ;
}
}
2022-04-21 19:33:22 +08:00
return plotterStyle . registeredMouseDoubleClickActions . cend ( ) ;
2019-01-28 06:24:12 +08:00
}
2022-04-21 19:33:22 +08:00
JKQTPMouseWheelActionsHashMapIterator JKQTPlotter : : findMatchingMouseWheelAction ( Qt : : KeyboardModifiers modifiers , bool * found ) const
2019-01-29 00:05:03 +08:00
{
2022-04-21 19:33:22 +08:00
if ( found ) * found = false ;
2019-06-21 21:46:53 +08:00
for ( JKQTPMouseWheelActionsHashMapIterator it = plotterStyle . registeredMouseWheelActions . begin ( ) ; it ! = plotterStyle . registeredMouseWheelActions . end ( ) ; + + it ) {
if ( it . key ( ) = = modifiers ) {
2022-04-21 19:33:22 +08:00
if ( found ) * found = true ;
2019-06-21 21:46:53 +08:00
return it ;
}
}
return plotterStyle . registeredMouseWheelActions . end ( ) ;
//return plotterStyle.registeredMouseWheelActions.find(modifiers);
2019-01-29 00:05:03 +08:00
}
2015-07-11 18:56:02 +08:00
2022-05-15 20:15:15 +08:00
JKQTPMouseMoveActionsHashMapIterator JKQTPlotter : : findMatchingMouseMoveAction ( Qt : : KeyboardModifiers modifiers , bool * found ) const
{
if ( found ) * found = false ;
for ( JKQTPMouseMoveActionsHashMapIterator it = plotterStyle . registeredMouseMoveActions . begin ( ) ; it ! = plotterStyle . registeredMouseMoveActions . end ( ) ; + + it ) {
if ( it . key ( ) = = modifiers ) {
if ( found ) * found = true ;
return it ;
}
}
return plotterStyle . registeredMouseMoveActions . end ( ) ;
//return plotterStyle.registeredMouseMoveActions.find(modifiers);
}
2019-01-26 03:16:04 +08:00
void JKQTPlotter : : setPlotUpdateEnabled ( bool enable )
2015-07-11 18:56:02 +08:00
{
doDrawing = enable ;
2019-01-26 03:16:04 +08:00
plotter - > setEmittingSignalsEnabled ( enable ) ;
2015-07-11 18:56:02 +08:00
//qDebug()<<objectName()<<" doDrawing="<<doDrawing;
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : registerMouseDragAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifier , JKQTPMouseDragActions action )
2019-01-28 06:24:12 +08:00
{
2022-04-22 19:27:31 +08:00
plotterStyle . registeredMouseDragActionModes [ QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifier ) ] = action ;
2019-05-06 01:31:20 +08:00
if ( button = = Qt : : LeftButton & & modifier = = Qt : : NoModifier ) {
actMouseLeftAsDefault - > setChecked ( true ) ;
resetMouseLeftAction ( ) ;
}
2019-01-28 06:24:12 +08:00
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : deregisterMouseDragAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifier )
2019-01-28 06:24:12 +08:00
{
2022-04-22 19:27:31 +08:00
plotterStyle . registeredMouseDragActionModes . remove ( QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifier ) ) ;
2019-01-28 06:24:12 +08:00
}
void JKQTPlotter : : clearAllRegisteredMouseDragActions ( )
{
2019-02-08 00:24:46 +08:00
plotterStyle . registeredMouseDragActionModes . clear ( ) ;
2019-01-29 00:05:03 +08:00
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : registerMouseDoubleClickAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifier , JKQTPMouseDoubleClickActions action )
2019-01-29 00:05:03 +08:00
{
2022-04-22 19:27:31 +08:00
plotterStyle . registeredMouseDoubleClickActions [ QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifier ) ] = action ;
2019-01-29 00:05:03 +08:00
}
2019-02-08 00:24:46 +08:00
void JKQTPlotter : : deregisterMouseDoubleClickAction ( Qt : : MouseButton button , Qt : : KeyboardModifiers modifier )
2019-01-29 00:05:03 +08:00
{
2022-04-22 19:27:31 +08:00
plotterStyle . registeredMouseDoubleClickActions . remove ( QPair < Qt : : MouseButton , Qt : : KeyboardModifiers > ( button , modifier ) ) ;
2019-01-29 00:05:03 +08:00
}
void JKQTPlotter : : clearAllRegisteredMouseDoubleClickActions ( )
{
2019-02-08 00:24:46 +08:00
plotterStyle . registeredMouseDoubleClickActions . clear ( ) ;
2019-01-28 06:24:12 +08:00
}
2018-12-03 01:30:12 +08:00
2019-01-20 23:15:10 +08:00
void initJKQTPlotterResources ( )
2018-12-03 01:30:12 +08:00
{
2019-01-20 17:49:29 +08:00
initJKQTBasePlotterResources ( ) ;
2018-12-03 01:30:12 +08:00
}
2019-01-28 06:24:12 +08:00
JKQTPlotter : : MouseDragAction : : MouseDragAction ( ) :
2019-02-08 00:24:46 +08:00
mode ( jkqtpmdaZoomByRectangle ) , modifier ( Qt : : NoModifier ) , mouseButton ( Qt : : LeftButton ) , valid ( false )
2019-01-28 06:24:12 +08:00
{
}
2019-02-08 00:24:46 +08:00
JKQTPlotter : : MouseDragAction : : MouseDragAction ( Qt : : MouseButton _mouseButton , Qt : : KeyboardModifiers _modifier , JKQTPMouseDragActions _mode ) :
2019-01-28 06:24:12 +08:00
mode ( _mode ) , modifier ( _modifier ) , mouseButton ( _mouseButton ) , valid ( true )
{
}
bool JKQTPlotter : : MouseDragAction : : isValid ( ) const {
return valid ;
}
void JKQTPlotter : : MouseDragAction : : clear ( )
{
valid = false ;
2019-02-08 00:24:46 +08:00
mode = jkqtpmdaZoomByRectangle ;
2019-01-28 06:24:12 +08:00
modifier = Qt : : NoModifier ;
mouseButton = Qt : : LeftButton ;
}