diff --git a/src-tauri/src/events/frontend.rs b/src-tauri/src/events/frontend.rs index 4c33c7b..9ce30d1 100644 --- a/src-tauri/src/events/frontend.rs +++ b/src-tauri/src/events/frontend.rs @@ -91,7 +91,7 @@ pub async fn set_selected_profile(app: AppHandle, device: String, id: String, pr if selected_profile != id { let old_profile = &profile_stores.get_profile_store(devices.get(&device).unwrap(), selected_profile)?.value; for instance in old_profile.keys.iter().flatten().chain(&mut old_profile.sliders.iter().flatten()) { - if instance.action.uuid != "com.amansprojects.opendeck.multiaction" { + if !matches!(instance.action.uuid.as_str(), "com.amansprojects.opendeck.multiaction" | "com.amansprojects.opendeck.toggleaction") { let _ = crate::events::outbound::will_appear::will_disappear(instance, false).await; } else { for child in instance.children.as_ref().unwrap() { @@ -108,7 +108,7 @@ pub async fn set_selected_profile(app: AppHandle, device: String, id: String, pr *new_profile = profile; } for instance in new_profile.keys.iter().flatten().chain(&mut new_profile.sliders.iter().flatten()) { - if instance.action.uuid != "com.amansprojects.opendeck.multiaction" { + if !matches!(instance.action.uuid.as_str(), "com.amansprojects.opendeck.multiaction" | "com.amansprojects.opendeck.toggleaction") { let _ = crate::events::outbound::will_appear::will_appear(instance, false).await; } else { for child in instance.children.as_ref().unwrap() { @@ -165,8 +165,16 @@ pub async fn create_instance(action: Action, context: Context) -> Result Result<(), Error> { let slot = get_slot_mut(&context, &mut locks).await?; if let Some(instance) = slot { - if instance.action.uuid != "com.amansprojects.opendeck.multiaction" { + if !matches!(instance.action.uuid.as_str(), "com.amansprojects.opendeck.multiaction" | "com.amansprojects.opendeck.toggleaction") { let _ = crate::events::outbound::will_appear::will_disappear(instance, false).await; } else { for child in instance.children.as_ref().unwrap() { @@ -248,7 +256,7 @@ pub async fn remove_instance(context: ActionContext) -> Result<(), Error> { return Ok(()); }; - if instance.action.uuid != "com.amansprojects.opendeck.multiaction" { + if !matches!(instance.action.uuid.as_str(), "com.amansprojects.opendeck.multiaction" | "com.amansprojects.opendeck.toggleaction") { let _ = crate::events::outbound::will_appear::will_disappear(instance, false).await; *slot = None; } else { @@ -260,6 +268,9 @@ pub async fn remove_instance(context: ActionContext) -> Result<(), Error> { break; } } + if instance.action.uuid == "com.amansprojects.opendeck.toggleaction" && instance.settings.as_u64().unwrap() as usize >= children.len() { + instance.settings = serde_json::Value::from(if children.is_empty() { 0 } else { children.len() - 1 }); + } } save_profile(&context.device, &mut locks).await?; diff --git a/src-tauri/src/events/outbound/keypad.rs b/src-tauri/src/events/outbound/keypad.rs index 8b3a8c0..525034c 100644 --- a/src-tauri/src/events/outbound/keypad.rs +++ b/src-tauri/src/events/outbound/keypad.rs @@ -29,19 +29,7 @@ pub async fn key_down(device: &str, key: u8) -> Result<(), anyhow::Error> { let _ = crate::events::frontend::key_moved(crate::APP_HANDLE.get().unwrap(), context.clone(), true).await; let Some(instance) = get_slot_mut(&context, &mut locks).await? else { return Ok(()) }; - if instance.action.uuid != "com.amansprojects.opendeck.multiaction" { - send_to_plugin( - &instance.action.plugin, - &KeyEvent { - event: "keyDown", - action: instance.action.uuid.clone(), - context: instance.context.clone(), - device: instance.context.device.clone(), - payload: GenericInstancePayload::new(instance, false), - }, - ) - .await?; - } else { + if instance.action.uuid == "com.amansprojects.opendeck.multiaction" { for child in instance.children.as_mut().unwrap() { send_to_plugin( &child.action.plugin, @@ -78,6 +66,31 @@ pub async fn key_down(device: &str, key: u8) -> Result<(), anyhow::Error> { save_profile(device, &mut locks).await?; let _ = crate::events::frontend::update_state(crate::APP_HANDLE.get().unwrap(), context, &mut locks).await; + } else if instance.action.uuid == "com.amansprojects.opendeck.toggleaction" { + let child = &instance.children.as_ref().unwrap()[instance.settings.as_u64().unwrap() as usize]; + send_to_plugin( + &child.action.plugin, + &KeyEvent { + event: "keyDown", + action: child.action.uuid.clone(), + context: child.context.clone(), + device: child.context.device.clone(), + payload: GenericInstancePayload::new(child, false), + }, + ) + .await?; + } else { + send_to_plugin( + &instance.action.plugin, + &KeyEvent { + event: "keyDown", + action: instance.action.uuid.clone(), + context: instance.context.clone(), + device: instance.context.device.clone(), + payload: GenericInstancePayload::new(instance, false), + }, + ) + .await?; } Ok(()) @@ -98,21 +111,41 @@ pub async fn key_up(device: &str, key: u8) -> Result<(), anyhow::Error> { let slot = get_slot_mut(&context, &mut locks).await?; let Some(instance) = slot else { return Ok(()) }; - if instance.states.len() == 2 && !instance.action.disable_automatic_states { - instance.current_state = (instance.current_state + 1) % (instance.states.len() as u16); - } - - send_to_plugin( - &instance.action.plugin, - &KeyEvent { - event: "keyUp", - action: instance.action.uuid.clone(), - context: instance.context.clone(), - device: instance.context.device.clone(), - payload: GenericInstancePayload::new(instance, false), - }, - ) - .await?; + if instance.action.uuid == "com.amansprojects.opendeck.toggleaction" { + let index = instance.settings.as_u64().unwrap() as usize; + let children = instance.children.as_ref().unwrap(); + if children.is_empty() { + return Ok(()); + }; + let child = &children[index]; + send_to_plugin( + &child.action.plugin, + &KeyEvent { + event: "keyUp", + action: child.action.uuid.clone(), + context: child.context.clone(), + device: child.context.device.clone(), + payload: GenericInstancePayload::new(child, false), + }, + ) + .await?; + instance.settings = serde_json::Value::from((index + 1) % instance.children.as_ref().unwrap().len()); + } else if instance.action.uuid != "com.amansprojects.opendeck.multiaction" { + if instance.states.len() == 2 && !instance.action.disable_automatic_states { + instance.current_state = (instance.current_state + 1) % (instance.states.len() as u16); + } + send_to_plugin( + &instance.action.plugin, + &KeyEvent { + event: "keyUp", + action: instance.action.uuid.clone(), + context: instance.context.clone(), + device: instance.context.device.clone(), + payload: GenericInstancePayload::new(instance, false), + }, + ) + .await? + }; save_profile(device, &mut locks).await?; let _ = crate::events::frontend::update_state(crate::APP_HANDLE.get().unwrap(), context, &mut locks).await; diff --git a/src-tauri/src/shared.rs b/src-tauri/src/shared.rs index def4b08..cf53750 100644 --- a/src-tauri/src/shared.rs +++ b/src-tauri/src/shared.rs @@ -206,19 +206,34 @@ pub static CATEGORIES: Lazy>>> = Lazy::new(|| let mut hashmap = HashMap::new(); hashmap.insert( "OpenDeck".to_owned(), - vec![serde_json::from_str( - r#"{ - "name": "Multi Action", - "icon": "opendeck/multi-action.png", - "plugin": "com.amansprojects.opendeck", - "uuid": "com.amansprojects.opendeck.multiaction", - "tooltip": "Execute multiple actions", - "controllers": [ "Keypad" ], - "states": [ { "image": "opendeck/multi-action.png" } ], - "supported_in_multi_actions": false - }"#, - ) - .unwrap()], + vec![ + serde_json::from_str( + r#"{ + "name": "Multi Action", + "icon": "opendeck/multi-action.png", + "plugin": "com.amansprojects.opendeck", + "uuid": "com.amansprojects.opendeck.multiaction", + "tooltip": "Execute multiple actions", + "controllers": [ "Keypad" ], + "states": [ { "image": "opendeck/multi-action.png" } ], + "supported_in_multi_actions": false + }"#, + ) + .unwrap(), + serde_json::from_str( + r#"{ + "name": "Toggle Action", + "icon": "opendeck/toggle-action.png", + "plugin": "com.amansprojects.opendeck", + "uuid": "com.amansprojects.opendeck.toggleaction", + "tooltip": "Cycle through multiple actions", + "controllers": [ "Keypad" ], + "states": [ { "image": "opendeck/toggle-action.png" } ], + "supported_in_multi_actions": false + }"#, + ) + .unwrap(), + ], ); RwLock::new(hashmap) }); diff --git a/src/components/DeviceView.svelte b/src/components/DeviceView.svelte index 90871f2..298e5f8 100644 --- a/src/components/DeviceView.svelte +++ b/src/components/DeviceView.svelte @@ -7,7 +7,7 @@ import Key from "./Key.svelte"; import Slider from "./Slider.svelte"; - import { inspectedMultiAction } from "$lib/propertyInspector"; + import { inspectedParentAction } from "$lib/propertyInspector"; import { invoke } from "@tauri-apps/api"; export let device: DeviceInfo; @@ -61,7 +61,7 @@ {#key device} -
+
{#each { length: device.sliders } as _, i}
- -

Multi Action

+ +

{parentUuid == "com.amansprojects.opendeck.toggleaction" ? "Toggle Action" : "Multi Action"}

diff --git a/src/lib/propertyInspector.ts b/src/lib/propertyInspector.ts index 46a16de..d0a2c13 100644 --- a/src/lib/propertyInspector.ts +++ b/src/lib/propertyInspector.ts @@ -11,7 +11,7 @@ inspectedInstance.subscribe(async (value) => { old = value; }); -export const inspectedMultiAction: Writable = writable(null); +export const inspectedParentAction: Writable = writable(null); export const openContextMenu: Writable<{ context: Context, x: number, y: number } | null> = writable(null); document.addEventListener("click", () => openContextMenu.set(null)); diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 4be4900..927fe8f 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -2,13 +2,13 @@ import type { DeviceInfo } from "$lib/DeviceInfo"; import type { Profile } from "$lib/Profile"; - import { inspectedMultiAction } from "$lib/propertyInspector"; + import { inspectedParentAction } from "$lib/propertyInspector"; import ActionList from "../components/ActionList.svelte"; import DeviceSelector from "../components/DeviceSelector.svelte"; import DeviceView from "../components/DeviceView.svelte"; - import MultiActionView from "../components/MultiActionView.svelte"; import NoDevicesDetected from "../components/NoDevicesDetected.svelte"; + import ParentActionView from "../components/ParentActionView.svelte"; import PluginManager from "../components/PluginManager.svelte"; import ProfileSelector from "../components/ProfileSelector.svelte"; import PropertyInspectorView from "../components/PropertyInspectorView.svelte"; @@ -24,8 +24,8 @@
- {#if $inspectedMultiAction} - + {#if $inspectedParentAction} + {/if} {#if Object.keys(devices).length > 0 && selectedProfiles} {#each Object.entries(devices) as [ id, device ]} @@ -43,7 +43,7 @@
- {#if !$inspectedMultiAction} + {#if !$inspectedParentAction}