diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b223ffd..78cb04304 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file. - sixtyfps-compiler and sixtyfps-viewer can read the .60 file content from stdin by passing `-` - sixtyfps-viewer gained ability to read or save the property values to a json file with `--save-data` and `--load-data` + - `sixtyfps::Image` has now a `path()` accessor function in Rust and C++ to access the optional path + of the file on disk that's backing the image. ### Fixed diff --git a/api/sixtyfps-cpp/cbindgen.rs b/api/sixtyfps-cpp/cbindgen.rs index ee967db96..581c36013 100644 --- a/api/sixtyfps-cpp/cbindgen.rs +++ b/api/sixtyfps-cpp/cbindgen.rs @@ -147,6 +147,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> { "sixtyfps_color_brighter", "sixtyfps_color_darker", "sixtyfps_image_size", + "sixtyfps_image_path", ] .iter() .map(|x| x.to_string()) @@ -205,6 +206,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> { "Image", "Size", "sixtyfps_image_size", + "sixtyfps_image_path", "SharedPixelBuffer", "SharedImageBuffer", ], @@ -253,6 +255,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> { "sixtyfps_color_brighter", "sixtyfps_color_darker", "sixtyfps_image_size", + "sixtyfps_image_path", ] .iter() .filter(|exclusion| !rust_types.iter().any(|inclusion| inclusion == *exclusion)) diff --git a/api/sixtyfps-cpp/include/sixtyfps_image.h b/api/sixtyfps-cpp/include/sixtyfps_image.h index fcfa32167..ac69c6e33 100644 --- a/api/sixtyfps-cpp/include/sixtyfps_image.h +++ b/api/sixtyfps-cpp/include/sixtyfps_image.h @@ -54,6 +54,16 @@ public: /// Returns the size of the Image in pixels. Size size() const { return cbindgen_private::types::sixtyfps_image_size(&data); } + /// Returns the path of the image on disk, if it was constructed via Image::load_from_path(). + std::optional path() const + { + if (auto *str = cbindgen_private::types::sixtyfps_image_path(&data)) { + return *str; + } else { + return {}; + } + } + /// Returns true if \a a refers to the same image as \a b; false otherwise. friend bool operator==(const Image &a, const Image &b) { return a.data == b.data; } /// Returns false if \a a refers to the same image as \a b; true otherwise. diff --git a/api/sixtyfps-cpp/tests/datastructures.cpp b/api/sixtyfps-cpp/tests/datastructures.cpp index 036efc57e..b7e67b61f 100644 --- a/api/sixtyfps-cpp/tests/datastructures.cpp +++ b/api/sixtyfps-cpp/tests/datastructures.cpp @@ -86,6 +86,9 @@ TEST_CASE("Image") REQUIRE(size.width == 0.); REQUIRE(size.height == 0.); } + { + REQUIRE(!img.path().has_value()); + } img = Image::load_from_path(SOURCE_DIR "/../../vscode_extension/extension-logo.png"); { @@ -93,6 +96,11 @@ TEST_CASE("Image") REQUIRE(size.width == 128.); REQUIRE(size.height == 128.); } + { + auto actual_path = img.path(); + REQUIRE(actual_path.has_value()); + REQUIRE(*actual_path == SOURCE_DIR "/../../vscode_extension/extension-logo.png"); + } } TEST_CASE("SharedVector") diff --git a/sixtyfps_runtime/corelib/graphics/image.rs b/sixtyfps_runtime/corelib/graphics/image.rs index 5135d6a0a..334565383 100644 --- a/sixtyfps_runtime/corelib/graphics/image.rs +++ b/sixtyfps_runtime/corelib/graphics/image.rs @@ -304,6 +304,14 @@ impl Image { ImageInner::EmbeddedImage(buffer) => [buffer.width() as _, buffer.height() as _].into(), } } + + /// Returns the path of the image on disk, if it was constructed via [`Self::load_from_path`]. + pub fn path(&self) -> Option<&std::path::Path> { + match &self.0 { + ImageInner::AbsoluteFilePath(path) => Some(std::path::Path::new(path.as_str())), + _ => None, + } + } } #[test] @@ -347,4 +355,12 @@ pub(crate) mod ffi { pub unsafe extern "C" fn sixtyfps_image_size(image: &Image) -> Size { image.size() } + + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_image_path(image: &Image) -> Option<&SharedString> { + match &image.0 { + ImageInner::AbsoluteFilePath(path) => Some(&path), + _ => None, + } + } }