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