Buggy GeDialog Local2Global and Local2Screen



  • Hi again,
    In continuation of the whole GeDialog and mouse positions I need to report that GeDialog::Local2Global and GeDialog::Local2Screen do not seem to work as one would expect.

    In a CommandData::Execute:

    	BaseContainer bc;
    	if (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc))
    	{
    		const Int32 mx = bc.GetInt32(BFM_INPUT_X);
    		const Int32 my = bc.GetInt32(BFM_INPUT_Y);
    
    		const Int32 w = 50;
    		const Int32 h = 50;
    		mDlg.Open(DLG_TYPE::ASYNC_POPUPEDIT, TEST_COMMAND_PLUGIN_ID, mx, my, w, h, 0);
    
    		ApplicationOutput("Mouse cursor at @, @", mx, my);
    		Int32 dlgX = 0;
    		Int32 dlgY = 0;
    		mDlg.Local2Screen(&dlgX, &dlgY);
    		ApplicationOutput("Dialog created at @, @ (screen)", dlgX, dlgY);
    		dlgX = 0;
    		dlgY = 0;
    		mDlg.Local2Global(&dlgX, &dlgY);
    		ApplicationOutput("Dialog created at @, @ (global)", dlgX, dlgY);
    	}
    

    With the main Cinema4D application window open full screen (on a single monitor setup), the following result is obtained:

    GeDialog Positions NOK.png

    Notice the 179, 280 values from Local2Screen ... and 25, 25 from Local2Global ???
    These can't be right.



  • Hi @C4DS, thanks for reaching out us.

    I had very little time to better investigate the issue but on top of your behavior, I also spotted different results between mac and win. I'll dig more next week.

    Best, R



  • @r_gigante

    I didn't test on macOS yet. I seem to remember there was already an issue with the menu on macOS, especially the option/cog-wheel for plugins (see this topic).
    As such I assume the difference you encounter might be related to this (?).

    Trying out Screen2Local and Global2Local do provide the same erroneous result, which seems obvious as the internals of these methods will probably use similar functionality as their "mirror/reverse" counterparts (i.e. Local2Screen, Local2Global).
    Have tried same functionality using R16 and R19 SDK and can confirm same issues there. Not tested with R17 and R18, but I expect same results as well.

    From this I gather no one ever used these methods.



  • @C4DS said in Buggy GeDialog Local2Global and Local2Screen:

    From this I gather no one ever used these methods.

    There is an example of how to use a function in the documentation: GeDialog Manual.

    Not sure if it is related to your issue.



  • @PluginStudent said in Buggy GeDialog Local2Global and Local2Screen:

    There is an example of how to use a function in the documentation: GeDialog Manual.

    Right, I should be more careful with my assumptions.

    But apparently, no one tried to use Local2Screen outside of GeDialog::Command, as only inside of that method does it return appropriate values. (I tried in GeDialog::CreateLayout and GeDialog::InitValues)

    As for Local2Global, I cannot get it to return meaningful values outside nor inside GeDialog::Command.



  • Any update on this one?



  • Hi Daniel, after some investigation, it has been found that, as from your special case, having a completely empty dialog (ASYNC_POPUPEDIT) means there's nothing to layout. Therefore, the empty dialog content is centered in the window which means Local2Screen does account for that offset.
    That's legacy behavior of the layouter and probably has been like that since the last century.
    If the dialog presents items to display the Local2Screen and Local2Global behave correctly as from the tests we ran here.

    Best, R



  • @r_gigante
    Sorry Riccardo, I do not understand your reply.

    I had tried with empty as well as non-empty dialogs.
    Both as DLG_TYPE::ASYNC and DLG_TYPE::ASYNC_POPUPEDIT.
    Still with these 4 combinations I do not get appropriate values for the global position.

    Bool MyDialog::CreateLayout()
    {
    	Bool res = GeDialog::CreateLayout();
    
    	GroupBegin(0, BFH_SCALEFIT | BFV_SCALEFIT, 2, 0, ""_s, 0);
    
    	AddButton(ACTION_1, BFH_CENTER | BFV_CENTER, 200, 10, "button A"_s);
    	AddButton(ACTION_2, BFH_CENTER | BFV_CENTER, 300, 10, "button B"_s);
    	AddEditText(ACTION_3, BFH_CENTER | BFV_CENTER, 500, 10);
    
    	GroupEnd();
    
    	return res;
    }
    
    Bool MyCommand::Execute(BaseDocument* doc)
    {
    	if (mDlg.IsOpen())
    	{
    		mDlg.Close();
    		return true;
    	}
    
    	BaseContainer bc;
    	if (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc))
    	{
    		const Int32 mx = bc.GetInt32(BFM_INPUT_X);
    		const Int32 my = bc.GetInt32(BFM_INPUT_Y);
    
    		const Int32 w = 50;
    		const Int32 h = 50;
    		mDlg.Open(DLG_TYPE::ASYNC /*ASYNC_POPUPEDIT*/, TEST_COMMAND_PLUGIN_ID, mx, my, w, h, 0);
    
    		ApplicationOutput("Mouse cursor at @, @", mx, my);
    		Int32 dlgX = 0;
    		Int32 dlgY = 0;
    		mDlg.Local2Screen(&dlgX, &dlgY);
    		ApplicationOutput("Dialog created at @, @ (screen)", dlgX, dlgY);
    		dlgX = 0;
    		dlgY = 0;
    		mDlg.Local2Global(&dlgX, &dlgY);
    		ApplicationOutput("Dialog created at @, @ (global)", dlgX, dlgY);
    	}
    
    	return true;
    }
    

    Additionally, when activating the plugin when Cinema4D is fullscreen, the dialog gets positioned at the expected coordinates. But the position of the dialog is nowhere near the expected position if the plugin is activated when the Cinema4D window is not full screen.
    It seems as if the mouse coordinates relative to the application window are applied relative to the screen origin.

    Which means that if:
    1 Cinema4D is not full screen
    2 and offset from the top left corner of the screen by an amount X
    3 assuming the mouse position is at coordinate mx from the Cinema4D's main window's top left corner
    The dialog ends up at mx from the screen's top left corner, instead of the expected X + mx.

    (All the above was tested with R20 only, since I have refrained from further R21 development)

    Unfortunately, I have moved on and am currently not focused on this particular plugin anymore. As such, I may have missed some details. I will need to find the time to pick up where I had left.