]> git.mxchange.org Git - flightgear.git/blobdiff - src/GUI/puList.cxx
Clear chat messages when an aircraft becomes inactive in the property tree.
[flightgear.git] / src / GUI / puList.cxx
index b99ccd4051b66d2547938c0e180af2d0c464d838..63bdd60116b63fa1ef3cb302c9a1a3740f65cdb7 100644 (file)
@@ -10,13 +10,25 @@ static void
 handle_slider (puObject * slider)
 {
     puListBox * box = (puListBox *)slider->getUserData();
-    int index = int(box->getNumItems() * (1.0 - slider->getFloatValue()));
-    if (index >= box->getNumItems())
-        index = box->getNumItems() - 1;
+    int total = box->getNumItems();
+    int visible = box->getNumVisible();
+    // negative numbers are OK -- setTopItem() clamps anyway
+    int index = int((total - visible) * (1.0 - slider->getFloatValue()));
     box->setTopItem(index);
 }
 
 
+/**
+ * Static function: handle list entry clicks.
+ */
+static void
+handle_list_entry (puObject * listbox)
+{
+    puListBox * box = (puListBox *)listbox->getUserData();
+    box->invokeCallback();
+}
+
+
 /**
  * Static function: handle arrow clicks.
  */
@@ -25,6 +37,7 @@ handle_arrow (puObject * arrow)
 {
     puSlider * slider = (puSlider *)arrow->getUserData();
     puListBox * list_box = (puListBox *)slider->getUserData();
+    puList * list = (puList *)list_box->getUserData();
 
     int step;
     switch (((puArrowButton *)arrow)->getArrowType()) {
@@ -39,29 +52,25 @@ handle_arrow (puObject * arrow)
         break;
     }
 
-    int index = list_box->getTopItem();
-    index += step;
-    if (index < 0)
-        index = 0;
-    else if (index >= list_box->getNumItems())
-        index = list_box->getNumItems() - 1;
-    list_box->setTopItem(index);
-
-    slider->setValue(1.0f - float(index)/list_box->getNumItems());
+    int index = list->getTopItem();
+    list->setTopItem(index + step);
+    slider->setValue(1.0f - float(list->getTopItem()) / (list->getNumItems() - list->getNumVisible()));
 }
 
-puList::puList (int x, int y, int w, int h)
-    : puGroup(x, y)
+puList::puList (int x, int y, int w, int h, int sl_width)
+    : puGroup(x, y),
+      _sw(sl_width)
 {
     type |= PUCLASS_LIST;
-    init(w, h);
+    init(w, h, 1);
 }
 
-puList::puList (int x, int y, int w, int h, char ** contents)
-    : puGroup(x, y)
+puList::puList (int x, int y, int w, int h, char ** contents, int sl_width)
+    : puGroup(x, y),
+      _sw(sl_width)
 {
     type |= PUCLASS_LIST;
-    init(w, h);
+    init(w, h, 1);
     newList(contents);
 }
 
@@ -74,6 +83,28 @@ puList::newList (char ** contents)
 {
     _list_box->newList(contents);
     _contents = contents;
+
+    // new size calculation to consider slider visibility
+    setSize(_width, _height);
+}
+
+void
+puList::setTopItem( int top )
+{
+    int visible = _list_box->getNumVisible();
+    int num = _list_box->getNumItems();
+    if ( top < 0 || num <= visible )
+        top = 0 ;
+    else if ( num > 0 && top > num-visible )
+        top = num-visible;
+
+    _list_box->setTopItem(top);
+    top = _list_box->getTopItem();
+    // read clamped value back in, and only set slider if it doesn't match the new
+    // index to avoid jumps
+    int slider_index = int((1.0f - _slider->getFloatValue()) * (getNumItems() - getNumVisible()));
+    if (slider_index != top)
+        _slider->setValue(1.0f - float(getTopItem()) / (getNumItems() - getNumVisible()));
 }
 
 char *
@@ -90,29 +121,91 @@ puList::getListIntegerValue()
 }
 
 void
-puList::init (int w, int h)
+puList::setColourScheme (float r, float g, float b, float a)
+{
+    puObject::setColourScheme(r, g, b, a);
+    _list_box->setColourScheme(r, g, b, a);
+}
+
+void
+puList::setColour (int which, float r, float g, float b, float a)
+{
+    puObject::setColour(which, r, g, b, a);
+    _list_box->setColour(which, r, g, b, a);
+}
+
+void
+puList::setSize (int w, int h)
+{
+    _width = w;
+    _height = h;
+    puObject::setSize(w, h);
+    if (_frame)
+        _frame->setSize(w, h);
+
+    int total = _list_box->getNumItems();
+    int visible = _list_box->getNumVisible();
+
+    if (total > visible)
+    {
+        if (!_slider->isVisible())
+        {
+            _slider->setValue(1.0f);
+            _slider->reveal();
+            _up_arrow->reveal();
+            _down_arrow->reveal();
+        }
+        _list_box->setSize(w-_sw, h);
+
+        _slider->setPosition(w-_sw, _sw);
+        _slider->setSize(_sw, h-2*_sw);
+        _slider->setSliderFraction(float(visible) / total);
+
+        _down_arrow->setPosition(w-_sw, 0);
+        _up_arrow->setPosition(w-_sw, h-_sw);
+
+    }
+    else
+    {
+        if (_slider->isVisible())
+        {
+            _slider->hide();
+            _up_arrow->hide();
+            _down_arrow->hide();
+        }
+        _list_box->setSize(w, h);
+    }
+}
+
+void
+puList::init (int w, int h, short transparent)
 {
-    _frame = new puFrame(0, 0, w, h);
+    if ( transparent )
+        _frame = NULL ;
+    else
+        _frame = new puFrame(0, 0, w, h);
 
-    _list_box = new puListBox(0, 0, w-30, h);
+    _list_box = new puListBox(0, 0, w-_sw, h);
     _list_box->setStyle(-PUSTYLE_SMALL_SHADED);
     _list_box->setUserData(this);
+    _list_box->setCallback(handle_list_entry);
     _list_box->setValue(0);
 
-    _slider = new puSlider(w-30, 30, h-60, true);
+    _slider = new puSlider(w-_sw, _sw, h-2*_sw, true, _sw);
     _slider->setValue(1.0f);
     _slider->setUserData(_list_box);
     _slider->setCallback(handle_slider);
     _slider->setCBMode(PUSLIDER_ALWAYS);
 
-    _down_arrow = new puArrowButton(w-30, 0, w, 30, PUARROW_DOWN) ;
+    _down_arrow = new puArrowButton(w-_sw, 0, w, _sw, PUARROW_DOWN) ;
     _down_arrow->setUserData(_slider);
     _down_arrow->setCallback(handle_arrow);
 
-    _up_arrow = new puArrowButton(w-30, h-30, w, h, PUARROW_UP);
+    _up_arrow = new puArrowButton(w-_sw, h-_sw, w, h, PUARROW_UP);
     _up_arrow->setUserData(_slider);
     _up_arrow->setCallback(handle_arrow);
 
+    setSize(w, h);
     close();
 }