From 3b48ed191165ecd9306eb8e5b0fafb2f2de5f22b Mon Sep 17 00:00:00 2001 From: Edoardo Manfredi Date: Mon, 17 Feb 2025 22:12:10 +0100 Subject: [PATCH 1/2] draw time signature --- src/ui/canvas_measure.rs | 72 +++++++++++++++++++++++++++++++++------- src/ui/tablature.rs | 16 ++++++++- 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/ui/canvas_measure.rs b/src/ui/canvas_measure.rs index 2e80fca..e79a65a 100644 --- a/src/ui/canvas_measure.rs +++ b/src/ui/canvas_measure.rs @@ -1,4 +1,6 @@ -use crate::parser::song_parser::{Beat, HarmonicType, Note, NoteEffect, NoteType, SlideType, Song}; +use crate::parser::song_parser::{ + Beat, HarmonicType, Note, NoteEffect, NoteType, SlideType, Song, TimeSignature, +}; use crate::ui::application::Message; use iced::advanced::mouse; use iced::advanced::text::Shaping::Advanced; @@ -7,7 +9,8 @@ use iced::event::Status; use iced::mouse::{Cursor, Interaction}; use iced::widget::canvas::{Cache, Event, Frame, Geometry, Path, Stroke, Text}; use iced::widget::{canvas, Canvas}; -use iced::{Color, Element, Length, Point, Rectangle, Renderer, Size, Theme}; +use iced::{Color, Element, Font, Length, Point, Rectangle, Renderer, Size, Theme}; +use std::ops::Div; use std::rc::Rc; // Drawing constants @@ -47,16 +50,27 @@ pub struct CanvasMeasure { measure_len: f32, pub total_measure_len: f32, pub vertical_measure_height: f32, + has_time_signature: bool, } impl CanvasMeasure { - pub fn new(measure_id: usize, track_id: usize, song: Rc, focused: bool) -> Self { + pub fn new( + measure_id: usize, + track_id: usize, + song: Rc, + focused: bool, + has_time_signature: bool, + ) -> Self { let track = &song.tracks[track_id]; let measure = &track.measures[measure_id]; let beat_count = measure.voices[0].beats.len(); let measure_len = MIN_MEASURE_WIDTH.max(beat_count as f32 * BEAT_LENGTH); // total length of measure (padding on both sides) - let total_measure_len = measure_len + MEASURE_NOTES_PADDING * 2.0; + let total_measure_len = if has_time_signature { + measure_len + MEASURE_NOTES_PADDING * 2.0 + BEAT_LENGTH + } else { + measure_len + MEASURE_NOTES_PADDING * 2.0 + }; let string_count = track.strings.len(); // total height of measure (same for all measures in track) let vertical_measure_height = STRING_LINE_HEIGHT * (string_count - 1) as f32; @@ -71,6 +85,7 @@ impl CanvasMeasure { measure_len, total_measure_len, vertical_measure_height, + has_time_signature, } } @@ -182,13 +197,13 @@ impl canvas::Program for CanvasMeasure { }; // display time signature (if first measure OR if it changed) - if self.measure_id == 0 - || measure_header.time_signature != previous_measure_header.unwrap().time_signature - { - let numerator = measure_header.time_signature.numerator; - let denominator = measure_header.time_signature.denominator.value; - log::debug!("time signature change {} / {}", numerator, denominator); - // TODO draw time signature + if self.has_time_signature { + draw_time_signature( + frame, + &measure_header.time_signature, + measure_start_x, + string_count, + ); } // TODO draw repeat annotations @@ -269,11 +284,16 @@ impl canvas::Program for CanvasMeasure { } else { Color::WHITE }; + let beat_start = if self.has_time_signature { + measure_start_x + BEAT_LENGTH + } else { + measure_start_x + }; // draw beat draw_beat( frame, self.measure_len, - measure_start_x, + beat_start, measure_start_y, beats_len, b_id, @@ -458,6 +478,34 @@ fn draw_note( frame.fill_text(note_effect_text); } +fn draw_time_signature( + frame: &mut Frame, + time_signature: &TimeSignature, + measure_start_x: f32, + string_count: usize, +) { + let position_x = 12.0; + let position_y = if string_count > 4 { + (STRING_LINE_HEIGHT * (string_count - 4) as f32 ).div(2.0) + } else { + 0.0 + }; + let numerator = time_signature.numerator; + let denominator = time_signature.denominator.value; + let tempo_text = Text { + content: format!("{numerator}\n{denominator}"), + color: Color::WHITE, + size: 19.into(), + font: Font { + weight: iced::font::Weight::Semibold, + ..Font::default() + }, + position: Point::new(measure_start_x + position_x, (FIRST_STRING_Y - 3.0) + position_y), + ..Text::default() + }; + frame.fill_text(tempo_text); +} + // Similar to `https://www.tuxguitar.app/files/1.6.0/desktop/help/edit_effects.html` fn above_note_effect_annotation(note_effect: &NoteEffect) -> Vec { let mut annotations: Vec = vec![]; diff --git a/src/ui/tablature.rs b/src/ui/tablature.rs index df5f0e7..84fb451 100644 --- a/src/ui/tablature.rs +++ b/src/ui/tablature.rs @@ -43,8 +43,22 @@ impl Tablature { let track = &self.song.tracks[self.track_id]; let measures = track.measures.len(); for i in 0..measures { + let measure_header = &self.song.measure_headers[i]; + let previous_measure_header = if i > 0 { + Some(&self.song.measure_headers[i - 1]) + } else { + None + }; let focused = self.focused_measure == i; - let measure = CanvasMeasure::new(i, self.track_id, self.song.clone(), focused); + let has_time_signature = i == 0 + || measure_header.time_signature != previous_measure_header.unwrap().time_signature; + let measure = CanvasMeasure::new( + i, + self.track_id, + self.song.clone(), + focused, + has_time_signature, + ); if i == 0 { // all measures have the same height - grab first one self.canvas_measure_height = measure.vertical_measure_height; From fdd35722a429afeb59bac3556417140dddf4559d Mon Sep 17 00:00:00 2001 From: Edoardo Manfredi Date: Sun, 23 Feb 2025 12:00:54 +0100 Subject: [PATCH 2/2] use normal font for time signature decrease time signature size run cargo fmt use getter method --- src/ui/canvas_measure.rs | 15 +++++++-------- src/ui/tablature.rs | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/ui/canvas_measure.rs b/src/ui/canvas_measure.rs index e79a65a..c64a563 100644 --- a/src/ui/canvas_measure.rs +++ b/src/ui/canvas_measure.rs @@ -9,7 +9,7 @@ use iced::event::Status; use iced::mouse::{Cursor, Interaction}; use iced::widget::canvas::{Cache, Event, Frame, Geometry, Path, Stroke, Text}; use iced::widget::{canvas, Canvas}; -use iced::{Color, Element, Font, Length, Point, Rectangle, Renderer, Size, Theme}; +use iced::{Color, Element, Length, Point, Rectangle, Renderer, Size, Theme}; use std::ops::Div; use std::rc::Rc; @@ -486,7 +486,7 @@ fn draw_time_signature( ) { let position_x = 12.0; let position_y = if string_count > 4 { - (STRING_LINE_HEIGHT * (string_count - 4) as f32 ).div(2.0) + (STRING_LINE_HEIGHT * (string_count - 4) as f32).div(2.0) } else { 0.0 }; @@ -495,12 +495,11 @@ fn draw_time_signature( let tempo_text = Text { content: format!("{numerator}\n{denominator}"), color: Color::WHITE, - size: 19.into(), - font: Font { - weight: iced::font::Weight::Semibold, - ..Font::default() - }, - position: Point::new(measure_start_x + position_x, (FIRST_STRING_Y - 3.0) + position_y), + size: 17.into(), + position: Point::new( + measure_start_x + position_x, + (FIRST_STRING_Y - 1.0) + position_y, + ), ..Text::default() }; frame.fill_text(tempo_text); diff --git a/src/ui/tablature.rs b/src/ui/tablature.rs index 84fb451..ee674ff 100644 --- a/src/ui/tablature.rs +++ b/src/ui/tablature.rs @@ -45,7 +45,7 @@ impl Tablature { for i in 0..measures { let measure_header = &self.song.measure_headers[i]; let previous_measure_header = if i > 0 { - Some(&self.song.measure_headers[i - 1]) + self.song.measure_headers.get(i - 1) } else { None };