mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Added saving of color and size of brush from photo editor to settings.
This commit is contained in:
parent
dc7f440902
commit
e322733e20
5 changed files with 104 additions and 25 deletions
|
@ -113,7 +113,8 @@ QByteArray Settings::serialize() const {
|
|||
+ sizeof(qint64)
|
||||
+ sizeof(qint32) * 2
|
||||
+ Serialize::bytearraySize(windowPosition)
|
||||
+ sizeof(qint32);
|
||||
+ sizeof(qint32)
|
||||
+ Serialize::bytearraySize(_photoEditorBrush);
|
||||
for (const auto &[id, rating] : recentEmojiPreloadData) {
|
||||
size += Serialize::stringSize(id) + sizeof(quint16);
|
||||
}
|
||||
|
@ -216,7 +217,8 @@ QByteArray Settings::serialize() const {
|
|||
<< qint32(_workMode.current())
|
||||
<< proxy
|
||||
<< qint32(_hiddenGroupCallTooltips.value())
|
||||
<< qint32(_disableOpenGL ? 1 : 0);
|
||||
<< qint32(_disableOpenGL ? 1 : 0)
|
||||
<< _photoEditorBrush;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -297,6 +299,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
|||
qint32 workMode = static_cast<qint32>(_workMode.current());
|
||||
QByteArray proxy;
|
||||
qint32 hiddenGroupCallTooltips = qint32(_hiddenGroupCallTooltips.value());
|
||||
QByteArray photoEditorBrush = _photoEditorBrush;
|
||||
|
||||
stream >> themesAccentColors;
|
||||
if (!stream.atEnd()) {
|
||||
|
@ -444,6 +447,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
|||
if (!stream.atEnd()) {
|
||||
stream >> disableOpenGL;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> photoEditorBrush;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: "
|
||||
"Bad data for Core::Settings::constructFromSerialized()"));
|
||||
|
@ -573,6 +579,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
|||
? Tooltip::Microphone
|
||||
: Tooltip(0));
|
||||
}();
|
||||
_photoEditorBrush = photoEditorBrush;
|
||||
}
|
||||
|
||||
QString Settings::getSoundPath(const QString &key) const {
|
||||
|
|
|
@ -434,6 +434,13 @@ public:
|
|||
_videoPipGeometry = geometry;
|
||||
}
|
||||
|
||||
[[nodiscard]] QByteArray photoEditorBrush() const {
|
||||
return _photoEditorBrush;
|
||||
}
|
||||
void setPhotoEditorBrush(QByteArray brush) {
|
||||
_photoEditorBrush = brush;
|
||||
}
|
||||
|
||||
[[nodiscard]] float64 rememberedSongVolume() const {
|
||||
return _rememberedSongVolume;
|
||||
}
|
||||
|
@ -696,6 +703,8 @@ private:
|
|||
bool _rememberedSoundNotifyFromTray = false;
|
||||
bool _rememberedFlashBounceNotifyFromTray = false;
|
||||
|
||||
QByteArray _photoEditorBrush;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Editor {
|
|||
namespace {
|
||||
|
||||
constexpr auto kPrecision = 1000;
|
||||
constexpr auto kMinBrushSize = 0.1;
|
||||
constexpr auto kMinBrushSize = 0.1f;
|
||||
constexpr auto kMouseSkip = 1.4;
|
||||
|
||||
constexpr auto kMinInnerHeight = 0.2;
|
||||
|
@ -83,7 +83,9 @@ inline float64 InterpolationRatio(int from, int to, int result) {
|
|||
|
||||
} // namespace
|
||||
|
||||
ColorPicker::ColorPicker(not_null<Ui::RpWidget*> parent)
|
||||
ColorPicker::ColorPicker(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const Brush &savedBrush)
|
||||
: _circleColor(Qt::white)
|
||||
, _width(st::photoEditorColorPickerWidth)
|
||||
, _lineHeight(st::photoEditorColorPickerLineHeight)
|
||||
|
@ -93,7 +95,14 @@ ColorPicker::ColorPicker(not_null<Ui::RpWidget*> parent)
|
|||
, _outlinedStop(FindOutlinedStop(_circleColor, _gradientStops, _width))
|
||||
, _gradientBrush(
|
||||
GradientBrush(QPoint(_width, _lineHeight / 2), _gradientStops))
|
||||
, _brush(Brush{ .sizeRatio = kMinBrushSize, .color = QColor() }) {
|
||||
, _brush(Brush{
|
||||
.sizeRatio = (savedBrush.sizeRatio
|
||||
? savedBrush.sizeRatio
|
||||
: kMinBrushSize),
|
||||
.color = (savedBrush.color.isValid()
|
||||
? savedBrush.color
|
||||
: _gradientStops.front().second),
|
||||
}) {
|
||||
_colorLine->resize(_width, _lineHeight);
|
||||
_canvasForCircle->resize(
|
||||
_width + circleHeight(kMax),
|
||||
|
@ -101,6 +110,8 @@ ColorPicker::ColorPicker(not_null<Ui::RpWidget*> parent)
|
|||
|
||||
_canvasForCircle->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
_down.pos = QPoint(colorToPosition(savedBrush.color), 0);
|
||||
|
||||
_colorLine->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
Painter p(_colorLine);
|
||||
|
@ -146,6 +157,9 @@ ColorPicker::ColorPicker(not_null<Ui::RpWidget*> parent)
|
|||
}
|
||||
const auto e = static_cast<QMouseEvent*>(event.get());
|
||||
updateMousePosition(e->pos(), progress);
|
||||
if (isRelease) {
|
||||
_saveBrushRequests.fire_copy(_brush);
|
||||
}
|
||||
|
||||
_canvasForCircle->update();
|
||||
}, _colorLine->lifetime());
|
||||
|
@ -168,18 +182,14 @@ void ColorPicker::updateMousePosition(const QPoint &pos, float64 progress) {
|
|||
const auto from = 0;
|
||||
const auto to = bottom - skip;
|
||||
|
||||
const auto size = (mappedY > to)
|
||||
? _brush.current().sizeRatio // Don't change value.
|
||||
: std::clamp(
|
||||
1. - InterpolationRatio(from, to, _down.pos.y()),
|
||||
// Don't change the brush size when we are on the color line.
|
||||
if (mappedY <= to) {
|
||||
_brush.sizeRatio = std::clamp(
|
||||
float(1. - InterpolationRatio(from, to, _down.pos.y())),
|
||||
kMinBrushSize,
|
||||
1.);
|
||||
const auto color = positionToColor(_down.pos.x());
|
||||
|
||||
_brush = Brush{
|
||||
.sizeRatio = float(size),
|
||||
.color = color,
|
||||
};
|
||||
1.f);
|
||||
}
|
||||
_brush.color = positionToColor(_down.pos.x());
|
||||
}
|
||||
|
||||
void ColorPicker::moveLine(const QPoint &position) {
|
||||
|
@ -239,9 +249,9 @@ void ColorPicker::paintCircle(Painter &p) {
|
|||
const auto innerH = InterpolateF(
|
||||
h * kMinInnerHeight,
|
||||
h * kMaxInnerHeight,
|
||||
_brush.current().sizeRatio);
|
||||
_brush.sizeRatio);
|
||||
|
||||
p.setBrush(_brush.current().color);
|
||||
p.setBrush(_brush.color);
|
||||
|
||||
const auto innerRect = QRectF(
|
||||
r.x() + (r.width() - innerH) / 2.,
|
||||
|
@ -297,8 +307,18 @@ void ColorPicker::setVisible(bool visible) {
|
|||
_canvasForCircle->setVisible(visible);
|
||||
}
|
||||
|
||||
rpl::producer<Brush> ColorPicker::brushValue() const {
|
||||
return _brush.value();
|
||||
rpl::producer<Brush> ColorPicker::saveBrushRequests() const {
|
||||
return _saveBrushRequests.events();
|
||||
}
|
||||
|
||||
int ColorPicker::colorToPosition(const QColor &color) const {
|
||||
const auto step = 1. / kPrecision;
|
||||
for (auto i = 0.; i <= 1.; i += step) {
|
||||
if (positionToColor(i * _width) == color) {
|
||||
return i * _width;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
|
|
|
@ -25,17 +25,18 @@ public:
|
|||
std::optional<int> nextStopPos = std::nullopt;
|
||||
};
|
||||
|
||||
ColorPicker(not_null<Ui::RpWidget*> parent);
|
||||
ColorPicker(not_null<Ui::RpWidget*> parent, const Brush &savedBrush);
|
||||
|
||||
void moveLine(const QPoint &position);
|
||||
void setVisible(bool visible);
|
||||
|
||||
rpl::producer<Brush> brushValue() const;
|
||||
rpl::producer<Brush> saveBrushRequests() const;
|
||||
|
||||
private:
|
||||
void paintCircle(Painter &p);
|
||||
void paintOutline(Painter &p, const QRectF &rect);
|
||||
QColor positionToColor(int x) const;
|
||||
int colorToPosition(const QColor &color) const;
|
||||
int circleHeight(float64 progress = 0.) const;
|
||||
void updateMousePosition(const QPoint &pos, float64 progress);
|
||||
|
||||
|
@ -54,10 +55,12 @@ private:
|
|||
QPoint pos;
|
||||
bool pressed = false;
|
||||
} _down;
|
||||
rpl::variable<Brush> _brush;
|
||||
Brush _brush;
|
||||
|
||||
Ui::Animations::Simple _circleAnimation;
|
||||
|
||||
rpl::event_stream<Brush> _saveBrushRequests;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Editor
|
||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "editor/photo_editor.h"
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "editor/color_picker.h"
|
||||
#include "editor/photo_editor_content.h"
|
||||
#include "editor/photo_editor_controls.h"
|
||||
|
@ -14,6 +16,32 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_editor.h"
|
||||
|
||||
namespace Editor {
|
||||
namespace {
|
||||
|
||||
constexpr auto kPrecision = 100000;
|
||||
|
||||
[[nodiscard]] QByteArray Serialize(const Brush &brush) {
|
||||
auto result = QByteArray();
|
||||
auto stream = QDataStream(&result, QIODevice::WriteOnly);
|
||||
stream.setVersion(QDataStream::Qt_5_3);
|
||||
stream << qint32(brush.sizeRatio * kPrecision) << brush.color;
|
||||
stream.device()->close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] Brush Deserialize(const QByteArray &data) {
|
||||
auto stream = QDataStream(data);
|
||||
auto result = Brush();
|
||||
auto size = qint32(0);
|
||||
stream >> size >> result.color;
|
||||
result.sizeRatio = size / float(kPrecision);
|
||||
return (stream.status() != QDataStream::Ok)
|
||||
? Brush()
|
||||
: result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PhotoEditor::PhotoEditor(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
|
@ -28,7 +56,10 @@ PhotoEditor::PhotoEditor(
|
|||
_modifications,
|
||||
_undoController))
|
||||
, _controls(base::make_unique_q<PhotoEditorControls>(this, _undoController))
|
||||
, _colorPicker(std::make_unique<ColorPicker>(this)) {
|
||||
, _colorPicker(std::make_unique<ColorPicker>(
|
||||
this,
|
||||
Deserialize(Core::App().settings().photoEditorBrush()))) {
|
||||
|
||||
sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &size) {
|
||||
if (size.isEmpty()) {
|
||||
|
@ -97,9 +128,18 @@ PhotoEditor::PhotoEditor(
|
|||
}
|
||||
}, lifetime());
|
||||
|
||||
_colorPicker->brushValue(
|
||||
rpl::single(
|
||||
Deserialize(Core::App().settings().photoEditorBrush())
|
||||
) | rpl::then(
|
||||
_colorPicker->saveBrushRequests()
|
||||
) | rpl::start_with_next([=](const Brush &brush) {
|
||||
_content->applyBrush(brush);
|
||||
|
||||
const auto serialized = Serialize(brush);
|
||||
if (Core::App().settings().photoEditorBrush() != serialized) {
|
||||
Core::App().settings().setPhotoEditorBrush(serialized);
|
||||
Core::App().saveSettingsDelayed();
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue