src/mainwindow.cpp

Sat, 08 Apr 2023 16:59:55 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Sat, 08 Apr 2023 16:59:55 +0300
changeset 355
e81f4ad53efd
parent 354
91053052bb28
child 361
c5e8b68e34f8
permissions
-rw-r--r--

Move the about dialog to MainWindow. The hack to retrieve GL extensions is made a bit cleaner

#include "src/mainwindow.h"
#include "src/modelsubwindow.h"
#include "src/version.h"
#include <QTextBrowser>
#include <QOpenGLWidget>
#include <ui_about.h>

static constexpr MemberData<MainWindow, QAction*, gl::RenderStyle> renderStyleButtons[] = {
	{ offsetof(MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal },
	{ offsetof(MainWindow, actionRenderStyleBfc), gl::RenderStyle::BfcRedGreen },
	{ offsetof(MainWindow, actionRenderStyleRandom), gl::RenderStyle::RandomColors },
	{ offsetof(MainWindow, actionRenderStylePickScene), gl::RenderStyle::PickScene },
};

MainWindow::MainWindow(QWidget *parent)
: QMainWindow{parent}
{
	this->setupUi(this);
	for (const auto& memberData : ::renderStyleButtons)
	{
		QAction* action = memberData.memberInstance(this);
		const gl::RenderStyle newStyle = memberData.payload;
		QObject::connect(action, &QAction::triggered, [this, newStyle]{
			Q_EMIT this->renderStyleSelected(newStyle);
			this->setRenderStyle(newStyle);
		});
	}
	this->connect(this->actionAbout, &QAction::triggered, this, &MainWindow::showAboutDialog);
}

void MainWindow::setRenderStyle(gl::RenderStyle style)
{
	for (const auto& memberData : ::renderStyleButtons)
	{
		QAction* const action = memberData.memberInstance(this);
		const gl::RenderStyle buttonRenderStyle = memberData.payload;
		action->setChecked(style == buttonRenderStyle);
	}
}

static QStringList getGLExtensions(QWidget* parent)
{
	// We need to have GL activated at least once in order to able to retrieve
	// GL extensions properly. To make sure this is the case, we create a
	// temporary, plain OpenGL widget. While it is active, we call glewInit().
	// If this is not done, this function will crash.
	QOpenGLWidget glWidget{parent};
	glWidget.show();
	glewInit();
	GLint numExtensions;
	glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
	QStringList extensionsList;
	for (GLint i = 0; i < numExtensions; i++) {
		const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i);
		extensionsList.push_back(reinterpret_cast<const char*>(ext));
	}
	glWidget.hide();
	return extensionsList;
}

void MainWindow::showAboutDialog()
{
	QDialog dialog{this};
	Ui_About ui;
	ui.setupUi(&dialog);
	const char* glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
	const QString extensions = getGLExtensions(this).join(" ");
	for (QTextBrowser* browser : dialog.findChildren<QTextBrowser*>()) {
		browser->setHtml(
			browser->toHtml()
			.replace("%APPNAME%", CMAKE_PROJECT_NAME)
			.replace("%COPYRIGHT%", COPYRIGHT)
			.replace("%QTVERSION%", qVersion())
			.replace("%VERSION%", detailedVersionString(QLocale::LongFormat))
			.replace("%REVDATE%", revisionDateString(QLocale::LongFormat))
			.replace("%BUILDTYPE%", CMAKE_BUILD_TYPE)
			.replace("%COMPILER_ID%", CMAKE_CXX_COMPILER_ID)
			.replace("%COMPILER_VERSION%", CMAKE_CXX_COMPILER_VERSION)
			.replace("%COMPILER_FLAGS%", CMAKE_CXX_FLAGS)
			.replace("%COMPILER_CPU%", CMAKE_SYSTEM_PROCESSOR)
			.replace("%COMPILER_SYSTEM%", CMAKE_SYSTEM)
			.replace("%GLMVERSIONSTRING%", GLM_VERSION_MESSAGE)
			.replace("%GL_VERSION%", glVersion)
			.replace("%GL_EXTENSIONS%", extensions)
		);
	}
	dialog.setWindowTitle(QObject::tr("About %1").arg(CMAKE_PROJECT_NAME));
	dialog.exec();
}

mercurial