Skip to content

Commit 255cdea

Browse files
authored
Add thumbnails for layers (#286)
Fixes: #285
1 parent 06c26f4 commit 255cdea

File tree

7 files changed

+35
-3
lines changed

7 files changed

+35
-3
lines changed

client/web/src/components/panels/LayerTree.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
@click.alt.exact="handleControlClick(layer)"
2929
@click.exact="handleClick(layer)"
3030
>
31-
<div class="layer-thumbnail"></div>
31+
<div class="layer-thumbnail" v-html="layer.thumbnail"></div>
3232
<div class="layer-type-icon">
3333
<IconLabel :icon="'NodeTypePath'" title="Path" />
3434
</div>
@@ -92,6 +92,12 @@
9292
width: 64px;
9393
height: 100%;
9494
background: white;
95+
96+
svg {
97+
width: calc(100% - 4px);
98+
height: calc(100% - 4px);
99+
margin: 2px;
100+
}
95101
}
96102
97103
.layer-type-icon {

client/web/src/utilities/response-handler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ export interface LayerPanelEntry {
207207
layer_type: LayerType;
208208
path: BigUint64Array;
209209
layer_data: LayerData;
210+
thumbnail: string;
210211
}
211212
function newLayerPanelEntry(input: any): LayerPanelEntry {
212213
return {
@@ -215,6 +216,7 @@ function newLayerPanelEntry(input: any): LayerPanelEntry {
215216
layer_type: newLayerType(input.layer_type),
216217
layer_data: newLayerData(input.layer_data),
217218
path: new BigUint64Array(input.path.map((n: number) => BigInt(n))),
219+
thumbnail: input.thumbnail,
218220
};
219221
}
220222

core/document/src/document.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ impl Document {
212212
/// Adds a new layer to the folder specified by `path`.
213213
/// Passing a negative `insert_index` indexes relative to the end.
214214
/// -1 is equivalent to adding the layer to the top.
215-
pub fn add_layer(&mut self, path: &[LayerId], layer: Layer, insert_index: isize) -> Result<LayerId, DocumentError> {
216-
let _ = self.layer_mut(path).map(|x| x.cache_dirty = true);
215+
pub fn add_layer(&mut self, path: &[LayerId], mut layer: Layer, insert_index: isize) -> Result<LayerId, DocumentError> {
216+
layer.render();
217217
let folder = self.folder_mut(path)?;
218218
folder.add_layer(layer, insert_index).ok_or(DocumentError::IndexOutOfBounds)
219219
}

core/document/src/layers/folder.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ impl Folder {
7474
self.layers.as_slice()
7575
}
7676

77+
pub fn layers_mut(&mut self) -> &mut [Layer] {
78+
self.layers.as_mut_slice()
79+
}
80+
7781
pub fn layer(&self, id: LayerId) -> Option<&Layer> {
7882
let pos = self.layer_ids.iter().position(|x| *x == id)?;
7983
Some(&self.layers[pos])

core/document/src/layers/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ impl Layer {
175175
self.data.to_kurbo_path(self.transform, self.style)
176176
}
177177

178+
pub fn current_bounding_box(&self) -> Option<[DVec2; 2]> {
179+
self.bounding_box(self.transform, self.style)
180+
}
181+
178182
pub fn bounding_box(&self, transform: glam::DAffine2, style: style::PathStyle) -> Option<[DVec2; 2]> {
179183
if let Ok(folder) = self.as_folder() {
180184
folder.bounding_box(transform)

core/editor/src/document/document_file.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,27 @@ fn layer_data<'a>(layer_data: &'a mut HashMap<Vec<LayerId>, LayerData>, path: &[
4141
pub fn layer_panel_entry(layer_data: &mut LayerData, layer: &Layer, path: Vec<LayerId>) -> LayerPanelEntry {
4242
let layer_type: LayerType = (&layer.data).into();
4343
let name = layer.name.clone().unwrap_or_else(|| format!("Unnamed {}", layer_type));
44+
let arr = layer.current_bounding_box().unwrap_or([DVec2::ZERO, DVec2::ZERO]);
45+
let arr = arr.iter().map(|x| (*x).into()).collect::<Vec<(f64, f64)>>();
46+
let thumbnail = if let [(x_min, y_min), (x_max, y_max)] = arr.as_slice() {
47+
format!(
48+
r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="{} {} {} {}">{}</svg>"#,
49+
x_min,
50+
y_min,
51+
x_max - x_min,
52+
y_max - y_min,
53+
layer.cache.clone()
54+
)
55+
} else {
56+
String::new()
57+
};
4458
LayerPanelEntry {
4559
name,
4660
visible: layer.visible,
4761
layer_type,
4862
layer_data: *layer_data,
4963
path,
64+
thumbnail,
5065
}
5166
}
5267

core/editor/src/frontend/layer_panel.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub struct LayerPanelEntry {
1010
pub layer_type: LayerType,
1111
pub layer_data: LayerData,
1212
pub path: Vec<LayerId>,
13+
pub thumbnail: String,
1314
}
1415

1516
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]

0 commit comments

Comments
 (0)