Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Inconsistent GeDialog::Open position

    Cinema 4D SDK
    r20 c++ r21
    3
    5
    650
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • C4DSC
      C4DS
      last edited by r_gigante

      Hi,
      After the weird mouse position and screen dimensions stuff (see appropriate topic), I once more got side tracked by inconsistent behaviour I simply cannot explain.

      Here is some simple code to demonstrate the problem. All you need extra is an icon file "Test.png".
      The purpose of this testing plugin is to open a dialog. As you may notice I am using -1 for x and y position to let the dialog open at the current mouse position ...

      // Main.cpp
      
      #include "c4d.h"
      
      #define TEST_COMMAND_PLUGIN_ID	1000001
      
      
      // ====================================
      // GeDialog
      // ====================================
      
      class MyDialog : public GeDialog
      {
      public:
      	virtual Bool CreateLayout(void);
      };
      
      Bool MyDialog::CreateLayout()
      {
      	Bool res = GeDialog::CreateLayout();
      
      	GroupBegin(0, BFH_SCALEFIT | BFV_SCALEFIT, 1, 0, ""_s, 0);
      
      	// .. TODO
      
      	GroupEnd();
      
      	return res;
      }
      
      // ====================================
      // CommandData
      // ====================================
      
      class MyCommand : public CommandData
      {
      	INSTANCEOF(MyCommand, CommandData)
      
      public:
      
      	virtual Bool Execute(BaseDocument* doc, GeDialog* parentManager);
      	virtual Bool RestoreLayout(void* secret);
      
      	MyDialog mDlg;
      };
      
      Bool MyCommand::Execute(BaseDocument* doc, GeDialog* parentManager)
      {
      	if (mDlg.IsOpen())
      	{
      		mDlg.Close();
      		return true;
      	}
      
      	BaseContainer bc;
      	if (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc))
      	{
      		const Int32 x = -1;
      		const Int32 y = -1;
      		const Int32 w = 50;
      		const Int32 h = 50;
      		mDlg.Open(DLG_TYPE::ASYNC_POPUPEDIT, TEST_COMMAND_PLUGIN_ID, x, y, w, h, 0);
      	}
      
      	return true;
      }
      
      Bool MyCommand::RestoreLayout(void* secret)
      {
      	const Int32 subid = ((RestoreLayoutSecret*)secret)->subid;
      	return mDlg.RestoreLayout(TEST_COMMAND_PLUGIN_ID, subid, secret);
      }
      
      // ====================================
      // Plugin Main 
      // ====================================
      
      Bool PluginStart(void)
      {
      	ApplicationOutput("Test"_s);
      
      	if (!RegisterCommandPlugin(TEST_COMMAND_PLUGIN_ID, "Test"_s, 0, AutoBitmap("Test.png"_s), "Test"_s, NewObjClear(MyCommand)))
      		ApplicationOutput("Test - failed registering CommandData");
      
      	return true;
      }
      void PluginEnd(void)
      {
      }
      Bool PluginMessage(Int32 id, void * data)
      {
      	switch (id) {
      	case C4DPL_INIT_SYS:
      		if (!g_resource.Init())
      			return false;
      		return true;
      	case C4DMSG_PRIORITY:
      		return true;
      	case C4DPL_BUILDMENU:
      		break;
      	case C4DPL_ENDACTIVITY:
      		return true;
      	}
      	return false;
      }
      

      I have assigned a shortcut ( CTRL-T ) to the plugin, allowing me to execute the CommandData which will open the GeDialog using the current mouse position.
      An additional press of the shortcut will close the GeDialog, etc ...

      The first time the dialog is opened it is positioned centered at the current mouse position. Then all subsequent opening of the dialog gets it positioned with the topleft corner at the mouse position.
      Happens in R20 and R21. Why this inconsistency?

      Demonstration:

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by

        Hi,

        have you tried populating your dialog with some gadgets? My suspicion would be that the dialog is somehow initialised ignoring its minimum width and height arguments (500 in your case) and positioned with a height and width of zero under your cursor and only after that 'snaps' to its minimum height and width. Since you store a reference to the dialog and just reopen the dialog on subsequent executions of your plugin, the height and width are initialised then and the placement therefor correct.

        That all is pure speculation though.

        Cheers,
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • r_giganteR
          r_gigante
          last edited by

          Hi @C4DS, thanks for reaching out us.

          I confirm that the behavior you've reported is a bug and, as anticipated by @zipit, it's due to the fact that when the dialog is opened for the second time, an object then exists and the code follows a different path resulting in a different position of the dialog compared to the mouse position.

          You can mitigate the issue by using effective pointer position

          	if (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc))
          	{
          		Int32 xpos = bc.GetInt32(BFM_INPUT_X);
          		Int32 ypos = bc.GetInt32(BFM_INPUT_Y);
          		
          		const Int32 w = 50;
          		const Int32 h = 50;
          		mDlg.Open(DLG_TYPE::ASYNC_POPUPEDIT, TEST_COMMAND_PLUGIN_ID, xpos, ypos + h, w, h, 0);
          	}
          

          Best,

          C4DSC 1 Reply Last reply Reply Quote 0
          • C4DSC
            C4DS @r_gigante
            last edited by

            @r_gigante
            Thanks for the reply Riccardo.

            I was afraid the answer would be to use specific coordinates to position the GeDialog.
            From this other topic it was kind of clear that the mouse position is rather an ambiguous piece of information in a multi monitor setup.

            Nevertheless, thank you for your answer. Yet another mystery cleared.

            1 Reply Last reply Reply Quote 0
            • C4DSC
              C4DS
              last edited by

              Extra info!

              While I had set this topic as solved, without an actual WORKING solution being provided, I simply wanted to point out for future reference that R16 - R19 has a slight different behaviour.
              As with R20 and R21 the first time the dialog is opened it gets positioned centered on the current mouse position. On all subsequent opening it gets positioned with its upper left corner at 0,0.

              Something got "fixed" between R19 and R20, but not "fixed enough".

              1 Reply Last reply Reply Quote 1
              • First post
                Last post