Skip to content

Commit 59eda77

Browse files
committed
fixes #121, adjust guitar view y based on shape and pick, the logic is a bit messy, and might got corner cases not covered
1 parent f6e96e3 commit 59eda77

File tree

13 files changed

+1042
-94
lines changed

13 files changed

+1042
-94
lines changed

apps/notation_viewer/assets/tabs/test.ron

Lines changed: 907 additions & 44 deletions
Large diffs are not rendered by default.

crates/notation_bevy/src/app/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ fn handle_keyboard_inputs(
240240
if app_state.tab.is_none() {
241241
return;
242242
}
243-
if keyboard_input.just_released(KeyCode::LControl) {
243+
if keyboard_input.just_released(KeyCode::Tab) {
244244
app_state.hide_control = !app_state.hide_control;
245245
if !ControlView::HUD_MODE {
246246
window_resized_evts.send(WindowResizedEvent());

crates/notation_bevy/src/guitar/fret_finger.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ pub struct FretFingerExtra {
1717
pub fret: Option<u8>,
1818
pub finger: Option<Finger>,
1919
pub capo: u8,
20-
pub barre: u8,
2120
pub in_chord: bool,
2221
pub guitar_size: LayoutSize,
2322
}
@@ -33,7 +32,6 @@ impl FretFingerExtra {
3332
fret,
3433
finger,
3534
capo: 0,
36-
barre: 0,
3735
in_chord: false,
3836
guitar_size: LayoutSize::ZERO,
3937
}
@@ -142,7 +140,7 @@ impl FretFingerData {
142140
if self.value.extra.pick {
143141
self.value.extra.fret = pick_note.and_then(|x| x.fret);
144142
} else {
145-
self.value.extra.fret = shape.string_fret(self.value.extra.string);
143+
self.value.extra.fret = shape.string_fret_with_barre(self.value.extra.string);
146144
}
147145
if let Some(fretboard) = fretboard {
148146
self.value.extra.capo = fretboard.capo;
@@ -153,7 +151,6 @@ impl FretFingerData {
153151
};
154152
self.set_chord_meta_note(chord, meta, note);
155153
}
156-
self.value.extra.barre = shape.barre.unwrap_or(0);
157154
}
158155
pub fn update_with_syllable(
159156
&self,
@@ -165,7 +162,7 @@ impl FretFingerData {
165162
) {
166163
self.update(commands, theme, entity);
167164
let scale = theme.guitar.calc_scale(self.value.extra.guitar_size.width);
168-
if settings.show_guitar_syllable {
165+
if settings.show_guitar_syllable && self.value.extra.fret.is_some() {
169166
theme.guitar.syllable_text.spawn_scaled_syllable_text(commands, entity, assets, settings, &self.value.calc_syllable(), scale)
170167
}
171168
}
@@ -186,7 +183,7 @@ impl ChordNoteExtra for FretFingerExtra {
186183
let fret = self.fret.unwrap_or(0);
187184
let y = theme
188185
.guitar
189-
.calc_fret_y(fret + self.capo + self.barre, self.guitar_size.height);
186+
.calc_fret_y(fret + self.capo, self.guitar_size.height);
190187
Vec2::new(x, y)
191188
}
192189
fn get_color(&self, theme: &NotationTheme, color: Color) -> Color {

crates/notation_bevy/src/guitar/guitar_barre.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,63 @@
11
use bevy::prelude::*;
22
use bevy_prototype_lyon::prelude::*;
33
use notation_bevy_utils::prelude::{BevyUtil, FillRectangle, LayoutSize, ShapeOp};
4+
use notation_model::prelude::{HandShape6, Pick};
45

56
use crate::prelude::{NotationTheme};
67

78
#[derive(Clone, Debug)]
89
pub struct GuitarBarreData {
910
pub capo: u8,
10-
pub barre: u8,
11+
pub shape: Option<HandShape6>,
12+
pub pick: Option<Pick>,
1113
pub view_size: LayoutSize,
1214
pub guitar_size: LayoutSize,
1315
}
1416

15-
impl GuitarBarreData {
16-
pub fn new(capo: u8, barre: u8) -> Self {
17+
impl Default for GuitarBarreData {
18+
fn default() -> Self {
1719
Self {
18-
capo,
19-
barre,
20+
capo: 0,
21+
shape: None,
22+
pick: None,
2023
view_size: LayoutSize::ZERO,
2124
guitar_size: LayoutSize::ZERO,
2225
}
2326
}
2427
}
28+
impl GuitarBarreData {
29+
pub fn update_pick(&mut self, pick: &Pick) {
30+
if self.pick.is_none() || self.pick.unwrap().max_fret() < pick.max_fret() {
31+
self.pick = Some(pick.clone());
32+
}
33+
}
34+
pub fn barre(&self) -> u8 {
35+
self.shape.and_then(|x| x.barre).unwrap_or(0)
36+
}
37+
pub fn max_fret(&self) -> u8 {
38+
let mut max = self.shape.map(|x| x.max_fret_with_barre()).unwrap_or(0);
39+
if let Some(pick) = self.pick {
40+
let pick_max = pick.max_fret();
41+
if pick_max > max {
42+
max = pick_max
43+
}
44+
}
45+
max + self.capo
46+
}
47+
}
2548

2649
impl ShapeOp<NotationTheme, FillRectangle> for GuitarBarreData {
2750
fn get_shape(&self, theme: &NotationTheme) -> FillRectangle {
2851
let width = self.guitar_size.width * theme.guitar.barre_width_factor;
2952
let height = self.guitar_size.height * theme.guitar.barre_height_factor;
3053
let color = theme.colors.strings.barre;
31-
let offset = if self.barre == 0 || self.guitar_size.width <= 0.0 {
54+
let offset = if self.barre() == 0 || self.guitar_size.width <= 0.0 {
3255
BevyUtil::offscreen_offset()
3356
} else {
3457
let finger_radius = theme.guitar.string_x_factor * self.guitar_size.width / 2.0;
3558
let y = theme
3659
.guitar
37-
.calc_fret_y(self.capo + self.barre, self.guitar_size.height)
60+
.calc_fret_y(self.capo + self.barre(), self.guitar_size.height)
3861
+ height * 0.5
3962
- finger_radius;
4063
Vec3::new(0.0, y, theme.z.guitar_barre)

crates/notation_bevy/src/guitar/guitar_capo.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ pub struct GuitarCapoData {
1111
pub guitar_size: LayoutSize,
1212
}
1313

14-
impl GuitarCapoData {
15-
pub fn new(capo: u8) -> Self {
14+
impl Default for GuitarCapoData {
15+
fn default() -> Self {
1616
Self {
17-
capo,
17+
capo: 0,
1818
view_size: LayoutSize::ZERO,
1919
guitar_size: LayoutSize::ZERO,
2020
}

crates/notation_bevy/src/guitar/guitar_string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ impl GuitarStringData {
126126
) {
127127
let pick_note = pick.and_then(|x| x.get_pick_note(self.string));
128128
self.pick_fret = pick_note.and_then(|x| x.fret);
129-
self.fret = shape.string_fret(self.string);
129+
self.fret = shape.string_fret_with_barre(self.string);
130130
if let Some(fretboard) = fretboard {
131131
self.capo = fretboard.capo;
132132
} else {

crates/notation_bevy/src/guitar/guitar_view.rs

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ impl GuitarView {
7878
);
7979
}
8080
}
81-
let capo_data = GuitarCapoData::new(0);
81+
let capo_data = GuitarCapoData::default();
8282
capo_data.create(commands, theme, guitar_entity);
83-
let barre_data = GuitarBarreData::new(0, 0);
83+
let barre_data = GuitarBarreData::default();
8484
barre_data.create(commands, theme, guitar_entity);
8585
if Self::CHECKING_FRETS {
8686
let mut string = 1;
@@ -186,6 +186,7 @@ impl GuitarView {
186186
query: Query<(&Arc<LaneEntry>, &Pick, &EntryPlaying), Changed<EntryPlaying>>,
187187
mut string_query: Query<(Entity, &mut GuitarStringData), With<GuitarStringData>>,
188188
mut finger_query: Query<(Entity, &mut FretFingerData), With<FretFingerData>>,
189+
mut barre_query: Query<(Entity, &mut GuitarBarreData), With<GuitarBarreData>>,
189190
dot_query: Query<&Children>,
190191
) {
191192
if Self::CHECKING_FRETS {
@@ -246,6 +247,9 @@ impl GuitarView {
246247
finger_data.update_with_syllable(&mut commands, &assets, &theme, &settings, finger_entity);
247248
}
248249
}
250+
for (_barre_entity, mut barre_data) in barre_query.iter_mut() {
251+
barre_data.update_pick(pick);
252+
}
249253
}
250254
}
251255
pub fn update_hand_shape6(
@@ -311,19 +315,15 @@ impl GuitarView {
311315
capo_data.update(&mut commands, &theme, capo_entity);
312316
}
313317
}
314-
let barre = shape.barre.unwrap_or(0);
315318
for (barre_entity, mut barre_data) in barre_query.iter_mut() {
316-
if fretboard.capo != barre_data.capo ||
317-
barre != barre_data.barre {
318-
barre_data.capo = fretboard.capo;
319-
barre_data.barre = barre;
320-
barre_data.update(&mut commands, &theme, barre_entity);
321-
}
319+
barre_data.capo = fretboard.capo;
320+
barre_data.shape = Some(shape.clone());
321+
barre_data.pick = None;
322+
barre_data.update(&mut commands, &theme, barre_entity);
322323
}
323324
}
324325
} else {
325-
let position =
326-
TabState::get_position(&tab_state_query, None);
326+
let position = TabState::get_position(&tab_state_query, None);
327327
if position.is_some() && position.unwrap().bar.bar_ordinal == 0 {
328328
for (finger_entity, mut finger_data) in finger_query.iter_mut() {
329329
finger_data.reset();
@@ -333,6 +333,13 @@ impl GuitarView {
333333
string_data.reset();
334334
string_data.update(&mut commands, &theme, string_entity);
335335
}
336+
for (barre_entity, mut barre_data) in barre_query.iter_mut() {
337+
if barre_data.shape.is_some() {
338+
barre_data.shape = None;
339+
barre_data.pick = None;
340+
barre_data.update(&mut commands, &theme, barre_entity);
341+
}
342+
}
336343
}
337344
}
338345
}
@@ -342,36 +349,57 @@ impl GuitarView {
342349
) {
343350
if let Ok(mut transform) = guitar_view_query.single_mut() {
344351
let trans = transform.translation;
345-
println!("GuitarView::update_y {} -> {}", trans.y, y);
346352
if float_ne!(trans.y, y, abs <= 0.01) {
353+
println!("GuitarView::update_y {} -> {}", trans.y, y);
347354
*transform = Transform::from_xyz(trans.x, y, trans.z);
348355
}
349356
}
350357
}
351-
pub fn adjust_y_by_capo(
358+
pub fn adjust_y_by_frets(
359+
theme: &NotationTheme,
360+
guitar_view_query: &mut Query<&mut Transform, With<Arc<GuitarView>>>,
361+
view_size: LayoutSize,
362+
guitar_size: LayoutSize,
363+
min_fret: u8,
364+
max_fret: u8,
365+
) {
366+
let calc_y = |fret:u8| {
367+
let fret_y = theme
368+
.guitar
369+
.calc_fret_y(fret, guitar_size.height);
370+
-(fret_y + guitar_size.height * theme.guitar.capo_height_factor)
371+
};
372+
let top_y = calc_y(min_fret);
373+
let bottom_y = calc_y(max_fret + 1);
374+
let y = if bottom_y - top_y > view_size.height {
375+
bottom_y - view_size.height
376+
} else {
377+
top_y
378+
};
379+
println!("GuitarView::adjust_y_by_frets {} {} [{} - {}] -> {} {} -> {}", view_size, guitar_size, min_fret, max_fret, top_y, bottom_y, y);
380+
Self::update_y(guitar_view_query, y);
381+
}
382+
pub fn adjust_y_by_barre(
352383
theme: Res<NotationTheme>,
353384
settings: Res<NotationSettings>,
354-
capo_query: Query<&GuitarCapoData, Changed<GuitarCapoData>>,
385+
barre_query: Query<&GuitarBarreData, Changed<GuitarBarreData>>,
355386
mut guitar_view_query: Query<&mut Transform, With<Arc<GuitarView>>>,
356387
) {
388+
if Self::CHECKING_FRETS {
389+
return;
390+
}
357391
if theme._bypass_systems { return; }
358392
if settings.override_guitar_y.is_some() {
359393
return;
360394
}
361-
for capo_data in capo_query.iter() {
362-
if capo_data.view_size.height <= 0.0 {
363-
return;
364-
}
365-
let y = if capo_data.view_size.height > capo_data.guitar_size.height {
366-
-capo_data.guitar_size.height / 2.0
395+
for barre_data in barre_query.iter() {
396+
if barre_data.view_size.height > barre_data.guitar_size.height {
397+
Self::update_y(&mut guitar_view_query, -barre_data.guitar_size.height / 2.0);
367398
} else {
368-
let capo_y = theme
369-
.guitar
370-
.calc_fret_y(capo_data.capo, capo_data.guitar_size.height);
371-
-(capo_y + capo_data.guitar_size.height * theme.guitar.capo_height_factor)
372-
};
373-
println!("adjust_y_by_capo {} {} {} -> {}", capo_data.guitar_size, capo_data.view_size, capo_data.capo, y);
374-
Self::update_y(&mut guitar_view_query, y);
399+
let min_fret = barre_data.capo;
400+
let max_fret = barre_data.max_fret();
401+
Self::adjust_y_by_frets(&theme, &mut guitar_view_query, barre_data.view_size, barre_data.guitar_size, min_fret, max_fret);
402+
}
375403
}
376404
}
377405
}

crates/notation_bevy/src/ui/viewer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl Plugin for TabViewerPlugin {
4444
.with_system(GuitarView::on_layout_changed.system())
4545
.with_system(GuitarView::update_hand_shape6.system().label("GuitarView::update_hand_shape6"))
4646
.with_system(GuitarView::update_string_state.system().label("GuitarView::update_string_state").after("GuitarView::update_hand_shape6"))
47-
.with_system(GuitarView::adjust_y_by_capo.system())
47+
.with_system(GuitarView::adjust_y_by_barre.system())
4848
.with_system(TabViewer::do_layout.system()),
4949
);
5050
}

crates/notation_core/src/duration.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ pub struct Units(pub f32);
6161
impl Units {
6262
pub const _MIN_ACCURACY: f32 = 0.00001;
6363
pub const MIN_ACCURACY: Units = Units(Self::_MIN_ACCURACY);
64+
/*
65+
* This i quite messy here, the pasition passed checking needs some cleanup,
66+
* mainly for control the guitar view timing, and seeking next note
67+
*/
68+
pub const HALF_MIN_ACCURACY: Units = Units(Self::_MIN_ACCURACY * 0.5);
6469

6570
pub fn is_bigger_than(&self, other: &Units) -> bool {
6671
self.0 > other.0 + Self::_MIN_ACCURACY

crates/notation_fretted/src/fretboard.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ macro_rules! impl_fretboard {
7272
}
7373
pub fn shape_note(&self, shape: &$hand_shape, string: u8) -> Option<Note> {
7474
shape
75-
.string_fret(string)
75+
.string_fret_with_barre(string)
7676
.and_then(|fret| self.fretted_note(string, fret))
7777
}
7878
pub fn shape_fret_note(&self, shape: &$hand_shape, string: u8) -> Option<(u8, Note)> {
7979
shape
80-
.string_fret(string)
80+
.string_fret_with_barre(string)
8181
.and_then(|fret| self.fretted_note(string, fret).map(|n| (fret, n)))
8282
}
8383
pub fn shape_pick_note(

0 commit comments

Comments
 (0)