mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-11 00:11:46 +00:00
Merge pull request #12334 from rmsff/fix/vertical-type-history-name-12058
fix(engine): new vertical text is the history state "New Vertical Type Layer" (#12058)
This commit is contained in:
2 files changed
+79
-2
No files matched your search
@@ -953,7 +953,8 @@ pub(crate) fn new_text_layer(s: &Session, p: &Value, cmd: &str) -> Result<TextLa
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
/// The name of the history state a new type layer makes: what `type.create` records, and what the
|
||||
/// The name of the history state a new horizontal type layer makes: what `type.create` records
|
||||
/// (vertical text is "New Vertical Type Layer", #12058), and what the
|
||||
/// Type tool's commit keeps in the modes [`commits_as_selection`] names (#12041).
|
||||
pub const NEW_TYPE_LAYER_LABEL: &str = "New Type Layer";
|
||||
|
||||
@@ -1020,7 +1021,9 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
let mut t = new_text_layer(s, p, "type.create")?;
|
||||
let given = p.get("name").and_then(Value::as_str).map(str::to_string);
|
||||
let name = given.clone().unwrap_or_else(|| layer_name(&t.text));
|
||||
let id = s.edit(NEW_TYPE_LAYER_LABEL, |doc, active| {
|
||||
// The reference application names new vertical text after its tool (#12058).
|
||||
let label = if t.orientation == Orientation::Vertical { "New Vertical Type Layer" } else { NEW_TYPE_LAYER_LABEL };
|
||||
let id = s.edit(label, |doc, active| {
|
||||
refresh(doc, &mut t);
|
||||
let id = crate::layer_place::insert_new(doc, *active, Layer::new(name, LayerContent::Text(t)), crate::layer_place::Place::AutoEditable);
|
||||
*active = Some(id);
|
||||
@@ -1306,3 +1309,6 @@ fn step_size(s: &mut Session, p: &Value, up: bool, default_by: f32) -> Result<Va
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
#[cfg(test)]
|
||||
#[path = "type_vertical_history_name_tests.rs"]
|
||||
mod vertical_history_name_tests;
|
||||
@@ -0,0 +1,71 @@
|
||||
//! #12058: new vertical text is the history state "New Vertical Type Layer", point and paragraph
|
||||
//! text alike; horizontal text stays "New Type Layer", and a committed Type Mask session, vertical
|
||||
//! or not, still leaves one "Type Mask" state.
|
||||
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::Session;
|
||||
|
||||
fn session() -> Session {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", json!({"width": 300, "height": 300})).unwrap();
|
||||
s
|
||||
}
|
||||
|
||||
fn entries(s: &Session) -> Vec<String> {
|
||||
s.active().unwrap().history.entries()
|
||||
}
|
||||
|
||||
/// The history states `type.create` adds with `params`, and the layer it makes.
|
||||
fn create(params: Value) -> (Vec<String>, u64) {
|
||||
let mut s = session();
|
||||
let before = entries(&s).len();
|
||||
let layer = s.execute("type.create", params).unwrap()["layer"].as_u64().unwrap();
|
||||
(entries(&s)[before..].to_vec(), layer)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vertical_text_is_a_new_vertical_type_layer() {
|
||||
for (what, params) in [
|
||||
("point", json!({"text": "AB", "x": 150, "y": 40, "orientation": "vertical"})),
|
||||
("paragraph", json!({"text": "AB", "box": [100, 20, 60, 200], "orientation": "vertical"})),
|
||||
] {
|
||||
assert_eq!(create(params).0, ["New Vertical Type Layer"], "{what}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn horizontal_text_is_still_a_new_type_layer() {
|
||||
for (what, params) in [
|
||||
("point", json!({"text": "AB", "x": 40, "y": 120})),
|
||||
("point, horizontal", json!({"text": "AB", "x": 40, "y": 120, "orientation": "horizontal"})),
|
||||
("paragraph", json!({"text": "AB", "box": [20, 20, 200, 60]})),
|
||||
("paragraph, horizontal", json!({"text": "AB", "box": [20, 20, 200, 60], "orientation": "horizontal"})),
|
||||
] {
|
||||
assert_eq!(create(params).0, ["New Type Layer"], "{what}");
|
||||
}
|
||||
}
|
||||
|
||||
/// The Type Mask tools' commands: a hidden working layer from `type.create`, then
|
||||
/// `type.createSelection` removing it, all coalesced into the session's one step.
|
||||
#[test]
|
||||
fn a_type_mask_session_is_still_one_type_mask_state() {
|
||||
for orientation in ["horizontal", "vertical"] {
|
||||
let mut s = session();
|
||||
let before = entries(&s).len();
|
||||
let key = json!("type-mask-session");
|
||||
let created = json!({"text": "", "x": 150, "y": 40, "orientation": orientation, "coalesce": key});
|
||||
let layer = s.execute("type.create", created).unwrap()["layer"].as_u64().unwrap();
|
||||
s.execute("layer.setProps", json!({"layer": layer, "visible": false, "coalesce": key})).unwrap();
|
||||
s.execute("type.edit", json!({"layer": layer, "text": "AB", "coalesce": key})).unwrap();
|
||||
s.execute("type.createSelection", json!({"layer": layer, "removeLayer": true, "coalesce": key})).unwrap();
|
||||
assert_eq!(entries(&s)[before..], ["Type Mask"], "{orientation}");
|
||||
}
|
||||
// Without a layer, `type.createSelection` makes its text itself: the same one state.
|
||||
for orientation in ["horizontal", "vertical"] {
|
||||
let mut s = session();
|
||||
let before = entries(&s).len();
|
||||
s.execute("type.createSelection", json!({"text": "AB", "x": 150, "y": 40, "size": 48, "orientation": orientation})).unwrap();
|
||||
assert_eq!(entries(&s)[before..], ["Type Mask"], "{orientation}, no layer");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user