Jane wrote:
> What about one huge Fl_Widget[] array. Since each parameter has a unique
> ID starting by 0 and ending at 1900+ something, the index of that array
> is also the parameter ID (we knew that already).
> 
> But since I know what kind of widget is used for each parameter, 
> I can decide on incomung MIDI data what to update.

> (MIDI comes in)
> ..
> if (parameter == 0 || (parameter >= 12 && parameter <= 24)) // slider
>   ui->set_slider(parameter, value);
> else if ... // spinners
>   ui->set_spinner(parameter, value);

        Yes, I think this would be the 'wrapper object' approach, where
        'ui' is an object that is a wrapper around all the possible
        widgets a midi event can be.

        But with this approach you don't need separate set_xxx() methods,
        you could just have one, and have all the logic for how to set
        the value within the single SetValue() method.

        Here's one way to do it, where the 'wrapper' object can contain
        pointers to all the types of objects (spinners, sliders), and
        has a single method that converts them. eg:


class Midi_UI {
    Fl_Slider *slider;
    Fl_Spinner *spinner;
    [..]
    // INITIALIZERS
    //    Set what type of widget we are.
    //
    void InitSlider(Fl_Slider *val)   { slider = val; spinner = 0; }
    void InitSpinner(Fl_Spinner *val) { spinner = val; slider = 0; }
    [..]
    // SET THE WIDGET TO A VALUE
    //    Depending on what we are, a slider or spinner, set its value.
    //
    void SetValue(float value) {
             if ( slider  ) slider->set_slider(value);
        else if ( spinner ) spinner->set_spinner(value);
    }
    float GetValue() {
        [..similar logic..]
    }
};


        Then you can create a single monolithic array of these
        at program startup:


Midi_UI *ui_array[1900];
    :
int main(..) {
    :
    // ARRAY INITIALIZATION
    for ( int id = 0; id<1900; id++ ) {
        Midi_UI *ui = new Midi_UI();
        ui_array[id] = ui;
        // SLIDERS VS SPINNERS
        if ( id == 0 || id >= 12 && id <= 24 ) {        // logic for slider
            Fl_Slider *slide = new Fl_Slider(..);
            ui->InitSlider(slider);
        } else {                                        // logic for spinner
            Fl_Spinner *spin = new Fl_Spinner(..);
            ui->InitSpinner(spin);
        }
    }


        This way you're defining the logic once at initialization,
        building the logic 'into the array', rather than parsing
        the logic each time an event comes in.

        Then handling an event becomes simple:


void HandleMidiEvent(int id, float value) {
    ui_array[id]->SetValue(value);
}


        ..and the simple logic in SetValue() figures out
        which kind of widget it is.

        This way there's only simple logic in the class, so
        you don't have to have complicated if() statements spread
        out throughout the program for Get/Set methods.

        This also ensures all the "bookkeeping" for which-is-which
        is managed within the Midi_UI class, and therefore unlikely
        to accidentally interpret a slider as a spinner (or vice versa),
        which could crash the app if done wrong.

        This also makes it easy to re-assign sliders/spinners later.
        With hardcoded logic (like in the above for initialization)
        it would be impossible to reprogram things at run time without
        looping through min/max arrays.

        Hope that helps.
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to