Skip to content

Commit f13eb1b

Browse files
committed
fixes #89, update play buttons properly
1 parent 7fc33bc commit f13eb1b

File tree

15 files changed

+222
-38
lines changed

15 files changed

+222
-38
lines changed

crates/notation_bevy/src/bar/bar_playing.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ impl BarPlaying {
1414
) {
1515
for (_entity, mut bar_playing) in query.iter_mut() {
1616
let bar_ordinal = bar_playing.bar_props.bar_ordinal;
17-
if tab_state.is_bar_in_range(bar_ordinal) {
17+
// Hacky way to allow click on not selected bar, might do proper fix in the future
18+
if true || tab_state.is_bar_in_range(bar_ordinal) {
1819
if bar_ordinal == playing_bar_ordinal {
1920
if bar_playing.value != PlayingState::Current {
2021
bar_playing.value = PlayingState::Current;

crates/notation_bevy/src/entry/entry_playing.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ impl EntryPlaying {
3737
let playing_bar_ordinal = new_position.bar.bar_ordinal;
3838
for (_entity, entry, mut entry_playing) in query.iter_mut() {
3939
let bar_ordinal = entry_playing.bar_props.bar_ordinal;
40-
if tab_state.is_bar_in_range(bar_ordinal) {
40+
// Hacky way to allow click on not selected bar, might do proper fix in the future
41+
if true || tab_state.is_bar_in_range(bar_ordinal) {
4142
if entry_playing.value.is_current()
4243
&& new_position.is_passed_with(
4344
entry.pass_mode(),

crates/notation_bevy/src/play/play_button.rs

Lines changed: 88 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
use std::fmt::Display;
2+
use std::sync::Arc;
23

34
use bevy::prelude::*;
45
use bevy_utils::prelude::{BevyUtil, GridCell, LayoutAnchor, LayoutChangedWithChildrenQuery, ShapeOp, FillPath, View, ViewBundle};
6+
use notation_model::prelude::{PlayState, Tab};
57

6-
use crate::prelude::{NotationAssets, NotationTheme};
8+
use crate::prelude::{NotationAssets, NotationSettings, NotationTheme};
79
use crate::ui::layout::NotationLayout;
810

911
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
1012
pub enum PlayButtonAction {
1113
PlayPause,
1214
Stop,
13-
Settings,
15+
LoopMode,
1416
SetBegin,
1517
SetEnd,
16-
LoopMode,
18+
Clear,
1719
}
1820
impl Display for PlayButtonAction {
1921
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -25,10 +27,10 @@ impl PlayButtonAction {
2527
match self {
2628
PlayButtonAction::PlayPause => 0,
2729
PlayButtonAction::Stop => 1,
28-
PlayButtonAction::Settings => 2,
30+
PlayButtonAction::LoopMode => 2,
2931
PlayButtonAction::SetBegin => 3,
3032
PlayButtonAction::SetEnd => 4,
31-
PlayButtonAction::LoopMode => 5,
33+
PlayButtonAction::Clear => 5,
3234
}
3335
}
3436
pub fn size(&self) -> Vec2 {
@@ -41,18 +43,18 @@ impl PlayButtonAction {
4143
if playing {
4244
"M832 1184v-576q0-14-9-23t-23-9h-256q-14 0-23 9t-9 23v576q0 14 9 23t23 9h256q14 0 23-9t9-23zm448 0v-576q0-14-9-23t-23-9h-256q-14 0-23 9t-9 23v576q0 14 9 23t23 9h256q14 0 23-9t9-23zm384-288q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"
4345
} else {
44-
"M1312 896q0 37-32 55l-544 320q-15 9-32 9-16 0-32-8-32-19-32-56v-640q0-37 32-56 33-18 64 1l544 320q32 18 32 55zm128 0q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"
46+
"M896 128q209 0 385.5 103t279.5 279.5 103 385.5-103 385.5-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103zm384 823q32-18 32-55t-32-55l-544-320q-31-19-64-1-32 19-32 56v640q0 37 32 56 16 8 32 8 17 0 32-9z"
4547
}
4648
PlayButtonAction::Stop =>
4749
"M1216 1184v-576q0-14-9-23t-23-9h-576q-14 0-23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23-9t9-23zm448-288q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z",
48-
PlayButtonAction::Settings =>
49-
"M1152 896q0-106-75-181t-181-75-181 75-75 181 75 181 181 75 181-75 75-181zm512-109v222q0 12-8 23t-20 13l-185 28q-19 54-39 91 35 50 107 138 10 12 10 25t-9 23q-27 37-99 108t-94 71q-12 0-26-9l-138-108q-44 23-91 38-16 136-29 186-7 28-36 28h-222q-14 0-24.5-8.5t-11.5-21.5l-28-184q-49-16-90-37l-141 107q-10 9-25 9-14 0-25-11-126-114-165-168-7-10-7-23 0-12 8-23 15-21 51-66.5t54-70.5q-27-50-41-99l-183-27q-13-2-21-12.5t-8-23.5v-222q0-12 8-23t19-13l186-28q14-46 39-92-40-57-107-138-10-12-10-24 0-10 9-23 26-36 98.5-107.5t94.5-71.5q13 0 26 10l138 107q44-23 91-38 16-136 29-186 7-28 36-28h222q14 0 24.5 8.5t11.5 21.5l28 184q49 16 90 37l142-107q9-9 24-9 13 0 25 10 129 119 165 170 7 8 7 22 0 12-8 23-15 21-51 66.5t-54 70.5q26 50 41 98l183 28q13 2 21 12.5t8 23.5z",
50+
PlayButtonAction::LoopMode =>
51+
"M1664 256v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39 14-69l138-138q-148-137-349-137-104 0-198.5 40.5t-163.5 109.5-109.5 163.5-40.5 198.5 40.5 198.5 109.5 163.5 163.5 109.5 198.5 40.5q119 0 225-52t179-147q7-10 23-12 15 0 25 9l137 138q9 8 9.5 20.5t-7.5 22.5q-109 132-264 204.5t-327 72.5q-156 0-298-61t-245-164-164-245-61-298 61-298 164-245 245-164 298-61q147 0 284.5 55.5t244.5 156.5l130-129q29-31 70-14 39 17 39 59z",
5052
PlayButtonAction::SetBegin =>
5153
"M1203 544q0 13-10 23l-393 393 393 393q10 10 10 23t-10 23l-50 50q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l466-466q10-10 23-10t23 10l50 50q10 10 10 23z",
5254
PlayButtonAction::SetEnd =>
5355
"M1171 960q0 13-10 23l-466 466q-10 10-23 10t-23-10l-50-50q-10-10-10-23t10-23l393-393-393-393q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l466 466q10 10 10 23z",
54-
PlayButtonAction::LoopMode =>
55-
"M1664 256v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39 14-69l138-138q-148-137-349-137-104 0-198.5 40.5t-163.5 109.5-109.5 163.5-40.5 198.5 40.5 198.5 109.5 163.5 163.5 109.5 198.5 40.5q119 0 225-52t179-147q7-10 23-12 15 0 25 9l137 138q9 8 9.5 20.5t-7.5 22.5q-109 132-264 204.5t-327 72.5q-156 0-298-61t-245-164-164-245-61-298 61-298 164-245 245-164 298-61q147 0 284.5 55.5t244.5 156.5l130-129q29-31 70-14 39 17 39 59z",
56+
PlayButtonAction::Clear =>
57+
"M1792 896q0 26-19 45l-256 256q-19 19-45 19t-45-19-19-45v-128h-1024v128q0 26-19 45t-45 19-45-19l-256-256q-19-19-19-45t19-45l256-256q19-19 45-19t45 19 19 45v128h1024v-128q0-26 19-45t45-19 45 19l256 256q19 19 19 45z",
5658
}.to_owned()
5759
}
5860
}
@@ -62,10 +64,10 @@ impl From<usize> for PlayButtonAction {
6264
match v {
6365
0 => Self::PlayPause,
6466
1 => Self::Stop,
65-
2 => Self::Settings,
67+
2 => Self::LoopMode,
6668
3 => Self::SetBegin,
6769
4 => Self::SetEnd,
68-
_ => Self::LoopMode,
70+
_ => Self::Clear,
6971
}
7072
}
7173
}
@@ -85,20 +87,41 @@ pub struct PlayButtonShape {
8587
pub action: PlayButtonAction,
8688
pub width: f32,
8789
pub height: f32,
90+
pub play_state: PlayState,
91+
pub should_loop: bool,
92+
pub bars: usize,
93+
pub begin_bar_ordinal: usize,
94+
pub end_bar_ordinal: usize,
8895
}
8996
impl Display for PlayButtonShape {
9097
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9198
write!(f, "{:?}", self)
9299
}
93100
}
101+
impl PlayButtonShape {
102+
pub fn get_color(&self, theme: &NotationTheme) -> Color {
103+
match self.action {
104+
PlayButtonAction::PlayPause =>
105+
theme.colors.ui.button_on,
106+
PlayButtonAction::Stop =>
107+
theme.colors.ui.of_button(!self.play_state.is_stopped()),
108+
PlayButtonAction::LoopMode =>
109+
theme.colors.ui.of_button(self.should_loop),
110+
PlayButtonAction::SetBegin |
111+
PlayButtonAction::SetEnd |
112+
PlayButtonAction::Clear =>
113+
theme.colors.ui.of_button(self.begin_bar_ordinal != 1 || self.end_bar_ordinal != self.bars),
114+
}
115+
}
116+
}
94117

95118
impl ShapeOp<NotationTheme, FillPath> for PlayButtonShape {
96119
fn get_shape(&self, theme: &NotationTheme) -> FillPath {
97120
let scale = self.height / 1792.0;
98121
FillPath {
99122
size: self.action.size(),
100-
path: self.action.path(true),
101-
color: theme.shapes.shape_color,
123+
path: self.action.path(self.play_state.is_playing()),
124+
color: self.get_color(theme),
102125
//line_width: theme.shapes.shape_line_width,
103126
offset: Vec3::new(0.0, 0.0, theme.core.mini_map_z),
104127
scale: scale,
@@ -123,7 +146,9 @@ impl PlayButton {
123146
commands: &mut Commands,
124147
_assets: &NotationAssets,
125148
theme: &NotationTheme,
149+
settings: &NotationSettings,
126150
entity: Entity,
151+
tab: &Arc<Tab>,
127152
action: PlayButtonAction,
128153
) -> Entity {
129154
let button_entity = BevyUtil::spawn_child_bundle(
@@ -135,6 +160,11 @@ impl PlayButton {
135160
action,
136161
width: 32.0,
137162
height: 32.0,
163+
play_state: PlayState::Stopped,
164+
should_loop: settings.should_loop,
165+
bars: tab.bars.len(),
166+
begin_bar_ordinal: 1,
167+
end_bar_ordinal: tab.bars.len(),
138168
};
139169
button_shape.create(commands, theme, button_entity);
140170
button_entity
@@ -155,4 +185,48 @@ impl PlayButton {
155185
}
156186
}
157187
}
188+
pub fn on_play_state(
189+
commands: &mut Commands,
190+
theme: &NotationTheme,
191+
shape_query: &mut Query<(Entity, &mut PlayButtonShape)>,
192+
play_state: &PlayState,
193+
) {
194+
for (entity, mut shape) in shape_query.iter_mut() {
195+
shape.play_state = play_state.clone();
196+
if shape.action == PlayButtonAction::PlayPause
197+
|| shape.action == PlayButtonAction::Stop {
198+
shape.update(commands, theme, entity);
199+
}
200+
}
201+
}
202+
pub fn on_should_loop(
203+
commands: &mut Commands,
204+
theme: &NotationTheme,
205+
shape_query: &mut Query<(Entity, &mut PlayButtonShape)>,
206+
should_loop: bool,
207+
) {
208+
for (entity, mut shape) in shape_query.iter_mut() {
209+
shape.should_loop = should_loop;
210+
if shape.action == PlayButtonAction::LoopMode {
211+
shape.update(commands, theme, entity);
212+
}
213+
}
214+
}
215+
pub fn on_begin_end(
216+
commands: &mut Commands,
217+
theme: &NotationTheme,
218+
shape_query: &mut Query<(Entity, &mut PlayButtonShape)>,
219+
begin_bar_ordinal: usize,
220+
end_bar_ordinal: usize,
221+
) {
222+
for (entity, mut shape) in shape_query.iter_mut() {
223+
shape.begin_bar_ordinal = begin_bar_ordinal;
224+
shape.end_bar_ordinal = end_bar_ordinal;
225+
if shape.action == PlayButtonAction::SetBegin
226+
|| shape.action == PlayButtonAction::SetEnd
227+
|| shape.action == PlayButtonAction::Clear {
228+
shape.update(commands, theme, entity);
229+
}
230+
}
231+
}
158232
}

crates/notation_bevy/src/play/play_panel.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
use std::fmt::Display;
1+
use std::{fmt::Display, sync::Arc};
22

33
use bevy::prelude::*;
44
use bevy_utils::prelude::{BevyUtil, GridData, GridView, LayoutAnchor, LayoutQuery, LayoutSize, View, ViewBundle, ViewQuery};
5+
use notation_midi::prelude::PlayControlEvent;
6+
use notation_model::prelude::{PlayState, Tab};
57

68
use crate::{prelude::{NotationAppState, NotationAssets, NotationSettings, NotationTheme}, ui::layout::NotationLayout};
79

8-
use super::{play_button::{PlayButton}, play_plugin::PlayPanelDoLayoutEvent};
10+
use super::{play_button::{PlayButton, PlayButtonShape}, play_plugin::PlayPanelDoLayoutEvent};
911

1012
pub struct PlayPanel {
1113
pub playing: bool,
@@ -49,13 +51,15 @@ impl PlayPanel {
4951
commands: &mut Commands,
5052
assets: &NotationAssets,
5153
theme: &NotationTheme,
54+
settings: &NotationSettings,
5255
entity: Entity,
56+
tab: &Arc<Tab>,
5357
) -> Entity {
5458
let panel = PlayPanel::default();
5559
let panel_entity =
5660
BevyUtil::spawn_child_bundle(commands, entity, ViewBundle::from(panel));
5761
for i in 0..=5 {
58-
PlayButton::spawn(commands, assets, theme, panel_entity, (i as usize).into());
62+
PlayButton::spawn(commands, assets, theme, settings, panel_entity, tab, (i as usize).into());
5963
}
6064
panel_entity
6165
}
@@ -80,4 +84,31 @@ impl PlayPanel {
8084
)
8185
}
8286
}
87+
pub fn on_play_control_evt(
88+
mut commands: Commands,
89+
theme: Res<NotationTheme>,
90+
mut evts: EventReader<PlayControlEvent>,
91+
mut shape_query: Query<(Entity, &mut PlayButtonShape)>,
92+
) {
93+
for evt in evts.iter() {
94+
match evt {
95+
PlayControlEvent::OnTick {position: _, tick_result} => {
96+
if tick_result.stopped {
97+
let play_state = PlayState::Stopped;
98+
PlayButton::on_play_state(&mut commands, &theme, &mut shape_query, &play_state);
99+
}
100+
}
101+
PlayControlEvent::OnPlayState(play_state) => {
102+
PlayButton::on_play_state(&mut commands, &theme, &mut shape_query, play_state);
103+
}
104+
PlayControlEvent::OnShouldLoop(should_loop) => {
105+
PlayButton::on_should_loop(&mut commands, &theme, &mut shape_query, *should_loop);
106+
}
107+
PlayControlEvent::OnBeginEnd(begin_bar_ordinal, end_bar_ordinal) => {
108+
PlayButton::on_begin_end(&mut commands, &theme, &mut shape_query, *begin_bar_ordinal, *end_bar_ordinal)
109+
}
110+
PlayControlEvent::OnSpeedFactor(_) => {}
111+
}
112+
}
113+
}
83114
}

crates/notation_bevy/src/play/play_plugin.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl Plugin for PlayPlugin {
3636
app.add_system_set(
3737
SystemSet::on_update(NotationAssetsStates::Loaded)
3838
.with_system(PlayPanel::do_layout.system())
39+
.with_system(PlayPanel::on_play_control_evt.system())
3940
.with_system(PlayButton::on_layout_changed.system())
4041
.with_system(on_bar_playing_changed.system())
4142
.with_system(on_tab_play_state_changed.system())
@@ -323,6 +324,10 @@ fn on_play_control_evt(
323324
tab_state.set_begin_end(*begin_bar_ordinal, *end_bar_ordinal);
324325
BarBeatData::update_all(&mut commands, &theme, &tab_state, &mut beat_query);
325326
}
327+
PlayControlEvent::OnShouldLoop(should_loop) => {
328+
tab_state.set_should_loop(*should_loop);
329+
330+
}
326331
}
327332
}
328333
}

crates/notation_bevy/src/settings/notation_settings.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use super::layout_settings::LayoutSettings;
99
#[cfg_attr(feature = "inspector", derive(Inspectable))]
1010
pub struct NotationSettings {
1111
pub layout: LayoutSettings,
12+
pub should_loop: bool,
1213
pub speed_factor: f32,
1314
pub always_show_fret: bool,
1415
pub melody_piano_mode: bool,
@@ -19,6 +20,7 @@ impl Default for NotationSettings {
1920
fn default() -> Self {
2021
Self {
2122
layout: LayoutSettings::default(),
23+
should_loop: false,
2224
speed_factor: 1.0,
2325
always_show_fret: false,
2426
melody_piano_mode: false,

crates/notation_bevy/src/tab/tab_control.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl TabControl {
6363
commands: &mut Commands,
6464
assets: &NotationAssets,
6565
theme: &NotationTheme,
66+
settings: &NotationSettings,
6667
entity: Entity,
6768
tab: &Arc<Tab>,
6869
) -> Entity {
@@ -86,7 +87,9 @@ impl TabControl {
8687
commands,
8788
assets,
8889
theme,
90+
settings,
8991
control_entity,
92+
tab,
9093
);
9194
control_entity
9295
}

crates/notation_bevy/src/tab/tab_header.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ impl TabHeader {
6262
commands: &mut Commands,
6363
assets: &NotationAssets,
6464
theme: &NotationTheme,
65+
settings: &NotationSettings,
6566
entity: Entity,
6667
tab: &Arc<Tab>,
6768
) -> Entity {
6869
let view_bundle = ViewBundle::from(TabHeader::new(tab.clone()));
6970
let view = view_bundle.view.clone();
7071
let header_entity = BevyUtil::spawn_child_bundle(commands, entity, view_bundle);
71-
TabControl::spawn(commands, assets, theme, header_entity, &tab);
72+
TabControl::spawn(commands, assets, theme, settings, header_entity, &tab);
7273
TabChords::spawn(commands, theme, header_entity, &tab, &view.chords);
7374
header_entity
7475
}

0 commit comments

Comments
 (0)