@@ -17,8 +17,7 @@ import {
1717} from '../../theme' ;
1818import {
1919 RandomColorLensIcon ,
20- ColorLensIcon ,
21- TriangleIcon ,
20+ SquareIcon ,
2221} from './NetPyNEIcons' ;
2322import { changeInstanceColor } from '../../redux/actions/general' ;
2423
@@ -55,7 +54,7 @@ const useStyles = makeStyles((theme) => ({
5554 colorPickerBox : {
5655 position : 'absolute' ,
5756 top : '1.6rem' ,
58- right : '2.7rem ' ,
57+ right : '0 ' ,
5958 height : '3rem' ,
6059 } ,
6160 triangleIcon : {
@@ -65,7 +64,7 @@ const useStyles = makeStyles((theme) => ({
6564 colorPicker : {
6665 position : 'absolute' ,
6766 zIndex : 1000 ,
68- right : 0 ,
67+ right : '0' ,
6968 backgroundColor : `${ bgDarker } !important` ,
7069 padding : '0.2rem' ,
7170 '& label' : {
@@ -117,42 +116,79 @@ const ControlPanelTreeItem = (props) => {
117116 const dispatch = useDispatch ( ) ;
118117 const [ showColorPicker , setShowColorPicker ] = React . useState ( false ) ;
119118 const [ isHoveredOver , setIsHoveredOver ] = React . useState ( false ) ;
120- const [ color , setColor ] = React . useState ( {
121- g : 0.50 , b : 0.60 , r : 1 , a : 1 ,
122- } ) ;
123119 const [ visibility , setVisibility ] = React . useState ( true ) ;
124120 const instances = useSelector ( ( state ) => state . general . instances ) ;
121+ const defaultColor = {
122+ g : 0.50 ,
123+ b : 0.60 ,
124+ r : 1 ,
125+ a : 1 ,
126+ hex : "#FF7F99"
127+ } ;
125128
126- const handleColorSelection = ( _color , event , nodeId ) => {
127- const newInstances = instances . filter ( ( instance ) => ! ( instance . instancePath . startsWith ( nodeId ) ) ) ;
128- newInstances . push ( {
129+ const getColor = ( nodeId ) => {
130+ const insts = instances . filter ( ( instance ) => instance . instancePath === nodeId ) ;
131+ const hasChildren = instances . some ( ( instance ) => instance . instancePath . startsWith ( nodeId ) && instance . instancePath !== nodeId ) ;
132+ if ( props . children . length === 0 && insts . length > 0 && "color" in insts [ 0 ] ) {
133+ return insts [ 0 ] . color
134+ }
135+ // we check if all children have the same color
136+ const children = instances . filter ( ( instance ) => instance . instancePath . startsWith ( nodeId ) && instance . instancePath !== nodeId ) ;
137+ if ( children . length === 0 ) {
138+ return defaultColor ;
139+ }
140+ const color = children [ 0 ] . color ;
141+ if ( children . every ( x => x . color && x . color . hex === color . hex ) ) {
142+ return color
143+ }
144+ return { hex : "#989898" }
145+ }
146+
147+ const randomColor = ( ) => {
148+ const [ r , g , b ] = [ Math . random ( ) * 255 , Math . random ( ) * 255 , Math . random ( ) * 255 ] ;
149+ return {
150+ r : parseFloat ( r . toFixed ( 2 ) ) ,
151+ g : parseFloat ( g . toFixed ( 2 ) ) ,
152+ b : parseFloat ( b . toFixed ( 2 ) ) ,
153+ a : 1 ,
154+ hex : "#" + ( r >> 0 ) . toString ( 16 ) + ( g >> 0 ) . toString ( 16 ) + ( b >> 0 ) . toString ( 16 )
155+ }
156+ }
157+
158+ const translateColor = ( _color ) => {
159+ return {
160+ r : _color . r / 255 ,
161+ g : _color . g / 255 ,
162+ b : _color . b / 255 ,
163+ a : _color . a ,
164+ hex : _color . hex
165+ }
166+ }
167+
168+ const collectAllChildren = ( instance ) => {
169+ const children = [ ...instance . getChildren ( ) ]
170+ children . forEach ( child => children . push ( ...collectAllChildren ( child ) ) )
171+ return children
172+ }
173+
174+ const handleLeafColorChange = ( event , nodeId , colorGenerator ) => {
175+ const updateInstances = instances . filter ( ( instance ) => ! instance . pathInstance . startsWith ( nodeId ) ) ;
176+ updateInstances . push ( {
129177 instancePath : nodeId ,
130- color : {
131- r : _color . rgb . r / 255 ,
132- g : _color . rgb . g / 255 ,
133- b : _color . rgb . b / 255 ,
134- a : _color . rgb . a ,
135- } ,
178+ color : translateColor ( colorGenerator ( ) )
136179 } ) ;
137- dispatch ( changeInstanceColor ( newInstances ) ) ;
138- setColor ( _color . rgb ) ;
139- event . stopPropagation ( ) ;
140- event . preventDefault ( ) ;
141- } ;
142-
143- const getRandomColor = ( ) => ( {
144- r : parseFloat ( ( Math . random ( ) * 255 ) . toFixed ( 2 ) ) ,
145- g : parseFloat ( ( Math . random ( ) * 255 ) . toFixed ( 2 ) ) ,
146- b : parseFloat ( ( Math . random ( ) * 255 ) . toFixed ( 2 ) ) ,
147- a : 1 ,
148- } ) ;
180+ dispatch ( changeInstanceColor ( updateInstances ) ) ;
181+ }
149182
150- const generateRandomColor = ( event , nodeId ) => {
183+ const handleContainerColorChange = ( event , nodeId , colorGenerator ) => {
151184 event . stopPropagation ( ) ;
152185 event . preventDefault ( ) ;
153- const children = window . Instances . getInstance ( nodeId ) . getChildren ( ) . map ( ( instance ) => instance . getInstancePath ( ) ) ;
154- // const newInstances = instances.filter((instance) => !(instance.instancePath.startsWith(nodeId)));
155- const newInstances = instances . filter ( ( instance ) => {
186+
187+ const childrenPaths = collectAllChildren ( window . Instances . getInstance ( nodeId ) )
188+ . filter ( ( instance ) => ! instance . getChildren ( ) || instance . getChildren ( ) . length === 0 )
189+ . map ( ( instance ) => instance . getInstancePath ( ) ) ;
190+ const children = childrenPaths . filter ( ( path ) => path . startsWith ( nodeId ) ) ;
191+ const updateInstances = instances . filter ( ( instance ) => {
156192 let condition = true ;
157193 children . forEach ( ( child ) => {
158194 if ( instance . instancePath . startsWith ( child ) ) {
@@ -161,21 +197,22 @@ const ControlPanelTreeItem = (props) => {
161197 } ) ;
162198 return condition ;
163199 } ) ;
164-
165200 children . forEach ( ( child ) => {
166- const randomColor = getRandomColor ( ) ;
167- newInstances . push ( {
201+ updateInstances . push ( {
168202 instancePath : child ,
169- color : {
170- r : randomColor . r / 255 ,
171- g : randomColor . g / 255 ,
172- b : randomColor . b / 255 ,
173- a : randomColor . a ,
174- } ,
203+ color : translateColor ( colorGenerator ( ) )
175204 } ) ;
176205 } ) ;
177- dispatch ( changeInstanceColor ( newInstances ) ) ;
178- } ;
206+ dispatch ( changeInstanceColor ( updateInstances ) ) ;
207+ }
208+
209+ const handleColorChange = ( event , nodeId , colorGenerator ) => {
210+ if ( props . children . length === 0 ) {
211+ handleLeafColorChange ( event , nodeId , colorGenerator ) ;
212+ return
213+ }
214+ handleContainerColorChange ( event , nodeId , colorGenerator ) ;
215+ }
179216
180217 const changeVisibility = ( event , nodeId ) => {
181218 event . stopPropagation ( ) ;
@@ -232,8 +269,8 @@ const ControlPanelTreeItem = (props) => {
232269 label = { (
233270 < Grid
234271 container
235- onMouseEnter = { ( ) => setTimeout ( setIsHoveredOver ( true ) , 10000 ) }
236- onMouseLeave = { ( ) => setTimeout ( setIsHoveredOver ( false ) , 10000 ) }
272+ onMouseEnter = { ( ) => setIsHoveredOver ( true ) }
273+ onMouseLeave = { ( ) => { setIsHoveredOver ( false ) ; setShowColorPicker ( false ) } }
237274 display = "flex"
238275 flexDirection = "row"
239276 justifyContent = "space-between"
@@ -257,38 +294,36 @@ const ControlPanelTreeItem = (props) => {
257294 < IconButton onClick = { ( event ) => changeVisibility ( event , nodeId ) } >
258295 { visibility ? < Visibility style = { { marginRight : '0.5rem' } } /> : < VisibilityOff style = { { marginRight : '0.5rem' } } /> }
259296 </ IconButton >
260- < IconButton onClick = { ( event ) => {
261- event . stopPropagation ( ) ;
262- event . preventDefault ( ) ;
263- setShowColorPicker ( true ) ;
264- } }
265- >
266- < ColorLensIcon className = { showColorPicker ? classes . activeColorPicker : '' } />
297+ < IconButton disabled = { disableRandom } onClick = { ( event ) => handleColorChange ( event , nodeId , randomColor ) } >
298+ < RandomColorLensIcon style = { { marginRight : '0.5rem' } } />
267299 </ IconButton >
268- < IconButton disabled = { disableRandom } onClick = { ( event ) => generateRandomColor ( event , nodeId ) } >
269- < RandomColorLensIcon />
270- </ IconButton >
271- {
272- showColorPicker
300+ </ >
301+ )
302+ : null }
303+ < IconButton onClick = { ( event ) => {
304+ event . stopPropagation ( ) ;
305+ event . preventDefault ( ) ;
306+ setShowColorPicker ( true )
307+ } } >
308+ < SquareIcon fillColor = { getColor ( nodeId ) . hex } />
309+
310+ </ IconButton >
311+ { showColorPicker && isHoveredOver
273312 ? (
274313 < Box
275314 className = { classes . colorPickerBox }
276- onMouseLeave = { ( ) => setTimeout ( setShowColorPicker ( false ) , 30000 ) }
315+ onMouseLeave = { ( ) => setShowColorPicker ( false ) }
277316 >
278- { /* <TriangleIcon className={classes.triangleIcon} /> */ }
279317 < ChromePicker
280318 className = { classes . colorPicker }
281- color = { color }
319+ color = { getColor ( nodeId ) . hex }
282320 onChangeComplete = { ( color , event ) => {
283- handleColorSelection ( color , event , nodeId ) ;
321+ handleColorChange ( event , nodeId , ( ) => { return { ... color . rgb , hex : color . hex } } ) ;
284322 } }
285323 />
286324 </ Box >
287325 ) : null
288- }
289- </ >
290- )
291- : null }
326+ }
292327 </ Grid >
293328 </ Grid >
294329 ) }
0 commit comments