1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
#ifndef __listbox_h
#define __listbox_h
#include <sstream>
#include <lib/driver/rc.h>
#include <lib/gdi/grc.h>
#include <lib/gdi/fb.h>
#include <lib/gui/ewidget.h>
#include <lib/gui/eskin.h>
#include <lib/gui/ewindow.h>
#include <lib/gui/guiactions.h>
#include <lib/gui/statusbar.h>
int calcFontHeight( const gFont& font );
class eListBoxEntry;
class eListBoxBase: public eDecoWidget
{
int recalced;
const eWidget* descr;
#ifndef DISABLE_LCD
eLabel* tmpDescr; // used for description Label in LCD
#endif
gColor colorActiveB, colorActiveF;
eRect crect, crect_selected;
enum { arNothing, arCurrentOld, arAll};
int movemode, MaxEntries, flags, item_height, columns, in_atomic, atomic_redraw, atomic_old, atomic_new;
bool atomic_selchanged;
bool atomic_selected;
protected:
ePtrList<eListBoxEntry>::iterator top, bottom, current;
eListBoxBase(eWidget* parent, const eWidget* descr=0, int takefocus=1, int item_height=0, const char *deco="eListBox" );
ePtrList<eListBoxEntry> childs;
eListBoxEntry* getCurrent() { return current != childs.end() ? *current : 0; }
eListBoxEntry* getNext() { ePtrList<eListBoxEntry>::iterator c=current; ++c; return c != childs.end() ? *c : 0; }
eListBoxEntry* goNext();
eListBoxEntry* goPrev();
int setProperty(const eString &prop, const eString &value);
private:
eRect getEntryRect(int n);
int eventHandler(const eWidgetEvent &event);
void eraseBackground() {};
void recalcMaxEntries();
void recalcClientRect();
int newFocus();
void redrawWidget(gPainter *target, const eRect &area);
void lostFocus();
void gotFocus();
void init();
virtual void SendSelected( eListBoxEntry* entry )=0;
virtual void SendSelChanged( eListBoxEntry* entry )=0;
public:
~eListBoxBase();
enum { dirPageDown, dirPageUp, dirDown, dirUp, dirFirst, dirLast };
enum { flagNoUpDownMovement=1, flagNoPageMovement=2, flagShowEntryHelp=4, flagShowPartial=8 };
enum { OK = 0, ERROR=1, E_ALLREADY_SELECTED = 2, E_COULDNT_FIND = 4, E_INVALID_ENTRY = 8, E_NOT_VISIBLE = 16 };
void setFlags(int);
void removeFlags(int);
void invalidateEntry(int n){ invalidate(getEntryRect(n));}
void invalidateContent();
void setColumns(int col);
int getColumns() { return columns; }
void setMoveMode(int move) { movemode=move; }
void append(eListBoxEntry* e, bool holdCurrent=false, bool front=false);
void remove(eListBoxEntry* e, bool holdCurrent=false);
void clearList();
int getCount() { return childs.size(); }
int setCurrent(const eListBoxEntry *c, bool sendSelected=false);
void sort();
int moveSelection(int dir, bool sendSelected=false);
void setActiveColor(gColor back, gColor front);
void beginAtomic();
void endAtomic();
void FakeFocus( int i ) { have_focus=i; }
void invalidateCurrent()
{
int n=0;
for (ePtrList<eListBoxEntry>::iterator i(top); i != bottom; ++i, ++n)
if ( i == current )
invalidate(getEntryRect(n));
}
};
template <class T>
class eListBox: public eListBoxBase
{
void SendSelected( eListBoxEntry* entry )
{
/*emit*/ selected((T*)entry);
}
void SendSelChanged( eListBoxEntry* entry )
{
/*emit*/ selchanged((T*)entry);
}
public:
Signal1<void, T*> selected;
Signal1<void, T*> selchanged;
eListBox(eWidget *parent, const eWidget* descr=0, int takefocus=1 )
:eListBoxBase( parent, descr, takefocus, T::getEntryHeight() )
{
}
T* getCurrent() { return (T*)eListBoxBase::getCurrent(); }
T* getNext() { return (T*)eListBoxBase::getNext(); }
T* goNext() { return (T*)eListBoxBase::goNext(); }
T* goPrev() { return (T*)eListBoxBase::goPrev(); }
template <class Z>
int forEachEntry(Z ob)
{
for (ePtrList<eListBoxEntry>::iterator i(childs.begin()); i!=childs.end(); ++i)
if ( ob((T&)(**i)) )
return OK;
return ERROR;
}
template <class Z>
int forEachVisibleEntry(Z ob)
{
if (!isVisible())
return E_NOT_VISIBLE;
for (ePtrList<eListBoxEntry>::iterator i(top); i!=bottom; ++i)
if ( ob((T&)(**i)) )
return OK;
return ERROR;
}
};
class eListBoxEntry: public Object
{
friend class eListBox<eListBoxEntry>;
protected:
eListBox<eListBoxEntry>* listbox;
eString helptext;
public:
eListBoxEntry(eListBox<eListBoxEntry>* parent, eString hlptxt=0)
:listbox(parent), helptext(hlptxt?hlptxt:eString(" "))
{
if (listbox)
listbox->append(this);
}
virtual ~eListBoxEntry()
{
if (listbox)
listbox->remove(this);
}
virtual bool operator < ( const eListBoxEntry& e)const
{
return false;
}
virtual const eString& redraw(gPainter *rc, const eRect& rect, gColor coActiveB, gColor coActiveF, gColor coNormalB, gColor coNormalF, int state )=0;
void drawEntryRect(gPainter *rc, const eRect& rect, gColor coActiveB, gColor coActiveF, gColor coNormalB, gColor coNormalF, int state);
void drawEntryBorder(gPainter *rc, const eRect& rect, gColor coActiveB, gColor coActiveF, gColor coNormalB, gColor coNormalF);
const eString &getHelpText() const { return helptext; }
};
class eListBoxEntryText: public eListBoxEntry
{
friend class eListBox<eListBoxEntryText>;
protected:
eString text;
void *key;
int align;
eTextPara *para;
int yOffs;
static gFont font;
int keytype;
public:
enum { value, ptr };
static int getEntryHeight();
eListBoxEntryText(eListBox<eListBoxEntryText>* lb, const char* txt=0, void *key=0, int align=0, const eString &hlptxt="", int keytype = value )
:eListBoxEntry( (eListBox<eListBoxEntry>*)lb, hlptxt ), text(txt),
key(key), align(align), para(0), keytype(keytype)
{
}
eListBoxEntryText(eListBox<eListBoxEntryText>* lb, const eString& txt, void* key=0, int align=0, const eString &hlptxt="", int keytype = value )
:eListBoxEntry( (eListBox<eListBoxEntry>*)lb, hlptxt ), text(txt),
key(key), align(align), para(0), keytype(keytype)
{
}
~eListBoxEntryText();
bool operator < ( const eListBoxEntry& e) const
{
if (key == ((eListBoxEntryText&)e).key || keytype == ptr)
return text < ((eListBoxEntryText&)e).text;
else
return key < ((eListBoxEntryText&)e).key;
}
void *& getKey() { return key; }
const void* getKey() const { return key; }
const eString& getText() { return text; }
void SetText(const eString& txt); // not setText !!!
protected:
const eString& redraw(gPainter *rc, const eRect& rect, gColor coActiveB, gColor coActiveF, gColor coNormalB, gColor coNormalF, int state );
};
class eListBoxEntryTextStream: public eListBoxEntry
{
friend class eListBox<eListBoxEntryTextStream>;
protected:
std::stringstream text;
static gFont font;
public:
static int getEntryHeight();
eListBoxEntryTextStream(eListBox<eListBoxEntryTextStream>* lb)
:eListBoxEntry((eListBox<eListBoxEntry>*)lb)
{
}
bool operator < ( const eListBoxEntryTextStream& e) const
{
return text.str() < e.text.str();
}
protected:
const eString &redraw(gPainter *rc, const eRect& rect, gColor coActiveB, gColor coActiveF, gColor coNormalB, gColor coNormalF, int state );
};
class eListBoxEntryMenu: public eListBoxEntryText
{
friend class eListBox<eListBoxEntryMenu>;
public:
Signal0<void> selected;
eListBoxEntryMenu(eListBox<eListBoxEntryMenu>* lb, const char* txt, const eString &hlptxt="", int align=0 )
:eListBoxEntryText((eListBox<eListBoxEntryText>*)lb, txt, 0, align, hlptxt)
{
if (listbox)
CONNECT(listbox->selected, eListBoxEntryMenu::LBSelected);
}
void LBSelected(eListBoxEntry* t)
{
if (t == this)
/* emit */ selected();
}
};
template <class T>
class eListBoxWindow: public eWindow
{
public:
int Entrys;
int width;
eListBox<T> list;
eStatusBar *statusbar;
eListBoxWindow(eString Title="", int Entrys=0, int width=400, bool sbar=0);
};
template <class T>
inline eListBoxWindow<T>::eListBoxWindow(eString Title, int Entrys, int width, bool sbar)
: eWindow(0), Entrys(Entrys), width(width), list(this), statusbar(sbar?new eStatusBar(this):0)
{
list.setFlags( eListBoxBase::flagShowEntryHelp );
setText(Title);
cresize( eSize(width, (sbar?40:10)+Entrys*T::getEntryHeight() ) );
list.move(ePoint(10, 5));
list.resize(eSize(getClientSize().width()-20, getClientSize().height()-(sbar?35:5) ));
if (sbar)
{
statusbar->setFlags(eStatusBar::flagVCenter);
statusbar->move( ePoint(0, getClientSize().height()-30) );
statusbar->resize( eSize( getClientSize().width(), 30) );
statusbar->loadDeco();
statusbar->show();
}
}
#endif
|