NOISSUE move everything.
This commit is contained in:
27
application/widgets/Common.cpp
Normal file
27
application/widgets/Common.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "Common.h"
|
||||
|
||||
// Origin: Qt
|
||||
QStringList viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height,
|
||||
qreal &widthUsed)
|
||||
{
|
||||
QStringList lines;
|
||||
height = 0;
|
||||
widthUsed = 0;
|
||||
textLayout.beginLayout();
|
||||
QString str = textLayout.text();
|
||||
while (true)
|
||||
{
|
||||
QTextLine line = textLayout.createLine();
|
||||
if (!line.isValid())
|
||||
break;
|
||||
if (line.textLength() == 0)
|
||||
break;
|
||||
line.setLineWidth(lineWidth);
|
||||
line.setPosition(QPointF(0, height));
|
||||
height += line.height();
|
||||
lines.append(str.mid(line.textStart(), line.textLength()));
|
||||
widthUsed = qMax(widthUsed, line.naturalTextWidth());
|
||||
}
|
||||
textLayout.endLayout();
|
||||
return lines;
|
||||
}
|
6
application/widgets/Common.h
Normal file
6
application/widgets/Common.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <QStringList>
|
||||
#include <QTextLayout>
|
||||
|
||||
QStringList viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height,
|
||||
qreal &widthUsed);
|
43
application/widgets/IconLabel.cpp
Normal file
43
application/widgets/IconLabel.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "IconLabel.h"
|
||||
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
#include <QLayout>
|
||||
#include <QPainter>
|
||||
#include <QRect>
|
||||
|
||||
IconLabel::IconLabel(QWidget *parent, QIcon icon, QSize size)
|
||||
: QWidget(parent), m_size(size), m_icon(icon)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
QSize IconLabel::sizeHint() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void IconLabel::setIcon(QIcon icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
update();
|
||||
}
|
||||
|
||||
void IconLabel::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
QRect rect = contentsRect();
|
||||
int width = rect.width();
|
||||
int height = rect.height();
|
||||
if(width < height)
|
||||
{
|
||||
rect.setHeight(width);
|
||||
rect.translate(0, (height - width) / 2);
|
||||
}
|
||||
else if (width > height)
|
||||
{
|
||||
rect.setWidth(height);
|
||||
rect.translate((width - height) / 2, 0);
|
||||
}
|
||||
m_icon.paint(&p, rect);
|
||||
}
|
26
application/widgets/IconLabel.h
Normal file
26
application/widgets/IconLabel.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <QIcon>
|
||||
|
||||
class QStyleOption;
|
||||
|
||||
/**
|
||||
* This is a trivial widget that paints a QIcon of the specified size.
|
||||
*/
|
||||
class IconLabel : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Create a line separator. orientation is the orientation of the line.
|
||||
explicit IconLabel(QWidget *parent, QIcon icon, QSize size);
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
virtual void paintEvent(QPaintEvent *);
|
||||
|
||||
void setIcon(QIcon icon);
|
||||
|
||||
private:
|
||||
QSize m_size;
|
||||
QIcon m_icon;
|
||||
};
|
86
application/widgets/LabeledToolButton.cpp
Normal file
86
application/widgets/LabeledToolButton.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QResizeEvent>
|
||||
#include <QStyleOption>
|
||||
#include "LabeledToolButton.h"
|
||||
#include <QApplication>
|
||||
|
||||
/*
|
||||
*
|
||||
* Tool Button with a label on it, instead of the normal text rendering
|
||||
*
|
||||
*/
|
||||
|
||||
LabeledToolButton::LabeledToolButton(QWidget * parent)
|
||||
: QToolButton(parent)
|
||||
, m_label(new QLabel(this))
|
||||
{
|
||||
//QToolButton::setText(" ");
|
||||
m_label->setWordWrap(true);
|
||||
m_label->setMouseTracking(false);
|
||||
m_label->setAlignment(Qt::AlignCenter);
|
||||
m_label->setTextInteractionFlags(Qt::NoTextInteraction);
|
||||
// somehow, this makes word wrap work in the QLabel. yay.
|
||||
m_label->setMinimumWidth(100);
|
||||
}
|
||||
|
||||
QString LabeledToolButton::text() const
|
||||
{
|
||||
return m_label->text();
|
||||
}
|
||||
|
||||
void LabeledToolButton::setText(const QString & text)
|
||||
{
|
||||
m_label->setText(text);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QSize LabeledToolButton::sizeHint() const
|
||||
{
|
||||
/*
|
||||
Q_D(const QToolButton);
|
||||
if (d->sizeHint.isValid())
|
||||
return d->sizeHint;
|
||||
*/
|
||||
ensurePolished();
|
||||
|
||||
int w = 0, h = 0;
|
||||
QStyleOptionToolButton opt;
|
||||
initStyleOption(&opt);
|
||||
QSize sz =m_label->sizeHint();
|
||||
w = sz.width();
|
||||
h = sz.height();
|
||||
|
||||
opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height
|
||||
if (popupMode() == MenuButtonPopup)
|
||||
w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this);
|
||||
|
||||
QSize rawSize = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this);
|
||||
QSize sizeHint = rawSize.expandedTo(QApplication::globalStrut());
|
||||
return sizeHint;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LabeledToolButton::resizeEvent(QResizeEvent * event)
|
||||
{
|
||||
m_label->setGeometry(QRect(4, 4, width()-8, height()-8));
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
37
application/widgets/LabeledToolButton.h
Normal file
37
application/widgets/LabeledToolButton.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QToolButton>
|
||||
|
||||
class QLabel;
|
||||
|
||||
class LabeledToolButton : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QLabel * m_label;
|
||||
|
||||
public:
|
||||
LabeledToolButton(QWidget * parent = 0);
|
||||
|
||||
QString text() const;
|
||||
void setText(const QString & text);
|
||||
virtual QSize sizeHint() const;
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent * event);
|
||||
};
|
37
application/widgets/LineSeparator.cpp
Normal file
37
application/widgets/LineSeparator.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "LineSeparator.h"
|
||||
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
#include <QLayout>
|
||||
#include <QPainter>
|
||||
|
||||
void LineSeparator::initStyleOption(QStyleOption *option) const
|
||||
{
|
||||
option->initFrom(this);
|
||||
// in a horizontal layout, the line is vertical (and vice versa)
|
||||
if (m_orientation == Qt::Vertical)
|
||||
option->state |= QStyle::State_Horizontal;
|
||||
}
|
||||
|
||||
LineSeparator::LineSeparator(QWidget *parent, Qt::Orientation orientation)
|
||||
: QWidget(parent), m_orientation(orientation)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
QSize LineSeparator::sizeHint() const
|
||||
{
|
||||
QStyleOption opt;
|
||||
initStyleOption(&opt);
|
||||
const int extent =
|
||||
style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget());
|
||||
return QSize(extent, extent);
|
||||
}
|
||||
|
||||
void LineSeparator::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
QStyleOption opt;
|
||||
initStyleOption(&opt);
|
||||
style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p, parentWidget());
|
||||
}
|
18
application/widgets/LineSeparator.h
Normal file
18
application/widgets/LineSeparator.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
|
||||
class QStyleOption;
|
||||
|
||||
class LineSeparator : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Create a line separator. orientation is the orientation of the line.
|
||||
explicit LineSeparator(QWidget *parent, Qt::Orientation orientation = Qt::Horizontal);
|
||||
QSize sizeHint() const;
|
||||
void paintEvent(QPaintEvent *);
|
||||
void initStyleOption(QStyleOption *option) const;
|
||||
private:
|
||||
Qt::Orientation m_orientation = Qt::Horizontal;
|
||||
};
|
111
application/widgets/MCModInfoFrame.cpp
Normal file
111
application/widgets/MCModInfoFrame.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QtGui>
|
||||
|
||||
#include "MCModInfoFrame.h"
|
||||
#include "ui_MCModInfoFrame.h"
|
||||
#include "dialogs/CustomMessageBox.h"
|
||||
|
||||
void MCModInfoFrame::updateWithMod(Mod &m)
|
||||
{
|
||||
if(m.type() == m.MOD_FOLDER)
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
||||
QString text = "";
|
||||
QString name = "";
|
||||
if(m.name().isEmpty()) name = m.mmc_id();
|
||||
else name = m.name();
|
||||
|
||||
if(m.homeurl().isEmpty()) text = name;
|
||||
else text = "<a href=\"" + m.homeurl() + "\">" + name + "</a>";
|
||||
if(!m.authors().isEmpty()) text += " by " + m.authors();
|
||||
|
||||
setModText(text);
|
||||
|
||||
if(m.description().isEmpty())
|
||||
{
|
||||
setModDescription(tr("No description provided in mcmod.info"));
|
||||
}
|
||||
else
|
||||
{
|
||||
setModDescription(m.description());
|
||||
}
|
||||
}
|
||||
|
||||
void MCModInfoFrame::clear()
|
||||
{
|
||||
setModText(tr("Select a mod to view title and authors..."));
|
||||
setModDescription(tr("Select a mod to view description..."));
|
||||
}
|
||||
|
||||
MCModInfoFrame::MCModInfoFrame(QWidget *parent) :
|
||||
QFrame(parent),
|
||||
ui(new Ui::MCModInfoFrame)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
MCModInfoFrame::~MCModInfoFrame()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MCModInfoFrame::setModText(QString text)
|
||||
{
|
||||
ui->label_ModText->setText(text);
|
||||
}
|
||||
|
||||
void MCModInfoFrame::setModDescription(QString text)
|
||||
{
|
||||
ui->label_ModDescription->setToolTip("");
|
||||
QString intermediatetext = text.trimmed();
|
||||
bool prev(false);
|
||||
QChar rem('\n');
|
||||
QString finaltext;
|
||||
finaltext.reserve(intermediatetext.size());
|
||||
foreach(const QChar& c, intermediatetext)
|
||||
{
|
||||
if(c == rem && prev){
|
||||
continue;
|
||||
}
|
||||
prev = c == rem;
|
||||
finaltext += c;
|
||||
}
|
||||
QString labeltext;
|
||||
labeltext.reserve(300);
|
||||
if(finaltext.length() > 290)
|
||||
{
|
||||
ui->label_ModDescription->setOpenExternalLinks(false);
|
||||
ui->label_ModDescription->setTextFormat(Qt::TextFormat::RichText);
|
||||
desc = text;
|
||||
labeltext.append("<html><body>" + finaltext.left(287) + "<a href=\"#mod_desc\">...</a></body></html>");
|
||||
QObject::connect(ui->label_ModDescription, &QLabel::linkActivated, this, &MCModInfoFrame::modDescEllipsisHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->label_ModDescription->setTextFormat(Qt::TextFormat::PlainText);
|
||||
labeltext.append(finaltext);
|
||||
}
|
||||
ui->label_ModDescription->setText(labeltext);
|
||||
}
|
||||
void MCModInfoFrame::modDescEllipsisHandler(const QString &link)
|
||||
{
|
||||
CustomMessageBox::selectable(this, tr(""), desc)->show();
|
||||
}
|
46
application/widgets/MCModInfoFrame.h
Normal file
46
application/widgets/MCModInfoFrame.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFrame>
|
||||
#include "minecraft/Mod.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MCModInfoFrame;
|
||||
}
|
||||
|
||||
class MCModInfoFrame : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MCModInfoFrame(QWidget *parent = 0);
|
||||
~MCModInfoFrame();
|
||||
|
||||
void setModText(QString text);
|
||||
void setModDescription(QString text);
|
||||
|
||||
void updateWithMod(Mod &m);
|
||||
void clear();
|
||||
|
||||
public slots:
|
||||
void modDescEllipsisHandler(const QString& link );
|
||||
|
||||
private:
|
||||
Ui::MCModInfoFrame *ui;
|
||||
QString desc;
|
||||
};
|
68
application/widgets/MCModInfoFrame.ui
Normal file
68
application/widgets/MCModInfoFrame.ui
Normal file
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MCModInfoFrame</class>
|
||||
<widget class="QFrame" name="MCModInfoFrame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>527</width>
|
||||
<height>113</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Frame</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_ModText">
|
||||
<property name="text">
|
||||
<string>Select a mod to view title and authors...</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_ModDescription">
|
||||
<property name="text">
|
||||
<string>Select a mod to view description...</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
62
application/widgets/ModListView.cpp
Normal file
62
application/widgets/ModListView.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ModListView.h"
|
||||
#include <QHeaderView>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QDrag>
|
||||
#include <QRect>
|
||||
|
||||
ModListView::ModListView ( QWidget* parent )
|
||||
:QTreeView ( parent )
|
||||
{
|
||||
setAllColumnsShowFocus ( true );
|
||||
setExpandsOnDoubleClick ( false );
|
||||
setRootIsDecorated ( false );
|
||||
setSortingEnabled ( false );
|
||||
setAlternatingRowColors ( true );
|
||||
setSelectionMode ( QAbstractItemView::ContiguousSelection );
|
||||
setHeaderHidden ( false );
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOn );
|
||||
setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded );
|
||||
setDropIndicatorShown(true);
|
||||
setDragEnabled(true);
|
||||
setDragDropMode(QAbstractItemView::DropOnly);
|
||||
viewport()->setAcceptDrops(true);
|
||||
}
|
||||
|
||||
void ModListView::setModel ( QAbstractItemModel* model )
|
||||
{
|
||||
QTreeView::setModel ( model );
|
||||
auto head = header();
|
||||
head->setStretchLastSection(false);
|
||||
// HACK: this is true for the checkbox column of mod lists
|
||||
auto string = model->headerData(0,head->orientation()).toString();
|
||||
if(!string.size())
|
||||
{
|
||||
head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
head->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
for(int i = 2; i < head->count(); i++)
|
||||
head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
|
||||
}
|
||||
else
|
||||
{
|
||||
head->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
for(int i = 1; i < head->count(); i++)
|
||||
head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
|
||||
}
|
||||
}
|
27
application/widgets/ModListView.h
Normal file
27
application/widgets/ModListView.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QTreeView>
|
||||
|
||||
class Mod;
|
||||
|
||||
class ModListView: public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModListView ( QWidget* parent = 0 );
|
||||
virtual void setModel ( QAbstractItemModel* model );
|
||||
};
|
210
application/widgets/PageContainer.cpp
Normal file
210
application/widgets/PageContainer.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "PageContainer.h"
|
||||
|
||||
#include <QStackedLayout>
|
||||
#include <QPushButton>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QUrl>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QListView>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include "MultiMC.h"
|
||||
#include "settings/SettingsObject.h"
|
||||
#include "widgets/IconLabel.h"
|
||||
#include "Platform.h"
|
||||
#include "PageContainer_p.h"
|
||||
#include <MultiMC.h>
|
||||
|
||||
class PageEntryFilterModel : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
explicit PageEntryFilterModel(QObject *parent = 0) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
const QString pattern = filterRegExp().pattern();
|
||||
const auto model = static_cast<PageModel *>(sourceModel());
|
||||
const auto page = model->pages().at(sourceRow);
|
||||
if (!page->shouldDisplay())
|
||||
return false;
|
||||
// Regular contents check, then check page-filter.
|
||||
return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
|
||||
}
|
||||
};
|
||||
|
||||
PageContainer::PageContainer(BasePageProviderPtr pageProvider, QString defaultId,
|
||||
QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
createUI();
|
||||
m_model = new PageModel(this);
|
||||
m_proxyModel = new PageEntryFilterModel(this);
|
||||
int firstIndex = -1;
|
||||
int counter = 0;
|
||||
auto pages = pageProvider->getPages();
|
||||
for (auto page : pages)
|
||||
{
|
||||
page->stackIndex = m_pageStack->addWidget(dynamic_cast<QWidget *>(page));
|
||||
page->listIndex = counter;
|
||||
counter++;
|
||||
if (firstIndex == -1)
|
||||
{
|
||||
firstIndex = page->stackIndex;
|
||||
}
|
||||
}
|
||||
m_model->setPages(pages);
|
||||
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
m_pageList->setIconSize(QSize(pageIconSize, pageIconSize));
|
||||
m_pageList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_pageList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
m_pageList->setModel(m_proxyModel);
|
||||
connect(m_pageList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex, QModelIndex)),
|
||||
this, SLOT(currentChanged(QModelIndex)));
|
||||
m_pageStack->setStackingMode(QStackedLayout::StackOne);
|
||||
m_pageList->setFocus();
|
||||
// now find what we want to have selected...
|
||||
auto page = m_model->findPageEntryById(defaultId);
|
||||
QModelIndex index;
|
||||
if (page)
|
||||
{
|
||||
index = m_proxyModel->mapFromSource(m_model->index(page->listIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
index = m_proxyModel->index(0, 0);
|
||||
}
|
||||
if (index.isValid())
|
||||
m_pageList->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void PageContainer::createUI()
|
||||
{
|
||||
m_pageStack = new QStackedLayout;
|
||||
m_filter = new QLineEdit;
|
||||
m_pageList = new PageView;
|
||||
m_header = new QLabel();
|
||||
m_iconHeader = new IconLabel(this, QIcon(), QSize(24, 24));
|
||||
|
||||
QFont headerLabelFont = m_header->font();
|
||||
headerLabelFont.setBold(true);
|
||||
const int pointSize = headerLabelFont.pointSize();
|
||||
if (pointSize > 0)
|
||||
headerLabelFont.setPointSize(pointSize + 2);
|
||||
m_header->setFont(headerLabelFont);
|
||||
|
||||
QHBoxLayout *headerHLayout = new QHBoxLayout;
|
||||
const int leftMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
|
||||
headerHLayout->addSpacerItem(
|
||||
new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
|
||||
headerHLayout->addWidget(m_header);
|
||||
headerHLayout->addSpacerItem(
|
||||
new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
|
||||
headerHLayout->addWidget(m_iconHeader);
|
||||
const int rightMargin = MMC->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
|
||||
headerHLayout->addSpacerItem(
|
||||
new QSpacerItem(rightMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
|
||||
|
||||
m_pageStack->setMargin(0);
|
||||
m_pageStack->addWidget(new QWidget(this));
|
||||
|
||||
m_layout = new QGridLayout;
|
||||
m_layout->addLayout(headerHLayout, 0, 1, 1, 1);
|
||||
m_layout->addWidget(m_pageList, 0, 0, 2, 1);
|
||||
m_layout->addLayout(m_pageStack, 1, 1, 1, 1);
|
||||
m_layout->setColumnStretch(1, 4);
|
||||
setLayout(m_layout);
|
||||
}
|
||||
|
||||
void PageContainer::addButtons(QWidget *buttons)
|
||||
{
|
||||
m_layout->addWidget(buttons, 2, 0, 1, 2);
|
||||
}
|
||||
|
||||
void PageContainer::addButtons(QLayout *buttons)
|
||||
{
|
||||
m_layout->addLayout(buttons, 2, 0, 1, 2);
|
||||
}
|
||||
|
||||
void PageContainer::showPage(int row)
|
||||
{
|
||||
if (m_currentPage)
|
||||
{
|
||||
m_currentPage->closed();
|
||||
}
|
||||
if (row != -1)
|
||||
{
|
||||
m_currentPage = m_model->pages().at(row);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentPage = nullptr;
|
||||
}
|
||||
if (m_currentPage)
|
||||
{
|
||||
m_pageStack->setCurrentIndex(m_currentPage->stackIndex);
|
||||
m_header->setText(m_currentPage->displayName());
|
||||
m_iconHeader->setIcon(m_currentPage->icon());
|
||||
m_currentPage->opened();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pageStack->setCurrentIndex(0);
|
||||
m_header->setText(QString());
|
||||
m_iconHeader->setIcon(MMC->getThemedIcon("bug"));
|
||||
}
|
||||
}
|
||||
|
||||
void PageContainer::help()
|
||||
{
|
||||
if (m_currentPage)
|
||||
{
|
||||
QString pageId = m_currentPage->helpPage();
|
||||
if (pageId.isEmpty())
|
||||
return;
|
||||
QDesktopServices::openUrl(QUrl("https://github.com/MultiMC/MultiMC5/wiki/" + pageId));
|
||||
}
|
||||
}
|
||||
|
||||
void PageContainer::currentChanged(const QModelIndex ¤t)
|
||||
{
|
||||
showPage(current.isValid() ? m_proxyModel->mapToSource(current).row() : -1);
|
||||
}
|
||||
|
||||
bool PageContainer::requestClose(QCloseEvent *event)
|
||||
{
|
||||
for (auto page : m_model->pages())
|
||||
{
|
||||
if (!page->apply())
|
||||
return false;
|
||||
}
|
||||
if (m_currentPage)
|
||||
{
|
||||
m_currentPage->closed();
|
||||
}
|
||||
return true;
|
||||
}
|
63
application/widgets/PageContainer.h
Normal file
63
application/widgets/PageContainer.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include "pages/BasePageProvider.h"
|
||||
|
||||
class QLayout;
|
||||
class IconLabel;
|
||||
class QSortFilterProxyModel;
|
||||
class PageModel;
|
||||
class QLabel;
|
||||
class QListView;
|
||||
class QLineEdit;
|
||||
class QStackedLayout;
|
||||
class QGridLayout;
|
||||
|
||||
class PageContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PageContainer(BasePageProviderPtr pageProvider, QString defaultId = QString(),
|
||||
QWidget *parent = 0);
|
||||
virtual ~PageContainer() {}
|
||||
|
||||
void addButtons(QWidget * buttons);
|
||||
void addButtons(QLayout * buttons);
|
||||
bool requestClose(QCloseEvent *event);
|
||||
|
||||
private:
|
||||
void createUI();
|
||||
private
|
||||
slots:
|
||||
void currentChanged(const QModelIndex ¤t);
|
||||
void showPage(int row);
|
||||
void help();
|
||||
|
||||
private:
|
||||
BasePage * m_currentPage = 0;
|
||||
QSortFilterProxyModel *m_proxyModel;
|
||||
PageModel *m_model;
|
||||
QStackedLayout *m_pageStack;
|
||||
QLineEdit *m_filter;
|
||||
QListView *m_pageList;
|
||||
QLabel *m_header;
|
||||
IconLabel *m_iconHeader;
|
||||
QGridLayout *m_layout;
|
||||
};
|
123
application/widgets/PageContainer_p.h
Normal file
123
application/widgets/PageContainer_p.h
Normal file
@ -0,0 +1,123 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QListView>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QEvent>
|
||||
#include <QScrollBar>
|
||||
|
||||
class BasePage;
|
||||
const int pageIconSize = 24;
|
||||
|
||||
class PageViewDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
PageViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
||||
size.setHeight(qMax(size.height(), 32));
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
class PageModel : public QAbstractListModel
|
||||
{
|
||||
public:
|
||||
PageModel(QObject *parent = 0) : QAbstractListModel(parent)
|
||||
{
|
||||
QPixmap empty(pageIconSize, pageIconSize);
|
||||
empty.fill(Qt::transparent);
|
||||
m_emptyIcon = QIcon(empty);
|
||||
}
|
||||
virtual ~PageModel() {}
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const
|
||||
{
|
||||
return parent.isValid() ? 0 : m_pages.size();
|
||||
}
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
return m_pages.at(index.row())->displayName();
|
||||
case Qt::DecorationRole:
|
||||
{
|
||||
QIcon icon = m_pages.at(index.row())->icon();
|
||||
if (icon.isNull())
|
||||
icon = m_emptyIcon;
|
||||
// HACK: fixes icon stretching on windows. TODO: report Qt bug for this
|
||||
return QIcon(icon.pixmap(QSize(48,48)));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void setPages(const QList<BasePage *> &pages)
|
||||
{
|
||||
beginResetModel();
|
||||
m_pages = pages;
|
||||
endResetModel();
|
||||
}
|
||||
const QList<BasePage *> &pages() const
|
||||
{
|
||||
return m_pages;
|
||||
}
|
||||
|
||||
BasePage * findPageEntryById(QString id)
|
||||
{
|
||||
for(auto page: m_pages)
|
||||
{
|
||||
if (page->id() == id)
|
||||
return page;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QList<BasePage *> m_pages;
|
||||
QIcon m_emptyIcon;
|
||||
};
|
||||
|
||||
class PageView : public QListView
|
||||
{
|
||||
public:
|
||||
PageView(QWidget *parent = 0) : QListView(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
|
||||
setItemDelegate(new PageViewDelegate(this));
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
}
|
||||
|
||||
virtual QSize sizeHint() const
|
||||
{
|
||||
int width = sizeHintForColumn(0) + frameWidth() * 2 + 5;
|
||||
if (verticalScrollBar()->isVisible())
|
||||
width += verticalScrollBar()->width();
|
||||
return QSize(width, 100);
|
||||
}
|
||||
|
||||
virtual bool eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (obj == verticalScrollBar() &&
|
||||
(event->type() == QEvent::Show || event->type() == QEvent::Hide))
|
||||
updateGeometry();
|
||||
return QListView::eventFilter(obj, event);
|
||||
}
|
||||
};
|
129
application/widgets/ServerStatus.cpp
Normal file
129
application/widgets/ServerStatus.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
#include "ServerStatus.h"
|
||||
#include "LineSeparator.h"
|
||||
#include "IconLabel.h"
|
||||
#include "status/StatusChecker.h"
|
||||
|
||||
#include "MultiMC.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QMap>
|
||||
#include <QToolButton>
|
||||
#include <QAction>
|
||||
|
||||
ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
|
||||
{
|
||||
layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
goodIcon = MMC->getThemedIcon("status-good");
|
||||
yellowIcon = MMC->getThemedIcon("status-yellow");
|
||||
badIcon = MMC->getThemedIcon("status-bad");
|
||||
|
||||
addStatus("minecraft.net", tr("Web"));
|
||||
addLine();
|
||||
addStatus("account.mojang.com", tr("Account"));
|
||||
addLine();
|
||||
addStatus("skins.minecraft.net", tr("Skins"));
|
||||
addLine();
|
||||
addStatus("authserver.mojang.com", tr("Auth"));
|
||||
addLine();
|
||||
addStatus("sessionserver.mojang.com", tr("Session"));
|
||||
|
||||
m_statusRefresh = new QToolButton(this);
|
||||
m_statusRefresh->setCheckable(true);
|
||||
m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||
m_statusRefresh->setIcon(MMC->getThemedIcon("refresh"));
|
||||
layout->addWidget(m_statusRefresh);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
// Start status checker
|
||||
m_statusChecker.reset(new StatusChecker());
|
||||
{
|
||||
auto reloader = m_statusChecker.get();
|
||||
connect(reloader, &StatusChecker::statusChanged, this, &ServerStatus::StatusChanged);
|
||||
connect(reloader, &StatusChecker::statusLoading, this, &ServerStatus::StatusReloading);
|
||||
connect(m_statusRefresh, &QAbstractButton::clicked, this, &ServerStatus::reloadStatus);
|
||||
m_statusChecker->startTimer(60000);
|
||||
reloadStatus();
|
||||
}
|
||||
}
|
||||
|
||||
ServerStatus::~ServerStatus()
|
||||
{
|
||||
}
|
||||
|
||||
void ServerStatus::reloadStatus()
|
||||
{
|
||||
m_statusChecker->reloadStatus();
|
||||
}
|
||||
|
||||
void ServerStatus::addLine()
|
||||
{
|
||||
layout->addWidget(new LineSeparator(this, Qt::Vertical));
|
||||
}
|
||||
|
||||
void ServerStatus::addStatus(QString key, QString name)
|
||||
{
|
||||
{
|
||||
auto label = new IconLabel(this, badIcon, QSize(16, 16));
|
||||
label->setToolTip(key);
|
||||
serverLabels[key] = label;
|
||||
layout->addWidget(label);
|
||||
}
|
||||
{
|
||||
auto label = new QLabel(this);
|
||||
label->setText(name);
|
||||
label->setToolTip(key);
|
||||
layout->addWidget(label);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerStatus::setStatus(QString key, int value)
|
||||
{
|
||||
if (!serverLabels.contains(key))
|
||||
return;
|
||||
IconLabel *label = serverLabels[key];
|
||||
switch(value)
|
||||
{
|
||||
case 0:
|
||||
label->setIcon(goodIcon);
|
||||
break;
|
||||
case 1:
|
||||
label->setIcon(yellowIcon);
|
||||
break;
|
||||
default:
|
||||
case 2:
|
||||
label->setIcon(badIcon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerStatus::StatusChanged(const QMap<QString, QString> statusEntries)
|
||||
{
|
||||
auto convertStatus = [&](QString status)->int
|
||||
{
|
||||
if (status == "green")
|
||||
return 0;
|
||||
else if (status == "yellow")
|
||||
return 1;
|
||||
else if (status == "red")
|
||||
return 2;
|
||||
return 2;
|
||||
}
|
||||
;
|
||||
auto iter = statusEntries.begin();
|
||||
while (iter != statusEntries.end())
|
||||
{
|
||||
QString key = iter.key();
|
||||
auto value = convertStatus(iter.value());
|
||||
setStatus(key, value);
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerStatus::StatusReloading(bool is_reloading)
|
||||
{
|
||||
m_statusRefresh->setChecked(is_reloading);
|
||||
}
|
37
application/widgets/ServerStatus.h
Normal file
37
application/widgets/ServerStatus.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QMap>
|
||||
#include <QIcon>
|
||||
#include <memory>
|
||||
|
||||
class IconLabel;
|
||||
class QToolButton;
|
||||
class QHBoxLayout;
|
||||
class StatusChecker;
|
||||
|
||||
class ServerStatus: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ServerStatus(QWidget *parent = nullptr, Qt::WindowFlags f = 0);
|
||||
virtual ~ServerStatus();
|
||||
;
|
||||
public slots:
|
||||
void reloadStatus();
|
||||
void StatusChanged(const QMap<QString, QString> statuses);
|
||||
void StatusReloading(bool is_reloading);
|
||||
|
||||
private: /* methods */
|
||||
void addLine();
|
||||
void addStatus(QString key, QString name);
|
||||
void setStatus(QString key, int value);
|
||||
private: /* data */
|
||||
QHBoxLayout * layout = nullptr;
|
||||
QToolButton *m_statusRefresh = nullptr;
|
||||
QMap<QString, IconLabel *> serverLabels;
|
||||
QIcon goodIcon;
|
||||
QIcon yellowIcon;
|
||||
QIcon badIcon;
|
||||
std::shared_ptr<StatusChecker> m_statusChecker;
|
||||
};
|
147
application/widgets/VersionListView.cpp
Normal file
147
application/widgets/VersionListView.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QDrag>
|
||||
#include <QPainter>
|
||||
#include "VersionListView.h"
|
||||
#include "Common.h"
|
||||
|
||||
VersionListView::VersionListView(QWidget *parent)
|
||||
:QTreeView ( parent )
|
||||
{
|
||||
m_emptyString = tr("No versions are currently available.");
|
||||
}
|
||||
|
||||
void VersionListView::rowsInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
if(!m_itemCount)
|
||||
viewport()->update();
|
||||
m_itemCount += end-start+1;
|
||||
QTreeView::rowsInserted(parent, start, end);
|
||||
}
|
||||
|
||||
|
||||
void VersionListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
m_itemCount -= end-start+1;
|
||||
if(!m_itemCount)
|
||||
viewport()->update();
|
||||
QTreeView::rowsInserted(parent, start, end);
|
||||
}
|
||||
|
||||
void VersionListView::setModel(QAbstractItemModel *model)
|
||||
{
|
||||
m_itemCount = model->rowCount();
|
||||
if(!m_itemCount)
|
||||
viewport()->update();
|
||||
QTreeView::setModel(model);
|
||||
}
|
||||
|
||||
void VersionListView::reset()
|
||||
{
|
||||
if(model())
|
||||
{
|
||||
m_itemCount = model()->rowCount();
|
||||
}
|
||||
viewport()->update();
|
||||
QTreeView::reset();
|
||||
}
|
||||
|
||||
void VersionListView::setEmptyString(QString emptyString)
|
||||
{
|
||||
m_emptyString = emptyString;
|
||||
if(!m_itemCount)
|
||||
{
|
||||
viewport()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void VersionListView::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
if(m_itemCount)
|
||||
{
|
||||
QTreeView::paintEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
paintInfoLabel(event);
|
||||
}
|
||||
}
|
||||
|
||||
void VersionListView::paintInfoLabel(QPaintEvent *event)
|
||||
{
|
||||
//calculate the rect for the overlay
|
||||
QPainter painter(viewport());
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
QFont font("sans", 20);
|
||||
font.setBold(true);
|
||||
|
||||
QRect bounds = viewport()->geometry();
|
||||
bounds.moveTop(0);
|
||||
QTextLayout layout(m_emptyString, font);
|
||||
qreal height = 0.0;
|
||||
qreal widthUsed = 0.0;
|
||||
QStringList lines = viewItemTextLayout(layout, bounds.width() - 20, height, widthUsed);
|
||||
QRect rect (0,0, widthUsed, height);
|
||||
rect.setWidth(rect.width()+20);
|
||||
rect.setHeight(rect.height()+20);
|
||||
rect.moveCenter(bounds.center());
|
||||
//check if we are allowed to draw in our area
|
||||
if (!event->rect().intersects(rect)) {
|
||||
return;
|
||||
}
|
||||
//draw the letter of the topmost item semitransparent in the middle
|
||||
QColor background = QApplication::palette().color(QPalette::Foreground);
|
||||
QColor foreground = QApplication::palette().color(QPalette::Base);
|
||||
/*
|
||||
background.setAlpha(128 - scrollFade);
|
||||
foreground.setAlpha(128 - scrollFade);
|
||||
*/
|
||||
painter.setBrush(QBrush(background));
|
||||
painter.setPen(foreground);
|
||||
painter.drawRoundedRect(rect, 5.0, 5.0);
|
||||
foreground.setAlpha(190);
|
||||
painter.setPen(foreground);
|
||||
painter.setFont(font);
|
||||
painter.drawText(rect, Qt::AlignCenter, lines.join("\n"));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
void ModListView::setModel ( QAbstractItemModel* model )
|
||||
{
|
||||
QTreeView::setModel ( model );
|
||||
auto head = header();
|
||||
head->setStretchLastSection(false);
|
||||
// HACK: this is true for the checkbox column of mod lists
|
||||
auto string = model->headerData(0,head->orientation()).toString();
|
||||
if(!string.size())
|
||||
{
|
||||
head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
head->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
for(int i = 2; i < head->count(); i++)
|
||||
head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
|
||||
}
|
||||
else
|
||||
{
|
||||
head->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
for(int i = 1; i < head->count(); i++)
|
||||
head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
|
||||
}
|
||||
}
|
||||
*/
|
43
application/widgets/VersionListView.h
Normal file
43
application/widgets/VersionListView.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* Copyright 2013-2015 MultiMC Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QTreeView>
|
||||
|
||||
class Mod;
|
||||
|
||||
class VersionListView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VersionListView(QWidget *parent = 0);
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
void setEmptyString(QString emptyString);
|
||||
virtual void setModel ( QAbstractItemModel* model );
|
||||
|
||||
public slots:
|
||||
virtual void reset() override;
|
||||
|
||||
protected slots:
|
||||
virtual void rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end) override;
|
||||
virtual void rowsInserted(const QModelIndex &parent, int start, int end) override;
|
||||
|
||||
private: /* methods */
|
||||
void paintInfoLabel(QPaintEvent *event);
|
||||
|
||||
private: /* variables */
|
||||
int m_itemCount = 0;
|
||||
QString m_emptyString;
|
||||
};
|
Reference in New Issue
Block a user