I need this information to position floating UI elements around other Eto controls. Control.PointToScreen uses a coordinate system with its origin situated below the Windows menu bar, which results in an offset in relation to the parent Eto control.
var controlToLogicalScreen = ControlToDockTo.PointToScreen(dockingLocation);
var logicalScreenToNativeScreen = EtoHelpers.LogicalToScreen(controlToLogicalScreen );
var screenToAbsolute = new Point(OffsetPoint(logicalScreenToNativeScreen ));
var absoluteToLogical = new Point(EtoHelpers.ScreenToLogical(logicalToScreen));
Where LogicalToScreen and ScreenToLogical are methods suggested by @curtisw in this thread:
and OffsetPoint is a method using user32.dll to find the ClientRectangle of the main Rhino window.
RhinoView gives us access to ScreenRectangle, which can be nicely translated to Eto’s logical screen coordinates. Is there a similar way of retrieving true screen coordinates of Eto controls? @CallumSykes, @dale, maybe you can help?
The RhinoEtoApp.MainWindow is not a true Eto Window, so doesn’t have all of the properties set. That being said, let’s review why you want this. You want to position elements on the screen relative to elements in your panel?
yes, I want to create custom tooltips whose position is relative to other Eto controls. Some of these will be hosted on the panel, others are attached to viewport as HUD elements. The tooltip is a simple Eto.Forms.Form.
I have solved the offset issue. Control.PointToScreen works as expected and returns the correct screen coordinate.
The reason why it was failing for me, was because the form was attached to a native Window using user32.dll. Commenting it out fixes the offset, but creates another question: how can we make a floating form move with the main Rhino window? I need this to create fixed HUD elements. Win32Window.AddControl does the trick on Windows but is there a cross-platform solution I could use from Eto?
public class DockedForm : Form
{
public Control ControlToDockTo;
public bool DockedToViewport;
public bool DockedToControl;
public DockedForm()
{
//var mainWindow = new System.Windows.Win32Window(RhinoApp.MainWindowHandle());
//mainWindow.AddControl(new System.Windows.Win32Window(NativeHandle)); // Move with Rhino window when dragging
base.WindowStyle = WindowStyle.None;
Style = "transparent";
RhinoView.Modified -= RhinoView_Modified; // Move with Rhino window when resizing
RhinoView.Modified += RhinoView_Modified;
}
// Remaining implementation
}
On another note, is there a way of retrieving the location of this window? Currently, I iterate over all RhinoDoc.ActiveDoc.Views and get the extreme coordinates, but this approach is not robust to scenarios with missing viewports as shown below:
As @CallumSykes mentioned, RhinoEtoApp.MainWindow doesn’t return a usable Eto Window. The only real purpose of it is to use a a parent for some other Eto form.
Keep in mind that Rhino on Windows uses MFC for it’s main user interface framework.
If you want to subscribe to the Windows message you’ve mentioned, you might looking to setting up a Windows hook.
I’ve been doing HUDs in the display pipeline for years, but they have one major drawback - the view needs to be redrawn on each mouse move to allow for user interaction. With heavier models things get laggy fast.
It would be great if the events listed above were relayed to their native counterparts. Could this be added to the wish list?