multiview example
This commit is contained in:
parent
c247e0527c
commit
6528e9f804
3 changed files with 197 additions and 0 deletions
17
examples/multiview/Cargo.toml
Normal file
17
examples/multiview/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "multiview"
|
||||
version = "0.1.0"
|
||||
authors = ["Jeremy Soller <jeremy@system76.com>"]
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
cosmic-text = { path = "../.." }
|
||||
env_logger = "0.10"
|
||||
fontdb = "0.13"
|
||||
log = "0.4"
|
||||
softbuffer = "0.4"
|
||||
tiny-skia = "0.11"
|
||||
unicode-segmentation = "1.7"
|
||||
winit = "0.29"
|
||||
177
examples/multiview/src/main.rs
Normal file
177
examples/multiview/src/main.rs
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use cosmic_text::{Action, Attrs, Buffer, Edit, Family, FontSystem, Metrics, Shaping, SwashCache};
|
||||
use std::{collections::HashMap, env, fs, num::NonZeroU32, rc::Rc, slice};
|
||||
use tiny_skia::{Color, Paint, PixmapMut, Rect, Transform};
|
||||
use winit::{
|
||||
event::{ElementState, Event, KeyEvent, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
keyboard::{Key, NamedKey},
|
||||
window::{Window as WinitWindow, WindowBuilder},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let path = if let Some(arg) = env::args().nth(1) {
|
||||
arg
|
||||
} else {
|
||||
"sample/hello.txt".to_string()
|
||||
};
|
||||
|
||||
let mut font_system = FontSystem::new();
|
||||
|
||||
let mut swash_cache = SwashCache::new();
|
||||
|
||||
let mut buffer = Buffer::new_empty(Metrics::new(14.0, 20.0));
|
||||
|
||||
let mut buffer = buffer.borrow_with(&mut font_system);
|
||||
|
||||
let attrs = Attrs::new().family(Family::Monospace);
|
||||
match fs::read_to_string(&path) {
|
||||
Ok(text) => buffer.set_text(&text, attrs, Shaping::Advanced),
|
||||
Err(err) => {
|
||||
log::error!("failed to load {:?}: {}", path, err);
|
||||
}
|
||||
}
|
||||
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
struct Window {
|
||||
window: Rc<WinitWindow>,
|
||||
context: softbuffer::Context<Rc<WinitWindow>>,
|
||||
surface: softbuffer::Surface<Rc<WinitWindow>, Rc<WinitWindow>>,
|
||||
scroll: i32,
|
||||
}
|
||||
let mut windows = HashMap::new();
|
||||
for _ in 0..2 {
|
||||
let window = Rc::new(WindowBuilder::new().build(&event_loop).unwrap());
|
||||
let context = softbuffer::Context::new(window.clone()).unwrap();
|
||||
let surface = softbuffer::Surface::new(&context, window.clone()).unwrap();
|
||||
windows.insert(
|
||||
window.id(),
|
||||
Window {
|
||||
window,
|
||||
context,
|
||||
surface,
|
||||
scroll: 0,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
event_loop
|
||||
.run(move |event, elwt| {
|
||||
elwt.set_control_flow(ControlFlow::Wait);
|
||||
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::RedrawRequested,
|
||||
} => {
|
||||
if let Some(Window {
|
||||
window,
|
||||
surface,
|
||||
scroll,
|
||||
..
|
||||
}) = windows.get_mut(&window_id)
|
||||
{
|
||||
let (width, height) = {
|
||||
let size = window.inner_size();
|
||||
(size.width, size.height)
|
||||
};
|
||||
surface
|
||||
.resize(
|
||||
NonZeroU32::new(width).unwrap(),
|
||||
NonZeroU32::new(height).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut surface_buffer = surface.buffer_mut().unwrap();
|
||||
let surface_buffer_u8 = unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
surface_buffer.as_mut_ptr() as *mut u8,
|
||||
surface_buffer.len() * 4,
|
||||
)
|
||||
};
|
||||
let mut pixmap =
|
||||
PixmapMut::from_bytes(surface_buffer_u8, width, height).unwrap();
|
||||
pixmap.fill(Color::from_rgba8(0, 0, 0, 0xFF));
|
||||
|
||||
// Set scroll to view scroll
|
||||
buffer.set_scroll(*scroll);
|
||||
// Set size, will relayout and shape until scroll if changed
|
||||
buffer.set_size(width as f32, height as f32);
|
||||
// Shape until scroll, ensures scroll is clamped
|
||||
buffer.shape_until_scroll();
|
||||
// Update scroll after buffer clamps it
|
||||
*scroll = buffer.scroll();
|
||||
|
||||
let mut paint = Paint::default();
|
||||
paint.anti_alias = false;
|
||||
let transform = Transform::identity();
|
||||
buffer.draw(
|
||||
&mut swash_cache,
|
||||
cosmic_text::Color::rgb(0xFF, 0xFF, 0xFF),
|
||||
|x, y, w, h, color| {
|
||||
paint.set_color_rgba8(color.r(), color.g(), color.b(), color.a());
|
||||
pixmap.fill_rect(
|
||||
Rect::from_xywh(x as f32, y as f32, w as f32, h as f32)
|
||||
.unwrap(),
|
||||
&paint,
|
||||
transform,
|
||||
None,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
surface_buffer.present().unwrap();
|
||||
}
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event:
|
||||
WindowEvent::KeyboardInput {
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key,
|
||||
text,
|
||||
state,
|
||||
..
|
||||
},
|
||||
..
|
||||
},
|
||||
window_id,
|
||||
} => {
|
||||
if let Some(Window { window, scroll, .. }) = windows.get_mut(&window_id) {
|
||||
if state == ElementState::Pressed {
|
||||
match logical_key {
|
||||
Key::Named(NamedKey::ArrowDown) => {
|
||||
*scroll += 1;
|
||||
}
|
||||
Key::Named(NamedKey::ArrowUp) => {
|
||||
*scroll -= 1;
|
||||
}
|
||||
Key::Named(NamedKey::PageDown) => {
|
||||
*scroll += buffer.visible_lines();
|
||||
}
|
||||
Key::Named(NamedKey::PageUp) => {
|
||||
*scroll -= buffer.visible_lines();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
println!("{:?} {:?} {:?}", logical_key, text, state);
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
window_id: _,
|
||||
} => {
|
||||
//TODO: just close one window
|
||||
elwt.exit();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
3
multiview.sh
Executable file
3
multiview.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
RUST_LOG="cosmic_text=debug,multiview=debug" cargo run --release --package multiview -- "$@"
|
||||
Loading…
Add table
Add a link
Reference in a new issue