@@ -27,7 +27,7 @@ use graphene_std::text::{Font, TextAlign};
2727use graphene_std:: transform:: { Footprint , ReferencePoint , Transform } ;
2828use graphene_std:: vector:: QRCodeErrorCorrectionLevel ;
2929use graphene_std:: vector:: misc:: { ArcType , CentroidType , ExtrudeJoiningAlgorithm , GridType , MergeByDistanceAlgorithm , PointSpacingType , RowsOrColumns , SpiralType } ;
30- use graphene_std:: vector:: style:: { Fill , FillChoice , FillType , GradientStops , GradientType , PaintOrder , StrokeAlign , StrokeCap , StrokeJoin } ;
30+ use graphene_std:: vector:: style:: { Fill , FillChoice , FillType , Gradient , GradientStops , GradientType , PaintOrder , StrokeAlign , StrokeCap , StrokeJoin } ;
3131
3232pub ( crate ) fn string_properties ( text : & str ) -> Vec < LayoutGroup > {
3333 let widget = TextLabel :: new ( text) . widget_instance ( ) ;
@@ -1817,7 +1817,7 @@ pub(crate) fn generate_node_properties(node_id: NodeId, context: &mut NodeProper
18171817pub ( crate ) fn fill_properties ( node_id : NodeId , context : & mut NodePropertiesContext ) -> Vec < LayoutGroup > {
18181818 use graphene_std:: vector:: fill:: * ;
18191819
1820- let mut widgets_first_row = start_widgets ( ParameterWidgetsInfo :: new ( node_id, FillInput :: < Color > :: INDEX , true , context) ) ;
1820+ let mut widgets_first_row = start_widgets ( ParameterWidgetsInfo :: new ( node_id, ColorInput :: < Color > :: INDEX , true , context) ) ;
18211821
18221822 let document_node = match get_document_node ( node_id, context) {
18231823 Ok ( document_node) => document_node,
@@ -1828,7 +1828,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
18281828 } ;
18291829
18301830 let ( fill, backup_color, backup_gradient) = if let ( Some ( TaggedValue :: Fill ( fill) ) , Some ( TaggedValue :: Color ( backup_color) ) , Some ( TaggedValue :: Gradient ( backup_gradient) ) ) = (
1831- & document_node. inputs [ FillInput :: < Color > :: INDEX ] . as_value ( ) ,
1831+ & document_node. inputs [ ColorInput :: < Color > :: INDEX ] . as_value ( ) ,
18321832 & document_node. inputs [ BackupColorInput :: INDEX ] . as_value ( ) ,
18331833 & document_node. inputs [ BackupGradientInput :: INDEX ] . as_value ( ) ,
18341834 ) {
@@ -1842,9 +1842,9 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
18421842
18431843 widgets_first_row. push ( Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ) ;
18441844 widgets_first_row. push (
1845- ColorInput :: default ( )
1845+ crate :: messages :: layout :: utility_types :: widgets :: button_widgets :: ColorInput :: default ( )
18461846 . value ( fill. clone ( ) . into ( ) )
1847- . on_update ( move |x : & ColorInput | Message :: Batched {
1847+ . on_update ( move |x : & crate :: messages :: layout :: utility_types :: widgets :: button_widgets :: ColorInput | Message :: Batched {
18481848 messages : Box :: new ( [
18491849 match & fill2 {
18501850 Fill :: None => NodeGraphMessage :: SetInputValue {
@@ -1868,7 +1868,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
18681868 } ,
18691869 NodeGraphMessage :: SetInputValue {
18701870 node_id,
1871- input_index : FillInput :: < Color > :: INDEX ,
1871+ input_index : ColorInput :: < Color > :: INDEX ,
18721872 value : TaggedValue :: Fill ( x. value . to_fill ( fill2. as_gradient ( ) ) ) ,
18731873 }
18741874 . into ( ) ,
@@ -1896,7 +1896,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
18961896 }
18971897 } ,
18981898 node_id,
1899- FillInput :: < Color > :: INDEX ,
1899+ ColorInput :: < Color > :: INDEX ,
19001900 ) )
19011901 . widget_instance ( ) ;
19021902 row. push ( Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ) ;
@@ -1907,11 +1907,11 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
19071907 let entries = vec ! [
19081908 RadioEntryData :: new( "solid" )
19091909 . label( "Solid" )
1910- . on_update( update_value( move |_| TaggedValue :: Fill ( backup_color_fill. clone( ) ) , node_id, FillInput :: <Color >:: INDEX ) )
1910+ . on_update( update_value( move |_| TaggedValue :: Fill ( backup_color_fill. clone( ) ) , node_id, ColorInput :: <Color >:: INDEX ) )
19111911 . on_commit( commit_value) ,
19121912 RadioEntryData :: new( "gradient" )
19131913 . label( "Gradient" )
1914- . on_update( update_value( move |_| TaggedValue :: Fill ( backup_gradient_fill. clone( ) ) , node_id, FillInput :: <Color >:: INDEX ) )
1914+ . on_update( update_value( move |_| TaggedValue :: Fill ( backup_gradient_fill. clone( ) ) , node_id, ColorInput :: <Color >:: INDEX ) )
19151915 . on_commit( commit_value) ,
19161916 ] ;
19171917
@@ -1946,7 +1946,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
19461946 }
19471947 } ,
19481948 node_id,
1949- FillInput :: < Color > :: INDEX ,
1949+ ColorInput :: < Color > :: INDEX ,
19501950 ) )
19511951 . widget_instance ( ) ;
19521952 row. push ( Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ) ;
@@ -1967,7 +1967,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
19671967 TaggedValue :: Fill ( Fill :: Gradient ( new_gradient) )
19681968 } ,
19691969 node_id,
1970- FillInput :: < Color > :: INDEX ,
1970+ ColorInput :: < Color > :: INDEX ,
19711971 ) ;
19721972 RadioEntryData :: new ( format ! ( "{:?}" , grad_type) )
19731973 . label ( format ! ( "{:?}" , grad_type) )
@@ -2009,18 +2009,201 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) -
20092009 Some ( TaggedValue :: StrokeJoin ( x) ) => x,
20102010 _ => & StrokeJoin :: Miter ,
20112011 } ;
2012-
20132012 let dash_lengths_val = match & document_node. inputs [ DashLengthsInput :: < Vec < f64 > > :: INDEX ] . as_value ( ) {
20142013 Some ( TaggedValue :: VecF64 ( x) ) => x,
20152014 _ => & vec ! [ ] ,
20162015 } ;
2016+
20172017 let has_dash_lengths = dash_lengths_val. is_empty ( ) ;
20182018 let miter_limit_disabled = join_value != & StrokeJoin :: Miter ;
20192019
2020- let color = color_widget (
2021- ParameterWidgetsInfo :: new ( node_id, ColorInput :: INDEX , true , context) ,
2022- crate :: messages:: layout:: utility_types:: widgets:: button_widgets:: ColorInput :: default ( ) ,
2020+ let fill = document_node
2021+ . inputs
2022+ . get ( ColorInput :: < Fill > :: INDEX )
2023+ . and_then ( |i| i. as_non_exposed_value ( ) )
2024+ . and_then ( |t| match t {
2025+ TaggedValue :: Fill ( f) => Some ( f. clone ( ) ) ,
2026+ _ => None ,
2027+ } )
2028+ . unwrap_or ( Fill :: None ) ;
2029+ let backup_color = document_node
2030+ . inputs
2031+ . get ( BackupColorInput :: INDEX )
2032+ . and_then ( |i| i. as_non_exposed_value ( ) )
2033+ . and_then ( |t| match t {
2034+ TaggedValue :: Color ( c) => Some ( c. clone ( ) ) ,
2035+ _ => None ,
2036+ } )
2037+ . unwrap_or ( Table :: new ( ) ) ;
2038+ let backup_gradient = document_node
2039+ . inputs
2040+ . get ( BackupGradientInput :: INDEX )
2041+ . and_then ( |i| i. as_non_exposed_value ( ) )
2042+ . and_then ( |t| match t {
2043+ TaggedValue :: Gradient ( g) => Some ( g. clone ( ) ) ,
2044+ _ => None ,
2045+ } )
2046+ . unwrap_or ( Gradient :: default ( ) ) ;
2047+
2048+ let mut widgets = Vec :: new ( ) ;
2049+
2050+ let mut widgets_first_row = start_widgets ( ParameterWidgetsInfo :: new ( node_id, ColorInput :: < Fill > :: INDEX , true , context) ) ;
2051+ let fill2 = fill. clone ( ) ;
2052+ let backup_color_fill: Fill = backup_color. clone ( ) . into ( ) ;
2053+ let backup_gradient_fill: Fill = backup_gradient. clone ( ) . into ( ) ;
2054+
2055+ widgets_first_row. push ( Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ) ;
2056+ widgets_first_row. push (
2057+ crate :: messages:: layout:: utility_types:: widgets:: button_widgets:: ColorInput :: default ( )
2058+ . value ( fill. clone ( ) . into ( ) )
2059+ . on_update ( move |x : & crate :: messages:: layout:: utility_types:: widgets:: button_widgets:: ColorInput | {
2060+ let new_fill = x. value . to_fill ( fill2. as_gradient ( ) ) ;
2061+ let backup_msg = match & new_fill {
2062+ Fill :: None => NodeGraphMessage :: SetInputValue {
2063+ node_id,
2064+ input_index : BackupColorInput :: INDEX ,
2065+ value : TaggedValue :: Color ( Table :: new ( ) ) ,
2066+ }
2067+ . into ( ) ,
2068+ Fill :: Solid ( color) => NodeGraphMessage :: SetInputValue {
2069+ node_id,
2070+ input_index : BackupColorInput :: INDEX ,
2071+ value : TaggedValue :: Color ( Table :: new_from_element ( * color) ) ,
2072+ }
2073+ . into ( ) ,
2074+ Fill :: Gradient ( gradient) => NodeGraphMessage :: SetInputValue {
2075+ node_id,
2076+ input_index : BackupGradientInput :: INDEX ,
2077+ value : TaggedValue :: Gradient ( gradient. clone ( ) ) ,
2078+ }
2079+ . into ( ) ,
2080+ } ;
2081+ Message :: Batched {
2082+ messages : Box :: new ( [
2083+ backup_msg,
2084+ NodeGraphMessage :: SetInputValue {
2085+ node_id,
2086+ input_index : ColorInput :: < Fill > :: INDEX ,
2087+ value : TaggedValue :: Fill ( new_fill) ,
2088+ }
2089+ . into ( ) ,
2090+ ] ) ,
2091+ }
2092+ } )
2093+ . on_commit ( commit_value)
2094+ . widget_instance ( ) ,
20232095 ) ;
2096+ widgets. push ( LayoutGroup :: row ( widgets_first_row) ) ;
2097+
2098+ let mut fill_type_row = vec ! [ TextLabel :: new( "" ) . widget_instance( ) ] ;
2099+ match fill {
2100+ Fill :: Solid ( _) | Fill :: None => add_blank_assist ( & mut fill_type_row) ,
2101+ Fill :: Gradient ( ref gradient) => {
2102+ let reverse_button = IconButton :: new ( "Reverse" , 24 )
2103+ . tooltip_description ( "Reverse the gradient color stops." )
2104+ . on_update ( update_value (
2105+ {
2106+ let gradient = gradient. clone ( ) ;
2107+ move |_| {
2108+ let mut gradient = gradient. clone ( ) ;
2109+ gradient. stops = gradient. stops . reversed ( ) ;
2110+ TaggedValue :: Fill ( Fill :: Gradient ( gradient) )
2111+ }
2112+ } ,
2113+ node_id,
2114+ ColorInput :: < Color > :: INDEX ,
2115+ ) )
2116+ . widget_instance ( ) ;
2117+ fill_type_row. push ( Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ) ;
2118+ fill_type_row. push ( reverse_button) ;
2119+ }
2120+ }
2121+
2122+ let entries = vec ! [
2123+ RadioEntryData :: new( "solid" )
2124+ . label( "Solid" )
2125+ . on_update( update_value( move |_| TaggedValue :: Fill ( backup_color_fill. clone( ) ) , node_id, ColorInput :: <Color >:: INDEX ) )
2126+ . on_commit( commit_value) ,
2127+ RadioEntryData :: new( "gradient" )
2128+ . label( "Gradient" )
2129+ . on_update( update_value( move |_| TaggedValue :: Fill ( backup_gradient_fill. clone( ) ) , node_id, ColorInput :: <Color >:: INDEX ) )
2130+ . on_commit( commit_value) ,
2131+ ] ;
2132+
2133+ fill_type_row. extend_from_slice ( & [
2134+ Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ,
2135+ RadioInput :: new ( entries) . selected_index ( Some ( if fill. as_gradient ( ) . is_some ( ) { 1 } else { 0 } ) ) . widget_instance ( ) ,
2136+ ] ) ;
2137+ widgets. push ( LayoutGroup :: row ( fill_type_row) ) ;
2138+
2139+ if let Fill :: Gradient ( gradient) = fill. clone ( ) {
2140+ let mut row = vec ! [ TextLabel :: new( "" ) . widget_instance( ) ] ;
2141+ match gradient. gradient_type {
2142+ GradientType :: Linear => add_blank_assist ( & mut row) ,
2143+ GradientType :: Radial => {
2144+ let orientation = if ( gradient. end . x - gradient. start . x ) . abs ( ) > f64:: EPSILON * 1e6 {
2145+ gradient. end . x > gradient. start . x
2146+ } else {
2147+ ( gradient. start . x + gradient. start . y ) < ( gradient. end . x + gradient. end . y )
2148+ } ;
2149+ let reverse_radial_gradient_button = IconButton :: new ( if orientation { "ReverseRadialGradientToRight" } else { "ReverseRadialGradientToLeft" } , 24 )
2150+ . tooltip_description ( "Reverse which end the gradient radiates from." )
2151+ . on_update ( update_value (
2152+ {
2153+ let gradient = gradient. clone ( ) ;
2154+ move |_| {
2155+ let mut gradient = gradient. clone ( ) ;
2156+ std:: mem:: swap ( & mut gradient. start , & mut gradient. end ) ;
2157+ TaggedValue :: Fill ( Fill :: Gradient ( gradient) )
2158+ }
2159+ } ,
2160+ node_id,
2161+ ColorInput :: < Fill > :: INDEX ,
2162+ ) )
2163+ . widget_instance ( ) ;
2164+ row. push ( Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ) ;
2165+ row. push ( reverse_radial_gradient_button) ;
2166+ }
2167+ }
2168+
2169+ let gradient_for_closure = gradient. clone ( ) ;
2170+
2171+ let entries = [ GradientType :: Linear , GradientType :: Radial ]
2172+ . iter ( )
2173+ . map ( |& grad_type| {
2174+ let gradient = gradient_for_closure. clone ( ) ;
2175+ let set_input_value = update_value (
2176+ move |_: & ( ) | {
2177+ let mut new_gradient = gradient. clone ( ) ;
2178+ new_gradient. gradient_type = grad_type;
2179+ TaggedValue :: Fill ( Fill :: Gradient ( new_gradient) )
2180+ } ,
2181+ node_id,
2182+ ColorInput :: < Fill > :: INDEX ,
2183+ ) ;
2184+ RadioEntryData :: new ( format ! ( "{:?}" , grad_type) )
2185+ . label ( format ! ( "{:?}" , grad_type) )
2186+ . on_update ( move |_| Message :: Batched {
2187+ messages : Box :: new ( [
2188+ set_input_value ( & ( ) ) ,
2189+ GradientToolMessage :: UpdateOptions {
2190+ options : GradientOptionsUpdate :: Type ( grad_type) ,
2191+ }
2192+ . into ( ) ,
2193+ ] ) ,
2194+ } )
2195+ . on_commit ( commit_value)
2196+ } )
2197+ . collect ( ) ;
2198+
2199+ row. extend_from_slice ( & [
2200+ Separator :: new ( SeparatorStyle :: Unrelated ) . widget_instance ( ) ,
2201+ RadioInput :: new ( entries) . selected_index ( Some ( gradient. gradient_type as u32 ) ) . widget_instance ( ) ,
2202+ ] ) ;
2203+
2204+ widgets. push ( LayoutGroup :: row ( row) ) ;
2205+ }
2206+
20242207 let weight = number_widget ( ParameterWidgetsInfo :: new ( node_id, WeightInput :: INDEX , true , context) , NumberInput :: default ( ) . unit ( " px" ) . min ( 0. ) ) ;
20252208 let align = enum_choice :: < StrokeAlign > ( )
20262209 . for_socket ( ParameterWidgetsInfo :: new ( node_id, AlignInput :: INDEX , true , context) )
@@ -2029,24 +2212,23 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) -
20292212 let join = enum_choice :: < StrokeJoin > ( )
20302213 . for_socket ( ParameterWidgetsInfo :: new ( node_id, JoinInput :: INDEX , true , context) )
20312214 . property_row ( ) ;
2032-
20332215 let miter_limit = number_widget (
20342216 ParameterWidgetsInfo :: new ( node_id, MiterLimitInput :: INDEX , true , context) ,
20352217 NumberInput :: default ( ) . min ( 0. ) . disabled ( miter_limit_disabled) ,
20362218 ) ;
20372219 let paint_order = enum_choice :: < PaintOrder > ( )
20382220 . for_socket ( ParameterWidgetsInfo :: new ( node_id, PaintOrderInput :: INDEX , true , context) )
20392221 . property_row ( ) ;
2040- let disabled_number_input = NumberInput :: default ( ) . unit ( " px" ) . disabled ( has_dash_lengths) ;
20412222 let dash_lengths = array_of_number_widget (
20422223 ParameterWidgetsInfo :: new ( node_id, DashLengthsInput :: < Vec < f64 > > :: INDEX , true , context) ,
20432224 TextInput :: default ( ) . centered ( true ) ,
20442225 ) ;
2045- let number_input = disabled_number_input;
2046- let dash_offset = number_widget ( ParameterWidgetsInfo :: new ( node_id, DashOffsetInput :: INDEX , true , context) , number_input) ;
2226+ let dash_offset = number_widget (
2227+ ParameterWidgetsInfo :: new ( node_id, DashOffsetInput :: INDEX , true , context) ,
2228+ NumberInput :: default ( ) . unit ( " px" ) . disabled ( has_dash_lengths) ,
2229+ ) ;
20472230
2048- vec ! [
2049- color,
2231+ widgets. extend ( [
20502232 LayoutGroup :: row ( weight) ,
20512233 align,
20522234 cap,
@@ -2055,7 +2237,9 @@ pub fn stroke_properties(node_id: NodeId, context: &mut NodePropertiesContext) -
20552237 paint_order,
20562238 LayoutGroup :: row ( dash_lengths) ,
20572239 LayoutGroup :: row ( dash_offset) ,
2058- ]
2240+ ] ) ;
2241+
2242+ widgets
20592243}
20602244
20612245pub fn offset_path_properties ( node_id : NodeId , context : & mut NodePropertiesContext ) -> Vec < LayoutGroup > {
0 commit comments