Added initial ability to rotate and flip image to photo editor.

This commit is contained in:
23rd 2021-02-08 02:10:30 +03:00
parent 99deaf6005
commit 9d3d16a725
8 changed files with 86 additions and 9 deletions

View File

@ -510,6 +510,7 @@ PRIVATE
dialogs/dialogs_widget.h
editor/photo_editor.cpp
editor/photo_editor.h
editor/photo_editor_common.h
editor/photo_editor_content.cpp
editor/photo_editor_content.h
editor/photo_editor_controls.cpp

View File

@ -29,6 +29,21 @@ PhotoEditor::PhotoEditor(
- style::margins(0, contentRect.height(), 0, 0);
_controls->setGeometry(controlsRect);
}, lifetime());
_controls->rotateRequests(
) | rpl::start_with_next([=](int angle) {
_modifications.angle += 90;
if (_modifications.angle >= 360) {
_modifications.angle -= 360;
}
_content->applyModifications(_modifications);
}, lifetime());
_controls->flipRequests(
) | rpl::start_with_next([=] {
_modifications.flipped = !_modifications.flipped;
_content->applyModifications(_modifications);
}, lifetime());
}
} // namespace Editor

View File

@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rp_widget.h"
#include "editor/photo_editor_common.h"
#include "base/unique_qptr.h"
namespace Editor {
@ -24,6 +26,8 @@ public:
private:
PhotoModifications _modifications;
base::unique_qptr<PhotoEditorContent> _content;
base::unique_qptr<PhotoEditorControls> _controls;

View File

@ -0,0 +1,17 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Editor {
struct PhotoModifications {
int angle = 0;
bool flipped = false;
};
} // namespace Editor

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "editor/photo_editor_content.h"
#include "media/view/media_view_pip.h"
namespace Editor {
PhotoEditorContent::PhotoEditorContent(
@ -14,23 +16,33 @@ PhotoEditorContent::PhotoEditorContent(
std::shared_ptr<QPixmap> photo)
: RpWidget(parent) {
sizeValue(
) | rpl::start_with_next([=](const QSize &size) {
rpl::combine(
_modifications.value(),
sizeValue()
) | rpl::start_with_next([=](
const PhotoModifications &mods, const QSize &size) {
const auto rotatedSize =
Media::View::FlipSizeByRotation(size, mods.angle);
const auto imageSize = [&] {
const auto originalSize = photo->size() / cIntRetinaFactor();
if ((originalSize.width() > size.width())
&& (originalSize.height() > size.height())) {
if ((originalSize.width() > rotatedSize.width())
|| (originalSize.height() > rotatedSize.height())) {
return originalSize.scaled(
size,
rotatedSize,
Qt::KeepAspectRatio);
}
return originalSize;
}();
_imageRect = QRect(
QPoint(
(size.width() - imageSize.width()) / 2,
(size.height() - imageSize.height()) / 2),
QPoint(-imageSize.width() / 2, -imageSize.height() / 2),
imageSize);
_imageMatrix.reset();
_imageMatrix.translate(size.width() / 2, size.height() / 2);
if (mods.flipped) {
_imageMatrix.scale(-1, 1);
}
_imageMatrix.rotate(mods.angle);
}, lifetime());
paintRequest(
@ -38,8 +50,17 @@ PhotoEditorContent::PhotoEditorContent(
Painter p(this);
p.fillRect(clip, Qt::transparent);
p.drawPixmap(_imageRect, *photo, photo->rect());
p.setMatrix(_imageMatrix);
p.drawPixmap(_imageRect, *photo);
}, lifetime());
}
void PhotoEditorContent::applyModifications(
PhotoModifications modifications) {
_modifications = std::move(modifications);
update();
}
} // namespace Editor

View File

@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rp_widget.h"
#include "editor/photo_editor_common.h"
namespace Editor {
class PhotoEditorContent final : public Ui::RpWidget {
@ -17,9 +19,14 @@ public:
not_null<Ui::RpWidget*> parent,
std::shared_ptr<QPixmap> photo);
void applyModifications(PhotoModifications modifications);
private:
rpl::variable<PhotoModifications> _modifications;
QRect _imageRect;
QMatrix _imageMatrix;
};

View File

@ -75,4 +75,13 @@ PhotoEditorControls::PhotoEditorControls(
}, lifetime());
}
rpl::producer<int> PhotoEditorControls::rotateRequests() const {
return _rotateButton->clicks() | rpl::map([] { return 90; });
}
rpl::producer<> PhotoEditorControls::flipRequests() const {
return _flipButton->clicks() | rpl::to_empty;
}
} // namespace Editor

View File

@ -23,6 +23,9 @@ public:
not_null<Ui::RpWidget*> parent,
bool doneControls = true);
[[nodiscard]] rpl::producer<int> rotateRequests() const;
[[nodiscard]] rpl::producer<> flipRequests() const;
private:
const base::unique_qptr<HorizontalContainer> _buttonsContainer;