mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Added saving and discarding between modes in photo editor.
This commit is contained in:
parent
0adcd37030
commit
8eca57f419
9 changed files with 167 additions and 33 deletions
|
@ -29,6 +29,10 @@ std::shared_ptr<QGraphicsScene> EnsureScene(PhotoModifications &mods) {
|
|||
return mods.paint;
|
||||
}
|
||||
|
||||
auto FilterItems(QGraphicsItem *i) {
|
||||
return i->type() == QGraphicsItemGroup::Type;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Paint::Paint(
|
||||
|
@ -38,7 +42,8 @@ Paint::Paint(
|
|||
: RpWidget(parent)
|
||||
, _scene(EnsureScene(modifications))
|
||||
, _view(base::make_unique_q<QGraphicsView>(_scene.get(), this))
|
||||
, _imageSize(imageSize) {
|
||||
, _imageSize(imageSize)
|
||||
, _startItemsCount(itemsCount()) {
|
||||
Expects(modifications.paint != nullptr);
|
||||
|
||||
_view->show();
|
||||
|
@ -49,7 +54,6 @@ Paint::Paint(
|
|||
_scene->setSceneRect(0, 0, imageSize.width(), imageSize.height());
|
||||
|
||||
initDrawing();
|
||||
|
||||
}
|
||||
|
||||
void Paint::applyTransform(QRect geometry, int angle, bool flipped) {
|
||||
|
@ -120,14 +124,38 @@ void Paint::initDrawing() {
|
|||
base::install_event_filter(this, _scene.get(), std::move(callback));
|
||||
}
|
||||
|
||||
void Paint::applyMode(PhotoEditorMode mode) {
|
||||
setAttribute(
|
||||
Qt::WA_TransparentForMouseEvents,
|
||||
mode == PhotoEditorMode::Transform);
|
||||
}
|
||||
|
||||
std::shared_ptr<QGraphicsScene> Paint::saveScene() const {
|
||||
return _scene;
|
||||
}
|
||||
|
||||
void Paint::cancel() {
|
||||
const auto items = _scene->items(Qt::AscendingOrder);
|
||||
const auto filtered = ranges::views::all(
|
||||
items
|
||||
) | ranges::views::filter(FilterItems) | ranges::to_vector;
|
||||
|
||||
if (filtered.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto i = 0; i < filtered.size(); i++) {
|
||||
const auto &item = filtered[i];
|
||||
if (i < _startItemsCount) {
|
||||
if (!item->isVisible()) {
|
||||
item->show();
|
||||
}
|
||||
} else {
|
||||
_scene->removeItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Paint::keepResult() {
|
||||
_startItemsCount = itemsCount();
|
||||
}
|
||||
|
||||
int Paint::itemsCount() const {
|
||||
return ranges::count_if(_scene->items(), FilterItems);
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
|
|
|
@ -27,15 +27,19 @@ public:
|
|||
[[nodiscard]] std::shared_ptr<QGraphicsScene> saveScene() const;
|
||||
|
||||
void applyTransform(QRect geometry, int angle, bool flipped);
|
||||
void applyMode(PhotoEditorMode mode);
|
||||
void cancel();
|
||||
void keepResult();
|
||||
|
||||
private:
|
||||
void initDrawing();
|
||||
int itemsCount() const;
|
||||
|
||||
const std::shared_ptr<QGraphicsScene> _scene;
|
||||
const base::unique_qptr<QGraphicsView> _view;
|
||||
const QSize _imageSize;
|
||||
|
||||
int _startItemsCount = 0;
|
||||
|
||||
struct {
|
||||
QPointF lastPoint;
|
||||
|
||||
|
|
|
@ -35,6 +35,12 @@ PhotoEditor::PhotoEditor(
|
|||
_controls->setGeometry(controlsRect);
|
||||
}, lifetime());
|
||||
|
||||
_mode.value(
|
||||
) | rpl::start_with_next([=](const PhotoEditorMode &mode) {
|
||||
_content->applyMode(mode);
|
||||
_controls->applyMode(mode);
|
||||
}, lifetime());
|
||||
|
||||
_controls->rotateRequests(
|
||||
) | rpl::start_with_next([=](int angle) {
|
||||
_modifications.angle += 90;
|
||||
|
@ -52,9 +58,31 @@ PhotoEditor::PhotoEditor(
|
|||
|
||||
_controls->paintModeRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
_content->applyMode(PhotoEditorMode::Paint);
|
||||
_mode = PhotoEditorMode{
|
||||
.mode = PhotoEditorMode::Mode::Paint,
|
||||
.action = PhotoEditorMode::Action::None,
|
||||
};
|
||||
}, lifetime());
|
||||
|
||||
_controls->doneRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_mode.current().mode == PhotoEditorMode::Mode::Paint) {
|
||||
_mode = PhotoEditorMode{
|
||||
.mode = PhotoEditorMode::Mode::Transform,
|
||||
.action = PhotoEditorMode::Action::Save,
|
||||
};
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
_controls->cancelRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_mode.current().mode == PhotoEditorMode::Mode::Paint) {
|
||||
_mode = PhotoEditorMode{
|
||||
.mode = PhotoEditorMode::Mode::Transform,
|
||||
.action = PhotoEditorMode::Action::Discard,
|
||||
};
|
||||
}
|
||||
}, lifetime());
|
||||
_content->applyMode(PhotoEditorMode::Transform);
|
||||
}
|
||||
|
||||
void PhotoEditor::save() {
|
||||
|
|
|
@ -35,6 +35,10 @@ private:
|
|||
base::unique_qptr<PhotoEditorContent> _content;
|
||||
base::unique_qptr<PhotoEditorControls> _controls;
|
||||
|
||||
rpl::variable<PhotoEditorMode> _mode = PhotoEditorMode{
|
||||
.mode = PhotoEditorMode::Mode::Transform,
|
||||
.action = PhotoEditorMode::Action::None,
|
||||
};
|
||||
rpl::event_stream<PhotoModifications> _done;
|
||||
|
||||
};
|
||||
|
|
|
@ -11,9 +11,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Editor {
|
||||
|
||||
enum class PhotoEditorMode {
|
||||
Transform,
|
||||
Paint,
|
||||
struct PhotoEditorMode {
|
||||
enum class Mode {
|
||||
Transform,
|
||||
Paint,
|
||||
} mode = Mode::Transform;
|
||||
|
||||
enum class Action {
|
||||
None,
|
||||
Save,
|
||||
Discard,
|
||||
} action = Action::None;
|
||||
};
|
||||
|
||||
struct PhotoModifications {
|
||||
|
|
|
@ -93,9 +93,17 @@ void PhotoEditorContent::save(PhotoModifications &modifications) {
|
|||
}
|
||||
}
|
||||
|
||||
void PhotoEditorContent::applyMode(PhotoEditorMode mode) {
|
||||
_crop->setVisible(mode == PhotoEditorMode::Transform);
|
||||
_paint->applyMode(mode);
|
||||
void PhotoEditorContent::applyMode(const PhotoEditorMode &mode) {
|
||||
const auto isTransform = (mode.mode == PhotoEditorMode::Mode::Transform);
|
||||
_crop->setVisible(isTransform);
|
||||
|
||||
_paint->setAttribute(Qt::WA_TransparentForMouseEvents, isTransform);
|
||||
|
||||
if (mode.action == PhotoEditorMode::Action::Discard) {
|
||||
_paint->cancel();
|
||||
} else if (mode.action == PhotoEditorMode::Action::Save) {
|
||||
_paint->keepResult();
|
||||
}
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
PhotoModifications modifications);
|
||||
|
||||
void applyModifications(PhotoModifications modifications);
|
||||
void applyMode(PhotoEditorMode mode);
|
||||
void applyMode(const PhotoEditorMode &mode);
|
||||
void save(PhotoModifications &modifications);
|
||||
|
||||
private:
|
||||
|
|
|
@ -136,15 +136,25 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
bool doneControls)
|
||||
: RpWidget(parent)
|
||||
, _bg(st::mediaviewSaveMsgBg)
|
||||
, _buttonsContainer(base::make_unique_q<HorizontalContainer>(this))
|
||||
, _transformButtons(base::make_unique_q<HorizontalContainer>(this))
|
||||
, _paintButtons(base::make_unique_q<HorizontalContainer>(this))
|
||||
, _rotateButton(base::make_unique_q<Ui::IconButton>(
|
||||
_buttonsContainer,
|
||||
_transformButtons,
|
||||
st::photoEditorRotateButton))
|
||||
, _flipButton(base::make_unique_q<Ui::IconButton>(
|
||||
_buttonsContainer,
|
||||
_transformButtons,
|
||||
st::photoEditorFlipButton))
|
||||
, _paintModeButton(base::make_unique_q<Ui::IconButton>(
|
||||
_buttonsContainer,
|
||||
_transformButtons,
|
||||
st::photoEditorPaintModeButton))
|
||||
, _undoButton(base::make_unique_q<Ui::IconButton>(
|
||||
_paintButtons,
|
||||
st::photoEditorUndoButton))
|
||||
, _redoButton(base::make_unique_q<Ui::IconButton>(
|
||||
_paintButtons,
|
||||
st::photoEditorRedoButton))
|
||||
, _paintModeButtonActive(base::make_unique_q<Ui::IconButton>(
|
||||
_paintButtons,
|
||||
st::photoEditorPaintModeButton))
|
||||
, _cancel(base::make_unique_q<EdgeButton>(
|
||||
this,
|
||||
|
@ -163,7 +173,12 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
st::lightButtonFg,
|
||||
st::photoEditorRotateButton.ripple)) {
|
||||
|
||||
_buttonsContainer->updateChildrenPosition();
|
||||
_transformButtons->updateChildrenPosition();
|
||||
_paintButtons->updateChildrenPosition();
|
||||
|
||||
_paintModeButtonActive->setIconOverride(
|
||||
&st::photoEditorPaintModeButton.iconOver);
|
||||
_paintModeButtonActive->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
paintRequest(
|
||||
) | rpl::start_with_next([=](const QRect &clip) {
|
||||
|
@ -171,21 +186,30 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(_bg);
|
||||
p.drawRect(_buttonsContainer->geometry());
|
||||
p.drawRect(_transformButtons->geometry());
|
||||
|
||||
}, lifetime());
|
||||
|
||||
sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &size) {
|
||||
rpl::combine(
|
||||
sizeValue(),
|
||||
_mode.value()
|
||||
) | rpl::start_with_next([=](
|
||||
const QSize &size,
|
||||
const PhotoEditorMode &mode) {
|
||||
if (size.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_buttonsContainer->moveToLeft(
|
||||
(size.width() - _buttonsContainer->width()) / 2,
|
||||
const auto ¤t = _transformButtons->isHidden()
|
||||
? _paintButtons
|
||||
: _transformButtons;
|
||||
|
||||
current->moveToLeft(
|
||||
(size.width() - current->width()) / 2,
|
||||
0);
|
||||
|
||||
_cancel->moveToLeft(_buttonsContainer->x() - _cancel->width(), 0);
|
||||
_done->moveToLeft(
|
||||
_buttonsContainer->x() + _buttonsContainer->width(),
|
||||
0);
|
||||
_cancel->moveToLeft(current->x() - _cancel->width(), 0);
|
||||
_done->moveToLeft(current->x() + current->width(), 0);
|
||||
|
||||
}, lifetime());
|
||||
|
||||
|
@ -203,4 +227,19 @@ rpl::producer<> PhotoEditorControls::paintModeRequests() const {
|
|||
return _paintModeButton->clicks() | rpl::to_empty;
|
||||
}
|
||||
|
||||
rpl::producer<> PhotoEditorControls::doneRequests() const {
|
||||
return _done->clicks() | rpl::to_empty;
|
||||
}
|
||||
|
||||
rpl::producer<> PhotoEditorControls::cancelRequests() const {
|
||||
return _cancel->clicks() | rpl::to_empty;
|
||||
}
|
||||
|
||||
void PhotoEditorControls::applyMode(const PhotoEditorMode &mode) {
|
||||
using Mode = PhotoEditorMode::Mode;
|
||||
_transformButtons->setVisible(mode.mode == Mode::Transform);
|
||||
_paintButtons->setVisible(mode.mode == Mode::Paint);
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
|
|
|
@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
#include "editor/photo_editor_common.h"
|
||||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
} // namespace Ui
|
||||
|
@ -27,17 +29,30 @@ public:
|
|||
[[nodiscard]] rpl::producer<int> rotateRequests() const;
|
||||
[[nodiscard]] rpl::producer<> flipRequests() const;
|
||||
[[nodiscard]] rpl::producer<> paintModeRequests() const;
|
||||
[[nodiscard]] rpl::producer<> doneRequests() const;
|
||||
[[nodiscard]] rpl::producer<> cancelRequests() const;
|
||||
|
||||
void applyMode(const PhotoEditorMode &mode);
|
||||
|
||||
private:
|
||||
|
||||
const style::color &_bg;
|
||||
const base::unique_qptr<HorizontalContainer> _buttonsContainer;
|
||||
const base::unique_qptr<HorizontalContainer> _transformButtons;
|
||||
const base::unique_qptr<HorizontalContainer> _paintButtons;
|
||||
|
||||
const base::unique_qptr<Ui::IconButton> _rotateButton;
|
||||
const base::unique_qptr<Ui::IconButton> _flipButton;
|
||||
const base::unique_qptr<Ui::IconButton> _paintModeButton;
|
||||
|
||||
const base::unique_qptr<Ui::IconButton> _undoButton;
|
||||
const base::unique_qptr<Ui::IconButton> _redoButton;
|
||||
const base::unique_qptr<Ui::IconButton> _paintModeButtonActive;
|
||||
|
||||
const base::unique_qptr<EdgeButton> _cancel;
|
||||
const base::unique_qptr<EdgeButton> _done;
|
||||
|
||||
rpl::variable<PhotoEditorMode> _mode;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Editor
|
||||
|
|
Loading…
Add table
Reference in a new issue