title: Wt layout headache
body: <p>I am evaluating Wt and have been impressed up till a point where I hit a layout snag where what I code seemingly does not coincide with what ends up in the browser. Mainly to do with containers overlapping one another when they (apparently) shouldn't. Here is one example to illustrate what I mean:</p>
  
  <pre><code>#include &lt;stdio.h&gt;            
  #include &lt;stdlib.h&gt;           
  #include &lt;string.h&gt;           
  #include &lt;assert.h&gt;           
  
  #include &lt;string&gt;
  
  using namespace std;
  
  #include &lt;Wt/WApplication&gt;
  #include &lt;Wt/WContainerWidget&gt;
  #include &lt;Wt/WLineEdit&gt;       
  #include &lt;Wt/WHBoxLayout&gt;     
  #include &lt;Wt/WVBoxLayout&gt;     
  #include &lt;Wt/WGroupBox&gt;       
  #include &lt;Wt/WLabel&gt;          
  #include &lt;Wt/WDateEdit&gt;       
  #include &lt;Wt/WStackedWidget&gt;  
  #include &lt;Wt/WMenu&gt;           
  #include &lt;Wt/WBootstrapTheme&gt; 
  #include &lt;Wt/WTabWidget&gt;      
  
  using namespace Wt;
  
  class TSTApplication : public WApplication
  {                                         
          WContainerWidget *body;           
  
      public:
          TSTApplication(const WEnvironment&amp; env);
  };                                              
  
  class TSTConcoction : public WContainerWidget
  {                                            
      public:                                  
          TSTConcoction();                     
  };                                           
  
  TSTConcoction::TSTConcoction()
  {                             
      WVBoxLayout *vbox = new WVBoxLayout;
  
      WGroupBox *gbox = new WGroupBox("A Group Box");
      WTabWidget *tabw = new WTabWidget(gbox);       
      tabw-&gt;setStyleClass("tabwidget");              
  
      // tab1:
      {       
      WContainerWidget *tab = new WContainerWidget;
  
      WHBoxLayout *hbox = new WHBoxLayout;
  
      hbox-&gt;addWidget(new WLabel("First:"));
      hbox-&gt;addWidget(new WLineEdit);       
      hbox-&gt;addWidget(new WLabel("Second:"));
      hbox-&gt;addWidget(new WLineEdit);        
      hbox-&gt;addWidget(new WLabel("Third:")); 
      hbox-&gt;addWidget(new WLineEdit);        
  
      tab-&gt;setLayout(hbox);
  
      tabw-&gt;addTab(tab, "TAB1",  Wt::WTabWidget::PreLoading);
      }                                                      
  
      // tab2:
      {       
      WContainerWidget *tab = new WContainerWidget;
  
      WHBoxLayout *hbox = new WHBoxLayout;
  
      hbox-&gt;addWidget(new WLabel("Only:"));
      hbox-&gt;addWidget(new WLineEdit);      
  
      tab-&gt;setLayout(hbox);
  
      tabw-&gt;addTab(tab, "TAB2",  Wt::WTabWidget::PreLoading);
      }                                                      
  
      vbox-&gt;addWidget(gbox);
  
      // towards the bottom
      gbox = new WGroupBox("Below The Lot");
      WHBoxLayout *hbox = new WHBoxLayout;  
  
      hbox-&gt;addWidget(new WLabel("Left:"));
      hbox-&gt;addWidget(new WDateEdit);      
      hbox-&gt;addWidget(new WLineEdit);      
  
      hbox-&gt;addWidget(new WLabel("Middle:"));
      hbox-&gt;addWidget(new WDateEdit);        
      hbox-&gt;addWidget(new WLineEdit);        
  
      hbox-&gt;addWidget(new WLabel("Right:"));
      hbox-&gt;addWidget(new WLineEdit);       
  
      gbox-&gt;setLayout(hbox);
      vbox-&gt;addWidget(gbox);
  
      setLayout(vbox);
  }                   
  
  TSTApplication::TSTApplication
  (                             
      const WEnvironment&amp; env   
  )                             
  : WApplication(env)           
  {                             
      WApplication::instance()-&gt;setTheme(new WBootstrapTheme);
  
      WContainerWidget *appcont = new WContainerWidget;
      WStackedWidget *contents = new WStackedWidget;   
      WMenu *menu = new WMenu(contents, Wt::Horizontal, appcont);
      menu-&gt;addStyleClass("nav-tabs");                           
  
      // tab1
      WContainerWidget *cont = new WContainerWidget;
      WVBoxLayout *vbox = new WVBoxLayout;          
  
      WHBoxLayout *hbox = new WHBoxLayout;
      WLabel *l = new WLabel("Dummy:");   
      hbox-&gt;addWidget(l);                 
      hbox-&gt;addWidget(new WLineEdit);     
      vbox-&gt;addLayout(hbox);              
  
      vbox-&gt;addWidget(new TSTConcoction);
  
      cont-&gt;setLayout(vbox);
      menu-&gt;addItem("TAB1", cont);
  
      // tab2
      cont = new WContainerWidget;
      vbox = new WVBoxLayout;
      vbox-&gt;addWidget(new WLabel("TODO"));
      cont-&gt;setLayout(vbox);
      menu-&gt;addItem("TAB2", cont);
  
      appcont-&gt;addWidget(contents);
  
      root()-&gt;addWidget(appcont);
  }
  
  WApplication *createApplication(const WEnvironment&amp; env)
  {
      return new TSTApplication(env);
  }
  
  int main(int argc, char **argv)
  {
      return WRun(argc, argv, &amp;createApplication);
  }
  </code></pre>
  
  <p>Here is another (seemingly non-related) example:</p>
  
  <pre><code>#include &lt;stdio.h&gt;                                                          
  #include &lt;stdlib.h&gt;                                                         
  #include &lt;string.h&gt;                                                         
  #include &lt;assert.h&gt;                                                         
  
  #include &lt;string&gt;
  
  using namespace std;
  
  #include &lt;Wt/WApplication&gt;
  #include &lt;Wt/WBreak&gt;      
  #include &lt;Wt/WContainerWidget&gt;
  #include &lt;Wt/WPushButton&gt;     
  #include &lt;Wt/WText&gt;           
  #include &lt;Wt/WVBoxLayout&gt;     
  #include &lt;Wt/WLabel&gt;          
  #include &lt;Wt/WStackedWidget&gt;  
  #include &lt;Wt/WMenu&gt;           
  #include &lt;Wt/WBootstrapTheme&gt; 
  
  using namespace Wt;
  
  class TSTApplication : public WApplication
  {                                         
          WContainerWidget *body;           
  
          void start();
  
      public:
          TSTApplication(const WEnvironment&amp; env);
  };                                              
  
  class TSTMessage : public WContainerWidget
  {                                         
      public:                               
          TSTMessage();                     
  };                                        
  
  class TSTRelatives : public WContainerWidget
  {                                           
          void expand();                      
  
      public:
          TSTRelatives(const string &amp;);
  };                                   
  
  class TSTChildren : public TSTRelatives
  {                                      
      public:                            
          TSTChildren();                 
  };                                     
  
  class TSTParent : public TSTRelatives
  {                                    
      public:                          
          TSTParent();                 
  };                                   
  
  const char *MESSAGE = "This is a message\n\
  to help illustrate the problem i am\n\     
  having with the relative offsets of\n\     
      container widgets";                    
  
  const char *BODY = "  A Proferred Official ICP\n\
  \n\                                              
  By Initial Connection Protocol (ICP), I mean a third level protocol\n\
  which is initiated by a user process at one site in order to contact a\n\
  server process at another site.  Typically, the user process will be a\n\
  Telnet and the server process will be a logger, but there may be other\n\
  cases.\n\                                                                
  \n\                                                                      
  In this RFC, I wish to describe a family of ICPs suitable for\n\         
  establishing one pair of connections (one in each direction) between any\n\
  user process and any server process, and to propose further a particular\n\
  subset of this family as the standard ICP for connecting user processes\n\ 
  to loggers on systems which accept teletype-like devices.";                
  
  TSTMessage::TSTMessage()
  {                       
      WVBoxLayout *vbox = new WVBoxLayout;
      vbox-&gt;addWidget(new WText("&lt;pre&gt;" + string(MESSAGE) + "&lt;/pre&gt;"));
      vbox-&gt;addWidget(new TSTParent);                                  
      vbox-&gt;addWidget(new TSTChildren);                                
      vbox-&gt;addWidget(new WText("&lt;pre&gt;" + string(BODY) + "&lt;/pre&gt;"));   
      vbox-&gt;addWidget(new WPushButton("Dummy Button"));                
      setLayout(vbox);                                                 
  }                                                                    
  
  TSTRelatives::TSTRelatives
  (                         
      const string &amp;who     
  )                         
  {                         
      setLayoutSizeAware(true);
      WVBoxLayout *vbox = new WVBoxLayout;
      WPushButton *expand = new WPushButton("Expand " + who);
      expand-&gt;clicked().connect(this, &amp;TSTRelatives::expand);
      vbox-&gt;addWidget(expand);                               
      setLayout(vbox);                                       
  }                                                          
  
  void TSTRelatives::expand()
  {                          
      clear();               
      for (int i = 0; i &lt; 2; i++)
      {                          
          this-&gt;addWidget(new WBreak);
          WString num = WString("{1}&lt;hr/&gt;").arg(i);
          this-&gt;addWidget(new WText(num));         
          this-&gt;addWidget(new TSTMessage);         
      }                                            
  }                                                
  
  TSTChildren::TSTChildren()
  : TSTRelatives("Children")
  {                         
      setStyleClass("children");
  }                             
  
  TSTParent::TSTParent()
  : TSTRelatives("Parent")
  {                       
      setStyleClass("parent");
  }                           
  
  void TSTApplication::start()
  {                           
      for (int i = 0; i &lt; 3; i++)
      {                          
          body-&gt;addWidget(new WBreak);
          WString num = WString("{1}&lt;hr/&gt;").arg(i);
          body-&gt;addWidget(new WText(num));         
          body-&gt;addWidget(new TSTMessage);         
      }                                            
  }                                                
  
  TSTApplication::TSTApplication
  (                             
      const WEnvironment&amp; env   
  )                             
  : WApplication(env)           
  {                             
      WApplication::instance()-&gt;useStyleSheet("tstui.css");
      WApplication::instance()-&gt;setTheme(new WBootstrapTheme);
  
      WContainerWidget *appcont = new WContainerWidget;
      WStackedWidget *contents = new WStackedWidget;   
      WMenu *menu = new WMenu(contents, Wt::Horizontal, appcont);
      menu-&gt;addStyleClass("nav-tabs");                           
  
      // tab1
      WContainerWidget *cont = new WContainerWidget;
      WVBoxLayout *vbox = new WVBoxLayout;          
      body = new WContainerWidget;                  
      WPushButton *b = new WPushButton("Start");    
      b-&gt;clicked().connect(this, &amp;TSTApplication::start);
      vbox-&gt;addWidget(b);                                
      vbox-&gt;addWidget(body);                             
      cont-&gt;setLayout(vbox);
      menu-&gt;addItem("TAB1", cont);
  
      // tab2
      cont = new WContainerWidget;
      vbox = new WVBoxLayout;
      vbox-&gt;addWidget(new WLabel("TODO"));
      cont-&gt;setLayout(vbox);
      menu-&gt;addItem("TAB2", cont);
  
      appcont-&gt;addWidget(contents);
  
      root()-&gt;addWidget(appcont);
  }
  
  WApplication *createApplication(const WEnvironment&amp; env)
  {
      return new TSTApplication(env);
  }
  
  int main(int argc, char **argv)
  {
      return WRun(argc, argv, &amp;createApplication);
  }
  </code></pre>
  
  <p>When loaded, hit the Expand Parent/Children buttons arbitrarily around the page and within a handful of iterations some unwanted overlap of containers creeps in.</p>
  
  <p>To get them running, put each example into a file (e.g. tst.cpp) and compile with (on linux):</p>
  
  <p>c++ -o tst tst.cpp -lwthttp -lwt</p>
  
  <p>and run with:</p>
  
  <p>./tst --docroot . --http-address 0.0.0.0 --http-port 8080</p>
  
  <p>Normally at this point one might be tempted to move on to evaluate the next framework but I know C++ and Qt so Wt is a good fit and I hope I can find a simple explanation for this to continue my journey with Wt.</p>
  
  <p>No help will be frowned upon.</p>