diff options
Diffstat (limited to 'src/widget.cpp')
-rw-r--r-- | src/widget.cpp | 141 |
1 files changed, 122 insertions, 19 deletions
diff --git a/src/widget.cpp b/src/widget.cpp index a5f32fa..34684b5 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -7,6 +7,8 @@ #include <QDebug> #include <QtWidgets/QAction> #include <QAbstractItemView> +#include <QScreen> +#include <QThread> class ScreenWidget : public QWidget { @@ -16,6 +18,10 @@ public: QWidget::setStyleSheet(".QWidget { border-radius: 3px;border: 2px solid black; }"); QWidget::setLayout(new QVBoxLayout(this)); } + void setScaling(float scale) + { + this->scale = scale; + } protected: float scale; void resizeEvent(QResizeEvent *event) override @@ -59,12 +65,39 @@ static void addBoldListener(QComboBox *combo) //______________________________________________________________________________ Widget::Widget(QWidget *parent) : QWidget(parent), - _ui(new Ui::Widget) + _ui(new Ui::Widget), + _popupCount(0) { _ui->setupUi(this); setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); QTimer *top = new QTimer(this); connect(top, &QTimer::timeout, [=]() { + // Move window to current screen + QRect win = this->geometry(); + QPoint cursor = QCursor::pos(); + const QScreen *winScreen = nullptr, *mouseScreen = nullptr; + //qDebug() << "Mouse at" << cursor << " window at" << win; + for (auto screen : _qtScreens) { + QRect geo = screen->geometry(); + if (geo.contains(win)) { + winScreen = screen; + //qDebug() << "Window on screen" << geo; + } + if (geo.contains(cursor)) { + mouseScreen = screen; + //qDebug() << "Mouse on screen" << geo; + } + } + if (mouseScreen != nullptr && mouseScreen != winScreen) { + QPoint offset = mouseScreen->geometry().topLeft(); + QSize spacing = (mouseScreen->size() - this->size()) / 2; + offset.rx() += spacing.width(); + offset.ry() += spacing.height(); + this->move(offset); + } + // Raise window if appropriate + if (_popupCount > 0) + return; auto combos = this->findChildren<QComboBox*>(); for (auto combo : combos) { if (combo->view()->isVisible()) @@ -77,6 +110,22 @@ Widget::Widget(QWidget *parent) : addBoldListener(_ui->cboDualLeft); addBoldListener(_ui->cboDualRight); connectButtons(); + auto fun = [this](const QScreen *scrn) { + qDebug() << "QT SEES SCREEN" << scrn->geometry(); + _qtScreens.append(scrn); + /* + connect(scrn, &QScreen::geometryChanged, [this](const QRect &geom) { + + }); + */ + }; + for (auto scrn : QGuiApplication::screens()) { + fun(scrn); + } + connect(qApp, &QGuiApplication::screenAdded, fun); + connect(qApp, &QGuiApplication::screenRemoved, [this](const QScreen *scrn) { + _qtScreens.removeAll(scrn); + }); } //______________________________________________________________________________ @@ -178,7 +227,14 @@ void Widget::initControls() auto lists = QList<QComboBox*>({_ui->cboDualLeft, _ui->cboDualRight}); int j = 0; for (int i = 0; i < screenList.size() && j < 2; ++i) { - fillCombo(lists[j], screenList[i].modes, screenList[i].currentResolution, screenList[i].preferredResolution); + QSize selected; + if (ScreenSetup::inst()->getCurrentMode() == ScreenMode::Dual) { + // When we're not in dualhead mode, pre-select the preferred solution, so in case the user wants + // to switch to dualhead, they just need to switch to the "dual" tab and hit apply to get + // each screen configured to its preferred resolution. + selected = screenList[i].currentResolution; + } + fillCombo(lists[j], screenList[i].modes, selected, screenList[i].preferredResolution); lists[j]->setProperty("output", screenList[i].output); QLabel *sl = ( j == 0 ? _ui->lblDualLeft : _ui->lblDualRight ); sl->setText(screenList[i].output + "\n" + screenList[i].name); @@ -225,7 +281,7 @@ void Widget::initControls() res = QSize(16, 9); } AdvancedScreen *a = new AdvancedScreen(); - a->screen = new ScreenWidget(float(res.width()) / float(res.height())); + a->screen = new ScreenWidget(res.isEmpty() ? 1.33f : float(res.width()) / float(res.height())); a->desiredResolution = res; a->cboResolution = new QComboBox(); _ui->advancedContainer->addWidget(a->screen); @@ -233,12 +289,19 @@ void Widget::initControls() a->screen->layout()->addWidget(a->cboResolution); a->screen->layout()->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); positionList.append(QString::number(_advancedScreens.size())); - connect(a->cboResolution, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index) { + connect(a->cboResolution, QOverload<int>::of(&QComboBox::currentIndexChanged), [a, this](int index) { if (!_ignoreResolutionChange) { a->desiredResolution = a->cboResolution->itemData(index).toSize(); } }); addBoldListener(a->cboResolution); + connect(a->cboResolution, QOverload<int>::of(&QComboBox::currentIndexChanged), [a, this](int index) { + if (index < 0) + return; + QSize res = a->cboResolution->itemData(index).toSize(); + a->screen->setScaling(res.isEmpty() ? 1.33f : float(res.width()) / float(res.height())); + _ui->advancedContainer->update(); + }); } // Header _ui->advancedCombos->addWidget(new QLabel(tr("Output")), 0, 0); @@ -262,10 +325,10 @@ void Widget::initControls() // Logic cbo->addItems(positionList); // TODO Signal - connect(cbo, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index) { + connect(cbo, QOverload<int>::of(&QComboBox::currentIndexChanged), [a, this](int index) { a->info.position = index - 1; if (a->assignmentLabel->layout() != nullptr) { - a->assignmentLabel->layout()->removeWidget(cbo); + a->assignmentLabel->layout()->removeWidget(a->cboPosition); } if (index > 0) { _advancedScreens[index - 1]->screen->layout()->addWidget(a->assignmentLabel); @@ -318,23 +381,63 @@ void Widget::initControls() bool Widget::keepResolution() { - // Show a dialog asking if the res should be kept - TimeOutDialog keepDialog(15, this); - keepDialog.setWindowModality(Qt::ApplicationModal); - keepDialog.setWindowTitle(" "); - keepDialog.setLabelText(trUtf8("Do you want to keep this resolution?")); - keepDialog.setCancelButtonText(trUtf8("Keep")); - /* - keepDialog.move(monitorMode->width/2 - this->width()/2, - monitorMode->height/2 - this->height()); - */ - keepDialog.show(); + _popupCount += 1; + // Qt needs some time to notice the screen setup has changed + QCoreApplication::processEvents(); + QThread::msleep(10); + QCoreApplication::processEvents(); + QList<TimeOutDialog*> list; + this->setDisabled(true); + for (auto screen : _qtScreens) { + QRect geo = screen->geometry(); + bool skip = false; + // See if it overlaps with an existing screen + for (auto other : _qtScreens) { + if (other == screen) + break; + if (other->geometry().intersects(geo)) { + skip = true; + break; + } + } + if (skip) + continue; + // Show a dialog asking if the res should be kept + TimeOutDialog *keepDialog = new TimeOutDialog(15, this); + //keepDialog->setWindowModality(Qt::WindowModal); + keepDialog->setWindowTitle(" "); + keepDialog->setLabelText(trUtf8("Do you want to keep this resolution?")); + keepDialog->setCancelButtonText(trUtf8("Keep")); + keepDialog->setWindowFlag(Qt::WindowStaysOnTopHint, true); + QSize s = (geo.size() - keepDialog->size()) / 2; + QPoint tl = geo.topLeft(); + tl.rx() += s.width(); + tl.ry() += s.height(); + keepDialog->move(tl); + keepDialog->show(); + list.append(keepDialog); + } + bool wasCanceled = false; + bool active; do { + active = true; QCoreApplication::processEvents(); - } while (keepDialog.isActive()); + for (auto win : list) { + active = active && win->isActive(); + wasCanceled = wasCanceled || win->wasCanceled(); + } + } while (active && !wasCanceled); + + for (auto win : list) { + win->deleteLater(); + } + + this->setDisabled(false); + + _popupCount -= 1; - return keepDialog.wasCanceled(); + return wasCanceled; } //______________________________________________________________________________ |