From f8aa203b9d311ffd5ca3764fb7f8f0e10ecfbb46 Mon Sep 17 00:00:00 2001
From: Pos <pierpaolo.mancini@mail.polimi.it>
Date: Sat, 12 Dec 2020 21:19:15 +0100
Subject: [PATCH] Added scroll area module

---
 Modules/ImageViewer/imagevieweritem.cpp     | 60 +++++++-------
 Modules/ImageViewer/imagevieweritem.h       | 13 +--
 Modules/ImageViewer/imageviewermodule.cpp   |  8 +-
 Modules/ImageViewer/imageviewersettings.cpp |  6 ++
 Modules/ScrollArea/scrollareamodule.cpp     | 90 +++++++++++++++++++++
 Modules/ScrollArea/scrollareamodule.h       | 36 +++++++++
 Modules/ScrollArea/scrollareamodule.ui      | 53 ++++++++++++
 Modules/moduleinfo.h                        |  3 +-
 Modules/moduleslist.cpp                     |  8 ++
 SkywardHub.pro                              |  3 +
 SkywardHub.pro.user                         |  2 +-
 11 files changed, 242 insertions(+), 40 deletions(-)
 create mode 100644 Modules/ScrollArea/scrollareamodule.cpp
 create mode 100644 Modules/ScrollArea/scrollareamodule.h
 create mode 100644 Modules/ScrollArea/scrollareamodule.ui

diff --git a/Modules/ImageViewer/imagevieweritem.cpp b/Modules/ImageViewer/imagevieweritem.cpp
index 3b8b745d..1c19a7fa 100644
--- a/Modules/ImageViewer/imagevieweritem.cpp
+++ b/Modules/ImageViewer/imagevieweritem.cpp
@@ -84,16 +84,16 @@ void ImageViewerItem::operator =(const ImageViewerItem &other)
 bool ImageViewerItem::onMouseMoved(const QPointF &point)
 {
     bool needUpdate = false;
-    if(isPointInsideMyArea(point)){
-        setClicked(true);
-        needUpdate = true;
-    }
-    else{
-        if(getClicked()){
-            setClicked(false);
-            needUpdate = true;
-        }
-    }
+//    if(isPointInsideMyArea(point)){
+//        setClicked(true);
+//        needUpdate = true;
+//    }
+//    else{
+//        if(getClicked()){
+//            setClicked(false);
+//            needUpdate = true;
+//        }
+//    }
 
     if(isDragActive){
         QPointF newTopPosition(point.x() - dragOffset.x(), point.y() - dragOffset.y());
@@ -156,6 +156,12 @@ void ImageViewerItem::setTopLeftCornerPosition(const QPointF &value)
     topLeftCornerPosition = value;
 }
 
+void ImageViewerItem::setTopic(const QString &topic)
+{
+    XmlObject *xmlTopic = findOrAddXmlObject("topic");
+    xmlTopic->setTextValue(topic);
+}
+
 void ImageViewerItem::initialize()
 {
     xml.setObjectName("svg");
@@ -167,7 +173,7 @@ void ImageViewerItem::initialize()
     rect.addAttribute("height", QString::number(s.height()));
     rect.addAttribute("width", QString::number(s.width()));    
     rect.addAttribute("fill", "none");
-    rect.addAttribute("stroke", getCurrentBorderColor());
+    rect.addAttribute("stroke", "#000000");
     rect.addAttribute("stroke-width", "2");
 
     XmlObject text("text");
@@ -204,22 +210,22 @@ void ImageViewerItem::setXml(const XmlObject &value)
     }
 }
 
-QString ImageViewerItem::getCurrentBorderColor() const
-{
-    if(getClicked())
-        return clickedBorderColor;
-    return defaultBorderColor;
-}
-
-bool ImageViewerItem::getClicked() const
-{
-    return clicked;
-}
-
-void ImageViewerItem::setClicked(bool value)
-{
-    clicked = value;
-}
+//QString ImageViewerItem::getCurrentBorderColor() const
+//{
+//    if(getClicked())
+//        return clickedBorderColor;
+//    return defaultBorderColor;
+//}
+
+//bool ImageViewerItem::getClicked() const
+//{
+//    return clicked;
+//}
+
+//void ImageViewerItem::setClicked(bool value)
+//{
+//    clicked = value;
+//}
 
 QSize ImageViewerItem::getSize() const
 {
diff --git a/Modules/ImageViewer/imagevieweritem.h b/Modules/ImageViewer/imagevieweritem.h
index 6ae4f9e3..e6ef6ae8 100644
--- a/Modules/ImageViewer/imagevieweritem.h
+++ b/Modules/ImageViewer/imagevieweritem.h
@@ -35,16 +35,17 @@ public:
     int getId() const;
     void setId(int value);
 
-    bool getClicked() const;
-    void setClicked(bool value);
+//    bool getClicked() const;
+//    void setClicked(bool value);
 
     QString getCurrentBorderColor() const;
 
     void setXml(const XmlObject &value);
+    void setTopLeftCornerPosition(const QPointF &value);
+    void setTopic(const QString &topic);
 
 protected:
     void copy(const ImageViewerItem &other);
-    void setTopLeftCornerPosition(const QPointF &value);
     void initialize();
 
     XmlObject *findOrAddXmlObject(const QString &xmlChildName);
@@ -53,12 +54,12 @@ private:
     int id = -1;
     QPointF topLeftCornerPosition;
 
-    const QString defaultBorderColor = "#000000";
-    const QString clickedBorderColor = "#32a83a";
+//    const QString defaultBorderColor = "#000000";
+//    const QString clickedBorderColor = "#32a83a";
     const QSize defaultSize = QSize(250, 150);
     const QString defaultText = "New item";
 
-    bool clicked = false;
+//    bool clicked = false;
     QPointF dragOffset;
     bool isDragActive = false;
 
diff --git a/Modules/ImageViewer/imageviewermodule.cpp b/Modules/ImageViewer/imageviewermodule.cpp
index 388628ad..4585d8f5 100644
--- a/Modules/ImageViewer/imageviewermodule.cpp
+++ b/Modules/ImageViewer/imageviewermodule.cpp
@@ -143,7 +143,6 @@ void ImageViewerModule::onChangeImageRequested()
 }
 
 
-
 void ImageViewerModule::fitImage()
 {
     ui->graphicsView->fitInView(&backgroundImg, Qt::KeepAspectRatio);
@@ -269,13 +268,12 @@ void ImageViewerModule::onSettingsSetupToAllRequested()
         ImageViewerItem* item = imageViewerItems[key];
         QString previousText = item->getText();
         QString previousTopic = item->getTopic();
+        QPointF previousPosition = item->getTopLeftCornerPosition();
         item->setXml(settingsPanel.getDefaultSettings());
         item->setText(previousText);
+        item->setTopLeftCornerPosition(previousPosition);
+        item->setTopic(previousTopic);
         scene.updateImageViewItem(item);
-
-        if(item->getTopic() != previousTopic){
-            onItemTopicChanged(item);
-        }
     }
 }
 
diff --git a/Modules/ImageViewer/imageviewersettings.cpp b/Modules/ImageViewer/imageviewersettings.cpp
index bb14139d..a8c786d9 100644
--- a/Modules/ImageViewer/imageviewersettings.cpp
+++ b/Modules/ImageViewer/imageviewersettings.cpp
@@ -204,6 +204,12 @@ void ImageViewerSettings::updateUI(XmlObject &xml)
         ui->lineEdit_border_color->setText(border->getAttribute("stroke"));
         ui->lineEdit_fillColor->setText(border->getAttribute("fill"));
     }
+
+    childs = xml.deepSearchObjects("topic");
+    if(!childs.isEmpty()){
+        XmlObject *topicXml = childs[0];
+        ui->lineEdit_topic->setText(topicXml->getTextValue());
+    }
 }
 
 void ImageViewerSettings::resizeEvent(QResizeEvent *event)
diff --git a/Modules/ScrollArea/scrollareamodule.cpp b/Modules/ScrollArea/scrollareamodule.cpp
new file mode 100644
index 00000000..6b8928ca
--- /dev/null
+++ b/Modules/ScrollArea/scrollareamodule.cpp
@@ -0,0 +1,90 @@
+#include "scrollareamodule.h"
+#include "ui_scrollareamodule.h"
+
+#include "Core/module.h"
+#include "Core/modulesmanager.h"
+#include "Core/moduleeventshandler.h"
+
+ScrollAreaModule::ScrollAreaModule(QWidget *parent) : DefaultModule(parent), ui(new Ui::ScrollAreaModule)
+{
+    ui->setupUi(this);
+    defaultContextMenuSetup();
+}
+
+ScrollAreaModule::~ScrollAreaModule()
+{
+    clearModuleList();
+    delete ui;
+}
+
+
+QWidget *ScrollAreaModule::toWidget()
+{
+    return this;
+}
+
+XmlObject ScrollAreaModule::toXmlObject()
+{
+    return XmlObject(getName(ModuleId::SCROLLAREA));
+}
+
+void ScrollAreaModule::fromXmlObject(const XmlObject &xmlObject)
+{
+    Q_UNUSED(xmlObject);
+}
+
+void ScrollAreaModule::clearModuleList()
+{
+    QList<Module*> list = this->modulesList;
+    for(int i = 0; i <list.count(); i++){
+        delete list[i];
+    }
+    modulesList.clear();
+}
+
+void ScrollAreaModule::onModuleBeforeDelete(Module *module)
+{
+    if(module != nullptr){
+        modulesList.removeAll(module);
+    }
+}
+
+void ScrollAreaModule::addCustomActionsToMenu()
+{
+    QAction* addItem = new QAction("Add Item");
+    connect(addItem, &QAction::triggered,this, &ScrollAreaModule::onAddItemClicked);
+    addActionToMenu(addItem);
+}
+
+void ScrollAreaModule::onAddItemClicked()
+{
+    Module* module = getCore()->getModulesManager()->instantiateDefaultModule();
+    addModule(module);
+}
+
+
+void ScrollAreaModule::addModule(Module *module, int position)
+{
+    ui->scrollArea_mainLayout->insertWidget(position, module->toWidget());
+    if(position < modulesList.count()){
+        modulesList.insert(position, module);
+    }
+    else{
+        modulesList.append(module);
+    }
+    connect(module->getModuleEventsHandler(),&ModuleEventsHandler::beforeDelete, this, &ScrollAreaModule::onModuleBeforeDelete);
+    connect(module->getModuleEventsHandler(),&ModuleEventsHandler::contextMenuRequest,this,&ScrollAreaModule::onSkywardHubContextMenuRequested);
+    connect(module->getModuleEventsHandler(),&ModuleEventsHandler::replaceMeWith, [this](Module* sender, Module* newModule){
+        this->replace(sender,newModule);
+    });
+}
+
+void ScrollAreaModule::replace(Module *oldModule, Module *newModule)
+{
+    int indexOfModule = modulesList.indexOf(oldModule);
+    if(indexOfModule < 0)
+        return;
+
+    modulesList[indexOfModule] = newModule;
+    addModule(newModule, indexOfModule);
+}
diff --git a/Modules/ScrollArea/scrollareamodule.h b/Modules/ScrollArea/scrollareamodule.h
new file mode 100644
index 00000000..84bd3321
--- /dev/null
+++ b/Modules/ScrollArea/scrollareamodule.h
@@ -0,0 +1,36 @@
+#ifndef SCROLLAREAMODULE_H
+#define SCROLLAREAMODULE_H
+
+#include "Modules/DefaultModule/defaultmodule.h"
+
+namespace Ui {
+class ScrollAreaModule;
+}
+
+class ScrollAreaModule : public DefaultModule
+{
+    Q_OBJECT
+
+public:
+    explicit ScrollAreaModule(QWidget *parent = nullptr);
+    ~ScrollAreaModule();
+
+    QWidget *toWidget() override;
+    XmlObject toXmlObject() override;
+    void fromXmlObject(const XmlObject &xmlObject) override;
+
+protected:
+    void addCustomActionsToMenu() override;
+    void onAddItemClicked();
+
+    void clearModuleList();
+    void onModuleBeforeDelete(Module *module);
+    void addModule(Module *module, int position = 0);
+    void replace(Module *oldModule, Module *newModule);
+
+private:
+    Ui::ScrollAreaModule *ui;
+    QList<Module*> modulesList;
+};
+
+#endif // SCROLLAREAMODULE_H
diff --git a/Modules/ScrollArea/scrollareamodule.ui b/Modules/ScrollArea/scrollareamodule.ui
new file mode 100644
index 00000000..a27d231d
--- /dev/null
+++ b/Modules/ScrollArea/scrollareamodule.ui
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ScrollAreaModule</class>
+ <widget class="QWidget" name="ScrollAreaModule">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QScrollArea" name="scrollArea">
+     <property name="widgetResizable">
+      <bool>true</bool>
+     </property>
+     <widget class="QWidget" name="scrollAreaWidgetContents">
+      <property name="geometry">
+       <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>378</width>
+        <height>278</height>
+       </rect>
+      </property>
+      <layout class="QVBoxLayout" name="scrollArea_mainLayout">
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>255</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Modules/moduleinfo.h b/Modules/moduleinfo.h
index f36e1dc0..b4fda6b1 100644
--- a/Modules/moduleinfo.h
+++ b/Modules/moduleinfo.h
@@ -18,7 +18,8 @@ enum ModuleId{
     MESSAGEVIEWER,
     MAVLINK,
     FSMVIEWER,
-    TREEVIEWER
+    TREEVIEWER,
+    SCROLLAREA
 };
 
 enum ModuleCategory{
diff --git a/Modules/moduleslist.cpp b/Modules/moduleslist.cpp
index 7885ea3c..5f8ab855 100644
--- a/Modules/moduleslist.cpp
+++ b/Modules/moduleslist.cpp
@@ -16,6 +16,7 @@
 #include "Modules/Mavlink/mavlinkmodule.h"
 #include "Modules/Fsm/fsmviewermodule.h"
 #include "Modules/TreeViewer/treeviewermodule.h"
+#include "Modules/ScrollArea/scrollareamodule.h"
 
 void ModulesList::createModuleList()
 {
@@ -121,6 +122,13 @@ void ModulesList::createModuleList()
     treeViewer.addModuleSourceFiles("Modules/TreeViewer/");
     addModuleInfo(treeViewer);
     #endif
+
+    #ifdef SCROLLAREAMODULE_H
+    ModuleInfo scrollArea(ModuleId::SCROLLAREA, "ScrollArea", ModuleCategory::UTILITY);
+    scrollArea.setFactory([](){return new ScrollAreaModule();});
+    scrollArea.addModuleSourceFiles("Modules/ScrollArea/");
+    addModuleInfo(scrollArea);
+    #endif
 }
 
 
diff --git a/SkywardHub.pro b/SkywardHub.pro
index c0364dbf..c47107d4 100644
--- a/SkywardHub.pro
+++ b/SkywardHub.pro
@@ -47,6 +47,7 @@ SOURCES += \
     Modules/Mavlink/mavlinkreader.cpp \
     Modules/Mavlink/mavlinkwriter.cpp \
     Modules/MessageViewer/messagesviewermodule.cpp \
+    Modules/ScrollArea/scrollareamodule.cpp \
     Modules/SkywardHub/deployer.cpp \
     Modules/SkywardHub/deployerpathpicker.cpp \
     Modules/SkywardHub/prefabdialog.cpp \
@@ -106,6 +107,7 @@ HEADERS += \
     Modules/Mavlink/mavlinkreader.h \
     Modules/Mavlink/mavlinkwriter.h \
     Modules/MessageViewer/messagesviewermodule.h \
+    Modules/ScrollArea/scrollareamodule.h \
     Modules/SkywardHub/deployer.h \
     Modules/SkywardHub/deployerpathpicker.h \
     Modules/SkywardHub/prefabdialog.h \
@@ -140,6 +142,7 @@ FORMS += \
     Modules/MainWindow/window.ui \
     Modules/Mavlink/mavlinkmodule.ui \
     Modules/MessageViewer/messagesviewermodule.ui \
+    Modules/ScrollArea/scrollareamodule.ui \
     Modules/SkywardHub/deployerpathpicker.ui \
     Modules/SkywardHub/prefabdialog.ui \
     Modules/SkywardHub/prefabviewelement.ui \
diff --git a/SkywardHub.pro.user b/SkywardHub.pro.user
index 7a28e25a..78cbef79 100644
--- a/SkywardHub.pro.user
+++ b/SkywardHub.pro.user
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.13.0, 2020-12-09T20:21:36. -->
+<!-- Written by QtCreator 4.13.0, 2020-12-12T21:18:43. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
-- 
GitLab