- start on 'favourites' visual design. service listbox now configurable (in complex...
[enigma2.git] / lib / service / listboxservice.cpp
1 #include <lib/service/listboxservice.h>
2 #include <lib/service/service.h>
3
4 void eListboxServiceContent::setRoot(const eServiceReference &root)
5 {
6         m_list.clear();
7         m_root = root;
8         
9         assert(m_service_center);
10         
11         ePtr<iListableService> lst;
12         if (m_service_center->list(m_root, lst))
13                 eDebug("no list available!");
14         else
15                 if (lst->getContent(m_list))
16                         eDebug("getContent failed");
17
18         m_size = m_list.size();
19         cursorHome();
20         
21         if (m_listbox)
22                 m_listbox->entryReset();
23 }
24
25 void eListboxServiceContent::getCurrent(eServiceReference &ref)
26 {
27         if (cursorValid())
28                 ref = *m_cursor;
29         else
30                 ref = eServiceReference();
31 }
32
33 void eListboxServiceContent::initMarked()
34 {
35         m_marked.clear();
36 }
37
38 void eListboxServiceContent::addMarked(const eServiceReference &ref)
39 {
40         m_marked.insert(ref);
41         if (m_listbox)
42                 m_listbox->entryChanged(lookupService(ref));
43 }
44
45 void eListboxServiceContent::removeMarked(const eServiceReference &ref)
46 {
47         m_marked.erase(ref);
48         if (m_listbox)
49                 m_listbox->entryChanged(lookupService(ref));
50 }
51
52 int eListboxServiceContent::isMarked(const eServiceReference &ref)
53 {
54         return m_marked.find(ref) != m_marked.end();
55 }
56
57 void eListboxServiceContent::markedQueryStart()
58 {
59         m_marked_iterator = m_marked.begin();
60 }
61
62 int eListboxServiceContent::markedQueryNext(eServiceReference &ref)
63 {
64         if (m_marked_iterator == m_marked.end())
65                 return -1;
66         ref = *m_marked_iterator++;
67         return 0;
68 }
69
70 int eListboxServiceContent::lookupService(const eServiceReference &ref)
71 {
72                 /* shortcut for cursor */
73         if (ref == *m_cursor)
74                 return m_cursor_number;
75                 /* otherwise, search in the list.. */
76         int index = 0;
77         for (list::const_iterator i(m_list.begin()); i != m_list.end(); ++i, ++index);
78         
79                 /* this is ok even when the index was not found. */
80         return index;
81 }
82
83 void eListboxServiceContent::setVisualMode(int mode)
84 {
85         m_visual_mode = mode;
86         
87         if (m_visual_mode == visModeSimple)
88         {
89                 m_element_position[celServiceName] = eRect(ePoint(0, 0), m_itemsize);
90                 m_element_font[celServiceName] = new gFont("Arial", 14);
91                 m_element_position[celServiceNumber] = eRect();
92                 m_element_font[celServiceNumber] = 0;
93                 m_element_position[celIcon] = eRect();
94                 m_element_position[celServiceInfo] = eRect();
95                 m_element_font[celServiceInfo] = 0;
96         }
97 }
98
99 void eListboxServiceContent::setElementPosition(int element, eRect where)
100 {
101         if ((element >= 0) && (element < celElements))
102                 m_element_position[element] = where;
103 }
104
105 void eListboxServiceContent::setElementFont(int element, gFont *font)
106 {
107         if ((element >= 0) && (element < celElements))
108                 m_element_font[element] = font;
109 }
110
111 DEFINE_REF(eListboxServiceContent);
112
113 eListboxServiceContent::eListboxServiceContent()
114 {
115         m_visual_mode = visModeSimple;
116         m_size = 0;
117         cursorHome();
118         eServiceCenter::getInstance(m_service_center);
119 }
120
121 void eListboxServiceContent::cursorHome()
122 {
123         m_cursor = m_list.begin();
124         m_cursor_number = 0;
125 }
126
127 void eListboxServiceContent::cursorEnd()
128 {
129         m_cursor = m_list.end();
130         m_cursor_number = m_size;
131 }
132
133 int eListboxServiceContent::cursorMove(int count)
134 {
135         if (count > 0)
136         {
137                 while (count && (m_cursor != m_list.end()))
138                 {
139                         ++m_cursor;
140                         ++m_cursor_number;
141                         --count;
142                 }
143         } else if (count < 0)
144         {
145                 while (count && (m_cursor != m_list.begin()))
146                 {
147                         --m_cursor;
148                         --m_cursor_number;
149                         ++count;
150                 }
151         }
152         
153         return 0;
154 }
155
156 int eListboxServiceContent::cursorValid()
157 {
158         return m_cursor != m_list.end();
159 }
160
161 int eListboxServiceContent::cursorSet(int n)
162 {
163         cursorHome();
164         cursorMove(n);
165         
166         return 0;
167 }
168
169 int eListboxServiceContent::cursorGet()
170 {
171         return m_cursor_number;
172 }
173
174 void eListboxServiceContent::cursorSave()
175 {
176         m_saved_cursor = m_cursor;
177         m_saved_cursor_number = m_cursor_number;
178 }
179
180 void eListboxServiceContent::cursorRestore()
181 {
182         m_cursor = m_saved_cursor;
183         m_cursor_number = m_saved_cursor_number;
184 }
185
186 int eListboxServiceContent::size()
187 {
188         return m_size;
189 }
190         
191 void eListboxServiceContent::setSize(const eSize &size)
192 {
193         m_itemsize = size;
194         setVisualMode(m_visual_mode);
195 }
196
197 void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
198 {
199         painter.clip(eRect(offset, m_itemsize));
200         if (cursorValid() && isMarked(*m_cursor))
201                 style.setStyle(painter, eWindowStyle::styleListboxMarked);
202         else
203                 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
204         painter.clear();
205         
206         if (cursorValid())
207         {
208                         /* get service information */
209                 ePtr<iStaticServiceInformation> service_info;
210                 m_service_center->info(*m_cursor, service_info);
211                 
212                 for (int e = 0; e < celElements; ++e)
213                 {
214                         if (!m_element_font[e])
215                                 continue;
216                         painter.setFont(m_element_font[e]);
217                         
218                         std::string text = "<n/a>";
219                         
220                         switch (e)
221                         {
222                         case celServiceName:
223                         {
224                                 if (service_info)
225                                         service_info->getName(*m_cursor, text);
226                                 break;
227                         }
228                         case celServiceNumber:
229                         {
230                                 char bla[10];
231                                 sprintf(bla, "%d", m_cursor_number + 1);
232                                 text = bla;
233                                 break;
234                         }
235                         case celServiceInfo:
236                         {
237                                 text = "now&next";
238                                 break;
239                         }
240                         case celIcon:
241                                 continue;
242                         }
243                         
244                         eRect area = m_element_position[e];
245                         area.moveBy(offset.x(), offset.y());
246                         
247                         painter.renderText(area, text);
248                 }
249                 
250                 if (selected)
251                         style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
252         }
253         
254         painter.clippop();
255 }
256