mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Initial setup to use iced
This commit is contained in:
parent
fb72fc7433
commit
bbbede68fc
127
Cargo.lock
generated
127
Cargo.lock
generated
@ -535,6 +535,46 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
version = "4.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5123c6b97286809fea9e38d2c9bf530edbcb9fc0d8f8272c28b0c95f067fa92d"
|
||||
dependencies = [
|
||||
"error-code",
|
||||
"str-buf",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard_macos"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "145a7f9e9b89453bc0a5e32d166456405d389cea5b578f57f1274b1397588a95"
|
||||
dependencies = [
|
||||
"objc",
|
||||
"objc-foundation",
|
||||
"objc_id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard_wayland"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "926d872adca0fc88173f8b7532c651e29ce67dc97323f4546c1c8af6610937fb"
|
||||
dependencies = [
|
||||
"smithay-clipboard 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clipboard_x11"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "137cbd60c42327a8d63e710cee5a4d6a1ac41cdc90449ea2c2c63bd5e186290a"
|
||||
dependencies = [
|
||||
"xcb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
@ -708,11 +748,11 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4423d79fed83ebd9ab81ec21fa97144300a961782158287dc9bf7eddac37ff0b"
|
||||
dependencies = [
|
||||
"clipboard-win",
|
||||
"clipboard-win 3.1.1",
|
||||
"objc",
|
||||
"objc-foundation",
|
||||
"objc_id",
|
||||
"smithay-clipboard",
|
||||
"smithay-clipboard 0.6.1",
|
||||
"x11-clipboard",
|
||||
]
|
||||
|
||||
@ -1324,6 +1364,16 @@ dependencies = [
|
||||
"version_check 0.9.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "error-code"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b49c94f66f2d2c5ee8685039e458b4e6c9f13af7c28736baf10ce42966a5ab52"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"str-buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "euc"
|
||||
version = "0.5.1"
|
||||
@ -1988,6 +2038,33 @@ dependencies = [
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iced_core"
|
||||
version = "0.2.1"
|
||||
source = "git+https://github.com/hecrj/iced#f46431600cb61d4e83e0ded1ca79525478436be3"
|
||||
|
||||
[[package]]
|
||||
name = "iced_futures"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/hecrj/iced#f46431600cb61d4e83e0ded1ca79525478436be3"
|
||||
dependencies = [
|
||||
"futures 0.3.5",
|
||||
"log",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iced_native"
|
||||
version = "0.2.2"
|
||||
source = "git+https://github.com/hecrj/iced#f46431600cb61d4e83e0ded1ca79525478436be3"
|
||||
dependencies = [
|
||||
"iced_core",
|
||||
"iced_futures",
|
||||
"num-traits 0.2.12",
|
||||
"twox-hash",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
@ -4039,6 +4116,16 @@ dependencies = [
|
||||
"wayland-protocols 0.28.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smithay-clipboard"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e9db50a9b272938b767b731a1291f22f407315def4049db93871e8828034d5"
|
||||
dependencies = [
|
||||
"smithay-client-toolkit 0.11.0",
|
||||
"wayland-client 0.27.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smithay-clipboard"
|
||||
version = "0.6.1"
|
||||
@ -4173,6 +4260,12 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
||||
|
||||
[[package]]
|
||||
name = "str-buf"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a"
|
||||
|
||||
[[package]]
|
||||
name = "string"
|
||||
version = "0.2.1"
|
||||
@ -4669,6 +4762,9 @@ name = "twox-hash"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56"
|
||||
dependencies = [
|
||||
"rand 0.4.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tynm"
|
||||
@ -4989,6 +5085,7 @@ dependencies = [
|
||||
"glutin",
|
||||
"guillotiere",
|
||||
"hashbrown 0.7.2",
|
||||
"iced_native",
|
||||
"image",
|
||||
"inline_tweak",
|
||||
"itertools",
|
||||
@ -5014,6 +5111,7 @@ dependencies = [
|
||||
"veloren-server",
|
||||
"veloren-voxygen-anim",
|
||||
"veloren-world",
|
||||
"window_clipboard",
|
||||
"winit",
|
||||
"winres",
|
||||
]
|
||||
@ -5171,6 +5269,18 @@ dependencies = [
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.68"
|
||||
@ -5448,6 +5558,19 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "window_clipboard"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b849e24b344ea3535bcda7320b8b7f3560bd2c3692de73153d3c64acc84203e5"
|
||||
dependencies = [
|
||||
"clipboard-win 4.0.3",
|
||||
"clipboard_macos",
|
||||
"clipboard_wayland",
|
||||
"clipboard_x11",
|
||||
"raw-window-handle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.22.2"
|
||||
|
@ -24,9 +24,6 @@ common = {package = "veloren-common", path = "../common"}
|
||||
anim = {package = "veloren-voxygen-anim", path = "src/anim", default-features = false}
|
||||
|
||||
# Graphics
|
||||
conrod_core = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
|
||||
conrod_winit = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
|
||||
euc = {git = "https://github.com/zesterer/euc.git"}
|
||||
gfx = "0.18.2"
|
||||
gfx_device_gl = {version = "0.16.2", optional = true}
|
||||
gfx_gl = {version = "0.6.1", optional = true}
|
||||
@ -34,6 +31,13 @@ glutin = {git = "https://github.com/rust-windowing/glutin.git", rev="63a1ea7d6e6
|
||||
old_school_gfx_glutin_ext = "0.24"
|
||||
winit = {version = "0.22.2", features = ["serde"]}
|
||||
|
||||
# Ui
|
||||
conrod_core = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
|
||||
conrod_winit = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
|
||||
euc = {git = "https://github.com/zesterer/euc.git"}
|
||||
iced = {package = "iced_native", git = "https://github.com/hecrj/iced"}
|
||||
window_clipboard = "0.1.1"
|
||||
|
||||
# ECS
|
||||
specs = {git = "https://github.com/amethyst/specs.git", rev = "7a2e348ab2223818bad487695c66c43db88050a5"}
|
||||
specs-idvs = {git = "https://gitlab.com/veloren/specs-idvs.git", branch = "specs-git"}
|
||||
|
@ -2317,7 +2317,6 @@ impl<'a> Widget for SettingsWindow<'a> {
|
||||
.global_state
|
||||
.window
|
||||
.window()
|
||||
.window()
|
||||
.current_monitor()
|
||||
.unwrap()
|
||||
.video_modes()
|
||||
|
@ -4,11 +4,13 @@ use crate::{
|
||||
ui::{
|
||||
self,
|
||||
fonts::ConrodVoxygenFonts,
|
||||
ice::IcedUi,
|
||||
img_ids::{BlankGraphic, ImageGraphic, VoxelGraphic},
|
||||
Graphic, ImageFrame, Tooltip, Ui,
|
||||
Graphic, Ui,
|
||||
},
|
||||
GlobalState,
|
||||
};
|
||||
//ImageFrame, Tooltip,
|
||||
use common::assets::Asset;
|
||||
use conrod_core::{
|
||||
color,
|
||||
@ -17,6 +19,7 @@ use conrod_core::{
|
||||
widget::{text_box::Event as TextBoxEvent, Button, Image, List, Rectangle, Text, TextBox},
|
||||
widget_ids, Borderable, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||
};
|
||||
use iced::Column;
|
||||
use image::DynamicImage;
|
||||
use rand::{seq::SliceRandom, thread_rng, Rng};
|
||||
use std::time::Duration;
|
||||
@ -122,6 +125,32 @@ image_ids! {
|
||||
}
|
||||
}
|
||||
|
||||
image_ids_ice! {
|
||||
struct IcedImgs {
|
||||
<VoxelGraphic>
|
||||
v_logo: "voxygen.element.v_logo",
|
||||
|
||||
info_frame: "voxygen.element.frames.info_frame_2",
|
||||
banner: "voxygen.element.frames.banner",
|
||||
|
||||
banner_bottom: "voxygen.element.frames.banner_bottom",
|
||||
|
||||
<ImageGraphic>
|
||||
bg: "voxygen.background.bg_main",
|
||||
banner_top: "voxygen.element.frames.banner_top",
|
||||
button: "voxygen.element.buttons.button",
|
||||
button_hover: "voxygen.element.buttons.button_hover",
|
||||
button_press: "voxygen.element.buttons.button_press",
|
||||
input_bg_top: "voxygen.element.misc_bg.textbox_top",
|
||||
input_bg_mid: "voxygen.element.misc_bg.textbox_mid",
|
||||
input_bg_bot: "voxygen.element.misc_bg.textbox_bot",
|
||||
disclaimer: "voxygen.element.frames.disclaimer",
|
||||
|
||||
<BlankGraphic>
|
||||
nothing: (),
|
||||
}
|
||||
}
|
||||
|
||||
rotation_image_ids! {
|
||||
pub struct ImgsRot {
|
||||
<ImageGraphic>
|
||||
@ -158,8 +187,31 @@ pub struct PopupData {
|
||||
popup_type: PopupType,
|
||||
}
|
||||
|
||||
// No state currently
|
||||
struct IcedState {
|
||||
imgs: IcedImgs,
|
||||
}
|
||||
pub type Message = Event;
|
||||
impl IcedState {
|
||||
pub fn view(&mut self) -> iced::Column<Message, ui::ice::IcedRenderer> {
|
||||
Column::new().push(ui::ice::Image::new(
|
||||
(self.imgs.bg, ui::Rotation::None),
|
||||
500.0,
|
||||
500.0,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn update(message: Message) {
|
||||
match message {
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MainMenuUi {
|
||||
ui: Ui,
|
||||
ice_ui: IcedUi,
|
||||
ice_state: IcedState,
|
||||
ids: Ids,
|
||||
imgs: Imgs,
|
||||
rot_imgs: ImgsRot,
|
||||
@ -225,8 +277,15 @@ impl<'a> MainMenuUi {
|
||||
let fonts = ConrodVoxygenFonts::load(&voxygen_i18n.fonts, &mut ui)
|
||||
.expect("Impossible to load fonts!");
|
||||
|
||||
let mut ice_ui = IcedUi::new(window).unwrap();
|
||||
let ice_state = IcedState {
|
||||
imgs: IcedImgs::load(&mut ice_ui).expect("Failed to load images"),
|
||||
};
|
||||
|
||||
Self {
|
||||
ui,
|
||||
ice_ui,
|
||||
ice_state,
|
||||
ids,
|
||||
imgs,
|
||||
rot_imgs,
|
||||
@ -276,7 +335,7 @@ impl<'a> MainMenuUi {
|
||||
let intro_text = &self.voxygen_i18n.get("main.login_process");
|
||||
|
||||
// Tooltip
|
||||
let _tooltip = Tooltip::new({
|
||||
/*let _tooltip = Tooltip::new({
|
||||
// Edge images [t, b, r, l]
|
||||
// Corner images [tr, tl, br, bl]
|
||||
let edge = &self.rot_imgs.tt_side;
|
||||
@ -291,7 +350,7 @@ impl<'a> MainMenuUi {
|
||||
.title_font_size(self.fonts.cyri.scale(15))
|
||||
.desc_font_size(self.fonts.cyri.scale(10))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.desc_text_color(TEXT_COLOR_2);
|
||||
.desc_text_color(TEXT_COLOR_2);*/
|
||||
|
||||
// Background image, Veloren logo, Alpha-Version Label
|
||||
Image::new(if self.connect {
|
||||
@ -897,11 +956,18 @@ impl<'a> MainMenuUi {
|
||||
|
||||
pub fn handle_event(&mut self, event: ui::Event) { self.ui.handle_event(event); }
|
||||
|
||||
pub fn handle_iced_event(&mut self, event: ui::ice::Event) { self.ice_ui.handle_event(event); }
|
||||
|
||||
pub fn maintain(&mut self, global_state: &mut GlobalState, dt: Duration) -> Vec<Event> {
|
||||
let events = self.update_layout(global_state, dt);
|
||||
self.ui.maintain(global_state.window.renderer_mut(), None);
|
||||
self.ice_ui
|
||||
.maintain(self.ice_state.view(), global_state.window.renderer_mut());
|
||||
events
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) { self.ui.render(renderer, None); }
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
self.ui.render(renderer, None);
|
||||
self.ice_ui.render(renderer);
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,13 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop) {
|
||||
if let Some(event) = ui::Event::try_from(&event, global_state.window.window()) {
|
||||
global_state.window.send_event(Event::Ui(event));
|
||||
}
|
||||
// iced ui events
|
||||
// TODO: no clone
|
||||
if let winit::Event::WindowEvent { event, .. } = event.clone() {
|
||||
if let Some(event) = ui::ice::window_event(event) {
|
||||
global_state.window.send_event(Event::IcedUi(event));
|
||||
}
|
||||
}
|
||||
|
||||
match event {
|
||||
winit::event::Event::NewEvents(_) => {
|
||||
|
12
voxygen/src/ui/ice/clipboard.rs
Normal file
12
voxygen/src/ui/ice/clipboard.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// Taken from https://github.com/hecrj/iced/blob/e1438774af809c2951c4c7446638500446c81111/winit/src/clipboard.rs
|
||||
pub struct Clipboard(window_clipboard::Clipboard);
|
||||
|
||||
impl Clipboard {
|
||||
pub fn new(window: &winit::Window) -> Option<Clipboard> {
|
||||
window_clipboard::Clipboard::new(window).map(Clipboard).ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl iced::Clipboard for Clipboard {
|
||||
fn content(&self) -> Option<String> { self.0.read().ok() }
|
||||
}
|
72
voxygen/src/ui/ice/mod.rs
Normal file
72
voxygen/src/ui/ice/mod.rs
Normal file
@ -0,0 +1,72 @@
|
||||
// tooltip_manager: TooltipManager,
|
||||
mod clipboard;
|
||||
mod renderer;
|
||||
mod widget;
|
||||
mod winit_conversion;
|
||||
|
||||
pub use graphic::{Id, Rotation};
|
||||
pub use iced::Event;
|
||||
pub use renderer::IcedRenderer;
|
||||
pub use widget::image::Image;
|
||||
pub use winit_conversion::window_event;
|
||||
|
||||
use super::graphic::{self, Graphic};
|
||||
use crate::{render::Renderer, window::Window, Error};
|
||||
use clipboard::Clipboard;
|
||||
use iced::{Cache, Element, MouseCursor, Size, UserInterface};
|
||||
|
||||
pub struct IcedUi {
|
||||
renderer: IcedRenderer,
|
||||
cache: Option<Cache>,
|
||||
events: Vec<Event>,
|
||||
clipboard: Clipboard,
|
||||
}
|
||||
impl IcedUi {
|
||||
pub fn new(window: &mut Window) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
renderer: IcedRenderer::new(window)?,
|
||||
cache: Some(Cache::new()),
|
||||
events: Vec::new(),
|
||||
// TODO: handle None
|
||||
clipboard: Clipboard::new(window.window()).unwrap(),
|
||||
})
|
||||
}
|
||||
|
||||
// Add an new graphic that is referencable via the returned Id
|
||||
pub fn add_graphic(&mut self, graphic: Graphic) -> graphic::Id {
|
||||
self.renderer.add_graphic(graphic)
|
||||
}
|
||||
|
||||
// TODO: handle scaling here
|
||||
pub fn handle_event(&mut self, event: Event) { self.events.push(event); }
|
||||
|
||||
// TODO: produce root internally???
|
||||
pub fn maintain<'a, M, E: Into<Element<'a, M, IcedRenderer>>>(
|
||||
&mut self,
|
||||
root: E,
|
||||
renderer: &mut Renderer,
|
||||
) -> (Vec<M>, MouseCursor) {
|
||||
// TODO: convert to f32 at source
|
||||
let window_size = self.renderer.scaled_window_size().map(|e| e as f32);
|
||||
|
||||
let mut user_interface = UserInterface::build(
|
||||
root,
|
||||
Size::new(window_size.x, window_size.y),
|
||||
self.cache.take().unwrap(),
|
||||
&mut self.renderer,
|
||||
);
|
||||
|
||||
let messages =
|
||||
user_interface.update(self.events.drain(..), Some(&self.clipboard), &self.renderer);
|
||||
|
||||
let (primitive, mouse_cursor) = user_interface.draw(&mut self.renderer);
|
||||
|
||||
self.renderer.draw(primitive, renderer);
|
||||
|
||||
self.cache = Some(user_interface.into_cache());
|
||||
|
||||
(messages, mouse_cursor)
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) { self.renderer.render(renderer, None); }
|
||||
}
|
400
voxygen/src/ui/ice/renderer.rs
Normal file
400
voxygen/src/ui/ice/renderer.rs
Normal file
@ -0,0 +1,400 @@
|
||||
mod column;
|
||||
mod image;
|
||||
|
||||
use super::{
|
||||
super::{
|
||||
cache::Cache,
|
||||
graphic::{self, Graphic, TexId},
|
||||
scale::{Scale, ScaleMode},
|
||||
},
|
||||
widget,
|
||||
};
|
||||
use crate::{
|
||||
render::{
|
||||
create_ui_quad, Consts, DynamicModel, Globals, Mesh, Renderer, UiLocals, UiMode, UiPipeline,
|
||||
},
|
||||
window::Window,
|
||||
Error,
|
||||
};
|
||||
//use log::warn;
|
||||
use std::ops::Range;
|
||||
use vek::*;
|
||||
|
||||
enum DrawKind {
|
||||
Image(TexId),
|
||||
// Text and non-textured geometry
|
||||
Plain,
|
||||
}
|
||||
enum DrawCommand {
|
||||
Draw { kind: DrawKind, verts: Range<usize> },
|
||||
Scissor(Aabr<u16>),
|
||||
WorldPos(Option<usize>),
|
||||
}
|
||||
impl DrawCommand {
|
||||
fn image(verts: Range<usize>, id: TexId) -> DrawCommand {
|
||||
DrawCommand::Draw {
|
||||
kind: DrawKind::Image(id),
|
||||
verts,
|
||||
}
|
||||
}
|
||||
|
||||
fn plain(verts: Range<usize>) -> DrawCommand {
|
||||
DrawCommand::Draw {
|
||||
kind: DrawKind::Plain,
|
||||
verts,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum State {
|
||||
Image(TexId),
|
||||
Plain,
|
||||
}
|
||||
|
||||
pub enum Primitive {
|
||||
// Allocation :(
|
||||
Group {
|
||||
primitives: Vec<Primitive>,
|
||||
},
|
||||
Image {
|
||||
handle: widget::image::Handle,
|
||||
bounds: iced::Rectangle,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct IcedRenderer {
|
||||
//image_map: Map<(Image, Rotation)>,
|
||||
cache: Cache,
|
||||
// Model for drawing the ui
|
||||
model: DynamicModel<UiPipeline>,
|
||||
// Consts to specify positions of ingame elements (e.g. Nametags)
|
||||
ingame_locals: Vec<Consts<UiLocals>>,
|
||||
// Consts for default ui drawing position (ie the interface)
|
||||
interface_locals: Consts<UiLocals>,
|
||||
default_globals: Consts<Globals>,
|
||||
|
||||
// Window size for updating scaling
|
||||
//window_resized: Option<Vec2<f64>>,
|
||||
// Used to delay cache resizing until after current frame is drawn
|
||||
//need_cache_resize: bool,
|
||||
// Scaling of the ui
|
||||
scale: Scale,
|
||||
|
||||
half_res: Vec2<f32>,
|
||||
// Pixel perfection alignment
|
||||
align: Vec2<f32>,
|
||||
// Pretend dims :) (i.e. scaled)
|
||||
win_dims: Vec2<f32>,
|
||||
|
||||
// Per-frame/update
|
||||
current_state: State,
|
||||
mesh: Mesh<UiPipeline>,
|
||||
start: usize,
|
||||
// Draw commands for the next render
|
||||
draw_commands: Vec<DrawCommand>,
|
||||
//current_scissor: Aabr<u16>,
|
||||
}
|
||||
impl IcedRenderer {
|
||||
pub fn new(window: &mut Window) -> Result<Self, Error> {
|
||||
let scale = Scale::new(window, ScaleMode::Absolute(1.0));
|
||||
// TODO: looks like we can just get this from scale
|
||||
let win_dims = scale.scaled_window_size().map(|e| e as f32);
|
||||
|
||||
let renderer = window.renderer_mut();
|
||||
let res = renderer.get_resolution();
|
||||
|
||||
let half_res = res.map(|e| e as f32 / 2.0);
|
||||
let align = align(res);
|
||||
|
||||
Ok(Self {
|
||||
cache: Cache::new(renderer)?,
|
||||
draw_commands: Vec::new(),
|
||||
model: renderer.create_dynamic_model(100)?,
|
||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
||||
ingame_locals: Vec::new(),
|
||||
//window_resized: None,
|
||||
//need_cache_resize: false,
|
||||
mesh: Mesh::new(),
|
||||
current_state: State::Plain,
|
||||
scale,
|
||||
half_res,
|
||||
align,
|
||||
win_dims,
|
||||
start: 0,
|
||||
//current_scissor: default_scissor(renderer),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn scaled_window_size(&self) -> Vec2<f64> { self.scale.scaled_window_size() }
|
||||
|
||||
pub fn add_graphic(&mut self, graphic: Graphic) -> graphic::Id {
|
||||
self.cache.add_graphic(graphic)
|
||||
}
|
||||
|
||||
pub fn draw(&mut self, primitive: Primitive, renderer: &mut Renderer) {
|
||||
/*if self.need_cache_resize {
|
||||
// Resize graphic cache
|
||||
self.cache.resize_graphic_cache(renderer).unwrap();
|
||||
// Resize glyph cache
|
||||
self.cache.resize_glyph_cache(renderer).unwrap();
|
||||
|
||||
self.need_cache_resize = false;
|
||||
}*/
|
||||
|
||||
// Re-use memory
|
||||
self.draw_commands.clear();
|
||||
self.mesh.clear();
|
||||
|
||||
self.current_state = State::Plain;
|
||||
self.start = 0;
|
||||
|
||||
//self.current_scissor = default_scissor(renderer);
|
||||
|
||||
self.draw_primitive(primitive, renderer);
|
||||
|
||||
// Enter the final command.
|
||||
self.draw_commands.push(match self.current_state {
|
||||
State::Plain => DrawCommand::plain(self.start..self.mesh.vertices().len()),
|
||||
State::Image(id) => DrawCommand::image(self.start..self.mesh.vertices().len(), id),
|
||||
});
|
||||
|
||||
// Draw glyph cache (use for debugging).
|
||||
/*self.draw_commands
|
||||
.push(DrawCommand::Scissor(default_scissor(renderer)));
|
||||
start = mesh.vertices().len();
|
||||
mesh.push_quad(create_ui_quad(
|
||||
Aabr {
|
||||
min: (-1.0, -1.0).into(),
|
||||
max: (1.0, 1.0).into(),
|
||||
},
|
||||
Aabr {
|
||||
min: (0.0, 1.0).into(),
|
||||
max: (1.0, 0.0).into(),
|
||||
},
|
||||
Rgba::new(1.0, 1.0, 1.0, 0.8),
|
||||
UiMode::Text,
|
||||
));
|
||||
self.draw_commands
|
||||
.push(DrawCommand::plain(start..mesh.vertices().len()));*/
|
||||
|
||||
// Create a larger dynamic model if the mesh is larger than the current model
|
||||
// size.
|
||||
if self.model.vbuf.len() < self.mesh.vertices().len() {
|
||||
self.model = renderer
|
||||
.create_dynamic_model(self.mesh.vertices().len() * 4 / 3)
|
||||
.unwrap();
|
||||
}
|
||||
// Update model with new mesh.
|
||||
renderer.update_model(&self.model, &self.mesh, 0).unwrap();
|
||||
|
||||
// Handle window resizing.
|
||||
/*if let Some(new_dims) = self.window_resized.take() {
|
||||
let (old_w, old_h) = self.scale.scaled_window_size().into_tuple();
|
||||
self.scale.window_resized(new_dims, renderer);
|
||||
let (w, h) = self.scale.scaled_window_size().into_tuple();
|
||||
self.ui.handle_event(Input::Resize(w, h));
|
||||
|
||||
// Avoid panic in graphic cache when minimizing.
|
||||
// Avoid resetting cache if window size didn't change
|
||||
// Somewhat inefficient for elements that won't change size after a window resize
|
||||
let res = renderer.get_resolution();
|
||||
self.need_cache_resize = res.x > 0 && res.y > 0 && !(old_w == w && old_h == h);
|
||||
}*/
|
||||
}
|
||||
|
||||
fn gl_aabr(&self, bounds: iced::Rectangle) -> Aabr<f32> {
|
||||
/*let (ui_win_w, ui_win_h) = self.win_dims.into_tuple();
|
||||
let (l, b) = aabr.min.into_tuple();
|
||||
let (r, t) = aabr.max.into_tuple();
|
||||
let vx = |x: f64| (x / ui_win_w * 2.0) as f32;
|
||||
let vy = |y: f64| (y / ui_win_h * 2.0) as f32;
|
||||
let min = Vec2::new(
|
||||
((vx(l) * half_res.x + x_align).round() - x_align) / half_res.x,
|
||||
((vy(b) * half_res.y + y_align).round() - y_align) / half_res.y,
|
||||
);
|
||||
let max = Vec2::new(
|
||||
((vx(r) * half_res.x + x_align).round() - x_align) / half_res.x,
|
||||
((vy(t) * half_res.y + y_align).round() - y_align) / half_res.y,
|
||||
);*/
|
||||
let flipped_y = self.win_dims.y - bounds.y;
|
||||
let half_win_dims = self.win_dims.map(|e| e / 2.0);
|
||||
let half_res = self.half_res;
|
||||
let min = (((Vec2::new(bounds.x, flipped_y - bounds.height) - half_win_dims)
|
||||
/ half_win_dims
|
||||
* half_res
|
||||
+ self.align)
|
||||
.map(|e| e.round())
|
||||
- self.align)
|
||||
/ half_res;
|
||||
let max = (((Vec2::new(bounds.x + bounds.width, flipped_y) - half_win_dims)
|
||||
/ half_win_dims
|
||||
* half_res
|
||||
+ self.align)
|
||||
.map(|e| e.round())
|
||||
- self.align)
|
||||
/ half_res;
|
||||
Aabr { min, max }
|
||||
}
|
||||
|
||||
fn draw_primitive(&mut self, primitive: Primitive, renderer: &mut Renderer) {
|
||||
match primitive {
|
||||
Primitive::Group { primitives } => {
|
||||
primitives
|
||||
.into_iter()
|
||||
.for_each(|p| self.draw_primitive(p, renderer));
|
||||
},
|
||||
Primitive::Image { handle, bounds } => {
|
||||
let (graphic_id, rotation) = handle;
|
||||
let gl_aabr = self.gl_aabr(bounds);
|
||||
|
||||
let graphic_cache = self.cache.graphic_cache_mut();
|
||||
|
||||
match graphic_cache.get_graphic(graphic_id) {
|
||||
Some(Graphic::Blank) | None => return,
|
||||
_ => {},
|
||||
}
|
||||
|
||||
// TODO provide color with the image
|
||||
// let color =
|
||||
// srgba_to_linear(color.unwrap_or(conrod_core::color::WHITE).to_fsa().
|
||||
// into());
|
||||
let color = Rgba::from([1.0, 1.0, 1.0, 1.0]);
|
||||
|
||||
let resolution = Vec2::new(
|
||||
(gl_aabr.size().w * self.half_res.x).round() as u16,
|
||||
(gl_aabr.size().h * self.half_res.y).round() as u16,
|
||||
);
|
||||
// Transform the source rectangle into uv coordinate.
|
||||
// TODO: Make sure this is right.
|
||||
let source_aabr = {
|
||||
let (uv_l, uv_r, uv_b, uv_t) = (0.0, 1.0, 0.0, 1.0);
|
||||
/*match source_rect {
|
||||
Some(src_rect) => {
|
||||
let (l, r, b, t) = src_rect.l_r_b_t();
|
||||
((l / image_w) as f32,
|
||||
(r / image_w) as f32,
|
||||
(b / image_h) as f32,
|
||||
(t / image_h) as f32)
|
||||
}
|
||||
None => (0.0, 1.0, 0.0, 1.0),
|
||||
};*/
|
||||
Aabr {
|
||||
min: Vec2::new(uv_l, uv_b),
|
||||
max: Vec2::new(uv_r, uv_t),
|
||||
}
|
||||
};
|
||||
|
||||
// Cache graphic at particular resolution.
|
||||
let (uv_aabr, tex_id) = match graphic_cache.cache_res(
|
||||
renderer,
|
||||
graphic_id,
|
||||
resolution,
|
||||
source_aabr,
|
||||
rotation,
|
||||
) {
|
||||
// TODO: get dims from graphic_cache (or have it return floats directly)
|
||||
Some((aabr, tex_id)) => {
|
||||
let cache_dims = graphic_cache
|
||||
.get_tex(tex_id)
|
||||
.get_dimensions()
|
||||
.map(|e| e as f32);
|
||||
let min = Vec2::new(aabr.min.x as f32, aabr.max.y as f32) / cache_dims;
|
||||
let max = Vec2::new(aabr.max.x as f32, aabr.min.y as f32) / cache_dims;
|
||||
(Aabr { min, max }, tex_id)
|
||||
},
|
||||
None => return,
|
||||
};
|
||||
|
||||
match self.current_state {
|
||||
// Switch to the image state if we are not in it already.
|
||||
State::Plain => {
|
||||
self.draw_commands
|
||||
.push(DrawCommand::plain(self.start..self.mesh.vertices().len()));
|
||||
self.start = self.mesh.vertices().len();
|
||||
self.current_state = State::Image(tex_id);
|
||||
},
|
||||
// If the image is cached in a different texture switch to the new one
|
||||
State::Image(id) => {
|
||||
if id != tex_id {
|
||||
self.draw_commands.push(DrawCommand::image(
|
||||
self.start..self.mesh.vertices().len(),
|
||||
id,
|
||||
));
|
||||
self.start = self.mesh.vertices().len();
|
||||
self.current_state = State::Image(tex_id);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
self.mesh
|
||||
.push_quad(create_ui_quad(gl_aabr, uv_aabr, color, UiMode::Image));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer, maybe_globals: Option<&Consts<Globals>>) {
|
||||
let mut scissor = default_scissor(renderer);
|
||||
let globals = maybe_globals.unwrap_or(&self.default_globals);
|
||||
let mut locals = &self.interface_locals;
|
||||
for draw_command in self.draw_commands.iter() {
|
||||
match draw_command {
|
||||
DrawCommand::Scissor(new_scissor) => {
|
||||
scissor = *new_scissor;
|
||||
},
|
||||
DrawCommand::WorldPos(index) => {
|
||||
locals = index.map_or(&self.interface_locals, |i| &self.ingame_locals[i]);
|
||||
},
|
||||
DrawCommand::Draw { kind, verts } => {
|
||||
let tex = match kind {
|
||||
DrawKind::Image(tex_id) => self.cache.graphic_cache().get_tex(*tex_id),
|
||||
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||
};
|
||||
let model = self.model.submodel(verts.clone());
|
||||
renderer.render_ui_element(&model, tex, scissor, globals, locals);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Given the the resolution determines the offset needed to align integer
|
||||
// offsets from the center of the sceen to pixels
|
||||
fn align(res: Vec2<u16>) -> Vec2<f32> {
|
||||
// If the resolution is odd then the center of the screen will be within the
|
||||
// middle of a pixel so we need to offset by 0.5 pixels to be on the edge of
|
||||
// a pixel
|
||||
res.map(|e| (e & 1) as f32 * 0.5)
|
||||
}
|
||||
|
||||
fn default_scissor(renderer: &Renderer) -> Aabr<u16> {
|
||||
let (screen_w, screen_h) = renderer.get_resolution().map(|e| e as u16).into_tuple();
|
||||
Aabr {
|
||||
min: Vec2 { x: 0, y: 0 },
|
||||
max: Vec2 {
|
||||
x: screen_w,
|
||||
y: screen_h,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl iced::Renderer for IcedRenderer {
|
||||
// Default styling
|
||||
type Defaults = ();
|
||||
// TODO: use graph of primitives to enable diffing???
|
||||
type Output = (Primitive, iced::MouseCursor);
|
||||
|
||||
fn layout<'a, M>(
|
||||
&mut self,
|
||||
element: &iced::Element<'a, M, Self>,
|
||||
limits: &iced::layout::Limits,
|
||||
) -> iced::layout::Node {
|
||||
let node = element.layout(self, limits);
|
||||
|
||||
// Trim text measurements cache?
|
||||
|
||||
node
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: impl Debugger
|
34
voxygen/src/ui/ice/renderer/column.rs
Normal file
34
voxygen/src/ui/ice/renderer/column.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use super::{IcedRenderer, Primitive};
|
||||
use iced::{column, Element, Layout, MouseCursor, Point};
|
||||
|
||||
impl column::Renderer for IcedRenderer {
|
||||
fn draw<M>(
|
||||
&mut self,
|
||||
defaults: &Self::Defaults,
|
||||
content: &[Element<'_, M, Self>],
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
) -> Self::Output {
|
||||
let mut mouse_cursor = MouseCursor::OutOfBounds;
|
||||
|
||||
(
|
||||
Primitive::Group {
|
||||
primitives: content
|
||||
.iter()
|
||||
.zip(layout.children())
|
||||
.map(|(child, layout)| {
|
||||
let (primitive, new_mouse_cursor) =
|
||||
child.draw(self, defaults, layout, cursor_position);
|
||||
|
||||
if new_mouse_cursor > mouse_cursor {
|
||||
mouse_cursor = new_mouse_cursor;
|
||||
}
|
||||
|
||||
primitive
|
||||
})
|
||||
.collect(),
|
||||
},
|
||||
mouse_cursor,
|
||||
)
|
||||
}
|
||||
}
|
14
voxygen/src/ui/ice/renderer/image.rs
Normal file
14
voxygen/src/ui/ice/renderer/image.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use super::{super::widget::image, IcedRenderer, Primitive};
|
||||
use iced::MouseCursor;
|
||||
|
||||
impl image::Renderer for IcedRenderer {
|
||||
fn draw(&mut self, handle: image::Handle, layout: iced::Layout<'_>) -> Self::Output {
|
||||
(
|
||||
Primitive::Image {
|
||||
handle,
|
||||
bounds: layout.bounds(),
|
||||
},
|
||||
MouseCursor::OutOfBounds,
|
||||
)
|
||||
}
|
||||
}
|
1
voxygen/src/ui/ice/widget.rs
Normal file
1
voxygen/src/ui/ice/widget.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod image;
|
63
voxygen/src/ui/ice/widget/image.rs
Normal file
63
voxygen/src/ui/ice/widget/image.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use super::super::super::graphic::{self, Rotation};
|
||||
use iced::{layout, Element, Hasher, Layout, Length, Point, Size, Widget};
|
||||
use std::hash::Hash;
|
||||
|
||||
// TODO: consider iced's approach to images and caching image data
|
||||
// Also `Graphic` might be a better name for this is it wasn't already in use
|
||||
// elsewhere
|
||||
|
||||
pub type Handle = (graphic::Id, Rotation);
|
||||
|
||||
pub struct Image {
|
||||
handle: Handle,
|
||||
size: Size,
|
||||
}
|
||||
|
||||
impl Image {
|
||||
pub fn new(handle: Handle, w: f32, h: f32) -> Self {
|
||||
let size = Size::new(w, h);
|
||||
Self { handle, size }
|
||||
}
|
||||
}
|
||||
|
||||
impl<M, R> Widget<M, R> for Image
|
||||
where
|
||||
R: self::Renderer,
|
||||
{
|
||||
fn width(&self) -> Length { Length::Fill }
|
||||
|
||||
fn height(&self) -> Length { Length::Fill }
|
||||
|
||||
fn layout(&self, _renderer: &R, _limits: &layout::Limits) -> layout::Node {
|
||||
// We don't care about aspect ratios here :p
|
||||
layout::Node::new(self.size)
|
||||
// Infinite sizes confusing
|
||||
//layout::Node::new(limits.resolve(self.size))
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
_defaults: &R::Defaults,
|
||||
layout: Layout<'_>,
|
||||
_cursor_position: Point,
|
||||
) -> R::Output {
|
||||
renderer.draw(self.handle, layout)
|
||||
}
|
||||
|
||||
fn hash_layout(&self, state: &mut Hasher) {
|
||||
self.size.width.to_bits().hash(state);
|
||||
self.size.height.to_bits().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Renderer: iced::Renderer {
|
||||
fn draw(&mut self, handle: Handle, layout: Layout<'_>) -> Self::Output;
|
||||
}
|
||||
|
||||
impl<'a, M, R> From<Image> for Element<'a, M, R>
|
||||
where
|
||||
R: self::Renderer,
|
||||
{
|
||||
fn from(image: Image) -> Element<'a, M, R> { Element::new(image) }
|
||||
}
|
271
voxygen/src/ui/ice/winit_conversion.rs
Normal file
271
voxygen/src/ui/ice/winit_conversion.rs
Normal file
@ -0,0 +1,271 @@
|
||||
// Using reference impl: https://github.com/hecrj/iced/blob/e1438774af809c2951c4c7446638500446c81111/winit/src/conversion.rs
|
||||
use iced::{
|
||||
input::{
|
||||
keyboard::{self, KeyCode, ModifiersState},
|
||||
mouse, ButtonState,
|
||||
},
|
||||
window, Event,
|
||||
};
|
||||
|
||||
/// Converts a winit event into an iced event.
|
||||
pub fn window_event(event: winit::WindowEvent) -> Option<Event> {
|
||||
use winit::WindowEvent;
|
||||
|
||||
match event {
|
||||
WindowEvent::Resized(new_size) => {
|
||||
let logical_size: winit::dpi::LogicalSize = new_size;
|
||||
|
||||
Some(Event::Window(window::Event::Resized {
|
||||
width: logical_size.width as u32,
|
||||
height: logical_size.height as u32,
|
||||
}))
|
||||
},
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
let position: winit::dpi::LogicalPosition = position;
|
||||
|
||||
Some(Event::Mouse(mouse::Event::CursorMoved {
|
||||
x: position.x as f32,
|
||||
y: position.y as f32,
|
||||
}))
|
||||
},
|
||||
WindowEvent::MouseInput { button, state, .. } => Some(Event::Mouse(mouse::Event::Input {
|
||||
button: mouse_button(button),
|
||||
state: button_state(state),
|
||||
})),
|
||||
WindowEvent::MouseWheel { delta, .. } => match delta {
|
||||
winit::MouseScrollDelta::LineDelta(delta_x, delta_y) => {
|
||||
Some(Event::Mouse(mouse::Event::WheelScrolled {
|
||||
delta: mouse::ScrollDelta::Lines {
|
||||
x: delta_x,
|
||||
y: delta_y,
|
||||
},
|
||||
}))
|
||||
},
|
||||
winit::MouseScrollDelta::PixelDelta(position) => {
|
||||
let position: winit::dpi::LogicalPosition = position;
|
||||
Some(Event::Mouse(mouse::Event::WheelScrolled {
|
||||
delta: mouse::ScrollDelta::Pixels {
|
||||
x: position.x as f32,
|
||||
y: position.y as f32,
|
||||
},
|
||||
}))
|
||||
},
|
||||
},
|
||||
WindowEvent::ReceivedCharacter(c) => {
|
||||
Some(Event::Keyboard(keyboard::Event::CharacterReceived(c)))
|
||||
},
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
winit::KeyboardInput {
|
||||
virtual_keycode: Some(virtual_keycode),
|
||||
state,
|
||||
modifiers,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => Some(Event::Keyboard(keyboard::Event::Input {
|
||||
key_code: key_code(virtual_keycode),
|
||||
state: button_state(state),
|
||||
modifiers: modifiers_state(modifiers),
|
||||
})),
|
||||
// iced also can use file hovering events but we don't need them right now
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// iced has a function for converting mouse cursors here
|
||||
|
||||
/// Converts winit mouse button to iced mouse button
|
||||
fn mouse_button(mouse_button: winit::MouseButton) -> mouse::Button {
|
||||
match mouse_button {
|
||||
winit::MouseButton::Left => mouse::Button::Left,
|
||||
winit::MouseButton::Right => mouse::Button::Right,
|
||||
winit::MouseButton::Middle => mouse::Button::Middle,
|
||||
winit::MouseButton::Other(other) => mouse::Button::Other(other),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts winit `ElementState` to an iced button state
|
||||
fn button_state(element_state: winit::ElementState) -> ButtonState {
|
||||
match element_state {
|
||||
winit::ElementState::Pressed => ButtonState::Pressed,
|
||||
winit::ElementState::Released => ButtonState::Released,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts winit `ModifiersState` to iced `ModifiersState`
|
||||
fn modifiers_state(modifiers: winit::ModifiersState) -> ModifiersState {
|
||||
ModifiersState {
|
||||
shift: modifiers.shift,
|
||||
control: modifiers.ctrl,
|
||||
alt: modifiers.alt,
|
||||
logo: modifiers.logo,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts winit `VirtualKeyCode` to iced `KeyCode`
|
||||
fn key_code(virtual_keycode: winit::VirtualKeyCode) -> KeyCode {
|
||||
match virtual_keycode {
|
||||
winit::VirtualKeyCode::Key1 => KeyCode::Key1,
|
||||
winit::VirtualKeyCode::Key2 => KeyCode::Key2,
|
||||
winit::VirtualKeyCode::Key3 => KeyCode::Key3,
|
||||
winit::VirtualKeyCode::Key4 => KeyCode::Key4,
|
||||
winit::VirtualKeyCode::Key5 => KeyCode::Key5,
|
||||
winit::VirtualKeyCode::Key6 => KeyCode::Key6,
|
||||
winit::VirtualKeyCode::Key7 => KeyCode::Key7,
|
||||
winit::VirtualKeyCode::Key8 => KeyCode::Key8,
|
||||
winit::VirtualKeyCode::Key9 => KeyCode::Key9,
|
||||
winit::VirtualKeyCode::Key0 => KeyCode::Key0,
|
||||
winit::VirtualKeyCode::A => KeyCode::A,
|
||||
winit::VirtualKeyCode::B => KeyCode::B,
|
||||
winit::VirtualKeyCode::C => KeyCode::C,
|
||||
winit::VirtualKeyCode::D => KeyCode::D,
|
||||
winit::VirtualKeyCode::E => KeyCode::E,
|
||||
winit::VirtualKeyCode::F => KeyCode::F,
|
||||
winit::VirtualKeyCode::G => KeyCode::G,
|
||||
winit::VirtualKeyCode::H => KeyCode::H,
|
||||
winit::VirtualKeyCode::I => KeyCode::I,
|
||||
winit::VirtualKeyCode::J => KeyCode::J,
|
||||
winit::VirtualKeyCode::K => KeyCode::K,
|
||||
winit::VirtualKeyCode::L => KeyCode::L,
|
||||
winit::VirtualKeyCode::M => KeyCode::M,
|
||||
winit::VirtualKeyCode::N => KeyCode::N,
|
||||
winit::VirtualKeyCode::O => KeyCode::O,
|
||||
winit::VirtualKeyCode::P => KeyCode::P,
|
||||
winit::VirtualKeyCode::Q => KeyCode::Q,
|
||||
winit::VirtualKeyCode::R => KeyCode::R,
|
||||
winit::VirtualKeyCode::S => KeyCode::S,
|
||||
winit::VirtualKeyCode::T => KeyCode::T,
|
||||
winit::VirtualKeyCode::U => KeyCode::U,
|
||||
winit::VirtualKeyCode::V => KeyCode::V,
|
||||
winit::VirtualKeyCode::W => KeyCode::W,
|
||||
winit::VirtualKeyCode::X => KeyCode::X,
|
||||
winit::VirtualKeyCode::Y => KeyCode::Y,
|
||||
winit::VirtualKeyCode::Z => KeyCode::Z,
|
||||
winit::VirtualKeyCode::Escape => KeyCode::Escape,
|
||||
winit::VirtualKeyCode::F1 => KeyCode::F1,
|
||||
winit::VirtualKeyCode::F2 => KeyCode::F2,
|
||||
winit::VirtualKeyCode::F3 => KeyCode::F3,
|
||||
winit::VirtualKeyCode::F4 => KeyCode::F4,
|
||||
winit::VirtualKeyCode::F5 => KeyCode::F5,
|
||||
winit::VirtualKeyCode::F6 => KeyCode::F6,
|
||||
winit::VirtualKeyCode::F7 => KeyCode::F7,
|
||||
winit::VirtualKeyCode::F8 => KeyCode::F8,
|
||||
winit::VirtualKeyCode::F9 => KeyCode::F9,
|
||||
winit::VirtualKeyCode::F10 => KeyCode::F10,
|
||||
winit::VirtualKeyCode::F11 => KeyCode::F11,
|
||||
winit::VirtualKeyCode::F12 => KeyCode::F12,
|
||||
winit::VirtualKeyCode::F13 => KeyCode::F13,
|
||||
winit::VirtualKeyCode::F14 => KeyCode::F14,
|
||||
winit::VirtualKeyCode::F15 => KeyCode::F15,
|
||||
winit::VirtualKeyCode::F16 => KeyCode::F16,
|
||||
winit::VirtualKeyCode::F17 => KeyCode::F17,
|
||||
winit::VirtualKeyCode::F18 => KeyCode::F18,
|
||||
winit::VirtualKeyCode::F19 => KeyCode::F19,
|
||||
winit::VirtualKeyCode::F20 => KeyCode::F20,
|
||||
winit::VirtualKeyCode::F21 => KeyCode::F21,
|
||||
winit::VirtualKeyCode::F22 => KeyCode::F22,
|
||||
winit::VirtualKeyCode::F23 => KeyCode::F23,
|
||||
winit::VirtualKeyCode::F24 => KeyCode::F24,
|
||||
winit::VirtualKeyCode::Snapshot => KeyCode::Snapshot,
|
||||
winit::VirtualKeyCode::Scroll => KeyCode::Scroll,
|
||||
winit::VirtualKeyCode::Pause => KeyCode::Pause,
|
||||
winit::VirtualKeyCode::Insert => KeyCode::Insert,
|
||||
winit::VirtualKeyCode::Home => KeyCode::Home,
|
||||
winit::VirtualKeyCode::Delete => KeyCode::Delete,
|
||||
winit::VirtualKeyCode::End => KeyCode::End,
|
||||
winit::VirtualKeyCode::PageDown => KeyCode::PageDown,
|
||||
winit::VirtualKeyCode::PageUp => KeyCode::PageUp,
|
||||
winit::VirtualKeyCode::Left => KeyCode::Left,
|
||||
winit::VirtualKeyCode::Up => KeyCode::Up,
|
||||
winit::VirtualKeyCode::Right => KeyCode::Right,
|
||||
winit::VirtualKeyCode::Down => KeyCode::Down,
|
||||
winit::VirtualKeyCode::Back => KeyCode::Backspace,
|
||||
winit::VirtualKeyCode::Return => KeyCode::Enter,
|
||||
winit::VirtualKeyCode::Space => KeyCode::Space,
|
||||
winit::VirtualKeyCode::Compose => KeyCode::Compose,
|
||||
winit::VirtualKeyCode::Caret => KeyCode::Caret,
|
||||
winit::VirtualKeyCode::Numlock => KeyCode::Numlock,
|
||||
winit::VirtualKeyCode::Numpad0 => KeyCode::Numpad0,
|
||||
winit::VirtualKeyCode::Numpad1 => KeyCode::Numpad1,
|
||||
winit::VirtualKeyCode::Numpad2 => KeyCode::Numpad2,
|
||||
winit::VirtualKeyCode::Numpad3 => KeyCode::Numpad3,
|
||||
winit::VirtualKeyCode::Numpad4 => KeyCode::Numpad4,
|
||||
winit::VirtualKeyCode::Numpad5 => KeyCode::Numpad5,
|
||||
winit::VirtualKeyCode::Numpad6 => KeyCode::Numpad6,
|
||||
winit::VirtualKeyCode::Numpad7 => KeyCode::Numpad7,
|
||||
winit::VirtualKeyCode::Numpad8 => KeyCode::Numpad8,
|
||||
winit::VirtualKeyCode::Numpad9 => KeyCode::Numpad9,
|
||||
winit::VirtualKeyCode::AbntC1 => KeyCode::AbntC1,
|
||||
winit::VirtualKeyCode::AbntC2 => KeyCode::AbntC2,
|
||||
winit::VirtualKeyCode::Add => KeyCode::Add,
|
||||
winit::VirtualKeyCode::Apostrophe => KeyCode::Apostrophe,
|
||||
winit::VirtualKeyCode::Apps => KeyCode::Apps,
|
||||
winit::VirtualKeyCode::At => KeyCode::At,
|
||||
winit::VirtualKeyCode::Ax => KeyCode::Ax,
|
||||
winit::VirtualKeyCode::Backslash => KeyCode::Backslash,
|
||||
winit::VirtualKeyCode::Calculator => KeyCode::Calculator,
|
||||
winit::VirtualKeyCode::Capital => KeyCode::Capital,
|
||||
winit::VirtualKeyCode::Colon => KeyCode::Colon,
|
||||
winit::VirtualKeyCode::Comma => KeyCode::Comma,
|
||||
winit::VirtualKeyCode::Convert => KeyCode::Convert,
|
||||
winit::VirtualKeyCode::Decimal => KeyCode::Decimal,
|
||||
winit::VirtualKeyCode::Divide => KeyCode::Divide,
|
||||
winit::VirtualKeyCode::Equals => KeyCode::Equals,
|
||||
winit::VirtualKeyCode::Grave => KeyCode::Grave,
|
||||
winit::VirtualKeyCode::Kana => KeyCode::Kana,
|
||||
winit::VirtualKeyCode::Kanji => KeyCode::Kanji,
|
||||
winit::VirtualKeyCode::LAlt => KeyCode::LAlt,
|
||||
winit::VirtualKeyCode::LBracket => KeyCode::LBracket,
|
||||
winit::VirtualKeyCode::LControl => KeyCode::LControl,
|
||||
winit::VirtualKeyCode::LShift => KeyCode::LShift,
|
||||
winit::VirtualKeyCode::LWin => KeyCode::LWin,
|
||||
winit::VirtualKeyCode::Mail => KeyCode::Mail,
|
||||
winit::VirtualKeyCode::MediaSelect => KeyCode::MediaSelect,
|
||||
winit::VirtualKeyCode::MediaStop => KeyCode::MediaStop,
|
||||
winit::VirtualKeyCode::Minus => KeyCode::Minus,
|
||||
winit::VirtualKeyCode::Multiply => KeyCode::Multiply,
|
||||
winit::VirtualKeyCode::Mute => KeyCode::Mute,
|
||||
winit::VirtualKeyCode::MyComputer => KeyCode::MyComputer,
|
||||
winit::VirtualKeyCode::NavigateForward => KeyCode::NavigateForward,
|
||||
winit::VirtualKeyCode::NavigateBackward => KeyCode::NavigateBackward,
|
||||
winit::VirtualKeyCode::NextTrack => KeyCode::NextTrack,
|
||||
winit::VirtualKeyCode::NoConvert => KeyCode::NoConvert,
|
||||
winit::VirtualKeyCode::NumpadComma => KeyCode::NumpadComma,
|
||||
winit::VirtualKeyCode::NumpadEnter => KeyCode::NumpadEnter,
|
||||
winit::VirtualKeyCode::NumpadEquals => KeyCode::NumpadEquals,
|
||||
winit::VirtualKeyCode::OEM102 => KeyCode::OEM102,
|
||||
winit::VirtualKeyCode::Period => KeyCode::Period,
|
||||
winit::VirtualKeyCode::PlayPause => KeyCode::PlayPause,
|
||||
winit::VirtualKeyCode::Power => KeyCode::Power,
|
||||
winit::VirtualKeyCode::PrevTrack => KeyCode::PrevTrack,
|
||||
winit::VirtualKeyCode::RAlt => KeyCode::RAlt,
|
||||
winit::VirtualKeyCode::RBracket => KeyCode::RBracket,
|
||||
winit::VirtualKeyCode::RControl => KeyCode::RControl,
|
||||
winit::VirtualKeyCode::RShift => KeyCode::RShift,
|
||||
winit::VirtualKeyCode::RWin => KeyCode::RWin,
|
||||
winit::VirtualKeyCode::Semicolon => KeyCode::Semicolon,
|
||||
winit::VirtualKeyCode::Slash => KeyCode::Slash,
|
||||
winit::VirtualKeyCode::Sleep => KeyCode::Sleep,
|
||||
winit::VirtualKeyCode::Stop => KeyCode::Stop,
|
||||
winit::VirtualKeyCode::Subtract => KeyCode::Subtract,
|
||||
winit::VirtualKeyCode::Sysrq => KeyCode::Sysrq,
|
||||
winit::VirtualKeyCode::Tab => KeyCode::Tab,
|
||||
winit::VirtualKeyCode::Underline => KeyCode::Underline,
|
||||
winit::VirtualKeyCode::Unlabeled => KeyCode::Unlabeled,
|
||||
winit::VirtualKeyCode::VolumeDown => KeyCode::VolumeDown,
|
||||
winit::VirtualKeyCode::VolumeUp => KeyCode::VolumeUp,
|
||||
winit::VirtualKeyCode::Wake => KeyCode::Wake,
|
||||
winit::VirtualKeyCode::WebBack => KeyCode::WebBack,
|
||||
winit::VirtualKeyCode::WebFavorites => KeyCode::WebFavorites,
|
||||
winit::VirtualKeyCode::WebForward => KeyCode::WebForward,
|
||||
winit::VirtualKeyCode::WebHome => KeyCode::WebHome,
|
||||
winit::VirtualKeyCode::WebRefresh => KeyCode::WebRefresh,
|
||||
winit::VirtualKeyCode::WebSearch => KeyCode::WebSearch,
|
||||
winit::VirtualKeyCode::WebStop => KeyCode::WebStop,
|
||||
winit::VirtualKeyCode::Yen => KeyCode::Yen,
|
||||
winit::VirtualKeyCode::Copy => KeyCode::Copy,
|
||||
winit::VirtualKeyCode::Paste => KeyCode::Paste,
|
||||
winit::VirtualKeyCode::Cut => KeyCode::Cut,
|
||||
}
|
||||
}
|
@ -165,6 +165,25 @@ macro_rules! image_ids {
|
||||
)*
|
||||
};
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! image_ids_ice {
|
||||
($($v:vis struct $Ids:ident { $( <$T:ty> $( $name:ident: $specifier:expr ),* $(,)? )* })*) => {
|
||||
$(
|
||||
$v struct $Ids {
|
||||
$($( $v $name: crate::ui::GraphicId, )*)*
|
||||
}
|
||||
|
||||
impl $Ids {
|
||||
pub fn load(ui: &mut crate::ui::ice::IcedUi) -> Result<Self, common::assets::Error> {
|
||||
use crate::ui::img_ids::GraphicCreator;
|
||||
Ok(Self {
|
||||
$($( $name: ui.add_graphic(<$T as GraphicCreator>::new_graphic($specifier)?), )*)*
|
||||
})
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: combine with the img_ids macro above using a marker for specific fields
|
||||
// that should be `Rotations` instead of `widget::Id`
|
||||
|
@ -7,9 +7,10 @@ mod widgets;
|
||||
pub mod img_ids;
|
||||
#[macro_use]
|
||||
pub mod fonts;
|
||||
pub mod ice;
|
||||
|
||||
pub use event::Event;
|
||||
pub use graphic::{Graphic, SampleStrat, Transform};
|
||||
pub use graphic::{Graphic, Id as GraphicId, Rotation, SampleStrat, Transform};
|
||||
pub use scale::{Scale, ScaleMode};
|
||||
pub use widgets::{
|
||||
image_frame::ImageFrame,
|
||||
@ -36,7 +37,7 @@ use common::{assets, span, util::srgba_to_linear};
|
||||
use conrod_core::{
|
||||
event::Input,
|
||||
graph::{self, Graph},
|
||||
image::{self, Map},
|
||||
image::{Id as ImageId, Map},
|
||||
input::{touch::Touch, Motion, Widget},
|
||||
render::{Primitive, PrimitiveKind},
|
||||
text::{self, font},
|
||||
@ -187,7 +188,7 @@ impl Ui {
|
||||
// Get a copy of Scale
|
||||
pub fn scale(&self) -> Scale { self.scale }
|
||||
|
||||
pub fn add_graphic(&mut self, graphic: Graphic) -> image::Id {
|
||||
pub fn add_graphic(&mut self, graphic: Graphic) -> ImageId {
|
||||
self.image_map
|
||||
.insert((self.cache.add_graphic(graphic), Rotation::None))
|
||||
}
|
||||
@ -212,7 +213,7 @@ impl Ui {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_graphic(&mut self, id: image::Id, graphic: Graphic) {
|
||||
pub fn replace_graphic(&mut self, id: ImageId, graphic: Graphic) {
|
||||
let graphic_id = if let Some((graphic_id, _)) = self.image_map.get(&id) {
|
||||
*graphic_id
|
||||
} else {
|
||||
|
@ -282,6 +282,8 @@ pub enum Event {
|
||||
InputUpdate(GameInput, bool),
|
||||
/// Event that the ui uses.
|
||||
Ui(ui::Event),
|
||||
/// Event that the iced ui uses.
|
||||
IcedUi(ui::ice::Event),
|
||||
/// The view distance has changed.
|
||||
ViewDistanceChanged(u32),
|
||||
/// Game settings have changed.
|
||||
@ -622,12 +624,6 @@ impl Window {
|
||||
Ok((this, event_loop))
|
||||
}
|
||||
|
||||
pub fn window(
|
||||
&self,
|
||||
) -> &glutin::ContextWrapper<glutin::PossiblyCurrent, winit::window::Window> {
|
||||
&self.window
|
||||
}
|
||||
|
||||
pub fn renderer(&self) -> &Renderer { &self.renderer }
|
||||
|
||||
pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer }
|
||||
@ -1377,6 +1373,8 @@ impl Window {
|
||||
pub fn set_keybinding_mode(&mut self, game_input: GameInput) {
|
||||
self.remapping_keybindings = Some(game_input);
|
||||
}
|
||||
|
||||
pub fn window(&self) -> &winit::Window { self.window.window() }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||
|
Loading…
Reference in New Issue
Block a user