GameOfLife / Unit-Lib

The Unit Library is a system that provides high level abstractions on top of the SuperCollider language.
25 stars 6 forks source link

UMassEdit gui - just one slider mode #27

Open miguel-negrao opened 10 years ago

miguel-negrao commented 10 years ago

Very often I would just like to set an argument of a bunch of units to the same value. Selecting them in the score and opening the edit window I have to set two values in the range slider. It would be useful to have a button to in the gui where it would switch from range slider to just one slider (for instance taking the value of the first unit) and from then on moving the slider would set all the units to the value.

I think this could be done just in the GUI. Have a button which removes the range slider and puts a normal slider and then moving the slider actually actually sets an array of values instead of single value. With the flowlayout stuff, I wonder how does one show and hide the range slider and single slider ? Put them both inside a composite view using absolute coordinates at 0@0 (the composite gets flowed) and then hide an unhide each one in alternate ?

woutersnoei commented 10 years ago

This can be achieved by using the "flat" item from the edit menu. It sets all values to a single one which is the mean of the range slider's range. But we could also create a single slider for this. Or perhaps a "lock range" button, which would make the size of the range slider's range unchangeable. Then you would need to hit "flat", and then lock the range to achieve what you want. Btw for alternating views I usually stack two CompositeViews on top of each other, and hide/show them via a menu. Check how it is done in FreqSpec:makeView

miguel-negrao commented 10 years ago

But after using "flat" if we move one of the sides of the value range only some of the values will change, others stay in the previous value. I guess a lock button would do the trick, I can look into that. Btw, for my own work, this mostly removes the need for UGlobalControl, since I can just select a whole susbscore and tweak the values of all units inside, which was my current use for UGlobalControl.

miguel-negrao commented 10 years ago

Had a go at doing the lock for the rangeslider but got stuck because when we move the range the function passed to action_ doesn't know if it was the lo or the hi part of the range that was moved... to then automatically reset the opposite one. Also, the range would only become unchanged unless neither of the edges would reach the end of the possible range, in which case the the range would obviously have to change.

        vws[ \lock ] = SmoothButton( view, 20 @ (bounds.height) )
                .states_( [
                    [ \unlock, Color.black, Color.clear ],
                    [ \lock, Color.black, Color.clear ]
                ] )
                .border_( 1 )
                .radius_( 2 )
                .font_( font )

        vws[ \rangeSlider ] = EZSmoothRanger( view, (width - 84) @ (bounds.height),
            nil, this, { |sl|
                var values, min, max;
                values = this.unmap( vws[ \val ] );
                vws[ \range ] = sl.value;
                #min, max = this.unmap( vws[ \range ] );
                if(vws[ \lock ].value.booleanValue) {
                    if( min == max ) { max = max + 1.0e-11 };
                    values = values.linlin( values.minItem, values.maxItem, min, max );
                    if( values.every(_==min) ) {
                        values = Array.series( values.size, min, ((max - min)/(values.size-1)) );
                    };
                    vws[ \val ] = this.map( values );
                } {
                    ??
                };
                vws[ \setPlotter ].value;
                action.value( vws, vws[ \val ] );
            }
        );
woutersnoei commented 10 years ago

hmm yes I can imagine this to be hard to do. It may need to be done inside SmoothRangeSlider itself. What we could also do is create a small slider above or under the range slider which would always only move the whole range. The range slider could be made for example 2/3 of it's current height, to make space for the single slider. The value of the single slider would always be the mean of the total. Moving it to one of the outer bounds would "flatten" the range, basically making it into one value for all. This could provide a fast way of doing what you want.

miguel-negrao commented 10 years ago

Yes, that sounds like it would get the job done without much work.

miguel-negrao commented 10 years ago

Thought a bit more about this: The average slider would solve this issue for the normal controls, and it would certainly be useful to have but there is still the issue of how to deal with multiple units with "smart" controls such as the eqs, envelope editors, etc. One idea would be to have a single mode which is turned on or off for the whole unit with a button on the header of each unit in the gui, which would just take the current state from the first unit in the array, present the normal gui as if there was only one unit, but when something was changed it would change all the units. So for the envelopes or eqs, one could still use the normal gui. Haven't though about how to implement that though.

woutersnoei commented 10 years ago

yes that would make sense indeed. It brings up two questions to me:

miguel-negrao commented 10 years ago

what would we call this feature (preferably a nice and short name that fits in a button :-) ) ?

an "S" for "single mode" ?

would the change take effect only when you touch a slider / gui, or would we change all parameters of a unit immediately as soon as the "single-unit-link-gui" is activated?

I would say only after touching a slider/gui, so as not to disturb values that don't need to be disturbed, but I don't have a strong opinion about it. Btw, it might be nice to have undo also on the UChain GUI...