-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Parse dynamics when finished editing #25396
base: master
Are you sure you want to change the base?
Conversation
@CMakeScore You noted that you can use Ctrl + Shift + [character] to enter the proper dynamic character, which works, but it looks like you've also included some handling for automatically changing regular text to dynamic characters after editing (if that's all you've typed). This is an awesome addition, but there are a couple bugs and some room for improvement if you're willing to take it on. Screen.Recording.2024-10-22.at.4.44.31.PM.2.movBug: Replacing selected text (0:00–0:17 in video)If I double click into an existing dynamic to select the text, the first character I type does not appear.
This appears to be a preeexisting issue (at least in MSS 4.4), but since we didn't really previously provide much utility to typing in dynamics, I think we should aim to fix it in this PR. Request: Format known dynamics while typing (0:18–end of video)Ideally, anytime you begin a "word" in a dynamic text field with a character that typically starts a dynamic (p, m, f, s, or r), it should show up as a dynamic character while you're still editing the field. If you start a word with any other character, or you type a space and add expression text, it should look like expression text. You know you want a dynamic, so why require modifier keys to get the right characters? We should essentially recognize if the user is typing any of the existing dynamics in palettes until the string stops matching (i.e. another letter or a space is typed). Ideally, we would also retain the ability to prepend expression text by typing before a dynamic (and append after). Example 1:
Example 2:
Would much appreciate the bug fix to get this merged, and if you want to take on the request too, even better. If not, we can just turn that part into a feature request. Thanks! |
Before working on that request, it might make sense to do #25229 first. Otherwise, we're creating even more complexity right now, that will all need to be considered during the refactor task. |
Thanks for the context @cbjeukendrup. I'd then recommend fixing that bug (if not too difficult) and merging this, since the Add dynamic shortcut isn't very useful without at least the basic parsing of dynamics that's already been implemented. The request section can be saved for later implementation. |
21e8a53
to
f9c396e
Compare
@avvvvve I’ve identified the cause of the bug you mentioned and committed a fix. |
710f891
to
d2043bf
Compare
@CMakeScore Thanks for making quick work of this! Really nice solution you've come up with and I think people will be really excited to use this. I'll create another feature request to render dynamic characters as they're typed so we at least have it recorded. @cbjeukendrup Ready for code review |
Dynamic characters are not synced when parts exist Untitled.mp4 |
c70a897
to
1bfd1d2
Compare
Fixed a problem with synchronization with the part. Edit: |
c18789a
to
f241f95
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing those tweaks - almost there!
This isn't quite what I had in mind regarding these changes. I think what you had before was mostly fine but instead we should do something like this:
-
Change
parseDynamicText
so that it returns astd::pair<DynamicType, String>
-
Instead of directly calling
setXmlText
insideparseDynamicText
, do this (wheredynamicInfo
is a pair):
dynamicInfo.first = DynamicType(i);
dynamicInfo.second = String::fromStdString(utf8Tag);
return dynamicInfo;
- Finally, inside
setDynamicType
:
setXmlText(dynamicInfo.second);
setDynamicType(dynamicInfo.first);
Let me know how that sounds - in the meantime I'll investigate the crash you mentioned here.
5caeeeb
to
0aebfef
Compare
@mathesoncalum Thank you for your feedback! |
Sorry for the delay @CMakeScore - thanks very much for doing those tweaks! In the process of looking into this I discovered a crash in master - I think it would be wise to resolve this first before finishing up this PR. I'll drop another message here once that's done - thanks again! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for your patience @CMakeScore - been a busy few weeks but I created a fix for the crash the other day, so we should be safe to continue.
Here's what I'm thinking, hopefully it's viable:
- In
TextBase::endEdit
, simply:
Dynamic* d = toDynamic(this);
undoChangeProperty(Pid::DYNAMIC_TYPE, xmlText());
- For this to work we'll need to tweak
Dynamic::setProperty
so that it dispatches to the correct "set" method (instead of just modifyingm_dynamicType
):
case Pid::DYNAMIC_TYPE:
if (v.type() == P_TYPE::DYNAMIC_TYPE) {
setDynamicType(v.value<DynamicType>());
break;
}
setDynamicType(v.value<String>());
break;
...
- Make
parseDynamicText
private.
This seemed reliable in the (brief) testing I did - but do let me know if you notice any problems with this approach.
67b8830
to
6d96628
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good now @CMakeScore - now if you could just squash this into 1 or 2 commits that would be perfect.
Cheers!
6d96628
to
cbb28e2
Compare
OK, I've squashed the commits now. Thank you for all your support so far! |
Undo after changing dynamic does not update playback video1410913511.mp4 |
Thank you for testing! I’ve pushed a new commit to address the issue you mentioned. Could you please test it again? Oops, I'll look into the failed utests later. |
798a444
to
86451da
Compare
Hmm, it seems that for some reason |
Tested on MacOS 14, Windows 11, Ubuntu 22.04.3. Approved |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into that @CMakeScore! The change itself seems fine to me, but indeed it looks like we'll need to tweak the unit tests (what you had before in the reference file looked correct to me).
I'm pretty sure all we need to do is call Score::startCmd
immediately after Dynamic::startEdit
, and Score::endCmd
immediately before Dynamic::endEdit
for those three tests. This will ensure the undo stack updates its current index as it would if the text was edited by hand (and we get the correct value for textWasEdited
).
In dynamicAddTextBefore
it looks like this:
...
dynamic->startEdit(ed);
score->startCmd(TranslatableString::untranslatable("Edit dynamic text (test)"));
score->undo(new InsertText(dynamic->cursor(), String(u"poco ")), &ed);
score->endCmd();
dynamic->endEdit(ed);
...
Once that's done just squash everything again and we should be golden (you can squash my commit into yours, I don't mind).
Fixed typed text not being displayed when special symbols are selected deleteSelectedText() updates the font family and must be executed before setting the new font family. Parse dynamics when finished editing Fix utest Fix menu order Remove redundant toDynamic Fixed undo not update dynamicType Test it correctly
86451da
to
85e8b12
Compare
I've been busy this past week so I apologize for the delay in addressing this. |
Split from #25252
With this PR, dynamics you type with Ctrl+Shift+Alphabets will be interpreted and reflected in the playback.