init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
166
Telegram/SourceFiles/editor/photo_editor_content.cpp
Normal file
166
Telegram/SourceFiles/editor/photo_editor_content.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
#include "editor/photo_editor_content.h"
|
||||
|
||||
#include "editor/editor_crop.h"
|
||||
#include "editor/editor_paint.h"
|
||||
#include "history/history_drag_area.h"
|
||||
#include "media/view/media_view_pip.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
|
||||
namespace Editor {
|
||||
|
||||
using Media::View::FlipSizeByRotation;
|
||||
using Media::View::RotatedRect;
|
||||
|
||||
PhotoEditorContent::PhotoEditorContent(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
std::shared_ptr<Image> photo,
|
||||
PhotoModifications modifications,
|
||||
std::shared_ptr<Controllers> controllers,
|
||||
EditorData data)
|
||||
: RpWidget(parent)
|
||||
, _photoSize(photo->size())
|
||||
, _paint(base::make_unique_q<Paint>(
|
||||
this,
|
||||
modifications,
|
||||
_photoSize,
|
||||
std::move(controllers)))
|
||||
, _crop(base::make_unique_q<Crop>(
|
||||
this,
|
||||
modifications,
|
||||
_photoSize,
|
||||
std::move(data)))
|
||||
, _photo(std::move(photo))
|
||||
, _modifications(modifications) {
|
||||
|
||||
rpl::combine(
|
||||
_modifications.value(),
|
||||
sizeValue()
|
||||
) | rpl::on_next([=](
|
||||
const PhotoModifications &mods, const QSize &size) {
|
||||
if (size.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const auto imageSizeF = [&] {
|
||||
const auto rotatedSize
|
||||
= FlipSizeByRotation(size, mods.angle);
|
||||
const auto m = _crop->cropMargins();
|
||||
const auto sizeForCrop = rotatedSize
|
||||
- QSize(m.left() + m.right(), m.top() + m.bottom());
|
||||
const auto originalSize = QSizeF(_photoSize);
|
||||
if ((originalSize.width() > sizeForCrop.width())
|
||||
|| (originalSize.height() > sizeForCrop.height())) {
|
||||
return originalSize.scaled(
|
||||
sizeForCrop,
|
||||
Qt::KeepAspectRatio);
|
||||
}
|
||||
return originalSize;
|
||||
}();
|
||||
const auto imageSize = QSize(imageSizeF.width(), imageSizeF.height());
|
||||
_imageRect = QRect(
|
||||
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);
|
||||
|
||||
const auto geometry = _imageMatrix.mapRect(_imageRect);
|
||||
_crop->applyTransform(
|
||||
geometry + _crop->cropMargins(),
|
||||
mods.angle,
|
||||
mods.flipped, imageSizeF);
|
||||
_paint->applyTransform(geometry, mods.angle, mods.flipped);
|
||||
|
||||
_innerRect = geometry;
|
||||
}, lifetime());
|
||||
|
||||
paintRequest(
|
||||
) | rpl::on_next([=](const QRect &clip) {
|
||||
auto p = QPainter(this);
|
||||
|
||||
p.fillRect(clip, Qt::transparent);
|
||||
p.setTransform(_imageMatrix);
|
||||
p.drawPixmap(_imageRect, _photo->pix(_imageRect.size()));
|
||||
}, lifetime());
|
||||
|
||||
setupDragArea();
|
||||
}
|
||||
|
||||
void PhotoEditorContent::applyModifications(
|
||||
PhotoModifications modifications) {
|
||||
_modifications = std::move(modifications);
|
||||
update();
|
||||
}
|
||||
|
||||
void PhotoEditorContent::save(PhotoModifications &modifications) {
|
||||
modifications.crop = _crop->saveCropRect();
|
||||
_paint->keepResult();
|
||||
|
||||
const auto savedScene = _paint->saveScene();
|
||||
if (!modifications.paint) {
|
||||
modifications.paint = savedScene;
|
||||
}
|
||||
}
|
||||
|
||||
void PhotoEditorContent::applyMode(const PhotoEditorMode &mode) {
|
||||
if (mode.mode == PhotoEditorMode::Mode::Out) {
|
||||
if (mode.action == PhotoEditorMode::Action::Discard) {
|
||||
_paint->restoreScene();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto isTransform = (mode.mode == PhotoEditorMode::Mode::Transform);
|
||||
_crop->setVisible(isTransform);
|
||||
|
||||
_paint->setAttribute(Qt::WA_TransparentForMouseEvents, isTransform);
|
||||
if (!isTransform) {
|
||||
_paint->updateUndoState();
|
||||
}
|
||||
|
||||
if (mode.action == PhotoEditorMode::Action::Discard) {
|
||||
_paint->cancel();
|
||||
} else if (mode.action == PhotoEditorMode::Action::Save) {
|
||||
_paint->keepResult();
|
||||
}
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
void PhotoEditorContent::applyBrush(const Brush &brush) {
|
||||
_paint->applyBrush(brush);
|
||||
}
|
||||
|
||||
bool PhotoEditorContent::handleKeyPress(not_null<QKeyEvent*> e) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void PhotoEditorContent::setupDragArea() {
|
||||
auto dragEnterFilter = [=](const QMimeData *data) {
|
||||
return (_mode.mode == PhotoEditorMode::Mode::Paint)
|
||||
? Storage::ValidatePhotoEditorMediaDragData(data)
|
||||
: false;
|
||||
};
|
||||
|
||||
const auto areas = DragArea::SetupDragAreaToContainer(
|
||||
this,
|
||||
std::move(dragEnterFilter),
|
||||
nullptr,
|
||||
nullptr,
|
||||
[](const QMimeData *d) { return Storage::MimeDataState::Image; },
|
||||
true);
|
||||
|
||||
areas.photo->setDroppedCallback([=](const QMimeData *data) {
|
||||
_paint->handleMimeData(data);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
Reference in New Issue
Block a user