Show command row text, deck item text, add edit deck dialog
This commit is contained in:
parent
7d35810867
commit
c3ff8eca36
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,6 +1,3 @@
|
|||
[submodule "obws"]
|
||||
path = obws
|
||||
url = https://git.asonix.dog/asonix/obws
|
||||
[submodule "libhandy-rs"]
|
||||
path = libhandy-rs
|
||||
url = https://git.asonix.dog/asonix/libhandy-rs
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 12924ef6d6287fedcc4ffb4fc5b6ab78448d2ff3
|
48
streamdeck/Cargo.lock
generated
48
streamdeck/Cargo.lock
generated
|
@ -47,7 +47,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "atk"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#2f86e52185021b540913ae8e87cf857a1dbd1ea6"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#dff1e67f2da991a27fb18654cb70b7f169262dc2"
|
||||
dependencies = [
|
||||
"atk-sys",
|
||||
"bitflags",
|
||||
|
@ -58,7 +58,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "atk-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#2f86e52185021b540913ae8e87cf857a1dbd1ea6"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#dff1e67f2da991a27fb18654cb70b7f169262dc2"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
|
@ -104,7 +104,7 @@ checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
|
|||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-sys-rs",
|
||||
|
@ -116,7 +116,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cairo-sys-rs"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
|
@ -147,7 +147,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
[[package]]
|
||||
name = "command"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.asonix.dog/asonix/streamdeck-workspace?branch=main#e413cf6720fb0be076e534bf1da356e7781fcda4"
|
||||
source = "git+https://git.asonix.dog/asonix/streamdeck-workspace?branch=main#7d35810867c2669dce04acfb9fd36223e52109c8"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
@ -332,7 +332,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gdk"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#2f86e52185021b540913ae8e87cf857a1dbd1ea6"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#dff1e67f2da991a27fb18654cb70b7f169262dc2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cairo-rs",
|
||||
|
@ -347,7 +347,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gdk-pixbuf"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gio",
|
||||
|
@ -358,7 +358,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gdk-pixbuf-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
|
@ -370,7 +370,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gdk-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#2f86e52185021b540913ae8e87cf857a1dbd1ea6"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#dff1e67f2da991a27fb18654cb70b7f169262dc2"
|
||||
dependencies = [
|
||||
"cairo-sys-rs",
|
||||
"gdk-pixbuf-sys",
|
||||
|
@ -397,7 +397,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
|
@ -413,7 +413,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
|
@ -425,7 +425,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
|
@ -443,7 +443,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
|
@ -457,7 +457,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"system-deps",
|
||||
|
@ -466,7 +466,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"libc",
|
||||
|
@ -476,7 +476,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gtk"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#2f86e52185021b540913ae8e87cf857a1dbd1ea6"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#dff1e67f2da991a27fb18654cb70b7f169262dc2"
|
||||
dependencies = [
|
||||
"atk",
|
||||
"bitflags",
|
||||
|
@ -499,7 +499,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gtk-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#2f86e52185021b540913ae8e87cf857a1dbd1ea6"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#dff1e67f2da991a27fb18654cb70b7f169262dc2"
|
||||
dependencies = [
|
||||
"atk-sys",
|
||||
"cairo-sys-rs",
|
||||
|
@ -516,7 +516,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "gtk3-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#2f86e52185021b540913ae8e87cf857a1dbd1ea6"
|
||||
source = "git+https://github.com/gtk-rs/gtk3-rs#dff1e67f2da991a27fb18654cb70b7f169262dc2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
|
@ -596,7 +596,7 @@ checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
|||
[[package]]
|
||||
name = "libhandy"
|
||||
version = "0.8.0"
|
||||
source = "git+https://git.asonix.dog/asonix/libhandy-rs?branch=main#12924ef6d6287fedcc4ffb4fc5b6ab78448d2ff3"
|
||||
source = "git+https://gitlab.gnome.org/World/Rust/libhandy-rs#307a0e2fffa067724848dd7fc9a7eb7685102f94"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"gdk",
|
||||
|
@ -619,7 +619,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "libhandy-sys"
|
||||
version = "0.8.0"
|
||||
source = "git+https://git.asonix.dog/asonix/libhandy-rs?branch=main#12924ef6d6287fedcc4ffb4fc5b6ab78448d2ff3"
|
||||
source = "git+https://gitlab.gnome.org/World/Rust/libhandy-rs#307a0e2fffa067724848dd7fc9a7eb7685102f94"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gdk-sys",
|
||||
|
@ -645,7 +645,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "marble"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.asonix.dog/asonix/streamdeck-workspace?branch=main#e413cf6720fb0be076e534bf1da356e7781fcda4"
|
||||
source = "git+https://git.asonix.dog/asonix/streamdeck-workspace?branch=main#7d35810867c2669dce04acfb9fd36223e52109c8"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"futures-core",
|
||||
|
@ -701,7 +701,7 @@ checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
|||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"glib",
|
||||
|
@ -713,7 +713,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "pango-sys"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#ba69d8da4a4cfb37a1c250c0f3dd13d1ba9ddeb9"
|
||||
source = "git+https://github.com/gtk-rs/gtk-rs-core#9d6448fe4f1a24923835943335cde652315858c5"
|
||||
dependencies = [
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
|
@ -1035,7 +1035,9 @@ dependencies = [
|
|||
"async-io",
|
||||
"command",
|
||||
"env_logger",
|
||||
"event-listener",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-util",
|
||||
"gdk",
|
||||
|
|
|
@ -11,7 +11,9 @@ anyhow = "1"
|
|||
async-io = "1.4.1"
|
||||
command = { git = "https://git.asonix.dog/asonix/streamdeck-workspace", branch = "main" }
|
||||
env_logger = "0.8.3"
|
||||
event-listener = "2.5.1"
|
||||
futures-channel = { version = "0.3.14", features = ["sink"] }
|
||||
futures-core = "0.3.14"
|
||||
futures-executor = { version = "0.3.14", features = ["thread-pool"] }
|
||||
futures-util = { version = "0.3", features = ["sink"] }
|
||||
gdk = { git = "https://github.com/gtk-rs/gtk3-rs" }
|
||||
|
@ -20,7 +22,7 @@ gtk = { git = "https://github.com/gtk-rs/gtk3-rs" }
|
|||
gio = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
glib-sys = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
libhandy = { git = "https://git.asonix.dog/asonix/libhandy-rs", branch = "main" }
|
||||
libhandy = { git = "https://gitlab.gnome.org/World/Rust/libhandy-rs" }
|
||||
log = "0.4"
|
||||
marble = { git = "https://git.asonix.dog/asonix/streamdeck-workspace", branch = "main" }
|
||||
once_cell = "1.7.2"
|
||||
|
|
167
streamdeck/src/command.rs
Normal file
167
streamdeck/src/command.rs
Normal file
|
@ -0,0 +1,167 @@
|
|||
use command::Command;
|
||||
use event_listener::{Event, EventListener};
|
||||
use futures_core::stream::Stream;
|
||||
use gtk::prelude::*;
|
||||
use std::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
rc::Rc,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
pub(crate) fn render_text(command: &Command, grid: >k::Grid) {
|
||||
let row_command = gtk::Label::new(None);
|
||||
row_command.set_halign(gtk::Align::Start);
|
||||
row_command.set_valign(gtk::Align::Center);
|
||||
|
||||
grid.add(&row_command);
|
||||
|
||||
let cmd_type = CommandType::from_command(command);
|
||||
match command {
|
||||
Command::SwitchScene { name } => {
|
||||
row_command.set_label(cmd_type.as_name());
|
||||
render_switch_scene(&name, grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_switch_scene(name: &str, grid: >k::Grid) {
|
||||
let to = gtk::Label::new(Some("to"));
|
||||
to.set_halign(gtk::Align::Start);
|
||||
to.set_valign(gtk::Align::Center);
|
||||
|
||||
let scene_name = gtk::Label::new(Some(name));
|
||||
scene_name.set_halign(gtk::Align::Start);
|
||||
scene_name.set_valign(gtk::Align::Center);
|
||||
|
||||
grid.add(&to);
|
||||
grid.add(&scene_name);
|
||||
grid.show_all();
|
||||
}
|
||||
|
||||
pub(crate) fn render_config(command: Option<&Command>, grid: >k::Grid) -> ComboBoxHandle {
|
||||
let combobox = gtk::ComboBoxText::new();
|
||||
combobox.set_id_column(1);
|
||||
|
||||
for typ in CommandType::available() {
|
||||
combobox.append(Some(typ.as_id()), typ.as_name());
|
||||
}
|
||||
|
||||
let event = Rc::new(Event::default());
|
||||
|
||||
let handle = ComboBoxHandle {
|
||||
obj: combobox.clone(),
|
||||
event: event.clone(),
|
||||
};
|
||||
|
||||
let command_type = command
|
||||
.as_ref()
|
||||
.map(|c| CommandType::from_command(c))
|
||||
.unwrap_or(CommandType::SwitchScene);
|
||||
|
||||
combobox.connect_changed(move |_combobox| {
|
||||
event.notify(usize::MAX);
|
||||
});
|
||||
|
||||
handle
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub(crate) enum CommandType {
|
||||
SwitchScene,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ComboBoxHandle {
|
||||
obj: gtk::ComboBoxText,
|
||||
event: Rc<Event>,
|
||||
}
|
||||
|
||||
pub(crate) struct SelectedStream {
|
||||
listener: Option<EventListener>,
|
||||
event: Rc<Event>,
|
||||
obj: gtk::ComboBoxText,
|
||||
}
|
||||
|
||||
impl CommandType {
|
||||
fn as_id(&self) -> &'static str {
|
||||
match self {
|
||||
CommandType::SwitchScene => "SwitchScene",
|
||||
}
|
||||
}
|
||||
|
||||
fn as_name(&self) -> &'static str {
|
||||
match self {
|
||||
CommandType::SwitchScene => "Switch Scene",
|
||||
}
|
||||
}
|
||||
|
||||
fn available() -> &'static [Self] {
|
||||
&[CommandType::SwitchScene]
|
||||
}
|
||||
|
||||
fn from_command(command: &Command) -> Self {
|
||||
match command {
|
||||
Command::SwitchScene { .. } => Self::SwitchScene,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComboBoxHandle {
|
||||
pub(crate) fn select_first(&self) {
|
||||
if self.obj.active_id().is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let cmds = CommandType::available();
|
||||
if cmds.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.obj.set_active_id(Some(cmds[0].as_id()));
|
||||
}
|
||||
|
||||
pub(crate) fn selected(&self) -> SelectedStream {
|
||||
SelectedStream {
|
||||
listener: Some(self.event.listen()),
|
||||
event: self.event.clone(),
|
||||
obj: self.obj.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for SelectedStream {
|
||||
type Item = String;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
let mut listener = if let Some(listener) = self.listener.take() {
|
||||
listener
|
||||
} else {
|
||||
self.event.listen()
|
||||
};
|
||||
|
||||
match Pin::new(&mut listener).poll(cx) {
|
||||
Poll::Ready(()) => {
|
||||
let mut listener;
|
||||
while {
|
||||
listener = self.event.listen();
|
||||
|
||||
Pin::new(&mut listener).poll(cx).is_ready()
|
||||
} {}
|
||||
|
||||
self.listener = Some(listener);
|
||||
|
||||
if let Some(selected) = self.obj.active_id() {
|
||||
Poll::Ready(Some(selected.into()))
|
||||
} else {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
Poll::Pending => {
|
||||
self.listener = Some(listener);
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -372,7 +372,7 @@ struct Daemon {
|
|||
fn connect() -> futures_channel::mpsc::Sender<DBusMessage> {
|
||||
let (tx, mut rx) = futures_channel::mpsc::channel(16);
|
||||
|
||||
log::info!("Spawning connection pool");
|
||||
log::debug!("Spawning connection pool");
|
||||
|
||||
let mut senders = (0..16).map(|_| spawn_connection()).collect::<Vec<_>>();
|
||||
|
||||
|
@ -397,7 +397,7 @@ fn connect() -> futures_channel::mpsc::Sender<DBusMessage> {
|
|||
count = (count + 1) % len;
|
||||
}
|
||||
|
||||
log::info!("Shutting down dbus connection pool");
|
||||
log::debug!("Shutting down dbus connection pool");
|
||||
});
|
||||
|
||||
tx
|
||||
|
|
52
streamdeck/src/dialogs/edit_deck_dialog.rs
Normal file
52
streamdeck/src/dialogs/edit_deck_dialog.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use crate::daemon::Handle;
|
||||
use gtk::prelude::*;
|
||||
use marble::widgets::Dialog;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub(crate) fn build(serial_number: String, deck_name: String) -> Dialog {
|
||||
let dialog = Dialog::new();
|
||||
|
||||
let label = gtk::Label::new(Some("Edit deck name"));
|
||||
let entry = gtk::Entry::new();
|
||||
entry.set_valign(gtk::Align::Center);
|
||||
entry
|
||||
.style_context()
|
||||
.add_class(marble::STYLE_CLASS_H3_LABEL);
|
||||
entry.set_text(&deck_name);
|
||||
|
||||
let grid = gtk::Grid::new();
|
||||
grid.set_column_spacing(12);
|
||||
grid.set_row_spacing(12);
|
||||
grid.set_halign(gtk::Align::Center);
|
||||
grid.set_margin(24);
|
||||
|
||||
grid.attach(&label, 0, 0, 1, 1);
|
||||
grid.attach(&entry, 1, 0, 3, 1);
|
||||
|
||||
dialog.content_area().add(&grid);
|
||||
|
||||
let serial_number = Rc::new(serial_number);
|
||||
let previous_name = Rc::new(RefCell::new(deck_name));
|
||||
entry.connect_changed(move |entry| {
|
||||
let serial_number = Rc::clone(&serial_number);
|
||||
let previous_name = Rc::clone(&previous_name);
|
||||
|
||||
if previous_name.borrow().as_str() == entry.text() {
|
||||
return;
|
||||
}
|
||||
|
||||
*previous_name.borrow_mut() = entry.text().into();
|
||||
|
||||
glib::MainContext::default().spawn_local(async move {
|
||||
let _ = Handle::current()
|
||||
.set_deck_name(
|
||||
String::clone(&serial_number),
|
||||
String::clone(&previous_name.borrow()),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
});
|
||||
|
||||
dialog.show_all();
|
||||
dialog
|
||||
}
|
1
streamdeck/src/dialogs/mod.rs
Normal file
1
streamdeck/src/dialogs/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod edit_deck_dialog;
|
|
@ -2,8 +2,10 @@ use gio::{prelude::*, Settings};
|
|||
use once_cell::unsync::Lazy;
|
||||
|
||||
mod application;
|
||||
mod command;
|
||||
mod config;
|
||||
mod daemon;
|
||||
mod dialogs;
|
||||
mod main_window;
|
||||
mod views;
|
||||
mod widgets;
|
||||
|
|
|
@ -22,6 +22,8 @@ run_command(
|
|||
)
|
||||
|
||||
rust_sources = files(
|
||||
'dialogs/edit_deck_dialog.rs',
|
||||
'dialogs/mod.rs',
|
||||
'views/deck_stack.rs',
|
||||
'views/deck_view.rs',
|
||||
'views/mod.rs',
|
||||
|
@ -32,6 +34,7 @@ rust_sources = files(
|
|||
'widgets/deck_list.rs',
|
||||
'widgets/mod.rs',
|
||||
'application.rs',
|
||||
'command.rs',
|
||||
'config.rs',
|
||||
'daemon.rs',
|
||||
'main.rs',
|
||||
|
|
|
@ -12,9 +12,7 @@ impl DeckStack {
|
|||
}
|
||||
|
||||
pub(crate) fn select_deck(&self, serial_number: &str) {
|
||||
log::info!("Selecting");
|
||||
if self.child_by_name(serial_number).is_some() {
|
||||
log::info!("has child");
|
||||
self.set_visible_child_name(serial_number);
|
||||
}
|
||||
self.show_all();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
daemon::{CommandInfo, Handle},
|
||||
daemon::{CommandInfo, Handle, InputName},
|
||||
widgets::CommandRow,
|
||||
};
|
||||
use gtk::{prelude::*, subclass::prelude::*};
|
||||
|
@ -21,31 +21,50 @@ impl CommandList {
|
|||
let inner = imp::CommandList::from_instance(self);
|
||||
inner.serial_number.set(serial_number.clone()).unwrap();
|
||||
|
||||
let serial_number2 = serial_number.clone();
|
||||
glib::MainContext::default().spawn_local(glib::clone!(@weak self as obj => async move {
|
||||
// we have access to obj
|
||||
if let Ok(commands) = Handle::current().get_commands(serial_number).await {
|
||||
for info in commands {
|
||||
obj.add_command(info);
|
||||
}
|
||||
let mut handle = Handle::current();
|
||||
|
||||
if let Ok(commands) = handle.get_commands(serial_number).await {
|
||||
obj.add_commands(commands);
|
||||
}
|
||||
|
||||
if let Ok(names) = Handle::current().get_input_names(serial_number2).await {
|
||||
obj.set_names(names);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
fn add_command(&self, command_info: CommandInfo) {
|
||||
fn add_commands(&self, commands: Vec<CommandInfo>) {
|
||||
let inner = imp::CommandList::from_instance(self);
|
||||
let list_box = inner.list_box.get().unwrap();
|
||||
let serial_number = inner.serial_number.get().unwrap();
|
||||
let mut rows = inner.rows.borrow_mut();
|
||||
|
||||
if rows.contains_key(&command_info.key) {
|
||||
return;
|
||||
for command_info in commands {
|
||||
if rows.contains_key(&command_info.key) {
|
||||
return;
|
||||
}
|
||||
|
||||
let key = command_info.key;
|
||||
let row = CommandRow::new(serial_number, command_info);
|
||||
|
||||
list_box.add(&row);
|
||||
rows.insert(key, row);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_names(&self, names: Vec<InputName>) {
|
||||
let inner = imp::CommandList::from_instance(self);
|
||||
let rows = inner.rows.borrow();
|
||||
|
||||
for name in names {
|
||||
if let Some(row) = rows.get(&name.key) {
|
||||
row.set_name(&name.name);
|
||||
}
|
||||
}
|
||||
|
||||
let serial_number = inner.serial_number.get().unwrap();
|
||||
let list_box = inner.list_box.get().unwrap();
|
||||
let key = command_info.key;
|
||||
let row = CommandRow::new(serial_number, command_info);
|
||||
|
||||
list_box.add(&row);
|
||||
rows.insert(key, row);
|
||||
self.show_all();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ impl CommandRow {
|
|||
row_title.set_label(&format!("{}", command_info.key));
|
||||
}
|
||||
|
||||
// TODO: Render based on command
|
||||
let command_grid = inner.command_grid.get().unwrap();
|
||||
|
||||
crate::command::render_text(&command_info.command, command_grid);
|
||||
|
||||
inner.input_key.set(command_info.key).unwrap();
|
||||
inner
|
||||
|
@ -30,6 +32,12 @@ impl CommandRow {
|
|||
this.show_all();
|
||||
this
|
||||
}
|
||||
|
||||
pub(crate) fn set_name(&self, name: &str) {
|
||||
let this = imp::CommandRow::from_instance(self);
|
||||
let row_title = this.row_title.get().unwrap();
|
||||
row_title.set_label(name);
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
|
@ -41,7 +49,6 @@ mod imp {
|
|||
#[derive(Debug, Default)]
|
||||
pub struct CommandRow {
|
||||
pub(super) row_title: OnceCell<gtk::Label>,
|
||||
pub(super) row_command: OnceCell<gtk::Label>,
|
||||
pub(super) command_grid: OnceCell<gtk::Grid>,
|
||||
pub(super) serial_number: OnceCell<String>,
|
||||
pub(super) input_key: OnceCell<u8>,
|
||||
|
@ -61,10 +68,6 @@ mod imp {
|
|||
row_title.set_halign(gtk::Align::Start);
|
||||
row_title.set_valign(gtk::Align::Center);
|
||||
|
||||
let row_command = gtk::Label::new(None);
|
||||
row_command.set_halign(gtk::Align::Start);
|
||||
row_command.set_valign(gtk::Align::Center);
|
||||
|
||||
let command_grid = gtk::Grid::new();
|
||||
command_grid.set_halign(gtk::Align::Start);
|
||||
command_grid.set_valign(gtk::Align::Center);
|
||||
|
@ -73,8 +76,6 @@ mod imp {
|
|||
command_grid.set_margin_start(3);
|
||||
command_grid.set_column_spacing(3);
|
||||
|
||||
command_grid.add(&row_command);
|
||||
|
||||
let row_edit =
|
||||
gtk::Button::from_icon_name(Some("document-edit"), gtk::IconSize::Button);
|
||||
row_edit.set_tooltip_text(Some("Edit"));
|
||||
|
@ -96,7 +97,6 @@ mod imp {
|
|||
obj.show_all();
|
||||
|
||||
self.row_title.set(row_title).unwrap();
|
||||
self.row_command.set(row_command).unwrap();
|
||||
self.command_grid.set(command_grid).unwrap();
|
||||
|
||||
// TODO: Click connect
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::daemon::DeckInfo;
|
||||
use glib::object::ObjectExt;
|
||||
use gtk::{prelude::*, subclass::prelude::*};
|
||||
use marble::widgets::Dialog;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct DeckItem(ObjectSubclass<imp::DeckItem>)
|
||||
|
@ -17,14 +19,58 @@ impl DeckItem {
|
|||
}
|
||||
|
||||
pub(crate) fn serial_number(&self) -> Option<String> {
|
||||
let value = self.property("serial_number").ok()?;
|
||||
let value = self.property("serial-number").ok()?;
|
||||
|
||||
value.get().ok()
|
||||
}
|
||||
|
||||
pub(crate) fn device_name(&self) -> Option<String> {
|
||||
let value = self.property("device-name").ok()?;
|
||||
|
||||
value.get().ok()
|
||||
}
|
||||
|
||||
fn handle_clicked(&self) -> Option<()> {
|
||||
let this = imp::DeckItem::from_instance(self);
|
||||
|
||||
let serial_number = self.serial_number()?;
|
||||
let device_name = self.device_name()?;
|
||||
let mut dialog_opt = this.dialog.borrow_mut();
|
||||
|
||||
let dialog: Dialog = if let Some(dialog) = &*dialog_opt {
|
||||
dialog.clone()
|
||||
} else {
|
||||
let dialog =
|
||||
crate::dialogs::edit_deck_dialog::build(serial_number.clone(), device_name.clone());
|
||||
|
||||
dialog.set_transient_for(
|
||||
self.toplevel()
|
||||
.and_then(|widget| widget.downcast::<crate::main_window::MainWindow>().ok())
|
||||
.as_ref(),
|
||||
);
|
||||
|
||||
*dialog_opt = Some(dialog.clone());
|
||||
|
||||
dialog.connect_response(glib::clone!(@weak self as obj => move |_, _| {
|
||||
let this = imp::DeckItem::from_instance(&obj);
|
||||
let mut dialog_opt = this.dialog.borrow_mut();
|
||||
if let Some(dialog) = dialog_opt.take() {
|
||||
dialog.close();
|
||||
}
|
||||
}));
|
||||
|
||||
dialog
|
||||
};
|
||||
|
||||
dialog.present();
|
||||
|
||||
Some(())
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use gtk::{prelude::*, subclass::prelude::*};
|
||||
use marble::widgets::Dialog;
|
||||
use once_cell::{sync::Lazy, unsync::OnceCell};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
|
@ -33,6 +79,7 @@ mod imp {
|
|||
serial_number: OnceCell<String>,
|
||||
device_name: OnceCell<Rc<RefCell<String>>>,
|
||||
port_name: OnceCell<String>,
|
||||
pub(super) dialog: RefCell<Option<Dialog>>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -80,6 +127,20 @@ mod imp {
|
|||
obj.add(&grid);
|
||||
obj.show_all();
|
||||
|
||||
edit_button.connect_clicked(glib::clone!(@weak obj => move |_| {
|
||||
obj.handle_clicked();
|
||||
}));
|
||||
|
||||
glib::MainContext::default().spawn_local(glib::clone!(@weak obj => async move {
|
||||
let mut handle = crate::daemon::Handle::current();
|
||||
let this = DeckItem::from_instance(&obj);
|
||||
let serial_number = this.serial_number.get().unwrap();
|
||||
|
||||
if let Ok(name) = handle.get_deck_name(serial_number.to_owned()).await {
|
||||
let _ = obj.set_property("device-name", &name);
|
||||
}
|
||||
}));
|
||||
|
||||
obj.bind_property("device-name", &row_title, "label")
|
||||
.build();
|
||||
obj.bind_property("port-name", &row_desc, "label").build();
|
||||
|
|
|
@ -71,6 +71,7 @@ mod imp {
|
|||
pub struct DeckList {
|
||||
pub(super) stack: OnceCell<DeckStack>,
|
||||
pub(super) list_box: OnceCell<gtk::ListBox>,
|
||||
pub(super) usb_label: OnceCell<gtk::Label>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
|
@ -138,6 +139,7 @@ mod imp {
|
|||
// TODO: daemon decks added callback
|
||||
// TODO: daemon decks removed callback
|
||||
|
||||
self.usb_label.set(usb_label).unwrap();
|
||||
self.list_box.set(list_box).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue