Skip to content
GitLab
Menu
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
78ea73a0
Commit
78ea73a0
authored
May 30, 2021
by
Yann Boucher
Browse files
Significant performance improvements with GridView
parent
bef2a147
Pipeline
#78788
passed with stages
in 17 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
forms/interface.ui
View file @
78ea73a0
...
@@ -295,7 +295,7 @@ pattern recorded :</string>
...
@@ -295,7 +295,7 @@ pattern recorded :</string>
<number>
1
</number>
<number>
1
</number>
</property>
</property>
<property
name=
"maximum"
>
<property
name=
"maximum"
>
<number>
9999
</number>
<number>
1000
</number>
</property>
</property>
<property
name=
"value"
>
<property
name=
"value"
>
<number>
10
</number>
<number>
10
</number>
...
@@ -318,7 +318,7 @@ pattern recorded :</string>
...
@@ -318,7 +318,7 @@ pattern recorded :</string>
<number>
1
</number>
<number>
1
</number>
</property>
</property>
<property
name=
"maximum"
>
<property
name=
"maximum"
>
<number>
9999
</number>
<number>
1000
</number>
</property>
</property>
<property
name=
"value"
>
<property
name=
"value"
>
<number>
10
</number>
<number>
10
</number>
...
...
include/gridview.hpp
View file @
78ea73a0
...
@@ -12,6 +12,7 @@ Cette classe représente le widget utilisé pour l'affichage et l'interaction av
...
@@ -12,6 +12,7 @@ Cette classe représente le widget utilisé pour l'affichage et l'interaction av
#define GRIDVIEW_HPP
#define GRIDVIEW_HPP
#include
<map>
#include
<map>
#include
<set>
#include
<QFrame>
#include
<QFrame>
#include
<QGraphicsView>
#include
<QGraphicsView>
...
@@ -48,9 +49,10 @@ signals:
...
@@ -48,9 +49,10 @@ signals:
void
zoomed
();
void
zoomed
();
};
};
}
}
class
GridItem
;
class
GridView
;
class
GridView
;
class
GridGraphicsView
;
class
GridGraphicsView
;
class
DragDropHandlerItem
;
/**
/**
* \class GridView
* \class GridView
...
@@ -93,7 +95,7 @@ public:
...
@@ -93,7 +95,7 @@ public:
//! \brief Retourne la taille du côté en pixels d'une cellule au niveau de zoom actuel.
//! \brief Retourne la taille du côté en pixels d'une cellule au niveau de zoom actuel.
//! \returns Taille en pixel du côté d'une cellule.
//! \returns Taille en pixel du côté d'une cellule.
unsigned
cell_
pixel
_size
()
const
;
unsigned
cell_
screen
_size
()
const
;
//! \brief Retourne la taille de la grille, dans un QSize.
//! \brief Retourne la taille de la grille, dans un QSize.
//! \returns La taille de la Grid.
//! \returns La taille de la Grid.
...
@@ -127,16 +129,22 @@ signals:
...
@@ -127,16 +129,22 @@ signals:
void
zoom_changed
(
unsigned
cell_size
);
void
zoom_changed
(
unsigned
cell_size
);
private:
private:
GridItem
*
item_at
(
Coord
pos
);
const
GridItem
*
item_at
(
Coord
pos
)
const
;
void
load_grid
(
const
Grid
&
grid
);
void
load_grid
(
const
Grid
&
grid
);
void
set_cell_state
(
Coord
pos
,
unsigned
state
);
void
update_gridview
();
void
copy_selection
();
void
copy_selection
();
void
paste_clipboard
();
void
paste_clipboard
();
void
delete_selection
();
void
delete_selection
();
Coord
top_left_of_selection
()
const
;
Coord
top_left_of_selection
()
const
;
const
QPixmap
&
grid_pixmap
()
const
;
private
slots
:
void
handle_rubberband
(
QRect
,
QPointF
,
QPointF
);
protected:
protected:
void
keyPressEvent
(
QKeyEvent
*
event
);
void
keyPressEvent
(
QKeyEvent
*
event
);
void
keyReleaseEvent
(
QKeyEvent
*
event
);
void
keyReleaseEvent
(
QKeyEvent
*
event
);
...
@@ -145,8 +153,15 @@ private:
...
@@ -145,8 +153,15 @@ private:
GridGraphicsView
*
m_view
;
GridGraphicsView
*
m_view
;
QGraphicsScene
*
m_scene
;
QGraphicsScene
*
m_scene
;
detail
::
Graphics_view_zoom
*
m_zoom
;
detail
::
Graphics_view_zoom
*
m_zoom
;
std
::
vector
<
GridItem
*>
m_item_cache
;
// cache pour pouvoir accéder efficacement à un Item selon une coordonnée
History
m_undo_history
;
History
m_undo_history
;
QImage
m_grid_image
;
QPixmap
m_grid_pixmap
;
Grid
m_grid
;
std
::
set
<
Coord
>
m_selected_cells
;
std
::
vector
<
QGraphicsRectItem
*>
m_selection_rects
;
bool
m_handling_rubberband
;
DragDropHandlerItem
*
m_drag_drop_handler
;
unsigned
m_width
;
unsigned
m_width
;
unsigned
m_height
;
unsigned
m_height
;
unsigned
m_pen
;
unsigned
m_pen
;
...
...
src/gridview.cpp
View file @
78ea73a0
...
@@ -85,71 +85,20 @@ bool Graphics_view_zoom::eventFilter(QObject *object, QEvent *event) {
...
@@ -85,71 +85,20 @@ bool Graphics_view_zoom::eventFilter(QObject *object, QEvent *event) {
}
}
class
Grid
Item
:
public
QGraphicsRectItem
class
DragDropHandler
Item
:
public
QGraphicsRectItem
{
{
public:
public:
Grid
Item
(
GridView
&
in_gridview
,
unsigned
state
=
0
,
Coord
pos
=
Coord
{
0
,
0
},
QGraphicsItem
*
parent
=
nullptr
)
DragDropHandler
Item
(
GridView
&
in_gridview
,
QGraphicsItem
*
parent
=
nullptr
)
:
QGraphicsRectItem
(
0
,
0
,
GridItem
::
width
(),
GridItem
::
height
()
,
parent
),
m_grid_view
(
in_gridview
)
:
QGraphicsRectItem
(
0
,
0
,
1
,
1
,
parent
),
m_grid_view
(
in_gridview
)
{
{
setAcceptHoverEvents
(
true
);
setAcceptHoverEvents
(
true
);
setToolTip
(
m_state_name
);
setFlag
(
QGraphicsItem
::
ItemIsSelectable
);
setAcceptDrops
(
true
);
setAcceptDrops
(
true
);
//setCacheMode(QGraphicsItem::DeviceCoordinateCache);
set_state
(
state
);
setPen
(
Qt
::
NoPen
);
set_grid_pos
(
pos
);
setBrush
(
Qt
::
NoBrush
);
setPen
(
QPen
(
brush
(),
0
));
}
static
int
width
()
{
return
20
;
}
static
int
height
()
{
return
20
;
}
unsigned
state
()
const
{
return
m_cell_state
;
}
void
set_state
(
unsigned
s
,
bool
update_history
=
false
)
{
if
(
update_history
&&
m_cell_state
!=
s
)
m_grid_view
.
push_history
();
const
Alphabet
&
alph
=
m_grid_view
.
alphabet
();
setBrush
(
QBrush
(
stateColor_to_QColor
(
alph
.
getState
(
s
).
getColor
())));
setToolTip
(
QString
::
fromStdString
(
alph
.
getState
(
s
).
getStateLabel
()));
m_cell_state
=
s
;
update
();
}
Coord
grid_pos
()
const
{
return
m_cell_pos
;
}
void
set_grid_pos
(
Coord
c
)
{
setPos
(
QPointF
(
c
.
x
*
GridItem
::
width
(),
c
.
y
*
GridItem
::
height
()));
m_cell_pos
=
c
;
}
}
protected:
protected:
void
paint
(
QPainter
*
painter
,
const
QStyleOptionGraphicsItem
*
,
QWidget
*
)
override
{
QRectF
rect
=
QRectF
(
0
,
0
,
GridItem
::
width
(),
GridItem
::
height
());
painter
->
setPen
(
Qt
::
NoPen
);
if
(
isSelected
())
{
QBrush
selection_brush
=
brush
();
selection_brush
.
setColor
(
brush
().
color
().
darker
(
175
));
painter
->
setBrush
(
selection_brush
);
}
else
{
painter
->
setBrush
(
brush
());
}
painter
->
drawRect
(
rect
);
}
void
dragEnterEvent
(
QGraphicsSceneDragDropEvent
*
event
)
override
void
dragEnterEvent
(
QGraphicsSceneDragDropEvent
*
event
)
override
{
{
if
(
event
->
mimeData
()
->
hasText
())
if
(
event
->
mimeData
()
->
hasText
())
...
@@ -175,12 +124,11 @@ protected:
...
@@ -175,12 +124,11 @@ protected:
return
;
return
;
}
}
m_grid_view
.
paste_structure_at
(
m_cell_pos
,
s
);
Coord
coord
=
Coord
{(
int
)
event
->
pos
().
x
(),
(
int
)
event
->
pos
().
y
()};
m_grid_view
.
paste_structure_at
(
coord
,
s
);
}
}
private:
private:
Coord
m_cell_pos
;
unsigned
m_cell_state
;
QString
m_state_name
;
QString
m_state_name
;
GridView
&
m_grid_view
;
GridView
&
m_grid_view
;
};
};
...
@@ -204,6 +152,7 @@ protected:
...
@@ -204,6 +152,7 @@ protected:
void
mousePressEvent
(
QMouseEvent
*
event
);
void
mousePressEvent
(
QMouseEvent
*
event
);
void
mouseMoveEvent
(
QMouseEvent
*
event
);
void
mouseMoveEvent
(
QMouseEvent
*
event
);
void
drawForeground
(
QPainter
*
painter
,
const
QRectF
&
rect
);
void
drawForeground
(
QPainter
*
painter
,
const
QRectF
&
rect
);
void
drawBackground
(
QPainter
*
painter
,
const
QRectF
&
rect
);
private:
private:
void
draw_bresenham
(
QPointF
from
,
QPointF
to
);
void
draw_bresenham
(
QPointF
from
,
QPointF
to
);
...
@@ -217,42 +166,47 @@ private:
...
@@ -217,42 +166,47 @@ private:
void
GridGraphicsView
::
mousePressEvent
(
QMouseEvent
*
event
)
void
GridGraphicsView
::
mousePressEvent
(
QMouseEvent
*
event
)
{
{
QPointF
item_pos
=
mapToScene
(
event
->
pos
());
QPointF
item_pos
=
mapToScene
(
event
->
pos
());
Coord
coord
=
Coord
{(
int
)
item_pos
.
x
()
/
GridItem
::
width
(),
(
int
)
item_pos
.
y
()
/
GridItem
::
height
()};
if
(
!
sceneRect
().
contains
(
item_pos
))
GridItem
*
item
=
m_gridview
.
item_at
(
coord
);
return
;
Coord
coord
=
Coord
{(
int
)
item_pos
.
x
(),
(
int
)
item_pos
.
y
()};
m_last_mouse_pos
=
event
->
pos
();
m_last_mouse_pos
=
event
->
pos
();
if
(
QGuiApplication
::
keyboardModifiers
()
==
Qt
::
NoModifier
&&
event
->
button
()
==
Qt
::
LeftButton
)
if
(
QGuiApplication
::
keyboardModifiers
()
==
Qt
::
NoModifier
&&
event
->
button
()
==
Qt
::
LeftButton
)
{
{
if
(
item
)
unsigned
state
=
m_gridview
.
current_pen
();
{
m_gridview
.
set_cell_state
(
coord
,
state
);
unsigned
state
=
m_gridview
.
current_pen
();
m_gridview
.
update_gridview
();
item
->
set_state
(
state
,
true
);
}
}
}
else
if
(
event
->
button
()
==
Qt
::
RightButton
&&
item
)
else
if
(
event
->
button
()
==
Qt
::
RightButton
)
{
{
if
((
QGuiApplication
::
keyboardModifiers
()
&
Qt
::
ControlModifier
)
==
0
)
m_gridview
.
clear_selection
();
QGraphicsView
::
mousePressEvent
(
event
);
QGraphicsView
::
mousePressEvent
(
event
);
item
->
setSelected
(
true
);
//
item->setSelected(true);
}
}
else
else
QGraphicsView
::
mousePressEvent
(
event
);
QGraphicsView
::
mousePressEvent
(
event
);
}
}
void
GridGraphicsView
::
mouseMoveEvent
(
QMouseEvent
*
event
)
void
GridGraphicsView
::
mouseMoveEvent
(
QMouseEvent
*
event
)
{
{
QPointF
item_pos
=
mapToScene
(
event
->
pos
());
QPointF
item_pos
=
mapToScene
(
event
->
pos
());
Coord
coord
=
Coord
{(
int
)
item_pos
.
x
()
/
GridItem
::
width
(),
(
int
)
item_pos
.
y
()
/
GridItem
::
height
()};
if
(
!
sceneRect
().
contains
(
item_pos
)
||
!
sceneRect
().
contains
(
mapToScene
(
m_last_mouse_pos
)))
GridItem
*
item
=
m_gridview
.
item_at
(
coord
)
;
return
;
if
(
QGuiApplication
::
keyboardModifiers
()
==
Qt
::
NoModifier
&&
event
->
buttons
()
==
Qt
::
LeftButton
)
if
(
QGuiApplication
::
keyboardModifiers
()
==
Qt
::
NoModifier
&&
event
->
buttons
()
==
Qt
::
LeftButton
)
{
{
draw_bresenham
(
mapToScene
(
m_last_mouse_pos
),
mapToScene
(
event
->
pos
()));
draw_bresenham
(
mapToScene
(
m_last_mouse_pos
),
item_pos
);
m_gridview
.
update_gridview
();
}
}
else
if
(
event
->
buttons
()
==
Qt
::
RightButton
&&
item
)
else
if
(
event
->
buttons
()
==
Qt
::
RightButton
)
{
{
QGraphicsView
::
mouseMoveEvent
(
event
);
QGraphicsView
::
mouseMoveEvent
(
event
);
item
->
setSelected
(
true
);
//
item->setSelected(true);
}
}
else
else
QGraphicsView
::
mouseMoveEvent
(
event
);
QGraphicsView
::
mouseMoveEvent
(
event
);
...
@@ -260,11 +214,11 @@ void GridGraphicsView::mouseMoveEvent(QMouseEvent *event)
...
@@ -260,11 +214,11 @@ void GridGraphicsView::mouseMoveEvent(QMouseEvent *event)
m_last_mouse_pos
=
event
->
pos
();
m_last_mouse_pos
=
event
->
pos
();
}
}
void
GridGraphicsView
::
drawForeground
(
QPainter
*
painter
,
const
QRectF
&
rect
)
void
GridGraphicsView
::
drawForeground
(
QPainter
*
painter
,
const
QRectF
&
)
{
{
qreal
lod
=
QStyleOptionGraphicsItem
::
levelOfDetailFromTransform
(
painter
->
worldTransform
());
qreal
lod
=
QStyleOptionGraphicsItem
::
levelOfDetailFromTransform
(
painter
->
worldTransform
());
if
(
lod
<
0
.4
)
if
(
lod
<
1
0
)
return
;
// trop zoomé, on ne dessine rien
return
;
// trop zoomé, on ne dessine rien
painter
->
setPen
(
QPen
(
Qt
::
black
,
0
));
// cosmetic 1-pixel pen
painter
->
setPen
(
QPen
(
Qt
::
black
,
0
));
// cosmetic 1-pixel pen
...
@@ -273,14 +227,14 @@ void GridGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
...
@@ -273,14 +227,14 @@ void GridGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
// horizontal lines
// horizontal lines
for
(
int
i
=
-
1
;
i
<
m_gridview
.
grid_size
().
height
();
++
i
)
for
(
int
i
=
-
1
;
i
<
m_gridview
.
grid_size
().
height
();
++
i
)
{
{
const
unsigned
y_offset
=
(
i
+
1
)
*
GridItem
::
height
()
;
const
unsigned
y_offset
=
(
i
+
1
);
lines
.
append
(
QLine
(
QPoint
(
0
,
y_offset
),
QPoint
(
GridItem
::
width
()
*
m_gridview
.
grid_size
().
width
(),
y_offset
)));
lines
.
append
(
QLine
(
QPoint
(
0
,
y_offset
),
QPoint
(
m_gridview
.
grid_size
().
width
(),
y_offset
)));
}
}
// vertical lines
// vertical lines
for
(
int
j
=
-
1
;
j
<
m_gridview
.
grid_size
().
width
();
++
j
)
for
(
int
j
=
-
1
;
j
<
m_gridview
.
grid_size
().
width
();
++
j
)
{
{
const
unsigned
x_offset
=
(
j
+
1
)
*
GridItem
::
width
()
;
const
unsigned
x_offset
=
(
j
+
1
);
lines
.
append
(
QLine
(
QPoint
(
x_offset
,
0
),
QPoint
(
x_offset
,
GridItem
::
height
()
*
m_gridview
.
grid_size
().
height
())));
lines
.
append
(
QLine
(
QPoint
(
x_offset
,
0
),
QPoint
(
x_offset
,
m_gridview
.
grid_size
().
height
())));
}
}
painter
->
drawLines
(
lines
);
painter
->
drawLines
(
lines
);
...
@@ -288,13 +242,20 @@ void GridGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
...
@@ -288,13 +242,20 @@ void GridGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
painter
->
setPen
(
Qt
::
NoPen
);
painter
->
setPen
(
Qt
::
NoPen
);
}
}
void
GridGraphicsView
::
drawBackground
(
QPainter
*
painter
,
const
QRectF
&
rect
)
{
QGraphicsView
::
drawBackground
(
painter
,
rect
);
painter
->
drawPixmap
(
0
,
0
,
m_gridview
.
grid_pixmap
());
}
// Algorithme de Bresenham pour tracer une ligne entre les deux points et dessiner sur ces items
// Algorithme de Bresenham pour tracer une ligne entre les deux points et dessiner sur ces items
void
GridGraphicsView
::
draw_bresenham
(
QPointF
from
,
QPointF
to
)
void
GridGraphicsView
::
draw_bresenham
(
QPointF
from
,
QPointF
to
)
{
{
int
x0
=
from
.
x
()
/
GridItem
::
width
()
;
int
x0
=
from
.
x
();
int
y0
=
from
.
y
()
/
GridItem
::
height
()
;
int
y0
=
from
.
y
();
int
x1
=
to
.
x
()
/
GridItem
::
width
()
;
int
x1
=
to
.
x
();
int
y1
=
to
.
y
()
/
GridItem
::
height
()
;
int
y1
=
to
.
y
();
// cf. https://gist.github.com/bert/1085538
// cf. https://gist.github.com/bert/1085538
int
dx
=
abs
(
x1
-
x0
),
sx
=
x0
<
x1
?
1
:
-
1
;
int
dx
=
abs
(
x1
-
x0
),
sx
=
x0
<
x1
?
1
:
-
1
;
...
@@ -303,10 +264,8 @@ void GridGraphicsView::draw_bresenham(QPointF from, QPointF to)
...
@@ -303,10 +264,8 @@ void GridGraphicsView::draw_bresenham(QPointF from, QPointF to)
for
(;;){
/* loop */
for
(;;){
/* loop */
//printf("Trying %d %d\n", x, y);
m_gridview
.
set_cell_state
(
Coord
{
x0
,
y0
},
m_gridview
.
current_pen
());
auto
item
=
m_gridview
.
item_at
(
Coord
{
x0
,
y0
});
if
(
item
)
item
->
set_state
(
m_gridview
.
current_pen
());
if
(
x0
==
x1
&&
y0
==
y1
)
break
;
if
(
x0
==
x1
&&
y0
==
y1
)
break
;
e2
=
2
*
err
;
e2
=
2
*
err
;
if
(
e2
>=
dy
)
{
err
+=
dy
;
x0
+=
sx
;
}
/* e_xy+e_x > 0 */
if
(
e2
>=
dy
)
{
err
+=
dy
;
x0
+=
sx
;
}
/* e_xy+e_x > 0 */
...
@@ -315,11 +274,12 @@ void GridGraphicsView::draw_bresenham(QPointF from, QPointF to)
...
@@ -315,11 +274,12 @@ void GridGraphicsView::draw_bresenham(QPointF from, QPointF to)
}
}
GridView
::
GridView
(
QWidget
*
parent
)
GridView
::
GridView
(
QWidget
*
parent
)
:
QFrame
(
parent
),
m_undo_history
(
10
),
m_width
(
10
),
m_height
(
10
)
:
QFrame
(
parent
),
m_undo_history
(
10
),
m_grid
(
10
,
10
),
m_handling_rubberband
(
false
),
m_width
(
10
),
m_height
(
10
)
{
{
//setMouseTracking(true);
//setMouseTracking(true);
setFrameStyle
(
Sunken
|
StyledPanel
);
setFrameStyle
(
Sunken
|
StyledPanel
);
setAcceptDrops
(
true
);
m_scene
=
new
QGraphicsScene
(
this
);
m_scene
=
new
QGraphicsScene
(
this
);
...
@@ -333,13 +293,6 @@ GridView::GridView(QWidget *parent)
...
@@ -333,13 +293,6 @@ GridView::GridView(QWidget *parent)
m_view
->
viewport
()
->
setCursor
(
Qt
::
ArrowCursor
);
m_view
->
viewport
()
->
setCursor
(
Qt
::
ArrowCursor
);
m_view
->
setBackgroundBrush
(
QBrush
(
Qt
::
gray
));
m_view
->
setBackgroundBrush
(
QBrush
(
Qt
::
gray
));
m_view
->
setRubberBandSelectionMode
(
Qt
::
IntersectsItemBoundingRect
);
// provides better performance
m_view
->
setRubberBandSelectionMode
(
Qt
::
IntersectsItemBoundingRect
);
// provides better performance
/*
QOpenGLWidget *gl = new QOpenGLWidget();
QSurfaceFormat format;
format.setSamples(4);
gl->setFormat(format);
m_view->setViewport(gl);
*/
m_zoom
=
new
detail
::
Graphics_view_zoom
(
m_view
);
m_zoom
=
new
detail
::
Graphics_view_zoom
(
m_view
);
...
@@ -355,6 +308,9 @@ GridView::GridView(QWidget *parent)
...
@@ -355,6 +308,9 @@ GridView::GridView(QWidget *parent)
alph
.
newEtat
(
state
{
stateColor
{
0
,
0
,
255
},
"Alive"
});
alph
.
newEtat
(
state
{
stateColor
{
0
,
0
,
255
},
"Alive"
});
set_alphabet
(
alph
);
set_alphabet
(
alph
);
m_drag_drop_handler
=
new
DragDropHandlerItem
(
*
this
);
m_scene
->
addItem
(
m_drag_drop_handler
);
// Initialisation la première fois
// Initialisation la première fois
m_height
=
10
;
m_height
=
10
;
m_width
=
10
;
m_width
=
10
;
...
@@ -364,8 +320,9 @@ GridView::GridView(QWidget *parent)
...
@@ -364,8 +320,9 @@ GridView::GridView(QWidget *parent)
connect
(
m_zoom
,
&
detail
::
Graphics_view_zoom
::
zoomed
,
this
,
[
this
]
connect
(
m_zoom
,
&
detail
::
Graphics_view_zoom
::
zoomed
,
this
,
[
this
]
{
{
emit
zoom_changed
(
cell_
pixel
_size
());
emit
zoom_changed
(
cell_
screen
_size
());
});
});
connect
(
m_view
,
&
QGraphicsView
::
rubberBandChanged
,
this
,
&
GridView
::
handle_rubberband
);
}
}
void
GridView
::
set_alphabet
(
const
Alphabet
&
alph
)
void
GridView
::
set_alphabet
(
const
Alphabet
&
alph
)
...
@@ -396,9 +353,9 @@ void GridView::set_clipboard(const Structure &s)
...
@@ -396,9 +353,9 @@ void GridView::set_clipboard(const Structure &s)
m_copy_paste_buffer
=
s
;
m_copy_paste_buffer
=
s
;
}
}
unsigned
GridView
::
cell_
pixel
_size
()
const
unsigned
GridView
::
cell_
screen
_size
()
const
{
{
return
m_view
->
transform
().
mapRect
(
QRectF
(
0
,
0
,
GridItem
::
width
(),
GridItem
::
height
()
)).
size
().
toSize
().
width
();
return
m_view
->
transform
().
mapRect
(
QRectF
(
0
,
0
,
1
,
1
)).
size
().
toSize
().
width
();
}
}
QSize
GridView
::
grid_size
()
const
QSize
GridView
::
grid_size
()
const
...
@@ -410,30 +367,23 @@ void GridView::copy_grid(const Grid &grid)
...
@@ -410,30 +367,23 @@ void GridView::copy_grid(const Grid &grid)
{
{
push_history
();
push_history
();
load_grid
(
grid
);
load_grid
(
grid
);
update_gridview
();
}
}
Grid
GridView
::
get_grid
()
const
Grid
GridView
::
get_grid
()
const
{
{
Grid
grid
=
Grid
(
m_height
,
m_width
);
return
m_grid
;
for
(
size_t
i
=
0
;
i
<
grid
.
get_col
();
++
i
)
{
for
(
size_t
j
=
0
;
j
<
grid
.
get_rows
();
++
j
)
{
const
GridItem
*
item
=
item_at
(
Coord
{(
int
)
i
,
(
int
)
j
});
assert
(
item
);
Coord
pos
;
pos
.
x
=
i
;
pos
.
y
=
j
;
grid
.
set_cell
(
pos
,
item
->
state
());
}
}
return
grid
;
}
}
void
GridView
::
clear_selection
()
void
GridView
::
clear_selection
()
{
{
m_scene
->
clearSelection
();
for
(
auto
rect
:
m_selection_rects
)
{
m_scene
->
removeItem
(
rect
);
}
m_selection_rects
.
clear
();
m_selected_cells
.
clear
();
m_handling_rubberband
=
false
;
}
}
Structure
GridView
::
selected_cells
()
const
Structure
GridView
::
selected_cells
()
const
...
@@ -443,12 +393,9 @@ Structure GridView::selected_cells() const
...
@@ -443,12 +393,9 @@ Structure GridView::selected_cells() const
std
::
vector
<
std
::
pair
<
Coord
,
unsigned
>>
cells
;
std
::
vector
<
std
::
pair
<
Coord
,
unsigned
>>
cells
;
// on calcule la position du coin supérieur gauche de la sélection, afin de la considérer comme l'origine de de la structure
for
(
auto
coord
:
m_selected_cells
)
Coord
origin
=
top_left_of_selection
();
Q_FOREACH
(
const
auto
&
item
,
m_scene
->
selectedItems
())
{
{
GridItem
*
cell
=
static_cast
<
GridItem
*>
(
item
);
cells
.
push_back
(
std
::
make_pair
(
coord
,
m_grid
.
get_state
(
coord
)));
cells
.
push_back
(
std
::
make_pair
(
cell
->
grid_pos
()
-
origin
,
cell
->
state
()));
}
}
return
Structure
(
cells
.
begin
(),
cells
.
end
());
return
Structure
(
cells
.
begin
(),
cells
.
end
());
}
}
...
@@ -466,65 +413,37 @@ void GridView::undo()
...
@@ -466,65 +413,37 @@ void GridView::undo()
}
}
}
}
GridItem
*
GridView
::
item_at
(
Coord
pos
)
{
if
(
pos
.
x
<
0
||
pos
.
y
<
0
||
pos
.
x
>=
(
int
)
m_width
||
pos
.
y
>=
(
int
)
m_height
)
return
nullptr
;
return
m_item_cache
[
pos
.
y
*
m_width
+
pos
.
x
];
//QGraphicsItem* gitem_ptr = m_scene->itemAt(QPointF(pos.x*GridItem::width(), pos.y*GridItem::height()), QTransform());
//return dynamic_cast<GridItem*>(gitem_ptr);
}
const
GridItem
*
GridView
::
item_at
(
Coord
pos
)
const
{
if
(
pos
.
x
<
0
||
pos
.
y
<
0
||
pos
.
x
>=
(
int
)
m_width
||
pos
.
y
>=
(
int
)
m_height
)
return
nullptr
;
return
m_item_cache
[
pos
.
y
*
m_width
+
pos
.
x
];
//QGraphicsItem* gitem_ptr = m_scene->itemAt(QPointF(pos.x*GridItem::width(), pos.y*GridItem::height()), QTransform());
//return dynamic_cast<GridItem*>(gitem_ptr);
}
void
GridView
::
load_grid
(
const
Grid
&
grid
)
void
GridView
::
load_grid
(
const
Grid
&
grid
)
{
{
m_height
=
grid
.
get_rows
();
m_height
=
grid
.
get_rows
();
m_width
=
grid
.
get_col
();
m_width
=
grid
.
get_col
();
if
(
m_height
*
m_width
!=
m_item_cache
.
size
())