Compare commits
3 commits
0d4ee1455b
...
c5286a3340
Author | SHA1 | Date | |
---|---|---|---|
c5286a3340 | |||
|
afc101effc | ||
|
0976860b9f |
14 changed files with 659 additions and 616 deletions
|
@ -8,11 +8,13 @@ edition = "2024"
|
|||
quick-xml = "0.37.0"
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
serde_json = { version = "1.0.120" }
|
||||
paste = "1.0.15"
|
||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||
|
||||
vulkan-rs = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
||||
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }
|
||||
paste = "1.0.15"
|
||||
assetpath = { git = "https://gavania.de/hodasemi/vulkan_lib.git" }
|
||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||
ecs = { git = "https://gavania.de/hodasemi/engine.git" }
|
||||
|
||||
# optional
|
||||
audio = { git = "https://gavania.de/hodasemi/audio.git", optional = true }
|
||||
|
|
|
@ -55,20 +55,6 @@ impl<T> TargetMode<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn chain<'a, R>(&'a self, other: &'a TargetMode<R>) -> TargetMode<(&'a T, &'a R)> {
|
||||
match (self, other) {
|
||||
(TargetMode::Mono(mono_self), TargetMode::Mono(mono_other)) => {
|
||||
TargetMode::Mono((mono_self, mono_other))
|
||||
}
|
||||
(
|
||||
TargetMode::Stereo(left_self, right_self),
|
||||
TargetMode::Stereo(left_other, right_other),
|
||||
) => TargetMode::Stereo((left_self, left_other), (right_self, right_other)),
|
||||
|
||||
_ => panic!("Incompatible TargetModes"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute<F, R>(&self, mut f: F) -> anyhow::Result<TargetMode<R>>
|
||||
where
|
||||
F: FnMut(&T) -> anyhow::Result<R>,
|
||||
|
@ -90,6 +76,56 @@ impl<T> TargetMode<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Chain<'a, R, T> {
|
||||
fn chain(&'a self, other: &'a TargetMode<T>) -> TargetMode<(&'a R, &'a T)>;
|
||||
fn chain_mut_1(&'a mut self, other: &'a TargetMode<T>) -> TargetMode<(&'a mut R, &'a T)>;
|
||||
fn chain_mut_2(&'a self, other: &'a mut TargetMode<T>) -> TargetMode<(&'a R, &'a mut T)>;
|
||||
}
|
||||
|
||||
impl<'a, R, T> Chain<'a, R, T> for TargetMode<R> {
|
||||
fn chain(&'a self, other: &'a TargetMode<T>) -> TargetMode<(&'a R, &'a T)> {
|
||||
match (self, other) {
|
||||
(TargetMode::Mono(mono_self), TargetMode::Mono(mono_other)) => {
|
||||
TargetMode::Mono((mono_self, mono_other))
|
||||
}
|
||||
(
|
||||
TargetMode::Stereo(left_self, right_self),
|
||||
TargetMode::Stereo(left_other, right_other),
|
||||
) => TargetMode::Stereo((left_self, left_other), (right_self, right_other)),
|
||||
|
||||
_ => panic!("Incompatible TargetModes"),
|
||||
}
|
||||
}
|
||||
|
||||
fn chain_mut_1(&'a mut self, other: &'a TargetMode<T>) -> TargetMode<(&'a mut R, &'a T)> {
|
||||
match (self, other) {
|
||||
(TargetMode::Mono(mono_self), TargetMode::Mono(mono_other)) => {
|
||||
TargetMode::Mono((mono_self, mono_other))
|
||||
}
|
||||
(
|
||||
TargetMode::Stereo(left_self, right_self),
|
||||
TargetMode::Stereo(left_other, right_other),
|
||||
) => TargetMode::Stereo((left_self, left_other), (right_self, right_other)),
|
||||
|
||||
_ => panic!("Incompatible TargetModes"),
|
||||
}
|
||||
}
|
||||
|
||||
fn chain_mut_2(&'a self, other: &'a mut TargetMode<T>) -> TargetMode<(&'a R, &'a mut T)> {
|
||||
match (self, other) {
|
||||
(TargetMode::Mono(mono_self), TargetMode::Mono(mono_other)) => {
|
||||
TargetMode::Mono((mono_self, mono_other))
|
||||
}
|
||||
(
|
||||
TargetMode::Stereo(left_self, right_self),
|
||||
TargetMode::Stereo(left_other, right_other),
|
||||
) => TargetMode::Stereo((left_self, left_other), (right_self, right_other)),
|
||||
|
||||
_ => panic!("Incompatible TargetModes"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Unfold {
|
||||
type Output;
|
||||
|
||||
|
@ -104,9 +140,33 @@ macro_rules! impl_unfold {
|
|||
|
||||
fn unfold(self) -> Self::Output {
|
||||
match self {
|
||||
TargetMode::Mono( (($($var,)+), $rhs_var) ) => TargetMode::Mono(($($var,)+ &$rhs_var)),
|
||||
TargetMode::Mono( (($($var,)+), $rhs_var) ) => TargetMode::Mono(($($var,)+ $rhs_var)),
|
||||
TargetMode::Stereo( ( ( $( [<l_ $var>], )+ ) , [<l_ $rhs_var>] ), ( ( $( [<r_ $var>], )+ ) , [<r_ $rhs_var>] ) )
|
||||
=> TargetMode::Stereo( ( $( [<l_ $var>], )+ &[<l_ $rhs_var>] ), ( $( [<r_ $var>], )+ &[<r_ $rhs_var>] ) ),
|
||||
=> TargetMode::Stereo( ( $( [<l_ $var>], )+ [<l_ $rhs_var>] ), ( $( [<r_ $var>], )+ [<r_ $rhs_var>] ) ),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, $($type,)+ $rhs_type: 'a> Unfold for TargetMode<(&'a mut ($($type,)+), &'a $rhs_type)> {
|
||||
type Output = TargetMode<($(&'a mut $type,)+ &'a $rhs_type)>;
|
||||
|
||||
fn unfold(self) -> Self::Output {
|
||||
match self {
|
||||
TargetMode::Mono( (($($var,)+), $rhs_var) ) => TargetMode::Mono(($($var,)+ $rhs_var)),
|
||||
TargetMode::Stereo( ( ( $( [<l_ $var>], )+ ) , [<l_ $rhs_var>] ), ( ( $( [<r_ $var>], )+ ) , [<r_ $rhs_var>] ) )
|
||||
=> TargetMode::Stereo( ( $( [<l_ $var>], )+ [<l_ $rhs_var>] ), ( $( [<r_ $var>], )+ [<r_ $rhs_var>] ) ),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, $($type,)+ $rhs_type: 'a> Unfold for TargetMode<(&'a ($($type,)+), &'a mut $rhs_type)> {
|
||||
type Output = TargetMode<($(&'a $type,)+ &'a mut $rhs_type)>;
|
||||
|
||||
fn unfold(self) -> Self::Output {
|
||||
match self {
|
||||
TargetMode::Mono( (($($var,)+), $rhs_var) ) => TargetMode::Mono(($($var,)+ $rhs_var)),
|
||||
TargetMode::Stereo( ( ( $( [<l_ $var>], )+ ) , [<l_ $rhs_var>] ), ( ( $( [<r_ $var>], )+ ) , [<r_ $rhs_var>] ) )
|
||||
=> TargetMode::Stereo( ( $( [<l_ $var>], )+ [<l_ $rhs_var>] ), ( $( [<r_ $var>], )+ [<r_ $rhs_var>] ) ),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,14 @@ use anyhow::Result;
|
|||
|
||||
use super::executable::Executable;
|
||||
use super::framable::Framable;
|
||||
use crate::prelude::*;
|
||||
|
||||
#[cfg(feature = "audio")]
|
||||
use super::audible::Audible;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
|
||||
Arc, RwLock,
|
||||
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
|
||||
};
|
||||
|
||||
/// `Clickable` gives the ability to execute a closure when clicked
|
||||
|
@ -54,12 +55,8 @@ impl Clickable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `clickable` is a `&Arc<Clickable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.add_clickable(self.ui_layer.load(SeqCst), self.clone())?;
|
||||
|
||||
Ok(())
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_clickable(self.ui_layer.load(SeqCst), self.clone())
|
||||
}
|
||||
|
||||
/// Delete method, has to be explicitly called, otherwise it will remain in memory
|
||||
|
@ -67,11 +64,9 @@ impl Clickable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `clickable` is a `&Arc<Clickable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.delete_clickable(self.ui_layer.load(SeqCst), self)?;
|
||||
self.set_clicked(false)?;
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_clickable(self.ui_layer.load(SeqCst), self)?;
|
||||
self.set_clicked(gui_handler, false)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -104,7 +99,7 @@ impl Clickable {
|
|||
*self.audible.write().unwrap() = audible;
|
||||
}
|
||||
|
||||
pub fn set_clicked(&self, clicked: bool) -> Result<bool> {
|
||||
pub fn set_clicked(&self, gui_handler: &mut GuiHandler<'_>, clicked: bool) -> Result<bool> {
|
||||
if self.clicked() != clicked {
|
||||
self.clicked.store(clicked, SeqCst);
|
||||
|
||||
|
@ -122,7 +117,7 @@ impl Clickable {
|
|||
}
|
||||
}
|
||||
|
||||
self.executable.execute(())?;
|
||||
self.executable.execute(gui_handler, ())?;
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use crate::prelude::*;
|
||||
use anyhow::Result;
|
||||
|
||||
use utilities::{impl_reprc, prelude::*};
|
||||
use vulkan_rs::prelude::*;
|
||||
|
||||
|
@ -33,17 +34,18 @@ pub struct Colorable {
|
|||
impl Colorable {
|
||||
/// Factory method for `Colorable`, returns `Arc<Colorable>`.
|
||||
pub fn new(
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
framable: Arc<Framable>,
|
||||
color: Color,
|
||||
fill_type: DisplayableFillType,
|
||||
) -> Result<Arc<Self>> {
|
||||
let set = framable.gui_handler().color_descriptor(color)?;
|
||||
let set = gui_handler.color_descriptor(color)?;
|
||||
|
||||
let buffer = Buffer::builder()
|
||||
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||||
.set_memory_usage(MemoryUsage::CpuOnly)
|
||||
.set_size(6)
|
||||
.build(framable.gui_handler().device().clone())?;
|
||||
.build(gui_handler.device().clone())?;
|
||||
|
||||
let colorable = Arc::new(Colorable {
|
||||
framable,
|
||||
|
@ -67,7 +69,7 @@ impl Colorable {
|
|||
|
||||
colorable.framable.add_callback(
|
||||
weak_colorable,
|
||||
Box::new(move || colorable_clone.update_frame()),
|
||||
Box::new(move |gui_handler| colorable_clone.update_frame(gui_handler)),
|
||||
);
|
||||
|
||||
Ok(colorable)
|
||||
|
@ -78,10 +80,8 @@ impl Colorable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `colorable` is a `&Arc<Colorable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.add_colorable(self.ui_layer.load(SeqCst), self.clone())
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_colorable(self.ui_layer.load(SeqCst), self.clone())
|
||||
}
|
||||
|
||||
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
|
||||
|
@ -89,10 +89,8 @@ impl Colorable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `colorable` is a `&Arc<Colorable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.delete_colorable(self.ui_layer.load(SeqCst), self)
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_colorable(self.ui_layer.load(SeqCst), self)
|
||||
}
|
||||
|
||||
pub fn clear_callback(self: &Arc<Self>) {
|
||||
|
@ -109,8 +107,8 @@ impl Colorable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `color` defines the color
|
||||
pub fn set_color(&self, color: Color) -> Result<()> {
|
||||
let set = self.framable.gui_handler().color_descriptor(color)?;
|
||||
pub fn set_color(&self, color: Color, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
let set = gui_handler.color_descriptor(color)?;
|
||||
|
||||
*self.color.write().unwrap() = color;
|
||||
*self.descriptor_set.write().unwrap() = set;
|
||||
|
@ -149,7 +147,7 @@ impl Colorable {
|
|||
}
|
||||
|
||||
/// Update frame method if the original frame is invalidated
|
||||
pub fn update_frame(&self) -> Result<()> {
|
||||
pub fn update_frame(&self, gui_handler: &GuiHandler<'_>) -> Result<()> {
|
||||
let mut frame = self.buffer.map_complete()?;
|
||||
|
||||
let mut x_start = self.framable.left() as f32;
|
||||
|
@ -177,12 +175,12 @@ impl Colorable {
|
|||
let top = y_start + height * *self.top_factor.read().unwrap();
|
||||
let bottom = y_start + height * *self.bottom_factor.read().unwrap();
|
||||
|
||||
frame[0].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
frame[1].position = (self.framable.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
|
||||
frame[2].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[3].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[4].position = (self.framable.ortho() * vec4(left, top, 0.0, 1.0)).xy();
|
||||
frame[5].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
frame[0].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
frame[1].position = (gui_handler.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
|
||||
frame[2].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[3].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[4].position = (gui_handler.ortho() * vec4(left, top, 0.0, 1.0)).xy();
|
||||
frame[5].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -71,18 +71,17 @@ impl Displayable {
|
|||
/// * `framable` is a `Arc<Framable>` instance
|
||||
/// * `name` is the name for a png
|
||||
pub fn new(
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
framable: Arc<Framable>,
|
||||
displayable_type: impl Into<DisplayableType>,
|
||||
fill_type: DisplayableFillType,
|
||||
) -> Result<Arc<Self>> {
|
||||
let descriptor_set = framable.gui_handler().image_descriptor_set()?;
|
||||
let descriptor_set = gui_handler.image_descriptor_set()?;
|
||||
|
||||
let displayable_type = displayable_type.into();
|
||||
|
||||
if let DisplayableType::Path(path) = &displayable_type {
|
||||
let texture = framable
|
||||
.gui_handler()
|
||||
.displayable_image_from_path(path.clone())?;
|
||||
let texture = gui_handler.displayable_image_from_path(path.clone())?;
|
||||
descriptor_set.update(&[DescriptorWrite::combined_samplers(0, &[&texture])])?;
|
||||
}
|
||||
|
||||
|
@ -90,7 +89,7 @@ impl Displayable {
|
|||
.set_usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||||
.set_memory_usage(MemoryUsage::CpuOnly)
|
||||
.set_size(6)
|
||||
.build(framable.gui_handler().device().clone())?;
|
||||
.build(gui_handler.device().clone())?;
|
||||
|
||||
let displayable = Arc::new(Displayable {
|
||||
framable,
|
||||
|
@ -118,7 +117,7 @@ impl Displayable {
|
|||
|
||||
displayable.framable.add_callback(
|
||||
weak_displayable,
|
||||
Box::new(move || displayable_clone.update_frame()),
|
||||
Box::new(move |gui_handler| displayable_clone.update_frame(gui_handler)),
|
||||
);
|
||||
|
||||
Ok(displayable)
|
||||
|
@ -129,10 +128,8 @@ impl Displayable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `displayable` is a `&Arc<Displayable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.add_displayable(self.ui_layer.load(SeqCst), self.clone())
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_displayable(self.ui_layer.load(SeqCst), self.clone())
|
||||
}
|
||||
|
||||
/// Delete method, has to be explicitly called, otherwise it will remain in memory
|
||||
|
@ -140,10 +137,8 @@ impl Displayable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `displayable` is a `&Arc<Displayable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.delete_displayable(self.ui_layer.load(SeqCst), self)
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_displayable(self.ui_layer.load(SeqCst), self)
|
||||
}
|
||||
|
||||
pub fn inner_type(&self) -> DisplayableType {
|
||||
|
@ -164,25 +159,21 @@ impl Displayable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `name` is the name of the texture in `gui/` without `.png` suffix
|
||||
pub fn set_image(&self, displayable_type: impl Into<DisplayableType>) -> Result<()> {
|
||||
pub fn set_image(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
displayable_type: impl Into<DisplayableType>,
|
||||
) -> Result<()> {
|
||||
let displayable_type = displayable_type.into();
|
||||
|
||||
let texture = match displayable_type.clone() {
|
||||
DisplayableType::Path(path) => Some(
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.displayable_image_from_path(path)?,
|
||||
),
|
||||
DisplayableType::Path(path) => Some(gui_handler.displayable_image_from_path(path)?),
|
||||
DisplayableType::Descriptor(descriptor) => {
|
||||
let width = (self.framable.right() - self.framable.left()) as u32;
|
||||
let height = (self.framable.bottom() - self.framable.top()) as u32;
|
||||
|
||||
if width > 0 && height > 0 {
|
||||
Some(
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.displayable_image_from_descriptor(width, height, descriptor)?,
|
||||
)
|
||||
Some(gui_handler.displayable_image_from_descriptor(width, height, descriptor)?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -242,7 +233,7 @@ impl Displayable {
|
|||
}
|
||||
|
||||
/// Update frame method if the original frame is invalidated
|
||||
pub fn update_frame(&self) -> Result<()> {
|
||||
pub fn update_frame(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
let mut frame = self.buffer.map_complete()?;
|
||||
|
||||
let mut x_start = self.framable.left() as f32;
|
||||
|
@ -267,14 +258,11 @@ impl Displayable {
|
|||
|
||||
if let DisplayableType::Descriptor(descriptor) = &*self.displayable_type.read().unwrap() {
|
||||
if width > 0.0 && height > 0.0 {
|
||||
let texture = self
|
||||
.framable
|
||||
.gui_handler()
|
||||
.displayable_image_from_descriptor(
|
||||
width as u32,
|
||||
height as u32,
|
||||
descriptor.clone(),
|
||||
)?;
|
||||
let texture = gui_handler.displayable_image_from_descriptor(
|
||||
width as u32,
|
||||
height as u32,
|
||||
descriptor.clone(),
|
||||
)?;
|
||||
|
||||
self.descriptor_set
|
||||
.update(&[DescriptorWrite::combined_samplers(0, &[&texture])])?;
|
||||
|
@ -286,12 +274,12 @@ impl Displayable {
|
|||
let top = y_start + height * *self.top_factor.read().unwrap();
|
||||
let bottom = y_start + height * *self.bottom_factor.read().unwrap();
|
||||
|
||||
frame[0].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
frame[1].position = (self.framable.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
|
||||
frame[2].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[3].position = (self.framable.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[4].position = (self.framable.ortho() * vec4(left, top, 0.0, 1.0)).xy();
|
||||
frame[5].position = (self.framable.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
frame[0].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
frame[1].position = (gui_handler.ortho() * vec4(right, bottom, 0.0, 1.0)).xy();
|
||||
frame[2].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[3].position = (gui_handler.ortho() * vec4(right, top, 0.0, 1.0)).xy();
|
||||
frame[4].position = (gui_handler.ortho() * vec4(left, top, 0.0, 1.0)).xy();
|
||||
frame[5].position = (gui_handler.ortho() * vec4(left, bottom, 0.0, 1.0)).xy();
|
||||
|
||||
frame[0].texture_coordinates = vec2(
|
||||
*self.left_uv_factor.read().unwrap(),
|
||||
|
|
|
@ -8,15 +8,13 @@ use crate::prelude::*;
|
|||
|
||||
/// `Executable` holds a closure which can be executed
|
||||
pub struct Executable<I: Send + Sync + 'static> {
|
||||
gui_handler: Arc<GuiHandler>,
|
||||
callback: RwLock<Option<Arc<dyn Fn(I) -> Result<()> + Send + Sync>>>,
|
||||
}
|
||||
|
||||
impl<I: Send + Sync + 'static> Executable<I> {
|
||||
/// Factory method for `Executable`, returns `Arc<Executable>`
|
||||
pub fn new(gui_handler: &Arc<GuiHandler>) -> Arc<Self> {
|
||||
pub fn new() -> Arc<Self> {
|
||||
Arc::new(Executable {
|
||||
gui_handler: gui_handler.clone(),
|
||||
callback: RwLock::new(None),
|
||||
})
|
||||
}
|
||||
|
@ -39,11 +37,11 @@ impl<I: Send + Sync + 'static> Executable<I> {
|
|||
}
|
||||
|
||||
/// Execute the callback closure if possible
|
||||
pub fn execute(&self, input: I) -> Result<()> {
|
||||
pub fn execute(&self, gui_handler: &mut GuiHandler<'_>, input: I) -> Result<()> {
|
||||
if let Some(callback) = self.callback.read().unwrap().as_ref() {
|
||||
let callback = callback.clone();
|
||||
|
||||
self.gui_handler.add_callback(move || (callback)(input));
|
||||
gui_handler.add_callback(move || (callback)(input));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -6,13 +6,11 @@ use anyhow::Result;
|
|||
use std::{
|
||||
ffi::c_void,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicI32, AtomicU32, Ordering::SeqCst},
|
||||
Arc, RwLock, Weak,
|
||||
atomic::{AtomicBool, AtomicI32, AtomicU32, Ordering::SeqCst},
|
||||
},
|
||||
};
|
||||
|
||||
use vulkan_rs::prelude::cgmath::Matrix4;
|
||||
|
||||
/// Describes the vertical alignment for a `Framable`
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum VerticalAlign {
|
||||
|
@ -77,8 +75,6 @@ impl Drop for Handle {
|
|||
/// `Framable` keeps track of the position and size of an item
|
||||
/// and calls functions on resize to keep everything aligned correctly
|
||||
pub struct Framable {
|
||||
gui_handler: Arc<GuiHandler>,
|
||||
|
||||
left: AtomicI32,
|
||||
right: AtomicI32,
|
||||
top: AtomicI32,
|
||||
|
@ -87,7 +83,12 @@ pub struct Framable {
|
|||
vertical_alignment: RwLock<VerticalAlign>,
|
||||
horizontal_alignment: RwLock<HorizontalAlign>,
|
||||
|
||||
resize_callbacks: RwLock<Vec<(Handle, Box<dyn Fn() -> Result<()> + Send + Sync>)>>,
|
||||
resize_callbacks: RwLock<
|
||||
Vec<(
|
||||
Handle,
|
||||
Box<dyn Fn(&mut GuiHandler<'_>) -> Result<()> + Send + Sync>,
|
||||
)>,
|
||||
>,
|
||||
|
||||
x_off: AtomicI32,
|
||||
y_off: AtomicI32,
|
||||
|
@ -111,12 +112,10 @@ pub struct Framable {
|
|||
|
||||
impl Framable {
|
||||
/// Factory method for `Framable`, returns `Arc<Framable>`
|
||||
pub fn new(gui_handler: Arc<GuiHandler>, resize_allowed: bool) -> Result<Arc<Self>> {
|
||||
pub fn new(window_width: u32, window_height: u32, resize_allowed: bool) -> Result<Arc<Self>> {
|
||||
Ok(Arc::new(Framable {
|
||||
window_width: AtomicU32::new(gui_handler.width()),
|
||||
window_height: AtomicU32::new(gui_handler.height()),
|
||||
|
||||
gui_handler,
|
||||
window_width: AtomicU32::new(window_width),
|
||||
window_height: AtomicU32::new(window_height),
|
||||
|
||||
left: AtomicI32::new(0),
|
||||
right: AtomicI32::new(0),
|
||||
|
@ -150,22 +149,21 @@ impl Framable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `framable` - is a `&Arc<Framable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
// check if window size is the same as last time
|
||||
if self.gui_handler.width() != self.window_width.load(SeqCst)
|
||||
|| self.gui_handler.height() != self.window_height.load(SeqCst)
|
||||
if gui_handler.width() != self.window_width.load(SeqCst)
|
||||
|| gui_handler.height() != self.window_height.load(SeqCst)
|
||||
{
|
||||
// update window size
|
||||
self.window_width.store(self.gui_handler.width(), SeqCst);
|
||||
self.window_height.store(self.gui_handler.height(), SeqCst);
|
||||
self.window_width.store(gui_handler.width(), SeqCst);
|
||||
self.window_height.store(gui_handler.height(), SeqCst);
|
||||
|
||||
// force resize
|
||||
self.resize()?;
|
||||
self.resize(gui_handler)?;
|
||||
}
|
||||
|
||||
if self.resize_allowed() {
|
||||
self.gui_handler
|
||||
.add_framable(self.ui_layer.load(SeqCst), self.clone())?;
|
||||
gui_handler.add_framable(self.ui_layer.load(SeqCst), self.clone())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -176,10 +174,9 @@ impl Framable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `framable` - is a `&Arc<Framable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
if self.resize_allowed() {
|
||||
self.gui_handler
|
||||
.delete_framable(self.ui_layer.load(SeqCst), self)?;
|
||||
gui_handler.delete_framable(self.ui_layer.load(SeqCst), self)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -193,36 +190,49 @@ impl Framable {
|
|||
self.ui_layer.load(SeqCst)
|
||||
}
|
||||
|
||||
pub(crate) fn set_reference_size(&self, width: u32, height: u32) -> Result<()> {
|
||||
pub(crate) fn set_reference_size(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Result<()> {
|
||||
*self.reference_size.write().unwrap() = Some((width, height));
|
||||
self.reference_scale_position.store(true, SeqCst);
|
||||
self.reference_scale_size.store(true, SeqCst);
|
||||
|
||||
if self.is_framed() {
|
||||
self.resize()?;
|
||||
self.resize(gui_handler)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn allow_position_scale(&self, allowed: bool) -> Result<()> {
|
||||
pub(crate) fn allow_position_scale(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
allowed: bool,
|
||||
) -> Result<()> {
|
||||
if allowed != self.reference_scale_position.load(SeqCst) {
|
||||
self.reference_scale_position.store(allowed, SeqCst);
|
||||
|
||||
if self.is_framed() {
|
||||
self.resize()?;
|
||||
self.resize(gui_handler)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn allow_size_scale(&self, allowed: bool) -> Result<()> {
|
||||
pub(crate) fn allow_size_scale(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
allowed: bool,
|
||||
) -> Result<()> {
|
||||
if allowed != self.reference_scale_size.load(SeqCst) {
|
||||
self.reference_scale_size.store(allowed, SeqCst);
|
||||
|
||||
if self.is_framed() {
|
||||
self.resize()?;
|
||||
self.resize(gui_handler)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,6 +247,7 @@ impl Framable {
|
|||
/// width and a certain alignment
|
||||
pub fn set_frame(
|
||||
&self,
|
||||
gui_handler: &GuiHandler<'_>,
|
||||
x_off: i32,
|
||||
y_off: i32,
|
||||
w: u32,
|
||||
|
@ -252,7 +263,7 @@ impl Framable {
|
|||
*self.vertical_alignment.write().unwrap() = vertical_align;
|
||||
*self.horizontal_alignment.write().unwrap() = horizontal_align;
|
||||
|
||||
self.calculate_frame();
|
||||
self.calculate_frame(gui_handler);
|
||||
|
||||
self.framed.store(true, SeqCst);
|
||||
}
|
||||
|
@ -296,16 +307,11 @@ impl Framable {
|
|||
self.framed.load(SeqCst)
|
||||
}
|
||||
|
||||
/// Returns the ortho 4x4 matrix, which describes the window
|
||||
pub fn ortho(&self) -> Matrix4<f32> {
|
||||
self.gui_handler.ortho()
|
||||
}
|
||||
|
||||
/// Adds a callback closure which is executed on resize
|
||||
pub fn add_callback(
|
||||
&self,
|
||||
handle: impl Into<Handle>,
|
||||
callback: Box<dyn Fn() -> Result<()> + Send + Sync>,
|
||||
callback: Box<dyn Fn(&mut GuiHandler<'_>) -> Result<()> + Send + Sync>,
|
||||
) {
|
||||
let handle = handle.into();
|
||||
|
||||
|
@ -348,9 +354,9 @@ impl Framable {
|
|||
*self.horizontal_alignment.read().unwrap()
|
||||
}
|
||||
|
||||
fn calculate_frame(&self) {
|
||||
let width = self.gui_handler.width();
|
||||
let height = self.gui_handler.height();
|
||||
fn calculate_frame(&self, gui_handler: &GuiHandler<'_>) {
|
||||
let width = gui_handler.width();
|
||||
let height = gui_handler.height();
|
||||
|
||||
let y_align = match *self.vertical_alignment.read().unwrap() {
|
||||
VerticalAlign::Top => 0,
|
||||
|
@ -420,17 +426,27 @@ impl Framable {
|
|||
self.bottom.store(bottom, SeqCst);
|
||||
}
|
||||
|
||||
pub fn change_position(&self, x_offset: i32, y_offset: i32) -> Result<()> {
|
||||
pub fn change_position(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
x_offset: i32,
|
||||
y_offset: i32,
|
||||
) -> Result<()> {
|
||||
assert!(self.is_framed(), "framable needs to be framed first!");
|
||||
|
||||
self.x_off.store(x_offset, SeqCst);
|
||||
self.y_off.store(y_offset, SeqCst);
|
||||
|
||||
self.resize()?;
|
||||
self.resize(gui_handler)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn change_position_unscaled(&self, x: i32, y: i32) -> Result<()> {
|
||||
pub fn change_position_unscaled(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
x: i32,
|
||||
y: i32,
|
||||
) -> Result<()> {
|
||||
assert!(self.is_framed(), "framable needs to be framed first!");
|
||||
|
||||
let left = self.left.load(SeqCst);
|
||||
|
@ -447,23 +463,19 @@ impl Framable {
|
|||
self.bottom.store(y + height, SeqCst);
|
||||
|
||||
for (_, callback) in self.resize_callbacks.read().unwrap().iter() {
|
||||
callback()?;
|
||||
callback(gui_handler)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn resize(&self) -> Result<()> {
|
||||
self.calculate_frame();
|
||||
pub fn resize(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
self.calculate_frame(gui_handler);
|
||||
|
||||
for (_, callback) in self.resize_callbacks.read().unwrap().iter() {
|
||||
callback()?;
|
||||
callback(gui_handler)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn gui_handler(&self) -> &Arc<GuiHandler> {
|
||||
&self.gui_handler
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ use crate::prelude::*;
|
|||
use anyhow::Result;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
|
||||
Arc,
|
||||
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
|
||||
};
|
||||
|
||||
#[cfg(feature = "audio")]
|
||||
|
@ -56,10 +56,8 @@ impl Hoverable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `hoverable` is a `&Arc<Hoverable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.add_hoverable(self.ui_layer.load(SeqCst), self.clone())?;
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_hoverable(self.ui_layer.load(SeqCst), self.clone())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -69,11 +67,9 @@ impl Hoverable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `hoverable` is a `&Arc<Hoverable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.delete_hoverable(self.ui_layer.load(SeqCst), self)?;
|
||||
self.set_hovered(false)?;
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_hoverable(self.ui_layer.load(SeqCst), self)?;
|
||||
self.set_hovered(gui_handler, false)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -107,12 +103,13 @@ impl Hoverable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `hovered` is the new hovered state
|
||||
pub fn set_hovered(&self, hovered: bool) -> Result<()> {
|
||||
pub fn set_hovered(&self, gui_handler: &mut GuiHandler<'_>, hovered: bool) -> Result<()> {
|
||||
if self.hovered() != hovered {
|
||||
self.hovered.store(hovered, SeqCst);
|
||||
|
||||
self.hover_changed_executable.execute(hovered)?;
|
||||
self.on_hover_executable.execute(hovered)?;
|
||||
self.hover_changed_executable
|
||||
.execute(gui_handler, hovered)?;
|
||||
self.on_hover_executable.execute(gui_handler, hovered)?;
|
||||
|
||||
#[cfg(feature = "audio")]
|
||||
{
|
||||
|
|
|
@ -9,8 +9,8 @@ use vulkan_rs::prelude::*;
|
|||
use super::texturedvertex::TexturedVertex;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
|
||||
Arc, RwLock,
|
||||
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -85,16 +85,17 @@ impl Iconizable {
|
|||
/// * `framable` is a `Arc<Framable>` instance
|
||||
/// * `icon` is a reference to an `Arc<Image>`
|
||||
pub fn new(
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
framable: Arc<Framable>,
|
||||
icon_builder: impl Into<IconBuilderType>,
|
||||
positioning: impl Into<Option<IconizablePositioning>>,
|
||||
) -> Result<Arc<Self>> {
|
||||
let icon = framable.gui_handler().request_icon(icon_builder)?;
|
||||
let icon = gui_handler.request_icon(icon_builder)?;
|
||||
|
||||
let device = framable.gui_handler().device();
|
||||
let device = gui_handler.device();
|
||||
|
||||
let desc_pool = DescriptorPool::builder()
|
||||
.set_layout(framable.gui_handler().icon_descriptor_layout().clone())
|
||||
.set_layout(gui_handler.icon_descriptor_layout().clone())
|
||||
.build(device.clone())?;
|
||||
|
||||
let descriptor_set = DescriptorPool::prepare_set(&desc_pool).allocate()?;
|
||||
|
@ -125,7 +126,7 @@ impl Iconizable {
|
|||
|
||||
iconizable.framable.add_callback(
|
||||
weak_iconizable,
|
||||
Box::new(move || iconizable_clone.update_frame()),
|
||||
Box::new(move |gui_handler| iconizable_clone.update_frame(gui_handler)),
|
||||
);
|
||||
|
||||
Ok(iconizable)
|
||||
|
@ -136,10 +137,8 @@ impl Iconizable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `iconizable` is a `&Arc<Iconizable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.add_iconizable(self.ui_layer.load(SeqCst), self.clone())
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_iconizable(self.ui_layer.load(SeqCst), self.clone())
|
||||
}
|
||||
|
||||
/// Delete method, has to be explicitly called, otherwise it will remain in memory
|
||||
|
@ -147,10 +146,8 @@ impl Iconizable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `iconizable` is a `&Arc<Iconizable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.delete_iconizable(self.ui_layer.load(SeqCst), self)
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_iconizable(self.ui_layer.load(SeqCst), self)
|
||||
}
|
||||
|
||||
pub fn set_ui_layer(&self, ui_layer: i32) {
|
||||
|
@ -175,7 +172,7 @@ impl Iconizable {
|
|||
}
|
||||
|
||||
/// Updates the frame
|
||||
pub fn update_frame(&self) -> Result<()> {
|
||||
pub fn update_frame(&self, gui_handler: &GuiHandler<'_>) -> Result<()> {
|
||||
assert!(self.framable.is_framed(), "framable is not framed yet");
|
||||
|
||||
// frame parameter
|
||||
|
@ -239,7 +236,7 @@ impl Iconizable {
|
|||
let right = left + resulting_width;
|
||||
let bottom = top + resulting_height;
|
||||
|
||||
let ortho = self.framable.ortho();
|
||||
let ortho = gui_handler.ortho();
|
||||
|
||||
let mut frame = self.buffer.map_complete()?;
|
||||
|
||||
|
@ -270,8 +267,12 @@ impl Iconizable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `icon` the new icon
|
||||
pub fn set_icon(&self, icon_builder: impl Into<IconBuilderType>) -> Result<()> {
|
||||
let icon = self.framable.gui_handler().request_icon(icon_builder)?;
|
||||
pub fn set_icon(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
icon_builder: impl Into<IconBuilderType>,
|
||||
) -> Result<()> {
|
||||
let icon = gui_handler.request_icon(icon_builder)?;
|
||||
|
||||
self.descriptor_set
|
||||
.update(&[DescriptorWrite::combined_samplers(0, &[&icon])])?;
|
||||
|
|
|
@ -5,22 +5,20 @@ use crate::prelude::*;
|
|||
use anyhow::Result;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
|
||||
Arc, RwLock, Weak,
|
||||
atomic::{AtomicBool, AtomicI32, Ordering::SeqCst},
|
||||
};
|
||||
|
||||
/// `Selectable` gives the ability to navigate per button or controller to
|
||||
/// optionally adjacent neighbour Selectables and to execute a closure
|
||||
/// when the current Selectable is pressed
|
||||
pub struct Selectable<'a> {
|
||||
|
||||
|
||||
selected: AtomicBool,
|
||||
|
||||
east_neighbour: RwLock<Option<Weak<Selectable>>>,
|
||||
west_neighbour: RwLock<Option<Weak<Selectable>>>,
|
||||
north_neighbour: RwLock<Option<Weak<Selectable>>>,
|
||||
south_neighbour: RwLock<Option<Weak<Selectable>>>,
|
||||
east_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
|
||||
west_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
|
||||
north_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
|
||||
south_neighbour: RwLock<Option<Weak<Selectable<'a>>>>,
|
||||
|
||||
#[cfg(feature = "audio")]
|
||||
select_audible: RwLock<Option<Arc<Audible>>>,
|
||||
|
@ -38,10 +36,11 @@ pub struct Selectable<'a> {
|
|||
selected_changed_executable: Arc<Executable<(&'a mut World, bool)>>,
|
||||
|
||||
// exposed externally for event
|
||||
on_select_executable: Arc<Executable<(&'mut World, bool)>>,
|
||||
on_select_executable: Arc<Executable<(&'a mut World, bool)>>,
|
||||
|
||||
// used for custom buttons
|
||||
custom_callback: RwLock<Option<Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>>>,
|
||||
custom_callback:
|
||||
RwLock<Option<Box<dyn Fn(&mut World, ControllerButton) -> Result<bool> + Send + Sync>>>,
|
||||
}
|
||||
|
||||
impl<'a> Selectable<'a> {
|
||||
|
@ -51,15 +50,12 @@ impl<'a> Selectable<'a> {
|
|||
///
|
||||
/// * `executable` is a `Arc<Executable>` instance
|
||||
pub fn new(
|
||||
gui_handler: &'a GuiHandler<'a>,
|
||||
executable: Arc<Executable<()>>,
|
||||
selected_changed_executable: Arc<Executable<bool>>,
|
||||
on_select_executable: Arc<Executable<bool>>,
|
||||
executable: Arc<Executable<&'a mut World>>,
|
||||
selected_changed_executable: Arc<Executable<(&'a mut World, bool)>>,
|
||||
on_select_executable: Arc<Executable<(&'a mut World, bool)>>,
|
||||
isolate: bool,
|
||||
) -> Arc<Self> {
|
||||
Arc::new(Selectable {
|
||||
|
||||
|
||||
selected: AtomicBool::new(false),
|
||||
|
||||
east_neighbour: RwLock::new(None),
|
||||
|
@ -89,11 +85,8 @@ impl<'a> Selectable<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `selectable` is a `&Arc<Selectable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.gui_handler
|
||||
.add_selectable(self.ui_layer.load(SeqCst), self.clone())?;
|
||||
|
||||
Ok(())
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_selectable(self.ui_layer.load(SeqCst), self.clone())
|
||||
}
|
||||
|
||||
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
|
||||
|
@ -101,10 +94,9 @@ impl<'a> Selectable<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `selectable` is a `&Arc<Selectable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.gui_handler
|
||||
.delete_selectable(self.ui_layer.load(SeqCst), self)?;
|
||||
self.set_selected(false)?;
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_selectable(self.ui_layer.load(SeqCst), self)?;
|
||||
self.set_selected(gui_handler, false)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -118,8 +110,8 @@ impl<'a> Selectable<'a> {
|
|||
/// # Argument
|
||||
///
|
||||
/// * `selectable` is a `Arc<Selectable>` instance
|
||||
pub fn select(self: &Arc<Self>) -> Result<()> {
|
||||
self.gui_handler.set_selectable(Some(self.clone()))
|
||||
pub fn select(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.set_selectable(Some(self.clone()))
|
||||
}
|
||||
|
||||
pub fn set_custom_callback<F>(&self, custom_callback: F)
|
||||
|
@ -145,12 +137,13 @@ impl<'a> Selectable<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `selected` is the new selected state
|
||||
pub fn set_selected(&self, selected: bool) -> Result<()> {
|
||||
pub fn set_selected(&self, gui_handler: &mut GuiHandler<'_>, selected: bool) -> Result<()> {
|
||||
if self.selected() != selected {
|
||||
self.selected.store(selected, SeqCst);
|
||||
|
||||
self.selected_changed_executable.execute(selected)?;
|
||||
self.on_select_executable.execute(selected)?;
|
||||
self.selected_changed_executable
|
||||
.execute(gui_handler, selected)?;
|
||||
self.on_select_executable.execute(gui_handler, selected)?;
|
||||
|
||||
#[cfg(feature = "audio")]
|
||||
{
|
||||
|
@ -171,7 +164,7 @@ impl<'a> Selectable<'a> {
|
|||
}
|
||||
|
||||
/// Executes the `Executable`'s callback
|
||||
pub(crate) fn click_event(&self) -> Result<()> {
|
||||
pub(crate) fn click_event(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
#[cfg(feature = "audio")]
|
||||
{
|
||||
if let Some(audible) = self.click_audible.read().unwrap().as_ref() {
|
||||
|
@ -179,7 +172,7 @@ impl<'a> Selectable<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
self.executable.execute(())?;
|
||||
self.executable.execute(gui_handler, ())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -202,7 +195,7 @@ impl<'a> Selectable<'a> {
|
|||
}
|
||||
|
||||
/// Returns the current east neighbour, if possible
|
||||
pub fn east_neighbour(&self) -> Option<Arc<Selectable>> {
|
||||
pub fn east_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
|
||||
if let Some(weak_neighbour) = self.east_neighbour.read().unwrap().as_ref() {
|
||||
if let Some(neighbour) = weak_neighbour.upgrade() {
|
||||
return Some(neighbour);
|
||||
|
@ -217,7 +210,7 @@ impl<'a> Selectable<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `selectable` the new east neighbour
|
||||
pub fn set_east_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
|
||||
pub fn set_east_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
|
||||
if self.isolate {
|
||||
return;
|
||||
}
|
||||
|
@ -231,7 +224,7 @@ impl<'a> Selectable<'a> {
|
|||
}
|
||||
|
||||
/// Returns the current west neighbour, if possible
|
||||
pub fn west_neighbour(&self) -> Option<Arc<Selectable>> {
|
||||
pub fn west_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
|
||||
if let Some(weak_neighbour) = self.west_neighbour.read().unwrap().as_ref() {
|
||||
if let Some(neighbour) = weak_neighbour.upgrade() {
|
||||
return Some(neighbour);
|
||||
|
@ -246,7 +239,7 @@ impl<'a> Selectable<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `selectable` the new west neighbour
|
||||
pub fn set_west_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
|
||||
pub fn set_west_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
|
||||
if self.isolate {
|
||||
return;
|
||||
}
|
||||
|
@ -260,7 +253,7 @@ impl<'a> Selectable<'a> {
|
|||
}
|
||||
|
||||
/// Returns the current north neighbour, if possible
|
||||
pub fn north_neighbour(&self) -> Option<Arc<Selectable>> {
|
||||
pub fn north_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
|
||||
if let Some(weak_neighbour) = self.north_neighbour.read().unwrap().as_ref() {
|
||||
if let Some(neighbour) = weak_neighbour.upgrade() {
|
||||
return Some(neighbour);
|
||||
|
@ -275,7 +268,7 @@ impl<'a> Selectable<'a> {
|
|||
/// # Argumnents
|
||||
///
|
||||
/// * `selectable` the new north neighbour
|
||||
pub fn set_north_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
|
||||
pub fn set_north_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
|
||||
if self.isolate {
|
||||
return;
|
||||
}
|
||||
|
@ -289,7 +282,7 @@ impl<'a> Selectable<'a> {
|
|||
}
|
||||
|
||||
/// Returns the current south neighbour, if possible
|
||||
pub fn south_neighbour(&self) -> Option<Arc<Selectable>> {
|
||||
pub fn south_neighbour(&self) -> Option<Arc<Selectable<'a>>> {
|
||||
if let Some(weak_neighbour) = self.south_neighbour.read().unwrap().as_ref() {
|
||||
if let Some(neighbour) = weak_neighbour.upgrade() {
|
||||
return Some(neighbour);
|
||||
|
@ -304,7 +297,7 @@ impl<'a> Selectable<'a> {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `selectable` the new south neighbour
|
||||
pub fn set_south_neighbour(&self, selectable: Option<&Arc<Selectable>>) {
|
||||
pub fn set_south_neighbour(&self, selectable: Option<&Arc<Selectable<'a>>>) {
|
||||
if self.isolate {
|
||||
return;
|
||||
}
|
||||
|
@ -317,7 +310,7 @@ impl<'a> Selectable<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn connect_vertically(upper: &Arc<Selectable>, lower: &Arc<Selectable>) {
|
||||
pub fn connect_vertically<'c>(upper: &Arc<Selectable<'c>>, lower: &Arc<Selectable<'c>>) {
|
||||
if upper.isolate || lower.isolate {
|
||||
return;
|
||||
}
|
||||
|
@ -326,7 +319,7 @@ impl<'a> Selectable<'a> {
|
|||
*lower.north_neighbour.write().unwrap() = Some(Arc::downgrade(upper));
|
||||
}
|
||||
|
||||
pub fn connect_horizontally(left: &Arc<Selectable>, right: &Arc<Selectable>) {
|
||||
pub fn connect_horizontally<'c>(left: &Arc<Selectable<'c>>, right: &Arc<Selectable<'c>>) {
|
||||
if left.isolate || right.isolate {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ use super::texturedvertex::TexturedVertex;
|
|||
use std::{
|
||||
convert::TryFrom,
|
||||
sync::{
|
||||
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
|
||||
Arc, RwLock,
|
||||
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,7 @@ impl TryFrom<String> for TextAlignment {
|
|||
return Err(anyhow::Error::msg(format!(
|
||||
"Failed parsing TextAlignment from: {}",
|
||||
text
|
||||
)))
|
||||
)));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -80,19 +80,20 @@ impl Textable {
|
|||
/// * `height_ratio` the ratio of the height in respect to the framable height
|
||||
/// * `text_alignment` where the text is aligned to
|
||||
pub fn new(
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
framable: Arc<Framable>,
|
||||
text: String,
|
||||
height_ratio: f32,
|
||||
text_alignment: TextAlignment,
|
||||
text_color: Color,
|
||||
) -> Result<Arc<Self>> {
|
||||
let set = framable.gui_handler().color_descriptor(text_color)?;
|
||||
let set = gui_handler.color_descriptor(text_color)?;
|
||||
|
||||
let buffer = if text.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Self::create_text_buffer(
|
||||
framable.gui_handler().device(),
|
||||
gui_handler.device(),
|
||||
text.len() as u32 * 6,
|
||||
)?)
|
||||
};
|
||||
|
@ -120,7 +121,7 @@ impl Textable {
|
|||
|
||||
textable.framable.add_callback(
|
||||
weak_textable,
|
||||
Box::new(move || textable_clone.update_text()),
|
||||
Box::new(move |gui_handler| textable_clone.update_text(gui_handler)),
|
||||
);
|
||||
|
||||
Ok(textable)
|
||||
|
@ -142,10 +143,8 @@ impl Textable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `textable` is a `&Arc<Textable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.add_textable(self.ui_layer.load(SeqCst), self.clone())
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_textable(self.ui_layer.load(SeqCst), self.clone())
|
||||
}
|
||||
|
||||
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
|
||||
|
@ -153,10 +152,8 @@ impl Textable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `textable` is a `&Arc<Textable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.delete_textable(self.ui_layer.load(SeqCst), self)
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_textable(self.ui_layer.load(SeqCst), self)
|
||||
}
|
||||
|
||||
pub fn set_ui_layer(&self, ui_layer: i32) {
|
||||
|
@ -173,8 +170,12 @@ impl Textable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `text_color` defines the color of the text
|
||||
pub fn set_text_color(&self, text_color: Color) -> Result<()> {
|
||||
let set = self.framable.gui_handler().color_descriptor(text_color)?;
|
||||
pub fn set_text_color(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
text_color: Color,
|
||||
) -> Result<()> {
|
||||
let set = gui_handler.color_descriptor(text_color)?;
|
||||
|
||||
*self.descriptor_set.write().unwrap() = set;
|
||||
|
||||
|
@ -186,9 +187,13 @@ impl Textable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `text_alignment` where the text is aligned to
|
||||
pub fn set_text_alignment(&self, text_alignment: TextAlignment) -> Result<()> {
|
||||
pub fn set_text_alignment(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
text_alignment: TextAlignment,
|
||||
) -> Result<()> {
|
||||
*self.text_alignment.write().unwrap() = text_alignment;
|
||||
self.update_text()?;
|
||||
self.update_text(gui_handler)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -214,14 +219,14 @@ impl Textable {
|
|||
///
|
||||
/// * `text` the text to be displayed
|
||||
/// * `height_ratio` the ratio of the height in respect to the framable height
|
||||
pub fn set_text(&self, text: impl ToString) -> Result<()> {
|
||||
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: impl ToString) -> Result<()> {
|
||||
let text = text.to_string();
|
||||
|
||||
if text.is_empty() {
|
||||
self.vertex_count.store(0, SeqCst);
|
||||
*self.text.write().unwrap() = String::new();
|
||||
|
||||
self.framable.gui_handler().enqueue_text_update({
|
||||
gui_handler.enqueue_text_update({
|
||||
let weak_buffer = Arc::downgrade(&self.buffer);
|
||||
|
||||
Box::new(move || {
|
||||
|
@ -234,7 +239,7 @@ impl Textable {
|
|||
} else {
|
||||
self.vertex_count.store(text.len() as u32 * 6, SeqCst);
|
||||
*self.text.write().unwrap() = text;
|
||||
self.update_text()?;
|
||||
self.update_text(gui_handler)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -245,9 +250,9 @@ impl Textable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `height_ratio` the ratio of the height in respect to the framable height
|
||||
pub fn set_size(&self, height_ratio: f32) -> Result<()> {
|
||||
pub fn set_size(&self, gui_handler: &mut GuiHandler<'_>, height_ratio: f32) -> Result<()> {
|
||||
*self.height_ratio.write().unwrap() = height_ratio;
|
||||
self.update_text()?;
|
||||
self.update_text(gui_handler)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -279,12 +284,12 @@ impl Textable {
|
|||
}
|
||||
|
||||
/// Updates the texts buffer
|
||||
pub fn update_text(&self) -> Result<()> {
|
||||
pub fn update_text(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
self.calculate_text_size();
|
||||
|
||||
let (x, y) = self.calc_pos_from_alignment();
|
||||
|
||||
self.create_buffer(x, y)?;
|
||||
self.create_buffer(gui_handler, x, y)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -320,13 +325,18 @@ impl Textable {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_buffer(&self, win_x: f32, win_y: f32) -> Result<()> {
|
||||
fn create_buffer(
|
||||
&self,
|
||||
gui_handler: &mut GuiHandler<'_>,
|
||||
win_x: f32,
|
||||
win_y: f32,
|
||||
) -> Result<()> {
|
||||
let weak_buffer = Arc::downgrade(&self.buffer);
|
||||
let text = self.text.read().unwrap().clone();
|
||||
let character_size = self.character_size.load(SeqCst);
|
||||
let ortho = self.framable.ortho();
|
||||
let ortho = gui_handler.ortho();
|
||||
|
||||
let device = self.framable.gui_handler().device().clone();
|
||||
let device = gui_handler.device().clone();
|
||||
|
||||
let async_buffer_creation = Box::new(move || {
|
||||
if let Some(buffer) = weak_buffer.upgrade() {
|
||||
|
@ -484,14 +494,12 @@ impl Textable {
|
|||
Ok(())
|
||||
});
|
||||
|
||||
self.framable
|
||||
.gui_handler()
|
||||
.enqueue_text_update(async_buffer_creation);
|
||||
gui_handler.enqueue_text_update(async_buffer_creation);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn text_changed_through_write(&self) -> Result<()> {
|
||||
fn text_changed_through_write(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
self.vertex_count
|
||||
.store(self.text.read().unwrap().len() as u32 * 6, SeqCst);
|
||||
self.character_size.store(
|
||||
|
@ -500,28 +508,28 @@ impl Textable {
|
|||
SeqCst,
|
||||
);
|
||||
|
||||
self.update_text()?;
|
||||
self.update_text(gui_handler)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifyText for Textable {
|
||||
fn set_text(&self, text: String) -> Result<()> {
|
||||
fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: String) -> Result<()> {
|
||||
*self.text.write().unwrap() = text;
|
||||
self.text_changed_through_write()
|
||||
self.text_changed_through_write(gui_handler)
|
||||
}
|
||||
|
||||
fn add_letter(&self, letter: char) -> Result<String> {
|
||||
fn add_letter(&self, gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<String> {
|
||||
self.text.write().unwrap().push(letter);
|
||||
self.text_changed_through_write()?;
|
||||
self.text_changed_through_write(gui_handler)?;
|
||||
|
||||
Ok(self.text.read().unwrap().clone())
|
||||
}
|
||||
|
||||
fn remove_last(&self) -> Result<Option<String>> {
|
||||
fn remove_last(&self, gui_handler: &mut GuiHandler<'_>) -> Result<Option<String>> {
|
||||
self.text.write().unwrap().pop();
|
||||
self.text_changed_through_write()?;
|
||||
self.text_changed_through_write(gui_handler)?;
|
||||
|
||||
let text = self.text.read().unwrap().clone();
|
||||
|
||||
|
|
|
@ -4,20 +4,18 @@ use crate::prelude::*;
|
|||
use anyhow::Result;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicI32, Ordering::SeqCst},
|
||||
Arc, RwLock,
|
||||
atomic::{AtomicI32, Ordering::SeqCst},
|
||||
};
|
||||
|
||||
pub trait ModifyText: Send + Sync {
|
||||
fn set_text(&self, text: String) -> Result<()>;
|
||||
fn add_letter(&self, letter: char) -> Result<String>;
|
||||
fn remove_last(&self) -> Result<Option<String>>;
|
||||
fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: String) -> Result<()>;
|
||||
fn add_letter(&self, gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<String>;
|
||||
fn remove_last(&self, gui_handler: &mut GuiHandler<'_>) -> Result<Option<String>>;
|
||||
}
|
||||
|
||||
/// `Writeable` gives the ability to modify the text inside an `Textable`
|
||||
pub struct Writeable {
|
||||
gui_handler: Arc<GuiHandler>,
|
||||
|
||||
modifyable: Arc<dyn ModifyText>,
|
||||
text_change_executable: Arc<Executable<Option<String>>>,
|
||||
|
||||
|
@ -29,12 +27,10 @@ pub struct Writeable {
|
|||
impl Writeable {
|
||||
/// Factory method for `Writeable`, returns `Arc<Writeable>`.
|
||||
pub fn new(
|
||||
gui_handler: Arc<GuiHandler>,
|
||||
modifyable: Arc<dyn ModifyText>,
|
||||
text_change_executable: Arc<Executable<Option<String>>>,
|
||||
) -> Result<Arc<Self>> {
|
||||
Ok(Arc::new(Writeable {
|
||||
gui_handler,
|
||||
modifyable,
|
||||
text_change_executable,
|
||||
|
||||
|
@ -44,8 +40,8 @@ impl Writeable {
|
|||
}))
|
||||
}
|
||||
|
||||
pub fn set_active(self: &Arc<Self>) -> Result<()> {
|
||||
if self.gui_handler.set_active_writeable(self.clone())? {
|
||||
pub fn set_active(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
if gui_handler.set_active_writeable(self.clone())? {
|
||||
if let Some(exec) = &*self.activation_changed_executable.read().unwrap() {
|
||||
exec(true)?;
|
||||
}
|
||||
|
@ -74,9 +70,8 @@ impl Writeable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `writeable` is a `&Arc<Writeable>` instance that is going to be added
|
||||
pub fn add(self: &Arc<Self>) -> Result<()> {
|
||||
self.gui_handler
|
||||
.add_writeable(self.ui_layer.load(SeqCst), self.clone())
|
||||
pub fn add(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.add_writeable(self.ui_layer.load(SeqCst), self.clone())
|
||||
}
|
||||
|
||||
/// Delete method, has to be explicitly called, otherwise it will remain in memory.
|
||||
|
@ -84,9 +79,8 @@ impl Writeable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `writeable` is a `&Arc<Writeable>` instance that is going to be deleted
|
||||
pub fn delete(self: &Arc<Self>) -> Result<()> {
|
||||
self.gui_handler
|
||||
.delete_writeable(self.ui_layer.load(SeqCst), self)
|
||||
pub fn delete(self: &Arc<Self>, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
gui_handler.delete_writeable(self.ui_layer.load(SeqCst), self)
|
||||
}
|
||||
|
||||
pub fn set_ui_layer(&self, ui_layer: i32) {
|
||||
|
@ -98,11 +92,11 @@ impl Writeable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `text` that replaces the current text
|
||||
pub fn set_text(&self, text: String) -> Result<()> {
|
||||
self.modifyable.set_text(text.clone())?;
|
||||
pub fn set_text(&self, gui_handler: &mut GuiHandler<'_>, text: String) -> Result<()> {
|
||||
self.modifyable.set_text(gui_handler, text.clone())?;
|
||||
|
||||
self.text_change_executable
|
||||
.execute(if text.is_empty() { None } else { Some(text) })?;
|
||||
.execute(gui_handler, if text.is_empty() { None } else { Some(text) })?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -112,17 +106,19 @@ impl Writeable {
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `letter` the letter thats going to be added
|
||||
pub fn add_letter(&self, letter: char) -> Result<()> {
|
||||
self.text_change_executable
|
||||
.execute(Some(self.modifyable.add_letter(letter)?))?;
|
||||
pub fn add_letter(&self, gui_handler: &mut GuiHandler<'_>, letter: char) -> Result<()> {
|
||||
self.text_change_executable.execute(
|
||||
gui_handler,
|
||||
Some(self.modifyable.add_letter(gui_handler, letter)?),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Removes the last letter
|
||||
pub fn remove_last(&self) -> Result<()> {
|
||||
pub fn remove_last(&self, gui_handler: &mut GuiHandler<'_>) -> Result<()> {
|
||||
self.text_change_executable
|
||||
.execute(self.modifyable.remove_last()?)?;
|
||||
.execute(gui_handler, self.modifyable.remove_last(gui_handler)?)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
pub use super::builder::{builder::GuiBuilder, snippet::GuiSnippet};
|
||||
pub use super::context_interface::{ContextInterface, TargetMode, Unfold};
|
||||
pub use super::context_interface::{Chain, ContextInterface, TargetMode, Unfold};
|
||||
pub use super::controller_button::ControllerButton;
|
||||
pub use super::element_creator::*;
|
||||
pub use super::elements::prelude::*;
|
||||
|
|
Loading…
Reference in a new issue