@ -2,7 +2,6 @@
# include <QGraphicsLayout>
# include <QLabel>
# include <QPushButton>
# include <QRubberBand>
# include <QStackedLayout>
# include <QtCharts/QLineSeries>
@ -27,29 +26,104 @@ int64_t get_raw_value(uint8_t *data, size_t data_size, const Signal &sig) {
return ret ;
}
// ChartsWidget
ChartsWidget : : ChartsWidget ( QWidget * parent ) : QWidget ( parent ) {
main_layout = new QVBoxLayout ( this ) ;
QVBoxLayout * main_layout = new QVBoxLayout ( this ) ;
main_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
connect ( parser , & Parser : : showPlot , this , & ChartsWidget : : addChart ) ;
connect ( parser , & Parser : : hidePlot , this , & ChartsWidget : : removeChart ) ;
connect ( parser , & Parser : : signalRemoved , this , & ChartsWidget : : removeChart ) ;
// title bar
title_bar = new QWidget ( this ) ;
QHBoxLayout * title_layout = new QHBoxLayout ( title_bar ) ;
title_label = new QLabel ( tr ( " Charts " ) ) ;
title_layout - > addWidget ( title_label ) ;
title_layout - > addStretch ( ) ;
reset_zoom_btn = new QPushButton ( " ⟲ " , this ) ;
reset_zoom_btn - > setVisible ( false ) ;
reset_zoom_btn - > setFixedSize ( 30 , 30 ) ;
reset_zoom_btn - > setToolTip ( tr ( " Reset zoom (drag on chart to zoom X-Axis) " ) ) ;
title_layout - > addWidget ( reset_zoom_btn ) ;
remove_all_btn = new QPushButton ( tr ( " ✖ " ) ) ;
remove_all_btn - > setVisible ( false ) ;
remove_all_btn - > setToolTip ( tr ( " Remove all charts " ) ) ;
remove_all_btn - > setFixedSize ( 30 , 30 ) ;
title_layout - > addWidget ( remove_all_btn ) ;
dock_btn = new QPushButton ( ) ;
dock_btn - > setFixedSize ( 30 , 30 ) ;
updateDockButton ( ) ;
title_layout - > addWidget ( dock_btn ) ;
main_layout - > addWidget ( title_bar , 0 , Qt : : AlignTop ) ;
// charts
QWidget * charts_container = new QWidget ( this ) ;
QVBoxLayout * charts_main = new QVBoxLayout ( charts_container ) ;
charts_layout = new QVBoxLayout ( ) ;
charts_main - > addLayout ( charts_layout ) ;
charts_main - > addStretch ( ) ;
QScrollArea * charts_scroll = new QScrollArea ( this ) ;
charts_scroll - > setWidgetResizable ( true ) ;
charts_scroll - > setWidget ( charts_container ) ;
charts_scroll - > setFrameShape ( QFrame : : NoFrame ) ;
charts_scroll - > setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
main_layout - > addWidget ( charts_scroll ) ;
QObject : : connect ( parser , & Parser : : showPlot , this , & ChartsWidget : : addChart ) ;
QObject : : connect ( parser , & Parser : : hidePlot , this , & ChartsWidget : : removeChart ) ;
QObject : : connect ( parser , & Parser : : signalRemoved , this , & ChartsWidget : : removeChart ) ;
QObject : : connect ( reset_zoom_btn , & QPushButton : : clicked , parser , & Parser : : resetRange ) ;
QObject : : connect ( remove_all_btn , & QPushButton : : clicked , this , & ChartsWidget : : removeAll ) ;
QObject : : connect ( dock_btn , & QPushButton : : clicked , [ = ] ( ) {
emit dock ( ! docking ) ;
docking = ! docking ;
updateDockButton ( ) ;
} ) ;
}
void ChartsWidget : : updateDockButton ( ) {
dock_btn - > setText ( docking ? " ⬈ " : " ⬋ " ) ;
dock_btn - > setToolTip ( docking ? tr ( " Undock charts " ) : tr ( " Dock charts " ) ) ;
}
void ChartsWidget : : addChart ( const QString & id , const QString & sig_name ) {
const QString char_name = id + sig_name ;
if ( charts . find ( char_name ) = = charts . end ( ) ) {
auto chart = new ChartWidget ( id , sig_name , this ) ;
main_layout - > insertWidget ( 0 , chart ) ;
charts _layout- > insertWidget ( 0 , chart ) ;
charts [ char_name ] = chart ;
}
remove_all_btn - > setVisible ( true ) ;
reset_zoom_btn - > setVisible ( true ) ;
title_label - > setText ( tr ( " Charts (%1) " ) . arg ( charts . size ( ) ) ) ;
}
void ChartsWidget : : removeChart ( const QString & id , const QString & sig_name ) {
if ( auto it = charts . find ( id + sig_name ) ; it ! = charts . end ( ) ) {
it - > second - > deleteLater ( ) ;
charts . erase ( it ) ;
if ( charts . empty ( ) ) {
remove_all_btn - > setVisible ( false ) ;
reset_zoom_btn - > setVisible ( false ) ;
}
}
title_label - > setText ( tr ( " Charts (%1) " ) . arg ( charts . size ( ) ) ) ;
}
void ChartsWidget : : removeAll ( ) {
for ( auto [ _ , chart ] : charts )
chart - > deleteLater ( ) ;
charts . clear ( ) ;
remove_all_btn - > setVisible ( false ) ;
reset_zoom_btn - > setVisible ( false ) ;
}
// ChartWidget
ChartWidget : : ChartWidget ( const QString & id , const QString & sig_name , QWidget * parent ) : id ( id ) , sig_name ( sig_name ) , QWidget ( parent ) {
QStackedLayout * stacked = new QStackedLayout ( this ) ;
@ -64,17 +138,13 @@ ChartWidget::ChartWidget(const QString &id, const QString &sig_name, QWidget *pa
header - > setStyleSheet ( " background-color:white " ) ;
QHBoxLayout * header_layout = new QHBoxLayout ( header ) ;
header_layout - > setContentsMargins ( 11 , 11 , 11 , 0 ) ;
auto title = new QLabel ( tr ( " %1 %2 " ) . arg ( parser - > getMsg ( id ) - > name . c_str ( ) ) . arg ( id ) ) ;
QLabel * title = new QLabel ( tr ( " %1 %2 " ) . arg ( parser - > getMsg ( id ) - > name . c_str ( ) ) . arg ( id ) ) ;
header_layout - > addWidget ( title ) ;
header_layout - > addStretch ( ) ;
zoom_label = new QLabel ( " " , this ) ;
header_layout - > addWidget ( zoom_label ) ;
QPushButton * zoom_in = new QPushButton ( " ↺ " , this ) ;
zoom_in - > setToolTip ( tr ( " reset zoom " ) ) ;
QObject : : connect ( zoom_in , & QPushButton : : clicked , [ ] ( ) { parser - > resetRange ( ) ; } ) ;
header_layout - > addWidget ( zoom_in ) ;
QPushButton * remove_btn = new QPushButton ( " ✖ " , this ) ;
remove_btn - > setFixedSize ( 30 , 30 ) ;
remove_btn - > setToolTip ( tr ( " Remove chart " ) ) ;
QObject : : connect ( remove_btn , & QPushButton : : clicked , [ = ] ( ) {
emit parser - > hidePlot ( id , sig_name ) ;
} ) ;
@ -108,7 +178,7 @@ ChartWidget::ChartWidget(const QString &id, const QString &sig_name, QWidget *pa
chart_layout - > addStretch ( ) ;
stacked - > addWidget ( chart_widget ) ;
line_marker = new LineMarker ( chart , this ) ;
line_marker = new LineMarker ( this ) ;
stacked - > addWidget ( line_marker ) ;
line_marker - > setAttribute ( Qt : : WA_TransparentForMouseEvents , true ) ;
line_marker - > raise ( ) ;
@ -122,7 +192,15 @@ ChartWidget::ChartWidget(const QString &id, const QString &sig_name, QWidget *pa
}
void ChartWidget : : updateState ( ) {
line_marker - > update ( ) ;
auto chart = chart_view - > chart ( ) ;
auto axis_x = dynamic_cast < QValueAxis * > ( chart - > axisX ( ) ) ;
if ( axis_x - > max ( ) < = axis_x - > min ( ) ) return ;
int x = chart - > plotArea ( ) . left ( ) + chart - > plotArea ( ) . width ( ) * ( parser - > currentSec ( ) - axis_x - > min ( ) ) / ( axis_x - > max ( ) - axis_x - > min ( ) ) ;
if ( line_marker_x ! = x ) {
line_marker - > setX ( x ) ;
line_marker_x = x ;
}
}
void ChartWidget : : updateSeries ( ) {
@ -182,16 +260,15 @@ void ChartWidget::rangeChanged(qreal min, qreal max) {
chart_view - > chart ( ) - > axisY ( ) - > setRange ( min_y * 0.95 , max_y * 1.05 ) ;
}
LineMarker : : LineMarker ( QChart * chart , QWidget * parent ) : chart ( chart ) , QWidget ( parent ) { }
// LineMarker
void LineMarker : : paintEvent ( QPaintEvent * event ) {
auto axis_x = dynamic_cast < QValueAxis * > ( chart - > axisX ( ) ) ;
if ( axis_x - > max ( ) < = axis_x - > min ( ) ) return ;
void LineMarker : : setX ( double x ) {
x_pos = x ;
update ( ) ;
}
double x = chart - > plotArea ( ) . left ( ) + chart - > plotArea ( ) . width ( ) * ( parser - > currentSec ( ) - axis_x - > min ( ) ) / ( axis_x - > max ( ) - axis_x - > min ( ) ) ;
void LineMarker : : paintEvent ( QPaintEvent * event ) {
QPainter p ( this ) ;
QPen pen = QPen ( Qt : : black ) ;
pen . setWidth ( 2 ) ;
p . setPen ( pen ) ;
p . drawLine ( QPointF { x , 50. } , QPointF { x , ( qreal ) height ( ) - 11 } ) ;
p . setPen ( QPen ( Qt : : black , 2 ) ) ;
p . drawLine ( QPointF { x_pos , 50. } , QPointF { x_pos , ( qreal ) height ( ) - 11 } ) ;
}