Bring selected item to front; load/save z values

This commit is contained in:
Rebecca Breu 2021-03-30 20:51:58 +02:00
parent 0db0ef45ea
commit 751aebe26e
6 changed files with 85 additions and 30 deletions

View file

@ -3,8 +3,9 @@ SCHEMA = [
CREATE TABLE items (
id INTEGER PRIMARY KEY,
type TEXT NOT NULL,
pos_x REAL DEFAULT 0,
pos_y REAL DEFAULT 0,
x REAL DEFAULT 0,
y REAL DEFAULT 0,
z REAL DEFAULT 0,
scale REAL DEFAULT 1,
rotation REAL DEFAULT 0,
flip_h INTEGER DEFAULT 0,

View file

@ -127,19 +127,20 @@ class SQLiteIO:
@handle_sqlite_errors
def read(self):
rows = self.fetchall(
'SELECT pos_x, pos_y, scale, filename, sqlar.data, items.id '
'SELECT items.id, x, y, z, scale, filename, sqlar.data '
'FROM items '
'INNER JOIN sqlar on sqlar.item_id = items.id')
if self.progress:
self.progress.setMaximum(len(rows))
for i, row in enumerate(rows):
item = BeePixmapItem(QtGui.QImage(), filename=row[3])
item.save_id = row[5]
item.pixmap_from_bytes(row[4])
item.setPos(row[0], row[1])
item.setScale(row[2])
item = BeePixmapItem(QtGui.QImage(), filename=row[5])
item.save_id = row[0]
item.pixmap_from_bytes(row[6])
item.setPos(row[1], row[2])
self.scene.addItem(item)
item.setZValue(row[3])
item.setScale(row[4])
if self.progress:
self.progress.setValue(i)
if self.progress.wasCanceled():
@ -186,10 +187,10 @@ class SQLiteIO:
def insert_item(self, item):
self.ex(
'INSERT INTO items (type, pos_x, pos_y, scale, filename) '
'VALUES (?, ?, ?, ?, ?) ',
('pixmap', item.pos().x(), item.pos().y(), item.scale(),
item.filename))
'INSERT INTO items (type, x, y, z, scale, filename) '
'VALUES (?, ?, ?, ?, ?, ?) ',
('pixmap', item.pos().x(), item.pos().y(), item.zValue(),
item.scale(), item.filename))
item.save_id = self.cursor.lastrowid
pixmap = item.pixmap_to_bytes()
@ -212,8 +213,8 @@ class SQLiteIO:
data never changes and is also time-consuming to save.
"""
self.ex(
'UPDATE items SET pos_x=?, pos_y=?, scale=?, filename=? '
'UPDATE items SET x=?, y=?, z=?, scale=?, filename=? '
'WHERE id=?',
(item.pos().x(), item.pos().y(), item.scale(),
(item.pos().x(), item.pos().y(), item.zValue(), item.scale(),
item.filename, item.save_id))
self.connection.commit()

View file

@ -21,6 +21,7 @@ import logging
from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QGraphicsItem
from beeref import commands
@ -65,6 +66,13 @@ class BeePixmapItem(QtWidgets.QGraphicsPixmapItem):
self.prepareGeometryChange()
super().setScale(factor)
def setZValue(self, value):
super().setZValue(value)
self.scene().max_z = max(self.scene().max_z, value)
def bring_to_front(self):
self.setZValue(self.scene().max_z + 0.001)
def set_pos_center(self, x, y):
"""Sets the position using the item's center as the origin point."""
@ -79,6 +87,14 @@ class BeePixmapItem(QtWidgets.QGraphicsPixmapItem):
def height(self):
return self.pixmap().size().height()
def itemChange(self, change, value):
if (change == QGraphicsItem.GraphicsItemChange.ItemSelectedChange
and value
and self.scene()
and not self.scene().has_selection()):
self.bring_to_front()
return super().itemChange(change, value)
def pixmap_to_bytes(self):
"""Convert the pixmap data to PNG bytestring."""
barray = QtCore.QByteArray()

View file

@ -31,6 +31,7 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene):
self.move_active = False
self.undo_stack = undo_stack
self.selectionChanged.connect(self.on_selection_changed)
self.max_z = 0
def normalize_width_or_height(self, mode):
"""Scale the selected images to have the same width or height, as

View file

@ -88,25 +88,28 @@ class SQLiteIOWriteTestCase(BeeTestCase):
def test_inserts_new_item(self):
item = BeePixmapItem(QtGui.QImage(), filename='bee.jpg')
self.scene.addItem(item)
item.setScale(1.3)
item.setPos(44, 55)
item.setZValue(0.22)
item.pixmap_to_bytes = MagicMock(return_value=b'abc')
self.scene.addItem(item)
self.io.write()
assert item.save_id == 1
result = self.io.fetchone(
'SELECT pos_x, pos_y, scale, filename, type, '
'SELECT x, y, z, scale, filename, type, '
'sqlar.data, sqlar.name '
'FROM items '
'INNER JOIN sqlar on sqlar.item_id = items.id')
assert result[0] == 44.0
assert result[1] == 55.0
assert result[2] == 1.3
assert result[3] == 'bee.jpg'
assert result[4] == 'pixmap'
assert result[5] == b'abc'
assert result[6] == '0001-bee.png'
assert result[2] == 0.22
assert result[3] == 1.3
assert result[4] == 'bee.jpg'
assert result[5] == 'pixmap'
assert result[6] == b'abc'
assert result[7] == '0001-bee.png'
def test_inserts_new_item_without_filename(self):
item = BeePixmapItem(QtGui.QImage())
@ -122,14 +125,17 @@ class SQLiteIOWriteTestCase(BeeTestCase):
def test_updates_existing_item(self):
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
self.scene.addItem(item)
item.setScale(1.3)
item.setPos(44, 55)
item.setZValue(0.22)
item.save_id = 1
self.scene.addItem(item)
item.pixmap_to_bytes = MagicMock(return_value=b'abc')
self.io.write()
item.setScale(0.7)
item.setPos(20, 30)
item.setZValue(0.33)
item.filename = 'new.png'
item.pixmap_to_bytes.return_value = b'updated'
self.io.create_new = False
@ -137,14 +143,15 @@ class SQLiteIOWriteTestCase(BeeTestCase):
assert self.io.fetchone('SELECT COUNT(*) from items') == (1,)
result = self.io.fetchone(
'SELECT pos_x, pos_y, scale, filename, sqlar.data '
'SELECT x, y, z, scale, filename, sqlar.data '
'FROM items '
'INNER JOIN sqlar on sqlar.item_id = items.id')
assert result[0] == 20
assert result[1] == 30
assert result[2] == 0.7
assert result[3] == 'new.png'
assert result[4] == b'abc'
assert result[2] == 0.33
assert result[3] == 0.7
assert result[4] == 'new.png'
assert result[5] == b'abc'
def test_removes_nonexisting_item(self):
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
@ -195,9 +202,9 @@ class SQLiteIOReadTestCase(BeeTestCase):
fname = os.path.join(dirname, 'test.bee')
io = SQLiteIO(fname, self.scene, create_new=True)
io.create_schema_on_new()
io.ex('INSERT INTO items (type, pos_x, pos_y, scale, filename) '
'VALUES (?, ?, ?, ?, ?) ',
('pixmap', 22.2, 33.3, 3.4, 'bee.png'))
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
'VALUES (?, ?, ?, ?, ?, ?) ',
('pixmap', 22.2, 33.3, 0.22, 3.4, 'bee.png'))
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)',
(1, self.imgdata3x3))
io.connection.commit()
@ -210,6 +217,7 @@ class SQLiteIOReadTestCase(BeeTestCase):
assert item.save_id == 1
assert item.pos().x() == 22.2
assert item.pos().y() == 33.3
assert item.zValue() == 0.22
assert item.scale() == 3.4
assert item.filename == 'bee.png'
assert item.width == 3
@ -221,9 +229,9 @@ class SQLiteIOReadTestCase(BeeTestCase):
progress=progress)
io.create_schema_on_new()
io.ex('INSERT INTO items (type, pos_x, pos_y, scale, filename) '
'VALUES (?, ?, ?, ?, ?) ',
('pixmap', 0, 0, 1, 'bee.png'))
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
'VALUES (?, ?, ?, ?, ?, ?) ',
('pixmap', 0, 0, 0, 1, 'bee.png'))
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)', (1, b''))
io.connection.commit()
io.read()

View file

@ -9,6 +9,9 @@ from .base import BeeTestCase
class BeePixmapItemTestCase(BeeTestCase):
def setUp(self):
self.scene = BeeGraphicsScene(None)
def test_init(self):
item = BeePixmapItem(
QtGui.QImage(self.imgfilename3x3), self.imgfilename3x3)
@ -48,6 +51,31 @@ class BeePixmapItemTestCase(BeeTestCase):
assert item.pos().x() == -100
assert item.pos().y() == -50
def test_set_zvalue_sets_new_max(self):
item = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item)
item.setZValue(1.1)
assert item.zValue() == 1.1
assert self.scene.max_z == 1.1
def test_set_zvalue_keeps_old_max(self):
item = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item)
self.scene.max_z = 3.3
item.setZValue(1.1)
assert item.zValue() == 1.1
assert self.scene.max_z == 3.3
def test_bring_to_front(self):
item1 = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item1)
item1.setZValue(3.3)
item2 = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item2)
item2.bring_to_front()
assert item2.zValue() > item1.zValue()
assert item2.zValue() == self.scene.max_z
class BeePixmapItemPaintstuffTestCase(BeeTestCase):