Skip to content

Commit

Permalink
WIP: live preview
Browse files Browse the repository at this point in the history
Instead of simulating what e.g. move contents does, bypass the undo
framework and modify the image contents directly. When the dialog
is accepted or rejected, either commit or rollback the changes.
This allows live preview of certain changes to image contents.

Fixes #171
  • Loading branch information
mitchcurtis committed Aug 1, 2021
1 parent 3954e0d commit 53b98f7
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 112 deletions.
71 changes: 15 additions & 56 deletions app/qml/ui/MoveContentsDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,25 @@ Dialog {
focus: true
enabled: isLayeredImageProject

property Project project
property LayeredImageProject project
property bool isLayeredImageProject: project && project.type === Project.LayeredImageType

function updateLivePreview() {
project.moveContents(xDistanceSpinBox.value, yDistanceSpinBox.value, onlyMoveVisibleLayersCheckBox.checked)
}

onAboutToShow: {
if (project) {
xDistanceSpinBox.value = 0
yDistanceSpinBox.value = 0
xDistanceSpinBox.contentItem.forceActiveFocus()
imagePreview.source = "image://project"
}
}

onAboutToHide: {
// Ensure that an up-to-date image is assign when we open by clearing it when we close.
imagePreview.source = ""
project.beginLivePreview()
}
}

onAccepted: project.moveContents(xDistanceSpinBox.value, yDistanceSpinBox.value, onlyMoveVisibleLayersCheckBox.checked)
onAccepted: project.endLivePreview(LayeredImageProject.CommitModificaton)
onRejected: project.endLivePreview(LayeredImageProject.RollbackModification)

contentItem: ColumnLayout {
GridLayout {
Expand All @@ -75,6 +76,8 @@ Dialog {
ToolTip.delay: UiConstants.toolTipDelay
ToolTip.timeout: UiConstants.toolTipTimeout

onValueModified: root.updateLivePreview()

Keys.onReturnPressed: root.accept()
}

Expand All @@ -98,6 +101,8 @@ Dialog {
ToolTip.delay: UiConstants.toolTipDelay
ToolTip.timeout: UiConstants.toolTipTimeout

onValueModified: root.updateLivePreview()

Keys.onReturnPressed: root.accept()
}

Expand All @@ -116,55 +121,9 @@ Dialog {
ToolTip.delay: UiConstants.toolTipDelay
ToolTip.timeout: UiConstants.toolTipTimeout

Keys.onReturnPressed: root.accept()
}

Rectangle {
id: imagePreviewBackground
objectName: "imagePreviewBackground"
color: "black"
clip: true
onToggled: root.updateLivePreview()

Layout.columnSpan: 2
Layout.preferredWidth: 400
Layout.preferredHeight: 400
Layout.fillWidth: true
Layout.fillHeight: true

Image {
objectName: "imagePreviewOldBounds"
// QQuickImage uses ceil.
x: Math.ceil((parent.width - imagePreview.paintedWidth) / 2)
y: Math.ceil((parent.height - imagePreview.paintedHeight) / 2)
width: imagePreview.paintedWidth
height: imagePreview.paintedHeight
source: "qrc:/images/checker.png"
fillMode: Image.Tile
smooth: false
clip: true

// We want the project's image to be clipped by its old bounds,
// as that's what it will actually look like after moving.
// That's why it's a child of the old bounds image.
Image {
id: imagePreview
// Our parent has to be positioned correctly based on our painted size,
// which means we must deduct their position to get ours.
x: Math.ceil((xDistanceSpinBox.value * widthScale) - parent.x)
y: Math.ceil((yDistanceSpinBox.value * heightScale) - parent.y)
width: imagePreviewBackground.width
height: imagePreviewBackground.height
fillMode: Image.PreserveAspectFit
smooth: false
// Ensure that we get up-to-date images from the provider.
cache: false

// The image is scaled to fit the viewport (imagePreviewBackground),
// so our x and y position must be scaled to account for that.
readonly property int widthScale: paintedWidth / implicitWidth
readonly property int heightScale: paintedHeight / implicitHeight
}
}
Keys.onReturnPressed: root.accept()
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions lib/imagecanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,7 @@ void ImageCanvas::connectSignals()
connect(mProject, SIGNAL(preProjectSaved()), this, SLOT(saveState()));
connect(mProject, SIGNAL(aboutToBeginMacro(QString)),
this, SLOT(onAboutToBeginMacro(QString)));
connect(mProject, SIGNAL(livePreviewChanged()), this, SLOT(requestContentPaint()));

connect(window(), SIGNAL(activeFocusItemChanged()), this, SLOT(updateWindowCursorShape()));
}
Expand All @@ -997,6 +998,7 @@ void ImageCanvas::disconnectSignals()
mProject->disconnect(SIGNAL(preProjectSaved()), this, SLOT(saveState()));
mProject->disconnect(SIGNAL(aboutToBeginMacro(QString)),
this, SLOT(onAboutToBeginMacro(QString)));
mProject->disconnect(SIGNAL(livePreviewChanged()), this, SLOT(requestContentPaint()));

if (window()) {
window()->disconnect(SIGNAL(activeFocusItemChanged()), this, SLOT(updateWindowCursorShape()));
Expand Down
1 change: 1 addition & 0 deletions lib/imageproject.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public slots:

QUrl mImageUrl;
QImage mImage;

bool mUsingAnimation = false;
bool mHasUsedAnimation = false;
AnimationSystem mAnimationSystem;
Expand Down
Loading

0 comments on commit 53b98f7

Please sign in to comment.