refactor event into its own thing
This commit is contained in:
parent
9a31622002
commit
d04074dc42
10 changed files with 170 additions and 138 deletions
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -236,9 +236,9 @@ checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.4.1"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac"
|
checksum = "5a4bad0c5981acc24bc09e532f35160f952e35422603f0563cd7a73c2c2e65a0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
|
@ -831,6 +831,8 @@ dependencies = [
|
||||||
"bass-sys",
|
"bass-sys",
|
||||||
"ggez",
|
"ggez",
|
||||||
"image",
|
"image",
|
||||||
|
"imgui",
|
||||||
|
"imgui-winit-support",
|
||||||
"libosu",
|
"libosu",
|
||||||
"log",
|
"log",
|
||||||
"num",
|
"num",
|
||||||
|
@ -1292,6 +1294,36 @@ dependencies = [
|
||||||
"tiff",
|
"tiff",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imgui"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92a0077d3bb882960467aed0bc6eaf5d4033cb9b61bfdbb99c32d1288380032f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"imgui-sys",
|
||||||
|
"parking_lot",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imgui-sys"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0522b693da8a64322afbb32c63c04f39d9b9435cc75199d630207eee48886fc1"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "imgui-winit-support"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0669ee7f52b80aa33d5f45507790223380c253a8fd981ddf67d1427ab8ebc8bc"
|
||||||
|
dependencies = [
|
||||||
|
"imgui",
|
||||||
|
"winit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
@ -1444,9 +1476,9 @@ checksum = "3286f09f7d4926fc486334f28d8d2e6ebe4f7f9994494b6dab27ddfad2c9b11b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
version = "0.6.6"
|
version = "0.6.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e9367bdfa836b7e3cf895867f7a570283444da90562980ec2263d6e1569b16bc"
|
checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
|
|
|
@ -23,6 +23,8 @@ num = "0.3.1"
|
||||||
ordered-float = "2.0.1"
|
ordered-float = "2.0.1"
|
||||||
structopt = "0.3.21"
|
structopt = "0.3.21"
|
||||||
image = "0.23.12"
|
image = "0.23.12"
|
||||||
|
imgui = "0.6.1"
|
||||||
|
imgui-winit-support = "0.6.1"
|
||||||
|
|
||||||
[dependencies.libosu]
|
[dependencies.libosu]
|
||||||
git = "https://github.com/iptq/libosu"
|
git = "https://github.com/iptq/libosu"
|
||||||
|
|
|
@ -13,11 +13,11 @@ running on windows
|
||||||
|
|
||||||
wrapper script isn't written yet, in this case i just copied bass.dll to the project root
|
wrapper script isn't written yet, in this case i just copied bass.dll to the project root
|
||||||
|
|
||||||
roadmap
|
feature ideas
|
||||||
-------
|
-------------
|
||||||
|
|
||||||
- [ ] long term:
|
- automatically hiding timeline / seek bar
|
||||||
- [ ] new framework
|
- multiple editor tabs
|
||||||
|
|
||||||
license
|
license
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -4,8 +4,6 @@ use std::ptr;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bass::constants::*;
|
use bass::constants::*;
|
||||||
use libosu::timing::TimestampSec;
|
|
||||||
use ordered_float::NotNan;
|
|
||||||
|
|
||||||
pub struct AudioEngine {
|
pub struct AudioEngine {
|
||||||
current_device: AudioDevice,
|
current_device: AudioDevice,
|
||||||
|
|
122
src/game/events.rs
Normal file
122
src/game/events.rs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
use ggez::{
|
||||||
|
event::{EventHandler, KeyCode, KeyMods, MouseButton},
|
||||||
|
Context, GameError, GameResult,
|
||||||
|
};
|
||||||
|
use libosu::timing::{TimingPoint, TimingPointKind};
|
||||||
|
|
||||||
|
use crate::utils::rect_contains;
|
||||||
|
|
||||||
|
use super::{Game, Tool};
|
||||||
|
|
||||||
|
impl EventHandler for Game {
|
||||||
|
fn update(&mut self, _ctx: &mut Context) -> GameResult {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_motion_event(&mut self, _: &mut Context, x: f32, y: f32, _: f32, _: f32) {
|
||||||
|
self.mouse_pos = (x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_button_down_event(&mut self, _: &mut Context, btn: MouseButton, x: f32, y: f32) {
|
||||||
|
match btn {
|
||||||
|
MouseButton::Left => {
|
||||||
|
use super::seeker::BOUNDS;
|
||||||
|
if rect_contains(&BOUNDS, x, y) {
|
||||||
|
let jump_percent = (x - BOUNDS.x) / BOUNDS.w;
|
||||||
|
if let Some(song) = &self.song {
|
||||||
|
let pos = jump_percent as f64 * song.length().unwrap();
|
||||||
|
song.set_position(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.left_drag_start = Some((x, y));
|
||||||
|
}
|
||||||
|
MouseButton::Right => self.right_drag_start = Some((x, y)),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_button_up_event(&mut self, _: &mut Context, btn: MouseButton, x: f32, y: f32) {
|
||||||
|
match btn {
|
||||||
|
MouseButton::Left => {
|
||||||
|
if let Some((px, py)) = self.left_drag_start {
|
||||||
|
if px == x && py == y {
|
||||||
|
self.handle_click(MouseButton::Left, x, y).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.left_drag_start = None;
|
||||||
|
}
|
||||||
|
MouseButton::Right => {
|
||||||
|
if let Some((px, py)) = self.right_drag_start {
|
||||||
|
if px == x && py == y {
|
||||||
|
self.handle_click(MouseButton::Right, x, y).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.right_drag_start = None;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_wheel_event(&mut self, _: &mut Context, x: f32, y: f32) {
|
||||||
|
self.seek_by_steps(-y as i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_up_event(&mut self, _: &mut Context, keycode: KeyCode, _: KeyMods) {
|
||||||
|
use KeyCode::*;
|
||||||
|
match keycode {
|
||||||
|
Space => self.toggle_playing(),
|
||||||
|
Colon => {}
|
||||||
|
G => {
|
||||||
|
self.toggle_grid();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_down_event(&mut self, _: &mut Context, keycode: KeyCode, mods: KeyMods, _: bool) {
|
||||||
|
use KeyCode::*;
|
||||||
|
self.keymap.insert(keycode);
|
||||||
|
match keycode {
|
||||||
|
Key1 => self.switch_tool_to(Tool::Select),
|
||||||
|
Key2 => self.switch_tool_to(Tool::Circle),
|
||||||
|
Key3 => self.switch_tool_to(Tool::Slider),
|
||||||
|
|
||||||
|
Left => {
|
||||||
|
if let Some(TimingPoint {
|
||||||
|
kind: TimingPointKind::Uninherited(info),
|
||||||
|
..
|
||||||
|
}) = &self.current_uninherited_timing_point
|
||||||
|
{
|
||||||
|
let steps = -if mods.contains(KeyMods::SHIFT) {
|
||||||
|
info.meter as i32
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
self.seek_by_steps(steps).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Right => {
|
||||||
|
if let Some(TimingPoint {
|
||||||
|
kind: TimingPointKind::Uninherited(info),
|
||||||
|
..
|
||||||
|
}) = &self.current_uninherited_timing_point
|
||||||
|
{
|
||||||
|
let steps = if mods.contains(KeyMods::SHIFT) {
|
||||||
|
info.meter as i32
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
self.seek_by_steps(steps).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&mut self, ctx: &mut Context) -> GameResult {
|
||||||
|
if let Err(err) = self.draw_helper(ctx) {
|
||||||
|
return Err(GameError::RenderError(err.to_string()));
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
115
src/game/mod.rs
115
src/game/mod.rs
|
@ -1,4 +1,5 @@
|
||||||
mod background;
|
mod background;
|
||||||
|
mod events;
|
||||||
mod grid;
|
mod grid;
|
||||||
mod numbers;
|
mod numbers;
|
||||||
mod seeker;
|
mod seeker;
|
||||||
|
@ -13,11 +14,11 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ggez::{
|
use ggez::{
|
||||||
event::{EventHandler, KeyCode, KeyMods, MouseButton},
|
event::{KeyCode, MouseButton},
|
||||||
graphics::{
|
graphics::{
|
||||||
self, Color, DrawMode, DrawParam, FilterMode, Image, Mesh, Rect, StrokeOptions, Text, WHITE,
|
self, Color, DrawMode, DrawParam, FilterMode, Image, Mesh, Rect, StrokeOptions, Text, WHITE,
|
||||||
},
|
},
|
||||||
Context, GameError, GameResult,
|
Context,
|
||||||
};
|
};
|
||||||
use image::io::Reader as ImageReader;
|
use image::io::Reader as ImageReader;
|
||||||
use libosu::{
|
use libosu::{
|
||||||
|
@ -56,7 +57,6 @@ pub enum Tool {
|
||||||
Select,
|
Select,
|
||||||
Circle,
|
Circle,
|
||||||
Slider,
|
Slider,
|
||||||
SliderPlacing,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
|
@ -693,115 +693,6 @@ impl Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventHandler for Game {
|
|
||||||
fn update(&mut self, _ctx: &mut Context) -> GameResult {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mouse_motion_event(&mut self, _: &mut Context, x: f32, y: f32, _: f32, _: f32) {
|
|
||||||
self.mouse_pos = (x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mouse_button_down_event(&mut self, _: &mut Context, btn: MouseButton, x: f32, y: f32) {
|
|
||||||
match btn {
|
|
||||||
MouseButton::Left => {
|
|
||||||
use self::seeker::BOUNDS;
|
|
||||||
if rect_contains(&BOUNDS, x, y) {
|
|
||||||
let jump_percent = (x - BOUNDS.x) / BOUNDS.w;
|
|
||||||
if let Some(song) = &self.song {
|
|
||||||
let pos = jump_percent as f64 * song.length().unwrap();
|
|
||||||
song.set_position(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.left_drag_start = Some((x, y));
|
|
||||||
}
|
|
||||||
MouseButton::Right => self.right_drag_start = Some((x, y)),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mouse_button_up_event(&mut self, _: &mut Context, btn: MouseButton, x: f32, y: f32) {
|
|
||||||
match btn {
|
|
||||||
MouseButton::Left => {
|
|
||||||
if let Some((px, py)) = self.left_drag_start {
|
|
||||||
if px == x && py == y {
|
|
||||||
self.handle_click(MouseButton::Left, x, y).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.left_drag_start = None;
|
|
||||||
}
|
|
||||||
MouseButton::Right => {
|
|
||||||
if let Some((px, py)) = self.right_drag_start {
|
|
||||||
if px == x && py == y {
|
|
||||||
self.handle_click(MouseButton::Right, x, y).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.right_drag_start = None;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn key_up_event(&mut self, _: &mut Context, keycode: KeyCode, _: KeyMods) {
|
|
||||||
use KeyCode::*;
|
|
||||||
match keycode {
|
|
||||||
Space => self.toggle_playing(),
|
|
||||||
Colon => {}
|
|
||||||
G => {
|
|
||||||
self.toggle_grid();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn key_down_event(&mut self, _: &mut Context, keycode: KeyCode, mods: KeyMods, _: bool) {
|
|
||||||
use KeyCode::*;
|
|
||||||
self.keymap.insert(keycode);
|
|
||||||
match keycode {
|
|
||||||
Key1 => self.switch_tool_to(Tool::Select),
|
|
||||||
Key2 => self.switch_tool_to(Tool::Circle),
|
|
||||||
Key3 => self.switch_tool_to(Tool::Slider),
|
|
||||||
|
|
||||||
Left => {
|
|
||||||
if let Some(TimingPoint {
|
|
||||||
kind: TimingPointKind::Uninherited(info),
|
|
||||||
..
|
|
||||||
}) = &self.current_uninherited_timing_point
|
|
||||||
{
|
|
||||||
let steps = -if mods.contains(KeyMods::SHIFT) {
|
|
||||||
info.meter as i32
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
self.seek_by_steps(steps).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Right => {
|
|
||||||
if let Some(TimingPoint {
|
|
||||||
kind: TimingPointKind::Uninherited(info),
|
|
||||||
..
|
|
||||||
}) = &self.current_uninherited_timing_point
|
|
||||||
{
|
|
||||||
let steps = if mods.contains(KeyMods::SHIFT) {
|
|
||||||
info.meter as i32
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
self.seek_by_steps(steps).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw(&mut self, ctx: &mut Context) -> GameResult {
|
|
||||||
if let Err(err) = self.draw_helper(ctx) {
|
|
||||||
return Err(GameError::RenderError(err.to_string()));
|
|
||||||
};
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn upgrade_slider_type(initial_type: SliderSplineKind, after_len: usize) -> SliderSplineKind {
|
fn upgrade_slider_type(initial_type: SliderSplineKind, after_len: usize) -> SliderSplineKind {
|
||||||
match (initial_type, after_len) {
|
match (initial_type, after_len) {
|
||||||
(SliderSplineKind::Linear, 3) => SliderSplineKind::Perfect,
|
(SliderSplineKind::Linear, 3) => SliderSplineKind::Perfect,
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ggez::{
|
use ggez::{graphics::DrawParam, Context};
|
||||||
graphics::{self, DrawParam},
|
|
||||||
Context,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::Game;
|
use super::Game;
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,7 @@ use ggez::{
|
||||||
mint::Point2,
|
mint::Point2,
|
||||||
Context,
|
Context,
|
||||||
};
|
};
|
||||||
use libosu::{
|
use libosu::{beatmap::Beatmap, hitobject::SliderInfo, math::Point, spline::Spline};
|
||||||
beatmap::Beatmap,
|
|
||||||
hitobject::{HitObject, SliderInfo},
|
|
||||||
math::Point,
|
|
||||||
spline::Spline,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{Game, SliderCache};
|
use super::{Game, SliderCache};
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,7 @@ use ggez::{
|
||||||
mint::Point2,
|
mint::Point2,
|
||||||
Context,
|
Context,
|
||||||
};
|
};
|
||||||
use libosu::{
|
use libosu::{hitobject::HitObjectKind, timing::TimingPointKind};
|
||||||
hitobject::HitObjectKind,
|
|
||||||
timing::{Duration, TimestampSec, TimingPointKind},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::hitobject::HitObjectExt;
|
use crate::hitobject::HitObjectExt;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ggez::{
|
use ggez::{
|
||||||
graphics::{self, DrawParam, Image},
|
graphics::{self, DrawParam, Image},
|
||||||
|
|
Loading…
Reference in a new issue