Skip to content

Commit

Permalink
wip: add initial UI zoom
Browse files Browse the repository at this point in the history
  • Loading branch information
cilki committed Jul 25, 2024
1 parent 1893da3 commit de05c7c
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 49 deletions.
2 changes: 2 additions & 0 deletions sandpolis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ layer-inventory = []
layer-account = []
layer-logging = []
layer-meta = []

default = [ "layer-desktop", "layer-filesystem", "layer-shell", "layer-inventory", "layer-account", "layer-logging", "layer-meta" ]
6 changes: 1 addition & 5 deletions sandpolis/src/agent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,7 @@

use anyhow::{bail, Result};
use clap::Parser;
use std::collections::HashMap;
use std::io::{BufRead, IsTerminal};
use std::net::TcpStream;
use std::{thread, time};
use tracing::{debug, error, info};
use std::io::{IsTerminal};

use crate::core::database::Database;
use crate::CommandLine;
Expand Down
63 changes: 37 additions & 26 deletions sandpolis/src/client/ui/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ use bevy::{
touch::TouchPhase,
},
prelude::*,
window::{AppLifecycle, WindowMode},
};
use bevy_egui::EguiContexts;
use std::ops::{Add, Range};
use std::ops::Range;

use crate::core::Layer;

use super::{CurrentLayer, LayerChangeTimer};
use super::{CurrentLayer, ZoomLevel};

#[derive(Resource)]
pub struct MousePressed(pub bool);

#[derive(Resource, Deref, DerefMut)]
pub struct LayerChangeTimer(pub Timer);

// #[cfg(target_os = "android")]
pub fn touch_camera(
windows: Query<&Window>,
Expand Down Expand Up @@ -54,24 +56,42 @@ pub fn touch_camera(

const CAMERA_KEYBOARD_ZOOM_SPEED: f32 = 1.0;
const CAMERA_MOUSE_WHEEL_ZOOM_SPEED: f32 = 0.25;
const CAMERA_ZOOM_RANGE: Range<f32> = 1.0..12.0;
const CAMERA_ZOOM_RANGE: Range<f32> = 0.5..2.0;
const SPRITE_SIZE: f32 = 32.0;

/// Handle zooming using the mouse wheel or keyboard.
pub fn handle_zoom(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut mouse_wheel_input: EventReader<MouseWheel>,
mut zoom_level: ResMut<ZoomLevel>,
mut sprites: Query<&mut Sprite>,
) {
let mut zoom_delta = 0.0;
for mouse_wheel_event in mouse_wheel_input.read() {
zoom_delta -= mouse_wheel_event.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
}

if zoom_delta != 0.0 {
**zoom_level =
(zoom_level.0 + zoom_delta).clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end);

for mut sprite in sprites.iter_mut() {
sprite.custom_size = Some(Vec2 {
x: zoom_level.0 * SPRITE_SIZE,
y: zoom_level.0 * SPRITE_SIZE,
});
}
}
}

/// Handle camera movement (panning) using the mouse or keyboard.
pub fn handle_camera(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut mouse_button_events: EventReader<MouseButtonInput>,
mut mouse_motion_events: EventReader<MouseMotion>,
mut mouse_wheel_input: EventReader<MouseWheel>,
mut mouse_pressed: ResMut<MousePressed>,
mut cameras: Query<&mut Transform, With<Camera2d>>,
) {
let mut distance_delta = 0.0;

// Handle mouse events.
for mouse_wheel_event in mouse_wheel_input.read() {
distance_delta -= mouse_wheel_event.y * CAMERA_MOUSE_WHEEL_ZOOM_SPEED;
}

// Update transforms.
for mut camera_transform in cameras.iter_mut() {
// Handle keyboard events.
Expand All @@ -88,19 +108,6 @@ pub fn handle_camera(
camera_transform.translation.x += CAMERA_KEYBOARD_ZOOM_SPEED;
}

let local_z = camera_transform.local_z().as_vec3().normalize_or_zero();

if distance_delta != 0.0 {
// TODO z position doesn't work in 2D
camera_transform.translation = (camera_transform.translation.length() + distance_delta)
.clamp(CAMERA_ZOOM_RANGE.start, CAMERA_ZOOM_RANGE.end)
* local_z;
debug!(
position = ?camera_transform.translation,
"Moved camera position"
);
}

// Store left-pressed state in the MousePressed resource
for button_event in mouse_button_events.read() {
if button_event.button != MouseButton::Left {
Expand All @@ -126,6 +133,8 @@ pub fn handle_keymap(
) {
if keyboard_input.pressed(KeyCode::KeyK) {
let window_size = windows.single_mut().size();

// TODO separate window for layers and highlight active (HUD)
egui::Window::new("Keyboard shortcuts")
.id(egui::Id::new("keymap"))
.pivot(egui::Align2::CENTER_CENTER)
Expand All @@ -141,13 +150,14 @@ pub fn handle_keymap(
ui.label("> - Next layer");
ui.label("< - Previous layer");
ui.label("M - Meta layer");
ui.label("F - Filesystem layer");
});
}
}

/// Switch to another layer from keypress
pub fn handle_layer_change(
mut commands: Commands,
commands: Commands,
mut contexts: EguiContexts,
keyboard_input: Res<ButtonInput<KeyCode>>,
mut current_layer: ResMut<CurrentLayer>,
Expand All @@ -164,6 +174,7 @@ pub fn handle_layer_change(
// Now show the current layer for a few seconds
if !timer.tick(time.delta()).finished() {
let window_size = windows.single_mut().size();
// TODO util
egui::Window::new("Current layer")
.id(egui::Id::new("current_layer"))
.pivot(egui::Align2::CENTER_CENTER)
Expand Down
6 changes: 3 additions & 3 deletions sandpolis/src/client/ui/layer/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ pub fn check_layer_active(current_layer: Res<CurrentLayer>) -> bool {
}

pub fn handle_layer(
mut commands: Commands,
commands: Commands,
mut contexts: EguiContexts,
mut nodes: Query<(&mut Transform, &NodeId), With<NodeId>>,
mut windows: Query<&mut Window>,
mut cameras: Query<&Transform, (With<Camera2d>, Without<NodeId>)>,
cameras: Query<&Transform, (With<Camera2d>, Without<NodeId>)>,
) {
let window_size = windows.single_mut().size();
let camera_transform = cameras.single();

for (mut transform, id) in nodes.iter_mut() {
for (transform, id) in nodes.iter_mut() {
egui::Window::new("Hello")
.movable(false)
.resizable(false)
Expand Down
17 changes: 8 additions & 9 deletions sandpolis/src/client/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
use bevy::{
color::palettes::basic::*,
input::{
gestures::RotationGesture,
mouse::{MouseButtonInput, MouseMotion, MouseWheel},
touch::TouchPhase,
},
prelude::*,
window::{AppLifecycle, WindowMode},
};
use bevy_egui::{EguiContexts, EguiPlugin};
use bevy_rapier2d::prelude::*;
use std::ops::{Add, Range};

use crate::core::{database::Database, Layer};

use self::{input::MousePressed, node::spawn_node};
use self::{
input::{LayerChangeTimer, MousePressed},
node::spawn_node,
};

pub mod input;
pub mod layer;
Expand All @@ -29,7 +26,7 @@ pub struct AppState {
pub struct CurrentLayer(Layer);

#[derive(Resource, Deref, DerefMut)]
pub struct LayerChangeTimer(Timer);
pub struct ZoomLevel(f32);

/// Initialize and start rendering the UI.
pub fn run(state: AppState) {
Expand Down Expand Up @@ -57,6 +54,7 @@ pub fn run(state: AppState) {
.add_plugins(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))
.add_plugins(RapierDebugRenderPlugin::default())
.insert_resource(CurrentLayer(Layer::Desktop))
.insert_resource(ZoomLevel(1.0))
.insert_resource(LayerChangeTimer(Timer::from_seconds(3.0, TimerMode::Once)))
.insert_resource(state)
.insert_resource(MousePressed(false))
Expand All @@ -65,6 +63,7 @@ pub fn run(state: AppState) {
Update,
(
// touch_camera,
self::input::handle_zoom,
self::input::handle_camera,
self::input::handle_keymap,
self::input::handle_layer_change,
Expand Down Expand Up @@ -92,7 +91,7 @@ fn setup(
mut rapier_config: ResMut<RapierConfiguration>,
asset_server: Res<AssetServer>,
state: Res<AppState>,
mut contexts: EguiContexts,
contexts: EguiContexts,
) {
rapier_config.gravity = Vec2::ZERO;
commands.spawn(Camera2dBundle::default());
Expand Down
1 change: 0 additions & 1 deletion sandpolis/src/client/ui/node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use bevy::prelude::*;
use bevy_egui::EguiContexts;
use bevy_rapier2d::{
dynamics::RigidBody,
geometry::{Collider, Restitution},
Expand Down
2 changes: 1 addition & 1 deletion sandpolis/src/core/random.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::num::NonZeroU32;

use rand::distributions::{Alphanumeric, DistString};
use rand::{thread_rng, Rng};
use rand::{Rng};

pub fn next_alphanumeric(length: usize) -> String {
Alphanumeric.sample_string(&mut rand::thread_rng(), length)
Expand Down
8 changes: 4 additions & 4 deletions sandpolis/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use anyhow::Result;
use clap::Parser;
use futures::{future::join_all, Future};
use futures::Future;
use sandpolis::CommandLine;
use std::{net::SocketAddr, path::PathBuf, pin::Pin, process::ExitCode};
use tracing::{debug, info};
use std::process::ExitCode;
use tracing::info;

#[tokio::main]
async fn main() -> Result<ExitCode> {
Expand Down Expand Up @@ -37,5 +37,5 @@ async fn main() -> Result<ExitCode> {
#[cfg(feature = "agent")]
tokio::join!(agent_thread).0??;

Ok(ExitCode::SUCCESS)
bail!("No instance was enabled at build time");
}

0 comments on commit de05c7c

Please sign in to comment.