mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-30 05:16:56 -06:00
Merge #311: fix(pages): inherit the current page background when adding pages (M1) (@tylerjenningsw)
# Conflicts: # ROADMAP.md
This commit is contained in:
@@ -16,3 +16,7 @@
|
||||
#
|
||||
# To remove your names, delete your entry (or set fields empty) in a PR. The next
|
||||
# contributors.py run, and the next build, drop them.
|
||||
|
||||
[people.tylerjenningsw]
|
||||
real_name = "Tyler Jennings"
|
||||
display_name = "tylerjenningsw"
|
||||
|
||||
@@ -26,7 +26,12 @@ fn settle(s: &mut Session, cmd: &str) -> crate::Result<()> {
|
||||
pub fn specs() -> Vec<CommandSpec> {
|
||||
vec![
|
||||
spec!("page.add", "Add page", "{name?} (a name starting with a hyphen adds a divider)", true, |s, p| {
|
||||
let background = s.new_page_background();
|
||||
// An added page takes the current page's colour; the theme only decides new files.
|
||||
let current = s.page().ok().and_then(|p| match s.doc().ok()?.node(p)?.kind {
|
||||
NodeKind::Page { background, .. } => Some(background),
|
||||
_ => None,
|
||||
});
|
||||
let background = current.unwrap_or_else(|| s.new_page_background());
|
||||
let doc = s.doc_mut()?;
|
||||
let name = string(p, "name").unwrap_or_else(|| format!("Page {}", doc.pages.len() + 1));
|
||||
let id = doc.add_page(&name);
|
||||
|
||||
@@ -663,8 +663,8 @@ pub struct Session {
|
||||
pub prefs: Prefs,
|
||||
pub tool: tools::ToolState,
|
||||
pub ui_requests: Vec<UiRequest>,
|
||||
/// The interface's theme once the UI knows it ([`Session::set_ui_dark`]): new files and pages
|
||||
/// get the dark page colour while it is dark. Headless sessions (CLI, MCP, exports) have no
|
||||
/// The interface's theme once the UI knows it ([`Session::set_ui_dark`]): new files get the
|
||||
/// dark page colour while it is dark (added pages take the current page's). Headless sessions (CLI, MCP, exports) have no
|
||||
/// theme, so what scripts make is the same everywhere.
|
||||
pub ui_dark: Option<bool>,
|
||||
/// Command log (id + params) for actions/automation.
|
||||
@@ -721,7 +721,7 @@ impl Session {
|
||||
}
|
||||
}
|
||||
|
||||
/// The background new pages get: the dark page colour while the interface is dark.
|
||||
/// The background a new file's page gets: the dark page colour while the interface is dark.
|
||||
pub fn new_page_background(&self) -> figcraft_color::Color {
|
||||
if self.ui_dark == Some(true) { figcraft_color::Color::DARK_PAGE } else { figcraft_color::Color::DEFAULT_PAGE }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! The page colour of new files and pages follows the interface's theme when they are made (dark:
|
||||
//! #1E1E1E, light: #F5F5F5) and is the page's own from then on; a session without an interface
|
||||
//! (CLI, MCP, exports) has no theme and keeps the light default. Text drawn with the Text tool is
|
||||
//! white on a dark page and black on a light one.
|
||||
//! The page colour of a new file follows the interface's theme when it is made (dark: #1E1E1E,
|
||||
//! light: #F5F5F5) and is the page's own from then on; an added page takes the colour of the page
|
||||
//! it was added from. A session without an interface (CLI, MCP, exports) has no theme and keeps the
|
||||
//! light default. Text drawn with the Text tool is white on a dark page and black on a light one.
|
||||
|
||||
use figcraft_color::{Color, Paint};
|
||||
use figcraft_doc::{NodeId, NodeKind};
|
||||
@@ -38,8 +38,8 @@ fn draw_text(s: &mut Session, x: f64, y: f64) -> NodeId {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_files_and_pages_take_the_theme_they_are_made_in() {
|
||||
// (theme the interface reported, colour of a new file's page and of an added page)
|
||||
fn new_files_take_the_theme_they_are_made_in_and_added_pages_follow() {
|
||||
// (theme the interface reported, colour of a new file's page and of a page added to it)
|
||||
for (dark, want) in [(None, "#F5F5F5"), (Some(false), "#F5F5F5"), (Some(true), "#1E1E1E")] {
|
||||
let mut s = Session::empty();
|
||||
if let Some(d) = dark {
|
||||
@@ -62,8 +62,10 @@ fn a_change_of_theme_leaves_existing_pages_alone() {
|
||||
ex(&mut s, "file.new", json!({}));
|
||||
s.set_ui_dark(false);
|
||||
ex(&mut s, "page.add", json!({}));
|
||||
assert_eq!(backgrounds(&s), ["#1E1E1E", "#1E1E1E"], "an added page follows its page, not the theme");
|
||||
ex(&mut s, "page.setBackground", json!({"color": "#F5F5F5"}));
|
||||
s.set_ui_dark(true);
|
||||
assert_eq!(backgrounds(&s), ["#1E1E1E", "#F5F5F5"], "each page keeps the colour it was made with");
|
||||
assert_eq!(backgrounds(&s), ["#1E1E1E", "#F5F5F5"], "each page keeps its colour");
|
||||
// A copy of a page is that page's colour, whatever the theme.
|
||||
let first = s.doc().unwrap().pages[0];
|
||||
s.set_ui_dark(false);
|
||||
@@ -71,6 +73,57 @@ fn a_change_of_theme_leaves_existing_pages_alone() {
|
||||
assert_eq!(background(&s, copy), Color::DARK_PAGE);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_added_page_takes_the_current_pages_colour() {
|
||||
// Whatever the theme, and headless too: the page it was added from decides.
|
||||
for dark in [None, Some(false), Some(true)] {
|
||||
let mut s = Session::empty();
|
||||
if let Some(d) = dark {
|
||||
s.set_ui_dark(d);
|
||||
}
|
||||
ex(&mut s, "file.new", json!({}));
|
||||
ex(&mut s, "page.setBackground", json!({"color": "#336699"}));
|
||||
ex(&mut s, "page.add", json!({}));
|
||||
assert_eq!(backgrounds(&s), ["#336699", "#336699"], "theme {dark:?}");
|
||||
// From the second page, now current, after giving it its own colour.
|
||||
ex(&mut s, "page.setBackground", json!({"color": "#FFE08A"}));
|
||||
ex(&mut s, "page.add", json!({"name": "Third"}));
|
||||
assert_eq!(backgrounds(&s), ["#336699", "#FFE08A", "#FFE08A"], "theme {dark:?}");
|
||||
// One undo step, the colour with it.
|
||||
ex(&mut s, "edit.undo", json!({}));
|
||||
assert_eq!(backgrounds(&s), ["#336699", "#FFE08A"], "theme {dark:?} after undo");
|
||||
ex(&mut s, "edit.redo", json!({}));
|
||||
assert_eq!(backgrounds(&s), ["#336699", "#FFE08A", "#FFE08A"], "theme {dark:?} after redo");
|
||||
}
|
||||
// From a page other than the first: go there, then add.
|
||||
let mut s = Session::new();
|
||||
s.set_ui_dark(true);
|
||||
ex(&mut s, "page.add", json!({}));
|
||||
ex(&mut s, "page.setBackground", json!({"color": "#0B1F3A"}));
|
||||
ex(&mut s, "page.select", json!({"index": 0}));
|
||||
ex(&mut s, "page.add", json!({}));
|
||||
assert_eq!(backgrounds(&s), ["#1E1E1E", "#0B1F3A", "#1E1E1E"], "the current page decides, not the last");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn added_page_colours_survive_save_and_reopen() {
|
||||
let dir = std::env::temp_dir().join(format!("figcraft-added-pages-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let path = dir.join("pages.figcraft");
|
||||
let mut s = Session::new();
|
||||
ex(&mut s, "page.setBackground", json!({"color": "#336699"}));
|
||||
ex(&mut s, "page.add", json!({}));
|
||||
ex(&mut s, "file.saveAs", json!({"path": path.to_string_lossy()}));
|
||||
let mut s = Session::empty();
|
||||
s.set_ui_dark(true);
|
||||
ex(&mut s, "file.open", json!({"path": path.to_string_lossy()}));
|
||||
assert_eq!(backgrounds(&s), ["#336699", "#336699"]);
|
||||
// And a page added to the reopened file in the dark theme follows the file, not the theme.
|
||||
ex(&mut s, "page.add", json!({}));
|
||||
assert_eq!(backgrounds(&s), ["#336699", "#336699", "#336699"]);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_file_the_app_opened_with_takes_the_theme_once_it_is_known() {
|
||||
// Made before the interface knew its theme, nothing done to it yet.
|
||||
|
||||
@@ -892,7 +892,7 @@ impl FigApp {
|
||||
_ => false,
|
||||
};
|
||||
self.ui.dark = dark;
|
||||
// New files and pages take the theme's page colour (existing pages keep theirs).
|
||||
// New files take the theme's page colour (existing pages keep theirs).
|
||||
self.session.set_ui_dark(dark);
|
||||
theme::apply_with(ctx, if dark { theme::Tokens::dark() } else { theme::Tokens::light() }, self.reduce_motion());
|
||||
if self.worker.is_none() {
|
||||
|
||||
@@ -75,5 +75,7 @@ fn a_new_file_takes_the_page_colour_of_the_theme_and_keeps_it() {
|
||||
u.app.run("view.themeDark", json!({}));
|
||||
u.frame(vec![]);
|
||||
u.app.run("page.add", json!({}));
|
||||
assert_eq!(page_colour(&u), Color::DARK_PAGE, "a page added in the dark theme");
|
||||
assert_eq!(page_colour(&u), Color::DEFAULT_PAGE, "a page added in the dark theme follows its light page");
|
||||
u.app.run("file.new", json!({}));
|
||||
assert_eq!(page_colour(&u), Color::DARK_PAGE, "a file made in the dark theme");
|
||||
}
|
||||
|
||||
+3
-3
@@ -301,9 +301,9 @@ on; `key` resolves keys the way the canvas does. Commands behind keys:
|
||||
given, are or are in; default the selection) out of the library the file publishes, or let them
|
||||
back in (`on: false`; without `on` it toggles). The sign of it is the name: hiding puts a `.`
|
||||
before it, showing takes the leading `.` and `_` away. Returns `{ids, hidden}`; one undo step.
|
||||
- New files and pages: `file.new` and `page.add` give a page the colour `#F5F5F5`. Only the app
|
||||
with its dark theme showing makes them `#1E1E1E`; headless sessions (the CLI, this server) have
|
||||
no theme. Text made with `text.create` or `node.create` is black whatever the page here; in the
|
||||
- New files and pages: `file.new` gives its page the colour `#F5F5F5`. Only the app with its dark
|
||||
theme showing makes it `#1E1E1E`; headless sessions (the CLI, this server) have no theme.
|
||||
`page.add` gives the new page the current page's colour, wherever it runs. Text made with `text.create` or `node.create` is black whatever the page here; in the
|
||||
app (the control channel, `--attach`) it is white on a dark page unless `props` name a `fill`,
|
||||
as the Text tool (`pointer` with `tool.text`) makes it everywhere.
|
||||
- `transform.rotationOrigin {on?}` (`Alt+R`): show or hide the selection's rotation origin handle
|
||||
|
||||
Reference in New Issue
Block a user