macOS fix attempt, the next

This commit is contained in:
Ebu
2025-12-02 12:01:47 +01:00
parent 4680644c54
commit 64c0d94fbc
2 changed files with 107 additions and 83 deletions

View File

@@ -1,5 +1,7 @@
use crate::{parameters::PluginParams, window::EditorWindow}; use crate::{parameters::PluginParams, window::EditorWindow};
use baseview::{Event, EventStatus, MouseButton, MouseEvent, WindowEvent, WindowHandler}; use baseview::{
Event, EventStatus, MouseButton, MouseEvent, WindowEvent, WindowHandler, gl::GlContext,
};
use ebu_dsp::Rect; use ebu_dsp::Rect;
use femtovg::{Canvas, Color, ImageFlags, ImageId, Paint, Path, renderer::OpenGl}; use femtovg::{Canvas, Color, ImageFlags, ImageId, Paint, Path, renderer::OpenGl};
use nih_plug::prelude::*; use nih_plug::prelude::*;
@@ -19,13 +21,13 @@ const FRESHENER_FRAME_HEIGHT: f32 = 144.0;
pub struct PluginGui { pub struct PluginGui {
// font: FontId, // font: FontId,
params: Arc<PluginParams>, params: Arc<PluginParams>,
canvas: Canvas<OpenGl>, canvas: Option<Canvas<OpenGl>>,
_gui_context: Arc<dyn GuiContext>, _gui_context: Arc<dyn GuiContext>,
scaling_factor: f32, scaling_factor: f32,
freshener_image: ImageId, freshener_image: Option<ImageId>,
not_so_fresh_image: ImageId, not_so_fresh_image: Option<ImageId>,
fresh_dumbledore_image: ImageId, fresh_dumbledore_image: Option<ImageId>,
freshener_bounds: Rect<f32>, freshener_bounds: Rect<f32>,
@@ -36,39 +38,39 @@ pub struct PluginGui {
dragging: bool, dragging: bool,
} }
fn create_canvas(
context: &GlContext,
params: &PluginParams,
scaling_factor: f32,
) -> Result<Canvas<OpenGl>, &'static str> {
unsafe {
context.make_current();
}
let renderer = unsafe { OpenGl::new_from_function(|s| context.get_proc_address(s)) }
.map_err(|_| "Failed to create OpenGL renderer")?;
let mut canvas = Canvas::new(renderer).map_err(|_| "Failed to create femtovg canvas")?;
let (width, height) = params.editor_state.size();
canvas.set_size(width, height, scaling_factor);
unsafe {
context.make_not_current();
}
Ok(canvas)
}
impl PluginGui { impl PluginGui {
pub fn new( pub fn new(
window: &mut baseview::Window<'_>, window: &mut baseview::Window<'_>,
gui_context: Arc<dyn GuiContext>, gui_context: Arc<dyn GuiContext>,
params: Arc<PluginParams>, params: Arc<PluginParams>,
scaling_factor: f32, scaling_factor: f32,
) -> Result<Self, &'static str> { ) -> Self {
let context = window let canvas = if let Some(context) = window.gl_context() {
.gl_context() create_canvas(context, &params, scaling_factor).ok()
.ok_or("Failed to get window OpenGL context")?; } else {
unsafe { None
context.make_current(); };
}
let renderer = unsafe { OpenGl::new_from_function(|s| context.get_proc_address(s)) }
.map_err(|_| "Failed to create femtovg renderer")?;
let mut canvas = Canvas::new(renderer).map_err(|_| "Failed to create femtovg canvas")?;
let (width, height) = params.editor_state.size();
canvas.set_size(width, height, scaling_factor); let this = Self {
let le_fresh = canvas
.load_image_mem(FRESHENER_IMAGE, ImageFlags::empty())
.map_err(|_| "Failed to load le fresh")?;
let not_so_fresh_image = canvas
.load_image_mem(NOT_SO_FRESH_BG_IMAGE, ImageFlags::empty())
.map_err(|_| "Failed to load not so fresh")?;
let fresh_dumbledore_image = canvas
.load_image_mem(FRESH_DUMBLEDORE_BG_IMAGE, ImageFlags::empty())
.map_err(|_| "Failed to load fresh dumbledore")?;
unsafe {
context.make_not_current();
}
Ok(Self {
//font, //font,
params, params,
canvas, canvas,
@@ -79,16 +81,31 @@ impl PluginGui {
drag_start_mouse_pos: (0.0, 0.0), drag_start_mouse_pos: (0.0, 0.0),
drag_start_parameter_value: 0.0, drag_start_parameter_value: 0.0,
dragging: false, dragging: false,
freshener_image: le_fresh, freshener_image: None,
fresh_dumbledore_image, fresh_dumbledore_image: None,
not_so_fresh_image, not_so_fresh_image: None,
freshener_bounds: Rect { freshener_bounds: Rect {
x: 120.0, x: 120.0,
y: 20.0, y: 20.0,
width: FRESHENER_FRAME_WIDTH, width: FRESHENER_FRAME_WIDTH,
height: FRESHENER_FRAME_HEIGHT, height: FRESHENER_FRAME_HEIGHT,
}, },
}) };
/*
if let Some(canvas) = canvas {
this.freshener_image = canvas
.load_image_mem(FRESHENER_IMAGE, ImageFlags::empty())
.map_err(|_| "Failed to load le fresh")?;
let not_so_fresh_image = canvas
.load_image_mem(NOT_SO_FRESH_BG_IMAGE, ImageFlags::empty())
.map_err(|_| "Failed to load not so fresh")?;
let fresh_dumbledore_image = canvas
.load_image_mem(FRESH_DUMBLEDORE_BG_IMAGE, ImageFlags::empty())
.map_err(|_| "Failed to load fresh dumbledore")?;
}
*/
this
} }
} }
@@ -96,6 +113,10 @@ impl WindowHandler for PluginGui {
fn on_frame(&mut self, window: &mut baseview::Window) { fn on_frame(&mut self, window: &mut baseview::Window) {
const WINDOW_WIDTH: f32 = EditorWindow::WINDOW_SIZE.0 as f32; const WINDOW_WIDTH: f32 = EditorWindow::WINDOW_SIZE.0 as f32;
const WINDOW_HEIGHT: f32 = EditorWindow::WINDOW_SIZE.1 as f32; const WINDOW_HEIGHT: f32 = EditorWindow::WINDOW_SIZE.1 as f32;
if self.canvas.is_none() {
return;
}
let canvas = self.canvas.as_mut().unwrap();
if !self.dirty { if !self.dirty {
//return; //return;
@@ -111,10 +132,9 @@ impl WindowHandler for PluginGui {
unsafe { unsafe {
context.make_current(); context.make_current();
} }
let (width, height) = (self.canvas.width(), self.canvas.height()); let (width, height) = (canvas.width(), canvas.height());
self.canvas.reset(); canvas.reset();
self.canvas canvas.clear_rect(0, 0, width, height, Color::rgbaf(0.0, 0.0, 0.0, 1.0));
.clear_rect(0, 0, width, height, Color::rgbaf(0.0, 0.0, 0.0, 1.0));
let mut full_window_path = Path::new(); let mut full_window_path = Path::new();
full_window_path.rect( full_window_path.rect(
@@ -132,7 +152,7 @@ impl WindowHandler for PluginGui {
self.freshener_bounds.height, self.freshener_bounds.height,
); );
let bbox = self.canvas.path_bbox(&freshener_path); let bbox = canvas.path_bbox(&freshener_path);
let frame_index = (self.params.freshness.unmodulated_normalized_value() let frame_index = (self.params.freshness.unmodulated_normalized_value()
* (FRESHENER_FRAMES - 1) as f32) * (FRESHENER_FRAMES - 1) as f32)
@@ -140,10 +160,11 @@ impl WindowHandler for PluginGui {
let frame_x = (frame_index % FRESHENER_FRAMES_X as f32).floor(); let frame_x = (frame_index % FRESHENER_FRAMES_X as f32).floor();
let frame_y = (frame_index / FRESHENER_FRAMES_X as f32).floor(); let frame_y = (frame_index / FRESHENER_FRAMES_X as f32).floor();
self.canvas.fill_path( if let Some(not_so_fresh) = self.not_so_fresh_image {
canvas.fill_path(
&full_window_path, &full_window_path,
&Paint::image( &Paint::image(
self.not_so_fresh_image, not_so_fresh,
0.0, 0.0,
0.0, 0.0,
WINDOW_WIDTH, WINDOW_WIDTH,
@@ -152,10 +173,12 @@ impl WindowHandler for PluginGui {
1.0, 1.0,
), ),
); );
self.canvas.fill_path( }
if let Some(fresh_dumbledore) = self.fresh_dumbledore_image {
canvas.fill_path(
&full_window_path, &full_window_path,
&Paint::image( &Paint::image(
self.fresh_dumbledore_image, fresh_dumbledore,
0.0, 0.0,
0.0, 0.0,
WINDOW_WIDTH, WINDOW_WIDTH,
@@ -164,11 +187,13 @@ impl WindowHandler for PluginGui {
self.params.freshness.unmodulated_normalized_value(), self.params.freshness.unmodulated_normalized_value(),
), ),
); );
}
self.canvas.fill_path( if let Some(freshener) = self.freshener_image {
canvas.fill_path(
&freshener_path, &freshener_path,
&Paint::image( &Paint::image(
self.freshener_image, freshener,
bbox.minx - frame_x * FRESHENER_FRAME_WIDTH, bbox.minx - frame_x * FRESHENER_FRAME_WIDTH,
bbox.miny - frame_y * FRESHENER_FRAME_HEIGHT, bbox.miny - frame_y * FRESHENER_FRAME_HEIGHT,
self.freshener_bounds.width * FRESHENER_FRAMES_X as f32, self.freshener_bounds.width * FRESHENER_FRAMES_X as f32,
@@ -177,8 +202,9 @@ impl WindowHandler for PluginGui {
1.0, 1.0,
), ),
); );
}
self.canvas.flush(); canvas.flush();
context.swap_buffers(); context.swap_buffers();
unsafe { unsafe {
context.make_not_current(); context.make_not_current();
@@ -195,8 +221,9 @@ impl WindowHandler for PluginGui {
match event { match event {
Event::Window(WindowEvent::Resized(size)) => { Event::Window(WindowEvent::Resized(size)) => {
let phys_size = size.physical_size(); let phys_size = size.physical_size();
self.canvas if let Some(canvas) = self.canvas.as_mut() {
.set_size(phys_size.width, phys_size.height, self.scaling_factor); canvas.set_size(phys_size.width, phys_size.height, self.scaling_factor);
}
self.dirty = true; self.dirty = true;
} }
Event::Mouse(MouseEvent::CursorMoved { position, .. }) => { Event::Mouse(MouseEvent::CursorMoved { position, .. }) => {

View File

@@ -49,10 +49,7 @@ impl Editor for EditorWindow {
..Default::default() ..Default::default()
}) })
}, move |window: &mut baseview::Window<'_>| -> PluginGui { }, move |window: &mut baseview::Window<'_>| -> PluginGui {
match PluginGui::new(window, gui_context, params, scaling_factor.unwrap_or(1.0)) { PluginGui::new(window, gui_context, params, scaling_factor.unwrap_or(1.0))
Err(err) => { nih_error!("Failed to create plugin: {err}"); panic!("{err}"); }
Ok(plug) => plug
}
}); });
self.params.editor_state.open.store(true, Ordering::Release); self.params.editor_state.open.store(true, Ordering::Release);
Box::new(EditorHandle { Box::new(EditorHandle {