Skip to content

Commit

Permalink
Use Nuon for the playback progressbar (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyMeilex authored Jun 29, 2024
1 parent e20b983 commit 68fb849
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 25 deletions.
68 changes: 47 additions & 21 deletions neothesia/src/scene/playing_scene/top_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum Msg {
PlayResume,
LooperToggle,
SettingsToggle,
ProggresBarPressed,
LoopTickDrag(LooperDrag),
}

Expand Down Expand Up @@ -60,6 +61,9 @@ pub struct TopBar {
loop_button: Button,
settings_button: Button,

progress_bar_bbox: nuon::Rect,
progress_bar: nuon::ElementId,

loop_start_tick: Bbox,
loop_start_tick_id: nuon::ElementId,

Expand Down Expand Up @@ -136,6 +140,12 @@ impl TopBar {
.on_click(Msg::SettingsToggle),
);

let progress_bar = elements.insert(
nuon::ElementBuilder::new()
.name("ProgressBar")
.on_click(Msg::ProggresBarPressed),
);

let loop_start_tick_id = elements.insert(
nuon::ElementBuilder::new()
.name("LoopStartTick")
Expand Down Expand Up @@ -172,6 +182,8 @@ impl TopBar {
.delay(30.0),
is_expanded: false,
settings_animation: Animation::new(),
progress_bar_bbox: nuon::Rect::zero(),
progress_bar,
loop_start_tick: Bbox::default(),
loop_end_tick_id,
loop_end_tick: Bbox::default(),
Expand Down Expand Up @@ -201,6 +213,20 @@ impl TopBar {
Msg::LoopTickDrag(side) => {
scene.top_bar.drag = Some(side);
}
Msg::ProggresBarPressed => {
if !scene.rewind_controller.is_rewinding() {
scene
.rewind_controller
.start_mouse_rewind(&mut scene.player);

let x = ctx.window_state.cursor_logical_position.x;
let w = ctx.window_state.logical_size.width;

let p = x / w;
scene.player.set_percentage_time(p);
scene.keyboard.reset_notes();
}
}
}
}

Expand Down Expand Up @@ -243,26 +269,6 @@ impl TopBar {
Self::on_msg(scene, ctx, msg.clone());
return EVENT_CAPTURED;
}

let pos = &ctx.window_state.cursor_logical_position;

if pos.y > 30.0
&& pos.y < scene.top_bar.bbox.h()
&& !scene.rewind_controller.is_rewinding()
{
scene
.rewind_controller
.start_mouse_rewind(&mut scene.player);

let x = ctx.window_state.cursor_logical_position.x;
let w = ctx.window_state.logical_size.width;

let p = x / w;
log::debug!("Progressbar: x:{},p:{}", x, p);
scene.player.set_percentage_time(p);
scene.keyboard.reset_notes();
return EVENT_CAPTURED;
}
}
(ElementState::Released, MouseButton::Left) => {
scene.top_bar.drag = None;
Expand Down Expand Up @@ -369,7 +375,27 @@ fn update_proggress_bar(scene: &mut PlayingScene, _text: &mut TextRenderer, _now
let w = top_bar.bbox.w();

let progress_x = w * player.percentage();
draw_rect(quad_pipeline, &Bbox::new([0.0, y], [progress_x, h]), &BLUE);

top_bar.progress_bar_bbox.origin = (0.0, y).into();
top_bar.progress_bar_bbox.size = (w, h).into();

if top_bar.last_frame_bbox != top_bar.bbox {
top_bar
.elements
.update(top_bar.progress_bar, top_bar.progress_bar_bbox)
}

draw_rect(
quad_pipeline,
&Bbox::new(
[
top_bar.progress_bar_bbox.origin.x,
top_bar.progress_bar_bbox.origin.y,
],
[progress_x, top_bar.progress_bar_bbox.size.height],
),
&BLUE,
);

for m in player.song().file.measures.iter() {
let length = player.length().as_secs_f32();
Expand Down
16 changes: 12 additions & 4 deletions nuon/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,15 @@ mod elements_map {
#[derive(Debug, Default)]
pub struct ElementsMap<M> {
elements: thunderdome::Arena<Element<M>>,
zorder: Vec<ElementId>,
hovered: Option<ElementId>,
}

impl<M> ElementsMap<M> {
pub fn new() -> Self {
Self {
elements: thunderdome::Arena::new(),
zorder: Vec::new(),
hovered: None,
}
}
Expand All @@ -119,8 +121,9 @@ mod elements_map {
element.rect = rect;
}

fn listen_for_mouse(&mut self, _id: ElementId) {
// TODO: Track stacking order in a vec
fn listen_for_mouse(&mut self, id: ElementId) {
// TODO: Make this smarter
self.zorder.push(id);
}

pub fn get(&self, id: ElementId) -> Option<&Element<M>> {
Expand All @@ -129,10 +132,15 @@ mod elements_map {

pub fn update_cursor_pos(&mut self, point: Point) {
self.hovered = None;
for (id, element) in self.elements.iter_mut() {

for id in self.zorder.iter().rev() {
let Some(element) = self.elements.get_mut(id.0) else {
continue;
};

element.hovered = element.rect.contains(point);
if self.hovered.is_none() && element.hovered {
self.hovered = Some(ElementId(id));
self.hovered = Some(*id);
}
}
}
Expand Down

0 comments on commit 68fb849

Please sign in to comment.