]> git.mxchange.org Git - simgear.git/blobdiff - simgear/canvas/layout/canvas_layout_test.cxx
canvas::Layout: support for contents margins.
[simgear.git] / simgear / canvas / layout / canvas_layout_test.cxx
index 6aa9c79a67af42b8f42c5bbb0dd713f1d4fe92a6..a95aa76035db2ed0ed776a638123a933cc3d25f6 100644 (file)
@@ -23,6 +23,8 @@
 #include "NasalWidget.hxx"
 
 #include <simgear/debug/logstream.hxx>
+#include <simgear/nasal/cppbind/NasalContext.hxx>
+
 #include <cstdlib>
 
 //------------------------------------------------------------------------------
@@ -62,16 +64,17 @@ class TestWidget:
     void setMaxSize(const SGVec2i& size) { _max_size = size; }
     void setSizeHint(const SGVec2i& size) { _size_hint = size; }
 
-    virtual void setGeometry(const SGRecti& geom) { _geom = geom; }
-    virtual SGRecti geometry() const { return _geom; }
-
   protected:
 
-    SGRecti _geom;
-
     virtual SGVec2i sizeHintImpl() const { return _size_hint; }
     virtual SGVec2i minimumSizeImpl() const { return _min_size; }
     virtual SGVec2i maximumSizeImpl() const { return _max_size; }
+
+    virtual void visibilityChanged(bool visible)
+    {
+      if( !visible )
+        _geometry.set(0, 0, 0, 0);
+    }
 };
 
 class TestWidgetHFW:
@@ -91,12 +94,12 @@ class TestWidgetHFW:
       return true;
     }
 
-    virtual int heightForWidth(int w) const
+    virtual int heightForWidthImpl(int w) const
     {
       return _size_hint.x() * _size_hint.y() / w;
     }
 
-    virtual int minimumHeightForWidth(int w) const
+    virtual int minimumHeightForWidthImpl(int w) const
     {
       return _min_size.x() * _min_size.y() / w;
     }
@@ -295,35 +298,202 @@ BOOST_AUTO_TEST_CASE( vertical_layout)
 //------------------------------------------------------------------------------
 BOOST_AUTO_TEST_CASE( boxlayout_insert_remove )
 {
-  sc::HBoxLayout hbox;
+  sc::BoxLayoutRef hbox( new sc::HBoxLayout );
 
-  BOOST_CHECK_EQUAL(hbox.count(), 0);
-  BOOST_CHECK(!hbox.itemAt(0));
-  BOOST_CHECK(!hbox.takeAt(0));
+  BOOST_CHECK_EQUAL(hbox->count(), 0);
+  BOOST_CHECK(!hbox->itemAt(0));
+  BOOST_CHECK(!hbox->takeAt(0));
 
   TestWidgetRef w1( new TestWidget( SGVec2i(16,   16),
                                     SGVec2i(32,   32),
                                     SGVec2i(9999, 32) ) ),
                 w2( new TestWidget(*w1) );
 
-  hbox.addItem(w1);
-  BOOST_CHECK_EQUAL(hbox.count(), 1);
-  BOOST_CHECK_EQUAL(hbox.itemAt(0), w1);
+  hbox->addItem(w1);
+  BOOST_CHECK_EQUAL(hbox->count(), 1);
+  BOOST_CHECK_EQUAL(hbox->itemAt(0), w1);
+  BOOST_CHECK_EQUAL(w1->getParent(), hbox);
+
+  hbox->insertItem(0, w2);
+  BOOST_CHECK_EQUAL(hbox->count(), 2);
+  BOOST_CHECK_EQUAL(hbox->itemAt(0), w2);
+  BOOST_CHECK_EQUAL(hbox->itemAt(1), w1);
+  BOOST_CHECK_EQUAL(w2->getParent(), hbox);
+
+  hbox->removeItem(w2);
+  BOOST_CHECK_EQUAL(hbox->count(), 1);
+  BOOST_CHECK_EQUAL(hbox->itemAt(0), w1);
+  BOOST_CHECK( !w2->getParent() );
+
+  hbox->addItem(w2);
+  BOOST_CHECK_EQUAL(hbox->count(), 2);
+  BOOST_CHECK_EQUAL(w2->getParent(), hbox);
+
+  hbox->clear();
+  BOOST_CHECK_EQUAL(hbox->count(), 0);
+  BOOST_CHECK( !w1->getParent() );
+  BOOST_CHECK( !w2->getParent() );
+}
 
-  hbox.insertItem(0, w2);
-  BOOST_CHECK_EQUAL(hbox.count(), 2);
-  BOOST_CHECK_EQUAL(hbox.itemAt(0), w2);
-  BOOST_CHECK_EQUAL(hbox.itemAt(1), w1);
+//------------------------------------------------------------------------------
+BOOST_AUTO_TEST_CASE( boxlayout_visibility )
+{
+  sc::BoxLayoutRef hbox( new sc::HBoxLayout );
+  TestWidgetRef w1( new TestWidget( SGVec2i(16, 16),
+                                    SGVec2i(32, 32) ) ),
+                w2( new TestWidget(*w1) ),
+                w3( new TestWidget(*w1) );
 
-  hbox.removeItem(w2);
-  BOOST_CHECK_EQUAL(hbox.count(), 1);
-  BOOST_CHECK_EQUAL(hbox.itemAt(0), w1);
+  hbox->addItem(w1);
+  hbox->addItem(w2);
+  hbox->addItem(w3);
 
-  hbox.addItem(w2);
-  BOOST_CHECK_EQUAL(hbox.count(), 2);
+  BOOST_REQUIRE_EQUAL(hbox->sizeHint().x(), 3 * 32 + 2 * hbox->spacing());
+
+  hbox->setGeometry(SGRecti(0, 0, 69, 32));
+
+  BOOST_CHECK_EQUAL(w1->geometry(), SGRecti(0,  0, 20, 32));
+  BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(25, 0, 20, 32));
+  BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(50, 0, 19, 32));
+
+  w2->setVisible(false);
+
+  BOOST_REQUIRE(hbox->isVisible());
+  BOOST_REQUIRE(w1->isVisible());
+  BOOST_REQUIRE(!w2->isVisible());
+  BOOST_REQUIRE(w2->isExplicitlyHidden());
+  BOOST_REQUIRE(w3->isVisible());
 
-  hbox.clear();
-  BOOST_CHECK_EQUAL(hbox.count(), 0);
+  BOOST_CHECK_EQUAL(hbox->sizeHint().x(), 2 * 32 + 1 * hbox->spacing());
+
+  hbox->update();
+
+  BOOST_CHECK_EQUAL(w1->geometry(), SGRecti(0,  0, 32, 32));
+  BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(0,  0,  0,  0));
+  BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(37, 0, 32, 32));
+
+  hbox->setVisible(false);
+
+  BOOST_REQUIRE(!hbox->isVisible());
+  BOOST_REQUIRE(hbox->isExplicitlyHidden());
+  BOOST_REQUIRE(!w1->isVisible());
+  BOOST_REQUIRE(!w1->isExplicitlyHidden());
+  BOOST_REQUIRE(!w2->isVisible());
+  BOOST_REQUIRE(w2->isExplicitlyHidden());
+  BOOST_REQUIRE(!w3->isVisible());
+  BOOST_REQUIRE(!w3->isExplicitlyHidden());
+
+  BOOST_CHECK_EQUAL(w1->geometry(), SGRecti(0, 0, 0, 0));
+  BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(0, 0, 0, 0));
+  BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(0, 0, 0, 0));
+
+  w2->setVisible(true);
+
+  BOOST_REQUIRE(!w2->isVisible());
+  BOOST_REQUIRE(!w2->isExplicitlyHidden());
+
+  hbox->setVisible(true);
+
+  BOOST_REQUIRE(hbox->isVisible());
+  BOOST_REQUIRE(w1->isVisible());
+  BOOST_REQUIRE(w2->isVisible());
+  BOOST_REQUIRE(w3->isVisible());
+
+  hbox->update();
+
+  BOOST_CHECK_EQUAL(w1->geometry(), SGRecti(0,  0, 20, 32));
+  BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(25, 0, 20, 32));
+  BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(50, 0, 19, 32));
+}
+
+//------------------------------------------------------------------------------
+BOOST_AUTO_TEST_CASE( boxlayout_contents_margins )
+{
+  sc::Margins m;
+
+  BOOST_REQUIRE(m.isNull());
+
+  m = sc::Margins(5);
+
+  BOOST_REQUIRE_EQUAL(m.l, 5);
+  BOOST_REQUIRE_EQUAL(m.t, 5);
+  BOOST_REQUIRE_EQUAL(m.r, 5);
+  BOOST_REQUIRE_EQUAL(m.b, 5);
+
+  m = sc::Margins(6, 7);
+
+  BOOST_REQUIRE_EQUAL(m.l, 6);
+  BOOST_REQUIRE_EQUAL(m.t, 7);
+  BOOST_REQUIRE_EQUAL(m.r, 6);
+  BOOST_REQUIRE_EQUAL(m.b, 7);
+
+  BOOST_REQUIRE_EQUAL(m.horiz(), 12);
+  BOOST_REQUIRE_EQUAL(m.vert(), 14);
+  BOOST_REQUIRE(!m.isNull());
+
+  m = sc::Margins(1, 2, 3, 4);
+
+  BOOST_REQUIRE_EQUAL(m.l, 1);
+  BOOST_REQUIRE_EQUAL(m.t, 2);
+  BOOST_REQUIRE_EQUAL(m.r, 3);
+  BOOST_REQUIRE_EQUAL(m.b, 4);
+
+  BOOST_REQUIRE_EQUAL(m.horiz(), 4);
+  BOOST_REQUIRE_EQUAL(m.vert(), 6);
+  BOOST_REQUIRE_EQUAL(m.size(), SGVec2i(4, 6));
+
+  sc::BoxLayoutRef hbox( new sc::HBoxLayout );
+
+  hbox->setContentsMargins(5, 10, 15, 20);
+
+  BOOST_CHECK_EQUAL(hbox->minimumSize(), SGVec2i(20, 30));
+  BOOST_CHECK_EQUAL(hbox->sizeHint(),    SGVec2i(20, 30));
+  BOOST_CHECK_EQUAL(hbox->maximumSize(), SGVec2i(20, 30));
+
+  hbox->setGeometry(SGRecti(0, 0, 30, 40));
+
+  BOOST_CHECK_EQUAL(hbox->contentsRect(), SGRecti(5, 10, 10, 10));
+
+  TestWidgetRef w1( new TestWidget( SGVec2i(16, 16),
+                                    SGVec2i(32, 32) ) ),
+                w2( new TestWidget(*w1) ),
+                w3( new TestWidget(*w1) );
+
+  w1->setContentsMargin(5);
+  w2->setContentsMargin(6);
+  w3->setContentsMargin(7);
+
+  BOOST_CHECK_EQUAL(w1->minimumSize(), SGVec2i(26, 26));
+  BOOST_CHECK_EQUAL(w1->sizeHint(),    SGVec2i(42, 42));
+  BOOST_CHECK_EQUAL(w1->maximumSize(), sc::LayoutItem::MAX_SIZE);
+
+  BOOST_CHECK_EQUAL(w2->minimumSize(), SGVec2i(28, 28));
+  BOOST_CHECK_EQUAL(w2->sizeHint(),    SGVec2i(44, 44));
+  BOOST_CHECK_EQUAL(w2->maximumSize(), sc::LayoutItem::MAX_SIZE);
+
+  BOOST_CHECK_EQUAL(w3->minimumSize(), SGVec2i(30, 30));
+  BOOST_CHECK_EQUAL(w3->sizeHint(),    SGVec2i(46, 46));
+  BOOST_CHECK_EQUAL(w3->maximumSize(), sc::LayoutItem::MAX_SIZE);
+
+  hbox->addItem(w1);
+  hbox->addItem(w2);
+  hbox->addItem(w3);
+
+  BOOST_CHECK_EQUAL(hbox->minimumSize(), SGVec2i(114, 60));
+  BOOST_CHECK_EQUAL(hbox->sizeHint(),    SGVec2i(162, 76));
+  BOOST_CHECK_EQUAL(hbox->maximumSize(), sc::LayoutItem::MAX_SIZE);
+
+  hbox->setGeometry(SGRecti(0, 0, hbox->sizeHint().x(), hbox->sizeHint().y()));
+
+  BOOST_CHECK_EQUAL(hbox->contentsRect(), SGRecti(5, 10, 142, 46));
+
+  BOOST_CHECK_EQUAL(w1->geometry(), SGRecti(5,   10, 42, 46));
+  BOOST_CHECK_EQUAL(w2->geometry(), SGRecti(52,  10, 44, 46));
+  BOOST_CHECK_EQUAL(w3->geometry(), SGRecti(101, 10, 46, 46));
+
+  BOOST_CHECK_EQUAL(w1->contentsRect(), SGRecti(10,  15, 32, 36));
+  BOOST_CHECK_EQUAL(w2->contentsRect(), SGRecti(58,  16, 32, 34));
+  BOOST_CHECK_EQUAL(w3->contentsRect(), SGRecti(108, 17, 32, 32));
 }
 
 //------------------------------------------------------------------------------
@@ -417,13 +587,31 @@ BOOST_AUTO_TEST_CASE( boxlayout_hfw )
   BOOST_CHECK_EQUAL(w_no_hfw->geometry(), SGRecti(0, 90, 24, 32));
 }
 
+//------------------------------------------------------------------------------
+// TODO extend to_nasal_helper for automatic argument conversion
+static naRef f_Widget_visibilityChanged(nasal::CallContext ctx)
+{
+  sc::NasalWidget* w = ctx.from_nasal<sc::NasalWidget*>(ctx.me);
+
+  if( !ctx.requireArg<bool>(0) )
+    w->setGeometry(SGRecti(0, 0, -1, -1));
+
+  return naNil();
+}
+
 //------------------------------------------------------------------------------
 BOOST_AUTO_TEST_CASE( nasal_widget )
 {
-  naContext c = naNewContext();
-  naRef me = naNewHash(c);
+  nasal::Context c;
+  nasal::Hash globals = c.newHash();
+
+  nasal::Object::setupGhost();
+  nasal::Ghost<sc::LayoutItemRef>::init("LayoutItem");
+  sc::NasalWidget::setupGhost(globals);
 
-  sc::NasalWidgetRef w( new sc::NasalWidget(me) );
+  nasal::Hash me = c.newHash();
+  me.set("visibilityChanged", &f_Widget_visibilityChanged);
+  sc::NasalWidgetRef w( new sc::NasalWidget(me.get_naRef()) );
 
   // Default layout sizes (no user set values)
   BOOST_CHECK_EQUAL(w->minimumSize(), SGVec2i(16, 16));
@@ -457,5 +645,6 @@ BOOST_AUTO_TEST_CASE( nasal_widget )
   BOOST_CHECK_EQUAL(w->sizeHint(),    SGVec2i(3, 22));
   BOOST_CHECK_EQUAL(w->maximumSize(), SGVec2i(4, 23));
 
-  naFreeContext(c);
+  w->setVisible(false);
+  BOOST_CHECK_EQUAL(w->geometry(), SGRecti(0, 0, -1, -1));
 }