Re-implement native support
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
Isaac Mills 2024-03-19 21:40:26 -04:00
parent b8f59fef2a
commit 8c22c9d35d
Signed by: fnmain
GPG key ID: B67D7410F33A0F61
2 changed files with 92 additions and 36 deletions

View file

@ -7,7 +7,6 @@ rust-version = "1.72"
[dependencies]
arc-swap = "1.7.0"
cosmic-jotdown = { git = "https://git.nations.lol/fnmain/cosmic-jotdown" }
eframe = { version = "0.26.2", default-features = false, features = [
"accesskit", # Make egui comptaible with screen readers. NOTE: adds a lot of dependencies.
@ -24,8 +23,6 @@ image = { version = "0.24.9", features = ["jpeg", "png"] }
keyframe = { version = "1.1.1", default-features = false }
log = "0.4"
range-map = "0.2.0"
wasm-bindgen = "0.2.92"
web-sys = { version = "0.3.69", features = ["Window", "History", "PopStateEvent"] }
# native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
@ -35,6 +32,9 @@ env_logger = "0.10"
[target.'cfg(target_arch = "wasm32")'.dependencies]
wgpu = { version = "0.19.3", features = ["webgpu", "webgl"] }
wasm-bindgen-futures = "0.4"
wasm-bindgen = "0.2.92"
web-sys = { version = "0.3.69", features = ["Window", "History", "PopStateEvent"] }
arc-swap = "1.7.0"
[profile.release]

View file

@ -1,12 +1,17 @@
use std as alloc;
use std::borrow::Cow;
#[cfg(target_arch = "wasm32")]
use std::cell::RefCell;
#[cfg(target_arch = "wasm32")]
use std::mem::ManuallyDrop;
#[cfg(target_arch = "wasm32")]
use std::ops::Deref;
use std::ops::DerefMut;
#[cfg(target_arch = "wasm32")]
use std::rc::Rc;
use std::sync::Arc;
use alloc::cell::RefCell;
use alloc::mem::ManuallyDrop;
use alloc::ops::Deref;
#[cfg(target_arch = "wasm32")]
use arc_swap::ArcSwapAny;
use cosmic_jotdown::jotdown::{self, Event, ListKind};
use cosmic_jotdown::{Indent, INDENT_AMOUNT};
@ -47,10 +52,13 @@ pub struct Portfolio {
window: ContextWindow,
buffer_size: Vec2,
max_size: Rect,
#[cfg(target_arch = "wasm32")]
states: Rc<RefCell<Vec<State>>>,
#[cfg(target_arch = "wasm32")]
next_state: Rc<ArcSwapAny<Option<Rc<State>>>>,
}
#[cfg(target_arch = "wasm32")]
#[derive(Clone, Copy)]
pub enum State {
Home,
@ -61,6 +69,7 @@ pub enum State {
pub struct ContextWindow {
pub size: Vec2,
pub text: Vec<(Rect, Indent, ContextBlock)>,
#[cfg(target_arch = "wasm32")]
pub name: &'static str,
}
@ -226,11 +235,11 @@ impl ContextWindow {
pub fn set_content(
&mut self,
content: &'static Cow<'static, [Event<'static>]>,
transform: Option<Mat2>,
name: Option<&'static str>,
#[cfg(target_arch = "wasm32")] transform: Option<Mat2>,
#[cfg(target_arch = "wasm32")] name: Option<&'static str>,
font_system: &mut FontSystem,
mut max_width: f32,
states: &mut Vec<State>,
#[cfg(target_arch = "wasm32")] states: &mut Vec<State>,
) {
self.size = Vec2::new(max_width / 1.5, 0.0);
let mut last_indent = None;
@ -343,6 +352,7 @@ impl ContextWindow {
self.size.y += size.y;
}
#[cfg(target_arch = "wasm32")]
if let Some(name) = name {
self.name = name;
let state = states.len();
@ -410,9 +420,15 @@ impl Portfolio {
// Load previous app state (if any).
// Note that you must enable the `persistence` feature for this to work.
let states = Rc::new(RefCell::new(Vec::new()));
#[cfg(target_arch = "wasm32")]
let states;
#[cfg(target_arch = "wasm32")]
let next_state;
#[cfg(target_arch = "wasm32")]
{
states = Rc::new(RefCell::new(Vec::new()));
let pop_state = Rc::clone(&states);
let next_state = Rc::new(ArcSwapAny::new(None));
next_state = Rc::new(ArcSwapAny::new(None));
let pop_next_state = Rc::clone(&next_state);
let popstate_closure =
ManuallyDrop::new(wasm_bindgen::closure::Closure::<dyn FnMut(_)>::new(
@ -432,6 +448,7 @@ impl Portfolio {
.set_onpopstate(Some(wasm_bindgen::JsCast::unchecked_ref(
popstate_closure.as_ref(),
)));
}
egui_extras::install_image_loaders(&cc.egui_ctx);
let mut font_system = FontSystem::new();
@ -486,12 +503,19 @@ impl Portfolio {
buffer_size,
window: ContextWindow::default(),
max_size: Rect::ZERO,
#[cfg(target_arch = "wasm32")]
states,
#[cfg(target_arch = "wasm32")]
next_state,
}
}
pub fn click(&mut self, ui: &egui::Ui, transform: Option<Mat2>, push_state: bool) {
pub fn click(
&mut self,
ui: &egui::Ui,
transform: Option<Mat2>,
#[cfg(target_arch = "wasm32")] push_state: bool,
) {
self.from_size = self.to_size;
self.from_pos = self.to_pos;
self.click_time_offset = ui.input(|i| i.time);
@ -499,6 +523,7 @@ impl Portfolio {
self.to_size = 0.6;
self.to_pos = [0.0, 0.0];
self.zoomed = false;
#[cfg(target_arch = "wasm32")]
if push_state {
let mut states = self.states.borrow_mut();
let state = states.len();
@ -596,6 +621,7 @@ impl Portfolio {
);
}
#[cfg(target_arch = "wasm32")]
fn update_state(&mut self, ui: &mut egui::Ui) {
if let Some(state) = self.next_state.load().deref() {
log::info!("update_state");
@ -632,6 +658,7 @@ impl eframe::App for Portfolio {
.frame(Frame::default().fill(Color32::BLACK))
.show(ctx, |ui| {
self.update_customs(ui);
#[cfg(target_arch = "wasm32")]
self.update_state(ui);
self.custom.custom_painting(ui);
if ui.max_rect() != self.max_size {
@ -921,7 +948,12 @@ impl eframe::App for Portfolio {
self.image_zoomed = false;
});
} else if icon_link.is_none() {
self.click(ui, None, true);
self.click(
ui,
None,
#[cfg(target_arch = "wasm32")]
true,
);
}
}
} else {
@ -938,13 +970,21 @@ impl eframe::App for Portfolio {
}
if name_resp.clicked() {
self.click(ui, None, true);
self.click(
ui,
None,
#[cfg(target_arch = "wasm32")]
true,
);
self.window.set_content(
&ABOUT_ME,
#[cfg(target_arch = "wasm32")]
None,
#[cfg(target_arch = "wasm32")]
Some("About Me"),
self.font_system.lock().deref_mut(),
ui.max_rect().width(),
#[cfg(target_arch = "wasm32")]
self.states.borrow_mut().deref_mut(),
);
}
@ -991,13 +1031,21 @@ impl eframe::App for Portfolio {
if response.clicked() {
self.window.set_content(
i.content,
#[cfg(target_arch = "wasm32")]
Some(transform),
#[cfg(target_arch = "wasm32")]
Some(i.name),
self.font_system.lock().deref_mut(),
ui.max_rect().width(),
#[cfg(target_arch = "wasm32")]
self.states.borrow_mut().deref_mut(),
);
self.click(ui, Some(transform), true);
self.click(
ui,
Some(transform),
#[cfg(target_arch = "wasm32")]
true,
);
scroll_area.state.offset = Vec2::ZERO;
scroll_area.state.store(ui.ctx(), scroll_area.id);
}
@ -1014,15 +1062,23 @@ impl eframe::App for Portfolio {
let transform = glam::Mat2::from_angle((-icon.angle_at).to_radians());
self.window.set_content(
icon.content,
#[cfg(target_arch = "wasm32")]
Some(transform),
#[cfg(target_arch = "wasm32")]
Some(icon.name),
self.font_system.lock().deref_mut(),
ui.max_rect().width(),
#[cfg(target_arch = "wasm32")]
self.states.borrow_mut().deref_mut(),
);
self.zoomed = false;
self.click(ui, Some(transform), true);
self.click(
ui,
Some(transform),
#[cfg(target_arch = "wasm32")]
true,
);
self.zoomed = true;
scroll_area.state.offset = Vec2::ZERO;