From f4ad2cd9558955fe5360ea296f4dcfbac760c069 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Sun, 6 Jul 2025 17:24:01 -0700 Subject: [PATCH] Add dialog scrolling, docstrings on systems --- flake.nix | 2 ++ src/bin/trees/main.rs | 51 ++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 9 ++++++-- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 44b76ef..5ed92ab 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,8 @@ # Rustup rustup wayland # To use the wayland feature + # Bug tracking + git-bug ]; LD_LIBRARY_PATH = lib.makeLibraryPath [ alsa-lib diff --git a/src/bin/trees/main.rs b/src/bin/trees/main.rs index a71278e..8ffad02 100644 --- a/src/bin/trees/main.rs +++ b/src/bin/trees/main.rs @@ -12,14 +12,22 @@ fn main() { ) .add_systems( Update, - dialog_engine.run_if(input_just_pressed(KeyCode::KeyN)), + ( + dialog_engine.run_if(input_just_pressed(KeyCode::KeyN)), + mouse_wheel_scroll.run_if(on_event::), + auto_scroll.run_if(any_component_added::) + ), ) .run(); } +/// Tree marker component #[derive(Component)] struct Tree; +/// Initialize the trees, currently placeholders +/// Trees are 2d cards in a 3d world for flexibility +/// Might move fully 2d if the art style allows it fn init_trees( mut commands: Commands, mut meshes: ResMut>, @@ -88,9 +96,11 @@ fn init_trees( } } +/// Dialog box marker component #[derive(Component)] struct DialogBox; +/// Initialize the UI which consists soley of a dialog box (for now?) fn init_ui(mut commands: Commands) { commands.spawn(( DialogBox, @@ -104,11 +114,15 @@ fn init_ui(mut commands: Commands) { margin: UiRect::all(Val::Percent(1.0)), padding: UiRect::all(Val::Percent(1.0)), flex_direction: FlexDirection::Column, + // Scroll on the Y axis + overflow: Overflow::scroll_y(), ..default() }, )); } +/// On startup move the camera to a suitable position +/// This should be mostly static for the entire game fn position_camera(mut query: Query<&mut Transform, (With, With)>) { use std::f32::consts::PI; @@ -118,12 +132,15 @@ fn position_camera(mut query: Query<&mut Transform, (With, With>, @@ -152,6 +169,10 @@ fn dialog_engine( *idx += 1; } +/// When a dialog option is chosen (clicked on) we do the following: +/// 1. Remove the Button and DialogOption components from that entity +/// 2. Insert the DialogLine component to that entity +/// 3. Remove all other DialogOptions from the DialogBox fn choose_dialog(trigger: Trigger>, mut commands: Commands) { info!("Choosing dialog {:?}", trigger.target()); commands @@ -160,3 +181,31 @@ fn choose_dialog(trigger: Trigger>, mut commands: Commands) { .remove::() .insert(DialogLine); } + +/// Allows user to scroll (with mouse whell) through old dialog +fn mouse_wheel_scroll( + mut events: EventReader, + mut scroll_position: Query<&mut ScrollPosition>, +) { + events.read().for_each(|MouseWheel { unit, y, .. }| { + let offset_y = match unit { + MouseScrollUnit::Line => 10.0 * y, + MouseScrollUnit::Pixel => 1.0 * y, + }; + scroll_position + .iter_mut() + .for_each(|mut pos| pos.offset_y += offset_y); + }); +} + +/// Automatically scrolls dialog when a new batch of options are added +fn auto_scroll( + added: Query>, + mut scroll_positions: Query<&mut ScrollPosition>, +) { + debug_assert!(!added.is_empty(), "Should only scroll when dialog options are added"); + + scroll_positions.iter_mut().for_each(|mut sp| { + sp.offset_y = f32::MAX; + }); +} diff --git a/src/lib.rs b/src/lib.rs index 3766542..bf1b60c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,8 +12,13 @@ pub use std::fmt::Display; pub use bevy::{ asset::LoadState, color::palettes::css::{BLACK, BLUE, GREEN, RED, WHITE}, - input::common_conditions::{input_just_pressed, input_pressed}, - input::{ButtonState, keyboard::KeyboardInput, mouse::MouseMotion}, + input::{ + ButtonState, + common_conditions::{input_just_pressed, input_pressed}, + keyboard::KeyboardInput, + mouse::MouseMotion, + mouse::{MouseScrollUnit, MouseWheel}, + }, prelude::*, }; pub use bevy_rapier3d::prelude::*;