@@ -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
@@ -117,41 +116,66 @@ 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 ) ;
125-
126- const handleColorSelection = ( _color , event , nodeId ) => {
127- const newInstances = instances . filter ( ( instance ) => ! ( instance . instancePath . startsWith ( nodeId ) ) ) ;
128- newInstances . push ( {
129- 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- } ,
136- } ) ;
137- dispatch ( changeInstanceColor ( newInstances ) ) ;
138- setColor ( _color . rgb ) ;
139- event . stopPropagation ( ) ;
140- event . preventDefault ( ) ;
121+ const defaultColor = {
122+ g : 0.50 ,
123+ b : 0.60 ,
124+ r : 1 ,
125+ a : 1 ,
126+ hex : "#FF7F99"
141127 } ;
142128
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- } ) ;
129+ const getColor = ( nodeId ) => {
130+ const insts = instances . filter ( ( instance ) => instance . instancePath === nodeId ) ;
131+ if ( insts . length > 0 && "color" in insts [ 0 ] ) {
132+ return insts [ 0 ] . color
133+ }
134+ // we check if all children have the same color
135+ const children = instances . filter ( ( instance ) => instance . instancePath . startsWith ( nodeId ) && instance . instancePath !== nodeId ) ;
136+ if ( children . length === 0 ) {
137+ return defaultColor ;
138+ }
139+ const color = children [ 0 ] . color ;
140+ if ( children . every ( x => x . color && x . color . hex === color . hex ) ) {
141+ return color
142+ }
143+ return { hex : "#989898" }
144+ }
149145
150- const generateRandomColor = ( event , nodeId ) => {
151- event . stopPropagation ( ) ;
152- event . preventDefault ( ) ;
146+ const randomColor = ( ) => {
147+ const [ r , g , b ] = [ Math . random ( ) * 255 , Math . random ( ) * 255 , Math . random ( ) * 255 ] ;
148+ return {
149+ r : parseFloat ( r . toFixed ( 2 ) ) ,
150+ g : parseFloat ( g . toFixed ( 2 ) ) ,
151+ b : parseFloat ( b . toFixed ( 2 ) ) ,
152+ a : 1 ,
153+ hex : "#" + ( r >> 0 ) . toString ( 16 ) + ( g >> 0 ) . toString ( 16 ) + ( b >> 0 ) . toString ( 16 )
154+ }
155+ }
156+
157+ const translateColor = ( _color ) => {
158+ return {
159+ r : _color . r / 255 ,
160+ g : _color . g / 255 ,
161+ b : _color . b / 255 ,
162+ a : _color . a ,
163+ hex : _color . hex
164+ }
165+ }
166+
167+ const handleColorChange = ( event , nodeId , colorGenerator ) => {
153168 const children = window . Instances . getInstance ( nodeId ) . getChildren ( ) . map ( ( instance ) => instance . getInstancePath ( ) ) ;
154- // const newInstances = instances.filter((instance) => !(instance.instancePath.startsWith(nodeId)));
169+ if ( children . length === 0 ) { // If we're on a leaf, we do a classical color change
170+ const newInstances = instances . filter ( ( instance ) => ! ( instance . instancePath . startsWith ( nodeId ) ) ) ;
171+ newInstances . push ( {
172+ instancePath : nodeId ,
173+ color : translateColor ( colorGenerator ( ) )
174+ } ) ;
175+ dispatch ( changeInstanceColor ( newInstances ) ) ;
176+ return
177+ }
178+ // Otherwise, we need to change to color of children also
155179 const newInstances = instances . filter ( ( instance ) => {
156180 let condition = true ;
157181 children . forEach ( ( child ) => {
@@ -163,18 +187,16 @@ const ControlPanelTreeItem = (props) => {
163187 } ) ;
164188
165189 children . forEach ( ( child ) => {
166- const randomColor = getRandomColor ( ) ;
167190 newInstances . push ( {
168191 instancePath : child ,
169- color : {
170- r : randomColor . r / 255 ,
171- g : randomColor . g / 255 ,
172- b : randomColor . b / 255 ,
173- a : randomColor . a ,
174- } ,
192+ color : translateColor ( colorGenerator ( ) ) ,
175193 } ) ;
176194 } ) ;
177195 dispatch ( changeInstanceColor ( newInstances ) ) ;
196+ if ( event ) {
197+ event . stopPropagation ( ) ;
198+ event . preventDefault ( ) ;
199+ }
178200 } ;
179201
180202 const changeVisibility = ( event , nodeId ) => {
@@ -232,8 +254,8 @@ const ControlPanelTreeItem = (props) => {
232254 label = { (
233255 < Grid
234256 container
235- onMouseEnter = { ( ) => setTimeout ( setIsHoveredOver ( true ) , 10000 ) }
236- onMouseLeave = { ( ) => setTimeout ( setIsHoveredOver ( false ) , 10000 ) }
257+ onMouseEnter = { ( ) => setIsHoveredOver ( true ) }
258+ onMouseLeave = { ( ) => { setIsHoveredOver ( false ) ; setShowColorPicker ( false ) } }
237259 display = "flex"
238260 flexDirection = "row"
239261 justifyContent = "space-between"
@@ -257,38 +279,36 @@ const ControlPanelTreeItem = (props) => {
257279 < IconButton onClick = { ( event ) => changeVisibility ( event , nodeId ) } >
258280 { visibility ? < Visibility style = { { marginRight : '0.5rem' } } /> : < VisibilityOff style = { { marginRight : '0.5rem' } } /> }
259281 </ IconButton >
260- < IconButton onClick = { ( event ) => {
261- event . stopPropagation ( ) ;
262- event . preventDefault ( ) ;
263- setShowColorPicker ( true ) ;
264- } }
265- >
266- < ColorLensIcon className = { showColorPicker ? classes . activeColorPicker : '' } />
267- </ IconButton >
268- < IconButton disabled = { disableRandom } onClick = { ( event ) => generateRandomColor ( event , nodeId ) } >
269- < RandomColorLensIcon />
282+ < IconButton disabled = { disableRandom } onClick = { ( event ) => handleColorChange ( event , nodeId , randomColor ) } >
283+ < RandomColorLensIcon style = { { marginRight : '0.5rem' } } />
270284 </ IconButton >
271- {
272- showColorPicker
285+ </ >
286+ )
287+ : null }
288+ < IconButton onClick = { ( event ) => {
289+ event . stopPropagation ( ) ;
290+ event . preventDefault ( ) ;
291+ setShowColorPicker ( true )
292+ } } >
293+ < SquareIcon fillColor = { getColor ( nodeId ) . hex } />
294+
295+ </ IconButton >
296+ { showColorPicker && isHoveredOver
273297 ? (
274298 < Box
275299 className = { classes . colorPickerBox }
276- onMouseLeave = { ( ) => setTimeout ( setShowColorPicker ( false ) , 30000 ) }
300+ onMouseLeave = { ( ) => setShowColorPicker ( false ) }
277301 >
278- { /* <TriangleIcon className={classes.triangleIcon} /> */ }
279302 < ChromePicker
280303 className = { classes . colorPicker }
281- color = { color }
304+ color = { getColor ( nodeId ) . hex }
282305 onChangeComplete = { ( color , event ) => {
283- handleColorSelection ( color , event , nodeId ) ;
306+ handleColorChange ( event , nodeId , ( ) => { return { ... color . rgb , hex : color . hex } } ) ;
284307 } }
285308 />
286309 </ Box >
287310 ) : null
288- }
289- </ >
290- )
291- : null }
311+ }
292312 </ Grid >
293313 </ Grid >
294314 ) }
0 commit comments