]> git.mxchange.org Git - flightgear.git/blob - src/GUI/puList.cxx
catch non-existent nodes, too
[flightgear.git] / src / GUI / puList.cxx
1 // puList.cxx - implementation of a scrolling list box.
2
3 #include "puList.hxx"
4
5
6 /**
7  * Static function: handle slider movements.
8  */
9 static void
10 handle_slider (puObject * slider)
11 {
12     puListBox * box = (puListBox *)slider->getUserData();
13     int total = box->getNumItems();
14     int visible = box->getNumVisible();
15     // negative numbers are OK -- setTopItem() clamps anyway
16     int index = int((total - visible) * (1.0 - slider->getFloatValue()));
17     box->setTopItem(index);
18 }
19
20
21 /**
22  * Static function: handle list entry clicks.
23  */
24 static void
25 handle_list_entry (puObject * listbox)
26 {
27     puListBox * box = (puListBox *)listbox->getUserData();
28     box->invokeCallback();
29 }
30
31
32 /**
33  * Static function: handle arrow clicks.
34  */
35 static void
36 handle_arrow (puObject * arrow)
37 {
38     puSlider * slider = (puSlider *)arrow->getUserData();
39     puListBox * list_box = (puListBox *)slider->getUserData();
40
41     int step;
42     switch (((puArrowButton *)arrow)->getArrowType()) {
43     case PUARROW_DOWN:
44         step = 1;
45         break;
46     case PUARROW_UP:
47         step = -1;
48         break;
49     default:
50         step = 0;
51         break;
52     }
53
54     int total = list_box->getNumItems();
55     int visible = list_box->getNumVisible();
56     int index = list_box->getTopItem();
57     list_box->setTopItem(index + step);
58     // read back to get setTopItem()'s clamping
59     index = list_box->getTopItem();
60     // negative numbers can't happen, as the buttons aren't visible then
61     slider->setValue(1.0f - float(index)/(total-visible));
62 }
63
64 puList::puList (int x, int y, int w, int h, int sl_width)
65     : puGroup(x, y),
66       _sw(sl_width)
67 {
68     type |= PUCLASS_LIST;
69     init(w, h, 1);
70 }
71
72 puList::puList (int x, int y, int w, int h, char ** contents, int sl_width)
73     : puGroup(x, y),
74       _sw(sl_width)
75 {
76     type |= PUCLASS_LIST;
77     init(w, h, 1);
78     newList(contents);
79 }
80
81 puList::~puList ()
82 {
83 }
84
85 void
86 puList::newList (char ** contents)
87 {
88     _list_box->newList(contents);
89     _contents = contents;
90
91     // new size calculation to consider slider visibility
92     setSize(_width, _height);
93 }
94
95 char *
96 puList::getListStringValue ()
97 {
98     int i = _list_box->getIntegerValue();
99     return i < 0 ? 0 : _contents[i];
100 }
101
102 int
103 puList::getListIntegerValue()
104 {
105   return _list_box->getIntegerValue();
106 }
107
108 void
109 puList::init (int w, int h, short transparent)
110 {
111     if ( transparent )
112         _frame = NULL ;
113     else
114         _frame = new puFrame(0, 0, w, h);
115
116     _list_box = new puListBox(0, 0, w-_sw, h);
117     _list_box->setStyle(-PUSTYLE_SMALL_SHADED);
118     _list_box->setUserData(this);
119     _list_box->setCallback(handle_list_entry);
120     _list_box->setValue(0);
121
122     _slider = new puSlider(w-_sw, _sw, h-2*_sw, true, _sw);
123     _slider->setValue(1.0f);
124     _slider->setUserData(_list_box);
125     _slider->setCallback(handle_slider);
126     _slider->setCBMode(PUSLIDER_ALWAYS);
127
128     _down_arrow = new puArrowButton(w-_sw, 0, w, _sw, PUARROW_DOWN) ;
129     _down_arrow->setUserData(_slider);
130     _down_arrow->setCallback(handle_arrow);
131
132     _up_arrow = new puArrowButton(w-_sw, h-_sw, w, h, PUARROW_UP);
133     _up_arrow->setUserData(_slider);
134     _up_arrow->setCallback(handle_arrow);
135
136     setSize(w, h);
137     close();
138 }
139
140 void
141 puList::setColourScheme (float r, float g, float b, float a)
142 {
143     puObject::setColourScheme(r, g, b, a);
144     _list_box->setColourScheme(r, g, b, a);
145 }
146
147 void
148 puList::setColour (int which, float r, float g, float b, float a)
149 {
150     puObject::setColour(which, r, g, b, a);
151     _list_box->setColour(which, r, g, b, a);
152 }
153
154 void
155 puList::setTopItem( int top )
156 {
157     int visible = _list_box->getNumVisible();
158     int num = _list_box->getNumItems();
159     if ( top < 0 || num <= visible )
160         top = 0 ;
161     else if ( num > 0 && top > num-visible )
162         top = num-visible;
163
164     _list_box->setTopItem(top) ;
165 }
166
167 void
168 puList::setSize (int w, int h)
169 {
170     _width = w;
171     _height = h;
172     puObject::setSize(w, h);
173     if (_frame)
174         _frame->setSize(w, h);
175
176     int total = _list_box->getNumItems();
177     int visible = _list_box->getNumVisible();
178
179     if (total > visible)
180     {
181         if (!_slider->isVisible())
182         {
183             _slider->setValue(1.0f);
184             _slider->reveal();
185             _up_arrow->reveal();
186             _down_arrow->reveal();
187         }
188         _list_box->setSize(w-_sw, h);
189
190         _slider->setPosition(w-_sw, _sw);
191         _slider->setSize(_sw, h-2*_sw);
192         _slider->setSliderFraction(float(visible) / total);
193
194         _down_arrow->setPosition(w-_sw, 0);
195         _up_arrow->setPosition(w-_sw, h-_sw);
196
197     }
198     else
199     {
200         if (_slider->isVisible())
201         {
202             _slider->hide();
203             _up_arrow->hide();
204             _down_arrow->hide();
205         }
206         _list_box->setSize(w, h);
207     }
208 }
209
210 // end of puList.cxx