Code clean up

This commit is contained in:
Christophe Dumez 2011-09-24 17:28:25 +03:00
commit 28ba0c25a7
4 changed files with 341 additions and 340 deletions

View file

@ -34,215 +34,215 @@
DownloadedPiecesBar::DownloadedPiecesBar(QWidget *parent): QWidget(parent) DownloadedPiecesBar::DownloadedPiecesBar(QWidget *parent): QWidget(parent)
{ {
setFixedHeight(BAR_HEIGHT); setFixedHeight(BAR_HEIGHT);
bg_color = 0xffffff; bg_color = 0xffffff;
border_color = palette().color(QPalette::Dark).rgb(); border_color = palette().color(QPalette::Dark).rgb();
piece_color = 0x0000ff; piece_color = 0x0000ff;
piece_color_dl = 0x00d000; piece_color_dl = 0x00d000;
updatePieceColors(); updatePieceColors();
} }
std::vector<float> DownloadedPiecesBar::bitfieldToFloatVector(const libtorrent::bitfield &vecin, int reqSize) std::vector<float> DownloadedPiecesBar::bitfieldToFloatVector(const libtorrent::bitfield &vecin, int reqSize)
{ {
std::vector<float> result(reqSize, 0.0); std::vector<float> result(reqSize, 0.0);
if (vecin.size() == 0) if (vecin.empty())
return result; return result;
const float ratio = vecin.size() / (float)reqSize; const float ratio = vecin.size() / (float)reqSize;
// simple linear transformation algorithm // simple linear transformation algorithm
// for example: // for example:
// image.x(0) = pieces.x(0.0 >= x < 1.7) // image.x(0) = pieces.x(0.0 >= x < 1.7)
// image.x(1) = pieces.x(1.7 >= x < 3.4) // image.x(1) = pieces.x(1.7 >= x < 3.4)
for (int x = 0; x < reqSize; ++x) { for (int x = 0; x < reqSize; ++x) {
// don't use previously calculated value "ratio" here!!! // don't use previously calculated value "ratio" here!!!
// float cannot save irrational number like 7/9, if this number will be rounded up by std::ceil // float cannot save irrational number like 7/9, if this number will be rounded up by std::ceil
// give you x2 == pieces.size(), and index out of range: pieces[x2] // give you x2 == pieces.size(), and index out of range: pieces[x2]
// this code is safe, so keep that in mind when you try optimize more. // this code is safe, so keep that in mind when you try optimize more.
// tested with size = 3000000ul // tested with size = 3000000ul
// R - real // R - real
const float fromR = (x * vecin.size()) / (float)reqSize; const float fromR = (x * vecin.size()) / (float)reqSize;
const float toR = ((x + 1) * vecin.size()) / (float)reqSize; const float toR = ((x + 1) * vecin.size()) / (float)reqSize;
// C - integer // C - integer
int fromC = fromR;// std::floor not needed int fromC = fromR;// std::floor not needed
int toC = std::ceil(toR); int toC = std::ceil(toR);
// position in pieces table // position in pieces table
// libtorrent::bitfield::m_size is unsigned int(31 bits), so qlonglong is not needed // libtorrent::bitfield::m_size is unsigned int(31 bits), so qlonglong is not needed
// tested with size = 3000000ul // tested with size = 3000000ul
int x2 = fromC; int x2 = fromC;
// little speed up for really big pieces table, 10K+ size // little speed up for really big pieces table, 10K+ size
const int toCMinusOne = toC - 1; const int toCMinusOne = toC - 1;
// value in returned vector // value in returned vector
float value = 0; float value = 0;
// case when calculated range is (15.2 >= x < 15.7) // case when calculated range is (15.2 >= x < 15.7)
if (x2 == toCMinusOne) { if (x2 == toCMinusOne) {
if (vecin[x2]) { if (vecin[x2]) {
value += toR - fromR; value += toR - fromR;
} }
++x2; ++x2;
} }
// case when (15.2 >= x < 17.8) // case when (15.2 >= x < 17.8)
else { else {
// subcase (15.2 >= x < 16) // subcase (15.2 >= x < 16)
if (x2 != fromR) { if (x2 != fromR) {
if (vecin[x2]) { if (vecin[x2]) {
value += 1.0 - (fromR - fromC); value += 1.0 - (fromR - fromC);
} }
++x2; ++x2;
} }
// subcase (16 >= x < 17) // subcase (16 >= x < 17)
for (; x2 < toCMinusOne; ++x2) { for (; x2 < toCMinusOne; ++x2) {
if (vecin[x2]) { if (vecin[x2]) {
value += 1.0; value += 1.0;
} }
} }
// subcase (17 >= x < 17.8) // subcase (17 >= x < 17.8)
if (x2 == toCMinusOne) { if (x2 == toCMinusOne) {
if (vecin[x2]) { if (vecin[x2]) {
value += 1.0 - (toC - toR); value += 1.0 - (toC - toR);
} }
++x2; ++x2;
} }
} }
// normalization <0, 1> // normalization <0, 1>
value /= ratio; value /= ratio;
// float precision sometimes gives > 1, bacause in not possible to store irrational numbers // float precision sometimes gives > 1, because in not possible to store irrational numbers
value = qMin(value, (float)1.0); value = qMin(value, (float)1.0);
result[x] = value; result[x] = value;
} }
return result; return result;
} }
int DownloadedPiecesBar::mixTwoColors(int &rgb1, int &rgb2, float ratio) int DownloadedPiecesBar::mixTwoColors(int &rgb1, int &rgb2, float ratio)
{ {
int r1 = qRed(rgb1); int r1 = qRed(rgb1);
int g1 = qGreen(rgb1); int g1 = qGreen(rgb1);
int b1 = qBlue(rgb1); int b1 = qBlue(rgb1);
int r2 = qRed(rgb2); int r2 = qRed(rgb2);
int g2 = qGreen(rgb2); int g2 = qGreen(rgb2);
int b2 = qBlue(rgb2); int b2 = qBlue(rgb2);
float ratio_n = 1.0 - ratio; float ratio_n = 1.0 - ratio;
int r = (r1 * ratio_n) + (r2 * ratio); int r = (r1 * ratio_n) + (r2 * ratio);
int g = (g1 * ratio_n) + (g2 * ratio); int g = (g1 * ratio_n) + (g2 * ratio);
int b = (b1 * ratio_n) + (b2 * ratio); int b = (b1 * ratio_n) + (b2 * ratio);
return qRgb(r, g, b); return qRgb(r, g, b);
} }
void DownloadedPiecesBar::updateImage() void DownloadedPiecesBar::updateImage()
{ {
// qDebug() << "updateImage"; // qDebug() << "updateImage";
QImage image2(width() - 2, 1, QImage::Format_RGB888); QImage image2(width() - 2, 1, QImage::Format_RGB888);
if (pieces.empty()) { if (pieces.empty()) {
image2.fill(0xffffff); image2.fill(0xffffff);
image = image2; image = image2;
update(); update();
return; return;
} }
std::vector<float> scaled_pieces = bitfieldToFloatVector(pieces, image2.width()); std::vector<float> scaled_pieces = bitfieldToFloatVector(pieces, image2.width());
std::vector<float> scaled_pieces_dl = bitfieldToFloatVector(pieces_dl, image2.width()); std::vector<float> scaled_pieces_dl = bitfieldToFloatVector(pieces_dl, image2.width());
// filling image // filling image
for (unsigned int x = 0; x < scaled_pieces.size(); ++x) for (unsigned int x = 0; x < scaled_pieces.size(); ++x)
{ {
float pieces2_val = scaled_pieces.at(x); float pieces2_val = scaled_pieces.at(x);
float pieces2_val_dl = scaled_pieces_dl.at(x); float pieces2_val_dl = scaled_pieces_dl.at(x);
if (pieces2_val_dl != 0) if (pieces2_val_dl != 0)
{ {
float fill_ratio = pieces2_val + pieces2_val_dl; float fill_ratio = pieces2_val + pieces2_val_dl;
float ratio = pieces2_val_dl / fill_ratio; float ratio = pieces2_val_dl / fill_ratio;
int mixedColor = mixTwoColors(piece_color, piece_color_dl, ratio); int mixedColor = mixTwoColors(piece_color, piece_color_dl, ratio);
mixedColor = mixTwoColors(bg_color, mixedColor, fill_ratio); mixedColor = mixTwoColors(bg_color, mixedColor, fill_ratio);
image2.setPixel(x, 0, mixedColor); image2.setPixel(x, 0, mixedColor);
} }
else else
{ {
image2.setPixel(x, 0, piece_colors[pieces2_val * 255]); image2.setPixel(x, 0, piece_colors[pieces2_val * 255]);
} }
} }
image = image2; image = image2;
} }
void DownloadedPiecesBar::setProgress(const libtorrent::bitfield &bf, const libtorrent::bitfield &bf_dl) void DownloadedPiecesBar::setProgress(const libtorrent::bitfield &bf, const libtorrent::bitfield &bf_dl)
{ {
pieces = libtorrent::bitfield(bf); pieces = libtorrent::bitfield(bf);
pieces_dl = libtorrent::bitfield(bf_dl); pieces_dl = libtorrent::bitfield(bf_dl);
updateImage(); updateImage();
update(); update();
} }
void DownloadedPiecesBar::updatePieceColors() void DownloadedPiecesBar::updatePieceColors()
{ {
piece_colors = std::vector<int>(256); piece_colors = std::vector<int>(256);
for (int i = 0; i < 256; ++i) { for (int i = 0; i < 256; ++i) {
float ratio = (i / 255.0); float ratio = (i / 255.0);
piece_colors[i] = mixTwoColors(bg_color, piece_color, ratio); piece_colors[i] = mixTwoColors(bg_color, piece_color, ratio);
} }
} }
void DownloadedPiecesBar::clear() void DownloadedPiecesBar::clear()
{ {
image = QImage(); image = QImage();
update(); update();
} }
void DownloadedPiecesBar::paintEvent(QPaintEvent *) void DownloadedPiecesBar::paintEvent(QPaintEvent *)
{ {
QPainter painter(this); QPainter painter(this);
QRect imageRect(1, 1, width() - 2, height() - 2); QRect imageRect(1, 1, width() - 2, height() - 2);
if (image.isNull()) if (image.isNull())
{ {
painter.setBrush(Qt::white); painter.setBrush(Qt::white);
painter.drawRect(imageRect); painter.drawRect(imageRect);
} }
else else
{ {
if (image.width() != imageRect.width()) if (image.width() != imageRect.width())
updateImage(); updateImage();
painter.drawImage(imageRect, image); painter.drawImage(imageRect, image);
} }
QPainterPath border; QPainterPath border;
border.addRect(0, 0, width() - 1, height() - 1); border.addRect(0, 0, width() - 1, height() - 1);
painter.setPen(border_color); painter.setPen(border_color);
painter.drawPath(border); painter.drawPath(border);
} }
void DownloadedPiecesBar::setColors(int background, int border, int complete, int incomplete) void DownloadedPiecesBar::setColors(int background, int border, int complete, int incomplete)
{ {
bg_color = background; bg_color = background;
border_color = border; border_color = border;
piece_color = complete; piece_color = complete;
piece_color_dl = incomplete; piece_color_dl = incomplete;
updatePieceColors(); updatePieceColors();
updateImage(); updateImage();
update(); update();
} }

View file

@ -40,48 +40,48 @@
#define BAR_HEIGHT 18 #define BAR_HEIGHT 18
class DownloadedPiecesBar: public QWidget { class DownloadedPiecesBar: public QWidget {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(DownloadedPiecesBar) Q_DISABLE_COPY(DownloadedPiecesBar)
private: private:
QImage image; QImage image;
// I used values, bacause it should be possible to change colors in runtime // I used values, bacause it should be possible to change colors in runtime
// background color // background color
int bg_color; int bg_color;
// border color // border color
int border_color; int border_color;
// complete piece color // complete piece color
int piece_color; int piece_color;
// incomplete piece color // incomplete piece color
int piece_color_dl; int piece_color_dl;
// buffered 256 levels gradient from bg_color to piece_color // buffered 256 levels gradient from bg_color to piece_color
std::vector<int> piece_colors; std::vector<int> piece_colors;
// last used bitfields, uses to better resize redraw // last used bitfields, uses to better resize redraw
// TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster // TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster
libtorrent::bitfield pieces; libtorrent::bitfield pieces;
libtorrent::bitfield pieces_dl; libtorrent::bitfield pieces_dl;
// scale bitfield vector to float vector // scale bitfield vector to float vector
std::vector<float> bitfieldToFloatVector(const libtorrent::bitfield &vecin, int reqSize); std::vector<float> bitfieldToFloatVector(const libtorrent::bitfield &vecin, int reqSize);
// mix two colors by light model, ratio <0, 1> // mix two colors by light model, ratio <0, 1>
int mixTwoColors(int &rgb1, int &rgb2, float ratio); int mixTwoColors(int &rgb1, int &rgb2, float ratio);
// draw new image and replace actual image // draw new image and replace actual image
void updateImage(); void updateImage();
public: public:
DownloadedPiecesBar(QWidget *parent); DownloadedPiecesBar(QWidget *parent);
void setProgress(const libtorrent::bitfield &bf, const libtorrent::bitfield &bf_dl); void setProgress(const libtorrent::bitfield &bf, const libtorrent::bitfield &bf_dl);
void updatePieceColors(); void updatePieceColors();
void clear(); void clear();
void setColors(int background, int border, int complete, int incomplete); void setColors(int background, int border, int complete, int incomplete);
protected: protected:
void paintEvent(QPaintEvent *); void paintEvent(QPaintEvent *);
}; };
#endif // DOWNLOADEDPIECESBAR_H #endif // DOWNLOADEDPIECESBAR_H

View file

@ -33,205 +33,206 @@
//#include <QDebug> //#include <QDebug>
PieceAvailabilityBar::PieceAvailabilityBar(QWidget *parent) : PieceAvailabilityBar::PieceAvailabilityBar(QWidget *parent) :
QWidget(parent) QWidget(parent)
{ {
setFixedHeight(BAR_HEIGHT); setFixedHeight(BAR_HEIGHT);
bg_color = 0xffffff; bg_color = 0xffffff;
border_color = palette().color(QPalette::Dark).rgb(); border_color = palette().color(QPalette::Dark).rgb();
piece_color = 0x0000ff; piece_color = 0x0000ff;
updatePieceColors(); updatePieceColors();
} }
std::vector<float> PieceAvailabilityBar::intToFloatVector(const std::vector<int> &vecin, int reqSize) std::vector<float> PieceAvailabilityBar::intToFloatVector(const std::vector<int> &vecin, int reqSize)
{ {
std::vector<float> result(reqSize, 0.0); std::vector<float> result(reqSize, 0.0);
if (vecin.size() == 0) if (vecin.empty())
return result; return result;
const float ratio = vecin.size() / (float)reqSize; const float ratio = vecin.size() / (float)reqSize;
const int maxElement = *std::max_element(vecin.begin(), vecin.end()); const int maxElement = *std::max_element(vecin.begin(), vecin.end());
// qMax bacause in normalization we don't want divide by 0 // qMax bacause in normalization we don't want divide by 0
// if maxElement == 0 check will be disabled please enable this line: // if maxElement == 0 check will be disabled please enable this line:
// const int maxElement = qMax(*std::max_element(avail.begin(), avail.end()), 1); // const int maxElement = qMax(*std::max_element(avail.begin(), avail.end()), 1);
if (maxElement == 0) if (maxElement == 0)
return result; return result;
// simple linear transformation algorithm // simple linear transformation algorithm
// for example: // for example:
// image.x(0) = pieces.x(0.0 >= x < 1.7) // image.x(0) = pieces.x(0.0 >= x < 1.7)
// image.x(1) = pieces.x(1.7 >= x < 3.4) // image.x(1) = pieces.x(1.7 >= x < 3.4)
for (int x = 0; x < reqSize; ++x) { for (int x = 0; x < reqSize; ++x) {
// don't use previously calculated value "ratio" here!!! // don't use previously calculated value "ratio" here!!!
// float cannot save irrational number like 7/9, if this number will be rounded up by std::ceil // float cannot save irrational number like 7/9, if this number will be rounded up by std::ceil
// give you x2 == pieces.size(), and index out of range: pieces[x2] // give you x2 == pieces.size(), and index out of range: pieces[x2]
// this code is safe, so keep that in mind when you try optimize more. // this code is safe, so keep that in mind when you try optimize more.
// tested with size = 3000000ul // tested with size = 3000000ul
// R - real // R - real
const float fromR = (x * vecin.size()) / (float)reqSize; const float fromR = (x * vecin.size()) / (float)reqSize;
const float toR = ((x + 1) * vecin.size()) / (float)reqSize; const float toR = ((x + 1) * vecin.size()) / (float)reqSize;
// C - integer // C - integer
int fromC = fromR;// std::floor not needed int fromC = fromR;// std::floor not needed
int toC = std::ceil(toR); int toC = std::ceil(toR);
// position in pieces table // position in pieces table
// libtorrent::bitfield::m_size is unsigned int(31 bits), so qlonglong is not needed // libtorrent::bitfield::m_size is unsigned int(31 bits), so qlonglong is not needed
// tested with size = 3000000ul // tested with size = 3000000ul
int x2 = fromC; int x2 = fromC;
// little speed up for really big pieces table, 10K+ size // little speed up for really big pieces table, 10K+ size
const int toCMinusOne = toC - 1; const int toCMinusOne = toC - 1;
// value in returned vector // value in returned vector
float value = 0; float value = 0;
// case when calculated range is (15.2 >= x < 15.7) // case when calculated range is (15.2 >= x < 15.7)
if (x2 == toCMinusOne) { if (x2 == toCMinusOne) {
if (vecin[x2]) { if (vecin[x2]) {
value += (toR - fromR) * vecin[x2]; value += (toR - fromR) * vecin[x2];
} }
++x2; ++x2;
} }
// case when (15.2 >= x < 17.8) // case when (15.2 >= x < 17.8)
else { else {
// subcase (15.2 >= x < 16) // subcase (15.2 >= x < 16)
if (x2 != fromR) { if (x2 != fromR) {
if (vecin[x2]) { if (vecin[x2]) {
value += (1.0 - (fromR - fromC)) * vecin[x2]; value += (1.0 - (fromR - fromC)) * vecin[x2];
} }
++x2; ++x2;
} }
// subcase (16 >= x < 17) // subcase (16 >= x < 17)
for (; x2 < toCMinusOne; ++x2) { for (; x2 < toCMinusOne; ++x2) {
if (vecin[x2]) { if (vecin[x2]) {
value += vecin[x2]; value += vecin[x2];
} }
} }
// subcase (17 >= x < 17.8) // subcase (17 >= x < 17.8)
if (x2 == toCMinusOne) { if (x2 == toCMinusOne) {
if (vecin[x2]) { if (vecin[x2]) {
value += (1.0 - (toC - toR)) * vecin[x2]; value += (1.0 - (toC - toR)) * vecin[x2];
} }
++x2; ++x2;
} }
} }
// normalization <0, 1> // normalization <0, 1>
value /= ratio * maxElement; value /= ratio * maxElement;
// float precision sometimes gives > 1, bacause in not possible to store irrational numbers // float precision sometimes gives > 1, because in not possible to store irrational numbers
value = qMin(value, (float)1.0); value = qMin(value, (float)1.0);
result[x] = value; result[x] = value;
} }
return result; return result;
} }
int PieceAvailabilityBar::mixTwoColors(int &rgb1, int &rgb2, float ratio) int PieceAvailabilityBar::mixTwoColors(int &rgb1, int &rgb2, float ratio)
{ {
int r1 = qRed(rgb1); int r1 = qRed(rgb1);
int g1 = qGreen(rgb1); int g1 = qGreen(rgb1);
int b1 = qBlue(rgb1); int b1 = qBlue(rgb1);
int r2 = qRed(rgb2); int r2 = qRed(rgb2);
int g2 = qGreen(rgb2); int g2 = qGreen(rgb2);
int b2 = qBlue(rgb2); int b2 = qBlue(rgb2);
float ratio_n = 1.0 - ratio; float ratio_n = 1.0 - ratio;
int r = (r1 * ratio_n) + (r2 * ratio); int r = (r1 * ratio_n) + (r2 * ratio);
int g = (g1 * ratio_n) + (g2 * ratio); int g = (g1 * ratio_n) + (g2 * ratio);
int b = (b1 * ratio_n) + (b2 * ratio); int b = (b1 * ratio_n) + (b2 * ratio);
return qRgb(r, g, b); return qRgb(r, g, b);
} }
void PieceAvailabilityBar::updateImage() void PieceAvailabilityBar::updateImage()
{ {
// qDebug() << "updateImageAv"; // qDebug() << "updateImageAv";
QImage image2(width() - 2, 1, QImage::Format_RGB888); QImage image2(width() - 2, 1, QImage::Format_RGB888);
if (pieces.empty()) { if (pieces.empty()) {
image2.fill(0xffffff); image2.fill(0xffffff);
image = image2; image = image2;
update(); update();
return; return;
} }
std::vector<float> scaled_pieces = intToFloatVector(pieces, image2.width()); std::vector<float> scaled_pieces = intToFloatVector(pieces, image2.width());
// filling image // filling image
for (unsigned int x = 0; x < scaled_pieces.size(); ++x) for (unsigned int x = 0; x < scaled_pieces.size(); ++x)
{ {
float pieces2_val = scaled_pieces.at(x); float pieces2_val = scaled_pieces.at(x);
image2.setPixel(x, 0, piece_colors[pieces2_val * 255]); image2.setPixel(x, 0, piece_colors[pieces2_val * 255]);
} }
image = image2; image = image2;
} }
void PieceAvailabilityBar::setAvailability(const std::vector<int>& avail) void PieceAvailabilityBar::setAvailability(const std::vector<int>& avail)
{ {
pieces = std::vector<int>(avail); pieces = std::vector<int>(avail);
updateImage(); updateImage();
update(); update();
} }
void PieceAvailabilityBar::updatePieceColors() void PieceAvailabilityBar::updatePieceColors()
{ {
piece_colors = std::vector<int>(256); piece_colors = std::vector<int>(256);
for (int i = 0; i < 256; ++i) { for (int i = 0; i < 256; ++i) {
float ratio = (i / 255.0); float ratio = (i / 255.0);
piece_colors[i] = mixTwoColors(bg_color, piece_color, ratio); piece_colors[i] = mixTwoColors(bg_color, piece_color, ratio);
} }
} }
void PieceAvailabilityBar::clear() void PieceAvailabilityBar::clear()
{ {
image = QImage(); image = QImage();
update(); update();
} }
void PieceAvailabilityBar::paintEvent(QPaintEvent *) void PieceAvailabilityBar::paintEvent(QPaintEvent *)
{ {
QPainter painter(this); QPainter painter(this);
QRect imageRect(1, 1, width() - 2, height() - 2); QRect imageRect(1, 1, width() - 2, height() - 2);
if (image.isNull()) if (image.isNull())
{ {
painter.setBrush(Qt::white); painter.setBrush(Qt::white);
painter.drawRect(imageRect); painter.drawRect(imageRect);
} }
else else
{ {
if (image.width() != imageRect.width()) if (image.width() != imageRect.width())
updateImage(); updateImage();
painter.drawImage(imageRect, image); painter.drawImage(imageRect, image);
} }
QPainterPath border; QPainterPath border;
border.addRect(0, 0, width() - 1, height() - 1); border.addRect(0, 0, width() - 1, height() - 1);
painter.setPen(border_color); painter.setPen(border_color);
painter.drawPath(border); painter.drawPath(border);
} }
void PieceAvailabilityBar::setColors(int background, int border, int available) void PieceAvailabilityBar::setColors(int background, int border, int available)
{ {
bg_color = background; bg_color = background;
border_color = border; border_color = border;
piece_color = available; piece_color = available;
updatePieceColors(); updatePieceColors();
updateImage(); updateImage();
update(); update();
} }

View file

@ -40,46 +40,46 @@
#define BAR_HEIGHT 18 #define BAR_HEIGHT 18
class PieceAvailabilityBar: public QWidget { class PieceAvailabilityBar: public QWidget {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(PieceAvailabilityBar) Q_DISABLE_COPY(PieceAvailabilityBar)
private: private:
QImage image; QImage image;
// I used values, bacause it should be possible to change colors in runtime // I used values, bacause it should be possible to change colors in runtime
// background color // background color
int bg_color; int bg_color;
// border color // border color
int border_color; int border_color;
// complete piece color // complete piece color
int piece_color; int piece_color;
// buffered 256 levels gradient from bg_color to piece_color // buffered 256 levels gradient from bg_color to piece_color
std::vector<int> piece_colors; std::vector<int> piece_colors;
// last used int vector, uses to better resize redraw // last used int vector, uses to better resize redraw
// TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster // TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster
std::vector<int> pieces; std::vector<int> pieces;
// scale int vector to float vector // scale int vector to float vector
std::vector<float> intToFloatVector(const std::vector<int> &vecin, int reqSize); std::vector<float> intToFloatVector(const std::vector<int> &vecin, int reqSize);
// mix two colors by light model, ratio <0, 1> // mix two colors by light model, ratio <0, 1>
int mixTwoColors(int &rgb1, int &rgb2, float ratio); int mixTwoColors(int &rgb1, int &rgb2, float ratio);
// draw new image and replace actual image // draw new image and replace actual image
void updateImage(); void updateImage();
public: public:
PieceAvailabilityBar(QWidget *parent); PieceAvailabilityBar(QWidget *parent);
void setAvailability(const std::vector<int>& avail); void setAvailability(const std::vector<int>& avail);
void updatePieceColors(); void updatePieceColors();
void clear(); void clear();
void setColors(int background, int border, int available); void setColors(int background, int border, int available);
protected: protected:
void paintEvent(QPaintEvent *); void paintEvent(QPaintEvent *);
}; };