Show files in tooltips for pieces progress bars

In addition to the current tooltip, which shows color legend, if user
holds the Shift key during hovering we show another tooltip which
contains a table of contents for the piece under the moue cursor. The
table lists file sizes and names. If the cursor points to a part of a
file which spans several pieces, those pieces are highlighted.
This commit is contained in:
Eugene Shalygin
2016-02-29 00:44:08 +01:00
parent f9c2bd3502
commit b3378d4599
14 changed files with 756 additions and 237 deletions

View File

@@ -28,20 +28,16 @@
* Contact : chris@qbittorrent.org
*/
#include <cmath>
#include <QDebug>
#include "downloadedpiecesbar.h"
DownloadedPiecesBar::DownloadedPiecesBar(QWidget *parent) : QWidget(parent)
#include <cmath>
#include <QDebug>
DownloadedPiecesBar::DownloadedPiecesBar(QWidget *parent)
: base {parent}
, m_dlPieceColor {0, 0xd0, 0}
{
setToolTip(QString("%1\n%2\n%3").arg(tr("White: Missing pieces")).arg(tr("Green: Partial pieces")).arg(tr("Blue: Completed pieces")));
m_bgColor = 0xffffff;
m_borderColor = palette().color(QPalette::Dark).rgb();
m_pieceColor = 0x0000ff;
m_dlPieceColor = 0x00d000;
updatePieceColors();
}
QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin, int reqSize)
@@ -49,7 +45,7 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
QVector<float> result(reqSize, 0.0);
if (vecin.isEmpty()) return result;
const float ratio = vecin.size() / (float)reqSize;
const float ratio = vecin.size() / static_cast<float>(reqSize);
// simple linear transformation algorithm
// for example:
@@ -62,7 +58,7 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
const float toR = (x + 1) * ratio;
// C - integer
int fromC = fromR;// std::floor not needed
int fromC = fromR; // std::floor not needed
int toC = std::ceil(toR);
if (toC > vecin.size())
--toC;
@@ -108,7 +104,7 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
value /= ratio;
// float precision sometimes gives > 1, because in not possible to store irrational numbers
value = qMin(value, (float)1.0);
value = qMin(value, 1.0f);
result[x] = value;
}
@@ -116,38 +112,19 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
return result;
}
int DownloadedPiecesBar::mixTwoColors(int &rgb1, int &rgb2, float ratio)
{
int r1 = qRed(rgb1);
int g1 = qGreen(rgb1);
int b1 = qBlue(rgb1);
int r2 = qRed(rgb2);
int g2 = qGreen(rgb2);
int b2 = qBlue(rgb2);
float ratio_n = 1.0 - ratio;
int r = (r1 * ratio_n) + (r2 * ratio);
int g = (g1 * ratio_n) + (g2 * ratio);
int b = (b1 * ratio_n) + (b2 * ratio);
return qRgb(r, g, b);
}
void DownloadedPiecesBar::updateImage()
bool DownloadedPiecesBar::updateImage(QImage &image)
{
// qDebug() << "updateImage";
QImage image2(width() - 2, 1, QImage::Format_RGB888);
QImage image2(width() - 2 * borderWidth, 1, QImage::Format_RGB888);
if (image2.isNull()) {
qDebug() << "QImage image2() allocation failed, width():" << width();
return;
return false;
}
if (m_pieces.isEmpty()) {
image2.fill(0xffffff);
m_image = image2;
update();
return;
image2.fill(Qt::white);
image = image2;
return true;
}
QVector<float> scaled_pieces = bitfieldToFloatVector(m_pieces, image2.width());
@@ -161,16 +138,17 @@ void DownloadedPiecesBar::updateImage()
float fill_ratio = pieces2_val + pieces2_val_dl;
float ratio = pieces2_val_dl / fill_ratio;
int mixedColor = mixTwoColors(m_pieceColor, m_dlPieceColor, ratio);
mixedColor = mixTwoColors(m_bgColor, mixedColor, fill_ratio);
QRgb mixedColor = mixTwoColors(pieceColor().rgb(), m_dlPieceColor.rgb(), ratio);
mixedColor = mixTwoColors(backgroundColor().rgb(), mixedColor, fill_ratio);
image2.setPixel(x, 0, mixedColor);
}
else {
image2.setPixel(x, 0, m_pieceColors[pieces2_val * 255]);
image2.setPixel(x, 0, pieceColors()[pieces2_val * 255]);
}
}
m_image = image2;
image = image2;
return true;
}
void DownloadedPiecesBar::setProgress(const QBitArray &pieces, const QBitArray &downloadedPieces)
@@ -178,53 +156,25 @@ void DownloadedPiecesBar::setProgress(const QBitArray &pieces, const QBitArray &
m_pieces = pieces;
m_downloadedPieces = downloadedPieces;
updateImage();
update();
requestImageUpdate();
}
void DownloadedPiecesBar::updatePieceColors()
void DownloadedPiecesBar::setColors(const QColor &background, const QColor &border, const QColor &complete, const QColor &incomplete)
{
m_pieceColors = QVector<int>(256);
for (int i = 0; i < 256; ++i) {
float ratio = (i / 255.0);
m_pieceColors[i] = mixTwoColors(m_bgColor, m_pieceColor, ratio);
}
m_dlPieceColor = incomplete;
base::setColors(background, border, complete);
}
void DownloadedPiecesBar::clear()
{
m_image = QImage();
update();
m_pieces.clear();
m_downloadedPieces.clear();
base::clear();
}
void DownloadedPiecesBar::paintEvent(QPaintEvent*)
QString DownloadedPiecesBar::simpleToolTipText() const
{
QPainter painter(this);
QRect imageRect(1, 1, width() - 2, height() - 2);
if (m_image.isNull()) {
painter.setBrush(Qt::white);
painter.drawRect(imageRect);
}
else {
if (m_image.width() != imageRect.width())
updateImage();
painter.drawImage(imageRect, m_image);
}
QPainterPath border;
border.addRect(0, 0, width() - 1, height() - 1);
painter.setPen(m_borderColor);
painter.drawPath(border);
}
void DownloadedPiecesBar::setColors(int background, int border, int complete, int incomplete)
{
m_bgColor = background;
m_borderColor = border;
m_pieceColor = complete;
m_dlPieceColor = incomplete;
updatePieceColors();
updateImage();
update();
return tr("White: Missing pieces") + '\n'
+ tr("Green: Partial pieces") + '\n'
+ tr("Blue: Completed pieces") + '\n';
}