Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expandable player top bar #142

Merged
merged 1 commit into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading