summaryrefslogtreecommitdiff
path: root/src/gui.rs
diff options
context:
space:
mode:
authorozpv <39195175+ozpv@users.noreply.github.com>2026-06-20 03:11:03 -0500
committerozpv <39195175+ozpv@users.noreply.github.com>2026-06-20 03:11:03 -0500
commit029fc9d3cf4768d94a6e37380e1dcc1e758ae876 (patch)
treee38d6533ac8a08fca1109e6e4ee92fe2e227e274 /src/gui.rs
parent15452d1352dc01e4618a54c8159d8f049225d4fd (diff)
add vst3 support
Diffstat (limited to 'src/gui.rs')
-rw-r--r--src/gui.rs295
1 files changed, 0 insertions, 295 deletions
diff --git a/src/gui.rs b/src/gui.rs
deleted file mode 100644
index 7032a79..0000000
--- a/src/gui.rs
+++ /dev/null
@@ -1,295 +0,0 @@
-//! Contains all types and implementations related to the plugin's GUI
-
-use crate::{
- RetainPluginMainThread, RetainPluginShared, params::RetainParams, window_size::WindowSize,
- window_type::WindowType,
-};
-use atomic_float::AtomicF32;
-use clack_extensions::gui::{GuiApiType, GuiConfiguration, GuiSize, PluginGuiImpl, Window};
-use clack_plugin::prelude::*;
-use egui::{Align, CentralPanel, ComboBox, Context, Layout, Slider, Ui, Vec2, ViewportCommand};
-use egui_baseview::{
- EguiWindow, GraphicsConfig, Queue,
- baseview::{Size, WindowHandle, WindowOpenOptions, WindowScalePolicy, gl::GlConfig},
-};
-use std::sync::{Arc, atomic::Ordering};
-
-const DEFAULT_SIZE_X: f32 = 600.0;
-const DEFAULT_SIZE_Y: f32 = 350.0;
-
-pub struct AtomicVec2 {
- x: AtomicF32,
- y: AtomicF32,
-}
-
-impl Default for AtomicVec2 {
- fn default() -> Self {
- Self {
- x: AtomicF32::new(DEFAULT_SIZE_X),
- y: AtomicF32::new(DEFAULT_SIZE_Y),
- }
- }
-}
-
-impl AtomicVec2 {
- pub fn new() -> Self {
- Self::default()
- }
-
- pub fn get_x(&self) -> f32 {
- self.x.load(Ordering::SeqCst)
- }
-
- pub fn set_x(&self, x: f32) {
- self.x.store(x, Ordering::SeqCst);
- }
-
- pub fn get_y(&self) -> f32 {
- self.y.load(Ordering::SeqCst)
- }
-
- pub fn set_y(&self, x: f32) {
- self.y.store(x, Ordering::SeqCst);
- }
-
- pub fn as_vec2(&self) -> Vec2 {
- Vec2 {
- x: self.get_x(),
- y: self.get_y(),
- }
- }
-}
-
-/// The EGUI application state
-struct AppState {
- /// A handle to the shared params state
- params: Arc<RetainParams>,
- gui_size: Arc<AtomicVec2>,
-}
-
-impl AppState {
- /// Initializes a new [`AppState`] from the given shared params state handle
- pub fn new(params: &Arc<RetainParams>, gui_size: &Arc<AtomicVec2>) -> Self {
- Self {
- params: Arc::clone(params),
- gui_size: Arc::clone(gui_size),
- }
- }
-}
-
-/// GUI state that can be accessed directly by the main thread
-pub struct RetainPluginGui {
- /// The handle to the baseview plugin window.
- handle: WindowHandle,
- /// The handle to the EGUI context
- egui_context: Context,
-}
-
-impl RetainPluginGui {
- /// Creates a new GUI window, and embeds it into the given `parent`.
- pub fn new(parent: Window<'_>, plugin_state: &RetainPluginShared) -> Self {
- let settings = WindowOpenOptions {
- title: "Retain".to_string(),
- size: Size::new(
- plugin_state.gui_size.get_x().into(),
- plugin_state.gui_size.get_y().into(),
- ),
- scale: WindowScalePolicy::SystemScaleFactor,
- gl_config: Some(GlConfig::default()),
- };
-
- let (tx, rx) = std::sync::mpsc::channel();
-
- let handle = EguiWindow::open_parented(
- &parent,
- settings,
- GraphicsConfig::default(),
- AppState::new(&plugin_state.params, &plugin_state.gui_size),
- move |ctx: &Context, _queue: &mut Queue, _state: &mut AppState| {
- tx.send(ctx.clone()).unwrap();
- },
- |ui: &mut Ui, _queue: &mut Queue, state: &mut AppState| {
- ui.send_viewport_cmd(ViewportCommand::InnerSize(state.gui_size.as_vec2()));
-
- CentralPanel::default().show_inside(ui, |ui| {
- ui.heading("Retain");
-
- ui.horizontal(|ui| {
- ui.with_layout(Layout::top_down(Align::LEFT), |ui| {
- let mut order = state.params.get_order();
- let window_size = state.params.get_window_size().inner();
-
- let slider = ui.add(
- Slider::new(&mut order, 0..=window_size)
- .text("Order")
- .logarithmic(true),
- );
-
- if slider.changed() {
- state.params.set_order(order);
- }
-
- let mut window_size = state.params.get_window_size();
-
- ComboBox::from_label("Window Size")
- .selected_text(window_size.as_str())
- .show_ui(ui, |ui| {
- for size in WindowSize::iter() {
- let display = size.as_str();
- let inner = size.inner();
-
- if ui
- .selectable_value(&mut window_size, size, display)
- .changed()
- {
- state.params.set_window_size(inner.into());
- }
- }
- });
- });
-
- ui.with_layout(Layout::top_down(Align::RIGHT), |ui| {
- let mut complement = state.params.get_complement();
-
- if ui.checkbox(&mut complement, "Complement").changed() {
- state.params.set_complement(complement);
- }
-
- let window_type = state.params.get_window_type();
- let selected = window_type.as_str();
- let mut window_type = window_type.as_byte();
-
- ComboBox::from_label("Window Function")
- .selected_text(selected)
- .show_ui(ui, |ui| {
- for function in WindowType::iter() {
- let display = function.as_str();
- let byte = function.as_byte();
-
- if ui
- .selectable_value(
- &mut window_type,
- function.as_byte(),
- display,
- )
- .changed()
- {
- state.params.set_window_type(byte.into());
- }
- }
- });
- });
- });
- });
- },
- );
-
- let egui_context = rx.recv().unwrap();
-
- Self {
- handle,
- egui_context,
- }
- }
-
- /// Requests the UI to repaint itself, e.g. in response to events or parameter changes
- pub fn request_repaint(&self) {
- self.egui_context.request_repaint();
- }
-}
-
-impl Drop for RetainPluginGui {
- fn drop(&mut self) {
- self.handle.close();
- }
-}
-
-impl PluginGuiImpl for RetainPluginMainThread<'_> {
- fn is_api_supported(&mut self, configuration: GuiConfiguration) -> bool {
- configuration.api_type
- == GuiApiType::default_for_current_platform().expect("Unsupported platform")
- && !configuration.is_floating
- }
-
- fn get_preferred_api(&mut self) -> Option<GuiConfiguration<'_>> {
- Some(GuiConfiguration {
- api_type: GuiApiType::default_for_current_platform().expect("Unsupported platform"),
- is_floating: false,
- })
- }
-
- fn create(&mut self, configuration: GuiConfiguration) -> Result<(), PluginError> {
- if configuration.is_floating {
- return Err(PluginError::Message(
- "Invalid GUI configuration: this plugin does not support floating mode",
- ));
- }
-
- let supported_type =
- GuiApiType::default_for_current_platform().expect("Unsupported platform");
-
- if configuration.api_type != supported_type {
- return Err(PluginError::Message(
- "Invalid GUI configuration: unsupported API type",
- ));
- }
-
- Ok(())
- }
-
- fn destroy(&mut self) {
- let _ = self.gui.take();
- }
-
- fn set_scale(&mut self, _scale: f64) -> Result<(), PluginError> {
- Ok(())
- }
-
- fn get_size(&mut self) -> Option<GuiSize> {
- Some(GuiSize {
- width: self.shared.gui_size.get_x() as u32,
- height: self.shared.gui_size.get_y() as u32,
- })
- }
-
- fn can_resize(&mut self) -> bool {
- true
- }
-
- fn set_size(&mut self, size: GuiSize) -> Result<(), PluginError> {
- self.shared.gui_size.set_x(size.width as f32);
- self.shared.gui_size.set_y(size.height as f32);
-
- if let Some(gui) = &self.gui {
- gui.request_repaint();
- }
-
- Ok(())
- }
-
- fn set_parent(&mut self, window: Window) -> Result<(), PluginError> {
- self.gui = Some(RetainPluginGui::new(window, self.shared));
-
- Ok(())
- }
-
- fn set_transient(&mut self, _window: Window) -> Result<(), PluginError> {
- Ok(())
- }
-
- fn show(&mut self) -> Result<(), PluginError> {
- if let Some(gui) = &self.gui {
- gui.request_repaint();
- }
-
- Ok(())
- }
-
- fn hide(&mut self) -> Result<(), PluginError> {
- if let Some(gui) = &self.gui {
- gui.request_repaint();
- }
-
- Ok(())
- }
-}