Merge remote-tracking branch 'upstream/develop' into data-packs

Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
TheKodeToad 2025-04-29 09:15:11 +01:00
commit fadbcf2d04
No known key found for this signature in database
GPG key ID: 5E39D70B4C93C38E
279 changed files with 9562 additions and 2103 deletions

View file

@ -1,3 +1,5 @@
#pragma once
#include <QLineEdit>
class FocusLineEdit : public QLineEdit {

View file

@ -42,6 +42,7 @@ LogView::LogView(QWidget* parent) : QPlainTextEdit(parent)
{
setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
m_defaultFormat = new QTextCharFormat(currentCharFormat());
setUndoRedoEnabled(false);
}
LogView::~LogView()
@ -60,6 +61,14 @@ void LogView::setWordWrap(bool wrapping)
}
}
void LogView::setColorLines(bool colorLines)
{
if (m_colorLines == colorLines)
return;
m_colorLines = colorLines;
repopulate();
}
void LogView::setModel(QAbstractItemModel* model)
{
if (m_model) {
@ -121,6 +130,8 @@ void LogView::rowsInserted(const QModelIndex& parent, int first, int last)
QTextDocument document;
QTextCursor cursor(&document);
cursor.movePosition(QTextCursor::End);
cursor.beginEditBlock();
for (int i = first; i <= last; i++) {
auto idx = m_model->index(i, 0, parent);
auto text = m_model->data(idx, Qt::DisplayRole).toString();
@ -130,17 +141,17 @@ void LogView::rowsInserted(const QModelIndex& parent, int first, int last)
format.setFont(font.value<QFont>());
}
auto fg = m_model->data(idx, Qt::ForegroundRole);
if (fg.isValid()) {
if (fg.isValid() && m_colorLines) {
format.setForeground(fg.value<QColor>());
}
auto bg = m_model->data(idx, Qt::BackgroundRole);
if (bg.isValid()) {
if (bg.isValid() && m_colorLines) {
format.setBackground(bg.value<QColor>());
}
cursor.movePosition(QTextCursor::End);
cursor.insertText(text, format);
cursor.insertBlock();
}
cursor.endEditBlock();
QTextDocumentFragment fragment(&document);
QTextCursor workCursor = textCursor();

View file

@ -15,6 +15,7 @@ class LogView : public QPlainTextEdit {
public slots:
void setWordWrap(bool wrapping);
void setColorLines(bool colorLines);
void findNext(const QString& what, bool reverse);
void scrollToBottom();
@ -32,4 +33,5 @@ class LogView : public QPlainTextEdit {
QTextCharFormat* m_defaultFormat = nullptr;
bool m_scroll = false;
bool m_scrolling = false;
bool m_colorLines = true;
};

View file

@ -148,11 +148,10 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extended, QWi
connect(ui->forge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
connect(ui->fabric, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
connect(ui->quilt, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
connect(ui->neoForge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
connect(ui->forge, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
connect(ui->fabric, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
connect(ui->quilt, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
if (extended)
connect(ui->liteLoader, &QCheckBox::stateChanged, this, &ModFilterWidget::onLoadersFilterChanged);
else
ui->liteLoader->setVisible(false);
if (extended) {
connect(ui->clientSide, &QCheckBox::stateChanged, this, &ModFilterWidget::onSideFilterChanged);
@ -224,6 +223,7 @@ void ModFilterWidget::prepareBasicFilter()
ui->forge->setChecked(loaders & ModPlatform::Forge);
ui->fabric->setChecked(loaders & ModPlatform::Fabric);
ui->quilt->setChecked(loaders & ModPlatform::Quilt);
ui->liteLoader->setChecked(loaders & ModPlatform::LiteLoader);
m_filter->loaders = loaders;
auto def = m_instance->getPackProfile()->getComponentVersion("net.minecraft");
m_filter->versions.emplace_front(def);
@ -269,6 +269,8 @@ void ModFilterWidget::onLoadersFilterChanged()
loaders |= ModPlatform::Fabric;
if (ui->quilt->isChecked())
loaders |= ModPlatform::Quilt;
if (ui->liteLoader->isChecked())
loaders |= ModPlatform::LiteLoader;
m_filter_changed = loaders != m_filter->loaders;
m_filter->loaders = loaders;
if (m_filter_changed)
@ -289,7 +291,6 @@ void ModFilterWidget::onSideFilterChanged()
side = "";
}
m_filter_changed = side != m_filter->side;
m_filter->side = side;
if (m_filter_changed)

View file

@ -121,6 +121,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="liteLoader">
<property name="text">
<string>LiteLoader</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -1,9 +1,11 @@
#include "ProjectItem.h"
#include "Common.h"
#include <QApplication>
#include <QDebug>
#include <QIcon>
#include <QPainter>
#include "Common.h"
ProjectItemDelegate::ProjectItemDelegate(QWidget* parent) : QStyledItemDelegate(parent) {}
@ -14,13 +16,20 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
QStyleOptionViewItem opt(option);
initStyleOption(&opt, index);
const QStyle* style = opt.widget == nullptr ? QApplication::style() : opt.widget->style();
auto rect = opt.rect;
if (opt.state & QStyle::State_Selected) {
painter->fillRect(rect, opt.palette.highlight());
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
if (option.state & QStyle::State_Selected && style->objectName() != "windowsvista")
painter->setPen(opt.palette.highlightedText().color());
} else if (opt.state & QStyle::State_MouseOver) {
painter->fillRect(rect, opt.palette.window());
if (opt.features & QStyleOptionViewItem::HasCheckIndicator) {
QStyleOptionViewItem checkboxOpt = makeCheckboxStyleOption(opt, style);
style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &checkboxOpt, painter, opt.widget);
rect.setX(checkboxOpt.rect.right());
}
// The default icon size will be a square (and height is usually the lower value).
@ -42,6 +51,9 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
int x = rect.x() + icon_x_margin;
int y = rect.y() + icon_y_margin;
if (opt.features & QStyleOptionViewItem::HasCheckIndicator)
rect.translate(icon_x_margin / 2, 0);
// Prevent 'scaling null pixmap' warnings
if (icon_width > 0 && icon_height > 0)
opt.icon.paint(painter, x, y, icon_width, icon_height);
@ -56,26 +68,12 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
{ // Title painting
auto title = index.data(UserDataTypes::TITLE).toString();
if (index.data(UserDataTypes::INSTALLED).toBool())
title = tr("%1 [installed]").arg(title);
painter->save();
auto font = opt.font;
if (index.data(UserDataTypes::SELECTED).toBool()) {
// Set nice font
font.setBold(true);
font.setUnderline(true);
}
if (index.data(UserDataTypes::INSTALLED).toBool()) {
auto hRect = opt.rect;
hRect.setX(hRect.x() + 1);
hRect.setY(hRect.y() + 1);
hRect.setHeight(hRect.height() - 2);
hRect.setWidth(hRect.width() - 2);
// Set nice font
font.setItalic(true);
font.setOverline(true);
painter->drawRect(hRect);
}
font.setPointSize(font.pointSize() + 2);
painter->setFont(font);
@ -132,3 +130,56 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
painter->restore();
}
bool ProjectItemDelegate::editorEvent(QEvent* event,
QAbstractItemModel* model,
const QStyleOptionViewItem& option,
const QModelIndex& index)
{
if (!(event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonDblClick))
return false;
auto mouseEvent = (QMouseEvent*)event;
if (mouseEvent->button() != Qt::LeftButton)
return false;
QStyleOptionViewItem opt(option);
initStyleOption(&opt, index);
const QStyle* style = opt.widget == nullptr ? QApplication::style() : opt.widget->style();
const QStyleOptionViewItem checkboxOpt = makeCheckboxStyleOption(opt, style);
if (!checkboxOpt.rect.contains(mouseEvent->pos().x(), mouseEvent->pos().y()))
return false;
// swallow other events
// (prevents item being selected or double click action triggering)
if (event->type() != QEvent::MouseButtonRelease)
return true;
emit checkboxClicked(index);
return true;
}
QStyleOptionViewItem ProjectItemDelegate::makeCheckboxStyleOption(const QStyleOptionViewItem& opt, const QStyle* style) const
{
QStyleOptionViewItem checkboxOpt = opt;
checkboxOpt.state &= ~QStyle::State_HasFocus;
if (checkboxOpt.checkState == Qt::Checked)
checkboxOpt.state |= QStyle::State_On;
else
checkboxOpt.state |= QStyle::State_Off;
QRect checkboxRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &checkboxOpt, opt.widget);
// 5px is the typical top margin for image
// we don't want the checkboxes to be all over the place :)
checkboxOpt.rect = QRect(opt.rect.x() + 5, opt.rect.y() + (opt.rect.height() / 2 - checkboxRect.height() / 2), checkboxRect.width(),
checkboxRect.height());
return checkboxOpt;
}

View file

@ -6,8 +6,7 @@
enum UserDataTypes {
TITLE = 257, // QString
DESCRIPTION = 258, // QString
SELECTED = 259, // bool
INSTALLED = 260 // bool
INSTALLED = 259 // bool
};
/** This is an item delegate composed of:
@ -22,4 +21,12 @@ class ProjectItemDelegate final : public QStyledItemDelegate {
ProjectItemDelegate(QWidget* parent);
void paint(QPainter*, const QStyleOptionViewItem&, const QModelIndex&) const override;
bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) override;
signals:
void checkboxClicked(const QModelIndex& index);
private:
QStyleOptionViewItem makeCheckboxStyleOption(const QStyleOptionViewItem& opt, const QStyle* style) const;
};