Skip to content
Snippets Groups Projects
Commit 7a556380 authored by David Hammer's avatar David Hammer
Browse files

DRYing, compacting scenes

parent 16b41f08
No related branches found
No related tags found
2 merge requests!12Snapshot: field test deployed version as of end of run 202201,!3Base correction device, CalCat interaction, DSSC and AGIPD devices
import enum
import textwrap
import karathon
from karabo.common.scenemodel.api import (
......@@ -17,11 +16,13 @@ from karabo.common.scenemodel.api import (
LineEditModel,
RectangleModel,
SceneModel,
SceneTargetWindow,
write_scene,
)
BASE_INC = 30
PADDING = 10
BASE_INC = 25
NARROW_INC = 20
PADDING = 5
RECONFIGURABLE = 4 # TODO: look up proper enum
_type_to_line_editable = {
......@@ -185,287 +186,197 @@ class VerticalLayout:
)
class MaybeEditableRow:
class MaybeEditableRow(HorizontalLayout):
def __init__(
self,
device_id,
schema_hash,
key_path,
label_width=7,
display_width=5,
edit_width=5,
label_width=7 * NARROW_INC,
display_width=5 * NARROW_INC,
edit_width=5 * NARROW_INC,
height=NARROW_INC,
):
self.label_width = label_width * BASE_INC
self.display_width = display_width * BASE_INC
self.edit_width = edit_width * BASE_INC
super().__init__(padding=0)
key_attr = schema_hash.getAttributes(key_path)
label_text = textwrap.shorten(
label_text = (
key_attr["displayedName"]
if "displayedName" in key_attr
else key_path.split(".")[-1],
24,
)
self.label = LabelModel(
text=label_text,
width=self.label_width,
height=BASE_INC,
else key_path.split(".")[-1]
)
self.value_display = DisplayLabelModel(
keys=[f"{device_id}.{key_path}"],
width=self.display_width,
height=BASE_INC,
self.children.extend(
[
LabelModel(
text=label_text,
width=label_width,
height=height,
),
DisplayLabelModel(
keys=[f"{device_id}.{key_path}"],
width=display_width,
height=height,
),
]
)
if key_attr["accessMode"] == RECONFIGURABLE:
value_type = key_attr["valueType"]
if value_type in _type_to_line_editable:
line_editable_class, extra_args = _type_to_line_editable[value_type]
self.value_edit = line_editable_class(
keys=[f"{device_id}.{key_path}"],
width=self.edit_width,
height=BASE_INC,
**extra_args,
self.children.append(
line_editable_class(
keys=[f"{device_id}.{key_path}"],
width=edit_width,
height=height,
**extra_args,
)
)
else:
self.value_edit = LabelModel(
text=f"Not yet supported: editing {key_path} of type {value_type}",
width=self.edit_width,
height=BASE_INC,
self.children.append(
value_edit=LabelModel(
text=f"Not yet supported: editing {key_path} of type {value_type}",
width=edit_width,
height=height,
)
)
@property
def width(self):
return self.label_width + self.display_width + self.edit_width
@property
def height(self):
return BASE_INC
def render(self, x, y):
self.label.x = x
self.label.y = y
self.value_display.x = x + self.label_width
self.value_display.y = y
if hasattr(self, "value_edit"):
self.value_edit.x = x + self.label_width + self.display_width
self.value_edit.y = y
return [
self.label,
self.value_display,
self.value_edit,
]
else:
return [
self.label,
self.value_display,
]
@titled("Parameters used for CalCat queries", width=10)
@boxed
class ConstantParameterColumn:
class ConstantParameterColumn(VerticalLayout):
def __init__(self, device_id, schema_hash, prefix="constantParameters"):
super().__init__(padding=0)
if "." in prefix:
self.extra_path_prefix = prefix[: prefix.rfind(".") + 1]
extra_path_prefix = prefix[: prefix.rfind(".") + 1]
else:
self.extra_path_prefix = ""
device_id = device_id
self.rows = [
MaybeEditableRow(
device_id,
schema_hash,
f"{prefix}.{key}",
extra_path_prefix = ""
self.children.extend(
[
MaybeEditableRow(
device_id,
schema_hash,
f"{prefix}.{key}",
)
for key in schema_hash.get(prefix).getKeys()
]
)
self.children.append(
DisplayCommandModel(
keys=[f"{device_id}.{extra_path_prefix}loadMostRecentConstants"],
width=10 * BASE_INC,
height=BASE_INC,
)
for key in schema_hash.get(prefix).getKeys()
]
self.load_button = DisplayCommandModel(
keys=[f"{device_id}.{self.extra_path_prefix}loadMostRecentConstants"],
width=10 * BASE_INC,
height=BASE_INC,
)
def render(self, x, y):
res = []
y_offset = 0
for row in self.rows:
res.extend(row.render(x=x, y=y + y_offset))
y_offset += row.height
self.load_button.x = x + 7 * BASE_INC
self.load_button.y = y + y_offset
res.append(self.load_button)
return res
@property
def width(self):
return max(row.width for row in self.rows)
@property
def height(self):
return sum(row.height for row in self.rows) + BASE_INC
class ConstantNode:
class ConstantNode(HorizontalLayout):
def __init__(self, device_id, constant_path):
self.title = LabelModel(
text=constant_path.split(".")[-1],
width=7 * BASE_INC,
height=BASE_INC,
)
self.ampel = ColorBoolModel(
height=BASE_INC, width=BASE_INC, keys=[f"{device_id}.{constant_path}.found"]
super().__init__(padding=0)
self.children.extend(
[
LabelModel(
text=constant_path.split(".")[-1],
width=7 * NARROW_INC,
height=NARROW_INC,
),
ColorBoolModel(
width=NARROW_INC,
height=NARROW_INC,
keys=[f"{device_id}.{constant_path}.found"],
),
]
)
def render(self, x, y):
self.title.x = x
self.title.y = y
self.ampel.x = x + 7 * BASE_INC
self.ampel.y = y
y += BASE_INC
return [self.title, self.ampel]
@property
def width(self):
return 8 * BASE_INC
@property
def height(self):
return BASE_INC
@titled("Found constants", width=6)
@boxed
class FoundConstantsColumn:
class FoundConstantsColumn(VerticalLayout):
def __init__(self, device_id, schema_hash, prefix="foundConstants"):
self.rows = [
ConstantNode(device_id, f"{prefix}.{constant_name}")
for constant_name in schema_hash.get(prefix).getKeys()
]
super().__init__(padding=0)
self.children.extend(
[
ConstantNode(device_id, f"{prefix}.{constant_name}")
for constant_name in schema_hash.get(prefix).getKeys()
]
)
def render(self, x, y):
res = []
y_offset = 0
for row in self.rows:
res.extend(row.render(x, y + y_offset))
y_offset += row.height
return res
@property
def width(self):
return max(row.width for row in self.rows)
class Space:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def height(self):
return sum(row.height for row in self.rows)
def render(self, x, y):
return []
class CorrectionStepNode:
class CorrectionStepNode(HorizontalLayout):
def __init__(self, device_id, step_path):
self.label = LabelModel(
text=step_path.split(".")[-1], width=7 * BASE_INC, height=BASE_INC
)
self.checkbox_main = CheckBoxModel(
keys=[f"{device_id}.{step_path}.enable"],
width=BASE_INC,
height=BASE_INC,
klass="EditableCheckBox",
)
self.checkbox_preview = CheckBoxModel(
keys=[f"{device_id}.{step_path}.preview"],
width=BASE_INC,
height=BASE_INC,
klass="EditableCheckBox",
super().__init__(padding=0)
self.children.extend(
[
LabelModel(
text=step_path.split(".")[-1], width=7 * BASE_INC, height=BASE_INC
),
CheckBoxModel(
keys=[f"{device_id}.{step_path}.enable"],
width=BASE_INC,
height=BASE_INC,
klass="EditableCheckBox",
),
CheckBoxModel(
keys=[f"{device_id}.{step_path}.preview"],
width=BASE_INC,
height=BASE_INC,
klass="EditableCheckBox",
),
]
)
def render(self, x, y):
self.label.x = x
self.label.y = y
x += 5 * BASE_INC
self.checkbox_main.x = x
self.checkbox_main.y = y
x += 3 * BASE_INC
self.checkbox_preview.x = x
self.checkbox_preview.y = y
return [self.label, self.checkbox_main, self.checkbox_preview]
@property
def width(self):
return 10 * BASE_INC
@property
def height(self):
return BASE_INC
@titled("Correction steps", width=6)
@boxed
class CorrectionStepsColumn:
class CorrectionStepsColumn(VerticalLayout):
def __init__(self, device_id, schema_hash, prefix="corrections"):
self.header_main = LabelModel(
text="enable", width=3 * BASE_INC, height=BASE_INC
super().__init__(padding=0)
self.children.append(
HorizontalLayout(
children=[
Space(width=7 * BASE_INC, height=BASE_INC),
LabelModel(
text="enable/preview", width=6 * BASE_INC, height=BASE_INC
),
],
padding=0,
)
)
self.header_preview = LabelModel(
text="preview", width=3 * BASE_INC, height=BASE_INC
self.children.extend(
[
CorrectionStepNode(device_id, f"{prefix}.{step_path}")
for step_path in schema_hash.get(prefix).getKeys()
]
)
self.steps = [
CorrectionStepNode(device_id, f"{prefix}.{step_path}")
for step_path in schema_hash.get(prefix).getKeys()
]
def render(self, x, y):
self.header_main.x = x + 5 * BASE_INC
self.header_main.y = y
self.header_preview.x = x + 8 * BASE_INC
self.header_preview.y = y
res = [self.header_main, self.header_preview]
y += BASE_INC
for step in self.steps:
step.x = x
step.y = y
res.extend(step.render(x, y))
y += step.height
return res
@property
def width(self):
return max(step.width for step in self.steps)
@property
def height(self):
return sum(step.height for step in self.steps) + BASE_INC
class ConstantLoadedAmpeln:
class ConstantLoadedAmpeln(HorizontalLayout):
def __init__(self, device_id, schema_hash, prefix="foundConstants"):
self.content = HorizontalLayout(
children=[
super().__init__(padding=0)
self.children.extend(
[
ColorBoolModel(
keys=[f"{device_id}.{prefix}.{key}.found"],
height=BASE_INC,
width=BASE_INC,
)
for key in schema_hash.get(prefix).getKeys()
],
padding=0,
]
)
def render(self, x, y):
return self.content.render(x, y)
@property
def width(self):
return self.content.width
@property
def height(self):
return self.content.height
@titled("Manager status", width=6)
@boxed
class ManagerDeviceStatus:
class ManagerDeviceStatus(VerticalLayout):
def __init__(self, device_id):
super().__init__(padding=0)
self.name = DisplayLabelModel(
keys=[f"{device_id}.deviceId"],
width=14 * BASE_INC,
......@@ -497,8 +408,8 @@ class ManagerDeviceStatus:
width=14 * BASE_INC,
height=7 * BASE_INC,
)
self.content = VerticalLayout(
children=[
self.children.extend(
[
self.name,
HorizontalLayout(
children=[
......@@ -512,26 +423,15 @@ class ManagerDeviceStatus:
padding=0,
),
self.status_log,
],
padding=0,
]
)
def render(self, x, y):
return self.content.render(x, y)
@property
def width(self):
return self.content.width
@property
def height(self):
return self.content.height
@titled("Device status", width=6)
@boxed
class CorrectionDeviceStatus:
class CorrectionDeviceStatus(VerticalLayout):
def __init__(self, device_id):
super().__init__(padding=0)
self.name = DisplayLabelModel(
keys=[f"{device_id}.deviceId"],
width=14 * BASE_INC,
......@@ -563,10 +463,10 @@ class CorrectionDeviceStatus:
self.status_log = DisplayTextLogModel(
keys=[f"{device_id}.status"],
width=14 * BASE_INC,
height=20 * BASE_INC,
height=14 * BASE_INC,
)
self.content = VerticalLayout(
children=[
self.children.extend(
[
self.name,
HorizontalLayout(
children=[
......@@ -583,71 +483,44 @@ class CorrectionDeviceStatus:
padding=0,
),
self.status_log,
],
padding=0,
]
)
def render(self, x, y):
return self.content.render(x, y)
@property
def width(self):
return 14 * BASE_INC
@property
def height(self):
return 23 * BASE_INC
class CompactCorrectionDeviceOverview:
class CompactCorrectionDeviceOverview(HorizontalLayout):
def __init__(self, device_id, schema_hash):
self.name = DeviceSceneLinkModel(
text=device_id.split("/")[-1],
keys=[f"{device_id}.availableScenes"],
target="overview",
width=5 * BASE_INC,
height=BASE_INC,
)
self.status = DisplayStateColorModel(
show_string=True,
keys=[f"{device_id}.state"],
width=6 * BASE_INC,
height=BASE_INC,
)
self.rate = EvaluatorModel(
expression="f'{x:.02f}'",
keys=[f"{device_id}.performance.rate"],
width=4 * BASE_INC,
height=BASE_INC,
)
self.tid = DisplayLabelModel(
keys=[f"{device_id}.trainId"],
width=4 * BASE_INC,
height=BASE_INC,
)
self.ampeln = ConstantLoadedAmpeln(device_id, schema_hash)
self.content = HorizontalLayout(
children=[
self.name,
self.status,
self.rate,
self.tid,
self.ampeln,
],
padding=0,
super().__init__(padding=0)
self.children.extend(
[
DeviceSceneLinkModel(
text=device_id.split("/")[-1],
keys=[f"{device_id}.availableScenes"],
target="overview",
target_window=SceneTargetWindow.Dialog,
width=5 * BASE_INC,
height=BASE_INC,
),
DisplayStateColorModel(
show_string=True,
keys=[f"{device_id}.state"],
width=6 * BASE_INC,
height=BASE_INC,
),
EvaluatorModel(
expression="f'{x:.02f}'",
keys=[f"{device_id}.performance.rate"],
width=4 * BASE_INC,
height=BASE_INC,
),
DisplayLabelModel(
keys=[f"{device_id}.trainId"],
width=4 * BASE_INC,
height=BASE_INC,
),
ConstantLoadedAmpeln(device_id, schema_hash),
]
)
def render(self, x, y):
return self.content.render(x, y)
@property
def width(self):
return 19 * BASE_INC + self.ampeln.width
@property
def height(self):
return BASE_INC
def correction_device_overview_scene(device_id, schema):
if isinstance(schema, karathon.Schema):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment