Skip to content

Commit

Permalink
WIP - Tables
Browse files Browse the repository at this point in the history
  • Loading branch information
GDYendell committed Apr 13, 2023
1 parent 159196d commit d0640f7
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 18 deletions.
5 changes: 4 additions & 1 deletion src/pvi/_format/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,10 @@ def component(
sc.value,
)
elif isinstance(sc, SignalR) and sc.widget:
if isinstance(sc.widget, (TableRead, TableWrite)):
if (
isinstance(sc.widget, (TableRead, TableWrite))
and len(sc.widget.widgets) > 0
):
widget_bounds = row_bounds.copy()
widget_bounds.w *= len(sc.widget.widgets)
widget_bounds.h *= 10 # TODO: How do we know the number of rows?
Expand Down
20 changes: 12 additions & 8 deletions src/pvi/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,12 @@ class ArrayTrace(ReadWidget):
class TableRead(ReadWidget):
"""Tabular view of an NTTable"""

widgets: Annotated[
Sequence[ReadWidget],
desc("For each column, what widget should be repeated for every row"),
]
widgets: Optional[
Annotated[
Sequence[ReadWidget],
desc("For each column, what widget should be repeated for every row"),
]
] = field(default_factory=list)


class ImageRead(ReadWidget):
Expand Down Expand Up @@ -139,10 +141,12 @@ class ArrayWrite(WriteWidget):

@dataclass
class TableWrite(WriteWidget):
widgets: Annotated[
Sequence[Union[ReadWidget, WriteWidget]],
desc("For each column, what widget should be repeated for every row"),
]
widgets: Optional[
Annotated[
Sequence[Union[ReadWidget, WriteWidget]],
desc("For each column, what widget should be repeated for every row"),
]
] = field(default_factory=list)


@as_discriminated_union
Expand Down
47 changes: 47 additions & 0 deletions tests/format/output/dynamic_table_panda.bob
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<display version="2.0.0">
<name>Display</name>
<x>0</x>
<y>0</y>
<width>522</width>
<height>234</height>
<grid_step_x>4</grid_step_x>
<grid_step_y>4</grid_step_y>
<widget type="label" version="2.0.0">
<name>Title</name>
<class>TITLE</class>
<text>TableDevice - </text>
<x use_class="true">0</x>
<y use_class="true">0</y>
<width>522</width>
<height>26</height>
<font use_class="true">
<font name="Header 1" family="Liberation Sans" style="BOLD" size="22.0">
</font>
</font>
<foreground_color use_class="true">
<color name="Text" red="0" green="0" blue="0">
</color>
</foreground_color>
<transparent use_class="true">true</transparent>
<horizontal_alignment>1</horizontal_alignment>
</widget>
<widget type="table" version="2.0.0">
<name>Table</name>
<pv_name>pva://PANDAQSRV:SEQ1:STRTABLE</pv_name>
<x>22</x>
<y>30</y>
<width>496</width>
<height>200</height>
<columns>
<column>
<name>Column 1</name>
<editable>false</editable>
</column>
<column>
<name>Column 2</name>
<editable>false</editable>
</column>
<editable>false</editable>
</columns>
</widget>
</display>
44 changes: 35 additions & 9 deletions tests/test_dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,65 @@

from pvi._format.base import Formatter
from pvi._yaml_utils import deserialize_yaml
from pvi.device import LED, ComboBox, Device, SignalR, TableWrite, TextWrite
from pvi.device import (
LED,
ComboBox,
Device,
SignalR,
TableRead,
TableWrite,
TextRead,
TextWrite,
)

HERE = Path(__file__).parent


def test_dynamic_table(tmp_path, helper):
formatter_yaml = HERE / "produce_format" / "input" / "dls.bob.pvi.formatter.yaml"
formatter_yaml = HERE / "format" / "input" / "dls.bob.pvi.formatter.yaml"
formatter = deserialize_yaml(Formatter, formatter_yaml)

table = SignalR(
"DynamicTable",
"DynamicTable",
TableWrite([TextWrite(), LED(), ComboBox(["1", "A", "True"])]),
)
device = Device("TableDevice", children=[table])
device = Device("TableDevice", "asynPortDriver", children=[table])

expected_bob = (
HERE / "produce_format" / "output" / "test_screens" / "dynamic_table.edl"
)
expected_bob = HERE / "format" / "output" / "dynamic_table.bob"
output_bob = tmp_path / "dynamic_table.bob"
formatter.format(device, "$(P)$(R)", output_bob)

helper.assert_output_matches(expected_bob, output_bob)


def test_dynamic_table_panda(tmp_path, helper):
formatter_yaml = HERE / "format" / "input" / "dls.bob.pvi.formatter.yaml"
formatter = deserialize_yaml(Formatter, formatter_yaml)

table = SignalR(
"PandA ",
"PANDAQSRV:SEQ1:STRTABLE",
# Can pass no arguments to `TableRead()`, but it will be editable
TableRead([TextRead(), TextRead()]),
)
device = Device("TableDevice", "asynPortDriver", children=[table])

expected_bob = HERE / "format" / "output" / "dynamic_table_panda.bob"
output_bob = tmp_path / "dynamic_table_panda.bob"
formatter.format(device, "", output_bob)

helper.assert_output_matches(expected_bob, output_bob)


def test_combo_box(tmp_path, helper):
formatter_yaml = HERE / "produce_format" / "input" / "dls.bob.pvi.formatter.yaml"
formatter_yaml = HERE / "format" / "input" / "dls.bob.pvi.formatter.yaml"
formatter = deserialize_yaml(Formatter, formatter_yaml)

combo_box = SignalR("Enum", "Enum", ComboBox(["A", "B", "C"]))
device = Device("Device", children=[combo_box])
device = Device("Device", "asynPortDriver", children=[combo_box])

expected_bob = HERE / "produce_format" / "output" / "test_screens" / "combo_box.edl"
expected_bob = HERE / "format" / "output" / "combo_box.bob"
output_bob = tmp_path / "combo_box.bob"
formatter.format(device, "$(P)$(R)", output_bob)

Expand Down

0 comments on commit d0640f7

Please sign in to comment.