Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LO21_Pin_Noir_Boucher_Bouri_Detree
CellulutLO21
Commits
e3b7103a
Commit
e3b7103a
authored
May 22, 2021
by
Yann Boucher
Browse files
Added support for dragging and dropping structures
parent
ed9c113c
Pipeline
#78341
passed with stages
in 17 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
forms/structurelibraryview.ui
View file @
e3b7103a
...
...
@@ -7,7 +7,7 @@
<x>
0
</x>
<y>
0
</y>
<width>
400
</width>
<height>
3
0
0
</height>
<height>
3
7
0
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
...
...
@@ -145,6 +145,13 @@
</property>
</widget>
</item>
<item>
<widget
class=
"QLabel"
name=
"label_5"
>
<property
name=
"text"
>
<string>
Double clic pour faire un glisser-déposer de la structure.
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QPushButton"
name=
"button_copy"
>
<property
name=
"enabled"
>
...
...
include/gridview.hpp
View file @
e3b7103a
...
...
@@ -33,7 +33,9 @@ class GridGraphicsView : public QGraphicsView
public:
GridGraphicsView
(
GridView
&
gridview
,
QWidget
*
parent
)
:
QGraphicsView
(
parent
),
m_gridview
(
gridview
)
{}
{
setAcceptDrops
(
true
);
}
protected:
void
mousePressEvent
(
QMouseEvent
*
event
);
...
...
@@ -54,6 +56,8 @@ public:
void
set_current_pen
(
unsigned
state
);
unsigned
current_pen
()
const
;
void
paste_structure_at
(
Coord
origin
,
const
Structure
&
s
);
void
set_clipboard
(
const
Structure
&
s
);
void
copy_grid
(
const
Grid
&
grid
);
...
...
include/structurelibraryview.hpp
View file @
e3b7103a
...
...
@@ -30,8 +30,10 @@ signals:
private:
void
load_structures
();
QTreeWidgetItem
*
add_directory_contents
(
const
QDir
&
dir
);
bool
load_structure
(
const
QString
&
filename
,
Structure
&
s
);
bool
try_
load_structure
(
const
QString
&
filename
,
Structure
&
s
);
void
update_preview
(
const
Structure
&
s
);
QImage
create_preview_image
(
const
Structure
&
s
,
QColor
background
);
void
create_drag
(
QTreeWidgetItem
*
item
,
int
column
);
private
slots
:
void
update_info
(
QTreeWidgetItem
*
item
,
int
column
);
...
...
include/structurereader.hpp
View file @
e3b7103a
...
...
@@ -98,5 +98,8 @@ public:
virtual
Structure
read_structure
();
};
//! Lit une structure à partir d'un chemin de fichier, en déterminant automatiquement le type de format de structure
//! \exception StructureReaderException en cas de problème
Structure
load_structure
(
const
std
::
string
&
path
);
#endif // STRUCTUREREADER_HPP
src/gridview.cpp
View file @
e3b7103a
...
...
@@ -18,6 +18,7 @@ Cette classe représente le widget utilisé pour l'affichage et l'interaction av
#include
<QGridLayout>
#include
<QToolTip>
#include
<QLabel>
#include
<QMimeData>
#include
<QDebug>
...
...
@@ -25,17 +26,22 @@ Cette classe représente le widget utilisé pour l'affichage et l'interaction av
#include
<qmath.h>
#include
"structurereader.hpp"
class
GridItem
:
public
QGraphicsRectItem
{
public:
GridItem
(
QColor
color
,
const
QString
&
state_name
,
QGraphicsItem
*
parent
=
nullptr
)
:
QGraphicsRectItem
(
0
,
0
,
GridItem
::
width
(),
GridItem
::
height
(),
parent
),
m_state_name
(
state_name
)
GridItem
(
GridView
&
in_gridview
,
QColor
color
,
const
QString
&
state_name
,
QGraphicsItem
*
parent
=
nullptr
)
:
QGraphicsRectItem
(
0
,
0
,
GridItem
::
width
(),
GridItem
::
height
(),
parent
),
grid_view
(
in_gridview
),
m_state_name
(
state_name
)
{
setAcceptHoverEvents
(
true
);
setPen
(
QPen
(
QBrush
(
color
),
0
));
setBrush
(
QBrush
(
color
));
setToolTip
(
m_state_name
);
setFlag
(
QGraphicsItem
::
ItemIsSelectable
);
setAcceptDrops
(
true
);
view
=
nullptr
;
}
static
int
width
()
...
...
@@ -44,13 +50,17 @@ public:
{
return
20
;
}
protected:
void
paint
(
QPainter
*
painter
,
const
QStyleOptionGraphicsItem
*
,
QWidget
*
)
void
paint
(
QPainter
*
painter
,
const
QStyleOptionGraphicsItem
*
,
QWidget
*
)
override
{
assert
(
scene
()
->
views
().
size
()
!=
0
);
QGraphicsView
*
view
=
scene
()
->
views
().
first
();
if
(
!
view
)
{
assert
(
scene
()
->
views
().
size
()
!=
0
);
view
=
scene
()
->
views
().
first
();
}
QSizeF
screen_size
=
view
->
transform
().
mapRect
(
sceneBoundingRect
()).
size
();
QRectF
rect
=
boundingRec
t
();
QRectF
rect
=
QRectF
(
0
,
0
,
width
(),
heigh
t
()
)
;
if
(
screen_size
.
width
()
<
7.5
)
painter
->
setPen
(
Qt
::
NoPen
);
// if the cell is too small, don't draw its outline
...
...
@@ -69,10 +79,42 @@ protected:
painter
->
drawRect
(
rect
);
}
void
dragEnterEvent
(
QGraphicsSceneDragDropEvent
*
event
)
override
{
if
(
event
->
mimeData
()
->
hasText
())
{
event
->
acceptProposedAction
();
update
();
}
}
void
dropEvent
(
QGraphicsSceneDragDropEvent
*
event
)
override
{
event
->
acceptProposedAction
();
QString
file_path
=
event
->
mimeData
()
->
text
();
Structure
s
;
try
{
s
=
load_structure
(
file_path
.
toStdString
());
}
catch
(
const
StructureReaderException
&
e
)
{
//qDebug() << "StructureReaderException : " << e.what() << "\n";
return
;
}
grid_view
.
paste_structure_at
(
cell_pos
,
s
);
}
// infos associées à la cellule affichée
public:
unsigned
cell_state
;
Coord
cell_pos
;
QGraphicsView
*
view
;
GridView
&
grid_view
;
private:
QString
m_state_name
;
...
...
@@ -122,6 +164,7 @@ GridView::GridView(QWidget *parent)
m_view
->
setScene
(
m_scene
);
m_view
->
viewport
()
->
setCursor
(
Qt
::
ArrowCursor
);
m_view
->
setBackgroundBrush
(
QBrush
(
Qt
::
gray
));
m_view
->
setRubberBandSelectionMode
(
Qt
::
IntersectsItemBoundingRect
);
// provides better performance
detail
::
Graphics_view_zoom
*
z
=
new
detail
::
Graphics_view_zoom
(
m_view
);
(
void
)
z
;
...
...
@@ -183,7 +226,7 @@ void GridView::copy_grid(const Grid &grid)
Coord
pos
=
{
static_cast
<
int
>
(
i
),
static_cast
<
int
>
(
j
)};
unsigned
state
=
grid
.
get_state
(
pos
);
GridItem
*
item
=
new
GridItem
(
stateColor_to_QColor
(
m_alph
.
getState
(
state
).
getColor
()),
QString
::
fromStdString
(
m_alph
.
getState
(
state
).
getStateLabel
()));
GridItem
*
item
=
new
GridItem
(
*
this
,
stateColor_to_QColor
(
m_alph
.
getState
(
state
).
getColor
()),
QString
::
fromStdString
(
m_alph
.
getState
(
state
).
getStateLabel
()));
//GridItem *item = new GridItem((i ^ j) % 2 ? Qt::blue : Qt::white, (i ^ j) % 2 ? "Alive" : "Dead");
item
->
setPos
(
QPointF
(
i
*
GridItem
::
width
(),
j
*
GridItem
::
height
()));
item
->
cell_pos
=
Coord
{(
int
)
i
,
(
int
)
j
};
...
...
@@ -260,18 +303,7 @@ void GridView::paste_clipboard()
Coord
origin
=
top_left_of_selection
();
for
(
const
auto
&
cell
:
m_copy_paste_buffer
)
{
Coord
corrected
=
wrap_coords
(
cell
.
first
+
origin
,
m_width
,
m_height
);
GridItem
*
item
=
item_at
(
corrected
);
assert
(
item
!=
nullptr
);
item
->
cell_state
=
cell
.
second
;
item
->
setBrush
(
QBrush
(
stateColor_to_QColor
(
m_alph
.
getState
(
cell
.
second
).
getColor
())));
item
->
update
();
}
paste_structure_at
(
origin
,
m_copy_paste_buffer
);
}
void
GridView
::
fill_selection
(
unsigned
state
)
...
...
@@ -291,6 +323,21 @@ void GridView::delete_selection()
clear_selection
();
}
void
GridView
::
paste_structure_at
(
Coord
origin
,
const
Structure
&
s
)
{
for
(
const
auto
&
cell
:
s
)
{
Coord
corrected
=
wrap_coords
(
cell
.
first
+
origin
,
m_width
,
m_height
);
GridItem
*
item
=
item_at
(
corrected
);
assert
(
item
!=
nullptr
);
item
->
cell_state
=
cell
.
second
;
item
->
setBrush
(
QBrush
(
stateColor_to_QColor
(
m_alph
.
getState
(
cell
.
second
).
getColor
())));
item
->
update
();
}
}
Coord
GridView
::
top_left_of_selection
()
const
{
// on calcule la position du coin supérieur gauche de la sélection
...
...
src/interface.cpp
View file @
e3b7103a
...
...
@@ -4,8 +4,6 @@
#include
"structuresavingdialog.hpp"
#include
"structurewriter.hpp"
#include
<QDate>
#include
<QTextStream>
MainWindow
::
MainWindow
(
QWidget
*
parent
)
:
QMainWindow
(
parent
)
...
...
src/src.pro
View file @
e3b7103a
...
...
@@ -2,7 +2,7 @@ QT += core gui
greaterThan
(
QT_MAJOR_VERSION
,
4
)
:
QT
+=
widgets
CONFIG
+=
c
++
14
CONFIG
+=
c
++
14
TEMPLATE
=
app
#
You
can
make
your
code
fail
to
compile
if
it
uses
deprecated
APIs
.
...
...
src/structurelibraryview.cpp
View file @
e3b7103a
...
...
@@ -10,6 +10,9 @@
#include
<QTextStream>
#include
<QPixmap>
#include
<QImage>
#include
<QDrag>
#include
<QMimeData>
#include
<QDebug>
StructureLibraryView
::
StructureLibraryView
(
QWidget
*
parent
)
:
...
...
@@ -21,6 +24,7 @@ StructureLibraryView::StructureLibraryView(QWidget *parent) :
load_structures
();
connect
(
ui
->
tree
,
&
QTreeWidget
::
itemClicked
,
this
,
&
StructureLibraryView
::
update_info
);
connect
(
ui
->
tree
,
&
QTreeWidget
::
itemDoubleClicked
,
this
,
&
StructureLibraryView
::
create_drag
);
connect
(
ui
->
button_copy
,
&
QPushButton
::
pressed
,
this
,
&
StructureLibraryView
::
copy_button_clicked
);
connect
(
&
m_watcher
,
&
QFileSystemWatcher
::
directoryChanged
,
[
this
](
const
QString
&
)
{
...
...
@@ -65,7 +69,7 @@ QTreeWidgetItem *StructureLibraryView::add_directory_contents(const QDir &dir)
Q_FOREACH
(
QFileInfo
file
,
files
)
{
Structure
s
;
bool
valid
=
load_structure
(
file
.
absoluteFilePath
(),
s
);
bool
valid
=
try_
load_structure
(
file
.
absoluteFilePath
(),
s
);
if
(
!
valid
)
continue
;
...
...
@@ -83,70 +87,48 @@ QTreeWidgetItem *StructureLibraryView::add_directory_contents(const QDir &dir)
return
root
;
}
bool
StructureLibraryView
::
load_structure
(
const
QString
&
filename
,
Structure
&
s
)
bool
StructureLibraryView
::
try_
load_structure
(
const
QString
&
filename
,
Structure
&
s
)
{
QFile
f
(
filename
);
if
(
!
f
.
open
(
QFile
::
ReadOnly
|
QFile
::
Text
))
return
false
;
QTextStream
in
(
&
f
);
std
::
string
data
=
in
.
readAll
().
toStdString
();
if
(
QFileInfo
(
filename
).
suffix
()
==
"json"
)
try
{
JSONStructureReader
json
(
data
);
try
{
s
=
json
.
read_structure
();
return
true
;
}
catch
(
const
StructureReaderException
&
e
)
{
qDebug
()
<<
"StructureReaderException : "
<<
e
.
what
()
<<
"
\n
"
;
return
false
;
}
s
=
load_structure
(
filename
.
toStdString
());
return
true
;
}
else
if
(
QFileInfo
(
filename
).
suffix
()
==
"rle"
)
catch
(
const
StructureReaderException
&
e
)
{
RLEStructureReader
rle
(
data
);
try
{
s
=
rle
.
read_structure
();
return
true
;
}
catch
(
const
StructureReaderException
&
e
)
{
qDebug
()
<<
"StructureReaderException : "
<<
e
.
what
()
<<
"
\n
"
;
return
false
;
}
}
else
//qDebug() << "StructureReaderException : " << e.what() << "\n";
return
false
;
}
}
void
StructureLibraryView
::
update_preview
(
const
Structure
&
s
)
{
QPixmap
pix
;
QImage
img
(
s
.
width
(),
s
.
height
(),
QImage
::
Format_RGB32
);
img
.
fill
(
Qt
::
white
);
for
(
const
auto
&
cell
:
s
)
img
.
setPixel
(
cell
.
first
.
x
,
cell
.
first
.
y
,
Qt
::
black
);
/** to check wether load ok */
if
(
pix
.
convertFromImage
(
img
)){
if
(
pix
.
convertFromImage
(
create_preview_image
(
s
,
Qt
::
white
)
)){
/** scale pixmap to fit in label'size and keep ratio of pixmap */
pix
=
pix
.
scaled
(
ui
->
preview
->
size
()
-
2
*
QSize
(
ui
->
preview
->
lineWidth
(),
ui
->
preview
->
lineWidth
()),
Qt
::
KeepAspectRatio
);
ui
->
preview
->
setPixmap
(
pix
);
}
}
QImage
StructureLibraryView
::
create_preview_image
(
const
Structure
&
s
,
QColor
background
)
{
QImage
img
(
s
.
width
(),
s
.
height
(),
QImage
::
Format_ARGB32
);
img
.
fill
(
background
);
for
(
const
auto
&
cell
:
s
)
img
.
setPixelColor
(
cell
.
first
.
x
,
cell
.
first
.
y
,
QColor
(
Qt
::
black
));
return
img
;
}
void
StructureLibraryView
::
update_info
(
QTreeWidgetItem
*
item
,
int
column
)
{
(
void
)
column
;
Structure
s
;
if
(
!
load_structure
(
item
->
data
(
0
,
Qt
::
UserRole
).
toString
(),
s
))
if
(
!
try_
load_structure
(
item
->
data
(
0
,
Qt
::
UserRole
).
toString
(),
s
))
{
ui
->
button_copy
->
setEnabled
(
false
);
return
;
...
...
@@ -178,8 +160,35 @@ void StructureLibraryView::copy_button_clicked()
QTreeWidgetItem
*
item
=
ui
->
tree
->
selectedItems
()[
0
];
Structure
s
;
if
(
!
load_structure
(
item
->
data
(
0
,
Qt
::
UserRole
).
toString
(),
s
))
if
(
!
try_
load_structure
(
item
->
data
(
0
,
Qt
::
UserRole
).
toString
(),
s
))
return
;
emit
structure_copied
(
s
);
}
void
StructureLibraryView
::
create_drag
(
QTreeWidgetItem
*
item
,
int
column
)
{
(
void
)
column
;
Structure
s
;
if
(
!
try_load_structure
(
item
->
data
(
0
,
Qt
::
UserRole
).
toString
(),
s
))
{
ui
->
button_copy
->
setEnabled
(
false
);
return
;
}
QDrag
*
drag
=
new
QDrag
(
this
);
QMimeData
*
mimeData
=
new
QMimeData
;
QString
filename
=
QFileInfo
(
item
->
data
(
0
,
Qt
::
UserRole
).
toString
()).
absoluteFilePath
();
QPixmap
pix
;
QImage
img
=
create_preview_image
(
s
,
Qt
::
transparent
);
pix
.
convertFromImage
(
img
);
pix
=
pix
.
scaled
(
QSize
(
100
,
100
),
Qt
::
KeepAspectRatio
);
mimeData
->
setText
(
filename
);
drag
->
setMimeData
(
mimeData
);
drag
->
setPixmap
(
pix
);
drag
->
exec
(
Qt
::
CopyAction
);
}
src/structurereader.cpp
View file @
e3b7103a
...
...
@@ -12,6 +12,8 @@
#include
<QJsonDocument>
#include
<QJsonObject>
#include
<QJsonArray>
#include
<QFile>
#include
<QFileInfo>
#include
"structure.hpp"
#include
<vector>
...
...
@@ -270,3 +272,27 @@ Structure JSONStructureReader::read_structure()
s
.
load
(
data
.
begin
(),
data
.
end
());
return
s
;
}
Structure
load_structure
(
const
std
::
string
&
path
)
{
QString
filename
=
QString
::
fromStdString
(
path
);
QFile
f
(
filename
);
if
(
!
f
.
open
(
QFile
::
ReadOnly
|
QFile
::
Text
))
throw
StructureReaderException
(
"Impossible de lire le fichier"
);
QTextStream
in
(
&
f
);
std
::
string
data
=
in
.
readAll
().
toStdString
();
if
(
QFileInfo
(
filename
).
suffix
()
==
"json"
)
{
JSONStructureReader
json
(
data
);
return
json
.
read_structure
();
}
else
if
(
QFileInfo
(
filename
).
suffix
()
==
"rle"
)
{
RLEStructureReader
rle
(
data
);
return
rle
.
read_structure
();
}
else
throw
StructureReaderException
(
"Format de fichier de structure invalide"
);
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment