155 lines
4.6 KiB
Rust
155 lines
4.6 KiB
Rust
use std::{collections::HashMap, rc::Rc};
|
|
|
|
use wgui::{
|
|
components::button::ComponentButton, event::CallbackDataCommon, layout::WidgetID,
|
|
parser::Fetchable, renderer_vk::text::custom_glyph::CustomGlyphData,
|
|
widget::sprite::WidgetSprite,
|
|
};
|
|
|
|
use crate::{
|
|
backend::task::OverlayTask, overlays::edit::EditModeWrapPanel, state::LeftRight,
|
|
windowing::window::Positioning,
|
|
};
|
|
|
|
static POS_NAMES: [&str; 6] = ["static", "anchored", "floating", "hmd", "hand_l", "hand_r"];
|
|
|
|
struct PosButtonState {
|
|
name: &'static str,
|
|
sprite: CustomGlyphData,
|
|
component: Rc<ComponentButton>,
|
|
positioning: Positioning,
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub(super) struct PositioningHandler {
|
|
top_sprite_id: WidgetID,
|
|
buttons: HashMap<&'static str, Rc<PosButtonState>>,
|
|
active_button: Option<Rc<PosButtonState>>,
|
|
}
|
|
|
|
impl PositioningHandler {
|
|
pub fn new(panel: &mut EditModeWrapPanel) -> anyhow::Result<Self> {
|
|
let mut buttons = HashMap::new();
|
|
|
|
for name in &POS_NAMES {
|
|
let button_id = format!("pos_{name}");
|
|
let component = panel.parser_state.fetch_component_as(&button_id)?;
|
|
|
|
let sprite_id = format!("{button_id}_sprite");
|
|
let id = panel.parser_state.get_widget_id(&sprite_id)?;
|
|
let sprite_w = panel
|
|
.layout
|
|
.state
|
|
.widgets
|
|
.get_as::<WidgetSprite>(id)
|
|
.ok_or_else(|| {
|
|
anyhow::anyhow!("Element with id=\"{sprite_id}\" must be a <sprite>")
|
|
})?;
|
|
|
|
let sprite = sprite_w.params.glyph_data.clone().ok_or_else(|| {
|
|
anyhow::anyhow!("Element with id=\"{sprite_id}\" must have a valid src!")
|
|
})?;
|
|
|
|
buttons.insert(
|
|
*name,
|
|
Rc::new(PosButtonState {
|
|
component,
|
|
name,
|
|
sprite,
|
|
positioning: key_to_pos(name),
|
|
}),
|
|
);
|
|
}
|
|
|
|
let top_sprite_id = panel.parser_state.get_widget_id("top_pos_sprite")?;
|
|
Ok(Self {
|
|
buttons,
|
|
active_button: None,
|
|
top_sprite_id,
|
|
})
|
|
}
|
|
|
|
fn change_highlight(&mut self, common: &mut CallbackDataCommon, key: &str) {
|
|
if let Some(old) = self.active_button.take() {
|
|
old.component.set_sticky_state(common, false);
|
|
}
|
|
let new = self.buttons.get_mut(key).unwrap();
|
|
new.component.set_sticky_state(common, true);
|
|
self.active_button = Some(new.clone());
|
|
|
|
// change top sprite
|
|
if let Some(mut sprite) = common
|
|
.state
|
|
.widgets
|
|
.get_as::<WidgetSprite>(self.top_sprite_id)
|
|
{
|
|
sprite.params.glyph_data = Some(new.sprite.clone());
|
|
}
|
|
}
|
|
|
|
pub fn pos_button_clicked(
|
|
&mut self,
|
|
common: &mut CallbackDataCommon,
|
|
key: &str,
|
|
) -> Box<OverlayTask> {
|
|
self.change_highlight(common, key);
|
|
|
|
let pos = key_to_pos(key);
|
|
Box::new(move |app, owc| {
|
|
let state = owc.active_state.as_mut().unwrap(); //want panic
|
|
state.positioning = pos;
|
|
state.save_transform(app);
|
|
})
|
|
}
|
|
|
|
pub fn reset(&mut self, common: &mut CallbackDataCommon, pos: Positioning) {
|
|
let key = pos_to_key(pos);
|
|
self.change_highlight(common, key);
|
|
}
|
|
}
|
|
|
|
fn key_to_pos(key: &str) -> Positioning {
|
|
match key {
|
|
"static" => Positioning::Static,
|
|
"anchored" => Positioning::Anchored,
|
|
"floating" => Positioning::Floating,
|
|
"hmd" => Positioning::FollowHead { lerp: 1.0 },
|
|
"hand_l" => Positioning::FollowHand {
|
|
hand: LeftRight::Left,
|
|
lerp: 1.0,
|
|
},
|
|
"hand_r" => Positioning::FollowHand {
|
|
hand: LeftRight::Right,
|
|
lerp: 1.0,
|
|
},
|
|
_ => {
|
|
panic!("cannot translate to positioning: {key}")
|
|
}
|
|
}
|
|
}
|
|
|
|
const fn pos_to_key(pos: Positioning) -> &'static str {
|
|
match pos {
|
|
Positioning::Static => "static",
|
|
Positioning::Anchored => "anchored",
|
|
Positioning::Floating => "floating",
|
|
Positioning::FollowHead { .. } | Positioning::FollowHeadPaused { .. } => "hmd",
|
|
Positioning::FollowHand {
|
|
hand: LeftRight::Left,
|
|
..
|
|
}
|
|
| Positioning::FollowHandPaused {
|
|
hand: LeftRight::Left,
|
|
..
|
|
} => "hand_l",
|
|
Positioning::FollowHand {
|
|
hand: LeftRight::Right,
|
|
..
|
|
}
|
|
| Positioning::FollowHandPaused {
|
|
hand: LeftRight::Right,
|
|
..
|
|
} => "hand_r",
|
|
}
|
|
}
|