Skip to content

Commit

Permalink
Added new widgets:
Browse files Browse the repository at this point in the history
Added a
   byte monitor widget
   image widget
   progress bar widget
   array-trace widget
   checkbox
  • Loading branch information
evalott100 committed Feb 19, 2024
1 parent b2f67a3 commit ebf4667
Show file tree
Hide file tree
Showing 22 changed files with 194 additions and 26 deletions.
27 changes: 27 additions & 0 deletions schemas/pvi.device.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@
"title": "Labels",
"type": "array"
},
"number_of_bits": {
"default": 8,
"description": "Number of bits to display",
"exclusiveMinimum": 0,
"title": "Number Of Bits",
"type": "integer"
},
"type": {
"const": "BitField",
"default": "BitField",
Expand Down Expand Up @@ -339,6 +346,26 @@
"additionalProperties": false,
"description": "Progress bar from lower to upper limit of a float PV",
"properties": {
"use_pv_limits": {
"default": false,
"description": "Use PV limits, if True then maximum and minumum are ignored",
"title": "Use Pv Limits",
"type": "boolean"
},
"minimum": {
"default": 0.0,
"description": "Lower limit of progress bar",
"exclusiveMinimum": 0.0,
"title": "Minimum",
"type": "number"
},
"maximum": {
"default": 1.0,
"description": "Upper limit of progress bar",
"exclusiveMinimum": 0.0,
"title": "Maximum",
"type": "number"
},
"type": {
"const": "ProgressBar",
"default": "ProgressBar",
Expand Down
4 changes: 3 additions & 1 deletion src/pvi/_format/adl.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ def set(
case TextWrite(format=format) | TextRead(format=format) if (
is_text_widget(template) and format is not None
):
template = add_property(template, "format", ADL_TEXT_FORMATS[format])
template = add_property(
template, "format", ADL_TEXT_FORMATS[TextFormat(format)]
)

return template

Expand Down
32 changes: 30 additions & 2 deletions src/pvi/_format/bob.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
from pvi._format.widget import UITemplate, WidgetFormatter
from pvi.device import (
LED,
BitField,
ComboBox,
ImageRead,
ProgressBar,
TableRead,
TableWrite,
TextFormat,
Expand Down Expand Up @@ -48,6 +51,9 @@ def set(
properties["y"] = bounds.y
properties["width"] = bounds.w
properties["height"] = bounds.h
if isinstance(widget, BitField):
properties["width"] = widget.number_of_bits * 20
bounds.w = properties["width"]

widget_type = template.attrib.get("type", "")

Expand Down Expand Up @@ -81,7 +87,18 @@ def set(
"textupdate",
TextRead(format=format),
) if format is not None:
add_format(t_copy, BOB_TEXT_FORMATS[format])
add_format(t_copy, BOB_TEXT_FORMATS[TextFormat(format)]) # type: ignore
case ("byte_monitor", BitField()):
add_byte_number_of_bits(t_copy, widget.number_of_bits) # type: ignore
case ("image", ImageRead()):
pass
case ("progressbar", ProgressBar()):
add_minimum_and_maximum_progressbar(
t_copy,
widget.use_pv_limits, # type: ignore
widget.minimum, # type: ignore
widget.maximum, # type: ignore
)

return t_copy

Expand Down Expand Up @@ -206,14 +223,25 @@ def add_format(element: ElementBase, format: str):
SubElement(element, "format").text = format


def add_byte_number_of_bits(element: ElementBase, number_of_bits: int):
SubElement(element, "numBits").text = str(number_of_bits)


def add_minimum_and_maximum_progressbar(
element: ElementBase, use_pv_limits: bool, minimum: float, maximum: float
):
SubElement(element, "limits_from_pv").text = "true" if use_pv_limits else "false"
SubElement(element, "minimum").text = str(minimum)
SubElement(element, "maximum").text = str(maximum)


def find_element(root_element: ElementBase, tag: str, index: int = 0) -> ElementBase:
"""Iterate tree to find tag and replace text.
Args:
root_element: Root of tree to search
tag: Tag to search for in tree
index: Match to return if multiple matches are found
"""
match list(root_element.iter(tag=tag)):
case []:
Expand Down
54 changes: 51 additions & 3 deletions src/pvi/_format/dls.bob
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<display version="2.0.0">
<name>Display</name>
<x>12</x>
<y>12</y>
<y use_class="true">0</y>
<width>1000</width>
<height>800</height>
<grid_step_x>4</grid_step_x>
Expand Down Expand Up @@ -192,9 +192,57 @@
<widget type="table" version="2.0.0">
<name>Table</name>
<pv_name>pva://Table</pv_name>
<x>300</x>
<y>300</y>
<x>671</x>
<y>670</y>
<width>200</width>
<height>100</height>
<columns>
<column>
<name>Column 1</name>
<width>100</width>
<editable>true</editable>
</column>
</columns>
</widget>
<widget type="byte_monitor" version="2.0.0">
<name>BitField</name>
<pv_name>ByteMonitor</pv_name>
<x>172</x>
<y>412</y>
<width>165</width>
</widget>
<widget type="xyplot" version="3.0.0">
<name>ArrayTrace</name>
<x>348</x>
<y>412</y>
<width>230</width>
<height>230</height>
<traces>
<trace>
<name>$(traces[0].y_pv)</name>
<x_pv></x_pv>
<y_pv>ArrayTrace</y_pv>
<err_pv></err_pv>
<axis>0</axis>
<trace_type>1</trace_type>
<color>
<color red="0" green="0" blue="255">
</color>
</color>
<line_width>1</line_width>
<line_style>0</line_style>
<point_type>0</point_type>
<point_size>10</point_size>
<visible>true</visible>
</trace>
</traces>
</widget>
<widget type="image" version="2.0.0">
<name>ImageRead</name>
<pv_name>ImageRead</pv_name>
<x>566</x>
<y>48</y>
<width>300</width>
<height>301</height>
</widget>
</display>
20 changes: 20 additions & 0 deletions src/pvi/_format/dls.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,26 @@ def format_bob(self, device: Device, path: Path):
search="ProgressBar",
property_map={"pv_name": "pv"},
),
bitfield_formatter_cls=PVWidgetFormatter.from_template(
template,
search="BitField",
property_map={"pv_name": "pv"},
),
button_panel_formatter_cls=PVWidgetFormatter.from_template(
template,
search="ButtonPanel",
property_map={"pv_name": "pv"},
),
array_trace_formatter_cls=PVWidgetFormatter.from_template(
template,
search="ArrayTrace",
property_map={"y_pv": "pv"},
),
image_read_formatter_cls=PVWidgetFormatter.from_template(
template,
search="ImageRead",
property_map={"pv_name": "pv"},
),
text_read_formatter_cls=PVWidgetFormatter.from_template(
template,
search="TextUpdate",
Expand Down
2 changes: 1 addition & 1 deletion src/pvi/_format/edl.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def set(
is_text_widget(template) and format is not None
):
template = add_property(
template, "displayMode", EDL_TEXT_FORMATS[format]
template, "displayMode", EDL_TEXT_FORMATS[TextFormat(format)]
)

return template
Expand Down
2 changes: 1 addition & 1 deletion src/pvi/_format/screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ def generate_component_formatters(
for action, value in c.write_widget.actions.items()
]
# If this is a SignalRW, recreate the readback with a SignalR
if isinstance(c, SignalRW):
if isinstance(c, SignalRW) and c.read_widget is not None:
row_components += [
SignalR(name=c.name, read_pv=c.read_pv, read_widget=c.read_widget)
]
Expand Down
22 changes: 19 additions & 3 deletions src/pvi/_format/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
from pvi._format.utils import Bounds, GroupType
from pvi.device import (
LED,
ArrayTrace,
BitField,
ButtonPanel,
CheckBox,
ComboBox,
Group,
ImageRead,
ProgressBar,
TableRead,
TableWrite,
Expand Down Expand Up @@ -260,14 +264,17 @@ class WidgetFormatterFactory(BaseModel, Generic[T]):
label_formatter_cls: Type[LabelWidgetFormatter[T]]
led_formatter_cls: Type[PVWidgetFormatter[T]]
progress_bar_formatter_cls: Type[PVWidgetFormatter[T]]
# TODO: add bitfield, progress_bar, plot, image
text_read_formatter_cls: Type[PVWidgetFormatter[T]]
check_box_formatter_cls: Type[PVWidgetFormatter[T]]
combo_box_formatter_cls: Type[PVWidgetFormatter[T]]
text_write_formatter_cls: Type[PVWidgetFormatter[T]]
table_formatter_cls: Type[PVWidgetFormatter]
table_formatter_cls: Type[PVWidgetFormatter[T]]
action_formatter_cls: Type[ActionWidgetFormatter[T]]
sub_screen_formatter_cls: Type[SubScreenWidgetFormatter[T]]
bitfield_formatter_cls: Optional[Type[PVWidgetFormatter[T]]] = None
array_trace_formatter_cls: Optional[Type[PVWidgetFormatter[T]]] = None
button_panel_formatter_cls: Optional[Type[PVWidgetFormatter[T]]] = None
image_read_formatter_cls: Optional[Type[PVWidgetFormatter[T]]] = None

def pv_widget_formatter(
self,
Expand All @@ -286,7 +293,7 @@ def pv_widget_formatter(
A WidgetFormatter representing the component
"""

widget_formatter_classes: Dict[type, Type[PVWidgetFormatter[T]]] = {
widget_formatter_classes: Dict[type, Optional[Type[PVWidgetFormatter[T]]]] = {
# Currently supported formatters of ReadWidget/WriteWidget Components
LED: self.led_formatter_cls,
ProgressBar: self.progress_bar_formatter_cls,
Expand All @@ -296,11 +303,20 @@ def pv_widget_formatter(
ComboBox: self.combo_box_formatter_cls,
TextWrite: self.text_write_formatter_cls,
TableWrite: self.table_formatter_cls,
BitField: self.bitfield_formatter_cls,
ButtonPanel: self.button_panel_formatter_cls,
ArrayTrace: self.array_trace_formatter_cls,
ImageRead: self.image_read_formatter_cls,
}
if isinstance(widget, (TextRead, TextWrite)):
bounds.h *= widget.get_lines()

widget_formatter_cls = widget_formatter_classes[type(widget)]
if widget_formatter_cls is None:
raise RuntimeError(
f"Unsupported widget type {type(widget)} for this widget formatter"
)

return widget_formatter_cls(bounds=bounds, pv=pv, widget=widget)


Expand Down
14 changes: 12 additions & 2 deletions src/pvi/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import json
import re
from enum import IntEnum
from enum import Enum
from pathlib import Path
from typing import (
TYPE_CHECKING,
Expand Down Expand Up @@ -65,7 +65,7 @@ def enforce_pascal_case(s: str) -> str:
return s[0].upper() + s[1:]


class TextFormat(IntEnum):
class TextFormat(Enum):
"""Format to use for display of Text{Read,Write} widgets on a UI"""

decimal = 0
Expand Down Expand Up @@ -95,11 +95,21 @@ class BitField(ReadWidget):
"""LED and label for each bit of an int PV"""

labels: Sequence[str] = Field(description="Label for each bit")
number_of_bits: int = Field(
default=8, description="Number of bits to display", gt=0
)


class ProgressBar(ReadWidget):
"""Progress bar from lower to upper limit of a float PV"""

use_pv_limits: bool = Field(
default=False,
description="Use PV limits, if True then maximum and minumum are ignored",
)
minimum: float = Field(default=0.0, description="Lower limit of progress bar", gt=0)
maximum: float = Field(default=1.0, description="Upper limit of progress bar", gt=0)


class TextRead(ReadWidget):
"""Text view of any PV"""
Expand Down
2 changes: 1 addition & 1 deletion tests/format/output/button.bob
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<display version="2.0.0">
<name>Display</name>
<x>0</x>
<y>0</y>
<y use_class="true">0</y>
<width>274</width>
<height>102</height>
<grid_step_x>4</grid_step_x>
Expand Down
2 changes: 1 addition & 1 deletion tests/format/output/combo_box.bob
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<display version="2.0.0">
<name>Display</name>
<x>0</x>
<y>0</y>
<y use_class="true">0</y>
<width>274</width>
<height>54</height>
<grid_step_x>4</grid_step_x>
Expand Down
2 changes: 1 addition & 1 deletion tests/format/output/device_ref.bob
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<display version="2.0.0">
<name>Display</name>
<x>0</x>
<y>0</y>
<y use_class="true">0</y>
<width>274</width>
<height>54</height>
<grid_step_x>4</grid_step_x>
Expand Down
2 changes: 1 addition & 1 deletion tests/format/output/index.bob
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<display version="2.0.0">
<name>Display</name>
<x>0</x>
<y>0</y>
<y use_class="true">0</y>
<width>388</width>
<height>105</height>
<grid_step_x>4</grid_step_x>
Expand Down
5 changes: 4 additions & 1 deletion tests/format/output/mixedWidgets.bob
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<display version="2.0.0">
<name>Display</name>
<x>0</x>
<y>0</y>
<y use_class="true">0</y>
<width>576</width>
<height>688</height>
<grid_step_x>4</grid_step_x>
Expand Down Expand Up @@ -1026,6 +1026,9 @@
<y>144</y>
<width>124</width>
<height>20</height>
<limits_from_pv>false</limits_from_pv>
<minimum>0.0</minimum>
<maximum>1.0</maximum>
</widget>
</widget>
</display>
Loading

0 comments on commit ebf4667

Please sign in to comment.