Skip to content

Commit

Permalink
Save/restore controls state (#165).
Browse files Browse the repository at this point in the history
  • Loading branch information
gogins committed Jul 25, 2021
1 parent d85fc07 commit 18c08c9
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 25 deletions.
1 change: 1 addition & 0 deletions playpen/controls-test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print("hi")
221 changes: 221 additions & 0 deletions playpen/controls-test.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment2">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkPopover" id="gk_popover">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<object class="GtkGrid" id="user_controls_layout">
<property name="name">user_controls_layout</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">10</property>
<child>
<object class="GtkButton" id="gk_button">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="gk_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="gk_spin_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">adjustment2</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="gk_togglebutton">
<property name="label" translatable="yes">togglebutton</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="gk_checkbutton">
<property name="label" translatable="yes">checkbutton</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="gk_radiobutton">
<property name="label" translatable="yes">radiobutton</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">radiobutton1</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radiobutton1">
<property name="label" translatable="yes">radiobutton</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">gk_radiobutton</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="height">2</property>
</packing>
</child>
<child>
<object class="GtkScaleButton" id="gk_scalebutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child internal-child="plus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
</child>
<child internal-child="minus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">8</property>
</packing>
</child>
<child>
<object class="GtkScale" id="gk_scale">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">adjustment1</property>
<property name="round_digits">1</property>
<property name="value_pos">right</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">9</property>
</packing>
</child>
<child>
<object class="GtkVolumeButton" id="gk_volumebutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<property name="icons">audio-volume-muted-symbolic
audio-volume-high-symbolic
audio-volume-low-symbolic
audio-volume-medium-symbolic</property>
<child internal-child="plus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
</child>
<child internal-child="minus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">10</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="gk_menubutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="popover">gk_popover</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">11</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="gk_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">12</property>
</packing>
</child>
</object>
</interface>
53 changes: 28 additions & 25 deletions playpen/playpen.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def autoexception(message):
ui_controls_template = '''<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkGrid">
<object class="GtkGrid" id="user_controls_layout">
<property id="name">user_controls_layout</property>
<property name="name">user_controls_layout</property>
<property name="visible">True</property>
Expand Down Expand Up @@ -217,21 +217,26 @@ def load_piece():

"""
Saves the ui for the piece, not from the ui text, but from the ui controls,
updating the ui DOM with the current values of the user controls. The ids of the
controls should be unique.
updating the ui DOM with the _current_ values of the user controls. Each
control's name must be the same as its id, and each control must have a
unique id.
"""
def save_ui():
global piece_ui_dom
global widgets_for_channel_names
autolog(piece_filepath)
autolog(ElementTree.dump(piece_ui_dom))
autolog("piece_ui_dom dump:\n{}".format(ElementTree.dump(piece_ui_dom)))
try:
ui_filepath = get_ui_filepath()
autolog("ui_filepath: {}".format(ui_filepath))
for channel, value in widgets_for_channel_names.items():
autolog("channel: {} value: {}".format(channel, value))
# xpath = "//property"
xpath_id = "//object[@id='{}']".format(channel)
autolog(" widget value: {}".format(value[1].get_value()))
try:
autolog(" widget value: {}".format(value[1].get_value()))
except:
autoexception("widget.get_value?")
autolog(" xpath: {}".format(xpath_id))
dom_elements = piece_ui_dom.findall(xpath_id)
# autolog(dom_elements)
Expand Down Expand Up @@ -283,9 +288,12 @@ def connect_controls(container, on_control_changed_):
autolog(child.get_name())
child.connect("value-changed", on_control_changed_, -1.)
widgets_for_channel_names[channel_name] = (get_control_value(child), child)
if isinstance(child, Gtk.Switch):
autolog(child.get_name())
child.connect("state-set", on_control_changed_, -1.)
widgets_for_channel_names[channel_name] = (get_control_value(child), child)
if isinstance(child, Gtk.Editable):
autolog(child.get_name())
controls_for_ids[child.get_name()] = child
child.connect("activate", on_control_changed_, -1.)
widgets_for_channel_names[channel_name] = (get_control_value(child), child)
if isinstance(child, Gtk.SpinButton):
Expand All @@ -298,7 +306,7 @@ def connect_controls(container, on_control_changed_):
# Please note, the order of conditions matters; some subclasses do
# not handle superclass signals.

def on_control_change(control, data):
def on_control_change(control, data, user=None):
try:
channel_name = control.get_name()
channel_value = get_control_value(control)
Expand All @@ -319,7 +327,7 @@ def on_control_change(control, data):
channel_value = control.get_text()
csound.SetStringChannel(channel_name, channel_value)
widgets_for_channel_names[channel_name] = (channel_value, control)
autolog("on_control_change: channel: {} type: {} (widget: {} data: {} value: {})".format(channel_name, type(channel_value), control, data, channel_value))
autolog("on_control_change:\n\tchannel: {}\n\ttype: {} (widget: {} data: {} value: {})".format(channel_name, type(channel_value), control, data, channel_value))
except:
print(traceback.format_exc())

Expand All @@ -337,23 +345,18 @@ def load_ui():
ui_filepath = get_ui_filepath()
if os.path.exists(ui_filepath) == True:
try:
with open(ui_filepath, "r") as file:
ui_xml = file.read()
piece_ui_dom = ElementTree.parse(ui_filepath)
autolog(piece_ui_dom)
piece_ui_dom.write(ui_filepath + ".xml")
# print("ui:", ui_xml)
result = builder.add_from_string(ui_xml)
if result == 0:
print("Failed to parse {} file.".format(ui_filepath))
user_controls_layout = builder.get_object("user_controls_layout")
# print("user_controls_layout: {}".format(user_controls_layout))
children = controls_layout.get_children()
for child in children:
if child.get_name() == "user_controls_layout":
controls_layout.remove(child)
controls_layout.add(user_controls_layout)
connect_controls(controls_layout, on_control_change)
piece_ui_dom = ElementTree.parse(ui_filepath)
piece_ui_dom.write(ui_filepath + ".xml")
ui_text = ElementTree.tostring(piece_ui_dom.getroot(), encoding="unicode")
result = builder.add_from_string(ui_text)
user_controls_layout = builder.get_object("user_controls_layout")
autolog("user_controls_layout: {}".format(user_controls_layout))
children = controls_layout.get_children()
for child in children:
if child.get_name() == "user_controls_layout":
controls_layout.remove(child)
controls_layout.add(user_controls_layout)
connect_controls(controls_layout, on_control_change)
except:
autolog("Error: failed to load user-defined controls layout.")
print(traceback.format_exc())
Expand Down

0 comments on commit 18c08c9

Please sign in to comment.