Finish status pills.
This commit is contained in:
		
							
								
								
									
										30
									
								
								gui/widgets/IconLabel.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								gui/widgets/IconLabel.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #include "IconLabel.h" | ||||
|  | ||||
| #include <QStyle> | ||||
| #include <QStyleOption> | ||||
| #include <QLayout> | ||||
| #include <QPainter> | ||||
| #include <QRect> | ||||
|  | ||||
| IconLabel::IconLabel(QWidget *parent, QIcon icon, QSize size) | ||||
| 	: QWidget(parent), m_icon(icon), m_size(size) | ||||
| { | ||||
| 	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); | ||||
| 	m_icon.paint(&p, contentsRect()); | ||||
| } | ||||
							
								
								
									
										26
									
								
								gui/widgets/IconLabel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								gui/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; | ||||
| }; | ||||
							
								
								
									
										37
									
								
								gui/widgets/LineSeparator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								gui/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
									
								
								gui/widgets/LineSeparator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								gui/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::Vertical); | ||||
| 	QSize sizeHint() const; | ||||
| 	void paintEvent(QPaintEvent *); | ||||
| 	void initStyleOption(QStyleOption *option) const; | ||||
| private: | ||||
| 	Qt::Orientation m_orientation = Qt::Vertical; | ||||
| }; | ||||
| @@ -1,4 +1,6 @@ | ||||
| #include "ServerStatus.h" | ||||
| #include "LineSeparator.h" | ||||
| #include "IconLabel.h" | ||||
| #include "logic/status/StatusChecker.h" | ||||
|  | ||||
| #include "MultiMC.h" | ||||
| @@ -8,118 +10,106 @@ | ||||
| #include <QLabel> | ||||
| #include <QMap> | ||||
| #include <QToolButton> | ||||
| #include <QAction> | ||||
|  | ||||
| ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) | ||||
| 	:QWidget(parent, f) | ||||
| ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) | ||||
| { | ||||
| 	clear(); | ||||
| 	goodIcon = QPixmap(":/icons/multimc/48x48/status-good.png"); | ||||
| 	goodIcon.setDevicePixelRatio(2.0); | ||||
| 	badIcon = QPixmap(":/icons/multimc/48x48/status-bad.png"); | ||||
| 	badIcon.setDevicePixelRatio(2.0); | ||||
| 	addStatus(tr("No status available"), false); | ||||
| 	layout = new QHBoxLayout(this); | ||||
| 	layout->setContentsMargins(0, 0, 0, 0); | ||||
| 	goodIcon = QIcon::fromTheme("status-good"); | ||||
| 	badIcon = QIcon::fromTheme("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(QIcon::fromTheme("refresh")); | ||||
| 	layout->addWidget(m_statusRefresh); | ||||
|  | ||||
| 	setLayout(layout); | ||||
|  | ||||
| 	// Start status checker | ||||
| 	{ | ||||
| 		connect(MMC->statusChecker().get(), &StatusChecker::statusLoaded, this, | ||||
| 				&ServerStatus::updateStatusUI); | ||||
| 		connect(MMC->statusChecker().get(), &StatusChecker::statusLoadingFailed, this, | ||||
| 				&ServerStatus::updateStatusFailedUI); | ||||
|  | ||||
| 		auto reloader = MMC->statusChecker().get(); | ||||
| 		connect(reloader, &StatusChecker::statusChanged, this, &ServerStatus::StatusChanged); | ||||
| 		connect(reloader, &StatusChecker::statusLoading, this, &ServerStatus::StatusReloading); | ||||
| 		connect(m_statusRefresh, &QAbstractButton::clicked, this, &ServerStatus::reloadStatus); | ||||
| 		connect(&statusTimer, &QTimer::timeout, this, &ServerStatus::reloadStatus); | ||||
| 		statusTimer.setSingleShot(true); | ||||
|  | ||||
| 		MMC->statusChecker()->startTimer(60000); | ||||
| 		reloadStatus(); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| ServerStatus::addLine() | ||||
| ServerStatus::~ServerStatus() | ||||
| { | ||||
| 	auto line = new QFrame(this); | ||||
| 	line->setFrameShape(QFrame::VLine); | ||||
| 	line->setFrameShadow(QFrame::Sunken); | ||||
| 	layout->addWidget(line); | ||||
| } | ||||
|  | ||||
| ServerStatus::addStatus(QString name, bool online) | ||||
| { | ||||
| 	auto label = new QLabel(this); | ||||
| 	label->setText(name); | ||||
| 	if(online) | ||||
| 		label->setPixmap(goodIcon); | ||||
| 	else | ||||
| 		label->setPixmap(badIcon); | ||||
| 	layout->addWidget(label); | ||||
| } | ||||
|  | ||||
| ServerStatus::clear() | ||||
| { | ||||
| 	if(layout) | ||||
| 		delete layout; | ||||
| 	layout = new QHBoxLayout(this); | ||||
| } | ||||
|  | ||||
| void ServerStatus::StatusChanged(QMap<QString, QString> statusEntries) | ||||
| { | ||||
| 	clear(); | ||||
| 	int howmany = statusEntries.size(); | ||||
| 	int index = 0; | ||||
| 	auto iter = statusEntries.begin(); | ||||
| 	while (iter != statusEntries.end()) | ||||
| 	{ | ||||
| 		addStatus(); | ||||
| 		index++; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static QString convertStatus(const QString &status) | ||||
| { | ||||
| 	QString ret = "?"; | ||||
|  | ||||
| 	if (status == "green") | ||||
| 		ret = "↑"; | ||||
| 	else if (status == "yellow") | ||||
| 		ret = "-"; | ||||
| 	else if (status == "red") | ||||
| 		ret = "↓"; | ||||
|  | ||||
| 	return "<span style=\"font-size:11pt; font-weight:600;\">" + ret + "</span>"; | ||||
| } | ||||
|  | ||||
| void ServerStatus::reloadStatus() | ||||
| { | ||||
| 	m_statusRefresh->setChecked(true); | ||||
| 	MMC->statusChecker()->reloadStatus(); | ||||
| 	// updateStatusUI(); | ||||
| } | ||||
|  | ||||
| static QString makeStatusString(const QMap<QString, QString> statuses) | ||||
| void ServerStatus::addLine() | ||||
| { | ||||
| 	QString status = ""; | ||||
| 	status += "Web: " + convertStatus(statuses["minecraft.net"]); | ||||
| 	status += "  Account: " + convertStatus(statuses["account.mojang.com"]); | ||||
| 	status += "  Skins: " + convertStatus(statuses["skins.minecraft.net"]); | ||||
| 	status += "  Auth: " + convertStatus(statuses["authserver.mojang.com"]); | ||||
| 	status += "  Session: " + convertStatus(statuses["sessionserver.mojang.com"]); | ||||
|  | ||||
| 	return status; | ||||
| 	layout->addWidget(new LineSeparator(this)); | ||||
| } | ||||
|  | ||||
| void ServerStatus::updateStatusUI() | ||||
| void ServerStatus::addStatus(QString key, QString name) | ||||
| { | ||||
| 	m_statusRefresh->setChecked(false); | ||||
| 	MMC->statusChecker()->getStatusEntries(); | ||||
| 	statusTimer.start(60 * 1000); | ||||
| 	{ | ||||
| 		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::updateStatusFailedUI() | ||||
| void ServerStatus::setStatus(QString key, bool value) | ||||
| { | ||||
| 	m_statusRefresh->setChecked(false); | ||||
| 	StatusChanged(); | ||||
| 	statusTimer.start(60 * 1000); | ||||
| 	if (!serverLabels.contains(key)) | ||||
| 		return; | ||||
| 	IconLabel *label = serverLabels[key]; | ||||
| 	label->setIcon(value ? goodIcon : badIcon); | ||||
| } | ||||
|  | ||||
| void ServerStatus::StatusChanged(const QMap<QString, QString> statusEntries) | ||||
| { | ||||
| 	auto convertStatus = [&](QString status)->bool | ||||
| 	{ | ||||
| 		if (status == "green") | ||||
| 			return true; | ||||
| 		else if (status == "yellow") | ||||
| 			return false; | ||||
| 		else if (status == "red") | ||||
| 			return false; | ||||
| 		return false; | ||||
| 	} | ||||
| 	; | ||||
| 	auto iter = statusEntries.begin(); | ||||
| 	while (iter != statusEntries.end()) | ||||
| 	{ | ||||
| 		QString key = iter.key(); | ||||
| 		bool value = convertStatus(iter.value()); | ||||
| 		setStatus(key, value); | ||||
| 		iter++; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void ServerStatus::StatusReloading(bool is_reloading) | ||||
| { | ||||
| 	m_statusRefresh->setChecked(is_reloading); | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,11 @@ | ||||
| #pragma once | ||||
| #include <QString> | ||||
| #include <QWidget> | ||||
| #include <QMap> | ||||
| #include <QIcon> | ||||
| #include <memory> | ||||
|  | ||||
| class IconLabel; | ||||
| class QToolButton; | ||||
| class QHBoxLayout; | ||||
|  | ||||
| @@ -10,23 +14,21 @@ class ServerStatus: public QWidget | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	explicit ServerStatus(QWidget *parent = nullptr, Qt::WindowFlags f = 0); | ||||
| 	virtual ~ServerStatus() {}; | ||||
| 	virtual ~ServerStatus(); | ||||
| 	; | ||||
| public slots: | ||||
| 	void updateStatusUI(); | ||||
|  | ||||
| 	void updateStatusFailedUI(); | ||||
|  | ||||
| 	void reloadStatus(); | ||||
| 	void StatusChanged(); | ||||
| 	void StatusChanged(const QMap<QString, QString> statuses); | ||||
| 	void StatusReloading(bool is_reloading); | ||||
|  | ||||
| private: /* methods */ | ||||
| 	clear(); | ||||
| 	addLine(); | ||||
| 	addStatus(QString name, bool online); | ||||
| 	void addLine(); | ||||
| 	void addStatus(QString key, QString name); | ||||
| 	void setStatus(QString key, bool value); | ||||
| private: /* data */ | ||||
| 	QHBoxLayout * layout = nullptr; | ||||
| 	QToolButton *m_statusRefresh = nullptr; | ||||
| 	QPixmap goodIcon; | ||||
| 	QPixmap badIcon; | ||||
| 	QTimer statusTimer; | ||||
| 	QMap<QString, IconLabel *> serverLabels; | ||||
| 	QIcon goodIcon; | ||||
| 	QIcon badIcon; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user