Commit Graph

73 Commits

Author SHA1 Message Date
regulus79
679f9b848e Add splitting (and resizing) to all types of clips (#7477)
Allow for splitting and resizing all types of clips (automation, MIDI, sample, pattern, etc) using the knife tool in the Song Editor.

---------

Co-authored-by: szeli1 <143485814+szeli1@users.noreply.github.com>
Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
2025-04-29 17:56:13 -04:00
Rossmaxx
7367750823 [Code Cleanup] Cleaned up some header files and move a bit of debugging logic to cmake (#7677)
* Renamed lmms_basics.h to LmmsTypes.h and scoped it down for that purpose.

* Shifted the LMMS_STRINGIFY macro to it's own header.

* Removed the debug.h header file and use cmake to handle the macro logic.

* Remove some unused headers and include directives
2025-03-24 19:07:46 +05:30
Cas Pascal
786088baec Improve performance when rendering sample waveforms (#7366)
This PR attempts a number of improvements to the sample rendering (in the song editor, automation editor, AudioFileProcessor, SlicerT, etc) in LMMS:

Thumbnails: Samples are aggregated into a set of thumbnails of multiple resolutions. The smallest larger thumbnail is then chosen for rendering during sample drawing. Each set of thumbnails is stored with its sample file metadata in an unordered_map, so that duplicate samples will use the same set of thumbnails.

Partial rendering: additionally, this PR only renders the portions of the sample clips visible to the viewer to save rendering time.

* Experimental sample thumbnail

* Rename some classes and type aliases. Make some type declarations explicit

* Use a combination of audioFile name and shared_ptrs to track samples; refactor some loops

* That weird line at the end of the sample is now gone

* Small changes to the code; Add comments

* Add missing word to comment; Fix typo

* Track `SharedSampleThumbnailList`s instead

* Major refactor; implement thumbnailing for SlicerT, AFP and Automation editor

* Code clean up, renames and documenting

* Add the namespace lmms comments

* More code updates and documentation

* Fix error in comment

* Comment out `qDebug`s

* Fix formatting

* Use alternative initialization of `SampleThumbnailVisualizeParameters`

* Remove commented code

* Fix style and simplify code

* Use auto

* Draw lines using floating point

* Merge the classes into one nested class
+ Replace while loop with std::find_if

* Fix comparison of different signedness

* Include memory header

* Fix a logic error when selecting samples; Rename a const

* Fix more issues with signedness

* Fix sample drawing error in `visualizeOriginal`

* Only render regions in view of the sample

* Allow partial repaints of sample clips

* Remove unused variable

* Limit most of the painting to the visible region

* Revert back to using rect() in some places

* Partial rendering for AutomationEditor

* Don't redraw painted regions; allowHighResolution; remove `visualizeOriginal`; Remove s_sampleThumbnailCacheMap

* Add s_sampleThumbnailCacheMap back for testing convenience

* Minor change to the way `thumbnailSizeDivisor` is calculated

* Extend update region by an amount

* forgot about this

* Adapt to master; Redesign VisualizeParameters; Don't rely entirely on needsUpdate()

* Don't try to preserve painted regions

* Allow for a bit more thumbnails; Fix incorrect rendering when vertically scrolling

* Fix missing include statement

* Remove the unused variable

* Code optimization; Remove RMS member from Bit; Rename viewRect to drawRect

* More code optimizations

* Fix formatting

* Use begin instead of cbegin

* Improve generation of thumbnails

* Improve expressiveness of the draw code

* Add support for reversing

* Fix drawing code

* Fix draw code (part 2)

* Apply more fixes and simplifications

* Undo some out of scope changes

* Remove SampleWaveform

* Improve documentation

* Use size_t for some counters

* Change width parameter to be size_t

* Remove temporary aggregated peak variable

* Bump up AggregationPerZoomStep to 10

* Zoom out only requested range of thumbnail instead of clipping it separately

* Rename targetSampleWidth to targetThumbnailWidth

* Handle reversing for AFP; Iterate in reverse instead of reversing the entire thumbnail

* Change names to be more accurate

* Improve implementation of sample thumbnail cache map

* Move AggregationPerZoomStep back down to 2, do not cap smallest thumbnail width to display width
To improve performance with especially long
samples (~20 minutes)

* Simplify sample thumbnail cache handling in constructor

* Call drawLines instead of drawLine in a loop

QPainter::drawLine calls drawLines with a line count of 1. Therefore, calling drawLine in a loop means we are simply calling drawLines a lot more times than necessary.

* Bump up AggregationPerZoomStep to 10 again
Thought using 2 would help performance (when rendering). Maybe it does, but it's still quite slow when rendering a bunch of thumbnails at once.

* Fix off-by-one error when constructing Thumbnail from buffer

* Fix crash when viewport is not in bounds

* Apply performance improvements

Performance in the zoomOut function was bad because of the dynamic memory allocation. Huge chunks of memory were being allocated quite often, casuing a ton of cache misses and all around slower performance. To fix this, all the necessary downsampling is now done within the for loop and handled one pixel after another, instead of all at once.

To further avoid allocations in the draw call, the change to use drawLines has been reverted.

We now pass VisualizeParameters by value (it is only 64 bytes, which will fit quite nicely in a cache line, which is more benefical than reaching for that data by reference to some other part of the code).

After applying these changes, we are now practically only bounded by the painting done by Qt (according to profiling done by Valgrind). Proper use of OpenGL could resolve this issue, which should finally make the performance quite optimal in  variety of situations.

* Apply minor changes

Update copyright and unused functions. Move in newly created thumbnail into the cache instead of copying it.

* Use C++20's designated initializers

* Create param right before visualizing

* Fix regressions with reversing

* Fix incorrect rendering in AFP and SlicerT

* Move MaxSampleThumbnailCacheSize and AggregationPerZoomStep into implementation file

* Remove static keyword

* Remove getter and setter for peak data

---------

Co-authored-by: Sotonye Atemie <sakertooth@gmail.com>
2025-02-08 20:05:19 -05:00
regulus79
7dbc80926d Adding proportional scrolling (#7476)
Add proportional scrolling to the song editor, piano roll and automation editor. Proportional scrolling means that if for example a certain measure is on the right side of the song editor then it will take a certain number of mouse wheel moves to get it to the left side of the editor. It is the same number of wheel moves regardless of the zoom level.
2024-10-06 21:27:39 +02:00
DanielKauss
c2811aebef Ghost notes for the automation editor (#6940)
Show ghost notes or sample track as a visual aid in the Automation Editor.

---------

Co-authored-by: IanCaio <iancaio_dev@hotmail.com>
2023-11-25 12:16:56 +01:00
saker
aa050ae0b7 Fix memory leaks (#6879)
* Replace knobFModel with std::vector

* Create QPixmap's on the stack

* Assign parent for QGraphicsScene
A call to QGraphicsView::setScene does not make
the view take ownership of the scene.

* Do not allocate QList on the heap

* Use static QPixmap's
The QPixmap's need to be created within the constructor, and not outside
where they are defined, since it can't find them otherwise.
I'm not too sure why.

* Clear m_vi2->knobFModel in destructor

* Use local static QPixmap's

* Do not allocate QPixmap with new in AudioFileProcessor

* Do not allocate QPixmap with new in Nes

* Do not allocate QPixmap with new in Organic

* Do not allocate QPixmap with new in SaControlsDialog

* Do not allocate QPixmap with new in Vestige

* Do not allocate QPixmap with new for FileBrowser

* Do not allocate QPixmap with new in MixerLine

* Do not allocate QPixmap with new in SendButtonIndicator

* Do not allocate QPixmap with new in AutomationClipView

* Do not allocate QPixmap with new in MidiClipView

* Do not allocate QPixmap with new in AutomationEditor

* Do not allocate QPixmap with new in PianoRoll

* Do not allocate QPixmap with new in TimeLineWidget

* Do not allocate QPixmap with new in EnvelopeAndLfoView

* Do not allocate QPixmap with new in PianoView

* Do not allocate QPixmap with new in ComboBox

* Do not allocate QPixmap with new in Fader

* Do not allocate QPixmap with new for LcdWidget

* Do not allocate QPixmap with new for LedCheckbox

* Use m_ as prefix for members

* Use uniform initialization
I already started using uniform initialization for the QPixmap changes
for some reason, so I'm finishing that up.

* Uniform initiaization

* And then he realized he was making copies...

* Do not call QPixmap copy constructor

* Do not call QPixmap copy constructor in SaControlsDialog

* Do not make pixmap's static for Lcd's and Led's

* Initialize pixmaps in-class

* Fix few mistakes and formatting
2023-11-19 00:44:15 -05:00
IanCaio
999c10e4b3 Adds feature to edit tangents of Cubic Hermite progressions (#5924)
Enables the editing of a node's tangents of Cubic Hermite progressions.

* First commit

	This commit introduces the use of AutomationNodes instead of just floats for keeping the automation values. The AutomationNodes will give more flexibility when it comes to storing extra information about the values (and make it possible to have multiple progression types in the future). Now the tangents are stored on the node, requiring one less timeMap on the automation pattern. Some methods had to be changed for that, since before they used const_iterator, which wouldn't allow us to change the tangent values.

TODO:
	- Check TODO comments that were added in places of the code I had some doubts about.
	- Maybe change the timeMap to hold pointers to AutomationNodes and not actual instances.
	- In some pieces of the code, I check if the AutomationNode already exists before setting its value or creating another node. I think that's unnecessary since if I create another node and assign it to the current existing one it could just clone its value. (That would not be valid for pointers to AutomationNodes, so that's something to consider when deciding between the two).
	- I still didn't find a good solution for renaming QMap::iterator method from "value()" to something else, so now we have lines that look a bit odd like "it.value().getValue()", because value() is actually returning the node, and getValue() is getting the node's automation value.

* Implements inValue/outValue on Automation Nodes

	This commit is a big change in comparison to the previous one. Automation nodes now have a inValue and outValue instead of a single value. The inValue represents the core value of the node, which is used for incoming progressions. The outValue represents the value of the node for progressions starting from that node on. In practice, the true value of the node is the inValue and outValue represents a way of creating discrete jumps in a node's position.
	By default inValue and outValue are the same. The user will then be allowed to change the outValue to create those discrete jumps. Because their values might be different, we now need two tangents for a single node: One for the curve coming before the node and one for the curve coming after the node. So instead of a single tangent variable, we now have inTangent and outTangent. If inValue and outValue are the same, so are inTangent and outTangent, but if they are different both are calculated according to the curve before and after the node.
	On the Automation Editor, the inValue of the node is represented by our default blue circle, while the outValue is represented by a red circle with 80% alpha (we should add a variable to the Automation Editor class to hold the color of this second circle in the future).
	Lots of comments were added on the modified files to explain the existing methods where changes were required (not only explaining the logic of the methods but the reason behind using inValue or outValue on them). Lots of TODO comments were also added as placeholders for changes that could or should be done before the finishing of this PR (or after it).
	For now only the logic for the nodes was added, but there's still no way for the user to change outValues (on the next commit a small placeholder shortcut will be added to do that for testing purposes).
	The drawing of the notes detuning on the piano roll was updated to account for the discrete jumps.
	The drawing of the pattern TCO was updated to account for the discrete jumps.
	The drawing of the pattern on the AutomationEditor was updated to account for the discrete jumps.

	IMPORTANT:
		- There were changes to the loadSettings and saveSettings of AutomationPatterns, to account for inValues and outValues, but I didn't create an upgrade routine yet.

	Some behavior that is important to mention:
		- Most operations on nodes (drawing, moving, X/Y flipping, and even selection copy/paste, apparently not fully finished) ignore the outValue, basically reseting it to the inValue. So when an user moves a node with a discrete jump, for example, that discrete jump will be lost and the user will need to set it again. Obviously in the future we might want to keep that information, but that isn't a critical issue, just a behavior that can be improved later by upgrading the code.
		- Later on we might want to connect a signal to the AutomationNode class, so it calls generateTangents when node data is changed.
		- When an object is disconnected from an automation pattern and it has to rescale the values so they fit the new range of values (max and min) the outValue is reset, meaning all discrete jumps are lost. This behavior will be changed in the future.

	Things that I think are also important noting:
		- Mainly in the src/gui/editor/AutomationEditor.cpp file there were lots of codes that apparently are related to a feature that is not yet finished (moving/cutting/copying/pasting selections of automation values). This doesn't sound good unless it's currently being worked on. I tried my best to update the current code to comply to the use of AutomationNodes so their developing can be picked up from a unbroken state. As with other operations involving AutomationNodes, they only account for the inValue discarding any discrete jumps that were present.
		- I added comments on some logic that seemed flawed in the src/gui/editor/AutomationEditor.cpp file so it can be reviewed. It's beyond the scope of this PR, but since I had to read and change a lot on that file I thought it was pertinent to at least comment those observations.

* Fixes and refactor code on AutomationEditor.cpp

	While implementing the automation nodes, I noticed AutomatinEditor.cpp had some issues regarding flawed logic, code style convention, code that could comply to DRY paradigm, conditions that resulted in Undefined Behavior and unused legacy code. That's probably due to how old some changes are, they probably reflect a much different state of LMMS's code base. To make the transition to automation nodes a better one and avoid having to rework everything later I'm using the fact I have to get in touch with most of this code to try to fix some things.

	This commit starts refactoring AutomationEditor::mousePressEvent and AutomationEditor::mouseMoveEvent. There are still things to be improved on both but I'll slowly commit them so I can have better versioning control of the PR.

	Some changes worth noting:
		- A new action was created in the AutomationEditor class for drawing lines, since its logic was too mixed up with the logic of drawing and dragging a single node.
		- Changed most variable names to fit the current code style (just very few left to change).
		- Improved comments explaining the code.
		- Created a separate method for checking if the mouse position is sitting over an existing node (previously this code was repeated inside the event method and it had flaws on its logic, most of the times returning that the user didn't click a node even when he/she clicked one). Method is called getNodeAt(x,y,r), r being the "radius" to be considered (not actually a radius, the area is actually a square).

	Some changes that are still planned:
		- Removing legacy code for features that weren't finished (select and move selection) if it's agreed.
		- Adding some logic to the DRAW_LINE action so it can be even improved.
		- Not forgetting the main focus of the PR, adding a way for the user to edit the outValue of nodes.

* Avoids unnecessary check in putValue

	When adding a value to a particular time, instead of checking if there's a node there already and manually setting its value, we just assign it with a new AutomationNode. QMap silently removes the existing node and adds the new one.

* Adds upgrade routine for the automation nodes

	Adds an upgrade method for the change in the automation nodes settings. The "value" attribute of the <time> element is deleted and assigned to the "inValue" and "outValue" attributes.

	Now older project files can be loaded properly.

* Allows dragging outValues on the Automation Editor

	This commit introduces a way for the user to drag outValues on the Automation Editor, by Alt+clicking the outValue red node and dragging up and down.

	A new action was added for that purpose, called MOVE_OUTVALUE. When the user clicks a outValue sphere with the Alt modifier, m_action is set to MOVE_OUTVALUE, and the time position of the node being affected is stored on m_draggedOutValueKey. That is later used on the mouseMoveEvent to update the outValue of the node.

	Removed repeated code on the mouseReleaseEvent and removed excessive blank lines after a method.

	Things to keep in mind when testing through this commit's build:
		- Creating/Moving an automation node resets the outValue
		- When the outValue is changed, generateTangents isn't called automatically. So you'll notice that after adding another automation node the curves change (that's because after the new node being added the tangents are then recalculated).

	Still lots of work ahead!

* Small fix inside AutomationPattern.cpp

	Unnecessary loop was removed with call to appropriate method.

* Creates separate files for AutomationNode

	Creates a separate header and source file for the AutomationNode class.

* Adds more members to AutomationNode

	Adds 2 new members to the AutomationNode class:
		m_pattern - A pointer to the pattern this node belongs to
		m_key - The time position (timeMap key) of this node

	The constructors (and places they were used) were updated accordingly. AutomationNode was also made a friend class of AutomationPattern so it can access private/protected methods from its pointer. This will be later used to allow AutomationNode's to call generateTangents once their values are updated.

	Small fix on a code block related to moving selections inside the mouseMoveEvent from AutomationEditor.

* Removes unused code from AutomationEditor

	This commit removes code that was not currently used in the AutomationEditor. Most of it was related to a feature I believe was once functional but broke along the way, but the code was not cleaned up in an effort to fix it later. The feature allowed selecting and moving/cutting/copying/pasting/removing values from the automation pattern. It added up to lots of lines of code, which so far I was keeping up to date to the changes. However, I believe (and others devs agree) that rewritting this code later might be a better approach than trying to fix what we currently have, so I'm removing the obsolete code. The git history will allow us to reference back to it when implementing the feature again and this will make it harder for this PR to introduce bugs because a certain affected feature couldn't be tested.

	It also makes reviewing easier, for there are less affected code to cover.

For reviewing purposes:
	I used a single commit for removing the mentioned code, so its diff in relation to the previous commit should give a good idea of everything that was removed.

* Changes to the outValues now update the tangents

	The methods that change the inValue and outValue of nodes now also generate new tangents for the previous, current and next nodes (the ones affected), so now when the user drags the node outValue the curve is updated accordingly.

* Keeps discrete jumps when flipping patterns

	Adds a method to the automation node that returns the valueOffset between inValue and outValue. AutomationPattern::putValue now has an extra parameter called outValueOffset (defaults to 0), so when it adds a node to the timeMap the outValue is set according to this offset. flipY() will calculate the offset and invert it, so the discrete jumps are kept but flipped vertically as well. flipX() doesn't need to calculate this offset because it uses the outValue itself.

Obs:
	I believe cleanObjects() was meant to be called everytime AutomationPattern::flipX() is called, but it was inside a conditional that would only call it on some situations. I moved it outside of the conditional.

* Allows reseting outValues on the AutomationEditor

	User can now reset the outValue of nodes on a very analogous way to removing nodes but with the Alt key pressed. Alt + right clicking over the node (or dragging over an area), or Alt + clicking on it on Erase mode (or dragging over an area) will reset the outValues of the nodes.
	To do that, two new actions were created: ERASE_VALUES (for the regular node removing) and RESET_OUTVALUES (for the outValues reseting). Those are checked for in the moveMouseEvent, which acts accordingly. The removePoints() method was removed and two new methods were added instead: removeNodes() and resetNodes(), which will remove nodes on a tick range or reset them respectivately.

	The AutomationNode.h and AutomationNode.cpp files were fixed to fit the current code style conventions. The other files were kept as is, so they can be changed all at once at the end of the PR.

	Change requests made by Veratil were done.

* Makes so dragging nodes keep the outValue

	This commit makes a small change to setDragValue. When starting the drag (m_dragging == false), it checks if the time position being dragged already has a node. If it does, then the offset between inValue and offValue is stored on m_dragOutValueOffset so it can be used on the putValue calls, keeping the offset. If there isn't a node in the time position, m_dragOutValueOffset is set to 0.

* Fixes code style on modified code

	Fixes the modified code to comply to current code style convention.

	I tried to keep the changes exclusive to the lines modified by this PR (to keep the diff cleaner), but I might have fixed a couple of other because either they were hard to differentiate on the current diff or because they were too close in context. But still, tried to keep changes mostly to the lines actually changed by the PR.

* Adds a QProperty for the node outValue color

	Adds a CSS property for the outValue color and renames the one used for the inValue color so they are consistent.

	Colors were added to classic and default themes. The original inValue colors were kept, but to fit with the outValue node they had a little bit of transparency added.

* Adds doxygen comments on methods

	Adds doxygen comments explaining methods that were either introduced by this PR or which had parameters modified by this PR.

	Changes valueAt(timeMap::iterator, int offset) method, so it can handle offsets equal to 0 properly. This method is currently never used with an offset of 0 (because this case scenario is handled before this method is called), but it was a simply modification so I just added the conditional to make it possible to use an offset of 0.

* Refactor flipX and flipY methods

	AutomationPattern::flipX and AutomationPattern::flipY had some issues to the logic that caused UBs (from accessing an iterator past QMap::end()) and possibly misbehaviors when flipping an empty pattern.
	Both were refactored to fix those noted issues.

* Add a new edit mode to Automation Editor

	Adds another editing mode to Automation Editor (DRAW_OUTVALUES), specific to deal with node outValues. The Pixmap being used is the same as the DRAW edit mode for now.

	The way it works now:

DRAW Mode (Shortcut SHIFT+D)
	Shift + Left click = Draws lines of nodes
	Left click = Draws/Drag node
	Right click = Remove nodes

ERASE Mode (Shortcut SHIFT+E)
	Left click = Remove nodes
	Right click = Reset outValues

DRAW_OUTVALUES Mode (Shortcut SHIFT+C)
	Left click = Drags outValue
	Right click = Reset outValues

	Now using a switch statement on the events to make things more organized.

* Improves the Draw OutValue edit mode

	Now, instead of only being able to change an outValue by clicking over the sphere representing it, the user can also click on any time on the pattern: If the quantized time of the place he clicked has a node, the outValue of its node will be set to the value where the mouse click happened and the outValue will start being dragged. Very similar to the way it works for the node itself on the draw mode.

* Adds mutex to AutomationPattern

	Adds a recursive mutex to the AutomationPattern class and locks it on every method that access the member variables. Also rename the mutex from the AutomationEditor class and add locks to some methods that didn't have it before (except on methods that don't access member variables).

* Veratil's review changes

	Applies changes requested by Veratil:
		- Replaces NULL with nullptr where necessary on AutomationEditor.cpp
		- Fixes spacing on the mutex commit (plus some other places)
		- Changes some if blocks to one liners
		- Replace while with do-while on some places, since the condition was already checked for earlier on the method.
		- Moves getNodeAt call a level up on the block, since it's called on both conditionals below.
		- Fixes identation on some code inside AutomationEditor::mousePressEvent.
		- Adds explicits blocks on a switch statement. Even though this was not necessary for that particular one (because there was no variable declaration inside it) it helps keeping it consistent with another switch statement that happened earlier.

I also added a break statement to the last case of a switch (even though it was not needed, it's safer to avoid mistakes in the future with new cases being added).

* Changes the inValue sphere to be draw first

	The red sphere representing the outValue was drawed after the blue sphere representing the inValue. Because of that, if they had the same value the red sphere would be on top. For the user, it makes more sense to be able to see the blue sphere representing the input value on top instead. This commit changes the order of the drawing.

* Changes comments and variables names

	Fixes some comments pointed out on Spekular's review. Changes the AutomationNode's variable m_key to m_pos (leaving a comment on the header reminding that it matches the timeMap key). Removes comments related to removed code. Fixes code style on a pointer declaration.

* Changes QProperty variables to use MEMBER

	Instead of creating a getter and setter for each QProperty, we use MEMBER instead and access those variables directly.

* Overloads some AutomationNode's operators

	Overloads compound assignment operators +=, -=, *= and /= for AutomationNodes, making it so they affect the inValue and outValue of the node being assigned. Changes AutomationPattern::flipY() so it uses the new operators.

* Improves getNodeAt method

	Makes the AutomationEditor::getNodeAt method more efficient, by exiting if the node we are checking is already past the position we given (since the nodes are ordered in the timeMap, all subsequent nodes will also be past the position). Now instead of returning the last node that is inside the coordinates, it returns the first.
	Also improves AutomationEditor::mousePressEvent to avoid getNodeAt being called twice unnecessarily.

* Changes behavior of setDragValue

	Now, instead of keeping the offset between the inValue and outValue while dragging a node, setDragValue will either keep the current outValue intact, or move it together with the inValue if they are the same.
	The putValue method now doesn't have an offset parameter. If we want to put a node with an outValue different from the inValue we use putValues instead.

* Moves getNodeAt to an upper level, reducing lines

	Creates a boolean before the m_editMode switch, that will be true if the action being processed affects outValues and false if it affects inValues. That way we can move the statement clickedNode=getNodeAt() before the switch-case, reducing repeated lines.

* Changes icon of Draw OutValue edit mode

	Changes the icon for the Draw OutValue tool and toolbar action, so it's different from the Draw mode. Just a placeholder until a visual artist come up with something better or we change the controls.

* Removes unnecessary non-const methods

	Some getter methods had declarations for both const and
non-const object types, when just the const one were needed (no changes
to the object are made). The unnecessary ones were removed.
	Also fixes formatting on operator /= method.

* Fixes formatting and doxygen comments

	Fixes doxygen comments on AutomationPattern.cpp and
AutomationEditor.cpp (also changes one so it uses the same format as the
rest of the file).
	Fixes some formatting issues (removal of excessive tabs,
changing some statements to be one line instead of multiple lines,
fixing of spacing, use of one line ifs, removal of unnecessary else on a
method, use of ternary expressions, etc).

* Adds helper macros for AutomationNodes

	Adds 3 macros to the AutomationNode header file: INVAL, OUTVAL
and POS, which return the InValue, OutValue and Key of a node
respectively. This improved redability and made statements shorter on
the AutomationPattern.cpp code.
	Macros weren't added for InTangent and OutTangent, since those
are only used once in the code (and INTAN/OUTTAN might not have their
meaning as obvious as INVAL/OUTVAL).

* Removes tabs from ternary operator

	Removed tabs to improve formatting on a ternary operator
as requested and also removed a comment that doesn't seem necessary.

* Update files to use AutomationNode macros

	Other files besides "AutomationPattern.cpp" also included the
AutomationNode.h header and handled automation nodes, but they weren't
using the macros. Those were updated to use INVAL, OUTVAL and POS
macros.
	Two conditionals were changed to one liners for consistency.

* Addresses my own code review

	This commit addresses some fixes from a review I made from the
code on Github and also one requested change from Veratil.

	Changes:
	- Fixes code style issues.
	- Adds a helper MACRO to return the offset between the inValue
and outValue of a node and use it where getValueOffset was called.
	- Removes conditional that was not needed inside
AutomationPattern::valueAt.
	- Updates InlineAutomation.h to use the helper MACROs and
account for the outValue when deciding whether to save or discard an
inline automation.
	- Adds TODO comments on two loops present on
src/code/AutomationPattern.cpp that could be optimized.
	- Fixes some comments.
	- Uses INVAL(it) instead of valueAt(POS(it)) on the flip methods
when possible.
	- Adds a resetOutValue() method to AutomationNode and use it
where convenient.
	- Fixes a small "bug" where flipping a pattern from the TCO
context menu, when the pattern is smaller than the TCO, would use the
inValue of the last node for the node created at the end of the TCO
instead of the outValue (which is the value that the position would have
if the pattern continued).

* Addresses Veratil's review

	- Fixes some code style issues
	- Changes to improve readability at some snippets
	- Uses if one-liners when convenient
	- On a polynomial expression inside AutomationPattern::valueAt,
uses some variables to improve readability (those will be optimized out
by the compiler)
	- Removes unnecessary casting on alignedX variable inside
AutomationEditor::mousePressEvent (it was also using C-style casting
instead of static_cast)

* Adds helper MACROs for node tangents

	Adds INTAN and OUTTAN macros to retrieve a node's InTangent and
OutTangent respectively, and replace calls to getInTangent/getOutTangent
with those macros.

* Fixes header inclusion order

* Removes mutex from AutomationEditor

	Now that there's a mutex protecting the AutomationPattern on its
own methods, there's no need to have a mutex on the AutomationEditor
class. The editor's member variables don't need to be protected because
LMMS's UI runs from a single thread.
	This commit removes the m_patternEditorMutex.

* Locks mutex on AutomationPattern copy assignment

	On the copy assignment constructor of AutomationPattern, the
values were being copied from the other pattern without locking its
mutex, which could result in race conditions. Now the constructor locks
the other pattern's mutex.

	Other small changes:
	- Removes unnecessary comments and fix others.
	- Uses the OFFSET macro on the generateTangents method.
	- Uses the resetOutValue() method on
AutomationEditor::mousePressEvent, in a place where I forgot to change
it.

* Changes resetOutValue() so it generates tangents

	Changes the AutomationNode::resetOutValue() method so it calls
setOutValue() instead of directly setting the m_outValue, since the
latter will also take care of generating tangents.
	Fixes small bug where reseting outValues would not recalculate
the tangents.

* Changes some methods to use for loops

	AutomationEditor::removeNodes and AutomationEditor::resetNodes
were previously using while loops where for loops are much more well
suited. Both methods were changed to use those instead.

* Move removeNodes/resetNodes to AutomationPattern

	- Renames AutomationPattern::removeValue to
AutomationPattern::removeNode.
	- Moves AutomationEditor::removeNodes and
AutomationEditor::resetNodes to AutomationPattern, since they are more
suited there and could be reused in other areas of code that need to
remove a range of nodes.

* Optimizes loop inside putValue/putValues

	There was a TODO comment about a loop that could be optimized
inside putValue/putValues. It went through all the ticks in the
surrounding values instead of just going through the nodes that were in
that range. Now that the removeNodes/resetNodes methods are part of the
AutomationPattern we can use them to optimize the loop.

	Changes:
	- removeNodes/resetNodes will remove or reset a node if a range
with start == end is given (before it would return).
	- The loop was replaced with a call to removeNodes from
newTime + 1 to newTime + quantization() - 1 (which will cover the nodes
that are between the quantization limits). We add a conditional that
quantization() is greater than 1 to avoid a bug where the added node is
removed by that call because we get a range from [newTime + 1, newTime].

* Adds comment to mysterious calculation

	There was a calculation on the drawAutomationPoint method that
wasn't really obvious at first glance. Thanks to @PhysSong, a comment
was added explaining the reasoning behind the calculation.

* Reduces indentation on getNodeAt

	Reduces one indentation level on AutomationEditor::getNodeAt()
by reversing the conditional.
	Fixes style on switch statements.

* Applies Veratil suggestions

	Condense two code blocks in a single one by using a ternary
operator on the only variable that changed between them.

	Comment out a "else" block that currently doesn't have anything
(placeholder for future code).

	Format a for statement in multiple lines to improve readability.

* Updates comment from changed code

	Updates comment to better match the recently changed code.

* Uses lambda functions to extract code

	Uses two helper lambda functions inside
AutomationEditor::mousePressEvent to extract code and use fewer lines on
places where it's repeated.

* Fixes behavior of AutomationPattern::flipX

	To truly flip a pattern horizontally, we also needed to swap the
inValues and outValues of the nodes being flipped. This commit fixes
that behavior by including the swap when necessary.

	Also adds a TODO comment regarding the behavior of the
generateTangents method when the difference between inValue and outValue
is very small.

* Changes pattern XML for backwards compatibility

	Changes the inValue attribute name on the XML from "inValue" to
"value" to make projects created with the new automation pattern
partially backwards compatible (outValues will still not be loaded
obviously, but the inValues will be loaded as the regular pattern values
we had before).

* Fixes bug on AutomationPattern::resetNodes

	Fixes bug on AutomationPattern::resetNodes: If it was called
with tick0 == tick1, m_timeMap.find() return value was being used to
call resetOutValue. When QMap::find() doesn't find a value it returns
QMap::end() though, resulting in a SegFault.
	Fixed by checking if the return value is QMap::end() first.

* Adds drawing of automation node tangents

	This introduces a method on the AutomationEditor that draws a
line and an ellipse representing the inTangent and outTangent of
Automation Nodes, so they can be visualized on the Cubic Hermite
progression.
	The tangents are not yet editable.

* Adds mode to edit tangents

	Adds the edit mode that will be used to edit tangents. For now
there's no functionality, only the GUI elements were added.

* Adds comment about copy-assignment

	Adds a note about the default copy-assignment from
AutomationNode being used on the AutomationPattern constructor. If any
dynamic allocated resources are added to the class, an user-defined
copy-assignment constructor should be used instead.

	Also changes the position of an arithmetics operator on a
multiline statement for readability.

* Changes flipY logic and address PhysSong review

	This commit addresses PhysSong review:
	- An if-statement was replaced with a ternary operator on
AutomationEditor::paintEvent().
	- One comment was improved on PianoRow::drawDetuningInfo() to
make it clearer that drawing cubic hermit curves as straight lines is
just a temporary thing.
	- While applying the requested changes on the
AutomationPattern::flipY() method, I noticed that even though it
accepted any integer values as min and max, the current logic (both on
master and on the previous commit from this PR) would only work if the
range was [-max,+max] or [0,+max]. If min was -5 and max 10 for example,
the flipping could return us a pattern with values out of range. This
commit replaces the logic with an improved one that now relies on the
distance between the node and the edges of the range instead, thus
working for any range instead of those two mentioned earlier. The new
logic also attend to the request of using a for-loop and also using
in-place operations.

* Implements the dragging of node tangents

	Implements the action of dragging node tangents. A method called
getClosestNode returns the node that is closest to the mouse X position.
Then the action begins, with the tick of the node having its tangent
dragged stored in a local variable. It's also calculated whether we are
dragging the inTangent or outTangent.
	The new tangent is calculated as the tangent between the current
mouse position and the automation node.

* Saves tangent information from automation patterns

	Now saves the tangent values of automation pattern nodes. While
loading, for backwards compatibility, if any node doesn't have tangent
information the tangents are generated. Else, they are loaded from the
project file and kept.

	Dragging a node still resets all tangents. Moving an outValue
resets the tangents from the surrounding nodes.

* Implements the locking of tangents

	Now when the used manually edits a node's tangent, the node
locks both its tangents so they aren't recalculated by
AutomationPattern::generateTangents().
	When the used resets the tangents of a node (by right clicking
close to it on the edit tangents mode) they are unlocked again, and are
allowed to be recalculated.
	This information is saved on the project file as well.
	A macro was added to quickly return whether a node's tangents
are locked.
	AutomationEditor was made a friend class of AutomationPattern to
enable it to call generateTangents when a node's tangent is reset.

* Checks only for inTan on the LoadSettings

	When loading an automation node, when checking if we have
tangent information we only have to check for either inTan or outTan,
because if we have one we will have the other.

* Adds a convenient way to reset multiple tangents

	Now right clicking and dragging on Edit Tangents mode will reset
multiple tangents (similar to how it works for the reseting and removal
of nodes).

* Fixes small bug on generateTangents

	AutomationPattern::generateTangents() expects that a valid node
is given. While generating the amount of tangents requested, it avoids
going out of bound by checking if the node after the one being iterated
is the end of the timeMap, then setting the tangents to 0 and returning.
That worked fine before, but now we skip nodes that have their tangents
locked, so it could happen that the last tangent was locked and skipped
and we end up iterating m_timeMap.end().
	This was causing a segmentation fault if we edited the tangents
of the last node and added a new node after it. To avoid that, a second
conditional was added to the for-loop to check if the current node is
the end of the timemap.

* Fixes bug with Edit Tangents shortcut

	Bug found by @superpaik. I was setting the Edit Tangents
shortcut to the Draw OutValues mode, overriding its correct shortcut and
leaving Edit Tangents with none.

* Disables Edit Tan mode on other progressions

	The Edit tangents mode is now disabled when the user switches to
a different progression mode and reenabled when it changes back to Cubic
Hermite mode.

* Keep tangents when dragging nodes

	As requested by @superpaik after testing, logic was added to the
AutomationPattern::setDragValue method to keep a node's tangents if they
were locked.
	First, the method checks if the tangents were locked in the
first drag iteration and store its values if they were.
	Then, everytime the dragging routine puts a new value in the
timemap, it will set its tangents and lock them if needed.

* Changes tangent calculation behavior

	Changes the behavior of the tangent calculation for the Edit
Tangent mode. The new behavior will be submitted for testing to see if
it's considered better than the previous one, and reverted if it isn't.
	Also fixes a possible division by 0 bug.

* Fixes undo/redo with tangents editing

	The tangents editing logic was missing adding a journalling
checkpoint, hence the undo/redo wasn't working properly.
	This commit fixes it.

* Uses function to check if tangents can be edited

As per requested by PR review, instead of checking if the automation
clip uses Cubic Hermite progression to allow changing tangents, we now
instead use a method that will return true if the current progression
type allows tangent editing. That way it's easier to allow tangent
editing for new progression types that might be added in the future.

* Fixes bug reported by zonkmachine

	- The Edit Tangents button was not updating correctly when
the clip was changed inside the automation editor. This was fixed by
making the update routine a separate method and calling it on the places
necessary (when changing progression modes and when changing clips).
	- Some suggestions from messmerd PR review were also included.

* A couple review requests forgotten

	- Just adds 2 more review requested changes that were forgotten
in the previous commit.

* Address Sakertooth's review

* Adresses Sakertooth's review

* Address Sakertooth's review

	- Simplifies method that updates the edit tangent button on the
automation editor

---------

Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
2023-10-06 18:37:46 -04:00
Dominic Clark
f10277715f Classier enums (#6760) 2023-08-24 19:16:02 +01:00
saker
9a0add49fb Core Refactor: Replace `QVector with std::vector` (#6477)
* Replace QVector with std::vector in AudioEngine

* Replace QVector with std::vector in AudioEngineWorkerThread

* Replace QVector with std::vector in AudioJack

* Replace QVector with std::vector in AutomatableModel

* Replace QVector with std::vector in AutomationClip

* Replace QVector with std::vector in AutomationEditor

* Replace QVector with std::vector in ConfigManager

* Replace QVector with std::vector in Controller

* Replace QVector with std::vector in ControllerConnection

* Replace QVector with std::vector in EffectChain

* Replace QVector with std::vector in EnvelopeAndLfoParameters

* Replace QVector with std::vector in InstrumentFunctions

* Replace QVector with std::vector in MidiClient

* Replace QVector with std::vector in Mixer

* Replace QVector with std::vector in Note

* Replace QVector with std::vector in PeakController

* Replace QVector with std::vector in PianoRoll

* Replace QVector with std::vector in PluginFactory

* Replace QVector with std::vector in RenderManager

* Replace QVector with std::vector in StepRecorder

* Replace QVector with std::vector in Track

* Replace QVector with std::vector in TrackContainer

* Replace QVector with std::vector in Song

* Adapt QVector to std::vector changes in ControllerConnectionDialog

* Phase 2: Use std::abs in panning.h
Without this, the QVector changes will make the code not compile.

* Phase 2: Replace QVector with std::vector in PeakControllerEffect

* Phase 2: Replace QVector with std::vector in AutomatableModel

* Phase 2: Replace QVector with std::vector in AutomationClip

* Phase 2: Replace QVector with std::vector in ControllerConnection

* Phase 2: Replace QVector with std::vector in EffectChain

* Phase 2: Replace QVector with std::vector in Mixer

* Phase 2: Replace QVector with std::vector in PeakController

* Phase 2: Replace QVector with std::vector in RenderManager

* Phase 2: Replace QVector with std::vector in Song

* Phase 2: Replace QVector with std::vector in StepRecorder

* Phase 2: Replace QVector with std::vector in Track

* Phase 2: Replace QVector with std::vector in TrackContainer

* Phase 2: Adapt QVector changes in EffectRackView

* Phase 2: Adapt QVector changes in AutomationClipView

* Phase 2: Adapt QVector changes in ClipView

* Phase 2: Adapt QVector changes in AutomationEditor

* Phase 2: Adapt QVector changes in PianoRoll

* Phase 2: Adapt QVector changes in TrackContainerView

* Phase 2: Adapt QVector changes in TrackContentWidget

* Phase 2: Adapt QVector changes in InstrumentTrack

* Phase 2: Adapt QVector changes in MidiClip

* Phase 2: Adapt QVector changes in SampleTrack

* Fix segmentation fault in ConfigManager::value

* Fix unintended faulty std::vector insert in AutomationClip::resolveAllIDs

* Resolve trailing whitespace in src/core/StepRecorder.cpp

Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>

* Use std::next and std::prev in EffectChain::moveUp/moveDown

* Introduce static "combineAllTracks" function in AutomationClip

* Adjust variable name in Song::automatedValuesAt

* Adjust removal of long step notes in StepRecorder::removeNotesReleasedForTooLong

* Iterate over m_chords by const reference in src/core/InstrumentFunctions.cpp

Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>

* Fix StepRecorder::removeNotesReleasedForTooLong again

* Combine the ConfigManager::value overloads using std::optional

* Revise StepRecorder::removeNotesReleasedForTooLong

* Remove redundant std::optional in ConfigManager::value

* Remove trailing whitespace in ConfigManager::value

* Fix: Prevent incorrect use of std::distance when element not found

* Chore: Remove trailing whitespace in edited files

* Only set the id attribute if the controller was found

Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>

* Remove extra indents from 84b8fe8a559855ed263b74cc582eab3655250c5f

* Fix compilation issues

* Add LMMS_ prefix for header guard in Track.h

* Undo changes made to MixerView::deleteUnusedChannels

* Simplify code to handle failure of finding tracks
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>

* Split ternary operator into separate if statement
Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>

* Undo changes to indentation in MixerRoute

* Do general clean-up
Some of the changes made:
+ Use auto where benefical
+ Fix bug in AutomatableModel::globalAutomationValueAt (for loop should be looping over clips variable, not clipsInRange)
+ Undo out of focus whitespace changes

* Always assign to m_steps regardless if clip is found or not
Even when the clip is not found (i.e., currentClip is -1), m_steps still
gets assigned to.

* Insert at the end of tracks vector in src/core/Mixer.cpp

Co-authored-by: Dominic Clark <mrdomclark@gmail.com>

* Insert at the end of tracks vector in src/core/Mixer.cpp (2)

Co-authored-by: Dominic Clark <mrdomclark@gmail.com>

* Remove redundant template parameter

* Use std::array for zoomLevels

---------

Co-authored-by: Hyunjin Song <tteu.ingog@gmail.com>
Co-authored-by: Dominic Clark <mrdomclark@gmail.com>
2023-08-22 12:08:56 +09:00
Dalton Messmer
2c6d88f799 Add GUARD_H closing comments 2023-01-05 17:58:49 -05:00
Dalton Messmer
fe6df8dbaf Add namespace prefix to include guards 2023-01-02 19:51:32 -05:00
saker
b451e40b51 clang-tidy: Apply modernize-use-using everywhere (#6453) 2022-07-07 10:54:34 +02:00
Levin Oehlmann
28ec71f91a clang-tidy: Apply modernize-use-equals-default everywhere (#6450) 2022-06-26 08:48:24 +02:00
Levin Oehlmann
5904b249c0 clang-tidy: Apply modernize-use-override everywhere (#6439)
... to mark overriding functions `override` instead of `virtual`.
2022-06-19 23:03:55 +02:00
Levin Oehlmann
7227c89847 Namespace lmms (#6174)
This PR places all LMMS symbols into namespaces to eliminate any potential future name collisions between LMMS and third-party modules.

Also, this PR changes back `LmmsCore` to `Engine`, reverting c519921306 .

Co-authored-by: allejok96 <allejok96@gmail.com>
2022-06-19 20:08:46 +02:00
Johannes Lorenz
7db3fa94a1 Improve includes (#6320)
* Update ringbuffer submodule to fix includes

* Remove cyclic includes

* Remove Qt include prefixes

* Include C++ versions of C headers

E.g.: assert.h -> cassert

* Move CLIP_BORDER_WIDTH into ClipView

This allows to remove includes to TrackView.h in ClipView cpp files.

* Elliminate useless includes

This improves the include structure by elliminating includes that are
not used. Most of this was done by using `include-what-you-use` with
`CMAKE_C_INCLUDE_WHAT_YOU_USE` and `CMAKE_CXX_INCLUDE_WHAT_YOU_USE`
set to (broken down here):

```
include-what-you-use;
    -Xiwyu;--mapping_file=/usr/share/include-what-you-use/qt5_11.imp;
    -Xiwyu;--keep=*/xmmintrin.h;
    -Xiwyu;--keep=*/lmmsconfig.h;
    -Xiwyu;--keep=*/weak_libjack.h;
    -Xiwyu;--keep=*/sys/*;
    -Xiwyu;--keep=*/debug.h;
    -Xiwyu;--keep=*/SDL/*;
    -Xiwyu;--keep=*/alsa/*;
    -Xiwyu;--keep=*/FL/x.h;
    -Xiwyu;--keep=*/MidiApple.h;
    -Xiwyu;--keep=*/MidiWinMM.h;
    -Xiwyu;--keep=*/AudioSoundIo.h
```

* Fixup: Remove empty #if-#ifdef pairs

* Remove LMMS_HAVE_STD(LIB|INT)_H
2022-03-02 13:30:43 +01:00
Alex
dc73911391 Rename Beat/Bassline to Pattern (#6284)
- BB* -> Pattern*
- BBTrackContainer -> PatternStore
- BBTrackContainerView -> PatternEditor
- BBEditor -> PatternEditorWindow

Does not touch save files
2022-02-13 09:03:37 +01:00
Alexandre Almeida
55d361fb65 Rename TCO and related to Clip (#6226)
This PR renames

    TCO -> Clip
    Pattern -> MidiClip
    *TCO and *TCOView -> *Clip and *ClipView

The savefiles are not yet modified by this PR.
2022-01-14 05:45:21 +01:00
Hyunjin Song
5b2570def5 Revert "Fix validPattern to check if hasAutomation as well (#5124)" (#6041)
This reverts commit e37f3793f3.
2021-06-06 11:27:58 +09:00
David CARLIER
e9f264e37f Gui editors: Use float for zoom precision (#6008)
This fixes build errors with casts.
2021-05-15 17:17:40 +02:00
IanCaio
3ab86fa381 Automation Node fine tuning with double-click (Rewrites #5292) (#5923)
Co-authored-by: tecknixia <50790262+tecknixia@users.noreply.github.com>
2021-03-27 23:32:51 -03:00
IanCaio
e880e3cb2a Changes AutomationPattern to use nodes instead of raw float values (#5712) 2021-02-28 06:48:15 -03:00
Alexandre Almeida
6e081265ba Rename MidiTime to TimePos (#5684)
Fixes #4866
2020-11-29 19:46:13 +01:00
Kevin Zander
966f18423f Center vertical scroll position when opening the Automation Editor (#5123)
* Center vertical scroll position when opening the Automation Editor
2020-08-11 10:18:34 -05:00
Kevin Zander
e37f3793f3 Fix validPattern to check if hasAutomation as well (#5124) 2020-07-29 20:26:20 +02:00
tecknixia
abcfee1334 disable drag after drawing line (#5315) 2020-04-22 20:47:59 +02:00
David CARLIER
dac59a5fa0 C++11 inheritance updates
Add `override` and remove `virtual` where applicable
2019-10-31 20:05:33 +01:00
Alexandre Almeida
53e6b645c8 Use "bar" instead of "tact"
Closes #4865
2019-10-31 15:13:25 +01:00
https://gitlab.com/users/CYBERDEViLNL
5132d91bfc Give focus to AutomationEditor when the window gets the foucs (#5170)
This will make shortcuts work on opening the editor.
2019-10-02 08:00:11 +09:00
Oskar Wallgren
f9ab2dec02 Automation Point delete radius and size (#3902)
* Fix Automation Point delete radius. At lower zoom deleting would miss
automation points to delete and at higher zoom it would be too generous
and remove neighbouring points.

* Increase smallest Automation Point radius. For  visibility. The smallest
Automatin Point radius was tiny.
2017-10-24 17:42:30 +02:00
Uroš Šišović
e879fad25d Right Mouse Button To Erase Nodes In Automation Editor Cursor Icon... (#3414)
* Right Mouse Button To Erase Nodes In Automation Editor Cursor Icon Does Not Change #3310

* Remove unused member m_mouseDownLeft from PianoRoll

* Add move cursor for automation points drag
2017-03-13 01:14:42 +01:00
TheTravelingSpaceman
899e386df7 Aliasing in AutomationPatternView and AutomationEditor fixed (#3386)
* Ailiasing in AutomationPatternView; ERROR: Doesn't draw unreferanced tracks

* Draws one polygon instead of 'poly'-polygons

* Changed QPoints to QPointF

* Added int MidiTpT constant

* Added ppTact for reduced computation

* Added spaces in parentheses to be consistent

* Variable name change and spacing

* S P A C E S

* Anti-Aliasing of Automation Editor

* Commented out all referances to unused is_selected

* Changed css to non-gradient graphs

* Added Brackets

* Removed no-pixel line at bottom of graph

* Revert "Added Brackets"

This reverts commit ff801868b7.

* Revert "Revert "Added Brackets""

This reverts commit 4e127a78df.

* Revert "Removed no-pixel line at bottom of graph"

This reverts commit 940c766b61.
2017-03-13 01:14:05 +01:00
Umcaruje
de2e164aae Piano Roll and Automation editor grid redesign (w/ @BaraMGB) (#3062)
* Make dem grid ndasd

* grid BG

* fix bug in scroll behavior

* debugging scrolling

* Add CSS property, port to automation editor

* Fix a fail

* Spaces to tabs

* Use fillRect rather than drawRect

* Implement @vlad1777d's idea

* Seperate loops and stuff

* Finish up Piano Roll Grid

* Cleanup

* Redesign the grid for the Automation Editor

* Update colors

* Formatting changes

* formatting changes II
2017-02-22 19:56:32 +01:00
grejppi
9e85d7c66e update all copyright headers to the proper url (#3326) 2017-02-06 02:41:15 +02:00
Steffen Baranowsky
d600d56ad3 change automation editor window title on rename automation pattern 2016-09-18 13:56:36 +02:00
Umcaruje
27eaa4d512 Make scrollbars consistent over the software; Add padding to the scrollbars; Make the PianoView background themeable (#2807)
* Make scrollbars consistent over the software; Add padding to the scrollbars; Make the PianoView background themeable

* Make the scrollbar hover color brighter
2016-06-03 12:21:27 +02:00
Oskar Wallgren
36c181dbea Add zoom 12.5% 2016-05-28 21:18:05 +02:00
Umcaruje
8841b89b6d Merge pull request #2546 from Umcaruje/fixscrollbars
Fix inconsistent scrollbars
2016-02-15 01:38:07 +01:00
Umcaruje
d52d7d9fb7 Get rid of hardcoded colors in the Piano Roll and Automation Editor 2016-02-08 19:44:50 +01:00
Umcaruje
59f8fbd94b Fix inconsistent scrollbars 2016-02-06 12:17:38 +01:00
Colin Wallace
c112e50ddd Removed legacy friend declarations 2015-06-18 03:23:43 +00:00
Dave French
dfbbcfd38b 1416 tidy up 2015-01-23 02:38:17 +00:00
Dave French
c201a41c05 Proposed fix 1416 Drag-and-drop of automatables to Automation Editor 2015-01-23 02:16:30 +00:00
Lukas W
0c4833ca4a Adjust automation editor flip implementation 2015-01-06 23:40:14 +01:00
Lukas W
23e0e0fb8e Merge branch 'master' into ed_refac
Conflicts:
	include/AutomationEditor.h
	include/SongEditor.h
	plugins/delay/delaycontrols.cpp
	plugins/delay/delaycontrolsdialog.cpp
	src/gui/editors/AutomationEditor.cpp
	src/gui/editors/BBEditor.cpp
	src/gui/editors/PianoRoll.cpp
2015-01-06 23:05:13 +01:00
Spekular
eb0b0f5277 Adds automation flipping. 2014-12-23 19:29:50 +01:00
Lukas W
657fb06c49 More Automation refactoring 2014-12-17 11:34:57 +01:00
Lukas W
11cb8b5d68 Automation Editor tension fix 2014-12-12 10:51:15 +01:00
Lukas W
787788870b Introduce ActionGroup subclass 2014-12-11 12:56:51 +01:00
Lukas W
02869b13dd Editors: Some cleanups 2014-12-11 11:24:26 +01:00