mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Layer opacity (#312)
Closes #187 * Add layer opacity input * Improve Rust code cleanliness
This commit is contained in:
@@ -412,15 +412,22 @@ impl Document {
|
||||
}
|
||||
Operation::SetLayerBlendMode { path, blend_mode } => {
|
||||
self.mark_as_dirty(path)?;
|
||||
self.layer_mut(&path).unwrap().blend_mode = *blend_mode;
|
||||
self.layer_mut(path)?.blend_mode = *blend_mode;
|
||||
|
||||
let path = path.as_slice()[..path.len() - 1].to_vec();
|
||||
|
||||
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path }])
|
||||
}
|
||||
Operation::SetLayerOpacity { path, opacity } => {
|
||||
self.mark_as_dirty(path)?;
|
||||
self.layer_mut(path)?.opacity = *opacity;
|
||||
|
||||
let path = path.as_slice()[..path.len() - 1].to_vec();
|
||||
|
||||
Some(vec![DocumentResponse::DocumentChanged, DocumentResponse::FolderChanged { path }])
|
||||
}
|
||||
Operation::FillLayer { path, color } => {
|
||||
let layer = self.layer_mut(path).unwrap();
|
||||
layer.style.set_fill(layers::style::Fill::new(*color));
|
||||
self.layer_mut(path)?.style.set_fill(layers::style::Fill::new(*color));
|
||||
self.mark_as_dirty(path)?;
|
||||
Some(vec![DocumentResponse::DocumentChanged])
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ pub struct Layer {
|
||||
pub thumbnail_cache: String,
|
||||
pub cache_dirty: bool,
|
||||
pub blend_mode: BlendMode,
|
||||
pub opacity: f64,
|
||||
}
|
||||
|
||||
impl Layer {
|
||||
@@ -189,6 +190,7 @@ impl Layer {
|
||||
thumbnail_cache: String::new(),
|
||||
cache_dirty: true,
|
||||
blend_mode: BlendMode::Normal,
|
||||
opacity: 1.,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,8 +205,9 @@ impl Layer {
|
||||
self.cache.clear();
|
||||
let _ = write!(
|
||||
self.cache,
|
||||
r#"<g style="mix-blend-mode: {}">{}</g>"#,
|
||||
r#"<g style="mix-blend-mode: {}; opacity: {}">{}</g>"#,
|
||||
self.blend_mode.to_svg_style_name(),
|
||||
self.opacity,
|
||||
self.thumbnail_cache.as_str()
|
||||
);
|
||||
|
||||
|
||||
@@ -77,6 +77,10 @@ pub enum Operation {
|
||||
path: Vec<LayerId>,
|
||||
blend_mode: BlendMode,
|
||||
},
|
||||
SetLayerOpacity {
|
||||
path: Vec<LayerId>,
|
||||
opacity: f64,
|
||||
},
|
||||
FillLayer {
|
||||
path: Vec<LayerId>,
|
||||
color: Color,
|
||||
|
||||
@@ -40,6 +40,7 @@ fn layer_data<'a>(layer_data: &'a mut HashMap<Vec<LayerId>, LayerData>, path: &[
|
||||
|
||||
pub fn layer_panel_entry(layer_data: &mut LayerData, layer: &mut Layer, path: Vec<LayerId>) -> LayerPanelEntry {
|
||||
let blend_mode = layer.blend_mode;
|
||||
let opacity = layer.opacity;
|
||||
let layer_type: LayerType = (&layer.data).into();
|
||||
let name = layer.name.clone().unwrap_or_else(|| format!("Unnamed {}", layer_type));
|
||||
let arr = layer.current_bounding_box().unwrap_or([DVec2::ZERO, DVec2::ZERO]);
|
||||
@@ -66,6 +67,7 @@ pub fn layer_panel_entry(layer_data: &mut LayerData, layer: &mut Layer, path: Ve
|
||||
name,
|
||||
visible: layer.visible,
|
||||
blend_mode,
|
||||
opacity,
|
||||
layer_type,
|
||||
layer_data: *layer_data,
|
||||
path,
|
||||
|
||||
@@ -27,6 +27,7 @@ pub enum DocumentMessage {
|
||||
DuplicateSelectedLayers,
|
||||
CopySelectedLayers,
|
||||
SetBlendModeForSelectedLayers(BlendMode),
|
||||
SetOpacityForSelectedLayers(f64),
|
||||
PasteLayers { path: Vec<LayerId>, insert_index: isize },
|
||||
AddFolder(Vec<LayerId>),
|
||||
RenameLayer(Vec<LayerId>, String),
|
||||
@@ -61,7 +62,7 @@ pub enum DocumentMessage {
|
||||
AlignSelectedLayers(AlignAxis, AlignAggregate),
|
||||
DragLayer(Vec<LayerId>, DVec2),
|
||||
MoveSelectedLayersTo { path: Vec<LayerId>, insert_index: isize },
|
||||
ReorderSelectedLayers(i32), // relatve_position,
|
||||
ReorderSelectedLayers(i32), // relative_position,
|
||||
SetLayerTranslation(Vec<LayerId>, Option<f64>, Option<f64>),
|
||||
}
|
||||
|
||||
@@ -361,8 +362,16 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
|
||||
SetBlendModeForSelectedLayers(blend_mode) => {
|
||||
let active_document = self.active_document();
|
||||
|
||||
for path in active_document.layer_data.iter().filter_map(|(path, data)| data.selected.then(|| path)) {
|
||||
responses.push_back(DocumentOperation::SetLayerBlendMode { path: path.clone(), blend_mode }.into());
|
||||
for path in active_document.layer_data.iter().filter_map(|(path, data)| data.selected.then(|| path.clone())) {
|
||||
responses.push_back(DocumentOperation::SetLayerBlendMode { path, blend_mode }.into());
|
||||
}
|
||||
}
|
||||
SetOpacityForSelectedLayers(opacity) => {
|
||||
let opacity = opacity.clamp(0., 1.);
|
||||
let active_document = self.active_document();
|
||||
|
||||
for path in active_document.layer_data.iter().filter_map(|(path, data)| data.selected.then(|| path.clone())) {
|
||||
responses.push_back(DocumentOperation::SetLayerOpacity { path, opacity }.into());
|
||||
}
|
||||
}
|
||||
ToggleLayerVisibility(path) => {
|
||||
|
||||
@@ -11,6 +11,7 @@ pub struct LayerPanelEntry {
|
||||
pub name: String,
|
||||
pub visible: bool,
|
||||
pub blend_mode: BlendMode,
|
||||
pub opacity: f64,
|
||||
pub layer_type: LayerType,
|
||||
pub layer_data: LayerData,
|
||||
pub path: Vec<LayerId>,
|
||||
|
||||
Reference in New Issue
Block a user