2015-07-11 18:56:02 +08:00
/*
2018-11-25 21:53:26 +08:00
Copyright ( c ) 2008 - 2018 Jan W . Krieger ( < jan @ jkrieger . de > , < j . krieger @ dkfz . de > ) , German Cancer Research Center
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 General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
/**
* \ defgroup jkqtplotter Qt based Scientific Plotter Class
* \ ingroup tools_qt
*
* A Qt based plotter for 2 D scientific graphs .
*/
/** \file jkqtplotter.h
* \ ingroup jkqtplotter
*
* A Qt based plotter for 2 D scientific graphs .
*/
# include <QWidget>
# include <QVector>
# include <QSettings>
# include <QColor>
# include <QMap>
# include <QVector>
# include <QScrollArea>
# include <QVBoxLayout>
# include <QToolBar>
# include <QGridLayout>
# include <QListWidget>
# include <QListWidgetItem>
# include <QToolBar>
# include <QPointer>
# include <QTimer>
# include <vector>
# include <cmath>
# include <iostream>
# include "jkqtpbaseplotter.h"
# include "jkqtptools.h"
# include "jkqtp_imexport.h"
# include <QKeyEvent>
# ifndef JKQTPLOTTER_H
# define JKQTPLOTTER_H
/** \brief class to plot function graphs in linear or (semi-)logarithmic scale
* \ ingroup jkqtplotter
*
* This class is an implementation of JKQtPlotterBase . It uses the tools from this base class
* to display function graphs that use the internal datastore as data source . You can add graphs
* to this component which are described by a JKQTPgraph struct .
*/
class LIB_EXPORT JKQtPlotter : public QWidget {
Q_OBJECT
public :
enum MouseActionModes {
ZoomRectangle ,
RectangleEvents ,
/*PolygonEvents,*/
CircleEvents ,
EllipseEvents ,
LineEvents ,
ScribbleEvents ,
NoMouseAction ,
ClickEvents
} ;
enum RightMouseButtonAction {
RightMouseButtonNone = 0 ,
RightMouseButtonZoom = 1 ,
RightMouseButtonContextMenu = 2
} ;
2015-10-12 23:05:15 +08:00
enum LeftDoubleClickAction {
LeftDoubleClickDefault ,
LeftDoubleClickContextMenu ,
LeftDoubleClickSpecialContextMenu ,
} ;
2015-07-11 18:56:02 +08:00
/** \brief class constructor
*/
2018-11-18 18:59:30 +08:00
explicit JKQtPlotter ( bool datastore_internal , QWidget * parent = nullptr , JKQTPdatastore * datast = nullptr ) ;
explicit JKQtPlotter ( QWidget * parent = nullptr ) ;
2015-07-11 18:56:02 +08:00
/** \brief class destructor */
virtual ~ JKQtPlotter ( ) ;
/** reinitializes the toolbar, i.e. fills in QActions added to the QWidget since its creation/the last call to this function */
virtual void updateToolbarActions ( ) ;
/** \brief set the width/height of the icons in the toolbar in pixels */
inline void set_toolbarIconSize ( int value ) {
toolbarIconSize = value ;
QSize s = QSize ( toolbarIconSize , toolbarIconSize ) ;
toolbar - > setIconSize ( s ) ;
} ;
/** \brief get the width/height of the icons in the toolbar in pixels */
inline int get_toolbarIconSize ( ) {
return toolbarIconSize ;
} ;
/** \brief returns the class internally used for plotting */
2015-08-02 19:36:54 +08:00
JKQtBasePlotter * get_plotter ( ) const { return plotter ; }
/** \brief returns the class internally used for plotting */
const JKQtBasePlotter * get_constplotter ( ) const { return const_cast < const JKQtBasePlotter * > ( plotter ) ; }
2015-07-11 18:56:02 +08:00
JKQTPGET_SET_MACRO_I ( bool , displayToolbar , updateToolbar ( ) )
JKQTPGET_SET_MACRO_I ( bool , toolbarAlwaysOn , updateToolbar ( ) )
JKQTPGET_SET_MACRO ( bool , displayMousePosition )
JKQTPGET_SET_MACRO ( bool , displayCustomMousePosition )
JKQTPGET_SET_MACRO_I ( QColor , userActionColor , update ( ) )
JKQTPGET_SET_MACRO_I ( QPainter : : CompositionMode , userActionCompositionMode , update ( ) )
JKQTPGET_SET_MACRO_I ( MouseActionModes , mouseActionMode , updateCursor ( ) )
/** \brief loads the plot properties from a QSettings object */
virtual void loadSettings ( QSettings & settings , QString group = QString ( " plots " ) ) ;
/** \brief saves the plot properties into a QSettings object.
*
* This method only saves those properties that differ from their default value .
*/
virtual void saveSettings ( QSettings & settings , QString group = QString ( " plots " ) ) ;
/** \brief returns the minimum size of the widget */
QSize minimumSizeHint ( ) const ;
/** \brief returns the size of the widget */
QSize sizeHint ( ) const ;
/*! \brief synchronize the plot borders with a given plotter
This function allows two plotters to draw a graph with exactly the same height or width
as in another graph . For example if you want to have two plotters which are positioned one
above the other ( and have the same widget widths , which could be guaranteed by a QLayout )
you may want to make sure that their plotWidth s are always the same . In this case call
\ code plotter2 - > synchronizeToMaster ( plotter1 , true , false ) \ endcode of the lower plotter \ c plotter2 .
Now whenever the size of plotter1 changes , also plotter2 is redrawn with the changed
borders .
\ param master the plotter widget to synchronize to
\ param synchronizeWidth do you want the plot width to be synchronized ?
\ param synchronizeHeight do you want the plot height to be synchronized ?
*/
void synchronizeToMaster ( JKQtPlotter * master , bool synchronizeWidth , bool synchronizeHeight ) ;
/** \brief switches any synchronization off, that has been created by synchronizeToMaster() */
void resetMasterSynchronization ( ) ;
/** \brief returns a pointer to the datastore used by this object */
inline JKQTPdatastore * getDatastore ( ) { return plotter - > getDatastore ( ) ; }
/** \brief tells the plotter object to use the given external datastore.
*
* If the current datastore is internally managed , this method will free that object and use the supplied datastore
* with external management . If the current datastore is already external , this method will simply replace it by the
* new one .
*/
inline void useExternalDatastore ( JKQTPdatastore * newStore ) { plotter - > useExternalDatastore ( newStore ) ; }
/** \brief tells the plotter object to use the given external datastore and treat it as an internal one (i.e. free it
* when the plotter object ist destroyed .
*/
inline void useAsInternalDatastore ( JKQTPdatastore * newStore ) { plotter - > useAsInternalDatastore ( newStore ) ; }
/** \brief tells the plotter object to use an internal datastore. A new internal datastore object is generated only if
* the current datastore is not internal .
*/
inline void useInternalDatastore ( ) { plotter - > useInternalDatastore ( ) ; }
/** \brief tells the plotter object to use an internal datastore (just like useInternalDatastore() ), but forces the
* generation of a new datastore , even if the current one is already internal ( the current one will be freed in
* the lather case */
inline void forceInternalDatastore ( ) { plotter - > forceInternalDatastore ( ) ; }
inline void set_emitSignals ( bool sig ) { plotter - > set_emitSignals ( sig ) ; }
inline bool get_emitSignals ( ) { return plotter - > get_emitSignals ( ) ; }
JKQTPGetMacro ( bool , doDrawing ) ;
void set_doDrawing ( bool enable ) ;
bool get_zoomByMouseRectangle ( ) const ;
void set_zoomByMouseRectangle ( bool zomByrectangle ) ;
//GET_SET_MACRO(bool, zoomByDoubleAndRightMouseClick);
JKQTPGET_SET_MACRO ( RightMouseButtonAction , rightMouseButtonAction ) ;
2015-10-12 23:05:15 +08:00
JKQTPGET_SET_MACRO ( LeftDoubleClickAction , leftDoubleClickAction ) ;
JKQTPGET_MACRO ( QMenu * , menuSpecialContextMenu ) ;
void set_menuSpecialContextMenu ( QMenu * menu ) ;
2015-07-11 18:56:02 +08:00
JKQTPGET_SET_MACRO ( bool , zoomByMouseWheel ) ;
2015-10-10 18:42:55 +08:00
JKQTPGetMacro ( double , mouseContextX )
JKQTPGetMacro ( double , mouseContextY )
2015-10-12 23:05:15 +08:00
JKQTPGetMacro ( int , mouseLastClickX )
JKQTPGetMacro ( int , mouseLastClickY )
2015-10-10 18:42:55 +08:00
2015-07-11 18:56:02 +08:00
inline JKQTPhorizontalAxis * getXAxis ( ) { return plotter - > getXAxis ( ) ; }
inline JKQTPverticalAxis * getYAxis ( ) { return plotter - > getYAxis ( ) ; }
inline JKQTPhorizontalAxis * get_xAxis ( ) { return plotter - > get_xAxis ( ) ; }
inline JKQTPverticalAxis * get_yAxis ( ) { return plotter - > get_yAxis ( ) ; }
/** \brief returns description of i'th graph */
inline JKQTPgraph * getGraph ( size_t i ) { return plotter - > getGraph ( i ) ; }
/** \brief returns the number of graphs */
inline size_t getGraphCount ( ) { return plotter - > getGraphCount ( ) ; }
/** \brief remove the i-th graph */
inline void deleteGraph ( size_t i , bool deletegraph = true ) { plotter - > deleteGraph ( i , deletegraph ) ; }
/** \brief returns \c true, if the given graph is present */
inline bool containsGraph ( JKQTPgraph * gr ) { return plotter - > containsGraph ( gr ) ; }
/** \brief remove the given graph, if it is contained */
inline void deleteGraph ( JKQTPgraph * gr , bool deletegraph = true ) { plotter - > deleteGraph ( gr , deletegraph ) ; } ;
/** \brief remove all plots
*
* \ param deleteGraphs if set \ c true ( default ) the graph objects will also be deleted
*/
inline void clearGraphs ( bool deleteGraphs = true ) { plotter - > clearGraphs ( deleteGraphs ) ; }
/** \brief add a new graph, returns it's position in the graphs list */
inline size_t addGraph ( JKQTPgraph * gr ) { return plotter - > addGraph ( gr ) ; }
/** \brief move the given graph to the top, or add it, if it is not yet contained */
inline size_t moveGraphTop ( JKQTPgraph * gr ) { return plotter - > moveGraphTop ( gr ) ; }
/** \brief move the given graph to the top, or add it, if it is not yet contained */
inline size_t moveGraphBottom ( JKQTPgraph * gr ) { return plotter - > moveGraphBottom ( gr ) ; }
2018-11-25 21:53:26 +08:00
/** \brief add a new graphs from a QVector<JKQTPgraph*>, QList<JKQTPgraph*>, std::vector<JKQTPgraph*> ... or any standard-iterateable container with JKQTPgraph*-items */
template < class TJKQTPgraphContainer >
inline void addGraphs ( const TJKQTPgraphContainer & gr ) { plotter - > addGraphs ( gr ) ; }
2015-07-11 18:56:02 +08:00
/** \brief sets minimum and maximum x-value to plot */
inline void setX ( double xminn , double xmaxx ) { plotter - > setX ( xminn , xmaxx ) ; }
/** \brief sets minimum and maximum y-value to plot */
inline void setY ( double yminn , double ymaxx ) { plotter - > setY ( yminn , ymaxx ) ; }
/** \brief sets minimum and maximum x- and y-values to plot */
inline void setXY ( double xminn , double xmaxx , double yminn , double ymaxx ) { plotter - > setXY ( xminn , xmaxx , yminn , ymaxx ) ; }
/** \brief returns the current x-axis min */
inline double getXMin ( ) const { return plotter - > getXMin ( ) ; }
/** \brief returns the current x-axis max */
inline double getXMax ( ) const { return plotter - > getXMax ( ) ; }
/** \brief returns the current y-axis min */
inline double getYMin ( ) const { return plotter - > getYMin ( ) ; }
/** \brief returns the current y-axis max */
inline double getYMax ( ) const { return plotter - > getYMax ( ) ; }
/** \brief sets absolute minimum and maximum x-value to plot */
inline void setAbsoluteX ( double xminn , double xmaxx ) { plotter - > setAbsoluteX ( xminn , xmaxx ) ; }
/** \brief sets absolute minimum and maximum y-value to plot */
inline void setAbsoluteY ( double yminn , double ymaxx ) { plotter - > setAbsoluteY ( yminn , ymaxx ) ; }
/** \brief sets absolute minimum and maximum x- and y-values to plot */
inline void setAbsoluteXY ( double xminn , double xmaxx , double yminn , double ymaxx ) { plotter - > setAbsoluteXY ( xminn , xmaxx , yminn , ymaxx ) ; }
/** \brief returns the absolute x-axis min */
inline double getAbsoluteXMin ( ) const { return plotter - > getAbsoluteXMin ( ) ; }
/** \brief returns the absolute x-axis max */
inline double getAbsoluteXMax ( ) const { return plotter - > getAbsoluteXMax ( ) ; }
/** \brief returns the absolute y-axis min */
inline double getAbsoluteYMin ( ) const { return plotter - > getAbsoluteYMin ( ) ; }
/** \brief returns the absolute y-axis max */
inline double getAbsoluteYMax ( ) const { return plotter - > getAbsoluteYMax ( ) ; }
inline double getMagnification ( ) const { return magnification ; }
2015-08-02 19:36:54 +08:00
/** \brief gets the next unused style id, i.e. the smalles number >=0 which is not contained in usedStyles */
inline int getNextStyle ( ) {
return get_plotter ( ) - > getNextStyle ( ) ;
}
/** \brief returns a QPen object for the i-th plot style */
inline JKQtBasePlotter : : JKQTPPen getPlotStyle ( int i ) const {
return get_constplotter ( ) - > getPlotStyle ( i ) ;
}
/** \brief font face for key labels */
inline QString get_keyFont ( ) const {
return get_constplotter ( ) - > get_keyFont ( ) ;
}
/** \brief font size for key labels [in points] */
inline double get_keyFontSize ( ) const {
return get_constplotter ( ) - > get_keyFontSize ( ) ;
}
2015-07-11 18:56:02 +08:00
public slots :
/** \brief set the plot magnification */
void setMagnification ( double m ) ;
/** \brief sets x/ymin and x/ymax to the supplied values and replots the graph (zoom operation!) */
inline void zoom ( double nxmin , double nxmax , double nymin , double nymax ) {
plotter - > zoom ( nxmin , nxmax , nymin , nymax ) ;
}
/** \brief sets whether to plot grid lines or not */
inline void setGrid ( bool val ) {
plotter - > setGrid ( val ) ;
}
/** \brief save the current plot as an image file, with the current widget aspect ratio, if filename is empty a file selection dialog is displayed.
* The image format is extracted from the file extension ( jpeg , tiff , png , pdf , . . . ) */
inline void saveImage ( QString filename = QString ( " " ) , bool displayPreview = true ) {
plotter - > saveImage ( filename , displayPreview ) ;
}
/** \brief save the data used for the current plot. The file format is extracted from the file extension (csv, ...)
*
* The parameter \ a format specifies the export format . if it is empty the format will be choosen according to the file extension , or
* if \ a filename is also empty the format will be choosen according to what is selected in the file selection dialog .
*
* If \ a format is \ c " slk " the output will be in SYLK format , if \ a format is \ c " csv " or \ a " dat " the output will be comma separated values
* and if \ a format is \ c " txt " the output will be tab separated values .
*/
inline void saveData ( QString filename = QString ( " " ) , QString format = QString ( " " ) ) {
plotter - > saveData ( filename , format ) ;
}
2018-11-18 18:59:30 +08:00
/** \brief print the current plot, if printer is \c nullptr a printer selection dialog is displayed */
inline void print ( QPrinter * printer = nullptr ) {
2015-07-11 18:56:02 +08:00
plotter - > print ( printer ) ;
}
/** \brief copy displayed data to cpliboard */
inline void copyData ( ) {
plotter - > copyData ( ) ;
}
/** \brief copy displayed data to cpliboard in Matlab syntax */
inline void copyDataMatlab ( ) {
plotter - > copyDataMatlab ( ) ;
}
/** \brief this method zooms the graph so that all plotted datapoints are visible.
*
* \ param zoomX if set \ c true ( default ) zooms the x axis
* \ param zoomY if set \ c true ( default ) zooms the y axis
* \ param includeX0 if this is \ c true zoomToFit ( ) will ensure that \ f $ x = 0 \ f $ is visible in the plot ( only for non - logx plots , default : false )
* \ param includeY0 if this is \ c true zoomToFit ( ) will ensure that \ f $ y = 0 \ f $ is visible in the plot ( only for non - logy plots , default : false )
* \ param scaleX the plot will have a width of \ f $ \ mbox { Xscale } \ cdot \ Delta x \ f $ where \ f $ \ Delta x \ f $ is the actual x - axis data range
* For logx plots we actually use this on the logarithmized data ! ( default : 1.05 )
* \ param scaleY the plot will have a height of \ f $ \ mbox { Yscale } \ cdot \ Delta < \ f $ where \ f $ \ Delta < \ f $ is the actual < - axis data range
* For log < plots we actually use this on the logarithmized data ! ( default : 1.05 )
*
*/
inline void zoomToFit ( bool zoomX = true , bool zoomY = true , bool includeX0 = false , bool includeY0 = false , double scaleX = 1.05 , double scaleY = 1.05 ) {
plotter - > zoomToFit ( zoomX , zoomY , includeX0 , includeY0 , scaleX , scaleY ) ;
}
/** \brief zooms into the graph (the same as turning the mouse wheel) by the given factor */
inline void zoomIn ( double factor = 2.0 ) { plotter - > zoomIn ( factor ) ; } ;
/** \brief zooms out of the graph (the same as turning the mouse wheel) by the given factor */
inline void zoomOut ( double factor = 2.0 ) { plotter - > zoomOut ( factor ) ; } ;
/** \brief update the plot */
void update_plot ( ) ;
/** \brief update the plot and replot immediately */
void replot_plot ( ) ;
/** \brief update overlays only */
void replot_overlays ( ) ;
/** \brief update overlays only */
void update_overlays ( ) ;
/** \brief may be connected to zoomChangedLocally() of a different plot and synchronizes the local x-axis to the other x-axis */
void synchronizeXAxis ( double newxmin , double newxmax , double newymin , double newymax , JKQtPlotter * sender ) ;
/** \brief may be connected to zoomChangedLocally() of a different plot and synchronizes the local y-axis to the other y-axis */
void synchronizeYAxis ( double newxmin , double newxmax , double newymin , double newymax , JKQtPlotter * sender ) ;
/** \brief may be connected to zoomChangedLocally() of a different plot and synchronizes the local x- and y-axis to the other x- and y-axis */
void synchronizeXYAxis ( double newxmin , double newxmax , double newymin , double newymax , JKQtPlotter * sender ) ;
/** \brief popuplate the given toolbar with all actions shown in a toolbar from this class ... */
virtual void populateToolbar ( QToolBar * toolbar ) const ;
void setMousePositionLabel ( const QString & text ) ;
2015-10-12 23:05:15 +08:00
void openContextMenu ( ) ;
void openContextMenu ( int x , int y ) ;
void openSpecialContextMenu ( ) ;
void openSpecialContextMenu ( int x , int y ) ;
2015-07-11 18:56:02 +08:00
signals :
/** \brief signal: emitted whenever the mouse moved over the plot */
void plotMouseMove ( double x , double y ) ;
/** \brief signal: emitted whenever the mouse was clicked over the plot */
void plotMouseClicked ( double x , double y , Qt : : KeyboardModifiers modifiers , Qt : : MouseButton button ) ;
/** \brief signal: emitted whenever the mouse was clicked over the plot */
void plotMouseDoubleClicked ( double x , double y , Qt : : KeyboardModifiers modifiers , Qt : : MouseButton button ) ;
/** \brief signal: emitted whenever a zoom rectangle is drawn (and it's size changes) */
void plotNewZoomRectangle ( double mouseDragRectXStart , double mouseDragRectXEnd , double mouseDragRectYStart , double mouseDragRectYEnd ) ;
/** \brief emitted when the plot scaling has been recalculated */
void plotScalingRecalculated ( ) ;
/** \brief emitted before the plot scaling has been recalculated */
void beforePlotScalingRecalculate ( ) ;
2015-10-10 18:42:55 +08:00
/** \brief emitted when a context-emnu was opened at the given position */
void contextMenuOpened ( double x , double y , QMenu * contextMenu ) ;
2015-07-11 18:56:02 +08:00
/** \brief signal: emitted whenever the user selects a new x-y zoom range (by mouse) */
void zoomChangedLocally ( double newxmin , double newxmax , double newymin , double newymax , JKQtPlotter * sender ) ;
/** \brief emitted when the user draws a rectangle */
void userClickFinished ( double x , double y , Qt : : KeyboardModifiers modifiers ) ;
/** \brief emitted when the user draws a rectangle */
void userScribbleClick ( double x , double y , Qt : : KeyboardModifiers modifiers , bool first , bool last ) ;
/** \brief emitted when the user draws a rectangle */
void userRectangleFinished ( double x , double y , double width , double height , Qt : : KeyboardModifiers modifiers ) ;
/** \brief emitted when the user draws a line */
void userLineFinished ( double x1 , double y1 , double x2 , double y2 , Qt : : KeyboardModifiers modifiers ) ;
/** \brief emitted when the user draws a circle */
void userCircleFinished ( double x , double y , double radius , Qt : : KeyboardModifiers modifiers ) ;
/** \brief emitted when the user draws an ellipse */
void userEllipseFinished ( double x , double y , double radiusX , double radiusY , Qt : : KeyboardModifiers modifiers ) ;
protected :
/** \brief you may overwrite this method to modify the given context emnu before it is displayed.
*
* The plotter will fill the menu with the default items and then call this method . The default implementation does NOTHING .
*/
virtual void modifyContextMenu ( QMenu * menu ) ;
void init ( bool datastore_internal , QWidget * parent , JKQTPdatastore * datast ) ;
MouseActionModes mouseActionMode ;
bool doDrawing ;
/** \brief JKQtPlotterBase used to plot */
JKQtBasePlotter * plotter ;
/** \brief fill color of the zoom rectangle */
2018-11-25 21:53:26 +08:00
JKQTPPROPERTY ( QColor , userActionColor )
2015-07-11 18:56:02 +08:00
/** \brief fill color of the zoom rectangle */
2018-11-25 21:53:26 +08:00
JKQTPPROPERTY ( QPainter : : CompositionMode , userActionCompositionMode )
2015-07-11 18:56:02 +08:00
/** \brief width/height of the icons in the plotter toolbar in pixels */
2018-11-25 21:53:26 +08:00
JKQTPPROPERTY ( int , toolbarIconSize )
2015-07-11 18:56:02 +08:00
/** \brief this is set \c true if we are drawing a zoom rectangle */
bool mouseDragingRectangle ;
/** \brief when zooming by moving the mouse this contains the x-coordinate the user clicked on */
double mouseDragRectXStart ;
/** \brief when zooming by moving the mouse this contains the x-coordinate the mouse is currently
* pointing to
*/
double mouseDragRectXEnd ;
/** \brief when zooming by moving the mouse this contains the y-coordinate the user clicked on */
double mouseDragRectYStart ;
/** \brief when zooming by moving the mouse this contains the y-coordinate the mouse is currently
* pointing to
*/
double mouseDragRectYEnd ;
/** \brief this stores the currently displayed plot */
QImage image ;
/** \brief this stores the currently displayed plot */
QImage imageNoOverlays ;
/** \brief this can be used when drawing a zoom rectangle to store an unchanged
* copy of the currently displayed image .
*/
QImage oldImage ;
/** \brief indicates whether zooming in by double clicking and zooming out by right-clicking is activated */
//bool zoomByDoubleAndRightMouseClick;
RightMouseButtonAction rightMouseButtonAction ;
/** \brief indicates whether zooming using the mouse-wheel is activated */
bool zoomByMouseWheel ;
2015-10-12 23:05:15 +08:00
/** \brief indicates the action to perform on a left mouse-button double-click */
LeftDoubleClickAction leftDoubleClickAction ;
QMenu * menuSpecialContextMenu ;
2015-07-11 18:56:02 +08:00
/** \brief toolbar class used for user input */
JKVanishQToolBar * toolbar ;
/** \brief paint the user action (rectangle, ellipse, ... */
void paintUserAction ( ) ;
/** \brief event handler for a double click (zoom in on time axis) */
void mouseDoubleClickEvent ( QMouseEvent * event ) ;
/*! \brief react on key presses.
These shortcuts are defined :
- ESC stops current zooming / drawing action
.
*/
void keyReleaseEvent ( QKeyEvent * event ) ;
/** \brief event handler for a mouse move
*
* This implements two behaviours :
* - If no mouse button is pressed this simply emits a plotMouseMove ( ) event which
* allows for some other widget to display the current position of the mouse inside
* the plot
* - If the left mouse button is pressed ( private property mouseZooming is \ c true )
* this displays a rectangle . If the mouse is release ( mouseReleaseEvent ( ) ) the control
* zooms the specified region . So you can use the mouse to select a range to zoom into .
* This stores the current mouse position in mouseZoomingTEnd .
* .
*/
void mouseMoveEvent ( QMouseEvent * event ) ;
/** \brief event handler for a mouse down event
*
* If the left mouse button is pressed down this starts the drawing of a zoom rectangle with
* the mouse . This method sets mouseZooming to \ c true and stores the current time in the private
* property mouseZoomingTStart . All this is only executed when the mouse is inside the coordinate
* system .
*
* If the right mouse button is clicked this zooms out of the coordinate system by a factor of two .
*/
void mousePressEvent ( QMouseEvent * event ) ;
/** \brief event handler for a mouse release event
*
* If the left mouse button is released ( and mouseZooming is \ c true ) this stops drawing a
* zoom rectangle and emits a tzoomChangedLocally ( ) event .
*/
void mouseReleaseEvent ( QMouseEvent * event ) ;
/** \brief event handler for a turn of the mouse wheel
* turning forward the mous wheel will zoom out and turning it backwards will zoom
* in by a factor of \ f $ 2 ^ { \ mbox { delta \ _wheel } } \ f $ . */
void wheelEvent ( QWheelEvent * event ) ;
/** \brief this simply paints the stored image to the widget's surface */
void paintEvent ( QPaintEvent * event ) ;
/** \brief resizes the internal representation (image) of the graphs */
void resizeEvent ( QResizeEvent * event ) ;
void leaveEvent ( QEvent * event ) ;
/** \brief specifies whether to display a toolbar with buttons when the mouse is in the upper border of the plot */
bool displayToolbar ;
/** <20> brief specifies whether the toolbar is always visible or only when the mouse moves to the upper left area */
bool toolbarAlwaysOn ;
void updateToolbar ( ) ;
/** \brief specifies whether to write the current position of the mouse in the top border of the plot (this may automatically extent the
top border , so the position fits in . The default widget font is used for the output . */
bool displayMousePosition ;
/** \brief this string is used to generate the position output above the graph */
2018-11-25 21:53:26 +08:00
JKQTPPROPERTY ( QString , mousePositionTemplate )
2015-07-11 18:56:02 +08:00
/** \brief if set \c true and displayMousePosition is \c true, the mouse position is not automaticallz determined, but the text given to setMousePositionLabel() is used */
bool displayCustomMousePosition ;
QString customMousePositiontext ;
/** \brief the master plotter, this plotter is connected to. */
QPointer < JKQtPlotter > masterPlotter ;
/** \brief calculate the y-axis shift of the plot, so there is space for the potentially displayed mouse position label */
int getPlotYOffset ( ) ;
double mousePosX ;
double mousePosY ;
double magnification ;
QSize minSize ;
QMenu * contextMenu ;
2015-10-10 18:42:55 +08:00
double mouseContextX ;
double mouseContextY ;
2015-10-12 23:05:15 +08:00
int mouseLastClickX ;
int mouseLastClickY ;
2015-07-11 18:56:02 +08:00
QList < QMenu * > contextSubMenus ;
void initContextMenu ( ) ;
void updateCursor ( ) ;
QTimer resizeTimer ;
protected slots :
void delayedResizeEvent ( ) ;
/** \brief connected to plotScalingRecalculated() of the masterPlotter */
void masterPlotScalingRecalculated ( ) ;
/** \brief called whenever the zoom changes in plotter */
void pzoomChangedLocally ( double newxmin , double newxmax , double newymin , double newymax , JKQtBasePlotter * sender ) ;
/** \brief emitted before the plot scaling has been recalculated */
void intBeforePlotScalingRecalculate ( ) ;
2018-08-20 00:17:18 +08:00
/** \brief called from a menu entry that encodes the graph ID */
void reactGraphVisible ( bool visible ) ;
2015-07-11 18:56:02 +08:00
} ;
# endif // JKQTPLOTTER_H