On 2008-10-18, Albrecht Schlosser <[EMAIL PROTECTED]> wrote:
> Jane wrote:
>> hello,
>> 
>> this is the situation:
>> main() creates an instance of my "ui" class which contains 
>> a piano widget. main calls ui->startup(); which first shows 
>> a window of ui and then creates instances of other objects 
>> which will then feed the ui widgets with some data.
>> the piano widget is one of those receivers. the data it 
>> receives will be used with information with x() and y() 
>> values of piano. so, piano receives the external data, 
>> calculates some values based on this data and x() and y(), 
>> and is happy.
>> but, sometimes it happens that the piano doesnt know its 
>> x() and y() in the moment the data is being received, 
>> resulting in garbage data.
>
> Why do you think that the piano widget doesn't know its x() and y()? 
> This can't happen at all, because the widget knows its x() and y() 
> immediately after (and even within) its constructor, regardless if it 
> has been drawn already or not. However, it may or may not know its 
> absolute display coordinates, if the window has not been displayed yet.
>

well, ok then, this problem is no more, i do the 
calculation in the constructor, that fixes it. :)

>> now, the x() and y() information is available when the 
>> piano widget is first being drawn, right?
>
> Sure, that's true, but it shouldn't matter (see above). What are you 
> doing with the piano widget's x() and y() coordinates that is needed to 
> do this startup processing?
>
>> why isnt piano finished drawing when i instanciate my other 
>> objects AFTER calling w_main->show(); ?
>
> You should read what Ian wrote to answer this question.
>
>>     w_main->show();
>>     ctrl = new ctrl(); // gets external data, feeds it to 
>> widget...widget however has not been drawn yet.
>
> To help you more, we would surely need to see more of your code, at 
> least more of your main() program. I assume that all this happens before 
> you call Fl::run(). Although calling Fl::check() can help much (as Ian 
> wrote), I wouldn't try to do this, unless you know exactly, why you are 
> doing it. When I once had a similar startup problem, I used an idle 
> callback or a timeout with a short time to do the startup code after 
> initializing the UI, something like (only short pseudo code):
>
> main()
> {
>    gui *win = new gui(...);
>    add more widgets here.
>    win->show(...);
>    Fl::add_idle(...); // or Fl::add_timeout(...)
>    Fl::run();
> }
>
> The idle or timeout callback can then do more initialization, after the 
> gui has been initialized.
>
> Albrecht

ok, here is more detail:

int main(int argc, char *argv[])
{
        pmesg(40, "main()\n");
    ui = new Prodatum_UI();
        ui->startup(argc, argv);
    Fl::lock();
        return Fl::run();
}

void Prodatum_UI::startup(int argc, char **argv) {
pmesg(20, "---- ui ---- Prodatum_UI::startup()\n");
w_main->show();
ctrl = new Prodatum_CTRL();
Parse_Config();
if (midiDevice != -1 && midi_outports[midiDevice] != 0)
        ctrl->Connect(midiDevice);
else
{
        char message[BUF_MSG];
        sprintf(message, "Please select an ID and MIDI port.");
        Update_Status((const char*) &message);
}



rolling:

main()
---- ui ---- prodatum_ui::Prodatum_UI()
---- ui ---- Prodatum_UI::startup()
>>> ctrl <<< Prodatum_CTRL::Prodatum_CTRL()
>>> midi <<< Prodatum_MIDI::GetSystemMIDIDevices()
---- ui ---- Prodatum_UI::Parse_Config()
>>> ctrl <<< Prodatum_CTRL::Connect(2)
---- ui ---- Prodatum_UI::Enable(0)
>>> midi <<< Prodatum_MIDI::Prodatum_MIDI(2)
>>> midi <<< Prodatum_MIDI::Device_Inquiry()
>>> midi <<< Prodatum_MIDI::Wait_For_Dump()
>>> midi <<< Prodatum_MIDI::Process_SysEx(15)
>>> midi <<< Prodatum_MIDI::Wait_For_Dump()
>>> midi <<< Prodatum_MIDI::Process_SysEx(18)
### data ### Prodatum_Data::Prodatum_Data()
### data ### Prodatum_Data::Initialize_Data()
### data ### check_datadir(/home/vvd/.prodatum/516_5)
### data ### Prodatum_Data::Fill_Browsers()
+++ Wid +++ Wid::cb(897)
>>> ctrl <<< Prodatum_CTRL::UI_To_Data(897, 384)
---- ui ---- Prodatum_UI::Enable(0)
### data ### Prodatum_Data::Parameter_Value_Edit(1, 897, 384)
>>> midi <<< Prodatum_MIDI::Parameter_Value_Edit(2, 7, 1, 0)
>>> midi <<< Prodatum_MIDI::Parameter_Value_Edit(1, 7, 0, 3)
### data ### Prodatum_Data::Load_Preset_Dump(384)
### data ### Prodatum_Data::Dump_To_UI(384)
>>> ctrl <<< Prodatum_CTRL::Data_To_UI(915, 1992)
### data ### Prodatum_Data::Parameter_Value_Request(1409, 1)
### data ### Prodatum_Data::IDMap(1409, 1)
### data ### Prodatum_Data::Parameter_Value_Request(1410, 1)
### data ### Prodatum_Data::IDMap(1410, 1)

... (more of that, piano has not been drawn yet, doesnt 
matter as its fixed but anyway...that MADE me wonder)

...oh, here comes data for the piano:

### data ### Prodatum_Data::Parameter_Value_Request(1416, 0)
### data ### Prodatum_Data::IDMap(1416, 0)
$$$ Piano $$$ Piano::Set_Range_Values(0, 0, 84, 0, 127, 0)
### data ### Prodatum_Data::Parameter_Value_Request(1413, 1)

... more data for the piano

shortly after we have all the data and finally the piano is 
shown:

$$$ Piano $$$ Piano::draw()
$$$ Piano $$$ Piano::draw_piano()
$$$ Piano $$$ Piano::draw_ranges()

at this point the UI is ready to be used.

so, what happens in this Piano::Set_Range_Values method?


void Piano::Set_Range_Values(int md, int layer, int low_k, int low_f,
                int high_k, int high_f)
{
        pmesg(40,
                        "$$$ Piano $$$ Piano::Set_Range_Values(%d, %d, %d, %d, 
%d, %d)\n",
                        md, layer, low_k, low_f, high_k, high_f);
    dragbox[md][layer][low_key][0] = taste_x0[low_k][0];
        dragbox[md][layer][low_fade][0] = taste_x0[low_k + low_f][0];
        dragbox[md][layer][high_key][0] = taste_x0[high_k][0];
        dragbox[md][layer][high_fade][0] = taste_x0[high_k - high_f][0];
        for (int i = 0; i < 4; i++) // center on white keys
        {
                if ((dragbox[md][layer][i][0] - keyboard_x0) % 14 == 0)
                        dragbox[md][layer][i][0] += 3; // center on white keys
        }
}

to understand it you need to know about taste_x0[127][2]
well, thats x() and (y) coordinates for every of those 128 
keys of the piano.  so this function maps keys to 
coordinates.  (the data i receive are key-values, eg where 
on the keyboard are we).  to set my range sliders (you 
remember) accordingly, i have to map these keys to some 
position in 2d-space. so far so good.

what i did was (silly): i calculated those values in 
Piano::draw() and not in Piano::Piano(). :D

so, no need for some wait or idle or sleep..

thank you Albrecht, thank you Ian!
jane
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to