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);
}
{
puSlider * slider = (puSlider *)arrow->getUserData();
puListBox * list_box = (puListBox *)slider->getUserData();
+ puList * list = (puList *)list_box->getUserData();
int step;
switch (((puArrowButton *)arrow)->getArrowType()) {
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);
}
{
_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 *
}
void
-puList::init (int w, int h)
+puList::setColourScheme (float r, float g, float b, float a)
{
- const int sw = 20;
- _frame = new puFrame(0, 0, w, h);
+ puObject::setColourScheme(r, g, b, a);
+ _list_box->setColourScheme(r, g, b, a);
+}
- _list_box = new puListBox(0, 0, w-sw, h);
+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)
+{
+ if ( transparent )
+ _frame = NULL ;
+ else
+ _frame = new puFrame(0, 0, w, 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-sw, sw, h-2*sw, true, sw);
+ _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-sw, 0, w, sw, 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-sw, h-sw, 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();
}
-void
-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);
-}
-
// end of puList.cxx