/*********************************************************************/
/* */
/* Copyright 2022-2023 Rémi Synave - remi.synave@univ-littoral.fr */
/* */
/* This file is part of DSL. */
/* This software uses Qt to build the Graphical User Interface */
/* https://www.qt.io/ */
/* */
/* DSL 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. */
/* */
/* DSL 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 DSL. If not, see . */
/* */
/*********************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include "WorkArea.hpp"
WorkArea::WorkArea (int screenSizeX, int screenSizeY, QWidget * parent):
QWidget(parent)
{
this->screenSizeX = screenSizeX;
this->screenSizeY = screenSizeY;
readOnly = false;
modificationInProgress = false;
img = NULL;
resizeFactor = 1;
indexPointClicked = -1;
maxLines = 0;
}
WorkArea::WorkArea (int screenSizeX, int screenSizeY, const std::string & filename, QWidget * parent):QWidget(parent)
{
this->screenSizeX = screenSizeX;
this->screenSizeY = screenSizeY;
readOnly = false;
modificationInProgress = false;
img = NULL;
resizeFactor = 1;
indexPointClicked = -1;
maxLines = 0;
loadImage(filename);
}
WorkArea::WorkArea (int screenSizeX, int screenSizeY, const std::string & imageFilename, const std::string & SLFilename, bool readOnly, QWidget * parent):QWidget(parent)
{
this->screenSizeX = screenSizeX;
this->screenSizeY = screenSizeY;
readOnly = false;
modificationInProgress = false;
img = NULL;
resizeFactor = 1;
indexPointClicked = -1;
maxLines = 0;
loadImage(imageFilename);
this->readOnly = readOnly;
loadSL(SLFilename);
}
WorkArea::~WorkArea ()
{
}
void
WorkArea::loadImage (const std::string & filename)
{
QImageReader qImgReader(QString::fromStdString (filename));
qImgReader.setAutoTransform(true);
original = new QImage (qImgReader.read());
img =
new QImage (original->scaled (screenSizeX, screenSizeY - this->geometry ().y (),
Qt::KeepAspectRatio, Qt::FastTransformation));
resizeFactor = (img->width()*1.0)/original->width();
liste_points.clear ();
setFixedSize (img->width (), img->height ());
}
void
WorkArea::loadSL (const std::string & filename)
{
liste_points.clear();
QFile fin(QString::fromStdString (filename));
fin.open(QIODevice::ReadOnly);
QByteArray ba2 = fin.readAll();
QJsonParseError parseError;
QJsonDocument doc2 = QJsonDocument::fromJson(ba2, &parseError);
QJsonArray lines = doc2["lines"].toArray();
for(int i=0; ix ()/resizeFactor);
point1.push_back(liste_points[i*2]->y ()/resizeFactor);
line.push_back(point1);
QJsonArray point2;
point2.push_back(liste_points[i*2+1]->x ()/resizeFactor);
point2.push_back(liste_points[i*2+1]->y ()/resizeFactor);
line.push_back(point2);
lines.push_back(line);
}
root["lines"] = lines;
QByteArray ba = QJsonDocument(root).toJson();
QFile fout(QString::fromStdString (filename));
fout.open(QIODevice::WriteOnly);
fout.write(ba);
this->modificationInProgress = false;
}
void
WorkArea::exportPNG (const std::string & filename)
{
QImage tempImg(*original);
QPainter painter(&tempImg);
for (int i = 0; i < liste_points.length (); i++)
{
if ((i % 2) == 1)
{
painter.setPen (QPen (Qt::red, epaisseurLigne/resizeFactor));
std::pair < QPoint *, QPoint * > endPoints =
StrengthLine (liste_points[i - 1], liste_points[i]).toDraw (&tempImg);
painter.drawLine (*(std::get < 0 > (endPoints))/resizeFactor,
*(std::get < 1 > (endPoints))/resizeFactor);
}
}
tempImg.save(QString::fromStdString (filename));
}
void
WorkArea::setReadOnly(bool readOnly){
this->readOnly = readOnly;
}
bool
WorkArea::getReadOnly(){
return this->readOnly;
}
QImage*
WorkArea::getOriginalImage() const
{
return new QImage(*original);
}
QImage*
WorkArea::getResizedImage() const
{
return new QImage(*img);
}
void
WorkArea::setModificationInProgress(bool mip){
this->modificationInProgress = mip;
}
bool
WorkArea::getModificationInProgress(){
return this->modificationInProgress;
}
int
WorkArea::getNumberOfLines() const
{
return ((int)(liste_points.size()/2));
}
void
WorkArea::addSL (const StrengthLine *sl)
{
liste_points << new QPoint((int)(sl->getP1()->x()*resizeFactor), (int)(sl->getP1()->y()*resizeFactor));
liste_points << new QPoint((int)(sl->getP2()->x()*resizeFactor), (int)(sl->getP2()->y()*resizeFactor));
}
void
WorkArea::addRandomSL ()
{
StrengthLine *sl = StrengthLine::getRandomLine(original);
liste_points << new QPoint((int)(sl->getP1()->x()*resizeFactor), (int)(sl->getP1()->y()*resizeFactor));
liste_points << new QPoint((int)(sl->getP2()->x()*resizeFactor), (int)(sl->getP2()->y()*resizeFactor));
}
void
WorkArea::paintEvent (QPaintEvent * event)
{
QPainter painter (this);
paint (painter);
}
void
WorkArea::paint (QPainter & painter)
{
if (img != NULL)
painter.drawImage (0, 0, *img);
for (int i = 0; i < liste_points.length (); i++)
{
if(readOnly==false)
{
painter.setBrush (QBrush (Qt::green));
painter.setPen (QPen (Qt::black));
painter.drawEllipse (liste_points[i]->x () - taillePoint / 2,
liste_points[i]->y () - taillePoint / 2,
taillePoint, taillePoint);
}
if ((i % 2) == 1)
{
painter.setPen (QPen (Qt::red, epaisseurLigne));
std::pair < QPoint *, QPoint * >endPoints =
StrengthLine (liste_points[i - 1], liste_points[i]).toDraw (img);
painter.drawLine (*(std::get < 0 > (endPoints)),
*(std::get < 1 > (endPoints)));
}
}
}
void
WorkArea::mousePressEvent (QMouseEvent * event)
{
if(readOnly==false)
{
if (img != NULL)
{
this->modificationInProgress = true;
// Est ce qu'on a cliqué sur un point existant ?
indexPointClicked = -1;
for (int i = 0; i < liste_points.length (); i++)
{
QPoint point = event->pos () - *(liste_points[i]);
if (point.manhattanLength () < taillePoint)
{
indexPointClicked = i;
}
}
// Clic gauche
if (event->button () == Qt::LeftButton)
{
if (indexPointClicked == -1)
{
if((maxLines == 0) || (liste_points.size()<(maxLines*2))){
indexPointClicked = liste_points.size ();
liste_points << new QPoint (event->x (), event->y ());
}
}
}
// Clic droit
if (event->button () == Qt::RightButton)
{
if (indexPointClicked != -1)
{
if (indexPointClicked == (liste_points.size () - 1))
liste_points.removeAt (indexPointClicked);
else
{
if ((indexPointClicked % 2) == 0)
{
QPoint *single =
liste_points.takeAt (indexPointClicked + 1);
liste_points.removeAt (indexPointClicked);
liste_points << single;
}
else
{
QPoint *single =
liste_points.takeAt (indexPointClicked - 1);
liste_points.removeAt (indexPointClicked - 1);
liste_points << single;
}
}
indexPointClicked = -1;
}
}
}
}
repaint ();
}
void
WorkArea::mouseMoveEvent (QMouseEvent * event)
{
if(readOnly==false)
{
if (indexPointClicked != -1)
{
liste_points[indexPointClicked]->setX (event->x ());
liste_points[indexPointClicked]->setY (event->y ());
}
}
repaint ();
}
void
WorkArea::mouseReleaseEvent (QMouseEvent * event)
{
indexPointClicked = -1;
}