Skip to content

Commit

Permalink
Move event and document abstractions to blitz-traits
Browse files Browse the repository at this point in the history
Signed-off-by: Nico Burns <[email protected]>
  • Loading branch information
nicoburns committed Jan 6, 2025
1 parent 75fc772 commit 000662a
Show file tree
Hide file tree
Showing 22 changed files with 886 additions and 795 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ futures-util = "0.3.30"
futures-intrusive = "0.5.0"
thiserror = "1.0.63"
pollster = "0.4"
smol_str = "0.2"

[profile.production]
inherits = "release"
Expand Down
5 changes: 1 addition & 4 deletions packages/blitz-dom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,8 @@ html-escape = { workspace = true }
url = { workspace = true, features = ["serde"] }

# Input
winit = { workspace = true }
keyboard-types = { workspace = true }
cursor-icon = { workspace = true }

# Rendering
raw-window-handle = { workspace = true }

[target.'cfg(any(target_os = "windows",target_os = "macos",target_os = "linux",target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
arboard = { workspace = true, optional = true }
32 changes: 8 additions & 24 deletions packages/blitz-dom/src/document.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::events::{handle_event, DomEvent, HitResult};
use crate::events::handle_event;
use crate::layout::construct::collect_layout_children;
use crate::node::{ImageData, NodeSpecificData, Status, TextBrush};
use crate::stylo_to_cursor_icon::stylo_to_cursor_icon;
Expand All @@ -7,7 +7,8 @@ use crate::{ElementNodeData, Node, NodeData, TextNodeData};
use app_units::Au;
use blitz_traits::navigation::{DummyNavigationProvider, NavigationProvider};
use blitz_traits::net::{DummyNetProvider, SharedProvider};
use blitz_traits::{ColorScheme, Viewport};
use blitz_traits::{ColorScheme, Document, Viewport};
use blitz_traits::{DomEvent, HitResult};
use cursor_icon::CursorIcon;
use markup5ever::local_name;
use parley::FontContext;
Expand All @@ -23,7 +24,6 @@ use style::values::GenericAtomIdent;
use crate::net::{Resource, StylesheetLoader};
use selectors::{matching::QuirksMode, Element};
use slab::Slab;
use std::any::Any;
use std::collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
Expand Down Expand Up @@ -70,27 +70,6 @@ impl FontMetricsProvider for DummyFontMetricsProvider {
}
}

pub trait Document:
AsRef<BaseDocument> + AsMut<BaseDocument> + Into<BaseDocument> + 'static
{
fn poll(&mut self, _cx: std::task::Context) -> bool {
// Default implementation does nothing
false
}

fn handle_event(&mut self, _event: DomEvent) {
// Default implementation does nothing
}

fn as_any_mut(&mut self) -> &mut dyn Any {
self
}

fn id(&self) -> usize {
self.as_ref().id
}
}

pub struct BaseDocument {
id: usize,

Expand Down Expand Up @@ -176,9 +155,14 @@ fn make_device(viewport: &Viewport) -> Device {
}

impl Document for BaseDocument {
type Doc = Self;
fn handle_event(&mut self, event: DomEvent) {
handle_event(self, event)
}

fn id(&self) -> usize {
self.id
}
}

impl BaseDocument {
Expand Down
12 changes: 6 additions & 6 deletions packages/blitz-dom/src/events/ime.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use winit::event::Ime;
use blitz_traits::BlitzImeEvent;

use crate::BaseDocument;

pub(crate) fn handle_ime_event(doc: &mut BaseDocument, event: Ime) {
pub(crate) fn handle_ime_event(doc: &mut BaseDocument, event: BlitzImeEvent) {
if let Some(node_id) = doc.focus_node_id {
let node = &mut doc.nodes[node_id];
let text_input_data = node
Expand All @@ -14,14 +14,14 @@ pub(crate) fn handle_ime_event(doc: &mut BaseDocument, event: Ime) {
let mut driver = editor.driver(&mut doc.font_ctx, &mut doc.layout_ctx);

match event {
Ime::Enabled => { /* Do nothing */ }
Ime::Disabled => {
BlitzImeEvent::Enabled => { /* Do nothing */ }
BlitzImeEvent::Disabled => {
driver.clear_compose();
}
Ime::Commit(text) => {
BlitzImeEvent::Commit(text) => {
driver.insert_or_replace_selection(&text);
}
Ime::Preedit(text, cursor) => {
BlitzImeEvent::Preedit(text, cursor) => {
if text.is_empty() {
driver.clear_compose();
} else {
Expand Down
61 changes: 23 additions & 38 deletions packages/blitz-dom/src/events/keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@ use crate::{
node::{TextBrush, TextInputData},
BaseDocument,
};
use blitz_traits::BlitzKeyEvent;
use keyboard_types::{Key, Modifiers};
use parley::{FontContext, LayoutContext};
use winit::{
event::{KeyEvent, Modifiers},
keyboard::{Key, NamedKey},
};

pub(crate) fn handle_keypress(
doc: &mut BaseDocument,
target: usize,
event: KeyEvent,
mods: Modifiers,
) {
pub(crate) fn handle_keypress(doc: &mut BaseDocument, target: usize, event: BlitzKeyEvent) {
if let Some(node_id) = doc.focus_node_id {
if target != node_id {
return;
Expand All @@ -27,42 +20,35 @@ pub(crate) fn handle_keypress(

if let Some(input_data) = text_input_data {
println!("Sent text event to {}", node_id);
apply_keypress_event(
input_data,
&mut doc.font_ctx,
&mut doc.layout_ctx,
event,
mods,
);
apply_keypress_event(input_data, &mut doc.font_ctx, &mut doc.layout_ctx, event);
}
}
}

#[cfg(target_os = "macos")]
const ACTION_MOD: Modifiers = Modifiers::SUPER;
#[cfg(not(target_os = "macos"))]
const ACTION_MOD: Modifiers = Modifiers::CONTROL;

pub(crate) fn apply_keypress_event(
input_data: &mut TextInputData,
font_ctx: &mut FontContext,
layout_ctx: &mut LayoutContext<TextBrush>,
event: KeyEvent,
mods: Modifiers,
event: BlitzKeyEvent,
) {
// Do nothing if it is a keyup event
if !event.state.is_pressed() {
return;
}

let shift = mods.state().shift_key();
let action_mod = {
if cfg!(target_os = "macos") {
mods.state().super_key()
} else {
mods.state().control_key()
}
};
let mods = event.modifiers;
let shift = mods.contains(Modifiers::SHIFT);
let action_mod = mods.contains(ACTION_MOD);

let is_multiline = input_data.is_multiline;
let editor = &mut input_data.editor;
let mut driver = editor.driver(font_ctx, layout_ctx);
match event.logical_key {
match event.key {
#[cfg(all(feature = "clipboard", not(target_os = "android")))]
Key::Character(c) if action_mod && matches!(c.as_str(), "c" | "x" | "v") => {
use arboard::Clipboard;
Expand Down Expand Up @@ -96,7 +82,7 @@ pub(crate) fn apply_keypress_event(
driver.select_all()
}
}
Key::Named(NamedKey::ArrowLeft) => {
Key::ArrowLeft => {
if action_mod {
if shift {
driver.select_word_left()
Expand All @@ -109,7 +95,7 @@ pub(crate) fn apply_keypress_event(
driver.move_left()
}
}
Key::Named(NamedKey::ArrowRight) => {
Key::ArrowRight => {
if action_mod {
if shift {
driver.select_word_right()
Expand All @@ -122,21 +108,21 @@ pub(crate) fn apply_keypress_event(
driver.move_right()
}
}
Key::Named(NamedKey::ArrowUp) => {
Key::ArrowUp => {
if shift {
driver.select_up()
} else {
driver.move_up()
}
}
Key::Named(NamedKey::ArrowDown) => {
Key::ArrowDown => {
if shift {
driver.select_down()
} else {
driver.move_down()
}
}
Key::Named(NamedKey::Home) => {
Key::Home => {
if action_mod {
if shift {
driver.select_to_text_start()
Expand All @@ -149,7 +135,7 @@ pub(crate) fn apply_keypress_event(
driver.move_to_line_start()
}
}
Key::Named(NamedKey::End) => {
Key::End => {
if action_mod {
if shift {
driver.select_to_text_end()
Expand All @@ -162,26 +148,25 @@ pub(crate) fn apply_keypress_event(
driver.move_to_line_end()
}
}
Key::Named(NamedKey::Delete) => {
Key::Delete => {
if action_mod {
driver.delete_word()
} else {
driver.delete()
}
}
Key::Named(NamedKey::Backspace) => {
Key::Backspace => {
if action_mod {
driver.backdelete_word()
} else {
driver.backdelete()
}
}
Key::Named(NamedKey::Enter) => {
Key::Enter => {
if is_multiline {
driver.insert_or_replace_selection("\n");
}
}
Key::Named(NamedKey::Space) => driver.insert_or_replace_selection(" "),
Key::Character(s) => driver.insert_or_replace_selection(&s),
_ => {}
};
Expand Down
67 changes: 9 additions & 58 deletions packages/blitz-dom/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,28 @@ mod ime;
mod keyboard;
mod mouse;

use blitz_traits::{DomEvent, DomEventData};
pub(crate) use ime::handle_ime_event;
pub(crate) use keyboard::handle_keypress;
pub(crate) use mouse::handle_click;

use crate::BaseDocument;
use winit::event::{Ime, KeyEvent, Modifiers};

pub(crate) fn handle_event(doc: &mut BaseDocument, event: DomEvent) {
let target_node_id = event.target;

match event.data {
DomEventData::MouseDown { .. } | DomEventData::MouseUp { .. } => {}
DomEventData::MouseDown(_) => {}
DomEventData::MouseUp(_) => {}
DomEventData::Hover => {}
DomEventData::Click { x, y, .. } => {
handle_click(doc, target_node_id, x, y);
DomEventData::Click(event) => {
handle_click(doc, target_node_id, event.x, event.y);
}
DomEventData::KeyPress { event, mods } => {
handle_keypress(doc, target_node_id, event, mods);
DomEventData::KeyPress(event) => {
handle_keypress(doc, target_node_id, event);
}
DomEventData::Ime(ime_event) => {
handle_ime_event(doc, ime_event);
DomEventData::Ime(event) => {
handle_ime_event(doc, event);
}
}
}

pub struct EventListener {
pub name: String,
}

#[derive(Debug, Clone)]
pub struct DomEvent {
pub target: usize,
pub data: DomEventData,
}

impl DomEvent {
/// Returns the name of the event ("click", "mouseover", "keypress", etc)
pub fn name(&self) -> &'static str {
self.data.name()
}
}

#[derive(Debug, Clone)]
pub enum DomEventData {
MouseDown { x: f32, y: f32, mods: Modifiers },
MouseUp { x: f32, y: f32, mods: Modifiers },
Click { x: f32, y: f32, mods: Modifiers },
KeyPress { event: KeyEvent, mods: Modifiers },
Ime(Ime),
Hover,
}

impl DomEventData {
pub fn name(&self) -> &'static str {
match self {
DomEventData::MouseDown { .. } => "mousedown",
DomEventData::MouseUp { .. } => "mouseup",
DomEventData::Click { .. } => "click",
DomEventData::KeyPress { .. } => "keypress",
DomEventData::Ime { .. } => "input",
DomEventData::Hover => "mouseover",
}
}
}

#[derive(Debug, Clone)]
pub struct HitResult {
/// The node_id of the node identified as the hit target
pub node_id: usize,
/// The x coordinate of the hit within the hit target's border-box
pub x: f32,
/// The y coordinate of the hit within the hit target's border-box
pub y: f32,
}
5 changes: 1 addition & 4 deletions packages/blitz-dom/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,12 @@ pub mod events;

pub mod net;

pub mod renderer;

pub use document::{BaseDocument, DocumentLike};
pub use document::BaseDocument;
pub use markup5ever::{
local_name, namespace_prefix, namespace_url, ns, Namespace, NamespaceStaticSet, Prefix,
PrefixStaticSet, QualName,
};
pub use node::{ElementNodeData, Node, NodeData, TextNodeData};
pub use parley::FontContext;
pub use renderer::{BlitzWindowHandle, DocumentRenderer};
pub use string_cache::Atom;
pub use style::invalidation::element::restyle_hints::RestyleHint;
Loading

0 comments on commit 000662a

Please sign in to comment.