From e371e2ead1fa0833a86f8a7788ece3136db75e33 Mon Sep 17 00:00:00 2001
From: "simon.fanetti" <simon.fanetti@etu.hesge.ch>
Date: Sun, 24 May 2020 18:54:11 +0200
Subject: [PATCH] add edit mask on UI

---
 app/SandboxSetup/croppingmask.cpp |  1 +
 app/SandboxSetup/maskedit.cpp     | 90 ++++++++++++++++++++++++++-----
 app/SandboxSetup/maskedit.h       | 10 ++++
 3 files changed, 88 insertions(+), 13 deletions(-)

diff --git a/app/SandboxSetup/croppingmask.cpp b/app/SandboxSetup/croppingmask.cpp
index da305cd..96dda9e 100644
--- a/app/SandboxSetup/croppingmask.cpp
+++ b/app/SandboxSetup/croppingmask.cpp
@@ -10,6 +10,7 @@ CroppingMask::CroppingMask(SandboxSetup *sandbox, QWidget *parent) :
     ui->setupUi(this);
     maskEdit = new MaskEdit(ui->frame->geometry());
     ui->vLayout->addWidget(maskEdit, 1);
+
     // TODO : try to load cropping mask from file
 
 }
diff --git a/app/SandboxSetup/maskedit.cpp b/app/SandboxSetup/maskedit.cpp
index d5392ad..3207629 100644
--- a/app/SandboxSetup/maskedit.cpp
+++ b/app/SandboxSetup/maskedit.cpp
@@ -5,7 +5,9 @@ MaskEdit::MaskEdit(const QRect geo, QWidget *parent) :
     QFrame(parent),
     ui(new Ui::MaskEdit)
 {
+    this->installEventFilter(this);
     ui->setupUi(this);
+    // set size like the parent widget's size
     setGeometry(0,0, geo.width(), geo.height());
     ui->lblFrame->setGeometry(0,0, width(), height());
 }
@@ -19,21 +21,22 @@ MaskEdit::~MaskEdit()
 void MaskEdit::updateFrame(cv::Mat *frame, std::vector<cv::Point> *points){
     capture = frame;
     rectPoints = points;
+    if(frame != nullptr && points != nullptr){
+        ratioX = (float)capture->size().width / ui->lblFrame->width();
+        ratioY = (float)capture->size().height / ui->lblFrame->height();
+    }
     update();
 }
 
 void MaskEdit::updateFrame(cv::Mat *frame){
-    capture = frame;
-    update();
+    updateFrame(frame, rectPoints);
 }
 
 void MaskEdit::updateFrame(std::vector<cv::Point> *points){
-    rectPoints = points;
-    update();
+    updateFrame(capture, points);
 }
 
 
-
 void MaskEdit::paintEvent(QPaintEvent *){
 
     if(capture != nullptr){
@@ -64,16 +67,77 @@ void MaskEdit::paintEvent(QPaintEvent *){
     }
 }
 
-/*
-void CroppingMask::scaleMaskWindowToFrame(){
 
-    float xCoeff = cameraRGBFrame.size().width / ui->vLayout->width();
-    float yCoeff = cameraRGBFrame.size().height / ui->vLayout->height();
+bool MaskEdit::eventFilter(QObject *object, QEvent *ev)
+{
+    if (ev->type() == QEvent::MouseButtonPress){
+
+        selectedCornerIndex = selectCorner((QMouseEvent*)ev);
+    }
+    else if (ev->type() == QEvent::MouseButtonRelease){
+
+        selectedCornerIndex = -1;
+    }
+    else if (ev->type() == QEvent::MouseMove){
+
+        QMouseEvent* eMouse = (QMouseEvent*)ev;
+        if (eMouse->type() == QMouseEvent::MouseMove){
+
+            UpdateSelectedCornerPosition(eMouse);
+        }
+    }
+
+    (void)object; // var unused
+    return false;
+}
+
+
 
-    for(uint i=0; i<rectPoints.size(); i++){
-        rectPoints[i].x = rectPoints[i].x * xCoeff;
-        rectPoints[i].y = rectPoints[i].y * yCoeff;
+int MaskEdit::selectCorner(QMouseEvent* eMouse){
+
+    if(capture != nullptr && rectPoints != nullptr){
+
+        int margin = 20;
+
+        // x and y relative to the captured frame, not the UI
+        int mouseX = (int)( (float)eMouse->x() * ratioX );
+        int mouseY = (int)( (float)eMouse->y() * ratioY );
+        int marginX = (int)( margin * ratioX );
+        int marginY = (int)( margin * ratioY );
+
+        for(uint i=0; i<rectPoints->size(); i++){
+
+            int x = rectPoints->at(i).x;
+            int y = rectPoints->at(i).y;
+
+            if( (x-marginX <= mouseX && mouseX <= x+marginX) &&
+                (y-marginY <= mouseY && mouseY <= y+marginY) )
+                {
+
+                return (int)i;
+            }
+        }
     }
 
+    return -1;
 }
-*/
+
+
+void MaskEdit::UpdateSelectedCornerPosition(QMouseEvent* eMouse){
+
+    if(capture != nullptr && rectPoints != nullptr){
+        if(selectedCornerIndex != -1){
+            if( (0 <= eMouse->x() && eMouse->x() < ui->lblFrame->width()) &&
+                (0 <= eMouse->y() && eMouse->y() < ui->lblFrame->height()) )
+                {
+
+                int mouseX = (int)( (float)eMouse->x() * ratioX );
+                int mouseY = (int)( (float)eMouse->y() * ratioY );
+                rectPoints->at(selectedCornerIndex).x = mouseX;
+                rectPoints->at(selectedCornerIndex).y = mouseY;
+                update();
+            }
+        }
+    }
+}
+
diff --git a/app/SandboxSetup/maskedit.h b/app/SandboxSetup/maskedit.h
index ee6ce86..32448dd 100644
--- a/app/SandboxSetup/maskedit.h
+++ b/app/SandboxSetup/maskedit.h
@@ -4,6 +4,7 @@
 #include <QPen>
 #include <QPainter>
 #include <QFrame>
+#include <QMouseEvent>
 #include <opencv2/opencv.hpp>
 
 namespace Ui {
@@ -20,11 +21,20 @@ public:
     void updateFrame(cv::Mat *frame, std::vector<cv::Point> *points);
     void updateFrame(cv::Mat *frame);
     void updateFrame(std::vector<cv::Point> *points);
+    virtual bool eventFilter(QObject *object, QEvent *ev) override;
 
 private:
     Ui::MaskEdit *ui;
     cv::Mat *capture = nullptr;
     std::vector<cv::Point> *rectPoints = nullptr;
+    int selectedCornerIndex = -1;
+
+    // relative to the captured frame, not the UI
+    float ratioX = 1.0f;
+    float ratioY = 1.0f;
+
+    int selectCorner(QMouseEvent* eMouse);
+    void UpdateSelectedCornerPosition(QMouseEvent* eMouse);
 
 protected:
     void paintEvent(QPaintEvent* event);
-- 
GitLab