mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
Bring selected item to front; load/save z values
This commit is contained in:
parent
0db0ef45ea
commit
751aebe26e
6 changed files with 85 additions and 30 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue