# Conflicts:
#	crates/engine/src/cmd/develop.rs
#	crates/engine/src/files.rs
#	docs/mcp.md
#	docs/parity-checklist.md
#	docs/whats-new.md
This commit is contained in:
Claude
2026-10-11 12:02:46 +00:00
37 changed files with 1009 additions and 93 deletions
+27 -10
View File
@@ -181,9 +181,12 @@ pub fn specs() -> Vec<CommandSpec> {
let angle = vals.iter().any(|(k, _)| k == CROP_ANGLE);
let apply = |d: &mut DevelopSettings, info: &lightcraft_pipeline::SourceInfo, dims: (f64, f64)| {
let before = d.crop.geometry;
if d.wb.mode == WbMode::AsShot && vals.iter().any(|(k, _)| k == "wb.temp" || k == "wb.tint") {
d.wb.temp = info.as_shot_temp;
d.wb.tint = info.as_shot_tint;
if vals.iter().any(|(k, _)| k == "wb.temp" || k == "wb.tint") {
lightcraft_pipeline::local::normalize_wb(d, info);
if d.wb.mode == WbMode::AsShot {
d.wb.temp = info.as_shot_temp;
d.wb.tint = info.as_shot_tint;
}
}
for (k, v) in &vals {
controls::set(d, k, *v);
@@ -226,6 +229,7 @@ pub fn specs() -> Vec<CommandSpec> {
edit(s, "develop.adjust", spec.label, |d| {
let before = d.crop.geometry;
if c == "wb.temp" || c == "wb.tint" {
lightcraft_pipeline::local::normalize_wb(d, &info);
if d.wb.mode == WbMode::AsShot {
d.wb.temp = info.as_shot_temp;
d.wb.tint = info.as_shot_tint;
@@ -262,10 +266,17 @@ pub fn specs() -> Vec<CommandSpec> {
// of its current as-shot reference
let info = s.source_info(id);
let defaults = s.catalog.photo(id).map(|p| p.camera_defaults()).unwrap_or_default();
DevelopSettings {
wb: lightcraft_develop::WhiteBalance { mode: WbMode::AsShot, temp: info.as_shot_temp, tint: info.as_shot_tint },
let mut fresh = DevelopSettings {
wb: lightcraft_develop::WhiteBalance {
mode: WbMode::AsShot,
temp: info.as_shot_temp,
tint: info.as_shot_tint,
..Default::default()
},
..defaults
}
};
lightcraft_pipeline::local::normalize_wb(&mut fresh, &info);
fresh
}
};
// a fresh start renders with the current process (a section or slider reset doesn't change it)
@@ -402,7 +413,7 @@ pub fn specs() -> Vec<CommandSpec> {
m => m
.preset()
.map(|(t, ti)| {
// presets are relative to daylight for rendered files
// presets are Kelvin on raws with that scale, relative to daylight (6500 K = as shot) elsewhere
if info.raw && !info.relative_wb { (t, ti) } else { (6500.0 * t / 5500.0, ti) }
})
.unwrap_or((info.as_shot_temp, info.as_shot_tint)),
@@ -412,6 +423,7 @@ pub fn specs() -> Vec<CommandSpec> {
// The resolved temperature/tint is stored, so rendering never depends on the mode; the
// mode is kept for the UI's WB dropdown.
edit(s, "develop.wb", "White Balance", |d| {
lightcraft_pipeline::local::normalize_wb(d, &info);
d.wb.mode = mode;
d.wb.temp = t.clamp(2000.0, 50000.0);
d.wb.tint = tint.clamp(-150.0, 150.0);
@@ -441,6 +453,7 @@ pub fn specs() -> Vec<CommandSpec> {
let patch = lightcraft_raster::Rgb32f::filled(4, 4, acc);
let (t, tint) = lightcraft_pipeline::auto::auto_wb(&patch, &info);
edit(s, "develop.wbPick", "White Balance", |d| {
lightcraft_pipeline::local::normalize_wb(d, &info);
d.wb.mode = WbMode::Custom;
d.wb.temp = t;
d.wb.tint = tint;
@@ -873,10 +886,14 @@ pub fn specs() -> Vec<CommandSpec> {
.filter_map(|id| s.develop_of(id).map(|d| (id, d)))
.filter_map(|(id, d)| {
let mut nd = (*d).clone();
if nd.wb.mode == WbMode::AsShot && (ctl == "wb.temp" || ctl == "wb.tint") {
if ctl == "wb.temp" || ctl == "wb.tint" {
// each photo on its own scale: Kelvin (an old relative value converted first) or relative
let info = s.source_info(id);
nd.wb.temp = info.as_shot_temp;
nd.wb.tint = info.as_shot_tint;
lightcraft_pipeline::local::normalize_wb(&mut nd, &info);
if nd.wb.mode == WbMode::AsShot {
nd.wb.temp = info.as_shot_temp;
nd.wb.tint = info.as_shot_tint;
}
}
let before = nd.crop.geometry;
let v = controls::get(&nd, &ctl).unwrap_or(spec.default);