Continues migration with DDS, Common
This commit is contained in:
1 parent
9b15cee841
commit
fa48db111e
668 files changed
+111841
-2
No files matched your search
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2016-11-01
|
||||
#
|
||||
|
||||
|
||||
# LtsMultiMonitor
|
||||
SET(LtsMultiMonitor_SRCS
|
||||
lts_multi_monitor_export.h
|
||||
lts_multi_monitor.cpp
|
||||
lts_dummy_widget.cpp
|
||||
lts_screen_container.cpp
|
||||
lts_multi_monitor_selector_base.cpp
|
||||
lts_screen_base.cpp
|
||||
lts_magic_corner.h
|
||||
lts_magic_corner.cpp
|
||||
|
||||
# normal screen
|
||||
lts_multi_monitor_selector_normal.cpp
|
||||
lts_screen_normal.cpp
|
||||
|
||||
# ultra wide screen
|
||||
lts_multi_monitor_selector_wide.cpp
|
||||
lts_screen_wide.cpp
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS LtsMultiMonitor SHARED ${LtsMultiMonitor_SRCS})
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsMultiMonitor
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(LtsMultiMonitor
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
Qt5::Widgets
|
||||
PRIVATE
|
||||
Qt5::Gui
|
||||
LtsWidgets
|
||||
LtsSessionData
|
||||
LtsUtilsCore
|
||||
LtsUtilsGuiDds
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(LtsMultiMonitor)
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
#include "lts_dummy_widget.h"
|
||||
|
||||
#include <LtsUtilsGui/LtsUtilsGuiDds/dds_vector_to_pixmap.h>
|
||||
|
||||
#include <QIcon>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
|
||||
FullscreenVideoDummyWidget::FullscreenVideoDummyWidget()
|
||||
{
|
||||
setWindowIcon(LtsUtils::iconFromSvg(QStringLiteral(":/style/mobile_video.svg")));
|
||||
setWindowTitle(tr("Fullscreen Video Helper"));
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FullscreenVideoDummyWidget::hideVideo()
|
||||
{
|
||||
qWarning() << "FullscreenVideoDummyWidget::hideVideo()";
|
||||
emit signalHideVideo();
|
||||
}
|
||||
|
||||
void FullscreenVideoDummyWidget::showVideo()
|
||||
{
|
||||
emit signalShowVideo();
|
||||
}
|
||||
|
||||
|
||||
bool FullscreenVideoDummyWidget::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Type::Show)
|
||||
assert(false);
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <LtsMultiMonitor/lts_multi_monitor_export.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class QEvent;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
|
||||
class LTSMULTIMONITOR_EXPORT SecondaryWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SecondaryWidget() = default;
|
||||
virtual ~SecondaryWidget() = default;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LTSMULTIMONITOR_EXPORT FullscreenVideoDummyWidget : public SecondaryWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FullscreenVideoDummyWidget();
|
||||
|
||||
void hideVideo();
|
||||
void showVideo();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *);
|
||||
|
||||
signals:
|
||||
void signalWidgetPlaced(const QRect &globalGeometry);
|
||||
void signalHideVideo();
|
||||
void signalShowVideo();
|
||||
};
|
||||
|
||||
}
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
#include "lts_magic_corner.h"
|
||||
|
||||
#include <LtsUtilsGui/LtsUtilsGuiDds/dds_vector_to_pixmap.h>
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
|
||||
#define SMOL 48
|
||||
#define SWOLE 100
|
||||
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
LtsMagicCorner::LtsMagicCorner(const QRect &neogeo)
|
||||
: m_neogeo(neogeo)
|
||||
, m_shrinkTimer(new QTimer(this))
|
||||
, m_label(new QLabel(this))
|
||||
{
|
||||
|
||||
|
||||
m_shrinkTimer->setInterval(1500ms);
|
||||
m_shrinkTimer->setSingleShot(true);
|
||||
|
||||
connect(m_shrinkTimer, &QTimer::timeout,
|
||||
this, &LtsMagicCorner::makeSmol);
|
||||
|
||||
makeSmol();
|
||||
|
||||
|
||||
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
setMouseTracking(true);
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
setWindowFlag(Qt::WindowType::WindowStaysOnTopHint);
|
||||
setWindowFlag(Qt::WindowType::X11BypassWindowManagerHint);
|
||||
activateWindow();
|
||||
|
||||
|
||||
|
||||
auto *t = new QTimer(this);
|
||||
connect(t, &QTimer::timeout,
|
||||
this, [this]()
|
||||
{
|
||||
if (!isVisible())
|
||||
return;
|
||||
|
||||
raise();
|
||||
|
||||
|
||||
|
||||
});
|
||||
t->setInterval(750ms);
|
||||
t->start();
|
||||
|
||||
|
||||
m_label->setMinimumSize(SWOLE, SWOLE);
|
||||
m_label->setMaximumSize(SWOLE, SWOLE);
|
||||
m_label->setGeometry(0, 0, SWOLE, SWOLE);
|
||||
m_label->setText(QStringLiteral("<unknown>"));
|
||||
m_label->setAlignment(Qt::AlignmentFlag::AlignCenter);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsMagicCorner::setActiveWidgetType(LtsScreenBase::WidgetType widgetType)
|
||||
{
|
||||
m_activeWidgetType = widgetType;
|
||||
if (widgetType == LtsScreenBase::WidgetType::MainWidget)
|
||||
m_label->setPixmap(m_mainPixmap);
|
||||
else
|
||||
m_label->setPixmap(m_secondaryPixmap);
|
||||
}
|
||||
|
||||
void LtsMagicCorner::setFreezed(bool freezed)
|
||||
{
|
||||
setVisible(!freezed);
|
||||
}
|
||||
|
||||
|
||||
void LtsMagicCorner::setIcon(const QIcon &icon, LtsScreenBase::WidgetType widgetType)
|
||||
{
|
||||
QPixmap p(LtsUtils::pixmapFromIcon(icon));
|
||||
|
||||
if (widgetType == LtsScreenBase::WidgetType::MainWidget)
|
||||
m_mainPixmap = p;
|
||||
else
|
||||
m_secondaryPixmap = p;
|
||||
|
||||
if (widgetType != m_activeWidgetType)
|
||||
m_label->setPixmap(p);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsMagicCorner::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
m_mousePressed = (event->button() == Qt::MouseButton::LeftButton);
|
||||
}
|
||||
|
||||
|
||||
void LtsMagicCorner::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!m_mousePressed)
|
||||
return;
|
||||
|
||||
m_mousePressed = false;
|
||||
|
||||
if (event->button() != Qt::MouseButton::LeftButton)
|
||||
return;
|
||||
|
||||
m_shrinkTimer->start();
|
||||
emit toggle();
|
||||
}
|
||||
|
||||
|
||||
void LtsMagicCorner::makeSmol()
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setGeometry(m_neogeo.x(), m_neogeo.y(), SMOL, SMOL);
|
||||
setMinimumSize(SMOL, SMOL);
|
||||
setMaximumSize(SMOL, SMOL);
|
||||
m_label->hide();
|
||||
}
|
||||
|
||||
|
||||
void LtsMagicCorner::makeSwole()
|
||||
{
|
||||
if (!isVisible())
|
||||
return;
|
||||
|
||||
setAttribute(Qt::WA_TranslucentBackground, false);
|
||||
setAttribute(Qt::WA_NoSystemBackground, false);
|
||||
setGeometry(m_neogeo.x(), m_neogeo.y(), SWOLE, SWOLE);
|
||||
setMinimumSize(SWOLE, SWOLE);
|
||||
setMaximumSize(SWOLE, SWOLE);
|
||||
m_label->show();
|
||||
m_shrinkTimer->start();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void LtsMagicCorner::mouseMoveEvent(QMouseEvent *)
|
||||
{
|
||||
|
||||
emit signalMakeAllSwole();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "lts_screen_base.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QPixmap>
|
||||
|
||||
|
||||
class QMouseEvent;
|
||||
class QPaintEvent;
|
||||
class QLabel;
|
||||
class QTimer;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LtsMagicCorner : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LtsMagicCorner(const QRect &neogeo);
|
||||
|
||||
void setIcon(const QIcon &icon, LtsScreenBase::WidgetType widgetType);
|
||||
void setActiveWidgetType(LtsScreenBase::WidgetType widgetType);
|
||||
|
||||
|
||||
void setFreezed(bool freezed);
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
signals:
|
||||
void toggle();
|
||||
void signalMakeAllSwole();
|
||||
|
||||
private slots:
|
||||
void makeSmol();
|
||||
|
||||
public slots:
|
||||
void makeSwole();
|
||||
|
||||
private:
|
||||
QRect m_neogeo;
|
||||
QTimer *m_shrinkTimer;
|
||||
bool m_mousePressed { false };
|
||||
bool m_freezed = false;
|
||||
QLabel *m_label;
|
||||
QPixmap m_mainPixmap;
|
||||
QPixmap m_secondaryPixmap;
|
||||
LtsScreenBase::WidgetType m_activeWidgetType;
|
||||
};
|
||||
}
|
||||
+696
@@ -0,0 +1,696 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_multi_monitor.h"
|
||||
#include "lts_multi_monitor_selector_normal.h"
|
||||
#include "lts_multi_monitor_selector_wide.h"
|
||||
#include "lts_screen_normal.h"
|
||||
#include "lts_screen_wide.h"
|
||||
#include "lts_dummy_widget.h"
|
||||
#include "lts_screen_container.h"
|
||||
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QPointer>
|
||||
#include <QWidget>
|
||||
#include <QRect>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QtPlatformHeaders/qwindowswindowfunctions.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
static LtsMultiMonitor *s_ltsMultiMonitor = nullptr;
|
||||
|
||||
|
||||
LtsMultiMonitor *LtsMultiMonitor::getInstance()
|
||||
{
|
||||
if (!s_ltsMultiMonitor)
|
||||
{
|
||||
s_ltsMultiMonitor = new LtsMultiMonitor;
|
||||
qAddPostRoutine(&cleanupLtsMultiMonitor);
|
||||
}
|
||||
return s_ltsMultiMonitor;
|
||||
}
|
||||
|
||||
void LtsMultiMonitor::cleanupLtsMultiMonitor()
|
||||
{
|
||||
delete s_ltsMultiMonitor;
|
||||
s_ltsMultiMonitor = nullptr;
|
||||
}
|
||||
|
||||
|
||||
LtsMultiMonitor::LtsMultiMonitor()
|
||||
: QObject(nullptr)
|
||||
, m_mainScreen(nullptr)
|
||||
, m_active(false)
|
||||
, m_initialized(false)
|
||||
, m_skipScreenId(-1)
|
||||
, m_subSkipScreenId(-1)
|
||||
|
||||
, m_overlapBaseLayouts(false)
|
||||
, m_debugMargins(false)
|
||||
{}
|
||||
|
||||
|
||||
LtsMultiMonitor::~LtsMultiMonitor()
|
||||
{
|
||||
|
||||
|
||||
|
||||
for (auto i = m_screens.begin(); i != m_screens.end(); ++i)
|
||||
{
|
||||
LtsScreenBase *screen = *i;
|
||||
disconnect(screen, &QObject::destroyed, this, &LtsMultiMonitor::screenDied);
|
||||
screen->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsMultiMonitor::screenDied()
|
||||
{
|
||||
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
void LtsMultiMonitor::init()
|
||||
{
|
||||
|
||||
if (LtsSessionData::LtsSessionData::getInstance()->isTablet())
|
||||
{
|
||||
m_overlapBaseLayouts = true;
|
||||
m_initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_initialized || !m_active)
|
||||
return;
|
||||
|
||||
QList<QScreen *> screenList = QGuiApplication::screens();
|
||||
const QScreen &mainScreen = *QGuiApplication::primaryScreen();
|
||||
|
||||
|
||||
|
||||
|
||||
for (auto i = screenList.constBegin(); i != screenList.constEnd(); ++i)
|
||||
{
|
||||
const QScreen &screen = **i;
|
||||
|
||||
|
||||
bool found = false;
|
||||
|
||||
for (LtsScreenBase *ltsScreen : qAsConst(m_screens))
|
||||
{
|
||||
if (ltsScreen->serialNumber() == screen.name())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
|
||||
int screenId = m_nextScreenId++;
|
||||
|
||||
|
||||
QRect screenGeo(screen.geometry());
|
||||
|
||||
if (screenId == m_skipScreenId)
|
||||
{
|
||||
if (m_subSkipScreenId == 0)
|
||||
{
|
||||
|
||||
QRect newScreenGeo(screenGeo);
|
||||
|
||||
newScreenGeo.moveLeft(screenGeo.x() + (screenGeo.width() / 2));
|
||||
newScreenGeo.setWidth(screenGeo.width() / 2);
|
||||
|
||||
screenGeo = newScreenGeo;
|
||||
}
|
||||
else if (m_subSkipScreenId == 1)
|
||||
{
|
||||
|
||||
QRect newScreenGeo(screenGeo);
|
||||
|
||||
newScreenGeo.setWidth(screenGeo.width() / 2);
|
||||
|
||||
screenGeo = newScreenGeo;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool isUltraWideView = (screenGeo.width() > 3000);
|
||||
|
||||
LtsScreenBase *newScreen;
|
||||
if (isUltraWideView)
|
||||
{
|
||||
newScreen = new LtsScreenWide(screenGeo, screenId, m_debugMargins, screen.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto *newScreenNormal = new LtsScreenNormal(std::move(screenGeo), screenId, m_debugMargins, screen.name());
|
||||
newScreen = newScreenNormal;
|
||||
|
||||
|
||||
connect(newScreenNormal, &LtsScreenNormal::signalMakeAllSwole,
|
||||
this, &LtsMultiMonitor::signalMakeAllSwole);
|
||||
connect(this, &LtsMultiMonitor::signalMakeAllSwole,
|
||||
newScreenNormal, &LtsScreenNormal::signalMakeSwole);
|
||||
}
|
||||
|
||||
connect(newScreen, &QObject::destroyed, this, &LtsMultiMonitor::screenDied);
|
||||
|
||||
if ((&mainScreen) == (&screen))
|
||||
m_mainScreen = newScreen;
|
||||
|
||||
m_screens.append(newScreen);
|
||||
}
|
||||
if (m_screens.isEmpty())
|
||||
{
|
||||
QMessageBox::critical(nullptr, QString(), tr("No screens found - cannot start application."));
|
||||
abort();
|
||||
}
|
||||
|
||||
if (m_mainScreen == nullptr)
|
||||
m_mainScreen = m_screens.first();
|
||||
|
||||
m_initialized = true;
|
||||
emit signalScreenCountChanged(screenCount());
|
||||
}
|
||||
|
||||
|
||||
int LtsMultiMonitor::screenCount() const
|
||||
{
|
||||
return m_screens.count();
|
||||
}
|
||||
|
||||
|
||||
bool LtsMultiMonitor::cancelAndProcessIfInactive(QWidget *widget) const
|
||||
{
|
||||
if (m_active)
|
||||
return false;
|
||||
|
||||
widget->activateWindow();
|
||||
widget->show();
|
||||
|
||||
place(widget);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LtsMultiMonitor::place(QWidget *widget)
|
||||
{
|
||||
|
||||
|
||||
auto *blw = qobject_cast<LtsWidgets::LtsBaseLayoutWidget *>(widget);
|
||||
if (blw != nullptr)
|
||||
emit blw->signalSuccessfullyPlaced();
|
||||
}
|
||||
|
||||
|
||||
bool LtsMultiMonitor::putScreen(QWidget *widget, int screenId, int screenPart)
|
||||
{
|
||||
Q_ASSERT(widget != nullptr);
|
||||
if (widget == nullptr)
|
||||
return false;
|
||||
|
||||
if (cancelAndProcessIfInactive(widget))
|
||||
return true;
|
||||
|
||||
init();
|
||||
|
||||
if (overlapBaseLayouts(widget))
|
||||
return true;
|
||||
|
||||
|
||||
bool isSecondary = isWidgetSecondary(widget);
|
||||
qWarning() << "putScreen: isSecondary" << isSecondary;
|
||||
|
||||
for (LtsScreenBase *screen : qAsConst(m_screens))
|
||||
{
|
||||
if (screen->screenId() != screenId)
|
||||
continue;
|
||||
|
||||
screen->switchToTemp(isSecondary ? LtsScreenBase::WidgetType::SecondaryWidget : LtsScreenBase::WidgetType::MainWidget);
|
||||
|
||||
try
|
||||
{
|
||||
screen->putWidget(widget, screenPart);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
screen->revertSwitch();
|
||||
|
||||
return selectScreen(widget);
|
||||
}
|
||||
|
||||
screen->check();
|
||||
|
||||
place(widget);
|
||||
screen->finalizeSwitch();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return selectScreen(widget);
|
||||
}
|
||||
|
||||
bool LtsMultiMonitor::putScreenAutomatically(QWidget *widget)
|
||||
{
|
||||
if (widget == nullptr)
|
||||
return false;
|
||||
|
||||
if (cancelAndProcessIfInactive(widget))
|
||||
return true;
|
||||
|
||||
init();
|
||||
|
||||
if (overlapBaseLayouts(widget))
|
||||
return true;
|
||||
|
||||
for (LtsScreenBase *screen : qAsConst(m_screens))
|
||||
{
|
||||
if (screen->screenId() == m_skipScreenId || !screen->isEmpty())
|
||||
continue;
|
||||
|
||||
screen->switchToTemp(LtsScreenBase::WidgetType::SecondaryWidget);
|
||||
|
||||
try
|
||||
{
|
||||
screen->putWidget(widget, 1);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
try
|
||||
{
|
||||
screen->putWidget(widget, 2);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
screen->revertSwitch();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
screen->check();
|
||||
place(widget);
|
||||
screen->finalizeSwitch();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LtsMultiMonitor::isOverlapBaseLayouts() const
|
||||
{
|
||||
return (m_overlapBaseLayouts );
|
||||
}
|
||||
|
||||
|
||||
void LtsMultiMonitor::freezeMagicCorner(int screenId)
|
||||
{
|
||||
|
||||
for (auto *screen : qAsConst(m_screens))
|
||||
{
|
||||
|
||||
if (screen->screenId() == screenId)
|
||||
{
|
||||
LtsScreenNormal* normalScreen = qobject_cast<LtsScreenNormal*>(screen);
|
||||
if(normalScreen->child()->hasMainWidget() && normalScreen->child()->hasSecondaryWidget())
|
||||
{
|
||||
normalScreen->hideMagicCorner(true);
|
||||
if(normalScreen->child()->activeWidgetType() == LtsScreenBase::WidgetType::MainWidget)
|
||||
normalScreen->child()->toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LtsMultiMonitor::unfreezeMagicCorner(int screenId)
|
||||
{
|
||||
|
||||
for (auto *screen : qAsConst(m_screens))
|
||||
{
|
||||
|
||||
if (screen->screenId() == screenId)
|
||||
{
|
||||
LtsScreenNormal* normalScreen = qobject_cast<LtsScreenNormal*>(screen);
|
||||
if(normalScreen->child()->hasMainWidget() && normalScreen->child()->hasSecondaryWidget())
|
||||
normalScreen->hideMagicCorner(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LtsMultiMonitor::overlapBaseLayouts(QWidget *widget)
|
||||
{
|
||||
if (!isOverlapBaseLayouts())
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
Q_ASSERT(qobject_cast<FullscreenVideoDummyWidget *>(widget) == nullptr);
|
||||
if (qobject_cast<FullscreenVideoDummyWidget *>(widget) != nullptr)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
widget->winId();
|
||||
QWindowsWindowFunctions::setHasBorderInFullScreen(widget->windowHandle(), true);
|
||||
#endif
|
||||
|
||||
widget->activateWindow();
|
||||
widget->showFullScreen();
|
||||
|
||||
place(widget);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LtsMultiMonitor::selectAndSwap(QWidget *widget)
|
||||
{
|
||||
if (!m_active)
|
||||
return false;
|
||||
|
||||
Q_ASSERT(!isOverlapBaseLayouts());
|
||||
if (isOverlapBaseLayouts())
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
LtsScreenContainer *oldContainer = nullptr;
|
||||
for (LtsScreenBase *_screen : qAsConst(m_screens))
|
||||
{
|
||||
try
|
||||
{
|
||||
oldContainer = _screen->containerOfWidget(widget);
|
||||
}
|
||||
catch (...){}
|
||||
}
|
||||
|
||||
if (oldContainer == nullptr)
|
||||
{
|
||||
|
||||
LtsWidgets::LtsMessageDialog::showMessage(widget, tr("Could not determine screen id for this swap!<br>Swapping not possible, please try again later."));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return selectScreen(widget, oldContainer);
|
||||
}
|
||||
|
||||
|
||||
LtsScreenBase *LtsMultiMonitor::widgetsScreen(QWidget *widget)
|
||||
{
|
||||
for (LtsScreenBase *screen : qAsConst(m_screens))
|
||||
if (screen->hasWidget(widget))
|
||||
return screen;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool LtsMultiMonitor::isWidgetSecondary(QWidget *widget)
|
||||
{
|
||||
#ifndef GUEZ_MODE
|
||||
return false;
|
||||
#endif
|
||||
|
||||
auto *blw = qobject_cast<LtsWidgets::LtsBaseLayoutWidget *>(widget);
|
||||
auto *secondaryWidget = qobject_cast<SecondaryWidget *>(widget);
|
||||
|
||||
bool isSecondaryWidget = ((blw != nullptr && blw->isSecondaryWidget()) || secondaryWidget != nullptr);
|
||||
|
||||
|
||||
|
||||
return isSecondaryWidget;
|
||||
}
|
||||
|
||||
|
||||
class StupidDeleter
|
||||
{
|
||||
public:
|
||||
explicit StupidDeleter(LtsScreenBase *screen)
|
||||
: m_screen(screen)
|
||||
{}
|
||||
|
||||
~StupidDeleter()
|
||||
{
|
||||
|
||||
if (m_screen != nullptr)
|
||||
{
|
||||
|
||||
m_screen->revertSwitch();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
|
||||
m_screen = nullptr;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LtsScreenBase *m_screen;
|
||||
};
|
||||
|
||||
|
||||
bool LtsMultiMonitor::selectScreen(QWidget *widget, LtsScreenContainer *swap, bool putOnMainIfFree, bool ltsScreenNormalOnly, const QVector<QWidget *> &irreplacableWidgets)
|
||||
{
|
||||
Q_ASSERT(widget != nullptr);
|
||||
if (widget == nullptr)
|
||||
return false;
|
||||
|
||||
if (cancelAndProcessIfInactive(widget))
|
||||
return true;
|
||||
|
||||
init();
|
||||
|
||||
if (overlapBaseLayouts(widget))
|
||||
return true;
|
||||
|
||||
bool isSecondary = isWidgetSecondary(widget);
|
||||
|
||||
|
||||
if (!isSecondary)
|
||||
{
|
||||
bool allEmpty = putOnMainIfFree;
|
||||
for (LtsScreenBase *screen : qAsConst(m_screens))
|
||||
{
|
||||
screen->switchToTemp(LtsScreenBase::WidgetType::MainWidget);
|
||||
bool isEmpty = screen->isEmpty();
|
||||
screen->revertSwitch();
|
||||
|
||||
if (isEmpty)
|
||||
continue;
|
||||
|
||||
allEmpty = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (allEmpty)
|
||||
{
|
||||
|
||||
|
||||
|
||||
m_mainScreen->switchToTemp(LtsScreenBase::WidgetType::MainWidget);
|
||||
|
||||
try
|
||||
{
|
||||
m_mainScreen->putWidget(widget);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
qWarning() << "failed - reverting";
|
||||
m_mainScreen->revertSwitch();
|
||||
|
||||
Q_ASSERT_X(false, __FUNCTION__, "screen promised to be empty but 'putWidgetSomewhere' method failed regardless");
|
||||
|
||||
|
||||
auto *blw = qobject_cast<LtsWidgets::LtsBaseLayoutWidget *>(widget);
|
||||
if (blw != nullptr)
|
||||
emit blw->signalClose();
|
||||
else
|
||||
widget->deleteLater();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_mainScreen->check();
|
||||
place(widget);
|
||||
m_mainScreen->finalizeSwitch();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto *selectionProcessWatcher = new QObject;
|
||||
|
||||
|
||||
bool minOnce = false;
|
||||
|
||||
for (auto i = m_screens.begin(); i != m_screens.end(); ++i)
|
||||
{
|
||||
LtsScreenBase *screen = *i;
|
||||
|
||||
screen->switchToTemp(isSecondary ? LtsScreenBase::WidgetType::SecondaryWidget : LtsScreenBase::WidgetType::MainWidget);
|
||||
|
||||
StupidDeleter _(screen);
|
||||
|
||||
if (screen->isIrreplaceable())
|
||||
{
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
bool skip = false;
|
||||
for (QWidget *widget : qAsConst(irreplacableWidgets))
|
||||
{
|
||||
|
||||
if (screen->hasWidget(widget))
|
||||
{
|
||||
|
||||
skip = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (skip)
|
||||
continue;
|
||||
|
||||
MultiMonitorSelectorBase *mms;
|
||||
if (qobject_cast<LtsScreenNormal *>(screen) != nullptr)
|
||||
{
|
||||
auto *screenNormal = static_cast<LtsScreenNormal *>(screen);
|
||||
mms = new MultiMonitorSelectorNormal(screenNormal, isSecondary, irreplacableWidgets);
|
||||
}
|
||||
else if (qobject_cast<LtsScreenWide *>(screen) != nullptr && !ltsScreenNormalOnly)
|
||||
{
|
||||
auto *screenWide = static_cast<LtsScreenWide *>(screen);
|
||||
mms = new MultiMonitorSelectorWide(screenWide, nullptr, irreplacableWidgets);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
QPointer<QWidget> widgetPtr(widget);
|
||||
|
||||
|
||||
connect(widget, &QWidget::destroyed,
|
||||
mms, &MultiMonitorSelectorBase::close);
|
||||
connect(mms, &MultiMonitorSelectorBase::rejected,
|
||||
this, [widgetPtr, swap]()
|
||||
{
|
||||
|
||||
|
||||
if (!widgetPtr || swap != nullptr)
|
||||
return;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
auto *blw = qobject_cast<LtsWidgets::LtsBaseLayoutWidget *>(widgetPtr.data());
|
||||
if (blw != nullptr)
|
||||
emit blw->signalClose();
|
||||
else
|
||||
widgetPtr->deleteLater();
|
||||
});
|
||||
connect(mms, &MultiMonitorSelectorBase::signalSelected,
|
||||
this, [this, mms, widgetPtr]()
|
||||
{
|
||||
|
||||
|
||||
for (LtsScreenBase *screen : qAsConst(m_screens))
|
||||
screen->check();
|
||||
|
||||
|
||||
|
||||
if (widgetPtr)
|
||||
place(widgetPtr.data());
|
||||
|
||||
|
||||
|
||||
mms->deleteLater();
|
||||
emit signalSelected();
|
||||
|
||||
|
||||
});
|
||||
connect(mms, &MultiMonitorSelectorBase::destroyed,
|
||||
selectionProcessWatcher, &QObject::deleteLater);
|
||||
connect(selectionProcessWatcher, &QObject::destroyed,
|
||||
mms, &MultiMonitorSelectorBase::close);
|
||||
|
||||
mms->setSwap(swap);
|
||||
mms->setWidget(widget);
|
||||
mms->show();
|
||||
_.reset();
|
||||
minOnce = true;
|
||||
}
|
||||
|
||||
if (!minOnce)
|
||||
{
|
||||
selectionProcessWatcher->deleteLater();
|
||||
auto *blw = qobject_cast<LtsWidgets::LtsBaseLayoutWidget *>(widget);
|
||||
if (blw != nullptr)
|
||||
emit blw->signalClose();
|
||||
else
|
||||
widget->deleteLater();
|
||||
|
||||
LtsWidgets::LtsMessageDialog::showMessage(m_mainScreen->screenDialog(), tr("There are no free screens available to select from."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include "lts_multi_monitor_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LtsScreenBase;
|
||||
class MultiMonitorSelectorBase;
|
||||
class LtsScreenContainer;
|
||||
|
||||
|
||||
class LTSMULTIMONITOR_EXPORT LtsMultiMonitor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static LtsMultiMonitor *getInstance();
|
||||
|
||||
|
||||
|
||||
bool selectScreen(QWidget *widget, LtsScreenContainer *swap = nullptr, bool putOnMainIfFree = true, bool ltsScreenNormalOnly = false, const QVector<QWidget *> &irreplacableWidgets = {});
|
||||
bool selectAndSwap(QWidget *widget);
|
||||
|
||||
|
||||
void setEnableMultiMonitorMode() { m_active = true; }
|
||||
void setDebugMultiMonitorMode() { m_debugMargins = true; }
|
||||
bool isActive() const { return m_active; }
|
||||
|
||||
LtsScreenBase *widgetsScreen(QWidget *widget);
|
||||
|
||||
|
||||
|
||||
|
||||
void freezeMagicCorner(int screenId);
|
||||
void unfreezeMagicCorner(int screenId);
|
||||
|
||||
bool putScreen(QWidget *widget, int screenId, int screenPart);
|
||||
bool putScreenAutomatically(QWidget *widget);
|
||||
static void place(QWidget *widget);
|
||||
void setSkipScreen(int screenId, int subScreenId = -1) { m_skipScreenId = screenId; m_subSkipScreenId = subScreenId; }
|
||||
LtsScreenBase *mainScreen() const { return m_mainScreen; }
|
||||
int screenCount() const;
|
||||
|
||||
private slots:
|
||||
void screenDied();
|
||||
|
||||
private:
|
||||
LtsMultiMonitor();
|
||||
~LtsMultiMonitor();
|
||||
static void cleanupLtsMultiMonitor();
|
||||
void init();
|
||||
bool cancelAndProcessIfInactive(QWidget *widget) const;
|
||||
static bool isWidgetSecondary(QWidget *widget) ;
|
||||
|
||||
|
||||
|
||||
bool overlapBaseLayouts(QWidget *widget);
|
||||
bool isOverlapBaseLayouts() const;
|
||||
|
||||
QVector<LtsScreenBase *> m_screens;
|
||||
int m_nextScreenId { 0 };
|
||||
LtsScreenBase *m_mainScreen;
|
||||
bool m_active;
|
||||
bool m_initialized;
|
||||
int m_skipScreenId;
|
||||
int m_subSkipScreenId;
|
||||
|
||||
bool m_overlapBaseLayouts;
|
||||
bool m_debugMargins;
|
||||
|
||||
signals:
|
||||
void signalQuitLoop();
|
||||
void signalSelected();
|
||||
void signalScreenCountChanged(int);
|
||||
void signalMakeAllSwole();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef LTSMULTIMONITOR_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define LTSMULTIMONITOR_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_LTSMULTIMONITOR_LIB)
|
||||
# define LTSMULTIMONITOR_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define LTSMULTIMONITOR_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,419 @@
|
||||
|
||||
|
||||
#include "lts_multi_monitor_selector_base.h"
|
||||
#include "lts_multi_monitor.h"
|
||||
#include "lts_screen_base.h"
|
||||
#include "lts_screen_container.h"
|
||||
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
#include <LtsUtilsCore/promise.h>
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QCloseEvent>
|
||||
#include <QStyle>
|
||||
#include <QRect>
|
||||
#include <QSize>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QColor>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
int MultiMonitorSelectorBase::s_margin = 10;
|
||||
int MultiMonitorSelectorBase::s_offset = 6;
|
||||
int MultiMonitorSelectorBase::s_buttonSize = 20;
|
||||
|
||||
|
||||
MultiMonitorSelectorBase::MultiMonitorSelectorBase(LtsScreenBase *screen, const QVector<QWidget *> &irreplacableWidgets, QWidget *)
|
||||
: QDialog(nullptr)
|
||||
, m_irreplacableWidgets(irreplacableWidgets)
|
||||
, m_screen(screen)
|
||||
, m_screenIsIrreplaceable(screen->isIrreplaceable())
|
||||
{
|
||||
setGeometry(screen->screenRect());
|
||||
setMouseTracking(true);
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint );
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
|
||||
bool MultiMonitorSelectorBase::isNullSwap(LtsScreenContainer *container)
|
||||
{
|
||||
if (container == m_swap)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorBase::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
|
||||
|
||||
qWarning() << "closeEvent";
|
||||
|
||||
if (!m_selected && !m_reverted)
|
||||
{
|
||||
qWarning() << "closeEvent: not selected and not reverted! reverting!";
|
||||
m_screen->revertSwitch();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
||||
bool MultiMonitorSelectorBase::killOrSwapOldBLW(LtsScreenContainer *container ) noexcept(false)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (isNullSwap(container))
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_swap != nullptr)
|
||||
{
|
||||
QWidget *oldSwapWidget;
|
||||
try
|
||||
{
|
||||
|
||||
oldSwapWidget = m_swap->stealWidget();
|
||||
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!container->isEmpty())
|
||||
{
|
||||
|
||||
QWidget *oldContainerWidget;
|
||||
try
|
||||
{
|
||||
|
||||
oldContainerWidget = container->stealWidget();
|
||||
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
|
||||
m_swap->setWidget(oldContainerWidget);
|
||||
}
|
||||
|
||||
|
||||
|
||||
container->setWidget(oldSwapWidget);
|
||||
|
||||
|
||||
if(m_swap->activeWidgetType() == LtsScreenBase::WidgetType::SecondaryWidget && !m_swap->hasSecondaryWidget() && m_swap->hasMainWidget())
|
||||
m_swap->toggle();
|
||||
else if(m_swap->activeWidgetType() == LtsScreenBase::WidgetType::MainWidget && !m_swap->hasMainWidget() && m_swap->hasSecondaryWidget())
|
||||
m_swap->toggle();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QWidget *oldWidget;
|
||||
try
|
||||
{
|
||||
|
||||
oldWidget = container->widget();
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
auto *oldBLW = qobject_cast<LtsWidgets::LtsBaseLayoutWidget *>(oldWidget);
|
||||
|
||||
if (oldBLW == nullptr)
|
||||
{
|
||||
container->stealWidget()->deleteLater();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!oldBLW->slotClose())
|
||||
{
|
||||
|
||||
throw "MultiMonitorSelectorBase::killOrSwapOldBLW: failed to close old blw";
|
||||
}
|
||||
|
||||
container->stealWidget();
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorBase::setWidget(QWidget *widget)
|
||||
{
|
||||
m_widget = widget;
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorBase::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
m_cursorPos = event->pos();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorBase::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
const QRect abortButtonRect(QRect(centeredRect().topRight() + QPoint(s_buttonSize, s_buttonSize), QSize(s_buttonSize, s_buttonSize)));
|
||||
auto pos = event->pos();
|
||||
|
||||
Q_ASSERT(m_widget != nullptr);
|
||||
|
||||
|
||||
if (abortButtonRect.contains(pos) || m_widget == nullptr)
|
||||
{
|
||||
qWarning() << "X pressed!";
|
||||
m_reverted = true;
|
||||
m_screen->revertSwitch();
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
|
||||
if (processSelection(pos))
|
||||
{
|
||||
qWarning() << "process!";
|
||||
m_screen->finalizeSwitch();
|
||||
selected();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorBase::selected()
|
||||
{
|
||||
m_widget = nullptr;
|
||||
m_selected = true;
|
||||
emit signalSelected();
|
||||
}
|
||||
|
||||
|
||||
QRect MultiMonitorSelectorBase::centeredRect() const
|
||||
{
|
||||
|
||||
if (m_cachedCenteredRect.isValid())
|
||||
return m_cachedCenteredRect;
|
||||
|
||||
|
||||
const QSize thisSize(size());
|
||||
const QSize newSize(thisSize.width() * 0.20, thisSize.height() * 0.20);
|
||||
m_cachedCenteredRect = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, newSize, rect());
|
||||
|
||||
return m_cachedCenteredRect;
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorBase::setColors(QPainter &p, const QRect checkSelection, bool occupied, bool countEdge)
|
||||
{
|
||||
if (occupied)
|
||||
{
|
||||
p.setBrush(QColor("silver"));
|
||||
p.setPen(QPen(QColor("white"), 2));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (checkSelection.contains(m_cursorPos, countEdge))
|
||||
{
|
||||
|
||||
p.setBrush(QColor("grey"));
|
||||
p.setPen(QPen(QColor("white"), 2));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
p.setBrush(QColor("black"));
|
||||
p.setPen(QPen(p.brush(), 1));
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorBase::drawBase(QPainter &p, bool drawSelector, bool occupied, bool isSecondary, bool isInactiveWidgetOccupied)
|
||||
{
|
||||
bool showReplacementIndicator = true;
|
||||
#ifndef GUEZ_MODE
|
||||
isSecondary = false;
|
||||
showReplacementIndicator = false;
|
||||
#endif
|
||||
|
||||
|
||||
p.save();
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
|
||||
|
||||
|
||||
p.setBrush(QColor(53, 53, 53, 150));
|
||||
p.drawRect(geometry());
|
||||
|
||||
|
||||
|
||||
const QRect centered(centeredRect());
|
||||
p.setBrush(QColor("silver"));
|
||||
p.setPen(QPen(QColor("black"), 0.5));
|
||||
|
||||
|
||||
|
||||
if (isSecondary && isInactiveWidgetOccupied)
|
||||
{
|
||||
const QRect r(centered.adjusted(12, 12, 12, 12));
|
||||
setColors(p, r, true);
|
||||
p.drawRoundedRect(r, 7, 7);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (drawSelector)
|
||||
{
|
||||
if (!m_screenIsIrreplaceable)
|
||||
{
|
||||
|
||||
setColors(p, centered, occupied);
|
||||
}
|
||||
|
||||
p.drawRoundedRect(centered, 7, 7);
|
||||
}
|
||||
|
||||
|
||||
const int cX = centered.x();
|
||||
const int cW = centered.width();
|
||||
const int cY = centered.y();
|
||||
const int cH = centered.height();
|
||||
|
||||
|
||||
|
||||
if (isSecondary)
|
||||
{
|
||||
QPen pen(p.pen());
|
||||
QColor pc(pen.color());
|
||||
const QColor c(255 - pc.red(), 255 - pc.green(), 255 - pc.blue());
|
||||
pen.setColor(c);
|
||||
p.setPen(pen);
|
||||
|
||||
QFont f(p.font());
|
||||
f.setBold(true);
|
||||
f.setPixelSize(cH / 2);
|
||||
p.setFont(f);
|
||||
|
||||
const QString text(tr("S", "Secondary (German: 'H' for 'Hilfsansicht')"));
|
||||
|
||||
p.drawText(centered, Qt::AlignCenter, text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const QRect abortButtonRect(QRect(centered.topRight() + QPoint(s_buttonSize, s_buttonSize), QSize(s_buttonSize, s_buttonSize)));
|
||||
const QPoint topRight(abortButtonRect.topLeft() );
|
||||
setColors(p, abortButtonRect, false, false);
|
||||
|
||||
QPen pen(p.pen());
|
||||
pen.setWidth(5.0);
|
||||
p.setPen(pen);
|
||||
|
||||
p.drawLines(QVector<QLine>()
|
||||
<< QLine(topRight , topRight + QPoint(s_buttonSize, s_buttonSize))
|
||||
<< QLine(topRight + QPoint(0, s_buttonSize), topRight + QPoint(s_buttonSize, 0))
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (showReplacementIndicator && occupied)
|
||||
{
|
||||
p.setBrush(QColor("silver"));
|
||||
p.setPen(QPen(QColor("white"), 2));
|
||||
|
||||
const QRect secondRect(centered.adjusted(cW + 70, 0, cW + 70, 0));
|
||||
p.drawRoundedRect(secondRect, 7, 7);
|
||||
|
||||
|
||||
p.drawLine(cX + cW + 15, cY + (cH / 2),
|
||||
cX + cW + 55, cY + (cH / 2));
|
||||
|
||||
|
||||
p.drawPolygon(QPolygon(
|
||||
{
|
||||
QPoint(cX + cW + 56, cY + (cH / 2)),
|
||||
QPoint(cX + cW + 46, cY + (cH / 2) - 10),
|
||||
QPoint(cX + cW + 46, cY + (cH / 2) + 10),
|
||||
}));
|
||||
|
||||
const int srX = secondRect.x();
|
||||
const int srY = secondRect.y();
|
||||
const int srH = secondRect.height();
|
||||
const int diameter = srH - 50;
|
||||
const int widthByTwo = (secondRect.width() / 2);
|
||||
const int diameterByTwo = (diameter / 2);
|
||||
const int lineX1 = srX + widthByTwo - diameterByTwo;
|
||||
const int lineY1 = srY + 25;
|
||||
|
||||
p.drawEllipse(lineX1, lineY1, diameter, diameter);
|
||||
|
||||
|
||||
if (isSecondary)
|
||||
{
|
||||
QFont f(p.font());
|
||||
f.setBold(true);
|
||||
f.setPixelSize(srH / 2);
|
||||
p.setFont(f);
|
||||
|
||||
const QString text(tr("S", "Secondary (German: 'H' for 'Hilfsansicht')"));
|
||||
|
||||
p.drawText(secondRect, Qt::AlignCenter, text);
|
||||
}
|
||||
|
||||
|
||||
const int lineX2 = lineX1 + diameter;
|
||||
const int lineY2 = lineY1 + diameter;
|
||||
p.drawLine(lineX1, lineY1, lineX2, lineY2);
|
||||
p.drawLine(lineX2, lineY1, lineX1, lineY2);
|
||||
}
|
||||
|
||||
|
||||
p.restore();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
class QScreen;
|
||||
class QPainter;
|
||||
class QPaintEvent;
|
||||
class QMouseEvent;
|
||||
class QCloseEvent;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LtsScreenBase;
|
||||
class LtsScreenContainer;
|
||||
|
||||
class MultiMonitorSelectorBase : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultiMonitorSelectorBase(LtsScreenBase *screen, const QVector<QWidget *> &irreplacableWidgets, QWidget *);
|
||||
virtual ~MultiMonitorSelectorBase() {}
|
||||
|
||||
void setSwap(LtsScreenContainer *swap) { m_swap = swap; }
|
||||
void setWidget(QWidget *widget);
|
||||
LtsScreenBase *screen() const { return m_screen; }
|
||||
|
||||
signals:
|
||||
void signalSelected();
|
||||
|
||||
protected:
|
||||
static int s_offset;
|
||||
static int s_margin;
|
||||
static int s_buttonSize;
|
||||
|
||||
LtsScreenContainer *m_swap { nullptr };
|
||||
QWidget *m_widget { nullptr };
|
||||
mutable QRect m_cachedCenteredRect;
|
||||
QVector<QWidget *> m_irreplacableWidgets;
|
||||
|
||||
void drawBase(QPainter &p, bool drawSelector = true, bool occupied = false, bool isSecondary = false, bool isInactiveWidgetOccupied = false);
|
||||
bool killOrSwapOldBLW(LtsScreenContainer *container) noexcept(false);
|
||||
bool isNullSwap(LtsScreenContainer *container);
|
||||
QRect centeredRect() const;
|
||||
void setColors(QPainter &p, const QRect checkSelection, bool occupied = false, bool countEdge = false);
|
||||
void selected();
|
||||
virtual bool processSelection(const QPoint &selection) = 0;
|
||||
|
||||
private:
|
||||
QPoint m_cursorPos;
|
||||
bool m_selected { false };
|
||||
LtsScreenBase *m_screen;
|
||||
bool m_screenIsIrreplaceable;
|
||||
bool m_reverted { false };
|
||||
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
|
||||
#include "lts_multi_monitor.h"
|
||||
#include "lts_multi_monitor_selector_normal.h"
|
||||
#include "lts_screen_container.h"
|
||||
#include "lts_screen_normal.h"
|
||||
#include "lts_dummy_widget.h"
|
||||
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QStyle>
|
||||
#include <QRect>
|
||||
#include <QSize>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QColor>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
|
||||
MultiMonitorSelectorNormal::MultiMonitorSelectorNormal(LtsScreenNormal *screen, bool isSecondary, const QVector<QWidget *> &irreplacableWidgets)
|
||||
: MultiMonitorSelectorBase(screen, irreplacableWidgets, nullptr)
|
||||
, m_screen(screen)
|
||||
, m_screenIsEmpty(screen->isEmpty())
|
||||
, m_isSecondary(isSecondary)
|
||||
, m_isInactiveWidgetOccupied(screen->child()->isInactiveWidgetOccupied())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
MultiMonitorSelectorNormal::~MultiMonitorSelectorNormal()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool MultiMonitorSelectorNormal::processSelection(const QPoint &selection)
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (!centeredRect().contains(selection))
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_screen->isIrreplaceable())
|
||||
{
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (m_irreplacableWidgets.contains(m_screen->child()->widget()))
|
||||
return false;
|
||||
}
|
||||
catch(...){}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (killOrSwapOldBLW(m_screen->child()))
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
m_screen->putWidgetUnmanaged(m_widget);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorNormal::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
drawBase(p, true, !m_screenIsEmpty, m_isSecondary, m_isInactiveWidgetOccupied);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "lts_multi_monitor_selector_base.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
class QScreen;
|
||||
class QPaintEvent;
|
||||
class QMouseEvent;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LtsScreenBase;
|
||||
class LtsScreenNormal;
|
||||
|
||||
class MultiMonitorSelectorNormal : public MultiMonitorSelectorBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultiMonitorSelectorNormal(LtsScreenNormal *screen, bool isSecondary, const QVector<QWidget *> &irreplacableWidgets = {});
|
||||
~MultiMonitorSelectorNormal();
|
||||
|
||||
private:
|
||||
LtsScreenNormal *m_screen;
|
||||
bool m_screenIsEmpty;
|
||||
bool m_isSecondary;
|
||||
bool m_isInactiveWidgetOccupied;
|
||||
|
||||
bool processSelection(const QPoint &selection) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
|
||||
|
||||
#include "lts_multi_monitor.h"
|
||||
#include "lts_multi_monitor_selector_wide.h"
|
||||
#include "lts_screen_container.h"
|
||||
#include "lts_screen_wide.h"
|
||||
|
||||
#include <QPaintEvent>
|
||||
#include <QStyle>
|
||||
#include <QRect>
|
||||
#include <QSize>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QColor>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
|
||||
MultiMonitorSelectorWide::MultiMonitorSelectorWide(LtsScreenWide *screen, QWidget *, const QVector<QWidget *> &irreplacableWidgets)
|
||||
: MultiMonitorSelectorBase(screen, irreplacableWidgets, nullptr )
|
||||
, m_screen(screen)
|
||||
{}
|
||||
|
||||
|
||||
bool MultiMonitorSelectorWide::isDrawOnlyOneSelector()
|
||||
{
|
||||
|
||||
|
||||
|
||||
bool res = ((m_screen->childMain()->isEmpty() && m_screen->childLeft()->isEmpty() && m_screen->childRight()->isEmpty())
|
||||
|| (!m_screen->childMain()->isEmpty() && m_swap != nullptr && m_screen->childMain() == m_swap));
|
||||
|
||||
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
bool MultiMonitorSelectorWide::processSelection(const QPoint &selection)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LtsScreenContainer *main = m_screen->childMain();
|
||||
LtsScreenContainer *left = m_screen->childLeft();
|
||||
LtsScreenContainer *right = m_screen->childRight();
|
||||
|
||||
bool singleSelector = isDrawOnlyOneSelector();
|
||||
|
||||
if (singleSelector)
|
||||
{
|
||||
if (main->isIrreplaceable())
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (m_irreplacableWidgets.contains(main->widget()))
|
||||
return false;
|
||||
}
|
||||
catch(...){}
|
||||
|
||||
|
||||
|
||||
if (isNullSwap(m_screen->childMain()))
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (centeredRect().contains(selection))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (killOrSwapOldBLW(m_screen->childMain()))
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_screen->putWidgetUnmanagedMain(m_widget);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool leftContains = leftSide().contains(selection);
|
||||
bool rightContains = rightSide().contains(selection);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (leftContains)
|
||||
{
|
||||
if (left->isIrreplaceable())
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (m_irreplacableWidgets.contains(left->widget()))
|
||||
return false;
|
||||
}
|
||||
catch(...){}
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
QWidget *oldWidget = main->stealWidget();
|
||||
|
||||
|
||||
m_screen->putWidgetUnmanagedRight(oldWidget);
|
||||
}
|
||||
catch (...) {}
|
||||
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (killOrSwapOldBLW(left))
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_screen->putWidgetUnmanagedLeft(m_widget);
|
||||
return true;
|
||||
}
|
||||
else if (rightContains)
|
||||
{
|
||||
if (right->isIrreplaceable())
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (m_irreplacableWidgets.contains(right->widget()))
|
||||
return false;
|
||||
}
|
||||
catch(...){}
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
QWidget *oldWidget = main->stealWidget();
|
||||
|
||||
|
||||
m_screen->putWidgetUnmanagedLeft(oldWidget);
|
||||
}
|
||||
catch (...) {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (killOrSwapOldBLW(right))
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_screen->putWidgetUnmanagedRight(m_widget);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QRect MultiMonitorSelectorWide::leftSide() const
|
||||
{
|
||||
QRect centered = centeredRect();
|
||||
|
||||
return QRect(centered.x() + s_margin,
|
||||
centered.y() + s_margin,
|
||||
(centered.width() / 2) - (s_margin*2),
|
||||
centered.height() - (s_margin*2));
|
||||
}
|
||||
|
||||
|
||||
QRect MultiMonitorSelectorWide::rightSide() const
|
||||
{
|
||||
QRect centered = centeredRect();
|
||||
|
||||
return QRect(centered.x() + (centered.width() / 2) + s_margin,
|
||||
centered.y() + s_margin,
|
||||
(centered.width() / 2) - (s_margin*2),
|
||||
centered.height() - (s_margin*2));
|
||||
}
|
||||
|
||||
|
||||
void MultiMonitorSelectorWide::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.save();
|
||||
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
|
||||
const QRect centered(centeredRect());
|
||||
|
||||
bool drawOnlyOneSelector = isDrawOnlyOneSelector();
|
||||
drawBase(p, drawOnlyOneSelector, false );
|
||||
|
||||
|
||||
|
||||
if (!drawOnlyOneSelector)
|
||||
{
|
||||
p.setBrush(QColor("silver"));
|
||||
p.setPen(QPen(QColor("black"), 0.5));
|
||||
p.drawRoundedRect(centered, 7, 7);
|
||||
|
||||
|
||||
bool leftIrreplacable = false;
|
||||
try
|
||||
{
|
||||
leftIrreplacable = m_irreplacableWidgets.contains(m_screen->childLeft()->widget());
|
||||
}
|
||||
catch(...){}
|
||||
|
||||
if (!m_screen->childLeft()->isIrreplaceable() && !leftIrreplacable)
|
||||
{
|
||||
|
||||
const QRect leftSide(centered.x() + s_margin,
|
||||
centered.y() + s_margin,
|
||||
(centered.width() / 2) - (s_margin*2),
|
||||
centered.height() - (s_margin*2));
|
||||
|
||||
setColors(p, leftSide, !m_screen->childLeft()->isEmpty());
|
||||
|
||||
p.drawRoundedRect(leftSide, 6, 6);
|
||||
}
|
||||
|
||||
|
||||
bool rightIrreplacable = false;
|
||||
try
|
||||
{
|
||||
rightIrreplacable = m_irreplacableWidgets.contains(m_screen->childRight()->widget());
|
||||
}
|
||||
catch(...){}
|
||||
|
||||
if (!m_screen->childRight()->isIrreplaceable() && !rightIrreplacable)
|
||||
{
|
||||
|
||||
const QRect rightSide(centered.x() + (centered.width() / 2) + s_margin,
|
||||
centered.y() + s_margin,
|
||||
(centered.width() / 2) - (s_margin*2),
|
||||
centered.height() - (s_margin*2));
|
||||
|
||||
setColors(p, rightSide, !m_screen->childRight()->isEmpty());
|
||||
|
||||
p.drawRoundedRect(rightSide, 6, 6);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int buttonSize = 20;
|
||||
const QRect abortButtonRect(QRect(centered.topRight() + QPoint(buttonSize, buttonSize), QSize(buttonSize, buttonSize)));
|
||||
const QPoint topRight(abortButtonRect.topLeft() );
|
||||
setColors(p, abortButtonRect, false, false);
|
||||
|
||||
|
||||
QPen pen(p.pen());
|
||||
pen.setWidth(5.0);
|
||||
p.setPen(pen);
|
||||
|
||||
p.drawLines(QVector<QLine>()
|
||||
<< QLine(topRight , topRight + QPoint(buttonSize, buttonSize))
|
||||
<< QLine(topRight + QPoint(0, buttonSize), topRight + QPoint(buttonSize, 0))
|
||||
);
|
||||
|
||||
|
||||
p.restore();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "LtsMultiMonitor/lts_multi_monitor_selector_base.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
|
||||
|
||||
class QScreen;
|
||||
class QPaintEvent;
|
||||
class QMouseEvent;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LtsScreenWide;
|
||||
class LtsScreenBase;
|
||||
|
||||
class MultiMonitorSelectorWide : public MultiMonitorSelectorBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultiMonitorSelectorWide(LtsScreenWide *screen, QWidget *superParent, const QVector<QWidget *> &irreplacableWidgets);
|
||||
|
||||
private:
|
||||
LtsScreenWide *m_screen;
|
||||
|
||||
bool isDrawOnlyOneSelector();
|
||||
QRect leftSide() const;
|
||||
QRect rightSide() const;
|
||||
bool processSelection(const QPoint &selection) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
};
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
#include "lts_screen_base.h"
|
||||
#include "lts_dummy_widget.h"
|
||||
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
#include <LtsUtilsCore/promise.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSplitter>
|
||||
#include <QHBoxLayout>
|
||||
#include <QCloseEvent>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QtPlatformHeaders/qwindowswindowfunctions.h>
|
||||
#endif
|
||||
|
||||
|
||||
class NoCloseWidget : public QWidget
|
||||
{
|
||||
void closeEvent(QCloseEvent *event) override
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
LtsScreenBase::LtsScreenBase(QRect screenGeo, int screenId, bool debugMargins, const QString &serial)
|
||||
: m_screenDialog(new NoCloseWidget())
|
||||
, m_screenId(screenId)
|
||||
, m_serial(serial)
|
||||
, m_screenRect(screenGeo)
|
||||
{
|
||||
connect(this, &LtsScreenBase::destroyed,
|
||||
m_screenDialog, &QWidget::deleteLater);
|
||||
|
||||
if (debugMargins)
|
||||
{
|
||||
qWarning() << "LtsScreenBase: screen rect adjusted for dev machines!";
|
||||
m_screenRect.adjust(+50, +50, -100, -100);
|
||||
}
|
||||
|
||||
|
||||
m_screenDialog->setWindowFlags(Qt::FramelessWindowHint);
|
||||
m_screenDialog->setGeometry(m_screenRect);
|
||||
m_screenDialog->setMinimumSize(m_screenRect.width(), m_screenRect.height());
|
||||
m_screenDialog->setMaximumSize(m_screenRect.width(), m_screenRect.height());
|
||||
m_screenDialog->setContentsMargins(0, 0, 0, 0);
|
||||
m_screenDialog->setWindowFlag(Qt::WindowType::WindowStaysOnBottomHint);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
m_screenDialog->winId();
|
||||
QWindowsWindowFunctions::setHasBorderInFullScreen(m_screenDialog->windowHandle(), true);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_screenDialog->activateWindow();
|
||||
m_screenDialog->show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include "lts_multi_monitor_export.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QRect>
|
||||
|
||||
class QSplitter;
|
||||
class QHBoxLayout;
|
||||
|
||||
namespace LtsUtils { class Promise; }
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LtsScreenContainer;
|
||||
|
||||
|
||||
|
||||
class LTSMULTIMONITOR_EXPORT LtsScreenBase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum WidgetType
|
||||
{
|
||||
MainWidget,
|
||||
SecondaryWidget,
|
||||
None,
|
||||
};
|
||||
|
||||
LtsScreenBase(QRect screenGeo, int screenId, bool debugMargins, const QString &serial);
|
||||
|
||||
const QRect &screenRect() const { return m_screenRect; }
|
||||
int screenId() const { return m_screenId; }
|
||||
const QString serialNumber() const { return m_serial; }
|
||||
QWidget *screenDialog() const { return m_screenDialog; }
|
||||
|
||||
virtual int screenType() const = 0;
|
||||
virtual int containerIdOfWidget(QWidget *widget) const noexcept(false) = 0;
|
||||
virtual LtsScreenContainer *putWidget(QWidget *widget, int screenPart = -1 ) noexcept(false) = 0;
|
||||
virtual LtsScreenContainer *containerOfWidget(QWidget *widget) noexcept(false) = 0;
|
||||
virtual bool isEmpty() const = 0;
|
||||
virtual bool isIrreplaceable() const = 0;
|
||||
virtual void check() {}
|
||||
virtual bool hasWidget(QWidget *widget) const = 0;
|
||||
virtual void switchToTemp(WidgetType ) {}
|
||||
virtual void finalizeSwitch() {}
|
||||
virtual void revertSwitch() {}
|
||||
|
||||
protected:
|
||||
QWidget *m_screenDialog;
|
||||
|
||||
private:
|
||||
int m_screenId;
|
||||
QString m_serial;
|
||||
QRect m_screenRect;
|
||||
};
|
||||
|
||||
}
|
||||
+555
@@ -0,0 +1,555 @@
|
||||
#include "lts_screen_container.h"
|
||||
#include "lts_dummy_widget.h"
|
||||
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QResizeEvent>
|
||||
#include <QRect>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
QString LtsScreenContainer::geoStr() const
|
||||
{
|
||||
return QStringLiteral("%1:%2:")
|
||||
.arg(QString::number(m_screenGeo.x()).rightJustified(4, QLatin1Char(' ')))
|
||||
.arg(QString::number(m_screenGeo.y()).rightJustified(4, QLatin1Char(' ')))
|
||||
;
|
||||
}
|
||||
|
||||
LtsScreenContainer::LtsScreenContainer(QRect screenGeo)
|
||||
: m_layout(new QHBoxLayout)
|
||||
, m_screenGeo(screenGeo)
|
||||
{
|
||||
|
||||
m_layout->setMargin(0);
|
||||
m_layout->setSpacing(0);
|
||||
m_layout->setStretch(0, 999);
|
||||
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
vanish();
|
||||
setLayout(m_layout);
|
||||
|
||||
|
||||
|
||||
QTimer *t = new QTimer(this);
|
||||
t->setInterval(3000);
|
||||
#ifdef LTS_DEBUG
|
||||
t->start();
|
||||
#endif
|
||||
connect(t, &QTimer::timeout,
|
||||
this, [this, screenGeo]()
|
||||
{
|
||||
QString old(QStringLiteral("<#!UNKNOWN!#>"));
|
||||
|
||||
if (m_oldActiveWidget == nullptr)
|
||||
old = QStringLiteral("null");
|
||||
else if (m_oldActiveWidget == &m_mainWidget)
|
||||
old = QStringLiteral("MAIN");
|
||||
else if (m_oldActiveWidget == &m_secondaryWidget)
|
||||
old = QStringLiteral("SECONDARY");
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenContainer::isInactiveWidgetOccupied() const
|
||||
{
|
||||
if (m_activeWidget == &m_mainWidget && m_secondaryWidget != nullptr)
|
||||
return true;
|
||||
if (m_activeWidget == &m_secondaryWidget && m_mainWidget != nullptr)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QIcon LtsScreenContainer::mainWindowIcon() const
|
||||
{
|
||||
if (m_mainWidget != nullptr)
|
||||
return m_mainWidget->windowIcon();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
QIcon LtsScreenContainer::secondaryWindowIcon() const
|
||||
{
|
||||
if (m_secondaryWidget != nullptr)
|
||||
return m_secondaryWidget->windowIcon();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenContainer::mainAndSecondaryOccupied() const
|
||||
{
|
||||
return (m_mainWidget != nullptr && m_secondaryWidget != nullptr);
|
||||
}
|
||||
|
||||
|
||||
LtsScreenBase::WidgetType LtsScreenContainer::activeWidgetType() const
|
||||
{
|
||||
if (m_activeWidget == &m_mainWidget)
|
||||
return LtsScreenBase::WidgetType::MainWidget;
|
||||
if (m_activeWidget == &m_secondaryWidget)
|
||||
return LtsScreenBase::WidgetType::SecondaryWidget;
|
||||
|
||||
assert(false);
|
||||
return LtsScreenBase::WidgetType::None;
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::toggle()
|
||||
{
|
||||
|
||||
switchToTemp((*m_activeWidget == m_mainWidget) ? LtsScreenBase::WidgetType::SecondaryWidget : LtsScreenBase::WidgetType::MainWidget);
|
||||
|
||||
QWidget *w = activeWidget();
|
||||
|
||||
assert(w != nullptr);
|
||||
if (w == nullptr)
|
||||
{
|
||||
revertSwitch();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tryPutDummyUnmanaged(w))
|
||||
w->show();
|
||||
|
||||
finalizeSwitch();
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenContainer::isIrreplaceable() const
|
||||
{
|
||||
if (m_activeWidget == nullptr)
|
||||
return false;
|
||||
|
||||
auto *blw = qobject_cast<LtsWidgets::LtsBaseLayoutWidget *>(activeWidget());
|
||||
if (blw == nullptr)
|
||||
return false;
|
||||
|
||||
return blw->isIrreplaceable();
|
||||
}
|
||||
|
||||
|
||||
QWidget *LtsScreenContainer::activeWidget() const
|
||||
{
|
||||
assert(m_activeWidget != nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return *m_activeWidget;
|
||||
}
|
||||
|
||||
|
||||
QWidget **LtsScreenContainer::activeWidgetPtr()
|
||||
{
|
||||
assert(m_activeWidget != nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return m_activeWidget;
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::vanish()
|
||||
{
|
||||
return;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_layout->setParent(nullptr);
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::reappear()
|
||||
{
|
||||
return;
|
||||
|
||||
|
||||
|
||||
|
||||
setAttribute(Qt::WA_TranslucentBackground, false);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_layout->parent() == nullptr)
|
||||
setLayout(m_layout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QWidget *LtsScreenContainer::stealWidget() noexcept(false)
|
||||
{
|
||||
|
||||
|
||||
QWidget **widgetPtr = activeWidgetPtr();
|
||||
QWidget *widget = *widgetPtr;
|
||||
|
||||
if (widget == nullptr)
|
||||
{
|
||||
|
||||
throw "stealWidget: no widget to steal";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
widget->setParent(nullptr);
|
||||
vanish();
|
||||
|
||||
|
||||
disconnect(widget, &QWidget::destroyed,
|
||||
this, &LtsScreenContainer::slotChildDestroyed);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QWidget *oldWidget = widget;
|
||||
*widgetPtr = nullptr;
|
||||
|
||||
return oldWidget;
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenContainer::hasWidget(QWidget *widget) const
|
||||
{
|
||||
if (m_mainWidget != nullptr && m_mainWidget == widget)
|
||||
return true;
|
||||
if (m_secondaryWidget != nullptr && m_secondaryWidget == widget)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenContainer::isEmpty() const
|
||||
{
|
||||
QWidget **currentWidgetPtr = m_activeWidget;
|
||||
if (currentWidgetPtr == nullptr)
|
||||
return true;
|
||||
return (*currentWidgetPtr == nullptr);
|
||||
}
|
||||
|
||||
bool LtsScreenContainer::hasMainWidget()
|
||||
{
|
||||
return m_mainWidget != nullptr;
|
||||
}
|
||||
|
||||
bool LtsScreenContainer::hasSecondaryWidget()
|
||||
{
|
||||
return m_secondaryWidget != nullptr;
|
||||
}
|
||||
|
||||
bool LtsScreenContainer::tryPutDummyUnmanaged(QWidget *widget)
|
||||
{
|
||||
auto *dummy = qobject_cast<FullscreenVideoDummyWidget *>(widget);
|
||||
|
||||
if (dummy == nullptr)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QRect r(mapToGlobal(rect().topLeft()), rect().size());
|
||||
|
||||
emit dummy->signalWidgetPlaced(r);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
emit signalSetCornerIcons();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::switchToTemp(LtsScreenBase::WidgetType widgetType)
|
||||
{
|
||||
|
||||
|
||||
Q_ASSERT(widgetType != LtsScreenBase::WidgetType::None);
|
||||
|
||||
if ((m_activeWidget == &m_mainWidget && widgetType == LtsScreenBase::WidgetType::MainWidget) ||
|
||||
(m_activeWidget == &m_secondaryWidget && widgetType == LtsScreenBase::WidgetType::SecondaryWidget))
|
||||
{
|
||||
|
||||
|
||||
m_nullSwitchActive = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (widgetType == LtsScreenBase::WidgetType::MainWidget)
|
||||
m_oldActiveWidget = &m_secondaryWidget;
|
||||
else if (widgetType == LtsScreenBase::WidgetType::SecondaryWidget)
|
||||
m_oldActiveWidget = &m_mainWidget;
|
||||
else
|
||||
Q_ASSERT(false);
|
||||
|
||||
|
||||
|
||||
|
||||
m_activeWidget = (widgetType == LtsScreenBase::WidgetType::SecondaryWidget ? &m_secondaryWidget : &m_mainWidget);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::finalizeSwitch()
|
||||
{
|
||||
|
||||
|
||||
QWidget **oldActiveWidget = m_oldActiveWidget;
|
||||
m_oldActiveWidget = nullptr;
|
||||
|
||||
|
||||
if (m_nullSwitchActive)
|
||||
{
|
||||
|
||||
m_nullSwitchActive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldActiveWidget == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (*oldActiveWidget == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QWidget *widget = *oldActiveWidget;
|
||||
auto *dummy = qobject_cast<FullscreenVideoDummyWidget *>(widget);
|
||||
if (dummy != nullptr)
|
||||
{
|
||||
|
||||
dummy->hideVideo();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
widget->hide();
|
||||
}
|
||||
|
||||
QWidget *widget2 = *m_activeWidget;
|
||||
auto *dummy2 = qobject_cast<FullscreenVideoDummyWidget *>(widget2);
|
||||
if (dummy2 != nullptr)
|
||||
{
|
||||
dummy2->showVideo();
|
||||
}
|
||||
|
||||
emit signalSetCornerIcons();
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::revertSwitch()
|
||||
{
|
||||
|
||||
|
||||
QWidget **oldActiveWidgetBackup = m_oldActiveWidget;
|
||||
m_oldActiveWidget = nullptr;
|
||||
|
||||
|
||||
if (m_nullSwitchActive)
|
||||
{
|
||||
|
||||
m_nullSwitchActive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (oldActiveWidgetBackup == nullptr)
|
||||
return;
|
||||
|
||||
m_activeWidget = oldActiveWidgetBackup;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::setWidget(QWidget *widget)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
QWidget **widgetPtr = activeWidgetPtr();
|
||||
|
||||
qWarning() << geoStr() << "setWidget: m_activeWidget" << m_activeWidget;
|
||||
|
||||
QWidget *currentWidget = *widgetPtr;
|
||||
|
||||
Q_ASSERT(currentWidget == nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*widgetPtr = widget;
|
||||
reappear();
|
||||
|
||||
connect(widget, &QWidget::destroyed,
|
||||
this, &LtsScreenContainer::slotChildDestroyed,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
if (tryPutDummyUnmanaged(widget))
|
||||
return;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_layout->addWidget(widget);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
widget->show();
|
||||
|
||||
emit signalSetCornerIcons();
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenContainer::slotChildDestroyed()
|
||||
{
|
||||
if (sender() == static_cast<QObject *>(m_mainWidget))
|
||||
{
|
||||
m_mainWidget = nullptr;
|
||||
qWarning() << geoStr() << "m_mainWidget set to nullptr!";
|
||||
|
||||
if (*m_activeWidget == m_mainWidget)
|
||||
{
|
||||
qWarning() << "slotChildDestroyed: switching to sec";
|
||||
switchToTemp(LtsScreenBase::WidgetType::SecondaryWidget);
|
||||
|
||||
QWidget *widget = activeWidget();
|
||||
|
||||
if (widget != nullptr)
|
||||
{
|
||||
auto *dummy = qobject_cast<FullscreenVideoDummyWidget *>(widget);
|
||||
if (dummy != nullptr)
|
||||
{
|
||||
QRect r(mapToGlobal(rect().topLeft()), rect().size());
|
||||
qWarning() << geoStr() << "LtsScreenContainer::slotChildDestroyed => (main) dummy->signalWidgetPlaced";
|
||||
emit dummy->signalWidgetPlaced(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
widget->show();
|
||||
}
|
||||
}
|
||||
|
||||
finalizeSwitch();
|
||||
}
|
||||
}
|
||||
else if (sender() == static_cast<QObject *>(m_secondaryWidget))
|
||||
{
|
||||
m_secondaryWidget = nullptr;
|
||||
qWarning() << geoStr() << "m_secondaryWidget set to nullptr!";
|
||||
|
||||
if (*m_activeWidget == m_secondaryWidget)
|
||||
{
|
||||
qWarning() << "slotChildDestroyed: switching to main";
|
||||
switchToTemp(LtsScreenBase::WidgetType::MainWidget);
|
||||
|
||||
QWidget *widget = activeWidget();
|
||||
|
||||
if (widget != nullptr)
|
||||
{
|
||||
auto *dummy = qobject_cast<FullscreenVideoDummyWidget *>(widget);
|
||||
if (dummy != nullptr)
|
||||
{
|
||||
QRect r(mapToGlobal(rect().topLeft()), rect().size());
|
||||
qWarning() << geoStr() << "LtsScreenContainer::slotChildDestroyed => (sec) dummy->signalWidgetPlaced";
|
||||
emit dummy->signalWidgetPlaced(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
widget->show();
|
||||
}
|
||||
}
|
||||
|
||||
finalizeSwitch();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << geoStr() << "slotChildDestroyed NOT received from any known widget !!";
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
vanish();
|
||||
emit check();
|
||||
}
|
||||
|
||||
|
||||
QWidget *LtsScreenContainer::widget() noexcept(false)
|
||||
{
|
||||
QWidget **widgetPtr = m_activeWidget;
|
||||
if (widgetPtr != nullptr && *widgetPtr != nullptr)
|
||||
return *widgetPtr;
|
||||
throw "no widget in container";
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "lts_screen_base.h"
|
||||
|
||||
#include <lts_multi_monitor_export.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QRect>
|
||||
|
||||
|
||||
class QHBoxLayout;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LTSMULTIMONITOR_EXPORT LtsScreenContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LtsScreenContainer(QRect screenGeo);
|
||||
|
||||
bool isIrreplaceable() const;
|
||||
bool isEmpty() const;
|
||||
bool hasMainWidget();
|
||||
bool hasSecondaryWidget();
|
||||
void setWidget(QWidget *widget);
|
||||
bool hasWidget(QWidget *widget) const;
|
||||
QWidget *widget() noexcept(false);
|
||||
QWidget *stealWidget() noexcept(false);
|
||||
void switchToTemp(LtsScreenBase::WidgetType widgetType);
|
||||
void finalizeSwitch();
|
||||
void revertSwitch();
|
||||
bool mainAndSecondaryOccupied() const;
|
||||
QIcon mainWindowIcon() const;
|
||||
QIcon secondaryWindowIcon() const;
|
||||
LtsScreenBase::WidgetType activeWidgetType() const;
|
||||
bool isInactiveWidgetOccupied() const;
|
||||
|
||||
signals:
|
||||
void check();
|
||||
void signalSetCornerIcons();
|
||||
|
||||
private:
|
||||
QHBoxLayout *m_layout { nullptr };
|
||||
QWidget *m_mainWidget { nullptr };
|
||||
QWidget *m_secondaryWidget { nullptr };
|
||||
QWidget **m_activeWidget { nullptr };
|
||||
QWidget **m_oldActiveWidget { nullptr };
|
||||
bool m_nullSwitchActive { false };
|
||||
QRect m_screenGeo;
|
||||
|
||||
QString geoStr() const;
|
||||
bool tryPutDummyUnmanaged(QWidget *widget);
|
||||
void vanish();
|
||||
void reappear();
|
||||
QWidget *activeWidget() const;
|
||||
QWidget **activeWidgetPtr();
|
||||
|
||||
public slots:
|
||||
void toggle();
|
||||
|
||||
private slots:
|
||||
|
||||
void slotChildDestroyed();
|
||||
};
|
||||
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
#include "lts_screen_normal.h"
|
||||
#include "lts_dummy_widget.h"
|
||||
#include "lts_screen_container.h"
|
||||
#include "lts_magic_corner.h"
|
||||
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSplitter>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QtPlatformHeaders/qwindowswindowfunctions.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
|
||||
LtsScreenNormal::LtsScreenNormal(QRect screenGeo, int screenId, bool debugMargins, const QString &serial)
|
||||
: LtsScreenBase(screenGeo, screenId, debugMargins, serial)
|
||||
, m_childContainer(new LtsScreenContainer(screenGeo))
|
||||
, m_corner(new LtsMagicCorner(screenGeo))
|
||||
{
|
||||
|
||||
connect(m_childContainer, &LtsScreenContainer::check,
|
||||
this, &LtsScreenNormal::check);
|
||||
|
||||
auto *theLayout = new QHBoxLayout;
|
||||
|
||||
theLayout->setContentsMargins(0, 0, 0, 0);
|
||||
theLayout->setMargin(0);
|
||||
theLayout->setSpacing(0);
|
||||
theLayout->setStretch(0, 999);
|
||||
theLayout->addWidget(m_childContainer);
|
||||
|
||||
m_screenDialog->setLayout(theLayout);
|
||||
|
||||
m_corner->hide();
|
||||
connect(m_corner, &LtsMagicCorner::toggle,
|
||||
this, [this]()
|
||||
{
|
||||
m_childContainer->toggle();
|
||||
m_corner->setActiveWidgetType(m_childContainer->activeWidgetType());
|
||||
setCornerIcons();
|
||||
});
|
||||
|
||||
connect(m_corner, &LtsMagicCorner::signalMakeAllSwole,
|
||||
this, &LtsScreenNormal::signalMakeAllSwole);
|
||||
connect(this, &LtsScreenNormal::signalMakeSwole,
|
||||
m_corner, &LtsMagicCorner::makeSwole);
|
||||
|
||||
connect(m_childContainer, &LtsScreenContainer::signalSetCornerIcons,
|
||||
this, &LtsScreenNormal::setCornerIcons);
|
||||
}
|
||||
|
||||
|
||||
LtsScreenNormal::~LtsScreenNormal()
|
||||
{
|
||||
m_corner->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenNormal::setCornerIcons()
|
||||
{
|
||||
m_corner->setActiveWidgetType(m_childContainer->activeWidgetType());
|
||||
m_corner->setIcon(m_childContainer->mainWindowIcon(), LtsScreenBase::WidgetType::MainWidget);
|
||||
m_corner->setIcon(m_childContainer->secondaryWindowIcon(), LtsScreenBase::WidgetType::SecondaryWidget);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenNormal::check()
|
||||
{
|
||||
m_childContainer->mainAndSecondaryOccupied() ? m_corner->show() : m_corner->hide();
|
||||
}
|
||||
|
||||
|
||||
LtsScreenContainer *LtsScreenNormal::containerOfWidget(QWidget *widget)
|
||||
{
|
||||
if (m_childContainer->hasWidget(widget))
|
||||
return m_childContainer;
|
||||
throw "widget is not present on this container";
|
||||
}
|
||||
|
||||
void LtsScreenNormal::hideMagicCorner(bool hide)
|
||||
{
|
||||
m_corner->setFreezed(hide);
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenNormal::isIrreplaceable() const
|
||||
{
|
||||
return m_childContainer->isIrreplaceable();
|
||||
}
|
||||
|
||||
|
||||
int LtsScreenNormal::containerIdOfWidget(QWidget *widget) const noexcept(false)
|
||||
{
|
||||
if (m_childContainer->hasWidget(widget))
|
||||
return 0;
|
||||
throw "widget not on this screen";
|
||||
}
|
||||
|
||||
|
||||
LtsScreenContainer *LtsScreenNormal::putWidget(QWidget *widget, int ) noexcept(false)
|
||||
{
|
||||
if (!isEmpty())
|
||||
throw "cannot put widget as container is non-empty";
|
||||
putWidgetUnmanaged(widget);
|
||||
return m_childContainer;
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenNormal::hasWidget(QWidget *widget) const
|
||||
{
|
||||
return (m_childContainer->hasWidget(widget));
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenNormal::putWidgetUnmanaged(QWidget *widget)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
m_childContainer->setWidget(widget);
|
||||
|
||||
|
||||
|
||||
|
||||
setCornerIcons();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenNormal::slotOverlayDestroyed()
|
||||
{
|
||||
m_screenDialog->show();
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenNormal::isEmpty() const
|
||||
{
|
||||
return m_childContainer->isEmpty();
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenNormal::switchToTemp(LtsScreenBase::WidgetType widgetType)
|
||||
{
|
||||
m_childContainer->switchToTemp(widgetType);
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenNormal::finalizeSwitch()
|
||||
{
|
||||
m_childContainer->finalizeSwitch();
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenNormal::revertSwitch()
|
||||
{
|
||||
m_childContainer->revertSwitch();
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "lts_screen_base.h"
|
||||
|
||||
#include <LtsMultiMonitor/lts_multi_monitor_export.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QRect>
|
||||
|
||||
|
||||
class QSplitter;
|
||||
class QHBoxLayout;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
class LtsMagicCorner;
|
||||
|
||||
|
||||
class LTSMULTIMONITOR_EXPORT LtsScreenNormal : public LtsScreenBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LtsScreenNormal(QRect screenGeo, int screenId, bool debugMargins, const QString &serial);
|
||||
~LtsScreenNormal();
|
||||
int screenType() const override { return 0; }
|
||||
int containerIdOfWidget(QWidget *widget) const noexcept(false) override;
|
||||
LtsScreenContainer *child() const { return m_childContainer; }
|
||||
LtsScreenContainer *putWidget(QWidget *widget, int) noexcept(false) override;
|
||||
LtsScreenContainer *containerOfWidget(QWidget *widget) noexcept(false) override;
|
||||
void hideMagicCorner(bool hide);
|
||||
bool isEmpty() const override;
|
||||
bool isIrreplaceable() const override;
|
||||
void putWidgetUnmanaged(QWidget *widget);
|
||||
bool hasWidget(QWidget *widget) const override;
|
||||
void switchToTemp(WidgetType widgetType) override;
|
||||
void finalizeSwitch() override;
|
||||
void revertSwitch() override;
|
||||
void check() override;
|
||||
|
||||
private:
|
||||
LtsScreenContainer *m_childContainer { nullptr };
|
||||
LtsMagicCorner *m_corner;
|
||||
|
||||
|
||||
void swapLeftRight();
|
||||
bool tryPutDummyUnmanaged(QWidget *widget);
|
||||
|
||||
signals:
|
||||
void signalMakeAllSwole();
|
||||
void signalMakeSwole();
|
||||
|
||||
private slots:
|
||||
void slotOverlayDestroyed();
|
||||
void setCornerIcons();
|
||||
};
|
||||
}
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
#include "lts_screen_wide.h"
|
||||
#include "lts_dummy_widget.h"
|
||||
#include "lts_screen_container.h"
|
||||
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSplitter>
|
||||
#include <QHBoxLayout>
|
||||
#include <QTimer>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QtPlatformHeaders/qwindowswindowfunctions.h>
|
||||
#endif
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
|
||||
LtsScreenWide::LtsScreenWide(const QRect &screenGeo, int screenId, bool debugMargins, const QString &serial)
|
||||
: LtsScreenBase(screenGeo, screenId, debugMargins, serial)
|
||||
, m_childContainerMain(new LtsScreenContainer(screenGeo))
|
||||
, m_childContainerLeft(new LtsScreenContainer(screenGeo))
|
||||
, m_childContainerRight(new LtsScreenContainer(screenGeo))
|
||||
{
|
||||
|
||||
connect(m_childContainerMain, &LtsScreenContainer::check,
|
||||
this, &LtsScreenWide::check);
|
||||
connect(m_childContainerLeft, &LtsScreenContainer::check,
|
||||
this, &LtsScreenWide::check);
|
||||
connect(m_childContainerRight, &LtsScreenContainer::check,
|
||||
this, &LtsScreenWide::check);
|
||||
|
||||
auto *theLayout = new QHBoxLayout;
|
||||
|
||||
theLayout->setContentsMargins(0, 0, 0, 0);
|
||||
theLayout->setMargin(0);
|
||||
theLayout->setSpacing(0);
|
||||
theLayout->setStretch(0, 9999);
|
||||
|
||||
m_splitter = new QSplitter;
|
||||
m_splitter->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_splitter->addWidget(m_childContainerLeft);
|
||||
m_splitter->addWidget(m_childContainerRight);
|
||||
|
||||
theLayout->addWidget(m_splitter);
|
||||
theLayout->addWidget(m_childContainerMain);
|
||||
|
||||
m_screenDialog->setLayout(theLayout);
|
||||
|
||||
m_splitter->hide();
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenWide::putWidgetUnmanagedMain(QWidget *widget)
|
||||
{
|
||||
|
||||
m_childContainerMain->setWidget(widget);
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenWide::putWidgetUnmanagedRight(QWidget *widget)
|
||||
{
|
||||
|
||||
m_childContainerRight->setWidget(widget);
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenWide::putWidgetUnmanagedLeft(QWidget *widget)
|
||||
{
|
||||
|
||||
m_childContainerLeft->setWidget(widget);
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenWide::hasWidget(QWidget *widget) const
|
||||
{
|
||||
return (m_childContainerMain->hasWidget(widget) ||
|
||||
m_childContainerLeft->hasWidget(widget) ||
|
||||
m_childContainerRight->hasWidget(widget));
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenWide::isIrreplaceable() const
|
||||
{
|
||||
return (childLeft()->isIrreplaceable() && childRight()->isIrreplaceable() && childMain()->isIrreplaceable());
|
||||
}
|
||||
|
||||
|
||||
bool LtsScreenWide::isEmpty() const
|
||||
{
|
||||
return (m_childContainerLeft->isEmpty() && m_childContainerRight->isEmpty() && m_childContainerMain->isEmpty());
|
||||
}
|
||||
|
||||
|
||||
int LtsScreenWide::containerIdOfWidget(QWidget *widget) const noexcept(false)
|
||||
{
|
||||
if (m_childContainerMain->hasWidget(widget))
|
||||
return 0;
|
||||
if (m_childContainerLeft->hasWidget(widget))
|
||||
return 1;
|
||||
if (m_childContainerRight->hasWidget(widget))
|
||||
return 2;
|
||||
throw "widget not on this screen";
|
||||
}
|
||||
|
||||
|
||||
LtsScreenContainer *LtsScreenWide::containerOfWidget(QWidget *widget) noexcept(false)
|
||||
{
|
||||
if (m_childContainerMain->hasWidget(widget))
|
||||
return m_childContainerMain;
|
||||
if (m_childContainerLeft->hasWidget(widget))
|
||||
return m_childContainerLeft;
|
||||
if (m_childContainerRight->hasWidget(widget))
|
||||
return m_childContainerRight;
|
||||
throw "widget is not present on this container";
|
||||
}
|
||||
|
||||
|
||||
LtsScreenContainer *LtsScreenWide::putWidget(QWidget *widget, int screenPart) noexcept(false)
|
||||
{
|
||||
if (screenPart == -1)
|
||||
{
|
||||
if (!isEmpty())
|
||||
throw "cannot put widget as at least one container is occupied and screen part was not specified";
|
||||
|
||||
putWidgetUnmanagedMain(widget);
|
||||
return m_childContainerMain;
|
||||
}
|
||||
|
||||
switch (screenPart)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (!m_childContainerMain->isEmpty())
|
||||
throw "cannot put widget as main container is already occupied";
|
||||
|
||||
putWidgetUnmanagedMain(widget);
|
||||
return m_childContainerMain;
|
||||
}
|
||||
|
||||
case 1:
|
||||
{
|
||||
if (!m_childContainerLeft->isEmpty())
|
||||
throw "cannot put widget as left container is already occupied";
|
||||
|
||||
|
||||
|
||||
if (!m_childContainerMain->isEmpty())
|
||||
putWidgetUnmanagedRight(m_childContainerMain->stealWidget());
|
||||
|
||||
putWidgetUnmanagedLeft(widget);
|
||||
return m_childContainerLeft;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if (!m_childContainerRight->isEmpty())
|
||||
throw "cannot put widget as right container is already occupied";
|
||||
|
||||
|
||||
|
||||
if (!m_childContainerMain->isEmpty())
|
||||
putWidgetUnmanagedLeft(m_childContainerMain->stealWidget());
|
||||
|
||||
putWidgetUnmanagedRight(widget);
|
||||
return m_childContainerRight;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw "unknown screen part id";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LtsScreenWide::check()
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Q_ASSERT( (!m_childContainerMain->isEmpty() && m_childContainerLeft->isEmpty() && m_childContainerRight->isEmpty()) || m_childContainerMain->isEmpty() );
|
||||
|
||||
|
||||
|
||||
if (m_childContainerMain->isEmpty())
|
||||
{
|
||||
if (m_childContainerLeft->isEmpty() && !m_childContainerRight->isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
QWidget *widget = m_childContainerRight->stealWidget();
|
||||
m_childContainerMain->setWidget(widget);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else if (!m_childContainerLeft->isEmpty() && m_childContainerRight->isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
QWidget *widget = m_childContainerLeft->stealWidget();
|
||||
m_childContainerMain->setWidget(widget);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!m_childContainerMain->isEmpty())
|
||||
{
|
||||
|
||||
m_childContainerMain->show();
|
||||
m_splitter->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
m_childContainerMain->hide();
|
||||
m_splitter->setVisible(!m_childContainerLeft->isEmpty() || !m_childContainerRight->isEmpty());
|
||||
m_childContainerLeft->setVisible(!m_childContainerLeft->isEmpty());
|
||||
m_childContainerRight->setVisible(!m_childContainerRight->isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "lts_screen_base.h"
|
||||
|
||||
#include <LtsMultiMonitor/lts_multi_monitor_export.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QRect>
|
||||
|
||||
|
||||
class QSplitter;
|
||||
class QHBoxLayout;
|
||||
|
||||
|
||||
namespace LtsMultiMonitor
|
||||
{
|
||||
|
||||
class LTSMULTIMONITOR_EXPORT LtsScreenWide : public LtsScreenBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LtsScreenWide(const QRect &screenGeo, int screenId, bool debugMargins, const QString &serial);
|
||||
|
||||
int screenType() const override { return 1; }
|
||||
LtsScreenContainer *containerOfWidget(QWidget *widget) noexcept(false) override;
|
||||
bool isEmpty() const override;
|
||||
LtsScreenContainer *childLeft() const { return m_childContainerLeft; }
|
||||
LtsScreenContainer *childRight() const { return m_childContainerRight; }
|
||||
LtsScreenContainer *childMain() const { return m_childContainerMain; }
|
||||
void putWidgetUnmanagedMain(QWidget *widget);
|
||||
void putWidgetUnmanagedLeft(QWidget *widget);
|
||||
void putWidgetUnmanagedRight(QWidget *widget);
|
||||
bool isIrreplaceable() const override;
|
||||
bool hasWidget(QWidget *widget) const override;
|
||||
LtsScreenContainer *putWidget(QWidget *widget, int screenPart) noexcept(false) override;
|
||||
int containerIdOfWidget(QWidget *widget) const noexcept(false) override;
|
||||
|
||||
public slots:
|
||||
void check() override;
|
||||
|
||||
private:
|
||||
LtsScreenContainer *m_childContainerMain;
|
||||
LtsScreenContainer *m_childContainerLeft;
|
||||
LtsScreenContainer *m_childContainerRight;
|
||||
QSplitter *m_splitter;
|
||||
|
||||
void swapLeftRight();
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user