Spectral/src/imageitem.cpp

107 lines
2.9 KiB
C++

#include "imageitem.h"
#include <QBitmap>
#include <QGraphicsOpacityEffect>
#include <QRect>
ImageItem::ImageItem(QQuickItem *parent) : QQuickPaintedItem(parent) {}
inline static QString stringtoColor(QString string) {
int hash = 0;
for (int i = 0; i < string.length(); i++)
hash = string.at(i).unicode() + ((hash << 5) - hash);
QString colour = "#";
for (int j = 0; j < 3; j++)
colour += ("00" + QString::number((hash >> (j * 8)) & 0xFF, 16)).right(2);
return colour;
}
inline static QImage getImageFromPaintable(QPointer<Paintable> p, QRectF b) {
if (p.isNull()) return {};
QImage image(p->image(int(b.width()), int(b.height())));
if (image.isNull()) return {};
return image;
}
void ImageItem::paint(QPainter *painter) {
QRectF bounding_rect = boundingRect();
painter->setRenderHint(QPainter::Antialiasing, true);
QImage image(getImageFromPaintable(m_paintable, bounding_rect));
if (image.isNull()) {
painter->setPen(Qt::NoPen);
if (m_color.isEmpty())
painter->setBrush(QColor(stringtoColor(m_hint)));
else
painter->setBrush(QColor(m_color));
if (m_round)
painter->drawEllipse(0, 0, int(bounding_rect.width()),
int(bounding_rect.height()));
else
painter->drawRect(0, 0, int(bounding_rect.width()),
int(bounding_rect.height()));
painter->setPen(QPen(Qt::white, 2));
QFont font;
font.setStyleHint(QFont::SansSerif);
font.setPixelSize(int(bounding_rect.width() / 2));
font.setBold(true);
painter->setFont(font);
painter->drawText(
QRect(0, 0, int(bounding_rect.width()), int(bounding_rect.height())),
Qt::AlignCenter, m_hint.at(0).toUpper());
} else {
QImage scaled = image.scaled(
int(bounding_rect.width()) + 1, int(bounding_rect.height()) + 1,
Qt::KeepAspectRatioByExpanding, Qt::FastTransformation);
QPointF center = bounding_rect.center() - scaled.rect().center();
if (m_round) {
QPainterPath clip;
clip.addEllipse(
0, 0, bounding_rect.width(),
bounding_rect.height()); // this is the shape we want to clip to
painter->setClipPath(clip);
}
painter->drawImage(center, scaled);
}
}
void ImageItem::setPaintable(Paintable *paintable) {
if (!paintable) return;
if (!m_paintable.isNull()) m_paintable->disconnect(this);
m_paintable = paintable;
connect(m_paintable, &Paintable::paintableChanged, this,
[=] { this->update(); });
emit paintableChanged();
update();
}
void ImageItem::setHint(QString newHint) {
if (m_hint != newHint) {
m_hint = newHint;
emit hintChanged();
update();
}
}
void ImageItem::setDefaultColor(QString color) {
if (color != m_color) {
m_color = color;
emit defaultColorChanged();
update();
}
}
void ImageItem::setRound(bool value) {
if (m_round != value) {
m_round = value;
emit roundChanged();
update();
}
}