Skip to content

Commit

Permalink
#187 - Prototype track scaling with a few example dots
Browse files Browse the repository at this point in the history
  • Loading branch information
dmh23 committed Mar 1, 2023
1 parent 38f2359 commit 533ad46
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/prototype_ui/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def __init__(self, style: QStyle):
self.file_save_as.setShortcut("Ctrl+A")
self.file_save_as.setIcon(style.standardIcon(QStyle.StandardPixmap.SP_DialogOpenButton))

self.file_save_as.setCheckable(True)

@staticmethod
def get_custom_icon(icon_name: str):
file_path = os.path.join(ICON_DIRECTORY, icon_name + ".png")
Expand Down
18 changes: 6 additions & 12 deletions src/prototype_ui/canvas.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from abc import abstractmethod

from PyQt6.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsRectItem, QGraphicsPixmapItem, \
QAbstractGraphicsShapeItem
from PyQt6.QtGui import QBrush, QPen, QPixmap, QPainter
Expand Down Expand Up @@ -37,18 +39,10 @@ def _recreate_scene(self):
scene.addItem(i)
self.setScene(scene)

# Hardcoded examples for now - these will be abstract shortly
@abstractmethod
def _paint(self, painter: QPainter):
painter.fillRect(0, 0, round(self._width / 2), round(self._height / 2), Qt.GlobalColor.darkYellow)
pass

# Hardcoded examples for now - these will be abstract shortly
@abstractmethod
def _get_scene_items(self) -> list[QAbstractGraphicsShapeItem]:
rect = QGraphicsRectItem(0, 0, self._width / 3, self._height / 3)
rect.setPos(self._width / 10, self._height / 10)
brush = QBrush(Qt.GlobalColor.red)
rect.setBrush(brush)
pen = QPen(Qt.GlobalColor.cyan)
pen.setWidth(10)
rect.setPen(pen)

return [rect]
pass
10 changes: 8 additions & 2 deletions src/prototype_ui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from PyQt6.QtWidgets import QMainWindow, QApplication, QLabel, QProgressBar

from prototype_ui.actions import Actions
from prototype_ui.canvas import Canvas
from prototype_ui.menubar import MenuBarManager
from prototype_ui.toolbar import ToolBarManager
from prototype_ui.track_analysis_canvas import TrackAnalysisCanvas, SolidCircle, TrackArea


class MainWindow(QMainWindow):
Expand Down Expand Up @@ -36,11 +36,17 @@ def __init__(self):
self._actions.file_new.triggered.connect(self._new_file)
self._actions.file_open.triggered.connect(self._open_file)

self.canvas = Canvas(Qt.GlobalColor.gray)
self.canvas = TrackAnalysisCanvas()
self.setCentralWidget(self.canvas)

self.show()

# Example of drawing stuff in the track canvas until I integrate with Tracks etc.
self.canvas.set_track_area(TrackArea(0, 0, 100, 100))
self.canvas.add_fixed_shape(SolidCircle((90, 90), 20, Qt.GlobalColor.red))
self.canvas.add_fixed_shape(SolidCircle((50, 50), 20, Qt.GlobalColor.white))
self.canvas.add_fixed_shape(SolidCircle((10, 10), 20, Qt.GlobalColor.blue))

def _new_file(self):
print("New File")
self.statusBar().showMessage("Hello Briefly", 5000) # 5 secs
Expand Down
1 change: 1 addition & 0 deletions src/prototype_ui/menubar.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ def _create_file_menu(self):
menu = self._menu_bar.addMenu("File")
menu.addAction(self._actions.file_new)
menu.addAction(self._actions.file_open)
menu.addSeparator()
menu.addAction(self._actions.file_save)
menu.addAction(self._actions.file_save_as)
117 changes: 117 additions & 0 deletions src/prototype_ui/track_analysis_canvas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
from abc import ABC

from PyQt6.uic.properties import QtGui

from prototype_ui.canvas import Canvas
from PyQt6.QtWidgets import QGraphicsRectItem, QAbstractGraphicsShapeItem
from PyQt6.QtGui import QBrush, QPen, QPainter, QColor
from PyQt6.QtCore import Qt, QPointF, QPoint


class CanvasItem(ABC):
pass


class FixedShape(CanvasItem):
pass


class FloatingShape(CanvasItem):
pass


class TrackArea:
def __init__(self, min_x, min_y, max_x, max_y):
assert max_x > min_x
assert max_y > min_y

self.min_x = min_x
self.min_y = min_y
self.max_x = max_x
self.max_y = max_y


class Scale:
def __init__(self, min_x, max_y, scale):
self.min_x = min_x
self.max_y = max_y
self.scale = scale


class TrackAnalysisCanvas(Canvas):
def __init__(self):
self._track_area = TrackArea(0, 0, 100, 100)

self._fixed_shapes = []

# self._ring_highlight_widgets = []
# self._angle_line_highlight_widgets = []
# self._car_widgets = []
# self._old_car_widgets = []

super().__init__(Qt.GlobalColor.black)

def reset_to_blank(self):
self._fixed_shapes = []

def set_track_area(self, track_area: TrackArea):
self._track_area = track_area

def _get_current_scale(self):
min_x = self._track_area.min_x
min_y = self._track_area.min_y
max_x = self._track_area.max_x
max_y = self._track_area.max_y

x_size = max_x - min_x
y_size = max_y - min_y

x_scale = self.geometry().width() / x_size
y_scale = self.geometry().height() / y_size

scale = min(x_scale, y_scale)

x_border = (1 - scale / x_scale) / 2 * x_size
y_border = (1 - scale / y_scale) / 2 * y_size

return Scale(min_x - x_border, max_y + y_border, scale)

def _paint(self, painter: QPainter):
scale = self._get_current_scale()
for f in self._fixed_shapes:
f.paint(painter, scale)

def _get_scene_items(self) -> list[QAbstractGraphicsShapeItem]:
rect = QGraphicsRectItem(0, 0, self._width / 20, self._height / 20)
rect.setPos(self._width / 10, self._height / 10)
brush = QBrush(Qt.GlobalColor.red)
rect.setBrush(brush)
pen = QPen(Qt.GlobalColor.cyan)
pen.setWidth(10)
rect.setPen(pen)

return [rect]

def add_fixed_shape(self, item: FixedShape):
self._fixed_shapes.append(item)


# plot_dot() in v3

class SolidCircle(FixedShape):
def __init__(self, point: (float | int, float | int), radius: float | int, colour: Qt.GlobalColor):
self._point = point
self._pen = QPen(colour)
self._pen.setWidth(radius)

def paint(self, painter: QPainter, scale: Scale):
(x, y) = self._point

x = (x - scale.min_x) * scale.scale
y = (scale.max_y - y) * scale.scale

painter.setPen(self._pen)
painter.drawPoint(int(x), int(y))



0 comments on commit 533ad46

Please sign in to comment.