Skip to content

Commit

Permalink
Expandable player top bar (#142)
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyMeilex authored Feb 2, 2024
1 parent f47c982 commit 13ca99b
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 19 deletions.
8 changes: 8 additions & 0 deletions neothesia/src/scene/playing_scene/animation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// exponential out curve
pub fn expo_out(t: f32) -> f32 {
if t == 1.0 {
1.0
} else {
1.0 - 2.0f32.powf(-10.0 * t)
}
}
12 changes: 12 additions & 0 deletions neothesia/src/scene/playing_scene/midi_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ impl MidiPlayer {
player
}

pub fn song(&self) -> &Song {
&self.song
}

/// When playing: returns midi events
///
/// When paused: returns None
Expand Down Expand Up @@ -144,6 +148,14 @@ impl MidiPlayer {
));
}

pub fn leed_in(&self) -> &Duration {
self.playback.leed_in()
}

pub fn lenght(&self) -> Duration {
self.playback.lenght()
}

pub fn percentage(&self) -> f32 {
self.playback.percentage()
}
Expand Down
29 changes: 12 additions & 17 deletions neothesia/src/scene/playing_scene/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
use midi_file::midly::MidiMessage;
use neothesia_core::render::{GuidelineRenderer, QuadInstance, QuadPipeline};
use neothesia_core::render::{GuidelineRenderer, QuadPipeline};
use std::time::Duration;
use wgpu_jumpstart::{Color, TransformUniform, Uniform};
use wgpu_jumpstart::{TransformUniform, Uniform};
use winit::{
event::{ElementState, KeyEvent, MouseButton, WindowEvent},
keyboard::{Key, NamedKey},
};

use self::top_bar::TopBar;

use super::Scene;
use crate::{
render::WaterfallRenderer, song::Song, target::Target, utils::window::WindowState,
NeothesiaEvent,
};
use crate::{render::WaterfallRenderer, song::Song, target::Target, NeothesiaEvent};

mod keyboard;
use keyboard::Keyboard;
Expand All @@ -25,6 +24,9 @@ use rewind_controller::RewindController;
mod toast_manager;
use toast_manager::ToastManager;

mod animation;
mod top_bar;

pub struct PlayingScene {
keyboard: Keyboard,
notes: WaterfallRenderer,
Expand All @@ -35,6 +37,8 @@ pub struct PlayingScene {
bg_quad_pipeline: QuadPipeline,
quad_pipeline: QuadPipeline,
toast_manager: ToastManager,

top_bar: TopBar,
}

impl PlayingScene {
Expand Down Expand Up @@ -85,18 +89,9 @@ impl PlayingScene {
bg_quad_pipeline: QuadPipeline::new(&target.gpu, &target.transform),
quad_pipeline: QuadPipeline::new(&target.gpu, &target.transform),
toast_manager: ToastManager::default(),
top_bar: TopBar::default(),
}
}

fn update_progresbar(&mut self, window_state: &WindowState) {
let size_x = window_state.logical_size.width * self.player.percentage();
self.quad_pipeline.instances().push(QuadInstance {
position: [0.0, 0.0],
size: [size_x, 5.0],
color: Color::from_rgba8(56, 145, 255, 1.0).into_linear_rgba(),
..Default::default()
});
}
}

impl Scene for PlayingScene {
Expand Down Expand Up @@ -141,7 +136,7 @@ impl Scene for PlayingScene {
self.keyboard
.update(&mut self.quad_pipeline, &mut target.text_renderer);

self.update_progresbar(&target.window_state);
TopBar::update(self, &target.window_state);

self.quad_pipeline.prepare(&target.gpu.queue);
}
Expand Down
2 changes: 1 addition & 1 deletion neothesia/src/scene/playing_scene/rewind_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl RewindController {
(ElementState::Pressed, MouseButton::Left) => {
let pos = &window_state.cursor_logical_position;

if pos.y < 20.0 && !self.is_rewinding() {
if pos.y < 45.0 && !self.is_rewinding() {
self.start_mouse_rewind(player);

let x = window_state.cursor_logical_position.x;
Expand Down
104 changes: 104 additions & 0 deletions neothesia/src/scene/playing_scene/top_bar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use neothesia_core::render::QuadInstance;
use wgpu_jumpstart::Color;

use crate::utils::window::WindowState;

use super::{animation, PlayingScene};

#[derive(Default)]
pub struct TopBar {
animation: f32,
}

macro_rules! color_u8 {
($r: expr, $g: expr, $b: expr, $a: expr) => {
Color::new($r as f32 / 255.0, $g as f32 / 255.0, $b as f32 / 255.0, 1.0)
};
}

const BAR_BG: Color = color_u8!(37, 35, 42, 1.0);
const BLUE: Color = color_u8!(56, 145, 255, 1.0);
const LIGHT_MEASURE: Color = Color::new(1.0, 1.0, 1.0, 0.5);
const DARK_MEASURE: Color = Color::new(0.4, 0.4, 0.4, 1.0);

impl TopBar {
pub fn update(scene: &mut PlayingScene, window_state: &WindowState) {
let top_bar = &mut scene.top_bar;
let quad_pipeline = &mut scene.quad_pipeline;
let player = &scene.player;
let rewind_controler = &scene.rewind_controler;

let h = 45.0;
let w = window_state.logical_size.width;
let progress_x = w * player.percentage();

let is_hovered =
window_state.cursor_logical_position.y < h || rewind_controler.is_rewinding();

if !is_hovered {
quad_pipeline.instances().push(QuadInstance {
position: [0.0, 0.0],
size: [progress_x, 5.0],
color: BLUE.into_linear_rgba(),
..Default::default()
});
}

if is_hovered {
top_bar.animation += 0.04;
} else {
top_bar.animation -= 0.1;
}

top_bar.animation = top_bar.animation.min(1.0);
top_bar.animation = top_bar.animation.max(0.0);

if top_bar.animation == 0.0 {
return;
}

let bar_animation = if is_hovered {
animation::expo_out(top_bar.animation)
} else {
top_bar.animation
};

let y = -h + (bar_animation * h);

quad_pipeline.instances().push(QuadInstance {
position: [0.0, y],
size: [w, h],
color: BAR_BG.into_linear_rgba(),
..Default::default()
});

let progress_x = w * player.percentage();
quad_pipeline.instances().push(QuadInstance {
position: [0.0, y],
size: [progress_x, h],
color: BLUE.into_linear_rgba(),
..Default::default()
});

for m in player.song().file.measures.iter() {
let lenght = player.lenght().as_secs_f32();
let start = player.leed_in().as_secs_f32() / lenght;
let measure = m.as_secs_f32() / lenght;

let x = (start + measure) * w;

let color = if x < progress_x {
LIGHT_MEASURE
} else {
DARK_MEASURE
};

quad_pipeline.instances().push(QuadInstance {
position: [x, y],
size: [1.0, h],
color: color.into_linear_rgba(),
..Default::default()
});
}
}
}
2 changes: 1 addition & 1 deletion wgpu-jumpstart/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub struct Color {
}

impl Color {
pub fn new(r: f32, g: f32, b: f32, a: f32) -> Color {
pub const fn new(r: f32, g: f32, b: f32, a: f32) -> Color {
Color { r, g, b, a }
}

Expand Down

0 comments on commit 13ca99b

Please sign in to comment.