Compare commits
7 commits
420092133f
...
85afd978ac
Author | SHA1 | Date | |
---|---|---|---|
85afd978ac | |||
792e06abdc | |||
e0dc572580 | |||
9c0250e1f6 | |||
20332deb41 | |||
be69061dd9 | |||
304a29397b |
8 changed files with 53 additions and 19 deletions
|
@ -5,7 +5,7 @@ authors = ["hodasemi <michaelh.95@t-online.de>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quick-xml = "0.31.0"
|
quick-xml = "0.37.0"
|
||||||
serde = { version = "1.0.203", features = ["derive"] }
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
serde_json = { version = "1.0.120" }
|
serde_json = { version = "1.0.120" }
|
||||||
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
||||||
|
|
|
@ -135,9 +135,9 @@ impl ButtonBuilder {
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let click_executable = Executable::new();
|
let click_executable = Executable::new(&gui_handler);
|
||||||
let select_executable = Executable::new();
|
let select_executable = Executable::new(&gui_handler);
|
||||||
let on_select_executable = Executable::new();
|
let on_select_executable = Executable::new(&gui_handler);
|
||||||
|
|
||||||
#[cfg(feature = "audio")]
|
#[cfg(feature = "audio")]
|
||||||
let click_sound = self
|
let click_sound = self
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use assetpath::AssetPath;
|
||||||
use utilities::prelude::*;
|
use utilities::prelude::*;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
|
@ -142,6 +143,10 @@ impl Icon {
|
||||||
self.iconizable_wrapper.set_icon(icon, self.visible())
|
self.iconizable_wrapper.set_icon(icon, self.visible())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_icon_from_path(&self, asset_path: AssetPath) -> Result<()> {
|
||||||
|
self.iconizable_wrapper.set_icon(asset_path, self.visible())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_margin(&self, margin: u32) -> Result<()> {
|
pub fn set_margin(&self, margin: u32) -> Result<()> {
|
||||||
self.iconizable_wrapper.set_margin(margin)
|
self.iconizable_wrapper.set_margin(margin)
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl MultiLineTextFieldBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = Arc::new(SplittedText::new(self.text));
|
let text = Arc::new(SplittedText::new(self.text));
|
||||||
let text_changed_exec = Executable::new();
|
let text_changed_exec = Executable::new(&gui_handler);
|
||||||
let writeable = Writeable::new(gui_handler, text.clone(), text_changed_exec.clone())?;
|
let writeable = Writeable::new(gui_handler, text.clone(), text_changed_exec.clone())?;
|
||||||
|
|
||||||
let multi_line_text_field = Arc::new(MultiLineTextField {
|
let multi_line_text_field = Arc::new(MultiLineTextField {
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl TextFieldBuilder {
|
||||||
self.text_color,
|
self.text_color,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let text_changed_executable = Executable::new();
|
let text_changed_executable = Executable::new(&gui_handler);
|
||||||
|
|
||||||
let writeable = Writeable::new(
|
let writeable = Writeable::new(
|
||||||
gui_handler,
|
gui_handler,
|
||||||
|
|
|
@ -4,15 +4,19 @@ use anyhow::Result;
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// `Executable` holds a closure which can be executed
|
/// `Executable` holds a closure which can be executed
|
||||||
pub struct Executable<I> {
|
pub struct Executable<I: Send + Sync + 'static> {
|
||||||
callback: RwLock<Option<Box<dyn Fn(I) -> Result<()> + Send + Sync>>>,
|
gui_handler: Arc<GuiHandler>,
|
||||||
|
callback: RwLock<Option<Arc<dyn Fn(I) -> Result<()> + Send + Sync>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> Executable<I> {
|
impl<I: Send + Sync + 'static> Executable<I> {
|
||||||
/// Factory method for `Executable`, returns `Arc<Executable>`
|
/// Factory method for `Executable`, returns `Arc<Executable>`
|
||||||
pub fn new() -> Arc<Self> {
|
pub fn new(gui_handler: &Arc<GuiHandler>) -> Arc<Self> {
|
||||||
Arc::new(Executable {
|
Arc::new(Executable {
|
||||||
|
gui_handler: gui_handler.clone(),
|
||||||
callback: RwLock::new(None),
|
callback: RwLock::new(None),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -29,7 +33,7 @@ impl<I> Executable<I> {
|
||||||
let mut function = self.callback.write().unwrap();
|
let mut function = self.callback.write().unwrap();
|
||||||
|
|
||||||
match callback.into() {
|
match callback.into() {
|
||||||
Some(f) => *function = Some(Box::new(f)),
|
Some(f) => *function = Some(Arc::new(f)),
|
||||||
None => *function = None,
|
None => *function = None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +41,9 @@ impl<I> Executable<I> {
|
||||||
/// Execute the callback closure if possible
|
/// Execute the callback closure if possible
|
||||||
pub fn execute(&self, input: I) -> Result<()> {
|
pub fn execute(&self, input: I) -> Result<()> {
|
||||||
if let Some(callback) = self.callback.read().unwrap().as_ref() {
|
if let Some(callback) = self.callback.read().unwrap().as_ref() {
|
||||||
(callback)(input)?;
|
let callback = callback.clone();
|
||||||
|
|
||||||
|
self.gui_handler.add_callback(move || (callback)(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -14,12 +14,12 @@ use super::{
|
||||||
|
|
||||||
use cgmath::{ortho, vec2};
|
use cgmath::{ortho, vec2};
|
||||||
|
|
||||||
use std::sync::Weak;
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
|
atomic::{AtomicBool, AtomicU32, Ordering::SeqCst},
|
||||||
Arc, Mutex, RwLock,
|
Arc, Mutex, RwLock,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, ptr};
|
use std::{collections::HashMap, ptr};
|
||||||
|
use std::{mem, sync::Weak};
|
||||||
|
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ impl TextToScreen {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GuiHandler {
|
pub struct GuiHandler {
|
||||||
context: Arc<dyn ContextInterface>,
|
_context: Arc<dyn ContextInterface>,
|
||||||
|
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue: Arc<Mutex<Queue>>,
|
queue: Arc<Mutex<Queue>>,
|
||||||
|
@ -257,6 +257,8 @@ pub struct GuiHandler {
|
||||||
current_selectable: RwLock<Option<Arc<Selectable>>>,
|
current_selectable: RwLock<Option<Arc<Selectable>>>,
|
||||||
|
|
||||||
text_sample_count: VkSampleCountFlags,
|
text_sample_count: VkSampleCountFlags,
|
||||||
|
|
||||||
|
callback_list: Mutex<Vec<Box<dyn FnOnce() -> Result<()> + Send + Sync>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GuiHandler {
|
impl GuiHandler {
|
||||||
|
@ -309,7 +311,7 @@ impl GuiHandler {
|
||||||
.build(device.clone())?;
|
.build(device.clone())?;
|
||||||
|
|
||||||
Ok(Arc::new(GuiHandler {
|
Ok(Arc::new(GuiHandler {
|
||||||
context: context.clone(),
|
_context: context.clone(),
|
||||||
|
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
queue: queue.clone(),
|
queue: queue.clone(),
|
||||||
|
@ -403,6 +405,8 @@ impl GuiHandler {
|
||||||
current_writeable: RwLock::new(None),
|
current_writeable: RwLock::new(None),
|
||||||
|
|
||||||
text_sample_count,
|
text_sample_count,
|
||||||
|
|
||||||
|
callback_list: Mutex::default(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +420,7 @@ impl GuiHandler {
|
||||||
|
|
||||||
#[cfg(feature = "audio")]
|
#[cfg(feature = "audio")]
|
||||||
pub(crate) fn context(&self) -> &Arc<dyn ContextInterface> {
|
pub(crate) fn context(&self) -> &Arc<dyn ContextInterface> {
|
||||||
&self.context
|
&self._context
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn width(&self) -> u32 {
|
pub fn width(&self) -> u32 {
|
||||||
|
@ -881,6 +885,16 @@ impl GuiHandler {
|
||||||
*self.tooltip_ui.write().unwrap() = tooltip;
|
*self.tooltip_ui.write().unwrap() = tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_callback<F: FnOnce() -> Result<()> + Send + Sync + 'static>(&self, f: F) {
|
||||||
|
self.callback_list.lock().unwrap().push(Box::new(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_callbacks(&self) -> Result<()> {
|
||||||
|
let callbacks = mem::take(&mut *self.callback_list.lock().unwrap());
|
||||||
|
|
||||||
|
callbacks.into_iter().try_for_each(|callback| callback())
|
||||||
|
}
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||||
|
@ -1657,9 +1671,13 @@ impl GuiHandler {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&self, width: u32, height: u32) -> Result<()> {
|
pub fn resize(
|
||||||
self.context
|
&self,
|
||||||
.images()
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
images: &TargetMode<Vec<Arc<Image>>>,
|
||||||
|
) -> Result<()> {
|
||||||
|
images
|
||||||
.chain(&self.render_targets)
|
.chain(&self.render_targets)
|
||||||
.execute(|(images, render_target)| {
|
.execute(|(images, render_target)| {
|
||||||
let mut rt_lock = render_target.write().unwrap();
|
let mut rt_lock = render_target.write().unwrap();
|
||||||
|
|
|
@ -238,6 +238,11 @@ impl States {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// lists available states
|
||||||
|
pub fn states(&self) -> impl Iterator<Item = &str> {
|
||||||
|
self.states.keys().map(|s| s.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds a single state
|
/// Adds a single state
|
||||||
pub fn add_state<'a>(
|
pub fn add_state<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
Loading…
Reference in a new issue