mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-11 16:30:12 -06:00
Dev Mode review fixes: slot imports keep the slot's depth base, Shift-click deselects, a comment link pastes, Enter on a drawing tool returns to the design, formal German
This commit is contained in:
@@ -166,7 +166,8 @@ fn call_imports(doc: &Document, id: NodeId, lang: CodeLang, depth: usize, out: &
|
||||
&& v.as_bool() == Some(true)
|
||||
&& let Some((slot, _)) = slots.iter().find(|(_, name)| *name == p.prop)
|
||||
{
|
||||
tree(&Ctx::new(doc, *slot), *slot, lang, depth + 1, out);
|
||||
// The same depth base as the slot's generated content, so its connected children count.
|
||||
tree(&Ctx { doc, root: *slot, comp: None, base: depth }, *slot, lang, depth + 1, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1228,8 +1228,11 @@ impl Session {
|
||||
vec![target]
|
||||
};
|
||||
self.set_selection(new_sel.clone());
|
||||
// Dev Mode only selects: nothing moves.
|
||||
// Dev Mode only selects (Shift-click still deselects): nothing moves.
|
||||
if !edits {
|
||||
if deselect.is_some() {
|
||||
self.set_selection(without_target());
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
// Locked layers selected in the layers panel stay put.
|
||||
|
||||
@@ -372,7 +372,7 @@ status = "draft — needs native review"
|
||||
"Detach variable" = "Variable lösen"
|
||||
"Details" = "Details"
|
||||
"Dev Mode" = "Entwicklermodus"
|
||||
"Dev Mode only inspects: switch to Design (Shift+D) to edit" = "Der Entwicklermodus prüft nur: wechsle zu Design (Shift+D), um zu bearbeiten"
|
||||
"Dev Mode only inspects: switch to Design (Shift+D) to edit" = "Der Entwicklermodus prüft nur: Wechseln Sie zu Design (Shift+D), um zu bearbeiten"
|
||||
"Dev resources" = "Entwicklerressourcen"
|
||||
"Development" = "Entwicklung"
|
||||
"Device" = "Gerät"
|
||||
|
||||
@@ -85,3 +85,26 @@ fn read_only_plugins_run_from_the_inspect_tab_show_their_panel() {
|
||||
assert!(u.app.session.execute("plugin.event", &json!({"id": "org.test.inspect", "control": "go"})).is_err());
|
||||
assert_eq!(layers(&u), before);
|
||||
}
|
||||
|
||||
/// A clipboard holding only text.
|
||||
struct TextClip(String);
|
||||
|
||||
impl crate::Services for TextClip {
|
||||
fn clipboard_get_text(&mut self) -> Option<String> {
|
||||
Some(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dev_mode_pastes_only_a_comments_link() {
|
||||
let mut s = Session::new();
|
||||
let c = s.execute("comment.add", &json!({"x": 10, "y": 10, "text": "Check the spacing"})).unwrap()["id"].as_u64().unwrap();
|
||||
let layers = |app: &crate::FigApp| app.session.doc().unwrap().node(app.session.page().unwrap()).unwrap().children.len();
|
||||
let mut app = crate::FigApp::new(s, Box::new(TextClip("Pasted words".into())));
|
||||
app.ui.right_tab = crate::RightTab::Inspect;
|
||||
crate::menus::paste(&mut app, None, None);
|
||||
assert_eq!(layers(&app), 0, "text doesn't paste into the design in Dev Mode");
|
||||
app.services = Box::new(TextClip(format!("figcraft://comment/{c}")));
|
||||
crate::menus::paste(&mut app, None, None);
|
||||
assert_eq!(app.ui.comments.open, Some(c), "the link opens its thread");
|
||||
}
|
||||
|
||||
@@ -35,12 +35,13 @@ pub const UI_COMMANDS: &[&str] = &[
|
||||
/// `event_text` is the text the platform handed over with the paste event (the browser has no
|
||||
/// other way to read it). `at`: the page point to paste at (Paste here); `None` pastes in the
|
||||
/// middle of the view.
|
||||
/// In Dev Mode only a comment's link pastes (it opens the thread); everything else would edit.
|
||||
pub fn paste(app: &mut FigApp, event_text: Option<&str>, at: Option<(f64, f64)>) {
|
||||
if dev_mode_refuses(app, "edit.paste") {
|
||||
return;
|
||||
}
|
||||
// Only HTML that holds readable design data takes this path; other HTML pastes as before.
|
||||
if let Some(html) = app.services.clipboard_get_html().filter(|h| figcraft_engine::cmd::edit::design_clipboard_buffer(h).is_some()) {
|
||||
if dev_mode_refuses(app, "edit.paste") {
|
||||
return;
|
||||
}
|
||||
let mut params = json!({"html": html});
|
||||
if let Some((x, y)) = at {
|
||||
params["x"] = json!(x);
|
||||
@@ -61,6 +62,9 @@ pub fn paste(app: &mut FigApp, event_text: Option<&str>, at: Option<(f64, f64)>)
|
||||
let (cx, cy) = at.or_else(|| app.session.ds().ok().map(|d| (d.view.cx, d.view.cy))).unwrap_or((0.0, 0.0));
|
||||
if !ours {
|
||||
if let Some((png, w, h)) = clipboard_png(app) {
|
||||
if dev_mode_refuses(app, "edit.paste") {
|
||||
return;
|
||||
}
|
||||
use base64::Engine as _;
|
||||
let b64 = base64::engine::general_purpose::STANDARD.encode(png);
|
||||
// Centred in the view; Paste here puts its top-left at the point, as it does layers.
|
||||
@@ -73,6 +77,8 @@ pub fn paste(app: &mut FigApp, event_text: Option<&str>, at: Option<(f64, f64)>)
|
||||
// A comment's link opens its thread.
|
||||
if text.trim().starts_with("figcraft://comment/") {
|
||||
app.run("comment.open", json!({"link": text.trim()}));
|
||||
} else if dev_mode_refuses(app, "edit.paste") {
|
||||
// Dev Mode: the note says why nothing was pasted.
|
||||
} else if figcraft_engine::looks_like_svg(&text) {
|
||||
use base64::Engine as _;
|
||||
let b64 = base64::engine::general_purpose::STANDARD.encode(text.as_bytes());
|
||||
@@ -83,7 +89,9 @@ pub fn paste(app: &mut FigApp, event_text: Option<&str>, at: Option<(f64, f64)>)
|
||||
return;
|
||||
}
|
||||
}
|
||||
app.run("edit.paste", at.map_or(json!({}), |(x, y)| json!({"x": x, "y": y})));
|
||||
if !dev_mode_refuses(app, "edit.paste") {
|
||||
app.run("edit.paste", at.map_or(json!({}), |(x, y)| json!({"x": x, "y": y})));
|
||||
}
|
||||
}
|
||||
|
||||
/// The system clipboard's image as PNG bytes, with its size.
|
||||
|
||||
@@ -115,7 +115,8 @@ fn main_toolbar(app: &mut FigApp, ui: &mut Ui, canvas: Rect, t: &Tokens) {
|
||||
if resp.clicked() {
|
||||
// Enter (a keyboard click) on the shape or frame tool already chosen places one; the
|
||||
// canvas takes the keyboard.
|
||||
if in_group && shown.draws_shape() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
|
||||
// In Dev Mode the tool goes through `choose`, which returns to the design first.
|
||||
if in_group && shown.draws_shape() && app.ui.right_tab != crate::RightTab::Inspect && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
|
||||
app.run("tool.place", json!({}));
|
||||
app.ui.nav.go(Region::Canvas);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user