diff --git a/b_asic/scheduler-gui/graphics_axes_item.py b/b_asic/scheduler-gui/graphics_axes_item.py index c8f8476ae3d6564db619975ccce69b23a8035dc4..02b84900250f75751698671b51db0acb2d2a378e 100644 --- a/b_asic/scheduler-gui/graphics_axes_item.py +++ b/b_asic/scheduler-gui/graphics_axes_item.py @@ -10,7 +10,7 @@ import sys from typing import Any, Optional from pprint import pprint from typing import Any, Union, Optional, overload, Dict, List, TypeAlias -from typing_extensions import Self +# from typing_extensions import Self import numpy as np from copy import deepcopy from math import cos, sin, pi @@ -151,12 +151,12 @@ class GraphicsAxesItem(QGraphicsItemGroup): """Register an object that receives events.""" self._event_items.append(item) - def set_height(self, height: int) -> "Self": + def set_height(self, height: int) -> "GraphicsAxesItem": # TODO: implement, docstring raise NotImplemented return self - def set_width(self, width: int) -> "Self": + def set_width(self, width: int) -> "GraphicsAxesItem": # TODO: docstring assert width >= 0, f"'width' greater or equal to 0 expected, got: {width}." delta_width = width - self._width diff --git a/b_asic/scheduler-gui/graphics_component_item.py b/b_asic/scheduler-gui/graphics_component_item.py index d7cce98907c110a73f566dd6c43f9c421a2298aa..c2b8e787a2fbfe44e1effb5cbeb3a9f5b0b0ebea 100644 --- a/b_asic/scheduler-gui/graphics_component_item.py +++ b/b_asic/scheduler-gui/graphics_component_item.py @@ -23,7 +23,7 @@ from qtpy.QtCore import ( Qt, QObject, QRect, QRectF, QPoint, QSize, QSizeF, QByteArray, Slot, QEvent) from qtpy.QtGui import ( QPaintEvent, QPainter, QPainterPath, QColor, QBrush, QPen, QFont, QPolygon, QIcon, QPixmap, - QLinearGradient, QTransform) + QLinearGradient, QTransform, QCursor) from qtpy.QtWidgets import ( QGraphicsView, QGraphicsScene, QGraphicsWidget, QGraphicsLayout, QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayoutItem, QGraphicsAnchorLayout, @@ -36,6 +36,7 @@ from qtpy.QtCore import ( # B-ASIC import logger from b_asic.schedule import Schedule +# from b_asic.graph_component import GraphComponent class GraphicsComponentItem(QGraphicsItemGroup): @@ -62,8 +63,10 @@ class GraphicsComponentItem(QGraphicsItemGroup): self._port_items = [] self.setFlag(QGraphicsItem.ItemIsMovable) # mouse move events - self.setAcceptHoverEvents(True) # mouse hover events + self.setFlag(QGraphicsItem.ItemIsSelectable) # mouse move events + # self.setAcceptHoverEvents(True) # mouse hover events self.setAcceptedMouseButtons(Qt.LeftButton) # accepted buttons for movements + self.setCursor(QCursor(Qt.OpenHandCursor)) # default cursor when hovering over object self._make_component() diff --git a/b_asic/scheduler-gui/graphics_graph_event.py b/b_asic/scheduler-gui/graphics_graph_event.py index 857b65a699c149e2086207345b9e2244a46bafc9..ab354462df6e87bf08c4e1f8ab40d6d168efaf7d 100644 --- a/b_asic/scheduler-gui/graphics_graph_event.py +++ b/b_asic/scheduler-gui/graphics_graph_event.py @@ -178,7 +178,9 @@ class GraphicsGraphEvent(QGraphicsItem): stores the current position in item's parent coordinates. 'event' will by default be accepted, and this item is then the mouse grabber. This allows the item to receive future move, release and double-click events.""" - item = self.scene().mouseGrabberItem() + item: GraphicsComponentItem = self.scene().mouseGrabberItem() + # op = self.schedule.sfg.find_by_id(item.op_id) + # emit fill_info_table_component(op) self._current_pos = item.mapToParent(event.pos()) self.setCursor(QCursor(Qt.ClosedHandCursor)) event.accept() diff --git a/b_asic/scheduler-gui/graphics_timeline_item.py b/b_asic/scheduler-gui/graphics_timeline_item.py index 0bfff1608091afe03e13d6e324bab5ebbd4c77b1..3ce7775c495ec6745e46ac336dfac255e08da8b4 100644 --- a/b_asic/scheduler-gui/graphics_timeline_item.py +++ b/b_asic/scheduler-gui/graphics_timeline_item.py @@ -25,7 +25,7 @@ from qtpy.QtCore import ( Qt, QObject, QRect, QRectF, QPoint, QSize, QSizeF, QByteArray, qAbs, QLineF) from qtpy.QtGui import ( QPaintEvent, QPainter, QPainterPath, QColor, QBrush, QPen, QFont, QPolygon, QIcon, QPixmap, - QLinearGradient, QTransform, QPolygonF) + QLinearGradient, QTransform, QPolygonF, QCursor) from qtpy.QtWidgets import ( QGraphicsView, QGraphicsScene, QGraphicsWidget, QGraphicsLayout, QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayoutItem, QGraphicsAnchorLayout, @@ -64,8 +64,9 @@ class GraphicsTimelineItem(QGraphicsLineItem): super().__init__(*args, **kwargs) self.setFlag(QGraphicsItem.ItemIsMovable) # mouse move events - self.setAcceptHoverEvents(True) # mouse hover events + # self.setAcceptHoverEvents(True) # mouse hover events self.setAcceptedMouseButtons(Qt.LeftButton) # accepted buttons for movements + self.setCursor(QCursor(Qt.SizeHorCursor)) # default cursor when hovering over object self._delta_time_label = QGraphicsTextItem() self._delta_time_label.hide() diff --git a/b_asic/scheduler-gui/main_window.py b/b_asic/scheduler-gui/main_window.py index a62996bcb0430bfd6346f025969850e24771bc14..95db280614a7bdaf581e25a5bdbdd3cebba7f617 100644 --- a/b_asic/scheduler-gui/main_window.py +++ b/b_asic/scheduler-gui/main_window.py @@ -10,7 +10,7 @@ import os import sys from pathlib import Path from types import ModuleType -from typing import Any, Iterable, List, Sequence, Type +from typing import Any, Iterable, List, Sequence, Type, Dict from pprint import pprint #from matplotlib.pyplot import bar #from diagram import * @@ -36,11 +36,12 @@ from qtpy.QtGui import ( from qtpy.QtWidgets import ( QGraphicsView, QGraphicsScene, QGraphicsWidget, QGraphicsScale, QGraphicsLayout, QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayoutItem, QGraphicsAnchorLayout, - QGraphicsItem, QGraphicsItemGroup, QGraphicsRectItem) + QGraphicsItem, QGraphicsItemGroup, QGraphicsRectItem, QHeaderView) # B-ASIC import logger from b_asic.schedule import Schedule +from b_asic.graph_component import GraphComponent from graphics_graph_item import GraphicsGraphItem from graphics_axes_item import GraphicsAxesItem from graphics_component_item import GraphicsComponentItem @@ -117,6 +118,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): _debug_rects: QGraphicsItemGroup _splitter_pos: int _splitter_min: int + _table_items: Dict[str, QTableWidgetItem] def __init__(self): @@ -126,6 +128,14 @@ class MainWindow(QMainWindow, Ui_MainWindow): self._open_file_dialog_opened = False self._scale = 75 self._debug_rects = None + self._table_items: Dict[str, QTableWidgetItem]= { + 'schedule_time': QTableWidgetItem(), # Schedule related part + 'cyclic': QTableWidgetItem(), + 'resolution': QTableWidgetItem(), + 'id': QTableWidgetItem(), # Component realtaed part + 'name': QTableWidgetItem(), + 'inports': QTableWidgetItem(), + 'outports': QTableWidgetItem()} QIcon.setThemeName('breeze') log.debug('themeName: \'{}\''.format(QIcon.themeName())) @@ -156,15 +166,20 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.closeEvent = self._close_event # Setup info table + self.info_table.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) self.info_table.setHorizontalHeaderLabels(['Property','Value']) # test = '#b085b2' # self.info_table.setStyleSheet('alternate-background-color: lightGray;background-color: white;') self.info_table.setStyleSheet('alternate-background-color: #fadefb;background-color: #ebebeb;') - for i in range(10): - self.info_table.insertRow(i) - item = QTableWidgetItem('this is a very very very very long string that says abolutly nothing') - self.info_table.setItem(i,0, QTableWidgetItem('property {}: '.format(i))) - self.info_table.setItem(i,1,item) + self.info_table.setSpan(0, 0, 1, 2) # Span 'Schedule' over 2 columns + self.info_table.setSpan(1, 0, 1, 2) # Span 'Operator' over 2 columns + self.info_table.setItem(0, 0, QTableWidgetItem('Schedule')) + self.info_table.setItem(1, 0, QTableWidgetItem('Operator')) + self.info_table.item(0, 0).setBackground(Qt.gray) + self.info_table.item(1, 0).setBackground(Qt.gray) + + + # Init central-widget splitter self._splitter_min = self.splitter.minimumSizeHint().height() @@ -181,7 +196,80 @@ class MainWindow(QMainWindow, Ui_MainWindow): GraphicsComponentItem._scale = self._scale GraphicsAxesItem._scale = self._scale self._scene.changed.connect(self.shrink_scene_to_min_size) + + def fill_info_table_schedule(self, schedule: Schedule) -> None: + self._table_items['schedule_time'].setText(str(schedule.schedule_time)) + self._table_items['cyclic'].setText(str(schedule.cyclic)) + self._table_items['resolution'].setText(str(schedule.resolution)) + self.info_table.insertRow(1) + self.info_table.insertRow(1) + self.info_table.insertRow(1) + self.info_table.setItem(1, 0, QTableWidgetItem('Schedule Time')) + self.info_table.setItem(2, 0, QTableWidgetItem('Cyclic')) + self.info_table.setItem(3, 0, QTableWidgetItem('Resolution')) + self.info_table.setItem(1, 1 ,self._table_items['schedule_time']) + self.info_table.setItem(2, 1 ,self._table_items['cyclic']) + self.info_table.setItem(3, 1 ,self._table_items['resolution']) + # self.info_table.setVerticalHeaderItem(0, mydict['test']) + # self._table_items['schedule_time'].setText('test item updated text') + + for i in range(5,10): + self.info_table.insertRow(i) + item = QTableWidgetItem('this is a very very very very long string that says abolutly nothing') + self.info_table.setItem(i,0, QTableWidgetItem('property {}: '.format(i))) + self.info_table.setItem(i,1,item) + + def fill_info_table_component(self, op: GraphComponent) -> None: + si = len(self._table_items) + 1 # si = start index + self.info_table.insertRow(si) + self.info_table.insertRow(si) + self.info_table.setItem(si + 0, 0, QTableWidgetItem('Graph ID')) + self.info_table.setItem(si + 0, 1, QTableWidgetItem(str(op.graph_id))) + self.info_table.setItem(si + 1, 0, QTableWidgetItem('Name')) + self.info_table.setItem(si + 1, 1, QTableWidgetItem(str(op.name))) + si += 2 + params = [(k,v) for k,v in op.params] + for i in range(len(params)): + self.info_table.insertRow(si + i) + self.info_table.setItem(si + i, 0, QTableWidgetItem(params[i][0])) + self.info_table.setItem(si + i, 1, QTableWidgetItem(params[i][1])) + + + # graph_id + # name + # params (dict) + self._table_items['schedule_time'].setText(str(schedule.schedule_time)) + self._table_items['cyclic'].setText(str(schedule.cyclic)) + self._table_items['resolution'].setText(str(schedule.resolution)) + self.info_table.insertRow(si) + self.info_table.insertRow(si) + self.info_table.insertRow(si) + self.info_table.setItem(si + 0, 0, QTableWidgetItem('ID')) + self.info_table.setItem(si + 1, 0, QTableWidgetItem('Name')) + self.info_table.setItem(si + 3, 0, QTableWidgetItem('Inports')) + self.info_table.setItem(si + 3, 0, QTableWidgetItem('Outports')) + self.info_table.setItem(si + 1, 1 ,self._table_items['id']) + self.info_table.setItem(si + 2, 1 ,self._table_items['name']) + self.info_table.setItem(si + 3, 1 ,self._table_items['inports']) + self.info_table.setItem(si + 3, 1 ,self._table_items['outports']) + # self.info_table.setVerticalHeaderItem(0, mydict['test']) + # self._table_items['schedule_time'].setText('test item updated text') + + for i in range(5,10): + self.info_table.insertRow(i) + item = QTableWidgetItem('this is a very very very very long string that says abolutly nothing') + self.info_table.setItem(i,0, QTableWidgetItem('property {}: '.format(i))) + self.info_table.setItem(i,1,item) + + def clear_info_table_schedule(self) -> None: + for _ in range(3): # Remove Schedule info + self.info_table.removeRow(1) + + def clear_info_table_component(self) -> None: + for _ in range(5): # Remove component info + self.info_table.removeRow(2) + ############### @@ -286,6 +374,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): # self._scene.setSceneRect(self._scene.itemsBoundingRect()) self.update_statusbar(self.tr('Schedule loaded successfully')) + self.fill_info_table_schedule(self._graph.schedule) @Slot() def save(self) -> None: diff --git a/b_asic/scheduler-gui/main_window.ui b/b_asic/scheduler-gui/main_window.ui index 030acc4732ec527b7e394bb63d79612f14415454..99e0ed0e8d4a647336c390b6bc0bb1a1406c5ac9 100644 --- a/b_asic/scheduler-gui/main_window.ui +++ b/b_asic/scheduler-gui/main_window.ui @@ -74,7 +74,7 @@ <enum>QAbstractItemView::SelectRows</enum> </property> <property name="rowCount"> - <number>0</number> + <number>2</number> </property> <property name="columnCount"> <number>2</number> @@ -88,6 +88,11 @@ <attribute name="verticalHeaderVisible"> <bool>false</bool> </attribute> + <attribute name="verticalHeaderDefaultSectionSize"> + <number>21</number> + </attribute> + <row/> + <row/> <column/> <column/> </widget> @@ -101,7 +106,7 @@ <x>0</x> <y>0</y> <width>800</width> - <height>20</height> + <height>22</height> </rect> </property> <widget class="QMenu" name="menuFile">