From 6cf83bb3814f18bc00daa869646ab5641d428846 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Thu, 11 Apr 2024 11:17:03 +0200 Subject: [PATCH] Add more status icon shapes --- novelwriter/constants.py | 26 ++++++--- novelwriter/core/status.py | 82 ++++++++++++++++++++++------- novelwriter/enum.py | 26 ++++++--- tests/test_core/test_core_status.py | 38 ++++++++++--- 4 files changed, 132 insertions(+), 40 deletions(-) diff --git a/novelwriter/constants.py b/novelwriter/constants.py index 04eea148..3c66f087 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -269,13 +269,25 @@ class nwLabels: nwBuildFmt.J_NWD: ".json", } STATUS_SHAPES = { - nwStatusShape.SQUARE: QT_TRANSLATE_NOOP("Constant", "Square"), - nwStatusShape.CIRCLE: QT_TRANSLATE_NOOP("Constant", "Circle"), - nwStatusShape.TRIANGLE: QT_TRANSLATE_NOOP("Constant", "Triangle"), - nwStatusShape.DIAMOND: QT_TRANSLATE_NOOP("Constant", "Diamond"), - nwStatusShape.PENTAGON: QT_TRANSLATE_NOOP("Constant", "Pentagon"), - nwStatusShape.STAR: QT_TRANSLATE_NOOP("Constant", "Star"), - nwStatusShape.PACMAN: QT_TRANSLATE_NOOP("Constant", "Pacman"), + nwStatusShape.SQUARE: QT_TRANSLATE_NOOP("Constant", "Square"), + nwStatusShape.CIRCLE_Q: QT_TRANSLATE_NOOP("Constant", "Circle, 1/4"), + nwStatusShape.CIRCLE_H: QT_TRANSLATE_NOOP("Constant", "Circle, Half"), + nwStatusShape.CIRCLE_T: QT_TRANSLATE_NOOP("Constant", "Circle, 3/4"), + nwStatusShape.CIRCLE: QT_TRANSLATE_NOOP("Constant", "Circle, Full"), + nwStatusShape.TRIANGLE: QT_TRANSLATE_NOOP("Constant", "Triangle"), + nwStatusShape.NABLA: QT_TRANSLATE_NOOP("Constant", "Nabla"), + nwStatusShape.DIAMOND: QT_TRANSLATE_NOOP("Constant", "Diamond"), + nwStatusShape.PENTAGON: QT_TRANSLATE_NOOP("Constant", "Pentagon"), + nwStatusShape.STAR: QT_TRANSLATE_NOOP("Constant", "Star"), + nwStatusShape.PACMAN: QT_TRANSLATE_NOOP("Constant", "Pacman"), + nwStatusShape.BARS_1: QT_TRANSLATE_NOOP("Constant", "1 Bar"), + nwStatusShape.BARS_2: QT_TRANSLATE_NOOP("Constant", "2 Bars"), + nwStatusShape.BARS_3: QT_TRANSLATE_NOOP("Constant", "3 Bars"), + nwStatusShape.BARS_4: QT_TRANSLATE_NOOP("Constant", "4 Bars"), + nwStatusShape.BLOCK_1: QT_TRANSLATE_NOOP("Constant", "1 Block"), + nwStatusShape.BLOCK_2: QT_TRANSLATE_NOOP("Constant", "2 Blocks"), + nwStatusShape.BLOCK_3: QT_TRANSLATE_NOOP("Constant", "3 Blocks"), + nwStatusShape.BLOCK_4: QT_TRANSLATE_NOOP("Constant", "4 Blocks"), } FILE_FILTERS = { "*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"), diff --git a/novelwriter/core/status.py b/novelwriter/core/status.py index cde8bf02..c2899ad7 100644 --- a/novelwriter/core/status.py +++ b/novelwriter/core/status.py @@ -244,48 +244,92 @@ class _ShapeCache: if shape in self._cache: return self._cache[shape] - def circ(r: float, a: float, x: float, y: float) -> QPointF: + def polar(r: float, a: float, x: float, y: float) -> QPointF: + # Converts polar coordinates to cartesian # print(round(x+r*sin(pi*a/180), 2), round(y-r*cos(pi*a/180), 2)) - return QPointF(round(x+r*sin(pi*a/180), 2), round(y-r*cos(pi*a/180), 2)) + return QPointF(x+r*sin(pi*a/180), y-r*cos(pi*a/180)) path = QPainterPath() if shape == nwStatusShape.SQUARE: path.addRoundedRect(2.0, 2.0, 44.0, 44.0, 4.0, 4.0) + elif shape == nwStatusShape.CIRCLE_Q: + path.moveTo(24.0, 24.0) + path.arcTo(2.0, 2.0, 44.0, 44.0, 0.0, 90.0) + elif shape == nwStatusShape.CIRCLE_H: + path.moveTo(24.0, 24.0) + path.arcTo(2.0, 2.0, 44.0, 44.0, -90.0, 180.0) + elif shape == nwStatusShape.CIRCLE_T: + path.moveTo(24.0, 24.0) + path.arcTo(2.0, 2.0, 44.0, 44.0, -180.0, 270.0) elif shape == nwStatusShape.CIRCLE: path.addEllipse(2.0, 2.0, 44.0, 44.0) elif shape == nwStatusShape.TRIANGLE: path.addPolygon(QPolygonF([ - circ(23.0, 0.0, 24.0, 26.0), - circ(23.0, 120.0, 24.0, 26.0), - circ(23.0, 240.0, 24.0, 26.0), + polar(23.0, 0.0, 24.0, 26.0), + polar(23.0, 120.0, 24.0, 26.0), + polar(23.0, 240.0, 24.0, 26.0), + ])) + elif shape == nwStatusShape.NABLA: + path.addPolygon(QPolygonF([ + polar(23.0, 180.0, 24.0, 26.0), + polar(23.0, 300.0, 24.0, 26.0), + polar(23.0, 60.0, 24.0, 26.0), ])) elif shape == nwStatusShape.DIAMOND: path.addPolygon(QPolygonF([ - circ(22.0, 0.0, 24.0, 24.0), - circ(20.0, 90.0, 24.0, 24.0), - circ(22.0, 180.0, 24.0, 24.0), - circ(20.0, 270.0, 24.0, 24.0), + polar(22.0, 0.0, 24.0, 24.0), + polar(20.0, 90.0, 24.0, 24.0), + polar(22.0, 180.0, 24.0, 24.0), + polar(20.0, 270.0, 24.0, 24.0), ])) elif shape == nwStatusShape.PENTAGON: path.addPolygon(QPolygonF([ - circ(23.0, 0.0, 24.0, 24.5), - circ(23.0, 72.0, 24.0, 24.5), - circ(23.0, 144.0, 24.0, 24.5), - circ(23.0, 216.0, 24.0, 24.5), - circ(23.0, 288.0, 24.0, 24.5), + polar(23.0, 0.0, 24.0, 24.5), + polar(23.0, 72.0, 24.0, 24.5), + polar(23.0, 144.0, 24.0, 24.5), + polar(23.0, 216.0, 24.0, 24.5), + polar(23.0, 288.0, 24.0, 24.5), ])) elif shape == nwStatusShape.STAR: path.addPolygon(QPolygonF([ - circ(24.0, 0.0, 24.0, 24.5), - circ(24.0, 144.0, 24.0, 24.5), - circ(24.0, 288.0, 24.0, 24.5), - circ(24.0, 72.0, 24.0, 24.5), - circ(24.0, 216.0, 24.0, 24.5), + polar(24.0, 0.0, 24.0, 24.5), polar(12.0, 36.0, 24.0, 24.5), + polar(24.0, 72.0, 24.0, 24.5), polar(12.0, 108.0, 24.0, 24.5), + polar(24.0, 144.0, 24.0, 24.5), polar(12.0, 180.0, 24.0, 24.5), + polar(24.0, 216.0, 24.0, 24.5), polar(12.0, 252.0, 24.0, 24.5), + polar(24.0, 288.0, 24.0, 24.5), polar(12.0, 314.0, 24.0, 24.5), ])) path.setFillRule(Qt.FillRule.WindingFill) elif shape == nwStatusShape.PACMAN: path.moveTo(24.0, 24.0) path.arcTo(2.0, 2.0, 44.0, 44.0, 40.0, 280.0) + elif shape == nwStatusShape.BARS_1: + path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0) + elif shape == nwStatusShape.BARS_2: + path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0) + path.addRoundedRect(14.0, 2.0, 8.0, 44.0, 4.0, 4.0) + elif shape == nwStatusShape.BARS_3: + path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0) + path.addRoundedRect(14.0, 2.0, 8.0, 44.0, 4.0, 4.0) + path.addRoundedRect(26.0, 2.0, 8.0, 44.0, 4.0, 4.0) + elif shape == nwStatusShape.BARS_4: + path.addRoundedRect(2.0, 2.0, 8.0, 44.0, 4.0, 4.0) + path.addRoundedRect(14.0, 2.0, 8.0, 44.0, 4.0, 4.0) + path.addRoundedRect(26.0, 2.0, 8.0, 44.0, 4.0, 4.0) + path.addRoundedRect(38.0, 2.0, 8.0, 44.0, 4.0, 4.0) + elif shape == nwStatusShape.BLOCK_1: + path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0) + elif shape == nwStatusShape.BLOCK_2: + path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0) + path.addRoundedRect(24.0, 2.0, 20.0, 20.0, 4.0, 4.0) + elif shape == nwStatusShape.BLOCK_3: + path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0) + path.addRoundedRect(2.0, 24.0, 20.0, 20.0, 4.0, 4.0) + path.addRoundedRect(24.0, 2.0, 20.0, 20.0, 4.0, 4.0) + elif shape == nwStatusShape.BLOCK_4: + path.addRoundedRect(2.0, 2.0, 20.0, 20.0, 4.0, 4.0) + path.addRoundedRect(2.0, 24.0, 20.0, 20.0, 4.0, 4.0) + path.addRoundedRect(24.0, 2.0, 20.0, 20.0, 4.0, 4.0) + path.addRoundedRect(24.0, 24.0, 20.0, 20.0, 4.0, 4.0) self._cache[shape] = path diff --git a/novelwriter/enum.py b/novelwriter/enum.py index c0f88ba7..e5ee3dd5 100644 --- a/novelwriter/enum.py +++ b/novelwriter/enum.py @@ -209,12 +209,24 @@ class nwBuildFmt(Enum): class nwStatusShape(Enum): - SQUARE = 0 - CIRCLE = 1 - TRIANGLE = 2 - DIAMOND = 3 - PENTAGON = 4 - STAR = 5 - PACMAN = 6 + SQUARE = 0 + CIRCLE_Q = 1 + CIRCLE_H = 2 + CIRCLE_T = 3 + CIRCLE = 4 + TRIANGLE = 5 + NABLA = 6 + DIAMOND = 7 + PENTAGON = 8 + STAR = 9 + PACMAN = 10 + BARS_1 = 11 + BARS_2 = 12 + BARS_3 = 13 + BARS_4 = 14 + BLOCK_1 = 15 + BLOCK_2 = 16 + BLOCK_3 = 17 + BLOCK_4 = 18 # END Enum nwStatusShape diff --git a/tests/test_core/test_core_status.py b/tests/test_core/test_core_status.py index 3c2b8edd..4ca9e29b 100644 --- a/tests/test_core/test_core_status.py +++ b/tests/test_core/test_core_status.py @@ -374,21 +374,45 @@ def testCoreStatus_ShapeCache(): shapes = _ShapeCache() # Generate all shapes - square = shapes.getShape(nwStatusShape.SQUARE) - circle = shapes.getShape(nwStatusShape.CIRCLE) - triangle = shapes.getShape(nwStatusShape.TRIANGLE) - diamond = shapes.getShape(nwStatusShape.DIAMOND) - pentagon = shapes.getShape(nwStatusShape.PENTAGON) - star = shapes.getShape(nwStatusShape.STAR) - pacman = shapes.getShape(nwStatusShape.PACMAN) + square = shapes.getShape(nwStatusShape.SQUARE) + circleQ = shapes.getShape(nwStatusShape.CIRCLE_Q) + circleH = shapes.getShape(nwStatusShape.CIRCLE_H) + circleT = shapes.getShape(nwStatusShape.CIRCLE_T) + circle = shapes.getShape(nwStatusShape.CIRCLE) + triangle = shapes.getShape(nwStatusShape.TRIANGLE) + nabla = shapes.getShape(nwStatusShape.NABLA) + diamond = shapes.getShape(nwStatusShape.DIAMOND) + pentagon = shapes.getShape(nwStatusShape.PENTAGON) + star = shapes.getShape(nwStatusShape.STAR) + pacman = shapes.getShape(nwStatusShape.PACMAN) + bars1 = shapes.getShape(nwStatusShape.BARS_1) + bars2 = shapes.getShape(nwStatusShape.BARS_2) + bars3 = shapes.getShape(nwStatusShape.BARS_3) + bars4 = shapes.getShape(nwStatusShape.BARS_4) + block1 = shapes.getShape(nwStatusShape.BLOCK_1) + block2 = shapes.getShape(nwStatusShape.BLOCK_2) + block3 = shapes.getShape(nwStatusShape.BLOCK_3) + block4 = shapes.getShape(nwStatusShape.BLOCK_4) # Request again should return from cache assert shapes.getShape(nwStatusShape.SQUARE) is square + assert shapes.getShape(nwStatusShape.CIRCLE_Q) is circleQ + assert shapes.getShape(nwStatusShape.CIRCLE_H) is circleH + assert shapes.getShape(nwStatusShape.CIRCLE_T) is circleT assert shapes.getShape(nwStatusShape.CIRCLE) is circle assert shapes.getShape(nwStatusShape.TRIANGLE) is triangle + assert shapes.getShape(nwStatusShape.NABLA) is nabla assert shapes.getShape(nwStatusShape.DIAMOND) is diamond assert shapes.getShape(nwStatusShape.PENTAGON) is pentagon assert shapes.getShape(nwStatusShape.STAR) is star assert shapes.getShape(nwStatusShape.PACMAN) is pacman + assert shapes.getShape(nwStatusShape.BARS_1) is bars1 + assert shapes.getShape(nwStatusShape.BARS_2) is bars2 + assert shapes.getShape(nwStatusShape.BARS_3) is bars3 + assert shapes.getShape(nwStatusShape.BARS_4) is bars4 + assert shapes.getShape(nwStatusShape.BLOCK_1) is block1 + assert shapes.getShape(nwStatusShape.BLOCK_2) is block2 + assert shapes.getShape(nwStatusShape.BLOCK_3) is block3 + assert shapes.getShape(nwStatusShape.BLOCK_4) is block4 # END Test testCoreStatus_ShapeCache