Open Recent, print sizes through an invalid resolution, Color Grading under Color (12.14b)

This commit is contained in:
雷电芽衣 committed 2026-09-30 01:43:23 -04:00
1 parent 94b884a2ef
commit 2183348aa6
21 files changed
+717 -38

No files matched your search

+12 -12
View File
@@ -21,9 +21,9 @@
namespace {
QString title(int section)
{
static const std::array<QString, 10> titles{QStringLiteral("Light"), QStringLiteral("Color"), QStringLiteral("Effects"),
QStringLiteral("Curve"), QStringLiteral("Color Mixer"), QStringLiteral("Color Grading"),
QStringLiteral("Detail"), QStringLiteral("Optics"), QStringLiteral("Geometry"),
static const std::array<QString, 10> titles{QStringLiteral("Light"), QStringLiteral("Color"), QStringLiteral("Color Grading"),
QStringLiteral("Effects"), QStringLiteral("Curve"), QStringLiteral("Color Mixer"),
QStringLiteral("Detail"), QStringLiteral("Optics"), QStringLiteral("Geometry"),
QStringLiteral("Calibration")};
return titles.at(size_t(section));
}
@@ -31,8 +31,8 @@ QString title(int section)
// The group's eye in CameraRawGroups, by section.
bool &shows(CameraRawGroups &groups, int section)
{
const std::array fields{&CameraRawGroups::light, &CameraRawGroups::color, &CameraRawGroups::effects, &CameraRawGroups::curve,
&CameraRawGroups::mixer, &CameraRawGroups::grading, &CameraRawGroups::detail, &CameraRawGroups::optics,
const std::array fields{&CameraRawGroups::light, &CameraRawGroups::color, &CameraRawGroups::grading, &CameraRawGroups::effects,
&CameraRawGroups::curve, &CameraRawGroups::mixer, &CameraRawGroups::detail, &CameraRawGroups::optics,
&CameraRawGroups::geometry, &CameraRawGroups::calibration};
return groups.*fields.at(size_t(section));
}
@@ -42,10 +42,10 @@ bool adjusts(const CameraRawSettings &raw, int section)
switch (section) {
case 0: return raw.adjustsLight();
case 1: return raw.adjustsColor();
case 2: return raw.adjustsEffects();
case 3: return raw.curve.adjusts();
case 4: return raw.mixer.adjusts();
case 5: return raw.grading.adjusts();
case 2: return raw.grading.adjusts();
case 3: return raw.adjustsEffects();
case 4: return raw.curve.adjusts();
case 5: return raw.mixer.adjusts();
case 6: return raw.detail.adjusts();
case 7: return raw.optics.adjusts();
case 8: return raw.geometry.adjusts();
@@ -194,10 +194,10 @@ CameraRawControls::CameraRawControls(EditorSession &session, QWidget *parent)
groups->setSpacing(12);
light(group(Section::light, groups));
color(group(Section::color, groups));
group(Section::colorGrading, groups)->addWidget(new CameraRawGradingControls(session));
effects(group(Section::effects, groups));
group(Section::curve, groups)->addWidget(new CameraRawCurveControls(session));
group(Section::colorMixer, groups)->addWidget(new CameraRawMixerControls(session));
group(Section::colorGrading, groups)->addWidget(new CameraRawGradingControls(session));
group(Section::detail, groups)->addWidget(new CameraRawDetailControls(session));
group(Section::optics, groups)->addWidget(new CameraRawOpticsControls(session));
group(Section::geometry, groups)->addWidget(new CameraRawGeometryControls(session));
@@ -246,8 +246,8 @@ QVBoxLayout *CameraRawControls::group(Section section, QVBoxLayout *column)
auto *rows = new QVBoxLayout(body);
rows->setContentsMargins(18, 0, 0, 0);
rows->setSpacing(8);
// Light and Color open first, Swift's `expanded`.
body->setVisible(section == Section::light || section == Section::color);
// Light, Color and Color Grading open first, Swift's `expanded`.
body->setVisible(section == Section::light || section == Section::color || section == Section::colorGrading);
connect(disclosure, &QToolButton::clicked, this, [this, body] {
body->setVisible(body->isHidden());
synchronize();
+1 -1
View File
@@ -23,7 +23,7 @@ protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
enum class Section { light, color, effects, curve, colorMixer, colorGrading, detail, optics, geometry, calibration };
enum class Section { light, color, colorGrading, effects, curve, colorMixer, detail, optics, geometry, calibration };
struct Group {
Section section;
QToolButton *disclosure;
+19
View File
@@ -1,4 +1,5 @@
#include "UI/CompositorMenus.h"
#include "IO/RecentProjects.h"
#include "Logging.h"
#include "UI/KeyboardShortcuts.h"
#include "UI/NativeLayerList.h"
@@ -37,6 +38,10 @@ CompositorMenus::CompositorMenus(ProjectWorkspace &workspace, QMenuBar &bar, QWi
QMenu *file = bar.addMenu(QStringLiteral("&File"));
add(file, QStringLiteral("newCanvas"), QStringLiteral("New Canvas…"), QKeySequence(Qt::CTRL | Qt::Key_N), [this] { projects().newCanvas(); });
add(file, QStringLiteral("openProject"), QStringLiteral("Open Project…"), QKeySequence(Qt::CTRL | Qt::Key_O), [this] { projects().open(); });
QMenu *recent = file->addMenu(QStringLiteral("Open Recent"));
recent->menuAction()->setObjectName(QStringLiteral("openRecent"));
listRecent(recent);
connect(&RecentProjects::shared(), &RecentProjects::changed, this, [this, recent] { listRecent(recent); });
add(file, QStringLiteral("importImages"), QStringLiteral("Import Images…"), QKeySequence(), [this] { session().setShowsImporter(true); });
file->addSeparator();
add(file, QStringLiteral("save"), QStringLiteral("Save"), QKeySequence(Qt::CTRL | Qt::Key_S), [this] { projects().save(); });
@@ -272,6 +277,19 @@ CompositorMenus::CompositorMenus(ProjectWorkspace &workspace, QMenuBar &bar, QWi
watchFront();
}
void CompositorMenus::listRecent(QMenu *recent)
{
recent->clear();
for (const QString &path : RecentProjects::shared().paths())
// A name's ampersand is literal, no mnemonic.
connect(recent->addAction(ProjectTab::nameWithoutSuffix(path).replace(QLatin1Char('&'), QStringLiteral("&&"))), &QAction::triggered, this, [this, path] { projects().open(path); });
recent->addSeparator();
QAction *clear = recent->addAction(QStringLiteral("Clear Menu"));
clear->setObjectName(QStringLiteral("clearRecent"));
clear->setEnabled(!RecentProjects::shared().paths().isEmpty());
connect(clear, &QAction::triggered, this, [] { RecentProjects::shared().clear(); });
}
QAction *CompositorMenus::add(QMenu *menu, const QString &name, const QString &text, const QKeySequence &shortcut, const std::function<void()> &run)
{
QAction *made = menu->addAction(text);
@@ -327,6 +345,7 @@ void CompositorMenus::synchronize()
const bool typing = m_field != nullptr || s.textDraft().has_value();
action(QStringLiteral("newCanvas"))->setEnabled(p.canStart());
action(QStringLiteral("openProject"))->setEnabled(p.canStart());
action(QStringLiteral("openRecent"))->setEnabled(p.canStart());
action(QStringLiteral("importImages"))->setEnabled(!s.levels() && !s.showsBusy() && !s.isImporting() && !s.showsNewDocument());
action(QStringLiteral("save"))->setEnabled(drawn && p.canStart());
action(QStringLiteral("saveAs"))->setEnabled(drawn && p.canStart());
+1
View File
@@ -23,6 +23,7 @@ private:
void watchFront();
EditorSession &session() const { return m_workspace.current().session; }
ProjectController &projects() const { return m_workspace.current().controller; }
void listRecent(QMenu *recent);
QAction *add(QMenu *menu, const QString &name, const QString &text, const QKeySequence &shortcut, const std::function<void()> &run);
// Each entry's own key, remapped from ShortcutSettings.
+12 -7
View File
@@ -49,7 +49,7 @@ bool physical(const QString &unit)
ImageSizeSheet::ImageSizeSheet(const CanvasDocument &document, std::function<void(std::optional<ImageSizeOptions>)> finish, QWidget *parent)
: QWidget(parent), m_originalWidth(document.width), m_originalHeight(document.height), m_finish(std::move(finish)),
m_width(double(document.width)), m_height(double(document.height)), m_resolution(document.resolution), m_units(new QComboBox(this)),
m_width(double(document.width)), m_height(double(document.height)), m_resolution(document.resolution), m_lastResolution(document.resolution), m_units(new QComboBox(this)),
m_widthField(dimension(true)), m_heightField(dimension(false)), m_lock(new QCheckBox(QStringLiteral("Lock aspect ratio"), this)),
m_resolutionField(new PickerField([this] {
bool number = false;
@@ -204,10 +204,11 @@ PickerField *ImageSizeSheet::dimension(bool isWidth)
// Swift's binding: pixels, or without resampling the resolution.
void ImageSizeSheet::setDimension(double value, bool isWidth)
{
if (!(std::isfinite(value) && value > 0))
// A print size means nothing without a usable resolution.
if (!(std::isfinite(value) && value > 0) || !canScrubDimensions())
return;
if (!m_resample) {
m_resolution = (isWidth ? m_width : m_height) / value * (m_unit == QLatin1String("Centimeters") ? 2.54 : 1);
setResolution((isWidth ? m_width : m_height) / value * (m_unit == QLatin1String("Centimeters") ? 2.54 : 1));
return;
}
double pixels = value;
@@ -230,11 +231,15 @@ void ImageSizeSheet::setDimension(double value, bool isWidth)
void ImageSizeSheet::setResolution(double value)
{
const double old = std::exchange(m_resolution, value);
if (m_resample && physical(m_unit) && old > 0 && value > 0 && std::isfinite(value)) {
m_width *= value / old;
m_height *= value / old;
m_resolution = value;
if (!(std::isfinite(value) && value > 0))
return;
// Scaled from the last usable one, past any invalid entry.
if (m_resample && physical(m_unit)) {
m_width *= value / m_lastResolution;
m_height *= value / m_lastResolution;
}
m_lastResolution = value;
}
NumericScrub *ImageSizeSheet::scrub(QLabel *title, bool isWidth)
+1
View File
@@ -39,6 +39,7 @@ private:
double m_width;
double m_height;
double m_resolution;
double m_lastResolution;
bool m_locked = true;
bool m_resample = true;
QString m_unit = QStringLiteral("Pixels");