Manage 2 TGMainFrame

Hello,

I am trying to build a GUI with a C++ project using ROOT. It goes through a TApplication. I can create a button within a TGMainFrame (Frame 1) that will open another TGMainFrame (Frame 2). I can toggle the new window using the UnmapWindow and MapWindow functions from TGMainFrame.
However, I would like that the frame 2 appears on the right of the frame 1.

My approach is to try to get the frame 1 position on screen, and to apply it to frame 2 with an offset corresponding to frame 1 width. I tried to use GetWindowSize from gVirtualX to get the frame 1 position as I don’t find a fitting function in TGWindow, TGFrame, etc. But the numbers I get does not seem to correspond to the reality (I access window id by frame1->GetId()). Dragging the window or resizing it does not change these numbers.

Do you have an idea how I can achieve this ?


ROOT Version: 6.24/06
Platform: 20.04.1-Ubuntu
Compiler: gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)


Welcome to the ROOT Forum!
Try something like this:

root [0] auto mf01 = new TGMainFrame(nullptr, 800, 600);
root [1] mf01->SetWMPosition(200, 100);
root [2] int x,y;
root [3] mf01->GetWMPosition(x,y)
root [4] auto mf02 = new TGMainFrame(nullptr, 800, 600);
root [5] mf02->SetWMPosition(x+mf01->GetWidth()+10,y)
root [6] mf01->MapWindow()
root [7] mf02->MapWindow()
root [8]

Thanks for your reply.
Unfortunately, SetWMPosition does not seem to affect the positionning of my frame 1 and frame 2 (it just put them in the top left corner now by default, no matter the values I set).
The GetWMPosition provide the right values (set by user, 200 and 100) but SetWMPosition does not seem to do the job.
I tried to execute the lines you suggested and they lead to the same result I get in my project.

OK, since it is dependent on the Window Manager, try something like this:

root [0] auto mf01 = new TGMainFrame(nullptr, 800, 600);
root [1] mf01->SetWMPosition(200, 100);
root [2] mf01->MapWindow();
root [3] mf01->MoveResize(200, 100, 800, 600);
root [4] int x,y;
root [5] mf01->GetWMPosition(x,y);
root [6] auto mf02 = new TGMainFrame(nullptr, 800, 600);
root [7] mf02->SetWMPosition(x+mf01->GetWidth()+10,y);
root [8] mf02->MapWindow();
root [9] mf02->MoveResize(x+mf01->GetWidth()+10, y, 800, 600);
root [10]

Alright it seems to work now, thanks !
Could you elaborate further why it is required to set the position through both SetWMPosition and Move/MoveResize please ?
Is it actually possible to get the current coordinate on screen after a window drag by user ? For instance, if I move my frame 1, the frame 2 will appear at the old position, not at the new one I expect him to be.

OK, so I found a way:

root [0] auto mf01 = new TGMainFrame(nullptr, 800, 600);
root [1] mf01->MapWindow();
root [2] Window_t wdum;
root [3] Int_t ax, ay;
root [4] gVirtualX->TranslateCoordinates(mf01->GetId(), gClient->GetDefaultRoot()->GetId(), 0,0,ax,ay,wdum);
root [5] ax
(int) 86
root [6] ay
(int) 109

... --> move the window

root [7] gVirtualX->TranslateCoordinates(mf01->GetId(), gClient->GetDefaultRoot()->GetId(), 0,0,ax,ay,wdum);
root [8] ay
(int) 204
root [9]

I can give you a full example later

So that should help you solving your issue:

root [0] Window_t wdum;
root [1] Int_t    ax, ay;
root [2] auto mf01 = new TGMainFrame(nullptr, 800, 600);
root [3] mf01->MapWindow()
root [4] gVirtualX->TranslateCoordinates(mf01->GetId(), gClient->GetDefaultRoot()->GetId(), 0, 0, ax, ay, wdum);
root [5] auto mf02 = new TGMainFrame(nullptr, 800, 600);
root [6] mf02->MapWindow()
root [7] mf02->MoveResize(ax + mf01->GetWidth() + 10, ay, 800, 600);
root [8]

It works like a charm, thank you !
I have more questions, but for now I will just try to solve them myself before asking :wink:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.