Finish the Qt main menu

This commit is contained in:
Cacodemon345
2021-12-12 01:16:27 +06:00
parent 975ea07b45
commit 457751d108
9 changed files with 375 additions and 5 deletions

View File

@@ -85,6 +85,10 @@ add_library(ui STATIC
qt_models_common.cpp
qt_models_common.hpp
qt_specifydimensions.h
qt_specifydimensions.cpp
qt_specifydimensions.ui
../qt_resources.qrc
)
if (APPLE)

View File

@@ -109,7 +109,6 @@ int main(int argc, char* argv[]) {
onesec.start(1000);
/* Initialize the rendering window, or fullscreen. */
QTimer::singleShot(50, []() { plat_resize(640, 480); } );
auto main_thread = std::thread([] {
main_thread_fn();
});

View File

@@ -1,6 +1,8 @@
#include "qt_mainwindow.hpp"
#include "ui_qt_mainwindow.h"
#include "qt_specifydimensions.h"
extern "C" {
#include <86box/86box.h>
#include <86box/config.h>
@@ -22,6 +24,7 @@ extern "C" {
#include <QPushButton>
#include <QDesktopServices>
#include <QUrl>
#include <QCheckBox>
#include <array>
#include <unordered_map>
@@ -53,6 +56,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->stackedWidget->setMouseTracking(true);
ui->ogl->setRenderType(HardwareRenderer::RenderType::OpenGL);
ui->gles->setRenderType(HardwareRenderer::RenderType::OpenGLES);
statusBar()->setVisible(!hide_status_bar);
this->setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico"));
@@ -61,6 +65,18 @@ MainWindow::MainWindow(QWidget *parent) :
connect(this, &MainWindow::setTitleForNonQtThread, this, &MainWindow::setTitle_, Qt::BlockingQueuedConnection);
connect(this, &MainWindow::getTitleForNonQtThread, this, &MainWindow::getTitle_, Qt::BlockingQueuedConnection);
connect(this, &MainWindow::updateMenuResizeOptions, [this]() {
ui->actionResizable_window->setEnabled(vid_resize != 2);
ui->actionResizable_window->setChecked(vid_resize == 1);
ui->menuWindow_scale_factor->setEnabled(vid_resize == 0);
});
connect(this, &MainWindow::updateWindowRememberOption, [this]() {
ui->actionRemember_size_and_position->setChecked(window_remember);
});
emit updateMenuResizeOptions();
connect(this, &MainWindow::pollMouse, ui->stackedWidget, &RendererStack::mousePoll);
connect(this, &MainWindow::setMouseCapture, this, [this](bool state) {
@@ -84,8 +100,9 @@ MainWindow::MainWindow(QWidget *parent) :
});
connect(this, &MainWindow::resizeContents, this, [this](int w, int h) {
if (!QApplication::platformName().contains("eglfs")) {
int modifiedHeight = h + menuBar()->height() + statusBar()->height();
if (!QApplication::platformName().contains("eglfs") && vid_resize == 0) {
w = w / (!dpi_scale ? devicePixelRatio() : 1);
int modifiedHeight = (h / (!dpi_scale ? devicePixelRatio() : 1)) + menuBar()->height() + (statusBar()->height() * !hide_status_bar);
ui->stackedWidget->resize(w, h);
if (vid_resize == 0) {
setFixedSize(w, modifiedHeight);
@@ -109,8 +126,12 @@ MainWindow::MainWindow(QWidget *parent) :
ui->actionKeyboard_requires_capture->setChecked(kbd_req_capture);
ui->actionRight_CTRL_is_left_ALT->setChecked(rctrl_is_lalt);
ui->actionResizable_window->setChecked(vid_resize > 0);
ui->actionResizable_window->setChecked(vid_resize == 1);
ui->actionRemember_size_and_position->setChecked(window_remember);
ui->menuWindow_scale_factor->setEnabled(vid_resize == 0);
ui->actionHiDPI_scaling->setChecked(dpi_scale);
ui->actionHide_status_bar->setChecked(hide_status_bar);
ui->actionUpdate_status_bar_icons->setChecked(update_icons);
switch (vid_api) {
case 0:
ui->stackedWidget->setCurrentIndex(0);
@@ -212,10 +233,56 @@ MainWindow::MainWindow(QWidget *parent) :
video_setblit(qt_blit);
}
void MainWindow::closeEvent(QCloseEvent *event) {
if (confirm_exit)
{
QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", "Are you sure you want to exit 86Box?", QMessageBox::Yes | QMessageBox::No, this);
QCheckBox *chkbox = new QCheckBox("Do not ask me again");
questionbox.setCheckBox(chkbox);
chkbox->setChecked(!confirm_exit);
bool confirm_exit_temp = false;
QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) {
confirm_exit = (state == Qt::CheckState::Unchecked);
});
questionbox.exec();
if (questionbox.result() == QMessageBox::No) {
confirm_exit = true;
event->ignore();
return;
}
config_save();
}
if (window_remember) {
window_w = ui->stackedWidget->width();
window_h = ui->stackedWidget->height();
if (!QApplication::platformName().contains("wayland")) {
window_x = this->geometry().x();
window_y = this->geometry().y();
}
}
event->accept();
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::showEvent(QShowEvent *event) {
if (window_remember && !QApplication::platformName().contains("wayland")) {
setGeometry(window_x, window_y, window_w, window_h);
}
if (vid_resize == 2) {
setFixedSize(fixed_size_x, fixed_size_y + this->menuBar()->height() + this->statusBar()->height());
scrnsz_x = fixed_size_x;
scrnsz_y = fixed_size_y;
}
else if (window_remember) {
emit resizeContents(window_w, window_h);
scrnsz_x = window_w;
scrnsz_y = window_h;
}
}
void MainWindow::on_actionKeyboard_requires_capture_triggered() {
kbd_req_capture ^= 1;
}
@@ -900,6 +967,11 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event)
#endif
}
QSize MainWindow::getRenderWidgetSize()
{
return ui->stackedWidget->size();
}
void MainWindow::on_actionSoftware_Renderer_triggered() {
ui->stackedWidget->setCurrentIndex(0);
ui->actionHardware_Renderer_OpenGL->setChecked(false);
@@ -1107,7 +1179,7 @@ void MainWindow::on_actionAbout_86Box_triggered()
#ifdef EMU_GIT_HASH
githash = QString(" [%1]").arg(EMU_GIT_HASH);
#endif
msgBox.setText(QString("<b>86Box %1%2</b>").arg(EMU_VERSION_FULL, githash));
msgBox.setText(QString("<b>86Box v%1%2</b>").arg(EMU_VERSION_FULL, githash));
msgBox.setInformativeText(R"(
An emulator of old computers
@@ -1146,3 +1218,57 @@ void MainWindow::on_actionForce_4_3_display_ratio_triggered() {
video_toggle_option(ui->actionForce_4_3_display_ratio, &force_43);
video_force_resize_set(1);
}
void MainWindow::on_actionRemember_size_and_position_triggered()
{
window_remember ^= 1;
window_w = ui->stackedWidget->width();
window_h = ui->stackedWidget->height();
if (!QApplication::platformName().contains("wayland")) {
window_x = geometry().x();
window_y = geometry().y();
}
ui->actionRemember_size_and_position->setChecked(window_remember);
}
void MainWindow::on_actionSpecify_dimensions_triggered()
{
SpecifyDimensions dialog(this);
dialog.setWindowModality(Qt::WindowModal);
dialog.exec();
}
void MainWindow::on_actionHiDPI_scaling_triggered()
{
dpi_scale ^= 1;
ui->actionHiDPI_scaling->setChecked(dpi_scale);
emit resizeContents(scrnsz_x, scrnsz_y);
}
void MainWindow::on_actionHide_status_bar_triggered()
{
hide_status_bar ^= 1;
ui->actionHide_status_bar->setChecked(hide_status_bar);
statusBar()->setVisible(!hide_status_bar);
if (vid_resize >= 2) setFixedSize(fixed_size_x, fixed_size_y + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()));
else {
int vid_resize_orig = vid_resize;
vid_resize = 0;
emit resizeContents(scrnsz_x, scrnsz_y);
vid_resize = vid_resize_orig;
}
}
void MainWindow::on_actionUpdate_status_bar_icons_triggered()
{
update_icons ^= 1;
ui->actionUpdate_status_bar_icons->setChecked(update_icons);
}
void MainWindow::on_actionTake_screenshot_triggered()
{
startblit();
screenshots++;
endblit();
device_force_redraw();
}

View File

@@ -28,6 +28,7 @@ public:
void setTitle(const wchar_t* title);
void getTitle(wchar_t* title);
void blitToWidget(int x, int y, int w, int h);
QSize getRenderWidgetSize();
signals:
void paint(const QImage& image);
void resizeContents(int w, int h);
@@ -36,6 +37,8 @@ signals:
void updateStatusBarPanes();
void updateStatusBarActivity(int tag, bool active);
void updateStatusBarEmpty(int tag, bool empty);
void updateMenuResizeOptions();
void updateWindowRememberOption();
void setFullscreen(bool state);
void setMouseCapture(bool state);
@@ -82,17 +85,26 @@ private slots:
void on_actionForce_4_3_display_ratio_triggered();
void on_actionChange_contrast_for_monochrome_display_triggered();
void on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered();
void on_actionRemember_size_and_position_triggered();
void on_actionSpecify_dimensions_triggered();
void on_actionHiDPI_scaling_triggered();
void on_actionHide_status_bar_triggered();
void on_actionUpdate_status_bar_icons_triggered();
void refreshMediaMenu();
void showMessage_(const QString& header, const QString& message);
void setTitle_(const wchar_t* title);
void getTitle_(wchar_t* title);
void on_actionTake_screenshot_triggered();
protected:
void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent* event) override;
void focusInEvent(QFocusEvent* event) override;
void focusOutEvent(QFocusEvent* event) override;
bool eventFilter(QObject* receiver, QEvent* event) override;
void showEvent(QShowEvent* event) override;
void closeEvent(QCloseEvent* event) override;
private:
Ui::MainWindow *ui;

View File

@@ -78,6 +78,9 @@
<string>Tools</string>
</property>
<addaction name="actionSettings"/>
<addaction name="actionUpdate_status_bar_icons"/>
<addaction name="separator"/>
<addaction name="actionTake_screenshot"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
@@ -496,6 +499,19 @@
<string>Documentation...</string>
</property>
</action>
<action name="actionUpdate_status_bar_icons">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Update status bar icons</string>
</property>
</action>
<action name="actionTake_screenshot">
<property name="text">
<string>Take screenshot...</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@@ -0,0 +1,60 @@
#include "qt_specifydimensions.h"
#include "ui_qt_specifydimensions.h"
#include "qt_mainwindow.hpp"
#include <QStatusBar>
#include <QMenuBar>
extern "C"
{
#include <86box/86box.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/video.h>
}
extern MainWindow* main_window;
SpecifyDimensions::SpecifyDimensions(QWidget *parent) :
QDialog(parent),
ui(new Ui::SpecifyDimensions)
{
ui->setupUi(this);
ui->checkBox->setChecked(vid_resize == 2);
ui->spinBoxWidth->setRange(16, 2048 + 64);
ui->spinBoxWidth->setValue(main_window->getRenderWidgetSize().width());
ui->spinBoxHeight->setRange(16, 2048 + 64);
ui->spinBoxHeight->setValue(main_window->getRenderWidgetSize().height());
}
SpecifyDimensions::~SpecifyDimensions()
{
delete ui;
}
void SpecifyDimensions::on_SpecifyDimensions_accepted()
{
if (ui->checkBox->isChecked())
{
vid_resize = 2;
window_remember = 0;
fixed_size_x = ui->spinBoxWidth->value();
fixed_size_y = ui->spinBoxHeight->value();
main_window->setFixedSize(ui->spinBoxWidth->value(), ui->spinBoxHeight->value() + (hide_status_bar ? main_window->statusBar()->height() : 0) + main_window->menuBar()->height());
emit main_window->updateMenuResizeOptions();
}
else
{
vid_resize = 0;
window_remember = 1;
window_w = ui->spinBoxWidth->value();
window_h = ui->spinBoxHeight->value();
main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
emit main_window->resizeContents(ui->spinBoxWidth->value(), ui->spinBoxHeight->value());
vid_resize = 1;
emit main_window->updateMenuResizeOptions();
}
emit main_window->updateWindowRememberOption();
}

View File

@@ -0,0 +1,25 @@
#ifndef QT_SPECIFYDIMENSIONS_H
#define QT_SPECIFYDIMENSIONS_H
#include <QDialog>
namespace Ui {
class SpecifyDimensions;
}
class SpecifyDimensions : public QDialog
{
Q_OBJECT
public:
explicit SpecifyDimensions(QWidget *parent = nullptr);
~SpecifyDimensions();
private slots:
void on_SpecifyDimensions_accepted();
private:
Ui::SpecifyDimensions *ui;
};
#endif // QT_SPECIFYDIMENSIONS_H

View File

@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SpecifyDimensions</class>
<widget class="QDialog" name="SpecifyDimensions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>388</width>
<height>158</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>20</x>
<y>110</y>
<width>361</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QSpinBox" name="spinBoxWidth">
<property name="geometry">
<rect>
<x>70</x>
<y>50</y>
<width>81</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="labelWidth">
<property name="geometry">
<rect>
<x>30</x>
<y>50</y>
<width>41</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Width:</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox">
<property name="geometry">
<rect>
<x>20</x>
<y>90</y>
<width>131</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Lock to this size</string>
</property>
</widget>
<widget class="QLabel" name="labelHeight">
<property name="geometry">
<rect>
<x>200</x>
<y>50</y>
<width>51</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Height:</string>
</property>
</widget>
<widget class="QSpinBox" name="spinBoxHeight">
<property name="geometry">
<rect>
<x>250</x>
<y>50</y>
<width>81</width>
<height>21</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SpecifyDimensions</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SpecifyDimensions</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -109,6 +109,7 @@ ui_sb_update_icon_state(int tag, int state) {
void
ui_sb_update_icon(int tag, int active) {
if (!update_icons) return;
main_window->updateStatusBarActivity(tag, active > 0 ? true : false);
}