mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-28 20:36:55 -06:00
Merge fix/666
This commit is contained in:
@@ -332,7 +332,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
spec!(
|
||||
"text.preview",
|
||||
"Preview text change",
|
||||
"{command: style.apply|library.applyStyle|text.setVariations|text.style, params} shows what the command would do on the canvas without an undo step (a hovered text style or named instance, a dragged axis slider), in place of an earlier preview; text.endPreview or any other command ends it, so running the command for real commits it as one undo step",
|
||||
"{command: style.apply|library.applyStyle|text.setVariations|text.style, params} shows what the command would do on the canvas without an undo step (a hovered font family or style, text style or named instance, a dragged axis slider), in place of an earlier preview; text.endPreview or any other command ends it, so running the command for real commits it as one undo step",
|
||||
false,
|
||||
|s, p| {
|
||||
let c = req_string("text.preview", p, "command")?;
|
||||
|
||||
@@ -357,8 +357,8 @@ pub struct DocState {
|
||||
versions_changed: bool,
|
||||
/// A version shown in place of the document (read-only).
|
||||
pub preview: Option<VersionPreview>,
|
||||
/// The document under a live text preview (a hovered text style or font instance, a dragged
|
||||
/// axis slider): `doc` shows the preview until [`textpreview::end`] puts this back.
|
||||
/// The document under a live text preview (a hovered font family or style, text style or
|
||||
/// font instance, a dragged axis slider): `doc` shows the preview until [`textpreview::end`] puts this back.
|
||||
pub text_preview: Option<Arc<Document>>,
|
||||
/// The document as of the last version saved or restored (none yet): autosaves, restores and
|
||||
/// merges only add a checkpoint for changes since.
|
||||
|
||||
@@ -212,6 +212,31 @@ fn previews_while_editing_keep_the_edit() {
|
||||
assert!(links(&s, t).iter().all(Option::is_none));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn previews_show_a_hovered_font_family() {
|
||||
let mut s = new_session();
|
||||
let t = text(&mut s, "Preview me");
|
||||
s.ds_mut().unwrap().mark_saved();
|
||||
let before = s.doc().unwrap().clone();
|
||||
let undo = s.ds().unwrap().history.undo.len();
|
||||
// Hovering a font family shows it on the canvas: no undo step, not dirty.
|
||||
s.execute("text.preview", &json!({"command": "text.style", "params": {"ids": [t], "fontFamily": "Arial"}})).unwrap();
|
||||
assert_eq!(data(&s, t).style_at(0).font_family, "Arial");
|
||||
assert_eq!(s.ds().unwrap().history.undo.len(), undo);
|
||||
assert!(!s.ds().unwrap().is_dirty());
|
||||
// Moving to another family replaces the preview, from the document itself.
|
||||
s.execute("text.preview", &json!({"command": "text.style", "params": {"ids": [t], "fontFamily": "Georgia"}})).unwrap();
|
||||
assert_eq!(data(&s, t).style_at(0).font_family, "Georgia");
|
||||
// Closing without picking puts the document back as it was.
|
||||
assert_eq!(s.execute("text.endPreview", &json!({})).unwrap()["ended"], json!(true));
|
||||
assert_eq!(*s.doc().unwrap(), before);
|
||||
// Clicking commits it as one undo step.
|
||||
s.execute("text.style", &json!({"ids": [t], "fontFamily": "Georgia"})).unwrap();
|
||||
assert_eq!(data(&s, t).style_at(0).font_family, "Georgia");
|
||||
assert_eq!(s.ds().unwrap().history.undo.len(), undo + 1);
|
||||
assert!(s.ds().unwrap().text_preview.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn previews_refuse_what_they_cant_show() {
|
||||
let mut s = new_session();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Live text previews: what a text command would do, shown on the canvas without an undo step —
|
||||
//! while the pointer is over a text style in the style browser or a font's named instance, or
|
||||
//! while a variable font axis slider is dragged. The document under the preview is kept and comes
|
||||
//! while the pointer is over a font family or style, a text style in the style browser or a
|
||||
//! font's named instance, or while a variable font axis slider is dragged. The document under the preview is kept and comes
|
||||
//! back when the preview ends ([`end`], `text.endPreview`). Every other command ends it first, so
|
||||
//! committing (running the command for real) applies to the document itself as one undo step, and
|
||||
//! Escape just ends the preview.
|
||||
|
||||
@@ -719,7 +719,7 @@ impl FigApp {
|
||||
}
|
||||
|
||||
/// Show what `command params` would do on the canvas as a live preview (`text.preview`) while
|
||||
/// a text style, a named instance or an axis slider is hovered or dragged. Call it every frame
|
||||
/// a font family, font style, text style, named instance or axis slider is hovered or dragged. Call it every frame
|
||||
/// the preview should stay: it ends on the first frame nothing asks for it.
|
||||
pub fn preview_text(&mut self, ctx: &egui::Context, command: &str, params: Value) {
|
||||
self.ui.text_preview_wanted = true;
|
||||
|
||||
@@ -186,9 +186,10 @@ fn font_rows(app: &mut FigApp, ui: &mut Ui, ids: &[NodeId], styles: &[TextStyle]
|
||||
remember_family(ui.ctx(), &f);
|
||||
apply_style(app, "fontFamily", json!(f));
|
||||
ui.close();
|
||||
} else if let Some(f) = pick.highlighted {
|
||||
// The canvas shows the family the arrow keys are on.
|
||||
app.preview_text(ui.ctx(), "text.style", text_style_params(ids, range, json!({"fontFamily": f})));
|
||||
} else if let Some(h) = pick.hovered.or(pick.highlighted) {
|
||||
// The canvas shows the hovered family (or the one the arrow keys are on);
|
||||
// closing without picking ends the preview.
|
||||
app.preview_text(ui.ctx(), "text.style", text_style_params(ids, range, json!({"fontFamily": h})));
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1161,9 +1162,12 @@ pub(crate) struct FontPick {
|
||||
pub picked: Option<String>,
|
||||
/// The family Up and Down are on (Enter picks it).
|
||||
pub highlighted: Option<String>,
|
||||
/// The family the pointer is over (the caller previews it on the canvas).
|
||||
pub hovered: Option<String>,
|
||||
}
|
||||
|
||||
/// The searchable family list: click a family, or step through it with Up and Down and press Enter.
|
||||
/// Hovering a family previews it on the canvas (closing without picking restores the original).
|
||||
pub(crate) fn font_picker(ui: &mut Ui, current: Option<&str>, just_opened: bool) -> FontPick {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let q_id = Id::new("font_query");
|
||||
@@ -1248,10 +1252,11 @@ pub(crate) fn font_picker(ui: &mut Ui, current: Option<&str>, just_opened: bool)
|
||||
PickRow::Family(f) => Some(f.clone()),
|
||||
PickRow::Header(_) => None,
|
||||
});
|
||||
return FontPick { picked: hi.and_then(family).or(first), highlighted: None };
|
||||
return FontPick { picked: hi.and_then(family).or(first), highlighted: None, hovered: None };
|
||||
}
|
||||
let mut budget = 4;
|
||||
let mut picked = None;
|
||||
let mut hovered_family = None;
|
||||
let mut area = egui::ScrollArea::vertical().max_height(LIST_HEIGHT).auto_shrink([false, true]);
|
||||
if let Some(y) = offset {
|
||||
area = area.vertical_scroll_offset(y);
|
||||
@@ -1297,12 +1302,15 @@ pub(crate) fn font_picker(ui: &mut Ui, current: Option<&str>, just_opened: bool)
|
||||
if resp.clicked() {
|
||||
picked = Some(f.clone());
|
||||
}
|
||||
if resp.hovered() {
|
||||
hovered_family = Some(f.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.data_mut(|d| d.insert_temp(hi_id.with("view"), (shown.state.offset.y, shown.inner_rect.height())));
|
||||
FontPick { highlighted: hi.and_then(family), picked }
|
||||
FontPick { highlighted: hi.and_then(family), picked, hovered: hovered_family }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user