Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ objc2-core-foundation = { version = "0.3.2", default-features = false, features
block2 = "0.6.2"
dispatch2 = "0.3.1"
objc2-foundation = { version = "0.3.2", default-features = false, features = ["std", "NSEnumerator", "block2", "NSOperation"] }
objc2-quartz-core = { version = "0.3.2", default-features = false, features = ["CADisplayLink"] }
objc2-app-kit = { version = "0.3.2", default-features = false, features = [
"NSApplication",
"NSCursor",
Expand All @@ -90,11 +91,12 @@ objc2-app-kit = { version = "0.3.2", default-features = false, features = [
"NSTrackingArea",
"NSView",
"NSWindow",
"objc2-quartz-core",
"objc2-core-foundation"
] }

[workspace]
members = ["examples/cursors","examples/open_parented", "examples/open_window", "examples/plugin_clack", "examples/render_femtovg", "examples/render_wgpu", "examples/plugin_clack_femtovg", "examples/test-frame-pacing"]
members = ["examples/cursors", "examples/open_parented", "examples/open_window", "examples/plugin_clack", "examples/render_femtovg", "examples/render_wgpu", "examples/plugin_clack_femtovg", "examples/test-frame-pacing", "examples/external-wakeup"]

[lints.clippy]
missing-safety-doc = "allow"
Expand Down
13 changes: 3 additions & 10 deletions examples/cursors/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ use baseview::{
};
use femtovg::renderer::OpenGl;
use femtovg::{Canvas, Color};
use std::cell::{Cell, RefCell};
use std::cell::RefCell;

struct CursorsExample {
window_context: WindowContext,
gl_context: GlContext,
canvas: RefCell<Canvas<OpenGl>>,
damaged: Cell<bool>,
}

impl CursorsExample {
Expand All @@ -29,7 +28,7 @@ impl CursorsExample {
canvas.set_size(size.physical.width, size.physical.height, size.scale_factor as f32);

unsafe { gl_context.make_not_current()? };
Ok(Self { gl_context, window_context, canvas: canvas.into(), damaged: true.into() })
Ok(Self { gl_context, window_context, canvas: canvas.into() })
}

fn in_blue_area(&self, position: PhysicalPosition<f64>) -> bool {
Expand All @@ -43,11 +42,7 @@ impl CursorsExample {
}

impl WindowHandler for CursorsExample {
fn on_frame(&self) -> Result<(), HandlerError> {
if !self.damaged.get() {
return Ok(());
}

fn draw(&self) -> Result<(), HandlerError> {
let context = &self.gl_context;
unsafe { context.make_current()? };

Expand All @@ -72,15 +67,13 @@ impl WindowHandler for CursorsExample {
canvas.flush();
context.swap_buffers()?;
unsafe { context.make_not_current()? };
self.damaged.set(false);

Ok(())
}

fn resized(&self, new_size: WindowSize) -> Result<(), HandlerError> {
let size = new_size.physical;
self.canvas.borrow_mut().set_size(size.width, size.height, new_size.scale_factor as f32);
self.damaged.set(true);

Ok(())
}
Expand Down
10 changes: 10 additions & 0 deletions examples/external-wakeup/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "external-wakeup"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
baseview = { path = "../..", features = ["opengl"] }
femtovg = "0.27.0"
rand = "0.10.3"
147 changes: 147 additions & 0 deletions examples/external-wakeup/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
use baseview::dpi::LogicalSize;
use baseview::gl::{GlConfig, GlContext};
use baseview::{
Event, EventStatus, HandlerError, Window, WindowContext, WindowHandler, WindowSettings,
WindowSize, WindowWaker,
};
use femtovg::renderer::OpenGl;
use femtovg::{Canvas, Color};
use std::cell::{Cell, RefCell};
use std::sync::mpsc::*;
use std::time::Duration;

#[derive(Copy, Clone, Debug)]
enum Message {
Hello,
}

struct FemtovgExample {
window_context: WindowContext,
gl_context: GlContext,
canvas: RefCell<Canvas<OpenGl>>,

green_rect_opacity: Cell<f32>,

receiver: Receiver<Message>,
}

impl FemtovgExample {
fn new(
window_context: WindowContext, receiver: Receiver<Message>,
) -> Result<Self, HandlerError> {
let Some(gl_context) = window_context.gl_context() else { unreachable!() };
unsafe { gl_context.make_current()? };

let renderer =
unsafe { OpenGl::new_from_function_cstr(|s| gl_context.get_proc_address(s)) }?;

let mut canvas = Canvas::new(renderer)?;
let size = window_context.size();

canvas.set_size(size.physical.width, size.physical.height, size.scale_factor as f32);

unsafe { gl_context.make_not_current()? };
Ok(Self {
gl_context,
window_context,
canvas: canvas.into(),
green_rect_opacity: 0.0.into(),
receiver,
})
}
}

impl WindowHandler for FemtovgExample {
fn draw(&self) -> Result<(), HandlerError> {
let context = &self.gl_context;
unsafe { context.make_current()? };

let mut canvas = self.canvas.borrow_mut();

let screen_height = canvas.height();
let screen_width = canvas.width();

// Clear
canvas.clear_rect(0, 0, screen_width, screen_height, Color::rgb(0x0A, 0x0A, 0x0A));

if self.green_rect_opacity.get() <= 0.0 {
// Make orange rectangle
canvas.clear_rect(
(screen_width as f32 * 0.3).floor() as u32,
(screen_height as f32 * 0.45).floor() as u32,
(screen_width as f32 * 0.1).floor() as u32,
(screen_height as f32 * 0.1).floor() as u32,
Color::rgbf(1.0, 0.5, 0.),
);
} else {
// Make green rectangle
canvas.clear_rect(
(screen_width as f32 * 0.5).floor() as u32,
(screen_height as f32 * 0.45).floor() as u32,
(screen_width as f32 * 0.1).floor() as u32,
(screen_height as f32 * 0.1).floor() as u32,
Color::rgbf(0.0, 1. * self.green_rect_opacity.get(), 0.),
);

// Prepare a next frame to animate it fading out
self.green_rect_opacity.set(self.green_rect_opacity.get() - 1.0 / 60.0);
self.window_context.request_redraw();
}

// Tell renderer to execute all drawing commands
canvas.flush();
context.swap_buffers()?;
unsafe { context.make_not_current()? };

Ok(())
}

fn resized(&self, new_size: WindowSize) -> Result<(), HandlerError> {
let size = new_size.physical;
self.canvas.borrow_mut().set_size(size.width, size.height, new_size.scale_factor as f32);

Ok(())
}

fn on_event(&self, _event: Event) -> EventStatus {
EventStatus::Ignored
}

fn poll(&self) {
let msg = match self.receiver.try_recv() {
Err(TryRecvError::Empty) => return,
Err(TryRecvError::Disconnected) => return eprintln!("Channel disconnected!"),
Ok(msg) => msg,
};

eprintln!("Message received: {msg:?}!");
self.green_rect_opacity.set(1.0);
self.window_context.request_redraw();
}
}

fn main() -> Result<(), baseview::Error> {
unsafe { baseview::assume_standalone_in_process() };
let (sender, receiver) = channel();

let window_open_options = WindowSettings::new()
.with_title("Baseview Waker example")
.with_size(LogicalSize::new(512, 512))
.with_gl_config(GlConfig { alpha_bits: 8, ..GlConfig::default() });

let window = Window::create(window_open_options, |ctx| FemtovgExample::new(ctx, receiver))?;
let waker = window.waker();
std::thread::spawn(|| run_thread(sender, waker));

window.run_until_closed()?;
Ok(())
}

fn run_thread(sender: Sender<Message>, waker: WindowWaker) {
loop {
let interval: f32 = rand::random_range(0.5..2.5);
std::thread::sleep(Duration::from_secs_f32(interval));
sender.send(Message::Hello).unwrap();
waker.request_poll();
}
}
25 changes: 7 additions & 18 deletions examples/open_parented/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ use baseview::{
Event, EventStatus, HandlerError, Window, WindowContext, WindowHandler, WindowSettings,
WindowSize,
};
use std::cell::{Cell, RefCell};
use std::cell::RefCell;
use std::num::NonZeroU32;

struct ParentWindowHandler {
surface: RefCell<softbuffer::Surface<WindowContext, WindowContext>>,
damaged: Cell<bool>,

child_window: Window,
}

Expand All @@ -26,18 +24,15 @@ impl ParentWindowHandler {
let child_window = Window::create(window_open_options, ChildWindowHandler::new)?;
child_window.show()?;

Ok(Self { surface: surface.into(), damaged: true.into(), child_window })
Ok(Self { surface: surface.into(), child_window })
}
}

impl WindowHandler for ParentWindowHandler {
fn on_frame(&self) -> Result<(), HandlerError> {
fn draw(&self) -> Result<(), HandlerError> {
let mut surface = self.surface.borrow_mut();
let mut buf = surface.buffer_mut()?;
if self.damaged.get() {
buf.fill(0xFFAA0000);
self.damaged.set(false);
}
buf.fill(0xFFAA0000);
buf.present()?;

Ok(())
Expand All @@ -50,7 +45,6 @@ impl WindowHandler for ParentWindowHandler {
(NonZeroU32::new(new_size.physical.width), NonZeroU32::new(new_size.physical.height))
{
self.surface.borrow_mut().resize(width, height)?;
self.damaged.set(true);
}

self.child_window.suggest_fallback_scale_factor(new_size.scale_factor)?;
Expand All @@ -71,7 +65,6 @@ impl WindowHandler for ParentWindowHandler {

struct ChildWindowHandler {
surface: RefCell<softbuffer::Surface<WindowContext, WindowContext>>,
damaged: Cell<bool>,
}

impl ChildWindowHandler {
Expand All @@ -81,18 +74,15 @@ impl ChildWindowHandler {
let size = window.size().physical;
surface.resize(size.width.try_into()?, size.height.try_into()?)?;

Ok(Self { surface: surface.into(), damaged: true.into() })
Ok(Self { surface: surface.into() })
}
}

impl WindowHandler for ChildWindowHandler {
fn on_frame(&self) -> Result<(), HandlerError> {
fn draw(&self) -> Result<(), HandlerError> {
let mut surface = self.surface.borrow_mut();
let mut buf = surface.buffer_mut()?;
if self.damaged.get() {
buf.fill(0xFFAAAAAA);
self.damaged.set(false);
}
buf.fill(0xFFAAAAAA);
buf.present()?;

Ok(())
Expand All @@ -105,7 +95,6 @@ impl WindowHandler for ChildWindowHandler {
(NonZeroU32::new(new_size.physical.width), NonZeroU32::new(new_size.physical.height))
{
self.surface.borrow_mut().resize(width, height)?;
self.damaged.set(true);
}

Ok(())
Expand Down
Loading
Loading