Fix GuiHandler
This commit is contained in:
parent
0976860b9f
commit
afc101effc
3 changed files with 140 additions and 65 deletions
|
@ -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>] ) ),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -439,8 +439,8 @@ impl<'a> GuiHandler<'a> {
|
|||
|
||||
let image = Image::from_file(path)?
|
||||
.max_mip_map_levels()
|
||||
.attach_pretty_sampler(self.device())?
|
||||
.build(self.device(), self.queue())?;
|
||||
.attach_pretty_sampler(&self.device)?
|
||||
.build(&self.device, &self.queue)?;
|
||||
|
||||
*weak_image = Arc::downgrade(&image);
|
||||
|
||||
|
@ -499,7 +499,10 @@ impl<'a> GuiHandler<'a> {
|
|||
DescriptorPool::prepare_set(&desc_pool).allocate()
|
||||
}
|
||||
|
||||
pub(crate) fn displayable_image_from_path(&self, mut path: AssetPath) -> Result<Arc<Image>> {
|
||||
pub(crate) fn displayable_image_from_path(
|
||||
&mut self,
|
||||
mut path: AssetPath,
|
||||
) -> Result<Arc<Image>> {
|
||||
if !path.has_prefix() {
|
||||
path.set_prefix(
|
||||
&self
|
||||
|
@ -583,7 +586,7 @@ impl<'a> GuiHandler<'a> {
|
|||
self.hover_sound.as_ref()
|
||||
}
|
||||
|
||||
pub fn set_on_selected_event<F>(&self, f: F)
|
||||
pub fn set_on_selected_event<F>(&mut self, f: F)
|
||||
where
|
||||
F: Fn() -> Result<()> + Send + Sync + 'static,
|
||||
{
|
||||
|
@ -611,6 +614,8 @@ impl<'a> GuiHandler<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
match hovered {
|
||||
Some(hovered) => {
|
||||
if let Some(current) = &self.current_hoverable {
|
||||
|
@ -618,7 +623,7 @@ impl<'a> GuiHandler<'a> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
current.set_hovered(self, false)?;
|
||||
current.set_hovered(callback_self, false)?;
|
||||
}
|
||||
|
||||
hovered.set_hovered(self, true)?;
|
||||
|
@ -637,7 +642,7 @@ impl<'a> GuiHandler<'a> {
|
|||
self.current_hoverable
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_hovered(self, false)?;
|
||||
.set_hovered(callback_self, false)?;
|
||||
self.current_hoverable = None;
|
||||
}
|
||||
}
|
||||
|
@ -676,12 +681,14 @@ impl<'a> GuiHandler<'a> {
|
|||
}
|
||||
|
||||
pub fn mouse_up(&mut self, mouse_button: MouseButton) -> Result<bool> {
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
if mouse_button == MouseButton::Left {
|
||||
if self.current_clickable.is_some() {
|
||||
self.current_clickable
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_clicked(self, false)?;
|
||||
.set_clicked(callback_self, false)?;
|
||||
|
||||
if self
|
||||
.current_clickable
|
||||
|
@ -690,7 +697,7 @@ impl<'a> GuiHandler<'a> {
|
|||
.is_pressed(self.mouse_x as i32, self.mouse_y as i32)
|
||||
{
|
||||
if let Some(hoverable) = self.current_hoverable.as_ref() {
|
||||
hoverable.set_hovered(self, true)?;
|
||||
hoverable.set_hovered(callback_self, true)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,8 +715,10 @@ impl<'a> GuiHandler<'a> {
|
|||
}
|
||||
|
||||
pub fn accept_selection(&mut self) -> Result<bool> {
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
if let Some(current_selectable) = &self.current_selectable {
|
||||
current_selectable.click_event(self)?;
|
||||
current_selectable.click_event(callback_self)?;
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
@ -767,10 +776,12 @@ impl<'a> GuiHandler<'a> {
|
|||
self.current_writeable.clone()
|
||||
}
|
||||
|
||||
pub fn remove_char(&self) -> Result<bool> {
|
||||
pub fn remove_char(&mut self) -> Result<bool> {
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
match &self.current_writeable {
|
||||
Some(current_writable) => {
|
||||
current_writable.remove_last()?;
|
||||
current_writable.remove_last(callback_self)?;
|
||||
Ok(true)
|
||||
}
|
||||
None => Ok(false),
|
||||
|
@ -784,41 +795,42 @@ impl<'a> GuiHandler<'a> {
|
|||
pub fn update_selection(&mut self, direction: GuiDirection) -> Result<bool> {
|
||||
if direction != self.last_direction {
|
||||
self.last_direction = direction;
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
match self.current_selectable.write().unwrap().as_mut() {
|
||||
match &mut self.current_selectable {
|
||||
Some(current_selectable) => match direction {
|
||||
GuiDirection::Left => {
|
||||
if let Some(neighbour) = current_selectable.west_neighbour() {
|
||||
current_selectable.set_selected(self, false)?;
|
||||
current_selectable.set_selected(callback_self, false)?;
|
||||
*current_selectable = neighbour;
|
||||
current_selectable.set_selected(self, true)?;
|
||||
current_selectable.set_selected(callback_self, true)?;
|
||||
};
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
GuiDirection::Right => {
|
||||
if let Some(neighbour) = current_selectable.east_neighbour() {
|
||||
current_selectable.set_selected(self, false)?;
|
||||
current_selectable.set_selected(callback_self, false)?;
|
||||
*current_selectable = neighbour;
|
||||
current_selectable.set_selected(self, true)?;
|
||||
current_selectable.set_selected(callback_self, true)?;
|
||||
};
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
GuiDirection::Up => {
|
||||
if let Some(neighbour) = current_selectable.north_neighbour() {
|
||||
current_selectable.set_selected(self, false)?;
|
||||
current_selectable.set_selected(callback_self, false)?;
|
||||
*current_selectable = neighbour;
|
||||
current_selectable.set_selected(self, true)?;
|
||||
current_selectable.set_selected(callback_self, true)?;
|
||||
};
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
GuiDirection::Down => {
|
||||
if let Some(neighbour) = current_selectable.south_neighbour() {
|
||||
current_selectable.set_selected(self, false)?;
|
||||
current_selectable.set_selected(callback_self, false)?;
|
||||
*current_selectable = neighbour;
|
||||
current_selectable.set_selected(self, true)?;
|
||||
current_selectable.set_selected(callback_self, true)?;
|
||||
};
|
||||
|
||||
Ok(true)
|
||||
|
@ -861,7 +873,7 @@ impl<'a> GuiHandler<'a> {
|
|||
fn render(
|
||||
&self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
command_buffer_state: &CommandBufferState,
|
||||
command_buffer_state: &mut CommandBufferState,
|
||||
render_target: &RenderTarget,
|
||||
single_color_objects: &GuiSeparator,
|
||||
rectangle_objects: &GuiSeparator,
|
||||
|
@ -940,15 +952,14 @@ impl<'a> GuiHandler<'a> {
|
|||
buffer_recorder.set_scissor(&scissor);
|
||||
buffer_recorder.set_viewport(&viewport);
|
||||
|
||||
let mut text_buffers = command_buffer_state.text_buffers.write().unwrap();
|
||||
text_buffers.clear();
|
||||
command_buffer_state.text_buffers.clear();
|
||||
|
||||
// ---------- render textables ----------
|
||||
for textable in elements.iter_textables() {
|
||||
if let Some(text_buffer) = textable.buffer() {
|
||||
buffer_recorder.bind_vertex_buffer(&text_buffer);
|
||||
|
||||
text_buffers.push(text_buffer);
|
||||
command_buffer_state.text_buffers.push(text_buffer);
|
||||
|
||||
buffer_recorder.bind_descriptor_sets_minimal(&[
|
||||
&self.bitmap_desc_set,
|
||||
|
@ -987,10 +998,8 @@ impl<'a> GuiHandler<'a> {
|
|||
|
||||
macro_rules! add_element {
|
||||
($layers: expr, $layer_id: ident, $element: ident) => {
|
||||
let mut layers = $layers.lock().unwrap();
|
||||
|
||||
paste! {
|
||||
match layers.iter_mut().find(|(id, _)| *id == $layer_id) {
|
||||
match $layers.iter_mut().find(|(id, _)| *id == $layer_id) {
|
||||
Some((_, layer)) => {
|
||||
layer.[<add_ $element>]($element);
|
||||
}
|
||||
|
@ -998,8 +1007,8 @@ macro_rules! add_element {
|
|||
let mut elements = Elements::default();
|
||||
elements.[<add_ $element>]($element);
|
||||
|
||||
layers.push(($layer_id, elements));
|
||||
layers.sort_by(|(left_id, _), (right_id, _)| left_id.cmp(right_id));
|
||||
$layers.push(($layer_id, elements));
|
||||
$layers.sort_by(|(left_id, _), (right_id, _)| left_id.cmp(right_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1225,8 +1234,10 @@ impl<'a> GuiHandler<'a> {
|
|||
}
|
||||
|
||||
pub(crate) fn set_selectable(&mut self, selectable: Option<Arc<Selectable<'a>>>) -> Result<()> {
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
if let Some(selectable) = &self.current_selectable {
|
||||
selectable.set_selected(self, false)?;
|
||||
selectable.set_selected(callback_self, false)?;
|
||||
}
|
||||
|
||||
if let Some(selectable) = &selectable {
|
||||
|
@ -1578,7 +1589,7 @@ impl<'a> GuiHandler<'a> {
|
|||
|
||||
impl<'a> GuiHandler<'a> {
|
||||
pub fn process(
|
||||
&self,
|
||||
&mut self,
|
||||
buffer_recorder: &mut CommandBufferRecorder<'_>,
|
||||
indices: &TargetMode<usize>,
|
||||
) -> Result<()> {
|
||||
|
@ -1594,21 +1605,23 @@ impl<'a> GuiHandler<'a> {
|
|||
self.needs_update = false;
|
||||
}
|
||||
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
self.command_buffers
|
||||
.chain(&self.render_targets)
|
||||
.chain(&self.text_objects)
|
||||
.chain_mut_1(&self.render_targets)
|
||||
.chain_mut_1(&mut self.text_objects)
|
||||
.unfold()
|
||||
.chain(&self.rectangle_objects)
|
||||
.chain_mut_1(&self.rectangle_objects)
|
||||
.unfold()
|
||||
.chain(&self.single_color_objects)
|
||||
.chain_mut_1(&self.single_color_objects)
|
||||
.unfold()
|
||||
.chain(indices)
|
||||
.chain_mut_1(indices)
|
||||
.unfold()
|
||||
.chain(&self.text_to_screen.pipeline)
|
||||
.chain_mut_1(&self.text_to_screen.pipeline)
|
||||
.unfold()
|
||||
.chain(&self.text_to_screen.descriptor)
|
||||
.chain_mut_1(&self.text_to_screen.descriptor)
|
||||
.unfold()
|
||||
.execute(
|
||||
.execute_into(
|
||||
|(
|
||||
command_buffers,
|
||||
render_target,
|
||||
|
@ -1619,16 +1632,16 @@ impl<'a> GuiHandler<'a> {
|
|||
text_pipeline,
|
||||
text_descriptor,
|
||||
)| {
|
||||
self.render(
|
||||
callback_self.render(
|
||||
buffer_recorder,
|
||||
&command_buffers[****index],
|
||||
&mut command_buffers[***index],
|
||||
render_target,
|
||||
single_color_object,
|
||||
rectangle_objects,
|
||||
text_objects,
|
||||
text_pipeline,
|
||||
text_descriptor,
|
||||
****index,
|
||||
***index,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
@ -1642,9 +1655,8 @@ impl<'a> GuiHandler<'a> {
|
|||
height: u32,
|
||||
images: &TargetMode<Vec<Arc<Image>>>,
|
||||
) -> Result<()> {
|
||||
images
|
||||
.chain(&self.render_targets)
|
||||
.execute(|(images, old_render_target)| {
|
||||
images.chain_mut_2(&mut self.render_targets).execute_into(
|
||||
|(images, old_render_target)| {
|
||||
let new_render_target = Self::create_render_target(
|
||||
&self.device,
|
||||
&images,
|
||||
|
@ -1653,10 +1665,11 @@ impl<'a> GuiHandler<'a> {
|
|||
self.text_sample_count,
|
||||
)?;
|
||||
|
||||
**old_render_target = new_render_target;
|
||||
*old_render_target = new_render_target;
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
|
||||
self.text_to_screen.update_on_resize(&self.render_targets)?;
|
||||
|
||||
|
@ -1666,9 +1679,11 @@ impl<'a> GuiHandler<'a> {
|
|||
self.width = width;
|
||||
self.height = height;
|
||||
|
||||
let callback_self = unsafe { remove_life_time_mut(self) };
|
||||
|
||||
for (_, elements) in self.layers.iter() {
|
||||
for framable in elements.iter_framables() {
|
||||
framable.resize(self)?;
|
||||
framable.resize(callback_self)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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