Moved edge buttons to bar in photo editor.

This commit is contained in:
23rd 2021-05-02 12:16:12 +03:00
parent df7026b59c
commit 5976a7ed19
3 changed files with 126 additions and 78 deletions

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
using "ui/basic.style"; using "ui/basic.style";
using "window/window.style";
using "ui/widgets/widgets.style"; using "ui/widgets/widgets.style";
using "ui/chat/chat.style"; using "ui/chat/chat.style";
@ -19,14 +20,19 @@ photoEditorButtonIconFgOver: mediaviewPipControlsFgOver;
photoEditorButtonIconFgActive: lightButtonFg; photoEditorButtonIconFgActive: lightButtonFg;
photoEditorButtonIconFgInactive: mediaviewPipPlaybackInactive; photoEditorButtonIconFgInactive: mediaviewPipPlaybackInactive;
photoEditorButtonBarHeight: 50px;
photoEditorButtonBarWidth: windowMinWidth;
photoEditorButtonBarPadding: margins(2px, 0px, 2px, 0px);
photoEditorTextButtonPadding: margins(22px, 0px, 22px, 0px);
photoEditorRotateButton: IconButton(defaultIconButton) { photoEditorRotateButton: IconButton(defaultIconButton) {
width: 56px; width: photoEditorButtonBarHeight;
height: 56px; height: photoEditorButtonBarHeight;
icon: icon {{ "photo_editor/rotate", photoEditorButtonIconFg }}; icon: icon {{ "photo_editor/rotate", photoEditorButtonIconFg }};
iconOver: icon {{ "photo_editor/rotate", photoEditorButtonIconFgOver }}; iconOver: icon {{ "photo_editor/rotate", photoEditorButtonIconFgOver }};
rippleAreaPosition: point(8px, 8px); rippleAreaPosition: point(5px, 5px);
rippleAreaSize: 40px; rippleAreaSize: 40px;
ripple: RippleAnimation(defaultRippleAnimation) { ripple: RippleAnimation(defaultRippleAnimation) {
color: shadowFg; color: shadowFg;
@ -63,8 +69,6 @@ photoEditorStickersIconActive: icon {{ "settings_stickers", photoEditorButtonIco
photoEditorUndoButtonInactive: icon {{ "photo_editor/undo", photoEditorButtonIconFgInactive }}; photoEditorUndoButtonInactive: icon {{ "photo_editor/undo", photoEditorButtonIconFgInactive }};
photoEditorRedoButtonInactive: icon {{ "photo_editor/undo-flip_horizontal", photoEditorButtonIconFgInactive }}; photoEditorRedoButtonInactive: icon {{ "photo_editor/undo-flip_horizontal", photoEditorButtonIconFgInactive }};
photoEditorTextButtonPadding: margins(10px, 0px, 10px, 0px);
photoEditorColorPickerTopSkip: 20px; photoEditorColorPickerTopSkip: 20px;
photoEditorColorPickerWidth: 250px; photoEditorColorPickerWidth: 250px;
photoEditorColorPickerLineHeight: 10px; photoEditorColorPickerLineHeight: 10px;

View file

@ -67,13 +67,13 @@ EdgeButton::EdgeButton(
} }
void EdgeButton::init() { void EdgeButton::init() {
const auto bg = rounded(_bg); // const auto bg = rounded(_bg);
paintRequest( paintRequest(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
Painter p(this); Painter p(this);
p.drawImage(QPoint(), bg); // p.drawImage(QPoint(), bg);
paintRipple(p, _rippleRect.x(), _rippleRect.y()); paintRipple(p, _rippleRect.x(), _rippleRect.y());
@ -106,30 +106,63 @@ QPoint EdgeButton::prepareRippleStartPosition() const {
return mapFromGlobal(QCursor::pos()) - _rippleRect.topLeft(); return mapFromGlobal(QCursor::pos()) - _rippleRect.topLeft();
} }
class HorizontalContainer final : public Ui::RpWidget { class ButtonBar final : public Ui::RpWidget {
public: public:
HorizontalContainer(not_null<Ui::RpWidget*> parent); ButtonBar(
not_null<Ui::RpWidget*> parent,
const style::color &bg);
void updateChildrenPosition(); private:
QImage _roundedBg;
}; };
HorizontalContainer::HorizontalContainer(not_null<Ui::RpWidget*> parent) ButtonBar::ButtonBar(
not_null<Ui::RpWidget*> parent,
const style::color &bg)
: RpWidget(parent) { : RpWidget(parent) {
} sizeValue(
) | rpl::start_with_next([=](const QSize &size) {
void HorizontalContainer::updateChildrenPosition() { const auto children = RpWidget::children();
auto left = 0; if (children.empty()) {
auto height = 0; return;
for (auto child : RpWidget::children()) {
if (child->isWidgetType()) {
const auto widget = static_cast<QWidget*>(child);
widget->move(left, 0);
left += widget->width();
height = std::max(height, widget->height());
} }
} const auto widgets = ranges::view::all(
resize(left, height); children
) | ranges::view::filter([](not_null<const QObject*> object) {
return object->isWidgetType();
}) | ranges::view::transform([](not_null<QObject*> object) {
return static_cast<Ui::RpWidget*>(object.get());
}) | ranges::to_vector;
const auto residualWidth = size.width()
- ranges::accumulate(widgets, 0, ranges::plus(), &QWidget::width);
const auto step = residualWidth / float(widgets.size() - 1);
auto left = 0.;
for (const auto &widget : widgets) {
widget->moveToLeft(int(left), 0);
left += widget->width() + step;
}
auto result = QImage(
size * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cIntRetinaFactor());
result.fill(bg->c);
const auto options = Images::Option::Smooth
| Images::Option::RoundedLarge
| Images::Option::RoundedAll;
_roundedBg = Images::prepare(std::move(result), 0, 0, options, 0, 0);
}, lifetime());
paintRequest(
) | rpl::start_with_next([=] {
Painter p(this);
p.drawImage(QPoint(), _roundedBg);
}, lifetime());
} }
PhotoEditorControls::PhotoEditorControls( PhotoEditorControls::PhotoEditorControls(
@ -139,8 +172,17 @@ PhotoEditorControls::PhotoEditorControls(
bool doneControls) bool doneControls)
: RpWidget(parent) : RpWidget(parent)
, _bg(st::roundedBg) , _bg(st::roundedBg)
, _transformButtons(base::make_unique_q<HorizontalContainer>(this)) , _buttonHeight(st::photoEditorButtonBarHeight)
, _paintButtons(base::make_unique_q<HorizontalContainer>(this)) , _transformButtons(base::make_unique_q<ButtonBar>(this, _bg))
, _paintBottomButtons(base::make_unique_q<ButtonBar>(this, _bg))
, _transformCancel(base::make_unique_q<EdgeButton>(
_transformButtons,
tr::lng_cancel(tr::now),
_buttonHeight,
true,
_bg,
st::activeButtonFg,
st::photoEditorRotateButton.ripple))
, _rotateButton(base::make_unique_q<Ui::IconButton>( , _rotateButton(base::make_unique_q<Ui::IconButton>(
_transformButtons, _transformButtons,
st::photoEditorRotateButton)) st::photoEditorRotateButton))
@ -150,39 +192,53 @@ PhotoEditorControls::PhotoEditorControls(
, _paintModeButton(base::make_unique_q<Ui::IconButton>( , _paintModeButton(base::make_unique_q<Ui::IconButton>(
_transformButtons, _transformButtons,
st::photoEditorPaintModeButton)) st::photoEditorPaintModeButton))
, _undoButton(base::make_unique_q<Ui::IconButton>( , _transformDone(base::make_unique_q<EdgeButton>(
_paintButtons, _transformButtons,
st::photoEditorUndoButton)) tr::lng_box_done(tr::now),
, _redoButton(base::make_unique_q<Ui::IconButton>( _buttonHeight,
_paintButtons, false,
st::photoEditorRedoButton)) _bg,
, _paintModeButtonActive(base::make_unique_q<Ui::IconButton>( st::lightButtonFg,
_paintButtons, st::photoEditorRotateButton.ripple))
st::photoEditorPaintModeButton)) , _paintCancel(base::make_unique_q<EdgeButton>(
, _stickersButton(controllers->stickersPanelController _paintBottomButtons,
? base::make_unique_q<Ui::IconButton>(
_paintButtons,
st::photoEditorStickersButton)
: nullptr)
, _cancel(base::make_unique_q<EdgeButton>(
this,
tr::lng_cancel(tr::now), tr::lng_cancel(tr::now),
_flipButton->height(), _buttonHeight,
true, true,
_bg, _bg,
st::activeButtonFg, st::activeButtonFg,
st::photoEditorRotateButton.ripple)) st::photoEditorRotateButton.ripple))
, _done(base::make_unique_q<EdgeButton>( , _undoButton(base::make_unique_q<Ui::IconButton>(
this, _paintBottomButtons,
st::photoEditorUndoButton))
, _redoButton(base::make_unique_q<Ui::IconButton>(
_paintBottomButtons,
st::photoEditorRedoButton))
, _paintModeButtonActive(base::make_unique_q<Ui::IconButton>(
_paintBottomButtons,
st::photoEditorPaintModeButton))
, _stickersButton(controllers->stickersPanelController
? base::make_unique_q<Ui::IconButton>(
_paintBottomButtons,
st::photoEditorStickersButton)
: nullptr)
, _paintDone(base::make_unique_q<EdgeButton>(
_paintBottomButtons,
tr::lng_box_done(tr::now), tr::lng_box_done(tr::now),
_flipButton->height(), _buttonHeight,
false, false,
_bg, _bg,
st::lightButtonFg, st::lightButtonFg,
st::photoEditorRotateButton.ripple)) { st::photoEditorRotateButton.ripple)) {
_transformButtons->updateChildrenPosition(); {
_paintButtons->updateChildrenPosition(); const auto &padding = st::photoEditorButtonBarPadding;
const auto w = st::photoEditorButtonBarWidth
- padding.left()
- padding.right();
_transformButtons->resize(w, _buttonHeight);
_paintBottomButtons->resize(w, _buttonHeight);
}
{ {
const auto icon = &st::photoEditorPaintIconActive; const auto icon = &st::photoEditorPaintIconActive;
@ -190,20 +246,6 @@ PhotoEditorControls::PhotoEditorControls(
} }
_paintModeButtonActive->setAttribute(Qt::WA_TransparentForMouseEvents); _paintModeButtonActive->setAttribute(Qt::WA_TransparentForMouseEvents);
paintRequest(
) | rpl::start_with_next([=](const QRect &clip) {
Painter p(this);
const auto &current = _transformButtons->isHidden()
? _paintButtons
: _transformButtons;
p.setPen(Qt::NoPen);
p.setBrush(_bg);
p.drawRect(current->geometry());
}, lifetime());
rpl::combine( rpl::combine(
sizeValue(), sizeValue(),
_mode.value() _mode.value()
@ -214,21 +256,17 @@ PhotoEditorControls::PhotoEditorControls(
return; return;
} }
const auto buttonsTop = height() const auto buttonsTop = size.height()
- st::photoEditorControlsBottomSkip - st::photoEditorControlsBottomSkip
- _transformButtons->height(); - _transformButtons->height();
const auto &current = _transformButtons->isHidden() const auto &current = _transformButtons->isHidden()
? _paintButtons ? _paintBottomButtons
: _transformButtons; : _transformButtons;
current->moveToLeft( current->moveToLeft(
(size.width() - current->width()) / 2, (size.width() - current->width()) / 2,
buttonsTop); buttonsTop);
_cancel->moveToLeft(current->x() - _cancel->width(), buttonsTop);
_done->moveToLeft(current->x() + current->width(), buttonsTop);
}, lifetime()); }, lifetime());
controllers->undoController->setPerformRequestChanges(rpl::merge( controllers->undoController->setPerformRequestChanges(rpl::merge(
@ -257,7 +295,7 @@ PhotoEditorControls::PhotoEditorControls(
) | rpl::map_to(std::optional<bool>(std::nullopt))); ) | rpl::map_to(std::optional<bool>(std::nullopt)));
controllers->stickersPanelController->setMoveRequestChanges( controllers->stickersPanelController->setMoveRequestChanges(
_paintButtons->positionValue( _paintBottomButtons->positionValue(
) | rpl::map([=](const QPoint &containerPos) { ) | rpl::map([=](const QPoint &containerPos) {
return QPoint( return QPoint(
(x() + width()) / 2, (x() + width()) / 2,
@ -298,17 +336,21 @@ rpl::producer<> PhotoEditorControls::paintModeRequests() const {
} }
rpl::producer<> PhotoEditorControls::doneRequests() const { rpl::producer<> PhotoEditorControls::doneRequests() const {
return _done->clicks() | rpl::to_empty; return rpl::merge(
_transformDone->clicks() | rpl::to_empty,
_paintDone->clicks() | rpl::to_empty);
} }
rpl::producer<> PhotoEditorControls::cancelRequests() const { rpl::producer<> PhotoEditorControls::cancelRequests() const {
return _cancel->clicks() | rpl::to_empty; return rpl::merge(
_transformCancel->clicks() | rpl::to_empty,
_paintCancel->clicks() | rpl::to_empty);
} }
void PhotoEditorControls::applyMode(const PhotoEditorMode &mode) { void PhotoEditorControls::applyMode(const PhotoEditorMode &mode) {
using Mode = PhotoEditorMode::Mode; using Mode = PhotoEditorMode::Mode;
_transformButtons->setVisible(mode.mode == Mode::Transform); _transformButtons->setVisible(mode.mode == Mode::Transform);
_paintButtons->setVisible(mode.mode == Mode::Paint); _paintBottomButtons->setVisible(mode.mode == Mode::Paint);
_mode = mode; _mode = mode;
} }

View file

@ -18,7 +18,7 @@ class IconButton;
namespace Editor { namespace Editor {
class EdgeButton; class EdgeButton;
class HorizontalContainer; class ButtonBar;
struct Controllers; struct Controllers;
class PhotoEditorControls final : public Ui::RpWidget { class PhotoEditorControls final : public Ui::RpWidget {
@ -40,20 +40,22 @@ public:
private: private:
const style::color &_bg; const style::color &_bg;
const base::unique_qptr<HorizontalContainer> _transformButtons; const int _buttonHeight;
const base::unique_qptr<HorizontalContainer> _paintButtons; const base::unique_qptr<ButtonBar> _transformButtons;
const base::unique_qptr<ButtonBar> _paintBottomButtons;
const base::unique_qptr<EdgeButton> _transformCancel;
const base::unique_qptr<Ui::IconButton> _rotateButton; const base::unique_qptr<Ui::IconButton> _rotateButton;
const base::unique_qptr<Ui::IconButton> _flipButton; const base::unique_qptr<Ui::IconButton> _flipButton;
const base::unique_qptr<Ui::IconButton> _paintModeButton; const base::unique_qptr<Ui::IconButton> _paintModeButton;
const base::unique_qptr<EdgeButton> _transformDone;
const base::unique_qptr<EdgeButton> _paintCancel;
const base::unique_qptr<Ui::IconButton> _undoButton; const base::unique_qptr<Ui::IconButton> _undoButton;
const base::unique_qptr<Ui::IconButton> _redoButton; const base::unique_qptr<Ui::IconButton> _redoButton;
const base::unique_qptr<Ui::IconButton> _paintModeButtonActive; const base::unique_qptr<Ui::IconButton> _paintModeButtonActive;
const base::unique_qptr<Ui::IconButton> _stickersButton; const base::unique_qptr<Ui::IconButton> _stickersButton;
const base::unique_qptr<EdgeButton> _paintDone;
const base::unique_qptr<EdgeButton> _cancel;
const base::unique_qptr<EdgeButton> _done;
bool _flipped = false; bool _flipped = false;