597298d5a7
- order functions like in puAuxList.cxx (plib/cvs) for easier back/forward-porting
212 lines
4.8 KiB
C++
212 lines
4.8 KiB
C++
// puList.cxx - implementation of a scrolling list box.
|
|
|
|
#include "puList.hxx"
|
|
|
|
|
|
/**
|
|
* Static function: handle slider movements.
|
|
*/
|
|
static void
|
|
handle_slider (puObject * slider)
|
|
{
|
|
puListBox * box = (puListBox *)slider->getUserData();
|
|
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.
|
|
*/
|
|
static void
|
|
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()) {
|
|
case PUARROW_DOWN:
|
|
step = 1;
|
|
break;
|
|
case PUARROW_UP:
|
|
step = -1;
|
|
break;
|
|
default:
|
|
step = 0;
|
|
break;
|
|
}
|
|
|
|
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, int sl_width)
|
|
: puGroup(x, y),
|
|
_sw(sl_width)
|
|
{
|
|
type |= PUCLASS_LIST;
|
|
init(w, h, 1);
|
|
}
|
|
|
|
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, 1);
|
|
newList(contents);
|
|
}
|
|
|
|
puList::~puList ()
|
|
{
|
|
}
|
|
|
|
void
|
|
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 *
|
|
puList::getListStringValue ()
|
|
{
|
|
int i = _list_box->getIntegerValue();
|
|
return i < 0 ? 0 : _contents[i];
|
|
}
|
|
|
|
int
|
|
puList::getListIntegerValue()
|
|
{
|
|
return _list_box->getIntegerValue();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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->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->setUserData(_slider);
|
|
_down_arrow->setCallback(handle_arrow);
|
|
|
|
_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();
|
|
}
|
|
|
|
// end of puList.cxx
|