diff --git a/DapUiScreen.cpp b/DapUiScreen.cpp index aceb7bd1bba96fd741b2715e7108b2c3d39fa2b0..6cb06737b74a727f2707debb2dd5cc2f6feee00e 100755 --- a/DapUiScreen.cpp +++ b/DapUiScreen.cpp @@ -13,7 +13,7 @@ * @param a_sw */ DapUiScreen::DapUiScreen(QObject *parent, QStackedWidget * a_sw) - : QObject(parent),m_sw(a_sw) + : QObject(parent), m_sw(a_sw) { Q_ASSERT(m_sw); diff --git a/auxiliary/ScreenInfo.cpp b/auxiliary/ScreenInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c16565b7804866cf8939f6f0405a2e71a710d23a --- /dev/null +++ b/auxiliary/ScreenInfo.cpp @@ -0,0 +1,28 @@ +#include "ScreenInfo.h" + +ScreenInfo::Rotation ScreenInfo::s_currentRotation = ScreenInfo::Rotation::Horizontal; + +ScreenInfo::ScreenInfo() +{ + +} + +QSize ScreenInfo::getWindowSizeInPoints() +{ + return QSize(1024, 744); +} + +QList<ScreenInfo::Rotation> ScreenInfo::allRotations() +{ + return { Rotation::Horizontal, Rotation::Vertical }; +} + +ScreenInfo::Rotation ScreenInfo::currentRotation() +{ + return ScreenInfo::s_currentRotation; +} + +void ScreenInfo::setCurrentRotation(const Rotation &value) +{ + s_currentRotation = value; +} diff --git a/auxiliary/ScreenInfo.h b/auxiliary/ScreenInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..42a626c111972a52f71a3d1de67ec27194f35933 --- /dev/null +++ b/auxiliary/ScreenInfo.h @@ -0,0 +1,32 @@ +#ifndef SCREENSIZEINFO_H +#define SCREENSIZEINFO_H + +#include <QObject> +#include <QSize> +#include <QSet> + +class ScreenInfo +{ + Q_GADGET + + ScreenInfo(); + +public: + enum class Rotation { Horizontal, Vertical }; Q_ENUM(Rotation); + + + static QSize getWindowSizeInPoints(); + static QList<Rotation> allRotations(); + + static Rotation currentRotation(); + static void setCurrentRotation(const Rotation &value); + +private: + static Rotation s_currentRotation; + + +}; + +Q_DECLARE_METATYPE(ScreenInfo::Rotation); + +#endif // SCREENSIZEINFO_H diff --git a/auxiliary/auxiliary.pri b/auxiliary/auxiliary.pri index 6bdd7c801b171a7514fc49adbb5f5af9f34d8e1f..8b6be36e1fdc0e43792fdd9c57cf12e56392fa03 100644 --- a/auxiliary/auxiliary.pri +++ b/auxiliary/auxiliary.pri @@ -1,10 +1,13 @@ HEADERS += \ $$PWD/AppStyleSheetHandler.h \ + $$PWD/ScreenInfo.h \ $$PWD/UiScaling.h \ - $$PWD/Utils.h + $$PWD/Utils.h \ + $$PWD/defines.h SOURCES += \ $$PWD/AppStyleSheetHandler.cpp \ + $$PWD/ScreenInfo.cpp \ $$PWD/UiScaling.cpp \ $$PWD/Utils.cpp diff --git a/auxiliary/defines.h b/auxiliary/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..9d83145ca3da9fda29321b0774cb121b26dcea6a --- /dev/null +++ b/auxiliary/defines.h @@ -0,0 +1,13 @@ +#ifndef DEFINES_H +#define DEFINES_H + +#include <QString> + +namespace Properties { + static const QString TEXT = "text"; + static const QString STATE = "state"; + +} + + +#endif // DEFINES_H diff --git a/controls/AdaptiveWidget.cpp b/controls/AdaptiveWidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91a3444a450739d7e1a7522f60cf0ec9f4af5940 --- /dev/null +++ b/controls/AdaptiveWidget.cpp @@ -0,0 +1,13 @@ +#include "AdaptiveWidget.h" + +AdaptiveWidget::AdaptiveWidget(QWidget *a_parent /*= nullptr*/) + :QStackedWidget(a_parent) +{ + +} + +QWidget *AdaptiveWidget::variant(ScreenInfo::Rotation a_rotation /*= ScreenInfo::Rotation::Horizontal*/) +{ + return m_variants.value(a_rotation, nullptr); +} + diff --git a/controls/AdaptiveWidget.h b/controls/AdaptiveWidget.h new file mode 100644 index 0000000000000000000000000000000000000000..72165c0bec7eb71f2f984ccc82a4c4197bba439a --- /dev/null +++ b/controls/AdaptiveWidget.h @@ -0,0 +1,91 @@ +#ifndef ADAPTIVEWIDGET_H +#define ADAPTIVEWIDGET_H + +#include <QStackedWidget> +#include <ScreenInfo.h> +#include <QState> +#include <QStyle> + +class AdaptiveWidget : public QStackedWidget +{ +public: + AdaptiveWidget(QWidget *a_parent = nullptr); + + QWidget* variant(ScreenInfo::Rotation a_rotation = ScreenInfo::Rotation::Horizontal); + +protected: + + template<class T> + void setupWidgetForm(QWidget * a_widget) + { + static T * l_uiForm = nullptr; + delete l_uiForm; + l_uiForm = new T; + l_uiForm->setupUi(a_widget); + } + + virtual void initVariantUi(QWidget * a_widget) = 0; + + template<class T> + inline void create() + { + ///TODO: add horisontal rotation for mobile. + QWidget *currentWidget (new QWidget(this)); + + this->addWidget(currentWidget); + this->setupWidgetForm<T>(currentWidget); + + initVariantUi(currentWidget); + } + + void setChildProperties(const QString& a_objName, const QString& a_property, const QVariant& a_value) + { + for (auto widget : getTheSameWidgets<QWidget>(a_objName)) { + widget->setProperty(a_property.toLatin1().constData(), a_value); + } + } + + void updateChildStyle(const QString& a_objName) + { + for (auto widget : getTheSameWidgets<QWidget>(a_objName)) { + widget->style()->unpolish(widget); + widget->style()->polish(widget); + } + } + + template <class T /*= QWidget*/> + inline QList<T*> getTheSameWidgets(const QString& a_objName) + { + QList<T*> widgetsList; + T* foundWidget = currentWidget()->findChild<T*>(a_objName); + if (foundWidget) + widgetsList.append(foundWidget); + + ///TODO: add horisontal rotation for mobile. + +// for (auto l_rotation: ScreenInfo::allRotations()) +// { +// T* foundWidget = page(l_rotation)->findChild<T*>(a_objName); +// if (foundWidget) +// widgets.append(foundWidget); +// } + return widgetsList; + } + + template <class T /*= QWidget*/> + void assignWidgetPropertyForState(QState *a_state, const QString& a_objName, const QString& a_property, const QVariant& a_value); + +private: + QMap<ScreenInfo::Rotation, QWidget*> m_variants; + +}; + +template<class T> +void AdaptiveWidget::assignWidgetPropertyForState(QState *a_state, const QString &a_objName, const QString &a_property, const QVariant &a_value) +{ + for (auto obj: getTheSameWidgets<T>(a_objName)) { + a_state->assignProperty(obj, qPrintable(a_property), a_value); + } +} + +#endif // ADAPTIVEWIDGET_H diff --git a/controls/AnimationChangingWidget.cpp b/controls/AnimationChangingWidget.cpp index db4c51178035f6787663e264f350446a2f4438c0..69daeea465ae07017140080e61babf6b27763df8 100644 --- a/controls/AnimationChangingWidget.cpp +++ b/controls/AnimationChangingWidget.cpp @@ -116,6 +116,16 @@ void AnimationChangingWidget::setCurrentIndex(int a_index) m_animation.start(); } +QWidget *AnimationChangingWidget::currentWidget() +{ + QLayoutItem* currentItem = m_ltWidgetPlacement.itemAt(this->currentIndex()); + + if (!currentItem) + return nullptr; + + return currentItem->widget(); +} + /** * @brief Getter for currentIndex * @return Current index diff --git a/controls/AnimationChangingWidget.h b/controls/AnimationChangingWidget.h index c90db62a08bfe6f38144d7c8afaafd1fbe8059b1..0647826b9675f00a413ef8a1ebf951fd3661c341 100644 --- a/controls/AnimationChangingWidget.h +++ b/controls/AnimationChangingWidget.h @@ -26,7 +26,8 @@ public: void setCurrentWidget(QWidget *a_widget); void setCurrentIndex (int a_index); - int currentIndex (); + QWidget *currentWidget(); + int currentIndex (); int count() const; diff --git a/controls/controls.pri b/controls/controls.pri index f435d1727f02a91c507757e0ed6da025a5eb91d3..60ea7401a948fdb22a3c3fc03d757c23ab464eb6 100644 --- a/controls/controls.pri +++ b/controls/controls.pri @@ -1,4 +1,5 @@ SOURCES += \ + $$PWD/AdaptiveWidget.cpp \ $$PWD/AnimationChangingWidget.cpp \ $$PWD/ComboBoxDelegate.cpp \ $$PWD/CustomComboBox.cpp \ @@ -14,6 +15,7 @@ SOURCES += \ $$PWD/StyledSubcontrol.cpp HEADERS += \ + $$PWD/AdaptiveWidget.h \ $$PWD/AnimationChangingWidget.h \ $$PWD/ComboBoxDelegate.h \ $$PWD/CustomComboBox.h \ diff --git a/libdap-qt-ui.pri b/libdap-qt-ui.pri index 098220bdb08f4beec2ea7b1aee7bcbd79d33ede6..0f981c739ce94b1e70b1d27090cb02e830548d99 100644 --- a/libdap-qt-ui.pri +++ b/libdap-qt-ui.pri @@ -28,6 +28,7 @@ HEADERS += \ include(auxiliary/auxiliary.pri) include(controls/controls.pri) +include(screens/screens.pri) INCLUDEPATH += $$PWD diff --git a/screens/AdaptiveScreen.cpp b/screens/AdaptiveScreen.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c685f4103c01ef6718336af18cafca29668c11dc --- /dev/null +++ b/screens/AdaptiveScreen.cpp @@ -0,0 +1,9 @@ +#include "AdaptiveScreen.h" + +QMap<QString, void*> AdaptiveScreen::s_initFuncMap; + +AdaptiveScreen::AdaptiveScreen(QWidget *a_parent /*= nullptr*/) + : AdaptiveWidget(a_parent) +{ +// AdaptiveScreen::initScreen(this); +} diff --git a/screens/AdaptiveScreen.h b/screens/AdaptiveScreen.h new file mode 100644 index 0000000000000000000000000000000000000000..c148214e92fcdf223a4a2f73681cfaed3d5b0c09 --- /dev/null +++ b/screens/AdaptiveScreen.h @@ -0,0 +1,52 @@ +#ifndef ADAPTIVE_SCREEN_H +#define ADAPTIVE_SCREEN_H + +#include "AdaptiveWidget.h" +#include <QDebug> + +class AdaptiveScreen : public AdaptiveWidget +{ + Q_OBJECT +public: + + AdaptiveScreen(QWidget *a_parent = nullptr); + + virtual QString screenName() = 0; + + virtual void initVariantUi(QWidget * a_widget) = 0; + + + template<typename T> + static void setInitFunc(void (*a_initFunc)(T*)); + +protected: + + template<typename T> + static void initScreen(T* a_screen); + +private: + + static QMap<QString, void*> s_initFuncMap; +}; + + + +//////////////////////////////////////////////////////////////////////////////////////////////// + +template<typename T> +void AdaptiveScreen::setInitFunc(void (*a_initFunc)(T*)/*typename T::InitializerFunc a_initFunc*/) { + s_initFuncMap[T::SCREEN_NAME] = reinterpret_cast<void*>(a_initFunc); +}; + +template<typename T> +void AdaptiveScreen::initScreen(T* a_screen) { + void* l_initFunctionVoid = s_initFuncMap.value(T::SCREEN_NAME, nullptr); + if (l_initFunctionVoid) + { + typedef void (*funcType)(T*); + auto l_initFunction = reinterpret_cast<funcType>(l_initFunctionVoid); + l_initFunction(a_screen); + } +} + +#endif // SCREEN_H diff --git a/screens/DefaultMultiScreen.cpp b/screens/DefaultMultiScreen.cpp new file mode 100755 index 0000000000000000000000000000000000000000..67a0a74d6b69182b71acb2a4da7dec87f367b42b --- /dev/null +++ b/screens/DefaultMultiScreen.cpp @@ -0,0 +1,54 @@ +/* +* Authors: +* Dmitriy Gerasimov <naeper@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2019 +* All rights reserved. + +This file is part of CellFrame SDK the open source project + +CellFrame SDK is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +CellFrame SDK is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "DefaultMultiScreen.h" + +const QString DefaultMultiScreen::SCREEN_NAME("FullScreen"); + +/** + * @brief Overloaded constructor. + * @param a_parent Parent. + * @param a_sw Application window stack. + */ +DefaultMultiScreen::DefaultMultiScreen(QWidget *a_parent) + : MultiScreenAbstract(a_parent) +{ + create<Ui_DefaultMultiScreen>(); +} + +QString DefaultMultiScreen::screenName() +{ + return DefaultMultiScreen::SCREEN_NAME; +} + +/** + * @brief Form initialization. + * @param a_w Window GUI widget. + * @param a_rotation Device display orientation. + */ +void DefaultMultiScreen::initVariantUi(QWidget * a_widget) +{ + // Initializing pointers to window widgets + initChangedScreen(a_widget); +} diff --git a/screens/DefaultMultiScreen.h b/screens/DefaultMultiScreen.h new file mode 100755 index 0000000000000000000000000000000000000000..66f422555c553440b66b0331ec5e277245d557d0 --- /dev/null +++ b/screens/DefaultMultiScreen.h @@ -0,0 +1,74 @@ +/* +* Authors: +* Dmitriy Gerasimov <naeper@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2019 +* All rights reserved. + +This file is part of CellFrame SDK the open source project + +CellFrame SDK is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +CellFrame SDK is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once +#include "MultiScreenAbstract.h" + +/** + * @brief Class wich hold full screen AnimationChangingWidget and can hold child screens + */ +class DefaultMultiScreen : public MultiScreenAbstract +{ + Q_OBJECT + +public: + DefaultMultiScreen(QWidget *a_parent = nullptr); + + virtual QString screenName() override; + static const QString SCREEN_NAME; + + +protected: + virtual void initVariantUi(QWidget * a_widget) override; + +}; + + + +//======================================================================= +// Default Form +//======================================================================= + +class Ui_DefaultMultiScreen +{ +public: + AnimationChangingWidget *changingScreen; + QHBoxLayout *horizontalLayout; + + void setupUi(QWidget *a_wgScreen) + { + if (a_wgScreen->objectName().isEmpty()) + a_wgScreen->setObjectName(QStringLiteral("FullScreenMultiScreen")); + horizontalLayout = new QHBoxLayout(a_wgScreen); + horizontalLayout->setSpacing(0); + horizontalLayout->setObjectName(QStringLiteral("centralLayout")); + horizontalLayout->setContentsMargins(0, 0, 0, 0); + a_wgScreen->setLayout(horizontalLayout); + + changingScreen = new AnimationChangingWidget(a_wgScreen); + changingScreen->setObjectName(QStringLiteral("changingScreen")); + changingScreen->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + horizontalLayout->addWidget(changingScreen); + } // setupUi + +}; diff --git a/screens/MultiScreenAbstract.cpp b/screens/MultiScreenAbstract.cpp new file mode 100755 index 0000000000000000000000000000000000000000..f6348ad92e1200954ef8bc7264bdfe995dbaaccb --- /dev/null +++ b/screens/MultiScreenAbstract.cpp @@ -0,0 +1,109 @@ +/* +* Authors: +* Dmitriy Gerasimov <naeper@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2019 +* All rights reserved. + +This file is part of CellFrame SDK the open source project + +CellFrame SDK is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +CellFrame SDK is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "MultiScreenAbstract.h" + +/** + * @brief Overloaded constructor. + * @param a_parent Parent. + * @param a_sw Application window stack. + */ +MultiScreenAbstract::MultiScreenAbstract(QWidget *parent) + :AdaptiveScreen(parent) +{ +} + +AdaptiveScreen *MultiScreenAbstract::activeScreen() +{ + QWidget* l_activeWidget = this->wgtChangingScreen()->currentWidget(); + return qobject_cast<AdaptiveScreen*>(l_activeWidget); +} + +QString MultiScreenAbstract::activeScreenName() +{ + AdaptiveScreen* activeScreen = this->activeScreen(); + + if (!activeScreen) + return QString(); + + return this->activeScreen()->screenName(); +} + +/** + * @brief Activate child a_screen. a_screen must exist + * @param a_screen pointer to child screen + * @return pointer to this screen (parent) + */ +MultiScreenAbstract *MultiScreenAbstract::activateChildScreen(AdaptiveScreen *a_screen) +{ + Q_ASSERT_X(MultiScreenAbstract::parentMultiscreen(a_screen) == this, "activateDescendantScreen", "screen is not a child of this screen"); + + m_wgtChangingScreen->setCurrentWidget(a_screen); + + return (this); +} + +MultiScreenAbstract *MultiScreenAbstract::parentMultiscreen(AdaptiveScreen *a_screen) +{ + MultiScreenAbstract *l_parentMultiscr; + + for (QObject *parentObj = a_screen->parent(); parentObj; parentObj = parentObj->parent()) + { + l_parentMultiscr = qobject_cast<MultiScreenAbstract*>(parentObj); + if (l_parentMultiscr) + return l_parentMultiscr; + } + return nullptr; +} + +/** + * @brief Getter for m_wgChangingScreen + * @return pointer to AnimationChangingWidget + */ +AnimationChangingWidget *MultiScreenAbstract::wgtChangingScreen() +{ + return m_wgtChangingScreen; +} + + +/** + * @brief Initialize m_wgChangedScreen. Must be called by initUi of inheritor class + * @param a_widget pointer widget in which will be founded ChangedWidget + */ +void MultiScreenAbstract::initChangedScreen(QWidget *a_widget) +{ + // initialize default a_widget + if (!a_widget) + a_widget = variant(ScreenInfo::currentRotation()); + + // Initializing pointers to window widgets + m_wgtChangingScreen = a_widget->findChild<AnimationChangingWidget*>(); + Q_ASSERT(m_wgtChangingScreen); + + connect(m_wgtChangingScreen, &AnimationChangingWidget::animationFinished, [=]{ + emit animationFinished(); + }); + +} + diff --git a/screens/MultiScreenAbstract.h b/screens/MultiScreenAbstract.h new file mode 100755 index 0000000000000000000000000000000000000000..8cc8b5313974964aadb5cc1d090080621f39f931 --- /dev/null +++ b/screens/MultiScreenAbstract.h @@ -0,0 +1,217 @@ +/* +* Authors: +* Dmitriy Gerasimov <naeper@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2019 +* All rights reserved. + +This file is part of CellFrame SDK the open source project + +CellFrame SDK is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +CellFrame SDK is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once + +#include <QWidget> +#include "DapUiScreen.h" +#include "AdaptiveScreen.h" +#include "controls/AnimationChangingWidget.h" + + +//================================================================================= +// Interface +//================================================================================= + +/** + * @brief Abstract class wich hold AnimationChangingWidget and can hold forms and child screens for all screen sizes and rotations. + * @todo If stylesheet of AnimationChangingWidget is empty on the form, sizes will be wrong. Set wtylesheet to "*{}". + */ +class MultiScreenAbstract : public AdaptiveScreen +{ + Q_OBJECT + +protected: + MultiScreenAbstract(QWidget *parent); + +public: + template<class T> + T *createSubScreen(int a_index = -1); + + template<class T> + void removeSubscreen(); + + template<class OldT, class NewT> + NewT *replaceSubscreen(); + + template<class T> + T *subScreen(); + + template<class T> + T *activateScreen(); + + AdaptiveScreen* activeScreen(); + QString activeScreenName(); + + MultiScreenAbstract *activateChildScreen(AdaptiveScreen *a_screen); + static MultiScreenAbstract *parentMultiscreen(AdaptiveScreen *a_screen); + + AnimationChangingWidget *wgtChangingScreen(); + +signals: + void animationFinished(); ///< Emits this signal after the animation transition has reached the end. + +protected: + virtual void initChangedScreen(QWidget * a_w); ///< Find changingWidget and assign to m_wgChangedScreen + virtual void initVariantUi(QWidget * a_widget) = 0; ///<pure virtual method. Must de reimplement it inherited classes + virtual QString screenName() = 0; + + AnimationChangingWidget *m_wgtChangingScreen = nullptr; ///< Pointer to ChangingWidget controll + +private: + QMap<QString, AdaptiveScreen*> m_screens; ///< Map with all screens that can be activated +}; + + + + + + + +//================================================================================= +// Realization +//================================================================================= + + +/** + * @brief Create screen with type T if not exist + * @param T new screen type + * @return Existing or created screen + */ +template<class T> +T *MultiScreenAbstract::createSubScreen(int a_index /*= -1*/) +{ + // if subscrin exist return + T *newScreen = subScreen<T>(); + if (subScreen<T>()) + return newScreen; + + newScreen = new T(this); // Create new screen + + //insert screen to m_screens and changing sreen widget + m_screens.insert(newScreen->screenName(), newScreen); + wgtChangingScreen()->insertWidget(a_index, newScreen); + + return newScreen; +} + +/** + * @brief Remove subscreen with type T + * @details If Screen with type T is not found do nothing + * @param T Removing screen type + */ +template<class T> +void MultiScreenAbstract::removeSubscreen() +{ + AdaptiveScreen *screen = subScreen<T>(); // Find subscreen + + if (screen) { // If found ... + // 1. remove from parent ChangingWidget, ... + MultiScreenAbstract *parentScreen = qobject_cast<MultiScreenAbstract*> (screen->parent()); + parentScreen->wgtChangingScreen()->removeWidget(screen); + // 2. delete stackedWidget and screen + m_screens.remove(screen->screenName()); + // 3. delete from Map with screens pointers + delete screen; + } + // if isn't found do nothing +} + +/** + * @brief Remove screen with type OldT and create subscreen with type NewT in the place of deleted + * @param OldT Removed screen type + * @param NewT New screen type + * @return New screen + */ +template<class OldT, class NewT> +NewT *MultiScreenAbstract::replaceSubscreen() +{ + OldT *oldScreen = subScreen<OldT>(); // Find subscrin + + if (oldScreen) {// If found ... + //1. get index of oldScreen stacked widget + MultiScreenAbstract *parentScreen = qobject_cast<MultiScreenAbstract*>(oldScreen->parent()); + int index = parentScreen->wgtChangingScreen()->indexOf(oldScreen->sw()); + //2. remove oldScreen, ... + parentScreen->removeSubscreen<OldT>(); + //3. create new subscreen in the place of deleted + return parentScreen->createSubScreen<NewT>(index); + } + // if isn't found just create new + return createSubScreen<NewT>(); + +} + +/** + * @brief Find subScreen with type T in child screens recursively + * @param T searching screen type + * @return subScreen with type T + */ +template<class T> +T *MultiScreenAbstract::subScreen() +{ + T *foundScreen = nullptr; + + // If isn't found search in all subScreens recursively + auto i = m_screens.constBegin(); + while (i != m_screens.constEnd() and !foundScreen) + { + //if this screen is searched return it + foundScreen = qobject_cast<T*>(i.value()); + if (foundScreen) + return foundScreen; + + MultiScreenAbstract *curScreen = qobject_cast<MultiScreenAbstract*>(i.value()); + //if i.value() is DapUIAnimationScreenAbstract object search in all subScreens + if (curScreen) + foundScreen = curScreen->subScreen<T>(); + ++i; + } + + return foundScreen; +} + +/** + * @brief Find subScreen with type T and activate all child screens in line from this to found screen + * @param T activating screen type + * @return activated subScreen with type T + */ +template<class T> +T *MultiScreenAbstract::activateScreen() +{ + T *screen = subScreen<T>(); //< find subScreen with type T + + // If does not exist create new + if (!screen) + screen = createSubScreen<T>(); + + // Activate all parent screens in line from found screen to this + MultiScreenAbstract *parent = MultiScreenAbstract::parentMultiscreen(screen); + AdaptiveScreen *nextScreen = screen; + //do while parent is not this screen + while (nextScreen != this) { + nextScreen = parent->activateChildScreen(nextScreen); + parent = qobject_cast<MultiScreenAbstract*>(parent->parent()); + } + return screen; +} diff --git a/screens/MultiScreenWindow.cpp b/screens/MultiScreenWindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..447aeba0b347225893f8165933ad0b9e4de97795 --- /dev/null +++ b/screens/MultiScreenWindow.cpp @@ -0,0 +1,23 @@ +#include "MultiScreenWindow.h" + +#include "StartScreen.h" + +MultiScreenWindow::MultiScreenWindow(MultiScreenAbstract* a_centralScreen /*= nullptr*/, QWidget *a_parent /*= nullptr*/) + : QMainWindow(a_parent) +{ + if (!a_centralScreen) + a_centralScreen = new DefaultMultiScreen(this); + + m_centralScreen = a_centralScreen; + setCentralWidget(a_centralScreen); +} + +QString MultiScreenWindow::activeScreenName() +{ + return centralScreen()->activeScreenName(); +} + +MultiScreenAbstract *MultiScreenWindow::centralScreen() +{ + return m_centralScreen; +} diff --git a/screens/MultiScreenWindow.h b/screens/MultiScreenWindow.h new file mode 100644 index 0000000000000000000000000000000000000000..79a3e9f02462bea2ab55ff2d0f4a93fce12cc340 --- /dev/null +++ b/screens/MultiScreenWindow.h @@ -0,0 +1,42 @@ +#ifndef MULTISCREENWINDOW_H +#define MULTISCREENWINDOW_H + +#include <QMainWindow> +#include "DefaultMultiScreen.h" +class MultiScreenWindow : public QMainWindow +{ + Q_OBJECT + + using QMainWindow::setCentralWidget; //disable access to setCentralWidget. +public: + explicit MultiScreenWindow(MultiScreenAbstract* a_centralScreen = nullptr, QWidget *a_parent = nullptr); + + MultiScreenAbstract* centralScreen(); + MultiScreenAbstract* m_centralScreen; + + QString activeScreenName(); + + template <typename T> + T* screen(); + + template <typename T> + T* activateScreen(); + +private: + QString m_activeScreen; +}; + + +template <typename T> +T* MultiScreenWindow::screen(){ + return this->centralScreen()->subScreen<T>(); +} + +template <typename T> +T* MultiScreenWindow::activateScreen() +{ + return this->centralScreen()->activateScreen<T>(); +} + + +#endif // MULTISCREENWINDOW_H diff --git a/screens/screens.pri b/screens/screens.pri new file mode 100644 index 0000000000000000000000000000000000000000..ce93b4f0fbebe7e8374759fe2cc0136b20a02c4c --- /dev/null +++ b/screens/screens.pri @@ -0,0 +1,14 @@ + +HEADERS += \ + $$PWD/AdaptiveScreen.h \ + $$PWD/DefaultMultiScreen.h \ + $$PWD/MultiScreenAbstract.h \ + $$PWD/MultiScreenWindow.h + +SOURCES += \ + $$PWD/AdaptiveScreen.cpp \ + $$PWD/DefaultMultiScreen.cpp \ + $$PWD/MultiScreenAbstract.cpp \ + $$PWD/MultiScreenWindow.cpp + +INCLUDEPATH += $$PWD