Skip to content
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

Widget highlighting and shortcut system implementation #7488

Open
wants to merge 84 commits into
base: master
Choose a base branch
from

Conversation

szeli1
Copy link
Contributor

@szeli1 szeli1 commented Sep 5, 2024

This PR contains multiple changes and overall it is focused on improving lmms functionality communication with the user and on immediate feedback to the user.

These changes are the following:

  • The StringPairDrag system and the StringPair system now uses a unified enum as key instead of custom strings. Before this, key names weren't documented and they were scattered across multiple files.
  • A new class was added that implements handling shortcuts and highlighting widgets:
    • This class was designed to encourage developers to implement shortcuts and pasting data into the widget.
    • Shortcuts:
      • Shortcuts support all QT keys and modifiers and they can differentiate between how many times a shortcut was pressed. Each shortcut has a description.
      • Shortcuts aim to be easy to work with.
      • If the user moves the mouse over the widget, then the available shortcuts will automatically be displayed.
      • In the future settings could be added that could allow the user to change the shortcuts.
    • Highlighting:
      • The idea behind highlighting is to show users which widget can accept which StringPair key while dragging or copying. If the user starts to drag a clip, the other clips will be highlighted to show that they can accept the datatype associated with the drag event.
      • Highlighting will be active for 10 seconds after the user starts to ctrl + drag a widget or when a widget is copied.
      • Highlighting will stop after a successful paste, but the user can keep pasting into other widgets.
  • The new class is implemented inside Knobs (FloatModelEditorBase) and all clips. I plan to implement it in other widgets in the future (if this gets merged).

Problems:

  • For shortcuts to work the new InteractiveModelView widgets redirect PianoView's PianoView::keyPressEvent to themself. This solution works but it isn't ideal.
  • ClipView::getClipStringPairType and TrackView::getTrackStringPairType does not implement Special types of tracks (video, event)
  • Shortcuts without modifiers (Qt::NoModifier) are not supported because of focusing issues.
  • I removed ClipView::dropEvent copying code because I found that this condition is never true:
// Defer to rubberband paste if we're in that mode
if (m_trackView->trackContainerView()->allowRubberband() == true)

Picture showing highlighting (for knobs and clips separately):

widget_highlighting6

Copy link
Member

@messmerd messmerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked over all the code yet, but here are some of my initial thoughts

@@ -40,6 +42,36 @@ namespace lmms::Clipboard
StringPair,
Default
};

enum StringPairDataType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name could probably be shortened to just DataType or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which one is better: KeyType or PairType or PairDataType or maybe CarriedDataType? I think DataType doesn't say anything about the StringPairDrag system and it could be confusing because there is also a Default mime type, but I guess this can be fixed with a comment.

I would like to get a finalized name because this change would effect 30 files.

Copy link
Member

@tresf tresf Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps MimeType::Default could be renamed to MimeType::Plain so that it's contextualized away from further entropy, then you could choose whatever name you'd like, including something as simple as Clipboard::Type, since for all intents and purposes, that's what this enum describes.

Edit: Hmm... on second thought, Type would look ugly next to MimeType, so perhaps @messmerd's proposal of DataType is the shortest possible name that we can get away with?

return shortcuts;
}

void FloatModelEditorBase::processShortcutPressed(size_t shortcutLocation, QKeyEvent* event)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if the size_t shortcutLocation parameter could be const ModelShortcut& instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to keep the size_t because I think it is easier to use in this case (with switch) and it could be more optimized (checking if size_t == size_t instead of ModelShortcut == shortcutArray[index]).

@szeli1 szeli1 force-pushed the widget_highlighting_and_improvements branch from 643cada to 2012037 Compare November 2, 2024 22:20
@qnebra
Copy link
Collaborator

qnebra commented Nov 21, 2024

So, overall:

  • shortcut system is fine, not absolutely perfect and across entirety of lmms, but much better than having nothing
  • linked controls, when user gets an idea on how to use it, is actually well done and useful. Just don't link a lot of controls, as disconnecting one by one can be tedious.
  • new automation pattern drag & drop behaviour, while changes few things in workflow, is much less buggy and had properly working undo, comparing to old method

It doesn't cause major issues with lmms in my case of using it daily for around two - three weeks.

@szeli1
Copy link
Contributor Author

szeli1 commented Jan 27, 2025

the volume of the midi track goes down without an active automation track.

I'm sorry, but I'm unsure if I see where this occurs. I don't see knobs moving and in the clip, both times the volume stays the same.

@Spacemagehq
Copy link

the volume of the midi track goes down without an active automation track.

I'm sorry, but I'm unsure if I see where this occurs. I don't see knobs moving and in the clip, both times the volume stays the same.

I looked elsewhere and nothing is automating the volume to make it go down.

@szeli1
Copy link
Contributor Author

szeli1 commented Jan 27, 2025

I looked elsewhere and nothing is automating the volume to make it go down.

I don't see where this happens, could you point me to the right direction?

@Spacemagehq
Copy link

I looked elsewhere and nothing is automating the volume to make it go down.

I don't see where this happens, could you point me to the right direction?

The issue is in the envelope tab in the instrument ui. when you turn the amt to the right, the audio bug happens. But if you don't the audio bug is not there.

@szeli1
Copy link
Contributor Author

szeli1 commented Jan 27, 2025

The issue is in the envelope tab in the instrument ui. when you turn the amt to the right, the audio bug happens. But if you don't the audio bug is not there.

Please could you show a screenshot of what happens and a description of what happens and a description of how it should behave? And a description of how to recreate it. I'm sorry, but I don't know what you mean by "audio bug", since I didn't touch the audio code. I believe you are trying to show that a knob moves without any automation channel attached, but I can't see this in the video you showed. I tried to reproduce the video and I believe everything worked as expected.

Please could you describe the issue you are experiencing in detail?

@szeli1
Copy link
Contributor Author

szeli1 commented Jan 27, 2025

And please could you share your opinion about the actual features this PR brings? @Spacemagehq I would appreciate it if I got feedback on how the shortcut system could be changed and how this PR could be improved, or at least it would be useful if you confirmed that everything else worked as it should.

@regulus79
Copy link
Contributor

With this pr there's an audio bug on Windows 11 when you go to the volume tab in the build in instruments when you move the amt to the right the volume of the midi track goes down without an active automation track. I tested this with Nescaline as well, not just with TripleOscillator.

As far as I can tell, this is not a bug. Your envelope has a bit of hold, with the sustain at about half. So, after the hold time is up, the note will go down to the sustain volume of 0.5. If you don't want you note to decay, turn the sustain knob to 1. I don't believe this is relevant to this PR.

@Spacemagehq
Copy link

With this pr there's an audio bug on Windows 11 when you go to the volume tab in the build in instruments when you move the amt to the right the volume of the midi track goes down without an active automation track. I tested this with Nescaline as well, not just with TripleOscillator.

As far as I can tell, this is not a bug. Your envelope has a bit of hold, with the sustain at about half. So, after the hold time is up, the note will go down to the sustain volume of 0.5. If you don't want you note to decay, turn the sustain knob to 1. I don't believe this is relevant to this PR.

I looked at it again the nightly and the pr they both set to default values on both the pr and the nightly lmms the nightly doesn't have this audio issue. The issue can be user error and my fault, if it is, I just delete the video from the github.

@Spacemagehq
Copy link

And please could you share your opinion about the actual features this PR brings? @Spacemagehq I would appreciate it if I got feedback on how the shortcut system could be changed and how this PR could be improved, or at least it would be useful if you confirmed that everything else worked as it should.

The pup up hotkey and the highlights I had no issues with. This might be a useless thing to add, but maybe the ability to change the highlight color in the future ?

@Spacemagehq
Copy link

Fixed the audio issue turns out it was something on my end didn't have a setting set correctly, both Golden Plunger on discord and regulus give me the solution. Deleting the video that is on here.

@@ -65,11 +67,62 @@ namespace lmms::Clipboard
}


QString getStringPairKeyName(StringPairDataType type)
Copy link
Member

@tresf tresf Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it right to assume that this will construct a new QString on each call to getStringPairKeyName? I'm not too familiar with C++ enums, but getting an enum by name is so very common in other languages that I feel that there may be a better strategy to this (seems like something that may be best tucked into the header too). Feel free to resolve this comment if I'm way off base.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it is needed to construct a "String" pair.

Copy link
Member

@tresf tresf Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes... Although this is technically true, I believe that in all or nearly all cases the code will effectively construct a new QString by concatenation (e.g. + ":Foo") (discarding this value immediately after constructing it)... Do you think it would make sense to make it more of a utility function that does this task for the developer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So void getStringPairKeyName(StringPairDataType type, QString& stringPair)?

Copy link
Member

@tresf tresf Feb 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of spitballing without knowing the code a whole lot so bear with me here...

  • Assuming that I'm right and that getStringPairKeyName doesn't need to construct a new QString each time it's called (and may be a candidate as a private function). 😅 then...
  • A utility functioncreateStringPair(StringPairDataType type, QString& value) can construct the new QString for cases where it's needed (e.g. new QString("Foo:Bar"))
  • copyStringPair will do the concat using createStringPair
  • StringPairDrag will do it's concat using createStringPair

As a result:

  • This will ensure that there's a contract between Clipboard and createStringPair to always create a new object.
  • Comparators such as decodeKey aren't creating new QStrings each time getStringPairKeyName is called.

Does that make any sense? 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants