[img-editor] Synced palette color and tool selection with text focus.

This commit is contained in:
23rd
2026-04-12 17:37:11 +03:00
parent 631fe4f362
commit 3ec1ff8c7e
10 changed files with 139 additions and 12 deletions
+18 -4
View File
@@ -351,6 +351,7 @@ ColorPicker::ColorPicker(
button->show();
}
const auto setToolRequest = [=](Brush::Tool tool) {
_toolClicks.fire({});
setTool(tool);
};
if (_toolButtons.size() >= 5) {
@@ -581,6 +582,11 @@ void ColorPicker::setColor(const QColor &color) {
}
}
void ColorPicker::setToolSelectionVisible(bool visible) {
_toolSelectionSuppressed = !visible;
_toolSelection->setVisible(visible);
}
void ColorPicker::updateColorButtonColor(const QColor &color, bool animated) {
const auto hasValid = _colorButtonFrom.isValid() && _colorButtonTo.isValid();
const auto from = hasValid ? colorButtonColor() : color;
@@ -643,11 +649,14 @@ void ColorPicker::setVisible(bool visible) {
_paletteWrap->setVisible(visible && _paletteVisible);
_sizeControlHoverArea->setVisible(visible);
_sizeControl->setVisible(visible);
_toolSelection->setVisible(visible && !_paletteVisible);
const auto showTools = visible
&& !_paletteVisible
&& !_toolSelectionSuppressed;
_toolSelection->setVisible(showTools);
for (const auto &button : _toolButtons) {
button->setVisible(visible && !_paletteVisible);
}
if (visible && !_paletteVisible) {
if (showTools) {
updateToolSelection(false);
}
}
@@ -656,6 +665,10 @@ rpl::producer<Brush> ColorPicker::saveBrushRequests() const {
return _saveBrushRequests.events_starting_with_copy(_brush);
}
rpl::producer<> ColorPicker::toolClicks() const {
return _toolClicks.events();
}
bool ColorPicker::preventHandleKeyPress() const {
return _sizeControl->isVisible()
&& (_sizeControlAnimation.animating() || _sizeDown.pressed);
@@ -796,13 +809,14 @@ void ColorPicker::setPaletteVisible(bool visible) {
_paletteVisible = visible;
_paletteWrap->setVisible(visible);
_colorButton->setVisible(!visible);
_toolSelection->setVisible(!visible);
const auto showTools = !visible && !_toolSelectionSuppressed;
_toolSelection->setVisible(showTools);
for (const auto &button : _toolButtons) {
button->setVisible(!visible);
}
if (visible) {
rebuildPalette();
} else {
} else if (showTools) {
updateToolSelection(false);
}
}
@@ -31,9 +31,11 @@ public:
void setCanvasRect(const QRect &rect);
void setVisible(bool visible);
void setColor(const QColor &color);
void setToolSelectionVisible(bool visible);
bool preventHandleKeyPress() const;
rpl::producer<Brush> saveBrushRequests() const;
rpl::producer<> toolClicks() const;
private:
void paintSizeControl(QPainter &p);
@@ -76,6 +78,7 @@ private:
int y = 0;
bool pressed = false;
} _sizeDown;
bool _toolSelectionSuppressed = false;
bool _sizeHoverAreaHovered = false;
bool _sizeControlHovered = false;
bool _sizeControlExpanded = false;
@@ -95,6 +98,7 @@ private:
Ui::Animations::Simple _toolSelectionAnimation;
rpl::event_stream<Brush> _saveBrushRequests;
rpl::event_stream<> _toolClicks;
std::vector<base::unique_qptr<Ui::ColorSample>> _paletteButtons;
base::unique_qptr<Ui::AbstractButton> _palettePlus;
@@ -250,14 +250,30 @@ void Paint::createTextItem() {
_scene->createTextAtCenter();
}
void Paint::clearSelection() {
_scene->clearSelection();
}
void Paint::setTextColor(const QColor &color) {
_scene->setTextColor(color);
}
void Paint::setSelectedTextColor(const QColor &color) {
_scene->setSelectedTextColor(color);
}
rpl::producer<QColor> Paint::textColorRequests() const {
return _scene->textColorRequests();
}
rpl::producer<QColor> Paint::textItemSelections() const {
return _scene->textItemSelections();
}
rpl::producer<> Paint::textItemDeselections() const {
return _scene->textItemDeselections();
}
void Paint::handleMimeData(const QMimeData *data) {
const auto add = [&](QImage image) {
if (image.isNull()) {
@@ -42,9 +42,13 @@ public:
void updateUndoState();
void createTextItem();
void clearSelection();
void setTextColor(const QColor &color);
void setSelectedTextColor(const QColor &color);
[[nodiscard]] rpl::producer<QColor> textColorRequests() const;
[[nodiscard]] rpl::producer<QColor> textItemSelections() const;
[[nodiscard]] rpl::producer<> textItemDeselections() const;
void handleMimeData(const QMimeData *data);
void paintImage(QPainter &p, const QPixmap &image) const;
+33 -8
View File
@@ -341,17 +341,27 @@ PhotoEditor::PhotoEditor(
}
}, lifetime());
_colorPicker->toolClicks(
) | rpl::on_next([=] {
_content->clearSelection();
}, lifetime());
_colorPicker->saveBrushRequests(
) | rpl::on_next([=](const Brush &brush) {
_content->applyBrush(brush);
_content->setTextColor(brush.color);
if (_textItemSelected) {
_content->setSelectedTextColor(brush.color);
_content->setTextColor(brush.color);
} else {
_content->applyBrush(brush);
_content->setTextColor(brush.color);
_brushTool = brush.tool;
_brushes[ToolIndex(brush.tool)] = brush;
const auto serialized = Serialize(_brushes, _brushTool);
if (Core::App().settings().photoEditorBrush() != serialized) {
Core::App().settings().setPhotoEditorBrush(serialized);
Core::App().saveSettingsDelayed();
_brushTool = brush.tool;
_brushes[ToolIndex(brush.tool)] = brush;
const auto serialized = Serialize(_brushes, _brushTool);
if (Core::App().settings().photoEditorBrush() != serialized) {
Core::App().settings().setPhotoEditorBrush(serialized);
Core::App().saveSettingsDelayed();
}
}
}, lifetime());
@@ -359,6 +369,21 @@ PhotoEditor::PhotoEditor(
) | rpl::on_next([=](const QColor &color) {
_colorPicker->setColor(color);
}, lifetime());
_content->textItemSelections(
) | rpl::on_next([=](const QColor &color) {
_textItemSelected = true;
_colorPicker->setColor(color);
_colorPicker->setToolSelectionVisible(false);
}, lifetime());
_content->textItemDeselections(
) | rpl::on_next([=] {
_textItemSelected = false;
const auto &brush = _brushes[ToolIndex(_brushTool)];
_colorPicker->setColor(brush.color);
_colorPicker->setToolSelectionVisible(true);
}, lifetime());
}
void PhotoEditor::keyPressEvent(QKeyEvent *e) {
@@ -72,6 +72,7 @@ private:
.mode = PhotoEditorMode::Mode::Transform,
.action = PhotoEditorMode::Action::None,
};
bool _textItemSelected = false;
rpl::event_stream<PhotoModifications> _done;
rpl::event_stream<> _cancel;
@@ -166,14 +166,30 @@ void PhotoEditorContent::createTextItem() {
_paint->createTextItem();
}
void PhotoEditorContent::clearSelection() {
_paint->clearSelection();
}
void PhotoEditorContent::setTextColor(const QColor &color) {
_paint->setTextColor(color);
}
void PhotoEditorContent::setSelectedTextColor(const QColor &color) {
_paint->setSelectedTextColor(color);
}
rpl::producer<QColor> PhotoEditorContent::textColorRequests() const {
return _paint->textColorRequests();
}
rpl::producer<QColor> PhotoEditorContent::textItemSelections() const {
return _paint->textItemSelections();
}
rpl::producer<> PhotoEditorContent::textItemDeselections() const {
return _paint->textItemDeselections();
}
bool PhotoEditorContent::handleKeyPress(not_null<QKeyEvent*> e) const {
return false;
}
@@ -32,9 +32,13 @@ public:
void applyMode(const PhotoEditorMode &mode);
void applyBrush(const Brush &brush);
void createTextItem();
void clearSelection();
void setTextColor(const QColor &color);
void setSelectedTextColor(const QColor &color);
[[nodiscard]] rpl::producer<QColor> textColorRequests() const;
[[nodiscard]] rpl::producer<QColor> textItemSelections() const;
[[nodiscard]] rpl::producer<> textItemDeselections() const;
void applyAspectRatio(float64 ratio);
void save(PhotoModifications &modifications);
@@ -288,6 +288,27 @@ Scene::Scene(const QRectF &rect)
addItem(item);
_canvas->setZValue(++_lastLineZ);
}, _lifetime);
QObject::connect(
this,
&QGraphicsScene::selectionChanged,
[=] {
const auto selected = selectedItems();
auto *textItem = (ItemText*)(nullptr);
if (selected.size() == 1
&& selected.front()->type() == ItemText::Type) {
textItem = static_cast<ItemText*>(selected.front());
}
if (textItem) {
if (!_textItemWasSelected) {
_textItemWasSelected = true;
_textItemSelections.fire_copy(textItem->color());
}
} else if (_textItemWasSelected) {
_textItemWasSelected = false;
_textItemDeselections.fire({});
}
});
}
void Scene::cancelDrawing() {
@@ -378,10 +399,26 @@ void Scene::setTextColor(const QColor &color) {
}
}
void Scene::setSelectedTextColor(const QColor &color) {
for (auto *item : selectedItems()) {
if (item->type() == ItemText::Type) {
static_cast<ItemText*>(item)->setColor(color);
}
}
}
rpl::producer<QColor> Scene::textColorRequests() const {
return _textColorRequests.events();
}
rpl::producer<QColor> Scene::textItemSelections() const {
return _textItemSelections.events();
}
rpl::producer<> Scene::textItemDeselections() const {
return _textItemDeselections.events();
}
void Scene::setBlurSource(Fn<QImage(QRect)> source) {
_blurSource = std::move(source);
}
@@ -52,8 +52,11 @@ public:
void startTextEditing(ItemText *item);
void createTextAtCenter();
void setTextColor(const QColor &color);
void setSelectedTextColor(const QColor &color);
[[nodiscard]] rpl::producer<QColor> textColorRequests() const;
[[nodiscard]] rpl::producer<QColor> textItemSelections() const;
[[nodiscard]] rpl::producer<> textItemDeselections() const;
[[nodiscard]] bool hasUndo() const;
[[nodiscard]] bool hasRedo() const;
@@ -99,6 +102,9 @@ private:
rpl::event_stream<> _addsItem, _removesItem;
rpl::event_stream<QColor> _textColorRequests;
rpl::event_stream<QColor> _textItemSelections;
rpl::event_stream<> _textItemDeselections;
bool _textItemWasSelected = false;
rpl::lifetime _lifetime;
};