diff --git a/src/lib.rs b/src/lib.rs index 4ab61cd..f761d2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,9 +12,9 @@ pub(crate) mod structure; use crate::client::{poll_websocket_stream, setup_websocket_stream}; use crate::io::load_crystal; use crate::structure::{update_crystal_system, UpdateStructure}; -use crate::ui::{camera_controls, refresh_atoms_system, setup_cameras, setup_scene}; +use crate::ui::reset_camera_button_interaction; use crate::ui::{ - handle_toggle_events, reset_camera_button_interaction, toggle_button, ToggleEvent, ToggleStates, + camera_controls, refresh_atoms_system, setup_cameras, setup_scene, toggle_light_attachment, }; use crate::ui::{setup_buttons, spawn_axis}; @@ -36,9 +36,7 @@ pub fn run_app() { filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(), custom_layer: |_| None, })) - .init_resource::() .add_event::() - .add_event::() .add_systems(Startup, load_crystal) .add_systems(Startup, setup_scene.after(load_crystal)) .add_systems( @@ -57,9 +55,8 @@ pub fn run_app() { poll_websocket_stream, update_crystal_system, refresh_atoms_system, - toggle_button, + toggle_light_attachment, reset_camera_button_interaction, - handle_toggle_events, camera_controls, ), ) diff --git a/src/ui.rs b/src/ui.rs index 93e1df9..718cd02 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,3 +1,5 @@ +#![allow(clippy::needless_pass_by_value)] + use std::collections::HashMap; use bevy::input::mouse::{MouseMotion, MouseWheel}; @@ -14,45 +16,13 @@ const LAYER_CANVAS: RenderLayers = RenderLayers::layer(0); #[derive(Component)] pub(crate) struct MainCamera; -/// Identifier for a reusable toggle interaction. -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -enum ToggleId { - LightAttachment, -} - -// struct AmbientLight - -impl ToggleId { - fn label(self, state: bool) -> &'static str { - match (self, state) { - (ToggleId::LightAttachment, true) => "Light: Attached", - (ToggleId::LightAttachment, false) => "Light: Detached", - } - } -} - -// XXX: REVIEW: this is very oop like implementation, better? - -/// Stores the current on/off state for each toggle. -#[derive(Resource, Default)] -pub(crate) struct ToggleStates { - states: HashMap, -} - -impl ToggleStates { - fn register(&mut self, id: ToggleId, initial_state: bool) { - self.states.entry(id).or_insert(initial_state); - } - - fn get(&self, id: ToggleId) -> bool { - self.states.get(&id).copied().unwrap_or(false) - } +/// Button that resets the camera to its original position/orientation. +#[derive(Component)] +pub(crate) struct ResetCameraButton; - fn toggle(&mut self, id: ToggleId) -> bool { - let new_state = !self.get(id); - self.states.insert(id, new_state); - new_state - } +#[derive(Component)] +pub(crate) struct LightAttachmentButton { + attached: bool, } /// Marks an entity that spawned the main camera. @@ -63,25 +33,6 @@ pub(crate) struct MainCameraEntity(pub Entity); #[derive(Resource)] pub(crate) struct MainLightEntity(pub Entity); -/// Component identifying a toggle button instance. -#[derive(Component)] -pub(crate) struct ToggleButton { - id: ToggleId, -} - -/// Component carried by the text to update when a toggle changes. -#[derive(Component)] -pub(crate) struct ToggleText { - id: ToggleId, -} - -/// Event emitted whenever a toggle switches state. -#[derive(Event)] -pub struct ToggleEvent { - id: ToggleId, - pub state: bool, -} - /// Stores camera orbit information and the original configuration so it can be restored. #[derive(Resource)] pub(crate) struct CameraRig { @@ -93,10 +44,6 @@ pub(crate) struct CameraRig { initial_scale: Vec3, } -/// Button that resets the camera to its original position/orientation. -#[derive(Component)] -pub(crate) struct ResetCameraButton; - // System to set up the 3D scene pub(crate) fn setup_scene( mut commands: Commands, @@ -148,11 +95,7 @@ pub(crate) fn setup_scene( } // System to set up the camera -pub fn setup_cameras( - mut commands: Commands, - mut toggle_states: ResMut, - windows: Query<&Window>, -) { +pub fn setup_cameras(mut commands: Commands, windows: Query<&Window>) { let window = windows.single().unwrap(); let viewport_size = UVec2::new(200, 200); let bottom_left_y = window.physical_height() - viewport_size.y - 10; @@ -219,8 +162,6 @@ pub fn setup_cameras( )) .id(); - toggle_states.register(ToggleId::LightAttachment, true); - commands.insert_resource(MainCameraEntity(camera_entity)); commands.insert_resource(MainLightEntity(light_entity)); commands.insert_resource(CameraRig { @@ -234,7 +175,7 @@ pub fn setup_cameras( } // Setup minimal UI with toggle buttons -pub fn setup_buttons(mut commands: Commands, toggle_states: Res) { +pub fn setup_buttons(mut commands: Commands) { // buttons at top-left commands .spawn(( @@ -249,38 +190,29 @@ pub fn setup_buttons(mut commands: Commands, toggle_states: Res) { BackgroundColor(Color::NONE), )) .with_children(|parent| { - let mut spawn_button = |id: ToggleId| { - let state = toggle_states.get(id); - let label = id.label(state); - - parent - .spawn(( - Button, - Node { - padding: UiRect::axes(Val::Px(10.0), Val::Px(6.0)), - border: UiRect::all(Val::Px(1.0)), + parent + .spawn(( + Button, + Node { + padding: UiRect::axes(Val::Px(10.0), Val::Px(6.0)), + border: UiRect::all(Val::Px(1.0)), + ..default() + }, + BorderColor(Color::srgb(0.3, 0.3, 0.3)), + BackgroundColor(Color::srgb(0.15, 0.15, 0.15)), + LightAttachmentButton { attached: false }, + )) + .with_children(|button| { + button.spawn(( + Text::new("Light: Detached"), + TextFont { + font: default(), + font_size: 12.0, ..default() }, - BorderColor(Color::srgb(0.3, 0.3, 0.3)), - BackgroundColor(Color::srgb(0.15, 0.15, 0.15)), - ToggleButton { id }, - )) - .with_children(|button| { - button.spawn(( - Text::new(label), - TextFont { - font: default(), - font_size: 12.0, - ..default() - }, - TextColor(Color::WHITE), - ToggleText { id }, - )); - }); - }; - - let id = ToggleId::LightAttachment; - spawn_button(id); + TextColor(Color::WHITE), + )); + }); parent .spawn(( @@ -491,33 +423,47 @@ pub(crate) fn camera_controls( } } -// Handle button interaction: toggle state and update label #[allow(clippy::type_complexity)] -pub fn toggle_button( +pub fn toggle_light_attachment( + mut commands: Commands, + light: Res, + camera: Res, mut interactions: Query< - (&Interaction, &mut BackgroundColor, &ToggleButton), - (Changed, With