1 /*****************************************************************************
2 * info_widgets.cpp : Widgets for info panels
3 ****************************************************************************
4 * Copyright (C) 2013 the VideoLAN team
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
22 #include "info_widgets.hpp"
24 #include <QGridLayout>
26 #include <QGraphicsView>
27 #include <QGraphicsScene>
29 #include <QGraphicsPolygonItem>
30 #include <QGraphicsLineItem>
31 #include <QVectorIterator>
33 #define STATS_LENGTH 60
34 #define ADD_LABEL(row, color, text) \
35 label = new QLabel( QString( "<font color=\"%1\">%2</font>" ) \
36 .arg( color.name() ) \
39 layout->addWidget( label, row, 0, 1, 1, 0 );
41 VLCStatsView::VLCStatsView( QWidget
*parent
) : QGraphicsView( parent
)
43 QColor
history(0, 0, 0, 255),
44 total(237, 109, 0, 160),
45 content(109, 237, 0, 160);
47 scale( 1.0, -1.0 ); /* invert our Y axis */
48 setOptimizationFlags( QGraphicsView::DontAdjustForAntialiasing
);
49 setAlignment( Qt::AlignLeft
);
50 setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff
);
51 setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff
);
52 viewScene
= new QGraphicsScene( this );
53 historyShape
= viewScene
->addPolygon( QPolygonF(), QPen(Qt::NoPen
),
55 totalbitrateShape
= viewScene
->addPolygon( QPolygonF(), QPen(Qt::NoPen
),
57 setScene( viewScene
);
60 QPen
linepen( Qt::DotLine
);
61 linepen
.setCosmetic( true );
62 linepen
.setBrush( QBrush( QColor( 33, 33, 33 ) ) );
63 for ( int i
=0; i
<3; i
++ )
64 rulers
[i
] = viewScene
->addLine( QLineF(), linepen
);
68 void VLCStatsView::reset()
70 historymergepointer
= 0;
72 valuesaccumulator
= 0;
73 valuesaccumulatorcount
= 0;
74 historyShape
->setPolygon( QPolygonF() );
75 totalbitrateShape
->setPolygon( QPolygonF() );
78 void VLCStatsView::addValue( float value
)
82 QPolygonF shape
= totalbitrateShape
->polygon();
83 if ( shape
.count() > ( STATS_LENGTH
+ 2 ) ) /* keep only STATS_LENGTH samples */
86 for(int i
=1; i
<( STATS_LENGTH
+ 2 ); i
++)
87 ( (QPointF
&) shape
.at(i
) ).setX( i
- 1 ); /*move back values*/
90 int count
= shape
.count();
93 shape
<< QPointF( 0, 0 ); /* begin and close shape */
94 shape
<< QPointF( count
, 0 );
97 shape
.insert( shape
.end() - 1, QPointF( count
, value
) );
98 ( (QPointF
&) shape
.last() ).setX( count
);
99 totalbitrateShape
->setPolygon( shape
);
101 addHistoryValue( value
);
103 QRectF maxsizes
= scene()->itemsBoundingRect();
104 maxsizes
.setRight( STATS_LENGTH
);
105 fitInView( maxsizes
); /* fix viewport */
106 drawRulers( maxsizes
);
109 void VLCStatsView::drawRulers( const QRectF
&maxsizes
)
111 float height
= maxsizes
.height() * 1000;
113 while( height
> 1.0 ) { height
/= 10; texp
++; }
115 while( texp
-- ) height
*= 10;
116 for ( int i
=0; i
<3; i
++ )
118 float y
= ( height
/ 5 ) * ( i
+ 1 ) / 1000;
119 rulers
[i
]->setLine( QLineF( 0, y
, STATS_LENGTH
, y
) );
123 void VLCStatsView::addHistoryValue( float value
)
125 /* We keep a full history by creating virtual blocks for inserts, growing
126 by power of 2 when no more space is available. At this time, we also
127 free space by agregating the oldest values 2 by 2.
128 Each shown value finally being a mean of blocksize samples.
130 bool doinsert
= false;
131 int next_blocksize
= blocksize
;
132 QPolygonF shape
= historyShape
->polygon();
133 int count
= shape
.count();
136 shape
<< QPointF( 0, 0 ); /* begin and close shape */
137 shape
<< QPointF( count
, 0 );
140 valuesaccumulator
+= ( value
/ blocksize
);
141 valuesaccumulatorcount
++;
143 if ( valuesaccumulatorcount
== blocksize
)
145 valuesaccumulator
= 0;
146 valuesaccumulatorcount
= 0;
152 if ( count
> ( STATS_LENGTH
+ 2 ) )
155 y
+= ((QPointF
&) shape
.at( historymergepointer
+ 1 )).y();
156 y
+= ((QPointF
&) shape
.at( historymergepointer
+ 2 )).y();
160 shape
.remove( historymergepointer
+ 2 );
161 ( (QPointF
&) shape
.at( historymergepointer
+ 1 ) ).setY( y
);
162 for(int i
=historymergepointer
+1; i
<( STATS_LENGTH
+ 2 ); i
++)
163 ( (QPointF
&) shape
.at(i
) ).setX( i
- 1 ); /*move back values*/
164 historymergepointer
++;
165 if ( historymergepointer
> ( STATS_LENGTH
- 1 ) )
167 historymergepointer
= 0;
168 next_blocksize
= ( blocksize
<< 1 );
172 shape
.insert( shape
.end() - 1, QPointF( count
, value
) );
173 ( (QPointF
&) shape
.last() ).setX( count
);
176 ( (QPointF
&) shape
.last() ).setX( count
- 1 );
178 historyShape
->setPolygon( shape
);
180 blocksize
= next_blocksize
;