macOS fix attempt, the next
This commit is contained in:
185
src/gui.rs
185
src/gui.rs
@@ -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, ¶ms, 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,45 +160,51 @@ 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 {
|
||||||
&full_window_path,
|
canvas.fill_path(
|
||||||
&Paint::image(
|
&full_window_path,
|
||||||
self.not_so_fresh_image,
|
&Paint::image(
|
||||||
0.0,
|
not_so_fresh,
|
||||||
0.0,
|
0.0,
|
||||||
WINDOW_WIDTH,
|
0.0,
|
||||||
WINDOW_HEIGHT,
|
WINDOW_WIDTH,
|
||||||
0.0,
|
WINDOW_HEIGHT,
|
||||||
1.0,
|
0.0,
|
||||||
),
|
1.0,
|
||||||
);
|
),
|
||||||
self.canvas.fill_path(
|
);
|
||||||
&full_window_path,
|
}
|
||||||
&Paint::image(
|
if let Some(fresh_dumbledore) = self.fresh_dumbledore_image {
|
||||||
self.fresh_dumbledore_image,
|
canvas.fill_path(
|
||||||
0.0,
|
&full_window_path,
|
||||||
0.0,
|
&Paint::image(
|
||||||
WINDOW_WIDTH,
|
fresh_dumbledore,
|
||||||
WINDOW_HEIGHT,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
self.params.freshness.unmodulated_normalized_value(),
|
WINDOW_WIDTH,
|
||||||
),
|
WINDOW_HEIGHT,
|
||||||
);
|
0.0,
|
||||||
|
self.params.freshness.unmodulated_normalized_value(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.canvas.fill_path(
|
if let Some(freshener) = self.freshener_image {
|
||||||
&freshener_path,
|
canvas.fill_path(
|
||||||
&Paint::image(
|
&freshener_path,
|
||||||
self.freshener_image,
|
&Paint::image(
|
||||||
bbox.minx - frame_x * FRESHENER_FRAME_WIDTH,
|
freshener,
|
||||||
bbox.miny - frame_y * FRESHENER_FRAME_HEIGHT,
|
bbox.minx - frame_x * FRESHENER_FRAME_WIDTH,
|
||||||
self.freshener_bounds.width * FRESHENER_FRAMES_X as f32,
|
bbox.miny - frame_y * FRESHENER_FRAME_HEIGHT,
|
||||||
self.freshener_bounds.height * FRESHENER_FRAMES_Y as f32,
|
self.freshener_bounds.width * FRESHENER_FRAMES_X as f32,
|
||||||
0.0,
|
self.freshener_bounds.height * FRESHENER_FRAMES_Y as f32,
|
||||||
1.0,
|
0.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, .. }) => {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user