2
* Copyright (C) 2002 by the Widelands Development Team
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
#include "constants.h"
22
#include "rendertarget.h"
25
#include "ui_listselect.h"
26
#include "ui_scrollbar.h"
29
Initialize a list select panel
31
Args: parent parent panel
32
x coordinates of the UIListselect
34
w dimensions, in pixels, of the UIListselect
36
align alignment of text inside the UIListselect
38
UIListselect::UIListselect(UIPanel *parent, int x, int y, uint w, uint h, Align align, bool show_check)
39
: UIPanel(parent, x, y, w, h)
48
m_scrollbar = new UIScrollbar(parent, x+get_w()-24, y, 24, h, false);
49
m_scrollbar->moved.set(this, &UIListselect::set_scrollpos);
51
m_scrollbar->set_pagesize(h - 2*g_fh->get_fontheight(UI_FONT_SMALL));
52
m_scrollbar->set_steps(1);
54
m_lineheight=g_fh->get_fontheight(UI_FONT_SMALL);
56
m_last_click_time=-10000;
59
m_show_check = show_check;
62
m_check_picid = g_gr->get_picture(PicMod_Game, "pics/list_selected.png", true);
63
g_gr->get_picture_size(m_check_picid, &m_max_pic_width, &pic_h);
64
if (pic_h > m_lineheight)
75
Free allocated resources
77
UIListselect::~UIListselect()
85
Remove all entries from the listselect
87
void UIListselect::clear()
89
for(uint i = 0; i < m_entries.size(); i++)
94
m_scrollbar->set_steps(1);
97
m_last_click_time = -10000;
98
m_last_selection = -1;
103
Add a new entry to the listselect.
105
Args: name name that will be displayed
106
value value returned by get_select()
107
select if true, directly select the new entry
109
void UIListselect::add_entry(const char *name, void* value, bool select, int picid)
111
Entry *e = (Entry *)malloc(sizeof(Entry) + strlen(name));
115
strcpy(e->name, name);
119
entry_height=g_fh->get_fontheight(UI_FONT_SMALL);
122
g_gr->get_picture_size(picid, &w, &h);
123
entry_height= (h >= g_fh->get_fontheight(UI_FONT_SMALL)) ? h : g_fh->get_fontheight(UI_FONT_SMALL);
124
if(m_max_pic_width<w) m_max_pic_width=w;
126
if(entry_height>m_lineheight) m_lineheight=entry_height;
128
m_entries.push_back(e);
130
m_scrollbar->set_steps(m_entries.size() * get_lineheight() - get_h());
132
update(0, 0, get_eff_w(), get_h());
134
m_selection=m_entries.size()-1;
136
m_entries[m_selection]->picid = m_check_picid;
142
* Sort the listbox alphabetically. make sure that the current selection stays
143
* valid (though it might scroll out of visibility).
144
* start and end defines the beginning and the end of a subarea to
145
* sort, for example you might want to sort directorys for themselves at the
146
* top of list and files at the bottom.
148
void UIListselect::sort(int gstart, int gend) {
151
if(gstart==-1) start=0;
152
if(gend==-1) stop=m_entries.size();
155
for(uint i=start; i<stop; i++)
156
for(uint j=i; j<stop; j++) {
159
if(strcmp(ei->name, ej->name) > 0) {
160
if(m_selection==((int)i))
162
else if(m_selection==((int)j))
171
Set the list alignment (only horizontal alignment works)
173
void UIListselect::set_align(Align align)
175
m_align = (Align)(align & Align_Horizontal);
180
Scroll to the given position, in pixels.
182
void UIListselect::set_scrollpos(int i)
186
update(0, 0, get_eff_w(), get_h());
192
* Change the currently selected entry
194
* Args: i the entry to select
196
void UIListselect::select(int i)
198
if (m_selection == i)
202
if (m_selection != -1)
203
m_entries[m_selection]->picid = -1;
204
m_entries[i]->picid = m_check_picid;
208
selected.call(m_selection);
209
update(0, 0, get_eff_w(), get_h());
214
Return the total height (text + spacing) occupied by a single line
216
int UIListselect::get_lineheight()
218
return m_lineheight+2;
223
Redraw the listselect box
225
void UIListselect::draw(RenderTarget* dst)
228
int lineheight = get_lineheight();
229
int idx = m_scrollpos / lineheight;
230
int y = 1 + idx*lineheight - m_scrollpos;
232
dst->brighten_rect(0,0,get_w(),get_h(),ms_darken_value);
234
while(idx < (int)m_entries.size())
239
Entry* e = m_entries[idx];
241
if (idx == m_selection) {
242
// dst->fill_rect(1, y, get_eff_w()-2, g_font->get_fontheight(), m_selcolor);
243
dst->brighten_rect(1, y, get_eff_w()-2, m_lineheight, -ms_darken_value);
247
if (m_align & Align_Right)
249
else if (m_align & Align_HCenter)
252
// Pictures are always left aligned, leave some space here
254
x= m_max_pic_width + 10;
259
// Horizontal center the string
260
g_fh->draw_string(dst, UI_FONT_SMALL, UI_FONT_SMALL_CLR, x, y + (get_lineheight()-g_fh->get_fontheight(UI_FONT_SMALL))/2, e->name, m_align, -1);
265
g_gr->get_picture_size(e->picid, &w, &h);
266
dst->blit(1, y + (get_lineheight()-h)/2, e->picid);
275
* Handle mouse clicks: select the appropriate entry
277
bool UIListselect::handle_mouseclick(uint btn, bool down, int x, int y)
280
if (btn != 0) // only left-click
284
int time=Sys_GetTime();
286
// This hick hack is needed if any of the
287
// callback functions calls clear to forget the last
289
int real_last_click_time=m_last_click_time;
291
m_last_selection=m_selection;
292
m_last_click_time=time;
294
y = (y + m_scrollpos) / get_lineheight();
295
if (y >= 0 && y < (int)m_entries.size())
298
// check if doubleclicked
299
if(time-real_last_click_time < DOUBLE_CLICK_INTERVAL && m_last_selection==m_selection && m_selection!=-1)
300
double_clicked.call(m_selection);
310
void UIListselect::remove_entry(int i) {
311
if(i<0 || ((uint)i)>=m_entries.size()) return;
314
m_entries.erase(m_entries.begin() + i);
320
* Remove an entry by name. This only removes
321
* the first entry with this name. If none is found, nothing
324
void UIListselect::remove_entry(const char *str ) {
325
for(uint i=0; i<m_entries.size(); i++) {
326
if(!strcmp(m_entries[i]->name,str)) {