Skip to content
Snippets Groups Projects
Unverified Commit 5379ade4 authored by Igor Korsukov's avatar Igor Korsukov Committed by GitHub
Browse files

Merge pull request #6441 from igorkorsukov/clipsview/wave_optima

[AU4] made wave draw optimization
parents 846d30d3 63dfec95
No related branches found
No related tags found
No related merge requests found
Showing with 323 additions and 540 deletions
......@@ -22,8 +22,16 @@ public:
QColor highlight;
};
struct Geometry {
double clipHeight = 0.0; // clip view height
double clipWidth = 0.0; // clip view width
double relClipLeft = 0.0; // relatively to frameLeft
double frameLeft = 0.0; // track line shift
double frameWidth = 0.0; // track line visible width
};
struct Params {
QRect viewRect;
Geometry geometry;
double zoom = 0.0;
Style style;
};
......
This diff is collapsed.
......@@ -55,5 +55,7 @@ Rectangle {
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 1
clipLeft: root.x
}
}
......@@ -13,6 +13,18 @@ Rectangle {
height: 76
color: ui.theme.backgroundPrimaryColor
//! NOTE This element must be the same width as the track wave visible area.
//! If this is different, than appropriate changes must be made.
onWidthChanged: {
timelineContext.onResizeFrameWidth(root.width)
}
Component.onCompleted: {
timelineContext.init(root.width)
}
//! ~~~ TimelineContext ~~~
//! NOTE See comment in TimelineContext (.h)
function onWheel(y) {
timelineContext.onWheel(y)
}
......@@ -28,11 +40,15 @@ Rectangle {
TimelineContext {
id: timelineContext
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
StyledTextLabel {
anchors.fill: parent
anchors.leftMargin: 16
text: "zoom: " + timelineContext.zoom + ", offset: " + timelineContext.offset
text: "zoom: " + timelineContext.zoom
+ ", frame start time: " + timelineContext.frameStartTime
+ ", end time: " + timelineContext.frameEndTime
+ ", root.width: " + root.width
}
SeparatorLine { anchors.bottom: parent.bottom }
......
......@@ -4,12 +4,14 @@ import Muse.UiComponents
import Audacity.ProjectScene
Item {
Rectangle {
id: root
clip: true
color: ui.theme.backgroundPrimaryColor
TracksListClipsModel {
id: tracksModel
}
......
......@@ -25,7 +25,7 @@ void ClipsListModel::load()
if (m_context) {
connect(m_context, &TimelineContext::zoomChanged, this, &ClipsListModel::onTimelineContextValuesChanged);
connect(m_context, &TimelineContext::offsetChanged, this, &ClipsListModel::onTimelineContextValuesChanged);
connect(m_context, &TimelineContext::frameTimeChanged, this, &ClipsListModel::onTimelineContextValuesChanged);
}
beginResetModel();
......@@ -91,7 +91,7 @@ QVariant ClipsListModel::data(const QModelIndex& index, int role) const
bool ClipsListModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
LOGD() << "" << index.row() << ", value: " << value << ", role: " << role;
//LOGD() << "" << index.row() << ", value: " << value << ", role: " << role;
switch (role) {
case ClipLeftRole: {
return changeClipStartTime(index, value);
......@@ -104,6 +104,10 @@ bool ClipsListModel::setData(const QModelIndex& index, const QVariant& value, in
void ClipsListModel::onTimelineContextValuesChanged()
{
// LOGDA() << "zoom: " << m_context->zoom()
// << " frameStartTime: " << m_context->frameStartTime()
// << " frameEndTime: " << m_context->frameEndTime();
for (size_t i = 0; i < m_clipList.size(); ++i) {
QModelIndex idx = this->index(int(i));
emit dataChanged(idx, idx, { ClipWidthRole, ClipLeftRole });
......
......@@ -8,40 +8,64 @@
static constexpr double ZOOM_MIN = 0.1;
TimelineContext::TimelineContext(QQuickItem* parent)
: QQuickItem(parent)
TimelineContext::TimelineContext(QObject* parent)
: QObject(parent)
{
}
void TimelineContext::init(double frameWidth)
{
m_zoom = 2.0;//{ 44100.0 / 512.0 };
emit zoomChanged();
m_frameStartTime = 0.0;
emit frameStartTimeChanged();
m_frameEndTime = positionToTime(frameWidth);
emit frameEndTimeChanged();
emit frameTimeChanged();
}
void TimelineContext::onWheel(double y)
{
Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
if (modifiers.testFlag(Qt::ControlModifier)) {
changeZoom(y < 0 ? -1 : 1);
} else if (modifiers.testFlag(Qt::ShiftModifier)) {
changeOffset(y < 0 ? -1 : 1);
shiftFrameTime(y < 0 ? -1 : 1);
}
}
void TimelineContext::changeZoom(int direction)
{
double step = std::max(zoom() / 2.0, ZOOM_MIN);
double step = (muse::is_equal(m_zoom, 1.0) && direction < 0) ? 0.1 : 1.0;
double _zoom = zoom() + (step * direction);
_zoom = std::floor(_zoom * 10.0) / 10.0;
if (_zoom > 4) {
_zoom = std::floor(_zoom);
double zoom = m_zoom + (step * direction);
zoom = std::max(zoom, ZOOM_MIN);
setZoom(zoom);
}
void TimelineContext::onResizeFrameWidth(double frameWidth)
{
m_frameWidth = frameWidth;
updateFrameTime();
}
_zoom = std::max(_zoom, ZOOM_MIN);
void TimelineContext::shiftFrameTime(int direction)
{
double step = 10.0;
double shift = step * direction;
setFrameStartTime(m_frameStartTime + shift);
setFrameEndTime(m_frameEndTime + shift);
setZoom(_zoom);
emit frameTimeChanged();
}
void TimelineContext::changeOffset(int direction)
void TimelineContext::updateFrameTime()
{
double step = 10;
setOffset(offset() + (step * direction));
setFrameEndTime(positionToTime(m_frameWidth));
emit frameTimeChanged();
}
void TimelineContext::onSelection(double x1, double x2)
......@@ -65,35 +89,16 @@ void TimelineContext::onSelectionTime(double startTime, double endTime)
setSelectionActive(!muse::is_zero(startTime) && !muse::is_zero(endTime));
}
qint64 TimelineContext::timeToPosition(double time) const
{
double t = 0.5 + m_zoom * (time - m_offset);
if (t < INT64_MIN) {
return INT64_MIN;
}
if (t > INT64_MAX) {
return INT64_MAX;
}
t = floor(t);
return static_cast<qint64>(t);
}
double TimelineContext::positionToTime(qint64 position) const
{
return m_offset + position / m_zoom;
}
double TimelineContext::offset() const
double TimelineContext::timeToPosition(double time) const
{
return m_offset;
double p = 0.5 + m_zoom * (time - m_frameStartTime);
p = std::floor(p);
return p;
}
void TimelineContext::setOffset(double newOffset)
double TimelineContext::positionToTime(double position) const
{
if (m_offset != newOffset) {
m_offset = newOffset;
emit offsetChanged();
}
return m_frameStartTime + position / m_zoom;
}
double TimelineContext::zoom() const
......@@ -106,6 +111,7 @@ void TimelineContext::setZoom(double zoom)
if (m_zoom != zoom) {
m_zoom = zoom;
emit zoomChanged();
updateFrameTime();
}
}
......@@ -148,3 +154,31 @@ void TimelineContext::setSelectionActive(bool newSelectionActive)
m_selectionActive = newSelectionActive;
emit selectionActiveChanged();
}
double TimelineContext::frameStartTime() const
{
return m_frameStartTime;
}
void TimelineContext::setFrameStartTime(double newFrameStartTime)
{
if (qFuzzyCompare(m_frameStartTime, newFrameStartTime)) {
return;
}
m_frameStartTime = newFrameStartTime;
emit frameStartTimeChanged();
}
double TimelineContext::frameEndTime() const
{
return m_frameEndTime;
}
void TimelineContext::setFrameEndTime(double newFrameEndTime)
{
if (qFuzzyCompare(m_frameEndTime, newFrameEndTime)) {
return;
}
m_frameEndTime = newFrameEndTime;
emit frameEndTimeChanged();
}
#pragma once
#include <QQuickItem>
#include <QObject>
class TimelineContext : public QQuickItem
//! NOTE This class does two things:
//! 1. This is a context that is passed to other classes
//! 2. This is a controller that interprets mouse and view resize events into context values
//!
//! If this class becomes more complex,
//! or we notice that its "controller" methods are being called in unexpected places,
//! then we should split it into two separate classes.
class TimelineContext : public QObject
{
Q_OBJECT
Q_PROPERTY(double offset READ offset WRITE setOffset NOTIFY offsetChanged FINAL)
// 0 sec visible frame end
// | ~~~~~ ~~~~ ~~~|
Q_PROPERTY(double frameStartTime READ frameStartTime NOTIFY frameStartTimeChanged FINAL)
Q_PROPERTY(double frameEndTime READ frameEndTime NOTIFY frameEndTimeChanged FINAL)
Q_PROPERTY(double zoom READ zoom WRITE setZoom NOTIFY zoomChanged FINAL)
Q_PROPERTY(double selectionStartTime READ selectionStartTime NOTIFY selectionStartTimeChanged FINAL)
......@@ -15,17 +26,11 @@ class TimelineContext : public QQuickItem
public:
TimelineContext(QQuickItem* parent = nullptr);
Q_INVOKABLE void onWheel(double y);
Q_INVOKABLE void onSelection(double x1, double x2);
Q_INVOKABLE void resetSelection();
TimelineContext(QObject* parent = nullptr);
Q_INVOKABLE qint64 timeToPosition(double time) const;
Q_INVOKABLE double positionToTime(qint64 position) const;
double frameStartTime() const;
double frameEndTime() const;
double offset() const;
void setOffset(double newOffset);
double zoom() const;
void setZoom(double zoom);
......@@ -35,9 +40,23 @@ public:
void setSelectionEndTime(double time);
bool selectionActive() const;
Q_INVOKABLE void init(double frameWidth);
Q_INVOKABLE void onResizeFrameWidth(double frameWidth);
Q_INVOKABLE void onWheel(double y);
Q_INVOKABLE void onSelection(double x1, double x2);
Q_INVOKABLE void resetSelection();
Q_INVOKABLE double timeToPosition(double time) const;
Q_INVOKABLE double positionToTime(double position) const;
signals:
void offsetChanged();
void frameStartTimeChanged();
void frameEndTimeChanged();
void frameTimeChanged(); // any or both together
void zoomChanged();
void selectionStartTimeChanged();
......@@ -46,15 +65,22 @@ signals:
private:
void shiftFrameTime(int direction);
void setFrameStartTime(double newFrameStartTime);
void setFrameEndTime(double newFrameEndTime);
void updateFrameTime();
void changeZoom(int direction);
void changeOffset(int direction);
void onSelectionTime(double t1, double t2);
void updateSelectionActive();
void setSelectionActive(bool newSelectionActive);
double m_offset = 0.0;
double m_zoom = 2.0;//{ 44100.0 / 512.0 };
double m_frameWidth = 0.0;
double m_frameStartTime = 0.0;
double m_frameEndTime = 0.0;
double m_zoom = 1.0; // see init
double m_selecitonStartTime = 0.0;
double m_selectionEndTime = 0.0;
......
......@@ -29,7 +29,12 @@ void WaveView::setClipKey(const ClipKey& newClipKey)
void WaveView::paint(QPainter* painter)
{
au3::IAu3WavePainter::Params params;
params.viewRect = QRect(0, 0, width(), height());
params.geometry.clipHeight = height();
params.geometry.clipWidth = width();
params.geometry.relClipLeft = m_clipLeft;
params.geometry.frameLeft = m_context->frameStartTime() * m_context->zoom();
params.geometry.frameWidth = (m_context->frameEndTime() - m_context->frameStartTime()) * m_context->zoom();
params.zoom = m_context->zoom();
const WaveStyle& style = configuration()->waveStyle();
......@@ -60,7 +65,36 @@ void WaveView::setTimelineContext(TimelineContext* newContext)
return;
}
//! TODO Subscribe on context props changes
if (m_context) {
disconnect(m_context, nullptr, this, nullptr);
}
m_context = newContext;
if (m_context) {
connect(m_context, &TimelineContext::frameTimeChanged, this, &WaveView::onFrameTimeChanged);
}
emit timelineContextChanged();
}
void WaveView::onFrameTimeChanged()
{
update();
}
double WaveView::clipLeft() const
{
return m_clipLeft;
}
void WaveView::setClipLeft(double newClipLeft)
{
if (qFuzzyCompare(m_clipLeft, newClipLeft)) {
return;
}
m_clipLeft = newClipLeft;
emit clipLeftChanged();
update();
}
......@@ -17,6 +17,11 @@ class WaveView : public QQuickPaintedItem
Q_PROPERTY(TimelineContext * context READ timelineContext WRITE setTimelineContext NOTIFY timelineContextChanged FINAL)
Q_PROPERTY(ClipKey clipKey READ clipKey WRITE setClipKey NOTIFY clipKeyChanged FINAL)
//! NOTE In a static position, the slip start time corresponds,
//! but it can change while dragging the clip, with the not changing start time
//! (until the end of dragging)
Q_PROPERTY(double clipLeft READ clipLeft WRITE setClipLeft NOTIFY clipLeftChanged FINAL)
muse::Inject<au3::IAu3WavePainter> wavePainter;
muse::Inject<IProjectSceneConfiguration> configuration;
......@@ -28,17 +33,22 @@ public:
void setClipKey(const ClipKey& newClipKey);
TimelineContext* timelineContext() const;
void setTimelineContext(TimelineContext* newContext);
double clipLeft() const;
void setClipLeft(double newClipLeft);
void paint(QPainter* painter) override;
signals:
void clipKeyChanged();
void timelineContextChanged();
void clipLeftChanged();
private:
void UpdateItemsCache(TimelineContext& trackPanelView);
void onFrameTimeChanged();
ClipKey m_clipKey;
TimelineContext* m_context = nullptr;
double m_clipLeft = 0;
};
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment