Tile-like layout

Dear all,

I am trying to write a GUI which has 2x2 of equally-sized sub-frames, each of which is composed of a TRootEmbeddedCanvas (and other widgets).
I want the embedded canvases to expand or shrink when the main window is resized.
I first implemented it using two horizontal composite frames nested in a vertical one, but I am hoping to implement with more (logically) organized way.
Blow, I tried to use TGMatrixLayout, but the canvases are not expanded with the main window.

  TGMatrixLayout *tl = new TGMatrixLayout(mainFrame, 2, 2);
  mainFrame->SetLayoutManager(tl);
  for (int i = 0; i < 4; ++i) {
    TRootEmbeddedCanvas *fCanvas =
      new TRootEmbeddedCanvas(Form("Ecanvas%d", i), mainFrame, 200, 200);
    mainFrame->AddFrame(fCanvas, new TGLayoutHints(kLHintsExpandX | LHintsExpandY));
  }

TGTableLayout or TGTileLayout sound useful for this purpose, but I couldn’t quite understand how to use them.
I would very much appreciate your advice.

Dear Kame,

In the absence of our GUI expert I’ll try to help you as much as I can.

First, I find your solution using horizontal/verical frames ok. Why are you not happy with that?

Second, if you know exactly what you want to do with child frames, you can always sub-class from the TGCompositeFrame and implement the Layout() virtual method. See for example TGPack.

I’ve never really used other layout managers. For some of them I remember Bertrand saying (~4 years ago) that they were created for specific widgets and would be hard to use under general conditions.

So, if you still want to try other layouts, I can have a deeper look … especially if you are willing to do the testing :slight_smile: We could add what we learn to the class documentation, too.

Best,
Matevz

Hi Matevz,

Thank you for your reply.
I have no problem with the solution using horizontal/vertical frames. I just thought that multiply nested frames needs a lot of code writing and dedicated classes had been offered for better readability. But if they are not intended for general use as you wrote, it’s perfectly okay to stick to the basics.

Hi Kame,

Here is a very simple example using TGTableLayout:

#include "TGTableLayout.h" 
#include "TGFrame.h" 

void testTableLayout()
{ 
   TGMainFrame * w = new TGMainFrame (gClient->GetRoot(), 800, 800); 
   TGTableLayout *tl = new TGTableLayout(w, 2, 2, kFALSE); 
   w->SetLayoutManager(tl);
   TRootEmbeddedCanvas *ec = new TRootEmbeddedCanvas("Ecanvas1", w, 200, 200); 
   w->AddFrame(ec, new TGTableLayoutHints(0, 1, 0, 1,
                                          kLHintsExpandX | kLHintsExpandY |
                                          kLHintsShrinkX | kLHintsShrinkY | 
                                          kLHintsCenterX | kLHintsCenterY |
                                          kLHintsFillX | kLHintsFillY,
                                          1, 1, 1, 1));

   ec = new TRootEmbeddedCanvas("Ecanvas2", w, 200, 200); 
   w->AddFrame(ec, new TGTableLayoutHints(1, 2, 0, 1,
                                          kLHintsExpandX | kLHintsExpandY |
                                          kLHintsShrinkX | kLHintsShrinkY | 
                                          kLHintsCenterX | kLHintsCenterY |
                                          kLHintsFillX | kLHintsFillY,
                                          1, 1, 1, 1));
   
   ec = new TRootEmbeddedCanvas("Ecanvas3", w, 200, 200); 
   w->AddFrame(ec, new TGTableLayoutHints(0, 1, 1, 2,
                                          kLHintsExpandX | kLHintsExpandY |
                                          kLHintsShrinkX | kLHintsShrinkY | 
                                          kLHintsCenterX | kLHintsCenterY |
                                          kLHintsFillX | kLHintsFillY,
                                          1, 1, 1, 1));
   
   ec = new TRootEmbeddedCanvas("Ecanvas4", w, 200, 200); 
   w->AddFrame(ec, new TGTableLayoutHints(1, 2, 1, 2,
                                          kLHintsExpandX | kLHintsExpandY |
                                          kLHintsShrinkX | kLHintsShrinkY | 
                                          kLHintsCenterX | kLHintsCenterY |
                                          kLHintsFillX | kLHintsFillY,
                                          1, 1, 1, 1));
   
   w->Connect("CloseWindow()", "TApplication", gApplication, "Terminate()");
   w->DontCallClose();
   
   w->SetWindowName("Example Macro"); 
   w->MapSubwindows(); 
   w->Resize(); 
   w->Resize(800, 800); 
   w->MapWindow(); 
    
}

Hope this will help.

Cheers, Bertrand.

Hi, Bertrand.

Your example is just what I wanted.
Thank you very much!

Hi Kame,

You’re welcome! :slight_smile:

Cheers, Bertrand.