LR-CROP-STRAIGHTEN: the Angle field writes a turned angle with its sign

The readout and the slider said "+2.50" where the field said "2.50";
it now writes the angle through crop_angle_label too. The test that
said the readout's "0.00°" matched the slider at rest (it shows "0")
says what it does match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nathaniel Ledford 2026-10-09 12:07:59 -04:00
parent b26bb3fa93
commit 9453085cef
No known key found for this signature in database
3 changed files with 18 additions and 2 deletions

View File

@ -1348,7 +1348,8 @@ fn crop_overlay(app: &mut LightcraftApp, ui: &mut egui::Ui, resp: &egui::Respons
pub(crate) fn crop_angle_label(angle: f64) -> String {
let shown =
lightcraft_develop::controls::find("crop.angle").map_or_else(|| format!("{angle:.2}"), |spec| crate::widgets::shown_value(spec, angle));
// the slider's format turns a rounded −0.00 into "0": every zero reads as the slider at rest
// the slider's format turns a rounded −0.00 into "0": every zero reads "0.00", the angle's
// usual two decimals
let shown = if shown == "0" { "0.00".to_string() } else { shown };
format!("{shown}°")
}

View File

@ -197,6 +197,8 @@ fn crop(app: &mut LightcraftApp, ui: &mut egui::Ui, id: PhotoId) {
.clamp_existing_to_range(false)
.speed(0.05)
.fixed_decimals(2)
// as the readout writes it: "+2.50", and every zero "0.00"
.custom_formatter(|v, _| super::detail::crop_angle_label(v).trim_end_matches('°').to_string())
.suffix("°")
// read as the Straighten value reads a typed one: "-3,25" too
.custom_parser(|text| crate::widgets::typed_value(&spec, text.trim().trim_end_matches('°')))

View File

@ -94,7 +94,7 @@ fn the_straighten_value_takes_an_exact_angle() {
#[test]
fn the_angle_reads_like_the_straighten_value() {
use crate::panels::detail::crop_angle_label;
assert_eq!(crop_angle_label(0.0), "0.00°", "as the slider shows it at rest");
assert_eq!(crop_angle_label(0.0), "0.00°", "as the Angle field shows it at rest");
assert_eq!(crop_angle_label(2.5), "+2.50°");
assert_eq!(crop_angle_label(-12.254), "-12.25°");
assert_eq!(crop_angle_label(-0.001), "0.00°", "no minus zero, and every zero the same");
@ -351,3 +351,16 @@ fn the_angle_field_reads_angles_as_people_type_them() {
assert!((angle(&h) - want).abs() < 1e-9, "{typed:?}: want {want}, got {}", angle(&h));
}
}
/// The Angle field writes an angle as the readout does: a sign on a turned angle.
#[test]
fn the_angle_field_writes_the_angle_like_the_readout() {
let mut h = crop_tool();
let r = h.request("engine.execute", json!({"command": "crop.straighten", "params": {"angle": 2.5}}), T);
assert_eq!(r["ok"], true, "{r}");
h.settle(SETTLE);
let texts = h.painted_text();
// the field's number follows its label (its "°" is painted on its own)
let field = texts.iter().position(|t| t == "Angle").and_then(|i| texts.get(i + 1));
assert_eq!(field.map(String::as_str), Some("+2.50"), "{texts:?}");
}