Allow renaming decks and inputs
This commit is contained in:
parent
225a8dd2d0
commit
585f5a79ba
|
@ -12,6 +12,8 @@ app_files = files(
|
|||
'src/Data/SwitchScene.vala',
|
||||
'src/Dialogs/EditCommandDialog.vala',
|
||||
'src/Dialogs/NewCommandDialog.vala',
|
||||
'src/Dialogs/EditDeckDialog.vala',
|
||||
'src/Views/CommandsView.vala',
|
||||
'src/Views/ConfigCommand.vala',
|
||||
'src/Views/DeckStack.vala',
|
||||
'src/Views/DeckView.vala',
|
||||
|
@ -33,6 +35,7 @@ executable(
|
|||
dependency('gdk-3.0'),
|
||||
dependency('gee-0.8'),
|
||||
dependency('gio-2.0'),
|
||||
dependency('glib-2.0'),
|
||||
dependency('granite'),
|
||||
dependency('gtk+-3.0'),
|
||||
dependency('json-glib-1.0'),
|
||||
|
|
146
src/Daemon.vala
146
src/Daemon.vala
|
@ -14,6 +14,11 @@ public struct Streamdeck.CommandInfo {
|
|||
public string command;
|
||||
}
|
||||
|
||||
public struct InputName {
|
||||
public uint8 key;
|
||||
public string name;
|
||||
}
|
||||
|
||||
public class Streamdeck.Daemon : Object {
|
||||
[DBus (name = "dog.asonix.git.asonix.Streamdeck")]
|
||||
private interface StreamdeckBackend : Object {
|
||||
|
@ -29,6 +34,10 @@ public class Streamdeck.Daemon : Object {
|
|||
public async abstract ReadInput[] read_input () throws GLib.Error;
|
||||
public async abstract void set_input (string serial_number, uint8 key, string command) throws GLib.Error;
|
||||
public async abstract void unset_input (string serial_number, uint8 key) throws GLib.Error;
|
||||
public async abstract void set_input_name (string serial_number, uint8 key, string name) throws GLib.Error;
|
||||
public async abstract InputName[] get_input_names (string serial_number) throws GLib.Error;
|
||||
public async abstract void set_deck_name (string serial_number, string name) throws GLib.Error;
|
||||
public async abstract string get_deck_name (string serial_number) throws GLib.Error;
|
||||
}
|
||||
|
||||
private static Daemon? _instance;
|
||||
|
@ -48,6 +57,8 @@ public class Streamdeck.Daemon : Object {
|
|||
private DeckInfo[] decks;
|
||||
private string[] scenes;
|
||||
private Gee.HashMap<string, Gee.ArrayList<CommandInfo?>> commands = new Gee.HashMap<string, Gee.ArrayList<CommandInfo?>> ();
|
||||
private Gee.HashMap<string, Gee.HashMap<uint8, string>> input_names = new Gee.HashMap<string, Gee.HashMap<uint8, string>> ();
|
||||
private Gee.HashMap<string, string> deck_names = new Gee.HashMap<string, string> ();
|
||||
|
||||
public signal void dbus_connection_signal ();
|
||||
public signal void obs_state_signal (string state);
|
||||
|
@ -55,27 +66,21 @@ public class Streamdeck.Daemon : Object {
|
|||
public signal void on_decks_added (DeckInfo[] decks);
|
||||
public signal void on_decks_removed (DeckInfo[] decks);
|
||||
public signal void scenes_signal (string[] scenes);
|
||||
public signal void commands_signal (string serial_number, CommandInfo[] commands);
|
||||
public signal void commands_signal (string serial_number, Gee.ArrayList<CommandInfo?> commands);
|
||||
public signal void key_press_signal (ReadInput key_press);
|
||||
public signal void input_name_signal (string serial_number, uint8 key, string name);
|
||||
public signal void deck_name_signal (string serial_number, string name);
|
||||
|
||||
construct {
|
||||
dbus_connection_signal.connect ((_obj) => {
|
||||
get_state.begin ((_obj, res) => {
|
||||
try {
|
||||
var state = get_state.end (res);
|
||||
obs_state_signal (state);
|
||||
} catch (Error e) {
|
||||
print ("Get state error: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
do_load_state ();
|
||||
do_load_decks ();
|
||||
|
||||
load_decks.begin ((_obj, res) => {
|
||||
try {
|
||||
var new_decks = load_decks.end (res);
|
||||
decks_signal (new_decks);
|
||||
} catch (Error e) {
|
||||
print ("Get decks error: %s\n", e.message);
|
||||
}
|
||||
GLib.Timeout.add_seconds_full (GLib.Priority.DEFAULT, 3, () => {
|
||||
do_load_state ();
|
||||
do_load_decks ();
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -100,6 +105,7 @@ public class Streamdeck.Daemon : Object {
|
|||
|
||||
foreach (DeckInfo deck_info in new_decks) {
|
||||
update_command_cache (deck_info.serial_number);
|
||||
update_name_cache (deck_info.serial_number);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -108,15 +114,7 @@ public class Streamdeck.Daemon : Object {
|
|||
});
|
||||
|
||||
commands_signal.connect ((_obj, serial_number, new_commands) => {
|
||||
var array_list = new Gee.ArrayList<CommandInfo?> ((a, b) => {
|
||||
return a.key == b.key && a.command == b.command;
|
||||
});
|
||||
|
||||
foreach (CommandInfo info in new_commands) {
|
||||
array_list.add (info);
|
||||
}
|
||||
|
||||
commands.set (serial_number, array_list);
|
||||
commands.set (serial_number, new_commands);
|
||||
});
|
||||
|
||||
Bus.get_proxy.begin<StreamdeckBackend> (
|
||||
|
@ -156,6 +154,30 @@ public class Streamdeck.Daemon : Object {
|
|||
return commands.get (serial_number);
|
||||
}
|
||||
|
||||
public string? get_deck_name (string serial_number) {
|
||||
return deck_names.get (serial_number);
|
||||
}
|
||||
|
||||
public string? get_input_name (string serial_number, uint8 key) {
|
||||
var hm = input_names.get (serial_number);
|
||||
if (hm != null) {
|
||||
return hm.get (key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async void set_deck_name (string serial_number, string name) throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
yield backend_object.set_deck_name (serial_number, name);
|
||||
}
|
||||
|
||||
public async void set_input_name (string serial_number, uint8 key, string name) throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
yield backend_object.set_input_name (serial_number, key, name);
|
||||
}
|
||||
|
||||
public async void add_command (string serial_number, uint8 key, string command) throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
|
@ -207,19 +229,66 @@ public class Streamdeck.Daemon : Object {
|
|||
load_commands.begin (serial_number, (_obj, res) => {
|
||||
try {
|
||||
var new_commands = load_commands.end (res);
|
||||
commands_signal (serial_number, new_commands);
|
||||
var array_list = new Gee.ArrayList<CommandInfo?> ((a, b) => {
|
||||
return a.key == b.key && a.command == b.command;
|
||||
});
|
||||
|
||||
foreach (CommandInfo info in new_commands) {
|
||||
array_list.add (info);
|
||||
}
|
||||
|
||||
commands_signal (serial_number, array_list);
|
||||
} catch (Error e) {
|
||||
print ("Command fetch error: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void update_name_cache (string serial_number) {
|
||||
load_deck_name.begin (serial_number, (_obj, res) => {
|
||||
try {
|
||||
var deck_name = load_deck_name.end (res);
|
||||
deck_names.set(serial_number, deck_name);
|
||||
deck_name_signal (serial_number, deck_name);
|
||||
} catch {
|
||||
// do nothing, this is fine
|
||||
}
|
||||
});
|
||||
|
||||
load_input_names.begin (serial_number, (_obj, res) => {
|
||||
try {
|
||||
var names = load_input_names.end (res);
|
||||
foreach (InputName name in names) {
|
||||
if (!input_names.has_key (serial_number)) {
|
||||
input_names.set (serial_number, new Gee.HashMap<uint8, string> ());
|
||||
}
|
||||
var hm = input_names.get (serial_number);
|
||||
hm.set (name.key, name.name);
|
||||
input_name_signal (serial_number, name.key, name.name);
|
||||
}
|
||||
} catch (Error e) {
|
||||
print ("Name fetch error: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async string[] load_scenes () throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
return yield backend_object.get_scenes ();
|
||||
}
|
||||
|
||||
private void do_load_decks () {
|
||||
load_decks.begin ((_obj, res) => {
|
||||
try {
|
||||
var new_decks = load_decks.end (res);
|
||||
decks_signal (new_decks);
|
||||
} catch (Error e) {
|
||||
print ("Get decks error: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async DeckInfo[] load_decks () throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
|
@ -232,6 +301,18 @@ public class Streamdeck.Daemon : Object {
|
|||
return yield backend_object.get_commands (serial_number);
|
||||
}
|
||||
|
||||
private async string load_deck_name (string serial_number) throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
return yield backend_object.get_deck_name (serial_number);
|
||||
}
|
||||
|
||||
private async InputName[] load_input_names (string serial_number) throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
return yield backend_object.get_input_names (serial_number);
|
||||
}
|
||||
|
||||
private async void on_state_change (string state) throws GLib.Error {
|
||||
if (obs_state == state) {
|
||||
return;
|
||||
|
@ -247,7 +328,18 @@ public class Streamdeck.Daemon : Object {
|
|||
}
|
||||
}
|
||||
|
||||
private async string get_state () throws GLib.Error {
|
||||
private void do_load_state () {
|
||||
load_state.begin ((_obj, res) => {
|
||||
try {
|
||||
var state = load_state.end (res);
|
||||
obs_state_signal (state);
|
||||
} catch (Error e) {
|
||||
print ("Get state error: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async string load_state () throws GLib.Error {
|
||||
disconnected_err ();
|
||||
|
||||
return yield backend_object.get_state ();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
namespace Streamdeck.Dialogs {
|
||||
public class EditCommandDialog : Granite.Dialog {
|
||||
public EditCommandDialog (string serial_number, Data.Command initial_command) {
|
||||
public EditCommandDialog (string serial_number, string? command_name, Data.Command initial_command) {
|
||||
var disconnected_page = new Widgets.DisconnectedPage ();
|
||||
|
||||
var command_page = new Views.ConfigCommand.from_existing (serial_number, initial_command);
|
||||
var command_page = new Views.ConfigCommand.from_existing (serial_number, command_name, initial_command);
|
||||
|
||||
var stack = new Gtk.Stack ();
|
||||
stack.add_named (disconnected_page, "disconnected");
|
||||
|
@ -24,6 +24,15 @@ namespace Streamdeck.Dialogs {
|
|||
} else {
|
||||
stack.set_visible_child_name ("command");
|
||||
}
|
||||
|
||||
response.connect ((response_id) => {
|
||||
if (response_id == Gtk.ResponseType.REJECT) {
|
||||
unowned var app = (MainWindow) transient_for;
|
||||
app.to_obs ();
|
||||
}
|
||||
|
||||
destroy ();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
49
src/Dialogs/EditDeckDialog.vala
Normal file
49
src/Dialogs/EditDeckDialog.vala
Normal file
|
@ -0,0 +1,49 @@
|
|||
namespace Streamdeck.Dialogs {
|
||||
public class EditDeckDialog : Granite.Dialog {
|
||||
private string previous_name;
|
||||
private string serial_number;
|
||||
private Gtk.Entry entry;
|
||||
|
||||
public EditDeckDialog (string serial_number, string deck_name) {
|
||||
this.serial_number = serial_number;
|
||||
this.previous_name = deck_name;
|
||||
|
||||
var label = new Gtk.Label (_("Edit Deck Name"));
|
||||
entry = new Gtk.Entry ();
|
||||
entry.valign = Gtk.Align.CENTER;
|
||||
entry.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
|
||||
entry.text = deck_name;
|
||||
|
||||
var grid = new Gtk.Grid ();
|
||||
grid.column_spacing = 12;
|
||||
grid.row_spacing = 12;
|
||||
grid.halign = Gtk.Align.CENTER;
|
||||
grid.margin = 24;
|
||||
|
||||
grid.attach (label, 0, 0);
|
||||
grid.attach (entry, 1, 0, 3);
|
||||
|
||||
get_content_area ().add (grid);
|
||||
|
||||
entry.changed.connect (handle_entry_change);
|
||||
|
||||
add_button ("Close", Gtk.ResponseType.CLOSE);
|
||||
|
||||
show_all ();
|
||||
}
|
||||
|
||||
private void handle_entry_change () {
|
||||
if (previous_name != entry.text) {
|
||||
previous_name = entry.text;
|
||||
Daemon.instance.set_deck_name.begin (serial_number, entry.text, (_obj, res) => {
|
||||
try {
|
||||
Daemon.instance.set_deck_name.end (res);
|
||||
Daemon.instance.update_name_cache (serial_number);
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
86
src/Views/CommandsView.vala
Normal file
86
src/Views/CommandsView.vala
Normal file
|
@ -0,0 +1,86 @@
|
|||
namespace Streamdeck.Views {
|
||||
public class CommandsView : Gtk.Grid {
|
||||
private string serial_number;
|
||||
private string device_name;
|
||||
private Gtk.Label label;
|
||||
private Widgets.CommandList list;
|
||||
private Dialogs.EditDeckDialog? edit_deck_dialog;
|
||||
|
||||
public signal void key_press (ReadInput key_info);
|
||||
public signal void name_change (string name);
|
||||
public signal void input_name_change (uint8 key, string name);
|
||||
public signal void command_list (Gee.ArrayList<CommandInfo?> commands);
|
||||
|
||||
public CommandsView (DeckInfo info) {
|
||||
serial_number = info.serial_number;
|
||||
device_name = info.device_name;
|
||||
|
||||
orientation = Gtk.Orientation.VERTICAL;
|
||||
|
||||
list = new Widgets.CommandList (info);
|
||||
list.expand = true;
|
||||
|
||||
label = new Gtk.Label (device_name);
|
||||
label.get_style_context ().add_class (Granite.STYLE_CLASS_H1_LABEL);
|
||||
label.halign = Gtk.Align.START;
|
||||
|
||||
var edit_button = new Gtk.Button.from_icon_name (
|
||||
"document-edit",
|
||||
Gtk.IconSize.BUTTON
|
||||
);
|
||||
edit_button.tooltip_text = _("Rename");
|
||||
edit_button.halign = Gtk.Align.END;
|
||||
edit_button.valign = Gtk.Align.CENTER;
|
||||
edit_button.expand = true;
|
||||
|
||||
var top_grid = new Gtk.Grid ();
|
||||
|
||||
top_grid.attach (label, 0, 0);
|
||||
top_grid.attach (edit_button, 1, 0);
|
||||
|
||||
attach (top_grid, 0, 0);
|
||||
attach (list, 0, 1, 1, 4);
|
||||
|
||||
show_all ();
|
||||
|
||||
key_press.connect ((info) => {
|
||||
list.key_press (info);
|
||||
});
|
||||
name_change.connect (handle_name_change);
|
||||
input_name_change.connect ((key, name) => {
|
||||
list.input_name_change (key, name);
|
||||
});
|
||||
command_list.connect ((commands) => {
|
||||
list.command_list (commands);
|
||||
});
|
||||
|
||||
edit_button.clicked.connect (handle_edit_click);
|
||||
}
|
||||
|
||||
private void handle_name_change (string name) {
|
||||
device_name = name;
|
||||
label.label = name;
|
||||
}
|
||||
|
||||
private void handle_edit_click () {
|
||||
if (edit_deck_dialog == null) {
|
||||
edit_deck_dialog = new Dialogs.EditDeckDialog (
|
||||
serial_number,
|
||||
device_name
|
||||
);
|
||||
edit_deck_dialog.transient_for = (Gtk.Window) get_toplevel ();
|
||||
edit_deck_dialog.show_all ();
|
||||
|
||||
edit_deck_dialog.response.connect ((_response_id) => {
|
||||
edit_deck_dialog.destroy ();
|
||||
});
|
||||
|
||||
edit_deck_dialog.destroy.connect (() => {
|
||||
edit_deck_dialog = null;
|
||||
});
|
||||
}
|
||||
|
||||
edit_deck_dialog.present ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,8 +4,10 @@ namespace Streamdeck.Views {
|
|||
private Widgets.ScenesComboBox scenes_combobox;
|
||||
private Widgets.CommandComboBox command_combobox;
|
||||
private string serial_number;
|
||||
private string? command_name;
|
||||
private uint8? key;
|
||||
private Data.Command? command;
|
||||
private Gtk.Entry name_entry;
|
||||
|
||||
public signal void changed (Data.Command command);
|
||||
|
||||
|
@ -18,9 +20,14 @@ namespace Streamdeck.Views {
|
|||
scenes_combobox.select_first ();
|
||||
}
|
||||
|
||||
public ConfigCommand.from_existing (string serial_number, Data.Command command) {
|
||||
public ConfigCommand.from_existing (string serial_number, string? name, Data.Command command) {
|
||||
this.serial_number = serial_number;
|
||||
this.key = command.get_command_key ();
|
||||
if (name == null) {
|
||||
this.command_name = "%d".printf (this.key);
|
||||
} else {
|
||||
this.command_name = name;
|
||||
}
|
||||
this.command = command;
|
||||
|
||||
build ();
|
||||
|
@ -65,40 +72,42 @@ namespace Streamdeck.Views {
|
|||
command_stack.add_named (new Gtk.Label ("..."), "Empty");
|
||||
command_stack.add_named (switch_scene_grid, "SwitchScene");
|
||||
|
||||
var name_label = new Gtk.Label (_("Name:"));
|
||||
name_entry = new Gtk.Entry ();
|
||||
name_entry.valign = Gtk.Align.CENTER;
|
||||
name_entry.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
|
||||
if (command_name != null) {
|
||||
name_entry.text = command_name;
|
||||
} else if (key != null) {
|
||||
command_name = "%d".printf (key);
|
||||
name_entry.text = command_name;
|
||||
}
|
||||
|
||||
column_spacing = 12;
|
||||
row_spacing = 12;
|
||||
halign = Gtk.Align.CENTER;
|
||||
margin = 24;
|
||||
|
||||
attach (command_title, 0, 0, 3);
|
||||
attach (command_label, 0, 1);
|
||||
attach (command_combobox, 1, 1);
|
||||
attach (command_stack, 2, 1);
|
||||
attach (name_label, 0, 1);
|
||||
attach (name_entry, 1, 1, 2);
|
||||
attach (command_label, 0, 2);
|
||||
attach (command_combobox, 1, 2);
|
||||
attach (command_stack, 2, 2);
|
||||
|
||||
show_all ();
|
||||
|
||||
changed.connect ((_obj, cmd) => {
|
||||
Daemon.instance.add_command.begin (
|
||||
serial_number,
|
||||
cmd.get_command_key (),
|
||||
cmd.to_json (),
|
||||
(obj, res) => {
|
||||
try {
|
||||
Daemon.instance.add_command.end (res);
|
||||
Daemon.instance.update_command_cache (serial_number);
|
||||
} catch (Error e) {
|
||||
print ("Error saving command %s\n", e.message);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
changed.connect (handle_change);
|
||||
name_entry.changed.connect (handle_name_change);
|
||||
scenes_combobox.selected.connect (handle_scene_change);
|
||||
command_combobox.selected.connect (handle_type_change);
|
||||
}
|
||||
|
||||
public void set_key (uint8 key) {
|
||||
this.key = key;
|
||||
if (command_name == null) {
|
||||
command_name = "%d".printf (key);
|
||||
}
|
||||
|
||||
var type = command_combobox.get_selected_type ();
|
||||
|
||||
|
@ -107,6 +116,41 @@ namespace Streamdeck.Views {
|
|||
}
|
||||
}
|
||||
|
||||
private void handle_change (Data.Command cmd) {
|
||||
Daemon.instance.add_command.begin (
|
||||
serial_number,
|
||||
cmd.get_command_key (),
|
||||
cmd.to_json (),
|
||||
(obj, res) => {
|
||||
try {
|
||||
Daemon.instance.add_command.end (res);
|
||||
Daemon.instance.update_command_cache (serial_number);
|
||||
} catch (Error e) {
|
||||
print ("Error saving command %s\n", e.message);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void handle_name_change () {
|
||||
if (command_name != name_entry.text && key != null) {
|
||||
command_name = name_entry.text;
|
||||
Daemon.instance.set_input_name.begin (
|
||||
serial_number,
|
||||
key,
|
||||
name_entry.text,
|
||||
(_obj, res) => {
|
||||
try {
|
||||
Daemon.instance.set_input_name.end (res);
|
||||
Daemon.instance.update_name_cache (serial_number);
|
||||
} catch {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void handle_type_change (Data.CommandType type) {
|
||||
switch (type) {
|
||||
case Data.CommandType.SWITCH_SCENE:
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Streamdeck.Views {
|
|||
add_named (new Widgets.EmptyConfigPane (), "empty-state");
|
||||
|
||||
show_all();
|
||||
|
||||
Daemon.instance.key_press_signal.connect (handle_key_press);
|
||||
Daemon.instance.commands_signal.connect (handle_commands);
|
||||
Daemon.instance.deck_name_signal.connect (handle_name_change);
|
||||
Daemon.instance.input_name_signal.connect (handle_input_name_change);
|
||||
}
|
||||
|
||||
public void select_deck (string serial_number) {
|
||||
|
@ -17,7 +22,7 @@ namespace Streamdeck.Views {
|
|||
return;
|
||||
}
|
||||
|
||||
var pane = new Widgets.CommandList (deck_info);
|
||||
var pane = new Views.CommandsView (deck_info);
|
||||
add_named (pane, deck_info.serial_number);
|
||||
}
|
||||
|
||||
|
@ -27,5 +32,45 @@ namespace Streamdeck.Views {
|
|||
remove (child);
|
||||
}
|
||||
}
|
||||
|
||||
private void handle_key_press (ReadInput key_info) {
|
||||
var child = get_visible_child ();
|
||||
if (child == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unowned var list = (Views.CommandsView) child;
|
||||
list.key_press (key_info);
|
||||
}
|
||||
|
||||
private void handle_name_change (string serial_number, string name) {
|
||||
var child = get_child_by_name (serial_number);
|
||||
if (child == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unowned var list = (Views.CommandsView) child;
|
||||
list.name_change (name);
|
||||
}
|
||||
|
||||
private void handle_input_name_change (string serial_number, uint8 key, string name) {
|
||||
var child = get_child_by_name (serial_number);
|
||||
if (child == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unowned var list = (Views.CommandsView) child;
|
||||
list.input_name_change (key, name);
|
||||
}
|
||||
|
||||
private void handle_commands (string serial_number, Gee.ArrayList<CommandInfo?> commands) {
|
||||
var child = get_child_by_name (serial_number);
|
||||
if (child == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unowned var list = (Views.CommandsView) child;
|
||||
list.command_list (commands);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
namespace Streamdeck.Widgets {
|
||||
public class CommandList : Gtk.Frame {
|
||||
private DeckInfo info;
|
||||
private string serial_number;
|
||||
private Gtk.ListBox list_box;
|
||||
private Dialogs.NewCommandDialog? new_command_dialog;
|
||||
private Gee.HashMap<uint8, CommandRow> row_map = new Gee.HashMap<uint8, CommandRow> ();
|
||||
|
||||
public signal void key_press (ReadInput key_info);
|
||||
public signal void input_name_change (uint8 key, string name);
|
||||
public signal void command_list (Gee.ArrayList<CommandInfo?> commands);
|
||||
|
||||
public CommandList(DeckInfo info) {
|
||||
this.info = info;
|
||||
this.serial_number = info.serial_number;
|
||||
|
||||
var alert = new Granite.Widgets.AlertView (
|
||||
_("No commands registered"),
|
||||
|
@ -42,29 +46,15 @@ namespace Streamdeck.Widgets {
|
|||
scrolled.expand = true;
|
||||
scrolled.add (list_box);
|
||||
|
||||
Daemon.instance.key_press_signal.connect ((_obj, key_info) => {
|
||||
key_press.connect ((_obj, key_info) => {
|
||||
if (new_command_dialog != null) {
|
||||
new_command_dialog.key_press (key_info);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var commands = Daemon.instance.get_commands (info.serial_number);
|
||||
var commands = Daemon.instance.get_commands (serial_number);
|
||||
if (commands != null) {
|
||||
foreach (CommandInfo cmd_info in commands) {
|
||||
var command = Data.Command.parse (cmd_info.key, cmd_info.command);
|
||||
|
||||
if (command != null) {
|
||||
var existing = row_map.get (cmd_info.key);
|
||||
if (existing != null) {
|
||||
list_box.remove (existing);
|
||||
}
|
||||
|
||||
var row = new CommandRow (info.serial_number, command);
|
||||
row_map.set (cmd_info.key, row);
|
||||
list_box.add (row);
|
||||
}
|
||||
}
|
||||
handle_command_list (commands);
|
||||
}
|
||||
|
||||
var grid = new Gtk.Grid ();
|
||||
|
@ -74,71 +64,85 @@ namespace Streamdeck.Widgets {
|
|||
|
||||
add (grid);
|
||||
|
||||
remove_button.clicked.connect (() => {
|
||||
var row = list_box.get_selected_row ();
|
||||
if (row == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unowned var command_row = (CommandRow) row;
|
||||
var key = command_row.get_key ();
|
||||
|
||||
Daemon.instance.remove_command.begin (info.serial_number, key, (_obj, res) => {
|
||||
try {
|
||||
Daemon.instance.remove_command.end (res);
|
||||
Daemon.instance.update_command_cache (info.serial_number);
|
||||
|
||||
row_map.unset (key);
|
||||
list_box.remove (row);
|
||||
} catch (Error e) {
|
||||
print ("Error removing command: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
add_button.clicked.connect (() => {
|
||||
if (new_command_dialog == null) {
|
||||
new_command_dialog = new Dialogs.NewCommandDialog (info.serial_number);
|
||||
new_command_dialog.transient_for = (Gtk.Window) get_toplevel ();
|
||||
new_command_dialog.show_all ();
|
||||
|
||||
new_command_dialog.response.connect ((response_id) => {
|
||||
if (response_id == Gtk.ResponseType.REJECT) {
|
||||
unowned var app = (MainWindow) get_toplevel ();
|
||||
app.to_obs ();
|
||||
}
|
||||
|
||||
new_command_dialog.destroy ();
|
||||
});
|
||||
|
||||
new_command_dialog.destroy.connect (() => {
|
||||
new_command_dialog = null;
|
||||
});
|
||||
}
|
||||
|
||||
new_command_dialog.present ();
|
||||
});
|
||||
|
||||
Daemon.instance.commands_signal.connect ((_obj, serial_number, commands) => {
|
||||
if (serial_number == info.serial_number) {
|
||||
foreach (CommandInfo cmd_info in commands) {
|
||||
var command = Data.Command.parse (cmd_info.key, cmd_info.command);
|
||||
|
||||
if (command != null) {
|
||||
var existing = row_map.get (cmd_info.key);
|
||||
if (existing != null) {
|
||||
list_box.remove (existing);
|
||||
}
|
||||
|
||||
var row = new CommandRow (serial_number, command);
|
||||
row_map.set (cmd_info.key, row);
|
||||
list_box.add (row);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
remove_button.clicked.connect (handle_remove_click);
|
||||
add_button.clicked.connect (handle_add_click);
|
||||
command_list.connect (handle_command_list);
|
||||
input_name_change.connect (handle_input_name_change);
|
||||
|
||||
show_all ();
|
||||
}
|
||||
|
||||
private void handle_remove_click () {
|
||||
var row = list_box.get_selected_row ();
|
||||
if (row == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
unowned var command_row = (CommandRow) row;
|
||||
var key = command_row.get_key ();
|
||||
|
||||
Daemon.instance.remove_command.begin (serial_number, key, (_obj, res) => {
|
||||
try {
|
||||
Daemon.instance.remove_command.end (res);
|
||||
Daemon.instance.update_command_cache (serial_number);
|
||||
|
||||
row_map.unset (key);
|
||||
list_box.remove (row);
|
||||
} catch (Error e) {
|
||||
print ("Error removing command: %s\n", e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handle_add_click () {
|
||||
if (new_command_dialog == null) {
|
||||
new_command_dialog = new Dialogs.NewCommandDialog (serial_number);
|
||||
new_command_dialog.transient_for = (Gtk.Window) get_toplevel ();
|
||||
new_command_dialog.show_all ();
|
||||
|
||||
new_command_dialog.response.connect ((response_id) => {
|
||||
if (response_id == Gtk.ResponseType.REJECT) {
|
||||
unowned var app = (MainWindow) get_toplevel ();
|
||||
app.to_obs ();
|
||||
}
|
||||
|
||||
new_command_dialog.destroy ();
|
||||
});
|
||||
|
||||
new_command_dialog.destroy.connect (() => {
|
||||
new_command_dialog = null;
|
||||
});
|
||||
}
|
||||
|
||||
new_command_dialog.present ();
|
||||
}
|
||||
|
||||
private void handle_command_list (Gee.ArrayList<CommandInfo?> commands) {
|
||||
foreach (CommandInfo cmd_info in commands) {
|
||||
var command = Data.Command.parse (cmd_info.key, cmd_info.command);
|
||||
|
||||
if (command != null) {
|
||||
var existing = row_map.get (cmd_info.key);
|
||||
if (existing != null) {
|
||||
list_box.remove (existing);
|
||||
}
|
||||
|
||||
var name = Daemon.instance.get_input_name (serial_number, cmd_info.key);
|
||||
|
||||
var row = new CommandRow (serial_number, name, command);
|
||||
row_map.set (cmd_info.key, row);
|
||||
list_box.add (row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handle_input_name_change (uint8 key, string name) {
|
||||
var row = row_map.get (key);
|
||||
if (row == null) {
|
||||
return;
|
||||
}
|
||||
unowned var command_row = (CommandRow) row;
|
||||
command_row.name_change (name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,31 @@
|
|||
namespace Streamdeck.Widgets {
|
||||
public class CommandRow : Gtk.ListBoxRow {
|
||||
private string serial_number;
|
||||
private string? command_name;
|
||||
private Data.Command command;
|
||||
private Dialogs.EditCommandDialog? edit_dialog;
|
||||
private Gtk.Label row_key;
|
||||
|
||||
public CommandRow (string serial_number, Data.Command command) {
|
||||
public signal void name_change (string name);
|
||||
|
||||
public CommandRow (string serial_number, string? command_name, Data.Command command) {
|
||||
this.serial_number = serial_number;
|
||||
this.command_name = command_name;
|
||||
this.command = command;
|
||||
|
||||
var key = command.get_command_key ();
|
||||
var row_key = new Gtk.Label (@"$(key)");
|
||||
row_key = new Gtk.Label ("%d".printf (key));
|
||||
if (command_name != null) {
|
||||
row_key.label = command_name;
|
||||
}
|
||||
row_key.halign = Gtk.Align.START;
|
||||
row_key.valign = Gtk.Align.START;
|
||||
row_key.valign = Gtk.Align.CENTER;
|
||||
row_key.expand = true;
|
||||
row_key.show_all ();
|
||||
|
||||
var row_command = new Gtk.Label (null);
|
||||
row_command.halign = Gtk.Align.START;
|
||||
row_command.valign = Gtk.Align.START;
|
||||
row_command.valign = Gtk.Align.CENTER;
|
||||
row_command.show_all ();
|
||||
|
||||
var row_grid = new Gtk.Grid ();
|
||||
|
@ -43,30 +52,8 @@ namespace Streamdeck.Widgets {
|
|||
);
|
||||
row_edit.tooltip_text = _("Edit");
|
||||
row_edit.halign = Gtk.Align.END;
|
||||
row_edit.valign = Gtk.Align.END;
|
||||
row_edit.valign = Gtk.Align.CENTER;
|
||||
row_edit.expand = true;
|
||||
row_edit.clicked.connect (() => {
|
||||
if (edit_dialog == null) {
|
||||
edit_dialog = new Dialogs.EditCommandDialog (serial_number, command);
|
||||
edit_dialog.transient_for = (Gtk.Window) get_toplevel ();
|
||||
edit_dialog.show_all ();
|
||||
|
||||
edit_dialog.response.connect ((response_id) => {
|
||||
if (response_id == Gtk.ResponseType.REJECT) {
|
||||
unowned var app = (MainWindow) get_toplevel ();
|
||||
app.to_obs ();
|
||||
}
|
||||
|
||||
edit_dialog.destroy ();
|
||||
});
|
||||
|
||||
edit_dialog.destroy.connect (() => {
|
||||
edit_dialog = null;
|
||||
});
|
||||
}
|
||||
|
||||
edit_dialog.present ();
|
||||
});
|
||||
|
||||
row_grid.add (row_edit);
|
||||
|
||||
|
@ -75,22 +62,45 @@ namespace Streamdeck.Widgets {
|
|||
add (row_grid);
|
||||
|
||||
show_all ();
|
||||
|
||||
row_edit.clicked.connect (handle_edit_click);
|
||||
name_change.connect (handle_name_change);
|
||||
|
||||
}
|
||||
|
||||
public uint8 get_key () {
|
||||
return command.get_command_key ();
|
||||
}
|
||||
|
||||
private void handle_edit_click () {
|
||||
if (edit_dialog == null) {
|
||||
edit_dialog = new Dialogs.EditCommandDialog (serial_number, command_name, command);
|
||||
edit_dialog.transient_for = (Gtk.Window) get_toplevel ();
|
||||
edit_dialog.show_all ();
|
||||
|
||||
edit_dialog.destroy.connect (() => {
|
||||
edit_dialog = null;
|
||||
});
|
||||
}
|
||||
|
||||
edit_dialog.present ();
|
||||
}
|
||||
|
||||
private void handle_name_change (string name) {
|
||||
command_name = name;
|
||||
row_key.label = name;
|
||||
}
|
||||
|
||||
private void switch_scene_ui (Gtk.Grid row_grid) {
|
||||
unowned var switch_scene = (Data.SwitchScene) command;
|
||||
var to = new Gtk.Label (_("to"));
|
||||
to.halign = Gtk.Align.START;
|
||||
to.valign = Gtk.Align.START;
|
||||
to.valign = Gtk.Align.CENTER;
|
||||
to.show_all ();
|
||||
|
||||
var scene_name = new Gtk.Label (switch_scene.scene_name);
|
||||
scene_name.halign = Gtk.Align.START;
|
||||
scene_name.valign = Gtk.Align.START;
|
||||
scene_name.valign = Gtk.Align.CENTER;
|
||||
scene_name.show_all ();
|
||||
|
||||
row_grid.add (to);
|
||||
|
|
|
@ -27,12 +27,6 @@ namespace Streamdeck.Widgets {
|
|||
|
||||
list_box.set_header_func (update_headers);
|
||||
|
||||
list_box.row_selected.connect ((row) => {
|
||||
row.activate ();
|
||||
unowned var item = (DeckItem) row;
|
||||
deck_stack.select_deck (item.serial_number);
|
||||
});
|
||||
|
||||
var scroll = new Gtk.ScrolledWindow (null, null);
|
||||
scroll.hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
scroll.expand = true;
|
||||
|
@ -41,13 +35,34 @@ namespace Streamdeck.Widgets {
|
|||
add (scroll);
|
||||
|
||||
show_all ();
|
||||
|
||||
list_box.row_selected.connect ((row) => {
|
||||
if (row == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
row.activate ();
|
||||
unowned var item = (DeckItem) row;
|
||||
deck_stack.select_deck (item.serial_number);
|
||||
});
|
||||
|
||||
Daemon.instance.deck_name_signal.connect (handle_deck_name);
|
||||
}
|
||||
|
||||
public void add_deck (DeckInfo deck_info) {
|
||||
var already_present = false;
|
||||
|
||||
foreach (Gtk.Widget child in list_box.get_children ()) {
|
||||
var deck_item = (DeckItem) child;
|
||||
var name = Daemon.instance.get_deck_name (deck_info.serial_number);
|
||||
if (name != null) {
|
||||
deck_info.device_name = name;
|
||||
}
|
||||
|
||||
foreach (unowned Gtk.Widget child in list_box.get_children ()) {
|
||||
if (child == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unowned var deck_item = (DeckItem) child;
|
||||
|
||||
already_present = already_present
|
||||
|| deck_item.serial_number == deck_info.serial_number;
|
||||
|
@ -69,8 +84,12 @@ namespace Streamdeck.Widgets {
|
|||
}
|
||||
|
||||
public void remove_deck (DeckInfo deck_info) {
|
||||
foreach (Gtk.Widget child in list_box.get_children ()) {
|
||||
var deck_item = (DeckItem) child;
|
||||
foreach (unowned Gtk.Widget child in list_box.get_children ()) {
|
||||
if (child == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unowned var deck_item = (DeckItem) child;
|
||||
|
||||
if (deck_item.serial_number == deck_info.serial_number) {
|
||||
deck_stack.remove_deck (deck_info);
|
||||
|
@ -83,6 +102,19 @@ namespace Streamdeck.Widgets {
|
|||
show_all ();
|
||||
}
|
||||
|
||||
private void handle_deck_name (string serial_number, string name) {
|
||||
foreach (unowned Gtk.Widget row in list_box.get_children ()) {
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unowned var item = (DeckItem) row;
|
||||
if (item.serial_number == serial_number) {
|
||||
item.device_name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void update_headers (Gtk.ListBoxRow row, Gtk.ListBoxRow? before = null) {
|
||||
if (before != null) {
|
||||
row.set_header (null);
|
||||
|
|
Loading…
Reference in a new issue