Export JPEG and Canvas Size take the app's colour picker; a panel opens over a modal sheet (13.4a)
This commit is contained in:
1 parent
0b7eb6cb6f
commit
bc49b722eb
23 files changed
+470
-134
No files matched your search
@@ -28,6 +28,11 @@ public:
|
||||
void openEffectColorPicker(LayerEffectKind kind);
|
||||
// The effect follows the picker's working colour.
|
||||
void previewEffectColor();
|
||||
// The picker on a dialog's colour, which hears each change.
|
||||
void openDialogColorPicker(const QString &title, const PaletteColor &color, std::function<void(const PaletteColor &)> change);
|
||||
// A dialog covers the canvas: nothing to sample.
|
||||
bool pickingForDialog() const;
|
||||
void previewDialogColor() const;
|
||||
// The open text draft previews the picker's working colour.
|
||||
void previewTextColor();
|
||||
// Paints the open text's selected letters, or all of it.
|
||||
|
||||
@@ -109,6 +109,8 @@ QString ColorPickerTarget::title() const
|
||||
return QStringLiteral("Color Picker (Vignette Color)");
|
||||
if (kind == Kind::dither)
|
||||
return light ? QStringLiteral("Color Picker (Dither Light Color)") : QStringLiteral("Color Picker (Dither Dark Color)");
|
||||
if (kind == Kind::dialog)
|
||||
return QStringLiteral("Color Picker (%1)").arg(dialogTitle);
|
||||
return background ? QStringLiteral("Color Picker (Background Color)") : QStringLiteral("Color Picker (Foreground Color)");
|
||||
}
|
||||
|
||||
@@ -257,6 +259,8 @@ void EditorSession::closeColorPicker(bool commit)
|
||||
setVignetteColor(commit ? color : picker.original);
|
||||
} else if (picker.target.kind == ColorPickerTarget::Kind::dither) {
|
||||
setDitherColor(commit ? color : picker.original, picker.target.light);
|
||||
} else if (picker.target.kind == ColorPickerTarget::Kind::dialog) {
|
||||
picker.dialogChange(commit ? color : picker.original);
|
||||
} else if (picker.target.kind == ColorPickerTarget::Kind::effect) {
|
||||
const PaletteColor chosen = commit ? color : picker.original;
|
||||
changeEffects([&](LayerEffects &effects) { effects.setColor(chosen, picker.target.effect); });
|
||||
@@ -440,3 +444,26 @@ std::optional<PaletteColor> EditorSession::sampleCompositeColor(QPointF point) c
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSession::openDialogColorPicker(const QString &title, const PaletteColor &color, std::function<void(const PaletteColor &)> change)
|
||||
{
|
||||
if (m_colorPicker)
|
||||
return;
|
||||
ColorPickerTarget target{ColorPickerTarget::Kind::dialog};
|
||||
target.dialogTitle = title;
|
||||
m_colorPicker.emplace(target, color);
|
||||
m_colorPicker->dialogChange = std::move(change);
|
||||
notify();
|
||||
}
|
||||
|
||||
bool EditorSession::pickingForDialog() const
|
||||
{
|
||||
return m_colorPicker && m_colorPicker->target.kind == ColorPickerTarget::Kind::dialog;
|
||||
}
|
||||
|
||||
// The dialog follows the working colour; the session keeps nothing.
|
||||
void EditorSession::previewDialogColor() const
|
||||
{
|
||||
if (pickingForDialog())
|
||||
m_colorPicker->dialogChange(m_colorPicker->color());
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <QColor>
|
||||
#include <QString>
|
||||
#include <QUuid>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
// Swift's PaletteColor: an sRGB colour without alpha.
|
||||
@@ -38,7 +39,7 @@ enum class LayerEffectKind;
|
||||
|
||||
// The picker's targets: palette, text, effect, a filter's colour.
|
||||
struct ColorPickerTarget {
|
||||
enum class Kind { palette, text, gradientMap, effect, vignette, dither };
|
||||
enum class Kind { palette, text, gradientMap, effect, vignette, dither, dialog };
|
||||
Kind kind;
|
||||
bool background = false;
|
||||
std::optional<QUuid> draftID = std::nullopt;
|
||||
@@ -48,6 +49,8 @@ struct ColorPickerTarget {
|
||||
LayerEffectKind effect{};
|
||||
// Dither's Two Colors: the light one, else the dark.
|
||||
bool light = false;
|
||||
// A dialog's own colour, such as Export JPEG's background.
|
||||
QString dialogTitle{};
|
||||
QString title() const;
|
||||
friend bool operator==(const ColorPickerTarget &, const ColorPickerTarget &) = default;
|
||||
};
|
||||
@@ -66,5 +69,7 @@ struct ColorPickerState {
|
||||
LayerTextStyle style;
|
||||
};
|
||||
std::optional<EditedText> editedText;
|
||||
// A dialog's colour: told as it moves, then on closing.
|
||||
std::function<void(const PaletteColor &)> dialogChange;
|
||||
PaletteColor color() const { return hsb.rgb().quantized(); }
|
||||
};
|
||||
@@ -140,7 +140,7 @@ void ProjectController::exportJPEG(std::function<void()> done)
|
||||
}
|
||||
QDialog *dialog = sheet(QStringLiteral("Export JPEG"));
|
||||
auto chosen = std::make_shared<std::optional<QByteArray>>();
|
||||
dialog->layout()->addWidget(new JPEGExportSheet(std::move(*rendered.raster), [dialog, chosen](std::optional<QByteArray> data) {
|
||||
dialog->layout()->addWidget(new JPEGExportSheet(std::move(*rendered.raster), session, [dialog, chosen](std::optional<QByteArray> data) {
|
||||
*chosen = std::move(data);
|
||||
dialog->done(*chosen ? QDialog::Accepted : QDialog::Rejected);
|
||||
}, dialog));
|
||||
|
||||
@@ -31,7 +31,7 @@ void ProjectController::canvasSize(std::function<void()> done)
|
||||
}
|
||||
QDialog *dialog = sheet(QStringLiteral("Canvas Size"));
|
||||
auto chosen = std::make_shared<std::optional<CanvasSizeOptions>>();
|
||||
dialog->layout()->addWidget(new CanvasSizeSheet(session.document().value(), session.foregroundColor(), session.backgroundColor(),
|
||||
dialog->layout()->addWidget(new CanvasSizeSheet(session.document().value(), session,
|
||||
[dialog, chosen](std::optional<CanvasSizeOptions> options) {
|
||||
*chosen = options;
|
||||
dialog->done(options ? QDialog::Accepted : QDialog::Rejected);
|
||||
|
||||
@@ -14,7 +14,8 @@ bool CanvasView::palettePicking() const
|
||||
bool CanvasView::picking() const
|
||||
{
|
||||
const std::optional<FilterEdit> &edit = m_session.filterEdit();
|
||||
return palettePicking() || m_session.colorPicker() || m_session.hueSampleMode() || (m_session.levels() && m_session.levels()->sampleMode) || m_session.colorRange()
|
||||
return palettePicking() || (m_session.colorPicker() && !m_session.pickingForDialog()) || m_session.hueSampleMode()
|
||||
|| (m_session.levels() && m_session.levels()->sampleMode) || m_session.colorRange()
|
||||
|| (edit
|
||||
&& (edit->rawPanel.samplesWhiteBalance || edit->rawPanel.samplesPointColor || edit->rawPanel.samplesDefringe
|
||||
|| edit->rawPanel.drawingGeometryGuide));
|
||||
|
||||
+16
-25
@@ -2,12 +2,11 @@
|
||||
#include "Document/DocumentLimits.h"
|
||||
#include "UI/KeyboardShortcuts.h"
|
||||
#include "UI/ByteCounts.h"
|
||||
#include "UI/ColorPaletteControls.h"
|
||||
#include "UI/ColorPickerSheet+Dialog.h"
|
||||
#include "UI/ColorPickerSheet.h"
|
||||
#include "UI/NumericScrub.h"
|
||||
#include <QButtonGroup>
|
||||
#include <QCheckBox>
|
||||
#include <QColorDialog>
|
||||
#include <QComboBox>
|
||||
#include <QFrame>
|
||||
#include <QGridLayout>
|
||||
@@ -109,13 +108,14 @@ protected:
|
||||
};
|
||||
}
|
||||
|
||||
CanvasSizeSheet::CanvasSizeSheet(const CanvasDocument &document, PaletteColor foreground, PaletteColor background,
|
||||
std::function<void(std::optional<CanvasSizeOptions>)> finish, QWidget *parent)
|
||||
: QWidget(parent), m_foreground(foreground), m_background(background), m_finish(std::move(finish)),
|
||||
CanvasSizeSheet::CanvasSizeSheet(const CanvasDocument &document, EditorSession &session, std::function<void(std::optional<CanvasSizeOptions>)> finish,
|
||||
QWidget *parent)
|
||||
: QWidget(parent), m_session(session), m_foreground(session.foregroundColor()), m_background(session.backgroundColor()), m_finish(std::move(finish)),
|
||||
m_draft(document.width, document.height, document.resolution), m_width(dimension(true)), m_height(dimension(false)),
|
||||
m_note(text(QString(), 12, QFont::Normal, QPalette::PlaceholderText, this)),
|
||||
m_anchors(new QButtonGroup(this)), m_anchorName(text(QString(), 12, QFont::Bold, QPalette::WindowText, this)), m_extension(new QComboBox(this)),
|
||||
m_customRow(new QWidget(this)), m_customSwatch(new SwatchButton([this] { return m_custom; }, 3, 0, 0.5, m_customRow)),
|
||||
m_customRow(new QWidget(this)), m_customSwatch(new DialogColorSwatch(
|
||||
QStringLiteral("Extension Color"), [this] { return m_custom; }, [this](const PaletteColor &custom) { m_custom = custom; }, session, m_customRow)),
|
||||
m_ok(new QPushButton(QStringLiteral("OK"), this))
|
||||
{
|
||||
setFixedWidth(450);
|
||||
@@ -224,14 +224,13 @@ CanvasSizeSheet::CanvasSizeSheet(const CanvasDocument &document, PaletteColor fo
|
||||
extension->addWidget(extensionLabel);
|
||||
extension->addWidget(m_extension, 1);
|
||||
column->addLayout(extension);
|
||||
// Swift's ColorPicker: its label and a well, no opacity.
|
||||
// Its label and the app's picker on a swatch.
|
||||
m_customRow->setObjectName(QStringLiteral("extensionColorRow"));
|
||||
m_customSwatch->setObjectName(QStringLiteral("extensionColor"));
|
||||
m_customSwatch->setFixedSize(36, 18);
|
||||
m_customSwatch->setAccessibleName(QStringLiteral("Extension color"));
|
||||
connect(m_customSwatch, &QAbstractButton::clicked, this, &CanvasSizeSheet::pickCustomColor);
|
||||
m_customSwatch->setToolTip(QStringLiteral("Color for the added canvas"));
|
||||
auto *customLayout = new QHBoxLayout(m_customRow);
|
||||
customLayout->setContentsMargins(0, 0, 0, 0);
|
||||
customLayout->setSpacing(8);
|
||||
customLayout->addWidget(new QLabel(QStringLiteral("Extension color"), m_customRow));
|
||||
customLayout->addWidget(m_customSwatch);
|
||||
customLayout->addStretch(1);
|
||||
@@ -240,13 +239,18 @@ CanvasSizeSheet::CanvasSizeSheet(const CanvasDocument &document, PaletteColor fo
|
||||
auto *cancel = new QPushButton(QStringLiteral("Cancel"), this);
|
||||
cancel->setObjectName(QStringLiteral("canvasCancel"));
|
||||
cancel->setAutoDefault(false);
|
||||
connect(cancel, &QPushButton::clicked, this, [this] { m_finish(std::nullopt); });
|
||||
connect(cancel, &QPushButton::clicked, this, [this] {
|
||||
DialogColorSwatch::closePicker(m_session);
|
||||
m_finish(std::nullopt);
|
||||
});
|
||||
m_ok->setObjectName(QStringLiteral("canvasOK"));
|
||||
m_ok->setDefault(true);
|
||||
// Swift's configuredNativeShortcut: Return and Escape, as remapped.
|
||||
NativeShortcut::bind(*this, m_ok, cancel);
|
||||
// OK rests while the draft is invalid: no guard needed.
|
||||
connect(m_ok, &QPushButton::clicked, this, [this] {
|
||||
// An open picker's colour counts: it closes first.
|
||||
DialogColorSwatch::closePicker(m_session);
|
||||
m_finish(CanvasSizeOptions{.width = qint64(std::round(m_draft.width)), .height = qint64(std::round(m_draft.height)), .anchor = m_anchor,
|
||||
.fill = fill()});
|
||||
});
|
||||
@@ -300,20 +304,6 @@ std::optional<CanvasExtensionColor> CanvasSizeSheet::fill() const
|
||||
}
|
||||
}
|
||||
|
||||
// The desktop's colour dialog, SwiftUI's colour panel, without alpha.
|
||||
void CanvasSizeSheet::pickCustomColor()
|
||||
{
|
||||
auto *dialog = new QColorDialog(m_custom.color(), this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->setWindowTitle(QStringLiteral("Extension color"));
|
||||
connect(dialog, &QColorDialog::colorSelected, this, [this](const QColor &picked) {
|
||||
const QColor srgb = picked.toRgb();
|
||||
m_custom = PaletteColor{srgb.redF(), srgb.greenF(), srgb.blueF()};
|
||||
m_customSwatch->update();
|
||||
});
|
||||
dialog->open();
|
||||
}
|
||||
|
||||
// Units, Relative and Lock change only through their own controls.
|
||||
void CanvasSizeSheet::synchronize()
|
||||
{
|
||||
@@ -347,4 +337,5 @@ void CanvasSizeSheet::synchronize()
|
||||
CanvasSizeSheet::~CanvasSizeSheet()
|
||||
{
|
||||
releaseFocus(*this);
|
||||
DialogColorSwatch::closePicker(m_session);
|
||||
}
|
||||
@@ -12,14 +12,15 @@ class QButtonGroup;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class SwatchButton;
|
||||
class DialogColorSwatch;
|
||||
class EditorSession;
|
||||
|
||||
// Swift's CanvasSizeSheet: the new size, the point kept, the extension.
|
||||
class CanvasSizeSheet : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CanvasSizeSheet(const CanvasDocument &document, PaletteColor foreground, PaletteColor background,
|
||||
std::function<void(std::optional<CanvasSizeOptions>)> finish, QWidget *parent = nullptr);
|
||||
CanvasSizeSheet(const CanvasDocument &document, EditorSession &session, std::function<void(std::optional<CanvasSizeOptions>)> finish,
|
||||
QWidget *parent = nullptr);
|
||||
~CanvasSizeSheet() override;
|
||||
|
||||
private:
|
||||
@@ -27,9 +28,9 @@ private:
|
||||
// Swift's scrubbable Width or Height title.
|
||||
NumericScrub *scrub(QLabel *title, bool widthAxis);
|
||||
std::optional<CanvasExtensionColor> fill() const;
|
||||
void pickCustomColor();
|
||||
void synchronize();
|
||||
|
||||
EditorSession &m_session;
|
||||
const PaletteColor m_foreground;
|
||||
const PaletteColor m_background;
|
||||
const std::function<void(std::optional<CanvasSizeOptions>)> m_finish;
|
||||
@@ -45,6 +46,6 @@ private:
|
||||
QLabel *const m_anchorName;
|
||||
QComboBox *const m_extension;
|
||||
QWidget *const m_customRow;
|
||||
SwatchButton *const m_customSwatch;
|
||||
DialogColorSwatch *const m_customSwatch;
|
||||
QPushButton *const m_ok;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "UI/ColorPickerSheet+Dialog.h"
|
||||
#include <QHideEvent>
|
||||
|
||||
// The brush's swatch: 34 by 18, a white ring.
|
||||
DialogColorSwatch::DialogColorSwatch(const QString &title, std::function<PaletteColor()> colour, std::function<void(const PaletteColor &)> change,
|
||||
EditorSession &session, QWidget *parent)
|
||||
: SwatchButton(colour, 4, 1, 1, parent), m_session(session)
|
||||
{
|
||||
setFixedSize(34, 18);
|
||||
setAccessibleName(title);
|
||||
connect(this, &QAbstractButton::clicked, this, [this, title, colour, change, &session] {
|
||||
session.openDialogColorPicker(title, colour(), [this, change](const PaletteColor &picked) {
|
||||
change(picked);
|
||||
update();
|
||||
});
|
||||
});
|
||||
connect(&session, &EditorSession::changed, this, [this, &session] {
|
||||
const std::optional<PaletteColor> now = session.colorPicker() ? std::optional(session.colorPicker()->color()) : std::nullopt;
|
||||
if (now == m_seen)
|
||||
return;
|
||||
m_seen = now;
|
||||
session.previewDialogColor();
|
||||
});
|
||||
}
|
||||
|
||||
void DialogColorSwatch::hideEvent(QHideEvent *event)
|
||||
{
|
||||
if (!event->spontaneous())
|
||||
closePicker(m_session);
|
||||
SwatchButton::hideEvent(event);
|
||||
}
|
||||
|
||||
void DialogColorSwatch::closePicker(EditorSession &session)
|
||||
{
|
||||
if (session.pickingForDialog())
|
||||
session.closeColorPicker(true);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "Document/EditorSession.h"
|
||||
#include "UI/ColorPaletteControls.h"
|
||||
|
||||
// Swift's DialogColorSwatch: a dialog's colour in the app's picker.
|
||||
class DialogColorSwatch : public SwatchButton {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DialogColorSwatch(const QString &title, std::function<PaletteColor()> colour, std::function<void(const PaletteColor &)> change, EditorSession &session,
|
||||
QWidget *parent);
|
||||
// Puts the picker away with the dialog, keeping its colour.
|
||||
static void closePicker(EditorSession &session);
|
||||
|
||||
protected:
|
||||
// Swift's onDisappear: the picker goes with the swatch.
|
||||
void hideEvent(QHideEvent *event) override;
|
||||
|
||||
private:
|
||||
EditorSession &m_session;
|
||||
// Swift's onChange: the picker's colour as last seen.
|
||||
std::optional<PaletteColor> m_seen;
|
||||
};
|
||||
@@ -235,19 +235,23 @@ ColorPickerSheet::ColorPickerSheet(EditorSession &session, std::function<void(bo
|
||||
m_hex->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
fields->addWidget(label(QStringLiteral("#"), this), 3, 0);
|
||||
fields->addWidget(m_hex, 3, 1, Qt::AlignLeft);
|
||||
auto *hint = new QLabel(QStringLiteral("Click the canvas to sample"), this);
|
||||
QFont small = hint->font();
|
||||
small.setPixelSize(10);
|
||||
hint->setFont(small);
|
||||
hint->setForegroundRole(QPalette::PlaceholderText);
|
||||
auto *column = new QVBoxLayout;
|
||||
column->setSpacing(0);
|
||||
column->addLayout(top);
|
||||
column->addStretch();
|
||||
column->addSpacing(12);
|
||||
column->addLayout(fields);
|
||||
column->addSpacing(8);
|
||||
column->addWidget(hint);
|
||||
// A dialog covers the canvas: nothing to sample.
|
||||
if (!m_session.pickingForDialog()) {
|
||||
auto *hint = new QLabel(QStringLiteral("Click the canvas to sample"), this);
|
||||
hint->setObjectName(QStringLiteral("pickerHint"));
|
||||
QFont small = hint->font();
|
||||
small.setPixelSize(10);
|
||||
hint->setFont(small);
|
||||
hint->setForegroundRole(QPalette::PlaceholderText);
|
||||
column->addSpacing(8);
|
||||
column->addWidget(hint);
|
||||
}
|
||||
auto *side = new QWidget(this);
|
||||
side->setFixedSize(180, int(fieldSize));
|
||||
side->setLayout(column);
|
||||
|
||||
@@ -65,8 +65,12 @@ void FloatingPanel::show(const QString &title, QWidget *content, QWidget *dock)
|
||||
showDocked(title, content, *dock);
|
||||
return;
|
||||
}
|
||||
// A modal sheet blocks its window's panels, not its own.
|
||||
QWidget *parent = QApplication::activeModalWidget() ? QApplication::activeModalWidget() : m_owner.window();
|
||||
if (m_panel && m_panel->parentWidget() != parent)
|
||||
m_panel->setParent(parent, m_panel->windowFlags());
|
||||
if (!m_panel) {
|
||||
m_panel = new PanelWindow(*this, m_owner.window());
|
||||
m_panel = new PanelWindow(*this, parent);
|
||||
m_panel->setObjectName(m_name);
|
||||
}
|
||||
const bool wasVisible = m_panel->isVisible();
|
||||
|
||||
+25
-29
@@ -1,8 +1,7 @@
|
||||
#include "UI/JPEGExportSheet.h"
|
||||
#include "UI/KeyboardShortcuts.h"
|
||||
#include "UI/ByteCounts.h"
|
||||
#include "UI/ColorPaletteControls.h"
|
||||
#include <QColorDialog>
|
||||
#include "UI/ColorPickerSheet+Dialog.h"
|
||||
#include <QFutureWatcher>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
@@ -83,10 +82,12 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
JPEGExportSheet::JPEGExportSheet(ExportRaster raster, std::function<void(std::optional<QByteArray>)> finish, QWidget *parent)
|
||||
: QWidget(parent), m_raster(std::move(raster)), m_finish(std::move(finish)), m_wait(new QTimer(this)), m_preview(new Preview(this)),
|
||||
JPEGExportSheet::JPEGExportSheet(ExportRaster raster, EditorSession &session, std::function<void(std::optional<QByteArray>)> finish, QWidget *parent)
|
||||
: QWidget(parent), m_raster(std::move(raster)), m_session(session), m_finish(std::move(finish)), m_wait(new QTimer(this)), m_preview(new Preview(this)),
|
||||
m_spinner(new QProgressBar(m_preview)), m_quality(new QSlider(Qt::Horizontal, this)),
|
||||
m_percent(text(QString(), 13, QFont::Normal, QPalette::WindowText, this)), m_matteSwatch(new SwatchButton([this] { return PaletteColor{m_options.red, m_options.green, m_options.blue}; }, 3, 0, 0.5, this)),
|
||||
m_percent(text(QString(), 13, QFont::Normal, QPalette::WindowText, this)), m_matteSwatch(new DialogColorSwatch(
|
||||
QStringLiteral("JPEG Background"), [this] { return PaletteColor{m_options.red, m_options.green, m_options.blue}; },
|
||||
[this](const PaletteColor &matte) { setMatte(matte); }, session, this)),
|
||||
m_failure(text(QString(), 13, QFont::Normal, QPalette::BrightText, this)), m_bytes(text(QString(), 13, QFont::Normal, QPalette::WindowText, this)),
|
||||
m_note(text(QString(), 13, QFont::Normal, QPalette::PlaceholderText, this)), m_export(new QPushButton(QStringLiteral("Export…"), this))
|
||||
{
|
||||
@@ -122,13 +123,12 @@ JPEGExportSheet::JPEGExportSheet(ExportRaster raster, std::function<void(std::op
|
||||
quality->addWidget(m_percent);
|
||||
column->addLayout(quality);
|
||||
|
||||
// Swift's ColorPicker: its label and a well, no opacity.
|
||||
// Its label and the app's picker on a swatch.
|
||||
auto *matte = new QHBoxLayout;
|
||||
matte->setSpacing(8);
|
||||
matte->addWidget(new QLabel(QStringLiteral("Background for transparency"), this));
|
||||
m_matteSwatch->setObjectName(QStringLiteral("jpegMatte"));
|
||||
m_matteSwatch->setFixedSize(36, 18);
|
||||
m_matteSwatch->setAccessibleName(QStringLiteral("Background for transparency"));
|
||||
connect(m_matteSwatch, &QAbstractButton::clicked, this, &JPEGExportSheet::pickMatte);
|
||||
m_matteSwatch->setToolTip(QStringLiteral("Color that fills transparent areas"));
|
||||
matte->addWidget(m_matteSwatch);
|
||||
matte->addStretch(1);
|
||||
column->addLayout(matte);
|
||||
@@ -146,13 +146,17 @@ JPEGExportSheet::JPEGExportSheet(ExportRaster raster, std::function<void(std::op
|
||||
auto *cancel = new QPushButton(QStringLiteral("Cancel"), this);
|
||||
cancel->setObjectName(QStringLiteral("jpegCancel"));
|
||||
cancel->setAutoDefault(false);
|
||||
connect(cancel, &QPushButton::clicked, this, [this] { m_finish(std::nullopt); });
|
||||
connect(cancel, &QPushButton::clicked, this, [this] {
|
||||
DialogColorSwatch::closePicker(m_session);
|
||||
m_finish(std::nullopt);
|
||||
});
|
||||
m_export->setObjectName(QStringLiteral("jpegExport"));
|
||||
m_export->setDefault(true);
|
||||
// Swift's configuredNativeShortcut: Return and Escape, as remapped.
|
||||
NativeShortcut::bind(*this, m_export, cancel);
|
||||
// Export rests until a result is ready.
|
||||
connect(m_export, &QPushButton::clicked, this, [this] {
|
||||
DialogColorSwatch::closePicker(m_session);
|
||||
QSettings().setValue(qualityKey, m_options.quality);
|
||||
m_finish(m_result.value().data);
|
||||
});
|
||||
@@ -172,6 +176,7 @@ JPEGExportSheet::JPEGExportSheet(ExportRaster raster, std::function<void(std::op
|
||||
JPEGExportSheet::~JPEGExportSheet()
|
||||
{
|
||||
m_cancelled->store(true);
|
||||
DialogColorSwatch::closePicker(m_session);
|
||||
}
|
||||
|
||||
// Swift's task(id:): the last request stops; this waits 200 ms.
|
||||
@@ -215,26 +220,17 @@ void JPEGExportSheet::encode()
|
||||
}));
|
||||
}
|
||||
|
||||
// The desktop's colour dialog, SwiftUI's colour panel, without alpha.
|
||||
void JPEGExportSheet::pickMatte()
|
||||
void JPEGExportSheet::setMatte(const PaletteColor &matte)
|
||||
{
|
||||
auto *dialog = new QColorDialog(QColor::fromRgbF(float(m_options.red), float(m_options.green), float(m_options.blue)), this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->setWindowTitle(QStringLiteral("Background for transparency"));
|
||||
connect(dialog, &QColorDialog::colorSelected, this, [this](const QColor &picked) {
|
||||
const QColor srgb = picked.toRgb();
|
||||
JPEGOptions next = m_options;
|
||||
next.red = srgb.redF();
|
||||
next.green = srgb.greenF();
|
||||
next.blue = srgb.blueF();
|
||||
// Swift's onChange: the same colour asks nothing.
|
||||
if (next == m_options)
|
||||
return;
|
||||
m_options = next;
|
||||
m_matteSwatch->update();
|
||||
request();
|
||||
});
|
||||
dialog->open();
|
||||
JPEGOptions next = m_options;
|
||||
next.red = matte.red;
|
||||
next.green = matte.green;
|
||||
next.blue = matte.blue;
|
||||
// Equal options ask nothing, as Swift's task id.
|
||||
if (next == m_options)
|
||||
return;
|
||||
m_options = next;
|
||||
request();
|
||||
}
|
||||
|
||||
void JPEGExportSheet::synchronize()
|
||||
|
||||
@@ -12,7 +12,8 @@ class QProgressBar;
|
||||
class QPushButton;
|
||||
class QSlider;
|
||||
class QTimer;
|
||||
class SwatchButton;
|
||||
class DialogColorSwatch;
|
||||
class EditorSession;
|
||||
|
||||
// Swift's JPEGExportSheet: quality, matte and the encoded preview.
|
||||
class JPEGExportSheet : public QWidget {
|
||||
@@ -21,17 +22,18 @@ public:
|
||||
// The last export's quality, where the next one starts.
|
||||
static const QString qualityKey;
|
||||
|
||||
JPEGExportSheet(ExportRaster raster, std::function<void(std::optional<QByteArray>)> finish, QWidget *parent = nullptr);
|
||||
JPEGExportSheet(ExportRaster raster, EditorSession &session, std::function<void(std::optional<QByteArray>)> finish, QWidget *parent = nullptr);
|
||||
~JPEGExportSheet() override;
|
||||
|
||||
private:
|
||||
class Preview;
|
||||
void request();
|
||||
void encode();
|
||||
void pickMatte();
|
||||
void setMatte(const PaletteColor &matte);
|
||||
void synchronize();
|
||||
|
||||
const ExportRaster m_raster;
|
||||
EditorSession &m_session;
|
||||
const std::function<void(std::optional<QByteArray>)> m_finish;
|
||||
JPEGOptions m_options;
|
||||
std::optional<JPEGResult> m_result;
|
||||
@@ -44,7 +46,7 @@ private:
|
||||
QProgressBar *const m_spinner;
|
||||
QSlider *const m_quality;
|
||||
QLabel *const m_percent;
|
||||
SwatchButton *const m_matteSwatch;
|
||||
DialogColorSwatch *const m_matteSwatch;
|
||||
QLabel *const m_failure;
|
||||
QLabel *const m_bytes;
|
||||
QLabel *const m_note;
|
||||
|
||||
Reference in new issue
Block a user