1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
from trame.app import get_server
from trame.ui.vuetify import SinglePageWithDrawerLayout
from trame.widgets import client, html, vuetify
# -----------------------------------------------------------------------------
# Trame setup
# -----------------------------------------------------------------------------
VAR_NAMES = set(["a123", "a456", "a789"])
server = get_server(client_type="vue2")
state, ctrl = server.state, server.controller
count = 800
state.update(
{
"items": [{"id": "a123"}, {"id": "a456"}, {"id": "a789"}],
"a123": {
"range": (10, 90),
"range_min": 0,
"range_max": 100,
"opacity": 1,
},
"a456": {
"range": (20, 80),
"range_min": 0,
"range_max": 100,
"opacity": 1,
},
"a789": {
"range": (30, 70),
"range_min": 0,
"range_max": 100,
"opacity": 1,
},
}
)
def add_entry():
# !!! Vue2 does not support new vars with getter but vue3 should handle it
global count
count += 1
key = f"a{count}"
state.items.append(dict(id=key))
state[key] = (
{
"range": (0, 100),
"range_min": 0,
"range_max": 100,
"opacity": 0.5,
},
)
state.dirty("items")
VAR_NAMES.add(key)
state.change(key)(on_change)
update_layout()
@state.change(*VAR_NAMES)
def on_change(**_):
for name in state.modified_keys & VAR_NAMES:
print(f"Data changed for {name}")
print(state[name])
print("-" * 30)
if name == "a123":
state.a456["range"] = list(state.a123["range"])
state.dirty("a456")
def update_layout():
with SinglePageWithDrawerLayout(server) as layout:
with layout.toolbar:
vuetify.VSpacer()
vuetify.VBtn("Add", click=add_entry)
vuetify.VBtn("Fast: {{fast}}", click="fast = !fast")
with layout.drawer:
with client.Getter(
v_for="(item, i) in items",
key="item.id",
name=("`${item.id}`",),
key_name="local_name",
value_name="local_var",
update_nested_name="update_local",
):
with vuetify.VListItem(): # Must only be 1 child for a Getter
vuetify.VRangeSlider(
label=("`${local_name}`",),
value=("local_var.range",),
input="update_local('range', $event)",
min=("local_var.range_min",),
max=("local_var.range_max",),
)
vuetify.VSlider(
value=("local_var.opacity",),
input="update_local('opacity', $event)",
min=0,
max=1,
step=0.01,
)
with layout.content:
with vuetify.VRow():
# With static HTML, the proper dependency get captured and state will print faster
with vuetify.VCol(v_if=("fast", True)):
html.Div("Static dependencies", classes="text-h6")
for name in VAR_NAMES:
html.Pre("%s = {{ %s }}" % (name, name))
# With method call in template, the refresh is debounced unless proper dep above
with vuetify.VCol():
html.Div("Use method call", classes="text-h6")
with html.Div(
"State: {{ item.id }}",
v_for="item, idx in items",
key="item.id",
):
html.Pre("{{ get(item.id) }}")
if __name__ == "__main__":
update_layout()
server.start()
|