203 lines
6.3 KiB
C++
203 lines
6.3 KiB
C++
// src/CommonWidgets.cpp
|
|
|
|
#include "CommonWidgets.h"
|
|
#include <QHBoxLayout>
|
|
#include <QVBoxLayout>
|
|
#include <QPainter>
|
|
#include <QMouseEvent>
|
|
#include <QPushButton>
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
// --- PlaylistDelegate Implementation ---
|
|
|
|
void PlaylistDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
|
|
painter->save();
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
|
|
|
// Background
|
|
if (option.state & QStyle::State_Selected) {
|
|
painter->fillRect(option.rect, QColor(50, 50, 50));
|
|
} else {
|
|
painter->fillRect(option.rect, QColor(17, 17, 17)); // Match list background
|
|
}
|
|
|
|
QRect r = option.rect.adjusted(5, 5, -5, -5);
|
|
|
|
// Icon / Art
|
|
QPixmap art = index.data(Qt::DecorationRole).value<QPixmap>();
|
|
QRect iconRect(r.left(), r.top(), 50, 50);
|
|
|
|
if (!art.isNull()) {
|
|
// Draw scaled art
|
|
painter->drawPixmap(iconRect, art.scaled(iconRect.size(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
|
} else {
|
|
// Placeholder
|
|
painter->fillRect(iconRect, QColor(40, 40, 40));
|
|
}
|
|
|
|
// Text
|
|
QRect textRect = r.adjusted(60, 0, 0, 0);
|
|
QString title = index.data(Qt::DisplayRole).toString();
|
|
QString artist = index.data(Qt::UserRole + 1).toString();
|
|
|
|
// Title
|
|
painter->setPen(Qt::white);
|
|
QFont f = option.font;
|
|
f.setBold(true);
|
|
f.setPointSize(14);
|
|
painter->setFont(f);
|
|
|
|
// Calculate height for title
|
|
QFontMetrics fmTitle(f);
|
|
int titleHeight = fmTitle.height();
|
|
QRect titleRect = textRect;
|
|
titleRect.setHeight(titleHeight);
|
|
|
|
QString elidedTitle = fmTitle.elidedText(title, Qt::ElideRight, titleRect.width());
|
|
painter->drawText(titleRect, Qt::AlignLeft | Qt::AlignTop, elidedTitle);
|
|
|
|
// Artist
|
|
painter->setPen(QColor(170, 170, 170));
|
|
f.setBold(false);
|
|
f.setPointSize(12);
|
|
painter->setFont(f);
|
|
|
|
QFontMetrics fmArtist(f);
|
|
QRect artistRect = textRect;
|
|
artistRect.setTop(titleRect.bottom() + 2);
|
|
artistRect.setHeight(fmArtist.height());
|
|
|
|
QString elidedArtist = fmArtist.elidedText(artist, Qt::ElideRight, artistRect.width());
|
|
painter->drawText(artistRect, Qt::AlignLeft | Qt::AlignTop, elidedArtist);
|
|
|
|
// Separator
|
|
painter->setPen(QColor(34, 34, 34));
|
|
painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
|
|
|
|
painter->restore();
|
|
}
|
|
|
|
QSize PlaylistDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const {
|
|
return QSize(0, 60);
|
|
}
|
|
|
|
// --- XYPad ---
|
|
|
|
XYPad::XYPad(const QString& title, QWidget* parent) : QWidget(parent), m_title(title) {
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
setMinimumHeight(150);
|
|
setCursor(Qt::CrossCursor);
|
|
}
|
|
|
|
void XYPad::setFormatter(std::function<QString(float, float)> formatter) {
|
|
m_formatter = formatter;
|
|
}
|
|
|
|
void XYPad::setValues(float x, float y) {
|
|
m_x = std::clamp(x, 0.0f, 1.0f);
|
|
m_y = std::clamp(y, 0.0f, 1.0f);
|
|
update();
|
|
}
|
|
|
|
void XYPad::paintEvent(QPaintEvent*) {
|
|
QPainter p(this);
|
|
p.setRenderHint(QPainter::Antialiasing);
|
|
|
|
p.fillRect(rect(), QColor(40, 40, 40, 200));
|
|
p.setPen(QPen(QColor(80, 80, 80), 1));
|
|
p.drawRect(rect().adjusted(0, 0, -1, -1));
|
|
|
|
p.setPen(QPen(QColor(60, 60, 60), 1, Qt::DotLine));
|
|
p.drawLine(width()/2, 0, width()/2, height());
|
|
p.drawLine(0, height()/2, width(), height()/2);
|
|
|
|
int px = m_x * width();
|
|
int py = (1.0f - m_y) * height();
|
|
|
|
p.setPen(Qt::NoPen);
|
|
p.setBrush(QColor(0, 212, 255, 180));
|
|
p.drawEllipse(QPoint(px, py), 12, 12);
|
|
p.setBrush(Qt::white);
|
|
p.drawEllipse(QPoint(px, py), 4, 4);
|
|
|
|
p.setPen(QPen(QColor(0, 212, 255, 100), 1));
|
|
p.drawLine(px, 0, px, height());
|
|
p.drawLine(0, py, width(), py);
|
|
|
|
p.setPen(Qt::white);
|
|
QFont f = font();
|
|
f.setBold(true);
|
|
f.setPointSize(10);
|
|
p.setFont(f);
|
|
|
|
QString text = m_title;
|
|
if (m_formatter) {
|
|
text += "\n" + m_formatter(m_x, m_y);
|
|
}
|
|
p.drawText(rect().adjusted(10, 10, -10, -10), Qt::AlignLeft | Qt::AlignTop, text);
|
|
}
|
|
|
|
void XYPad::mousePressEvent(QMouseEvent* event) { updateFromPos(event->pos()); }
|
|
void XYPad::mouseMoveEvent(QMouseEvent* event) { updateFromPos(event->pos()); }
|
|
|
|
void XYPad::updateFromPos(const QPoint& pos) {
|
|
m_x = std::clamp((float)pos.x() / width(), 0.0f, 1.0f);
|
|
m_y = std::clamp(1.0f - (float)pos.y() / height(), 0.0f, 1.0f);
|
|
update();
|
|
emit valuesChanged(m_x, m_y);
|
|
}
|
|
|
|
OverlayWidget::OverlayWidget(QWidget* content, QWidget* parent) : QWidget(parent), m_content(content) {
|
|
QPalette pal = palette();
|
|
pal.setColor(QPalette::Window, QColor(0, 0, 0, 100));
|
|
setAutoFillBackground(true);
|
|
setPalette(pal);
|
|
|
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
|
layout->setAlignment(Qt::AlignCenter);
|
|
layout->setContentsMargins(20, 20, 20, 20);
|
|
|
|
content->setParent(this);
|
|
content->setMaximumWidth(500);
|
|
content->setMaximumHeight(600);
|
|
|
|
layout->addWidget(content);
|
|
hide();
|
|
}
|
|
|
|
void OverlayWidget::mousePressEvent(QMouseEvent* event) {
|
|
if (!m_content->geometry().contains(event->pos())) {
|
|
hide();
|
|
}
|
|
}
|
|
|
|
void OverlayWidget::paintEvent(QPaintEvent* event) {
|
|
QPainter p(this);
|
|
p.fillRect(rect(), QColor(0, 0, 0, 100));
|
|
}
|
|
|
|
WelcomeWidget::WelcomeWidget(QWidget* parent) : QWidget(parent) {
|
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
|
layout->setAlignment(Qt::AlignCenter);
|
|
layout->setSpacing(20);
|
|
|
|
QLabel* title = new QLabel("Yr Crystals", this);
|
|
title->setStyleSheet("color: white; font-size: 32px; font-weight: bold;");
|
|
title->setAlignment(Qt::AlignCenter);
|
|
layout->addWidget(title);
|
|
|
|
QString btnStyle = "QPushButton { background-color: #333; color: white; border: 1px solid #555; border-radius: 8px; padding: 15px; font-size: 18px; } QPushButton:pressed { background-color: #555; }";
|
|
|
|
QPushButton* btnFile = new QPushButton("Open File", this);
|
|
btnFile->setStyleSheet(btnStyle);
|
|
btnFile->setFixedWidth(250);
|
|
connect(btnFile, &QPushButton::clicked, this, &WelcomeWidget::openFileClicked);
|
|
layout->addWidget(btnFile);
|
|
|
|
QPushButton* btnFolder = new QPushButton("Open Folder", this);
|
|
btnFolder->setStyleSheet(btnStyle);
|
|
btnFolder->setFixedWidth(250);
|
|
connect(btnFolder, &QPushButton::clicked, this, &WelcomeWidget::openFolderClicked);
|
|
layout->addWidget(btnFolder);
|
|
} |