Skip to content

Commit 4ab3c54

Browse files
authored
Added configuration dialog
2 parents 73b0d86 + ca028ac commit 4ab3c54

5 files changed

Lines changed: 252 additions & 56 deletions

File tree

schemas/com.github.philip-scott.spice-up.gschema.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,10 @@
2929
<summary>The last opened file</summary>
3030
<description>The last file you opened is here</description>
3131
</key>
32+
<key name="controler-config" type="s">
33+
<default>""</default>
34+
<summary>Controler configuration for presentation mode</summary>
35+
<description>In JSON format</description>
36+
</key>
3237
</schema>
3338
</schemalist>

src/Services/GamepadSlideController.vala

Lines changed: 214 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,63 +20,76 @@
2020
*/
2121

2222
public class Spice.GamepadSlideController : Object {
23-
private static GamepadSlideController? instance = null;
24-
private unowned SlideManager slide_manager;
23+
public signal void raw_button (int button);
24+
25+
private static Spice.GamepadSlideController? instance = null;
26+
private unowned Spice.SlideManager slide_manager;
27+
private unowned Spice.Window window;
2528

2629
private LibGamepad.GamepadMonitor gamepad_monitor;
2730
private LibGamepad.Gamepad[] gamepads = {};
2831

29-
public static void startup (SlideManager _slide_manager) {
32+
private Granite.Widgets.Toast? toast = null;
33+
private ControlerConfiguration? config = null;
34+
35+
public bool editing = false;
36+
37+
public static void startup (SlideManager _slide_manager, Spice.Window window) {
3038
if (instance == null) {
31-
instance = new GamepadSlideController ();
39+
instance = new GamepadSlideController (window);
3240
}
3341

3442
instance.slide_manager = _slide_manager;
3543
}
3644

37-
private GamepadSlideController () {
45+
private GamepadSlideController (Spice.Window window) {
46+
this.window = window;
3847
gamepad_monitor = new LibGamepad.GamepadMonitor ();
3948

40-
// On plugin, connect signals to the gamepad and store it in the gamepads array so it is not deleted by reference counting
41-
gamepad_monitor.gamepad_plugged.connect ((gamepad) => {
42-
print (@"GM Plugged in $(gamepad.raw_gamepad.identifier)- $(gamepad.raw_name)\n");
43-
gamepads += gamepad;
44-
// Bind events
45-
gamepad.button_event.connect (button_event);
46-
//gamepad.axis_event.connect ((axis, value) => print (@"$(gamepad.raw_name) - $(axis.to_string ()) - $value\n"));
47-
gamepad.unplugged.connect (() => print (@"$(gamepad.raw_name) - G Unplugged\n"));
48-
});
49-
50-
// Initialize initially plugged in gamepads
51-
gamepad_monitor.foreach_gamepad ((gamepad) => {
52-
print (@"GM Initially Plugged in $(gamepad.raw_gamepad.identifier) - $(gamepad.guid) - $(gamepad.raw_name)\n");
53-
gamepads += gamepad;
54-
// Bind events
55-
gamepad.button_event.connect (button_event);
56-
//gamepad.axis_event.connect ((axis, value) => print (@"$(gamepad.name) - $(axis.to_string ()) - $value\n"));
57-
gamepad.unplugged.connect (() => print (@"$(gamepad.raw_name) - G Unplugged\n"));
58-
});
49+
gamepad_monitor.gamepad_plugged.connect (connect_gamepad);
50+
gamepad_monitor.foreach_gamepad (connect_gamepad);
51+
}
52+
53+
private void connect_gamepad (LibGamepad.Gamepad gamepad) {
54+
debug ("Controler Plugged in %s, %s", gamepad.raw_gamepad.identifier, gamepad.raw_name);
55+
gamepads += gamepad;
56+
57+
config = new ControlerConfiguration ();
58+
59+
gamepad.button_event.connect (button_event);
60+
gamepad.unplugged.connect (() => debug (@"$(gamepad.raw_name) - G Unplugged\n"));
61+
show_controller_toast ();
62+
}
63+
64+
private void show_controller_toast () {
65+
if (toast == null) {
66+
toast = new Granite.Widgets.Toast (_("Controller found"));
67+
toast.set_default_action (_("Set up…"));
68+
69+
toast.default_action.connect (() => {
70+
var dialog = new ControllerConfigurationDialog (this, this.config);
71+
dialog.present ();
72+
});
73+
}
74+
75+
this.window.add_toast_notification (toast);
5976
}
6077

6178
private void button_event (int button) {
6279
debug ("Gamepad Button event: %d\n", button);
80+
raw_button (button);
81+
if (editing) return;
6382

64-
switch (button) {
65-
case 0:
66-
next_slide ();
67-
break;
68-
case 2:
69-
previous_slide ();
70-
break;
71-
case 12:
72-
toggle_present ();
73-
break;
74-
case 1:
75-
jump_to_checkpoint ();
76-
break;
77-
case 3:
78-
set_checkpoint ();
79-
break;
83+
if (button == config.next) {
84+
next_slide ();
85+
} else if (button == config.back) {
86+
previous_slide ();
87+
} else if (button == config.checkpoint) {
88+
set_checkpoint ();
89+
} else if (button == config.jump) {
90+
jump_to_checkpoint ();
91+
} else if (button == config.home) {
92+
toggle_present ();
8093
}
8194
}
8295

@@ -107,4 +120,165 @@ public class Spice.GamepadSlideController : Object {
107120
window.fullscreen ();
108121
}
109122
}
123+
124+
private class ControllerConfigurationDialog : Gtk.Dialog {
125+
private unowned ControlerConfiguration config;
126+
private unowned GamepadSlideController monitor;
127+
128+
private Gtk.Grid grid;
129+
private Gtk.Widget save_button;
130+
131+
private bool listening = false;
132+
private int** listening_action = null;
133+
private Gtk.Button listening_button;
134+
135+
private int row = 0;
136+
137+
public ControllerConfigurationDialog (GamepadSlideController monitor, ControlerConfiguration _config) {
138+
this.monitor = monitor;
139+
this.config = _config;
140+
141+
monitor.editing = true;
142+
143+
this.set_border_width (12);
144+
set_titlebar (new Gtk.Grid ());
145+
set_keep_above (true);
146+
set_size_request (360, 400);
147+
resizable = false;
148+
modal = true;
149+
150+
var label = new Gtk.Label (_("Controller Configuration"));
151+
label.get_style_context ().add_class ("h4");
152+
153+
this.grid = new Gtk.Grid ();
154+
grid.orientation = Gtk.Orientation.VERTICAL;
155+
grid.column_spacing = 12;
156+
grid.row_spacing = 6;
157+
158+
grid.attach (label, 0, row++, 1, 1);
159+
add_row (_("Next Slide:"), &(config.next));
160+
add_row (_("Previous Slide:"), &(config.back));
161+
add_row (_("Set Jump:"), &(config.checkpoint));
162+
add_row (_("Jump to slide:"), &(config.jump));
163+
add_row (_("Toggle Presentation:"), &(config.home));
164+
165+
get_content_area ().add (grid);
166+
add_button (_("Cancel"), 2);
167+
save_button = add_button (_("Apply"), 1);
168+
169+
response.connect ((ID) => {
170+
switch (ID) {
171+
case 1:
172+
config.save ();
173+
break;
174+
}
175+
176+
listening = false;
177+
monitor.editing = false;
178+
this.close ();
179+
});
180+
181+
monitor.raw_button.connect ((id) => {
182+
if (!this.listening) return;
183+
this.listening = false;
184+
185+
debug ("Event caught %d\n", id);
186+
187+
**listening_action = id;
188+
listening_button.label = _("Button %d").printf (id);
189+
190+
save_button.sensitive = config.is_valid ();
191+
});
192+
193+
this.show_all ();
194+
}
195+
196+
public void add_row (string name, int* action) {
197+
var label = new Gtk.Label (name);
198+
label.halign = Gtk.Align.END;
199+
200+
var button = new Gtk.Button.with_label (_("Button %d").printf (*action));
201+
button.clicked.connect (() => {
202+
if (listening) {
203+
listening_button.label = _("Button %d").printf (**listening_action);
204+
}
205+
206+
if (!listening || this.listening_button != button) {
207+
this.listening = true;
208+
this.listening_action = &action;
209+
this.listening_button = button;
210+
button.label = _("...");
211+
save_button.sensitive = false;
212+
} else if (listening && this.listening_button == button) {
213+
this.listening = false;
214+
this.listening_button = null;
215+
save_button.sensitive = config.is_valid ();
216+
}
217+
});
218+
219+
this.grid.attach (label, 0, row, 1, 1);
220+
this.grid.attach (button, 1, row++, 1, 1);
221+
}
222+
}
223+
224+
private class ControlerConfiguration : Object {
225+
// Defaults to JoyCon's Configuration
226+
public int next = 0;
227+
public int back = 2;
228+
public int checkpoint = 3;
229+
public int jump = 1;
230+
public int home = 12;
231+
232+
public ControlerConfiguration () {
233+
load ();
234+
}
235+
236+
public bool is_valid () {
237+
var buttons = new Array<int>();
238+
buttons.append_val (next);
239+
240+
if (back in buttons.data) return false;
241+
buttons.append_val (back);
242+
243+
if (checkpoint in buttons.data) return false;
244+
buttons.append_val (checkpoint);
245+
246+
if (jump in buttons.data) return false;
247+
buttons.append_val (jump);
248+
249+
if (home in buttons.data) return false;
250+
buttons.append_val (home);
251+
252+
return true;
253+
}
254+
255+
public void load () {
256+
var config = Spice.Services.Settings.get_instance ().controler_config;
257+
if (config == "") {
258+
save ();
259+
return;
260+
}
261+
262+
try {
263+
var parser = new Json.Parser ();
264+
parser.load_from_data (config);
265+
266+
var root = parser.get_root ().get_object ();
267+
268+
next = (int) root.get_int_member ("next");
269+
back = (int) root.get_int_member ("back");
270+
checkpoint = (int) root.get_int_member ("checkpoint");
271+
jump = (int) root.get_int_member ("jump");
272+
home = (int) root.get_int_member ("home");
273+
} catch (Error e) {
274+
warning ("Error loading controler config: %s", e.message);
275+
save ();
276+
}
277+
}
278+
279+
public void save () {
280+
var config = """{"next":%d, "back":%d, "checkpoint":%d, "jump":%d, "home":%d }""".printf (next, back, checkpoint, jump, home);
281+
Spice.Services.Settings.get_instance ().controler_config = config;
282+
}
283+
}
110284
}

src/Services/Settings.vala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class Spice.Services.Settings : Granite.Services.Settings {
2727
public int window_width { get; set; }
2828
public int window_height { get; set; }
2929
public string last_file { get; set; }
30+
public string controler_config { get; set; }
3031

3132
public static Settings get_instance () {
3233
if (instance == null) {

src/Services/SlideManager.vala

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,6 @@ public class Spice.SlideManager : Object {
5757
public SlideManager () {
5858
slideshow = new Gtk.Stack ();
5959
slides = new Gee.ArrayList<Slide> ();
60-
61-
GamepadSlideController.startup (this);
62-
63-
/*joycon.output_changed.connect ((text) => {
64-
stderr.printf (text);
65-
66-
67-
});
68-
69-
joycon.done.connect ((i) => {
70-
stderr.printf ("Done :(\n");
71-
});
72-
73-
joycon.run ();*/
7460
}
7561

7662
public void reset () {

0 commit comments

Comments
 (0)