Show command row text, deck item text, add edit deck dialog

This commit is contained in:
Aode 2021-05-15 16:35:59 -05:00
parent 7d35810867
commit c3ff8eca36
15 changed files with 363 additions and 58 deletions

3
.gitmodules vendored
View file

@ -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
View file

@ -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",

View file

@ -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
View 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: &gtk::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: &gtk::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: &gtk::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
}
}
}
}

View file

@ -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

View 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
}

View file

@ -0,0 +1 @@
pub mod edit_deck_dialog;

View file

@ -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;

View file

@ -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',

View file

@ -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();

View file

@ -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();
}
}

View file

@ -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

View file

@ -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();

View file

@ -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();
}
}