Can set stroke and fill on text and shapes (#551)

* Can set stroke and fill on text and shapes

* resend layout on failed update

* text input properly resets on bad input

* support modifying gradients

* can modify gradients in the properties panel

* updated labels

* remove heap allocation in favor of RC

* removed redundent line

* oops
This commit is contained in:
mfish33
2022-02-15 09:04:11 -08:00
committed by Keavon Chambers
parent 2aba0fc06b
commit ee0718ef5d
17 changed files with 286 additions and 33 deletions
+37
View File
@@ -162,4 +162,41 @@ impl Color {
pub fn rgb_hex(&self) -> String {
format!("{:02X?}{:02X?}{:02X?}", (self.r() * 255.) as u8, (self.g() * 255.) as u8, (self.b() * 255.) as u8,)
}
/// Creates a color from a 8-character RGBA hex string (without a # prefix).
///
/// # Examples
/// ```
/// use graphite_graphene::color::Color;
/// let color = Color::from_rgba_str("7C67FA61").unwrap();
/// assert!("7C67FA61" == color.rgba_hex())
/// ```
pub fn from_rgba_str(color_str: &str) -> Option<Color> {
if color_str.len() != 8 {
return None;
}
let r = u8::from_str_radix(&color_str[0..2], 16).ok()?;
let g = u8::from_str_radix(&color_str[2..4], 16).ok()?;
let b = u8::from_str_radix(&color_str[4..6], 16).ok()?;
let a = u8::from_str_radix(&color_str[6..8], 16).ok()?;
Some(Color::from_rgba8(r, g, b, a))
}
/// Creates a color from a 6-character RGB hex string (without a # prefix).
/// ```
/// use graphite_graphene::color::Color;
/// let color = Color::from_rgb_str("7C67FA").unwrap();
/// assert!("7C67FA" == color.rgb_hex())
/// ```
pub fn from_rgb_str(color_str: &str) -> Option<Color> {
if color_str.len() != 6 {
return None;
}
let r = u8::from_str_radix(&color_str[0..2], 16).ok()?;
let g = u8::from_str_radix(&color_str[2..4], 16).ok()?;
let b = u8::from_str_radix(&color_str[4..6], 16).ok()?;
Some(Color::from_rgb8(r, g, b))
}
}
+7
View File
@@ -775,11 +775,18 @@ impl Document {
let layer = self.layer_mut(&path)?;
match &mut layer.data {
LayerDataType::Shape(s) => s.style = style,
LayerDataType::Text(text) => text.style = style,
_ => return Err(DocumentError::NotAShape),
}
self.mark_as_dirty(&path)?;
Some([vec![DocumentChanged, LayerChanged { path: path.clone() }], update_thumbnails_upstream(&path)].concat())
}
Operation::SetLayerStroke { path, stroke } => {
let layer = self.layer_mut(&path)?;
layer.style_mut()?.set_stroke(stroke);
self.mark_as_dirty(&path)?;
Some([vec![DocumentChanged], update_thumbnails_upstream(&path)].concat())
}
Operation::SetLayerFill { path, fill } => {
let layer = self.layer_mut(&path)?;
layer.style_mut()?.set_fill(fill);
+11 -1
View File
@@ -133,7 +133,7 @@ impl Fill {
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Stroke {
color: Color,
width: f32,
@@ -157,6 +157,16 @@ impl Stroke {
}
}
// Having an alpha of 1 to start with leads to a better experience with the properties panel
impl Default for Stroke {
fn default() -> Self {
Self {
width: 0.,
color: Color::from_rgba8(0, 0, 0, 255),
}
}
}
#[repr(C)]
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct PathStyle {
+5 -1
View File
@@ -1,7 +1,7 @@
use crate::boolean_ops::BooleanOperation as BooleanOperationType;
use crate::layers::blend_mode::BlendMode;
use crate::layers::layer_info::Layer;
use crate::layers::style;
use crate::layers::style::{self, Stroke};
use crate::LayerId;
use serde::{Deserialize, Serialize};
@@ -180,6 +180,10 @@ pub enum Operation {
path: Vec<LayerId>,
fill: style::Fill,
},
SetLayerStroke {
path: Vec<LayerId>,
stroke: Stroke,
},
}
impl Operation {