Merge remote branch 'mine/ext-python'
[vuplus_xbmc] / xbmc / interfaces / python / xbmcmodule / controllist.cpp
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include <Python.h>
23
24 #include "../XBPythonDll.h"
25 #include "guilib/GUIListContainer.h"
26 #include "guilib/GUIFontManager.h"
27 #include "guilib/GUIWindowManager.h"
28 #include "guilib/GUILabel.h"
29 #include "control.h"
30 #include "pyutil.h"
31
32 using namespace std;
33
34 #ifndef __GNUC__
35 #pragma code_seg("PY_TEXT")
36 #pragma data_seg("PY_DATA")
37 #pragma bss_seg("PY_BSS")
38 #pragma const_seg("PY_RDATA")
39 #endif
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 namespace PYXBMC
46 {
47   extern PyObject* ControlSpin_New(void);
48
49   PyObject* ControlList_New(PyTypeObject *type, PyObject *args, PyObject *kwds)
50   {
51     static const char *keywords[] = {
52       "x", "y", "width", "height", "font",
53       "textColor", "buttonTexture", "buttonFocusTexture",
54       // maintain order of above items for backward compatibility
55       "selectedColor",
56       "imageWidth", "imageHeight",
57       "itemTextXOffset", "itemTextYOffset",
58       "itemHeight", "space", "alignmentY", NULL };//"shadowColor", NULL };
59     ControlList *self;
60     char *cFont = NULL;
61     char *cTextColor = NULL;
62     char *cSelectedColor = NULL;
63     char *cTextureButton = NULL;
64     char *cTextureButtonFocus = NULL;
65     //char* cShadowColor = NULL;
66     self = (ControlList*)type->tp_alloc(type, 0);
67     if (!self) return NULL;
68     new(&self->strFont) string();
69     new(&self->strTextureButton) string();
70     new(&self->strTextureButtonFocus) string();
71     new(&self->vecItems) std::vector<PYXBMC::ListItem*>();
72
73     // create a python spin control
74     self->pControlSpin = (ControlSpin*)ControlSpin_New();
75     if (!self->pControlSpin)
76     {
77       Py_DECREF( self );
78       return NULL;
79     }
80
81     // initialize default values
82     self->strFont = "font13";
83     self->textColor = 0xe0f0f0f0;
84     self->selectedColor = 0xffffffff;
85     self->imageHeight = 10;
86     self->imageWidth = 10;
87     self->itemHeight = 27;
88     self->space = 2;
89     self->itemTextOffsetX = CONTROL_TEXT_OFFSET_X;
90     self->itemTextOffsetY = CONTROL_TEXT_OFFSET_Y;
91     self->alignmentY = XBFONT_CENTER_Y;
92     //self->shadowColor = NULL;
93
94     if (!PyArg_ParseTupleAndKeywords(
95       args,
96       kwds,
97       (char*)"llll|ssssslllllll",//s",
98       (char**)keywords,
99       &self->dwPosX,
100       &self->dwPosY,
101       &self->dwWidth,
102       &self->dwHeight,
103       &cFont,
104       &cTextColor,
105       &cTextureButton,
106       &cTextureButtonFocus,
107       &cSelectedColor,
108       &self->imageWidth,
109       &self->imageHeight,
110       &self->itemTextOffsetX,
111       &self->itemTextOffsetY,
112       &self->itemHeight,
113       &self->space,
114       &self->alignmentY//,
115       ))//&cShadowColor))
116     {
117       Py_DECREF( self );
118       return NULL;
119     }
120
121     // set specified values
122     if (cFont) self->strFont = cFont;
123     if (cTextColor)
124     {
125       sscanf( cTextColor, "%x", &self->textColor );
126     }
127     if (cSelectedColor)
128     {
129       sscanf( cSelectedColor, "%x", &self->selectedColor );
130     }
131     //if (cShadowColor) sscanf( cShadowColor, "%x", &self->shadowColor );
132
133     self->strTextureButton = cTextureButton ? cTextureButton :
134       PyXBMCGetDefaultImage((char*)"listcontrol", (char*)"texturenofocus", (char*)"list-nofocus.png");
135     self->strTextureButtonFocus = cTextureButtonFocus ? cTextureButtonFocus :
136       PyXBMCGetDefaultImage((char*)"listcontrol", (char*)"texturefocus", (char*)"list-focus.png");
137
138     // default values for spin control
139     self->pControlSpin->dwPosX = self->dwWidth - 35;
140     self->pControlSpin->dwPosY = self->dwHeight - 15;
141
142     return (PyObject*)self;
143   }
144
145   void ControlList_Dealloc(ControlList* self)
146   {
147     // conditionally delete spincontrol
148     Py_XDECREF(self->pControlSpin);
149
150     // delete all ListItem from vector
151     vector<ListItem*>::iterator it = self->vecItems.begin();
152     while (it != self->vecItems.end())
153     {
154       ListItem* pListItem = *it;
155       Py_DECREF(pListItem);
156       ++it;
157     }
158     self->vecItems.clear();
159     self->vecItems.~vector();
160
161     self->strFont.~string();
162     self->strTextureButton.~string();
163     self->strTextureButtonFocus.~string();
164
165     self->ob_type->tp_free((PyObject*)self);
166   }
167
168   CGUIControl* ControlList_Create(ControlList* pControl)
169   {
170     CLabelInfo label;
171     label.align = pControl->alignmentY;
172     label.font = g_fontManager.GetFont(pControl->strFont);
173     label.textColor = label.focusedColor = pControl->textColor;
174     //label.shadowColor = pControl->shadowColor;
175     label.selectedColor = pControl->selectedColor;
176     label.offsetX = (float)pControl->itemTextOffsetX;
177     label.offsetY = (float)pControl->itemTextOffsetY;
178     // Second label should have the same font, alignment, and colours as the first, but
179     // the offsets should be 0.
180     CLabelInfo label2 = label;
181     label2.offsetX = label2.offsetY = 0;
182     label2.align |= XBFONT_RIGHT;
183
184     pControl->pGUIControl = new CGUIListContainer(
185       pControl->iParentId,
186       pControl->iControlId,
187       (float)pControl->dwPosX,
188       (float)pControl->dwPosY,
189       (float)pControl->dwWidth,
190       (float)pControl->dwHeight - pControl->pControlSpin->dwHeight - 5,
191       label, label2,
192       (CStdString)pControl->strTextureButton,
193       (CStdString)pControl->strTextureButtonFocus,
194       (float)pControl->itemHeight,
195       (float)pControl->imageWidth, (float)pControl->imageHeight,
196       (float)pControl->space);
197
198     return pControl->pGUIControl;
199   }
200
201   /*
202    * ControlList_AddItem
203    * (string label) / (ListItem)
204    * ListItem is added to vector
205    * For a string we create a new ListItem and add it to the vector
206    */
207 PyDoc_STRVAR(addItem__doc__,
208     "addItem(item) -- Add a new item to this list control.\n"
209     "\n"
210     "item               : string, unicode or ListItem - item to add.\n"
211     "\n"
212     "example:\n"
213     "  - cList.addItem('Reboot XBMC')\n");
214
215   PyObject* ControlList_AddItem(ControlList *self, PyObject *args)
216   {
217     PyObject *pObject;
218     if (!PyArg_ParseTuple(args, (char*)"O", &pObject))  return NULL;
219
220     ListItem* pListItem = NULL;
221     if (ListItem_CheckExact(pObject))
222     {
223       // object is a listitem
224       pListItem = (ListItem*)pObject;
225       Py_INCREF(pListItem);
226     }
227     else
228     {
229       string strText;
230       // object is probably a text item
231       if (!PyXBMCGetUnicodeString(strText, pObject, 1)) return NULL;
232       // object is a unicode string now, create a new ListItem
233       pListItem = ListItem_FromString(strText);
234     }
235
236     // add item to objects vector
237     self->vecItems.push_back(pListItem);
238
239     // construct a CFileItemList to pass 'em on to the list
240     CGUIListItemPtr items(new CFileItemList());
241     for (unsigned int i = 0; i < self->vecItems.size(); i++)
242       ((CFileItemList*)items.get())->Add(self->vecItems[i]->item);
243
244     CGUIMessage msg(GUI_MSG_LABEL_BIND, self->iParentId, self->iControlId, 0, 0, items);
245     msg.SetPointer(items.get());
246     g_windowManager.SendThreadMessage(msg, self->iParentId);
247
248     Py_INCREF(Py_None);
249     return Py_None;
250   }
251
252 PyDoc_STRVAR(addItems__doc__,
253     "addItems(items) -- Adds a list of listitems or strings to this list control.\n"
254     "\n"
255     "items                : List - list of strings, unicode objects or ListItems to add.\n"
256     "\n"
257     "*Note, You can use the above as keywords for arguments.\n"
258     "\n"
259     "       Large lists benefit considerably, than using the standard addItem()"
260     "\n"
261     "example:\n"
262     "  - cList.addItems(items=listitems)\n");
263
264   PyObject* ControlList_AddItems(ControlList *self, PyObject *args, PyObject *kwds)
265   {
266     PyObject *pList = NULL;
267     static const char *keywords[] = { "items", NULL };
268
269     if (!PyArg_ParseTupleAndKeywords(
270       args,
271       kwds,
272       (char*)"O",
273       (char**)keywords,
274       &pList) || pList == NULL || !PyObject_TypeCheck(pList, &PyList_Type))
275     {
276       PyErr_SetString(PyExc_TypeError, "Object should be of type List");
277       return NULL;
278     }
279
280     CGUIListItemPtr items(new CFileItemList());
281     for (int item = 0; item < PyList_Size(pList); item++)
282     {
283       PyObject *pItem = PyList_GetItem(pList, item);
284
285       ListItem* pListItem = NULL;
286       if (ListItem_CheckExact(pItem))
287       {
288         // object is a listitem
289         pListItem = (ListItem*)pItem;
290         Py_INCREF(pListItem);
291       }
292       else
293       {
294         string strText;
295         // object is probably a text item
296         if (!PyXBMCGetUnicodeString(strText, pItem, 1)) return NULL;
297         // object is a unicode string now, create a new ListItem
298         pListItem = ListItem_FromString(strText);
299       }
300
301       // add item to objects vector
302       self->vecItems.push_back(pListItem);
303       ((CFileItemList*)items.get())->Add(pListItem->item);
304     }
305
306     // create message
307     CGUIMessage msg(GUI_MSG_LABEL_BIND, self->iParentId, self->iControlId, 0, 0, items);
308     msg.SetPointer(items.get());
309     g_windowManager.SendThreadMessage(msg, self->iParentId);
310
311     Py_INCREF(Py_None);
312     return Py_None;
313   }
314
315   /*
316   * ControlList_SelectItem(int item)
317   * Select an item by index
318   */
319   PyDoc_STRVAR(selectItem,
320     "selectItem(item) -- Select an item by index number.\n"
321     "\n"
322     "item               : integer - index number of the item to select.\n"
323     "\n"
324     "example:\n"
325     "  - cList.selectItem(12)\n");
326
327   PyObject* ControlList_SelectItem(ControlList *self, PyObject *args)
328   {
329     long itemIndex;
330
331     if (!PyArg_ParseTuple(args, (char*)"l", &itemIndex)) return NULL;
332
333     // create message
334     CGUIMessage msg(GUI_MSG_ITEM_SELECT, self->iParentId, self->iControlId, itemIndex);
335
336     // send message
337     g_windowManager.SendThreadMessage(msg, self->iParentId);
338
339     Py_INCREF(Py_None);
340     return Py_None;
341   }
342
343   // reset() method
344   PyDoc_STRVAR(reset__doc__,
345     "reset() -- Clear all ListItems in this control list.\n"
346     "\n"
347     "example:\n"
348     "  - cList.reset()\n");
349
350   PyObject* ControlList_Reset(ControlList *self, PyObject *args)
351   {
352     // create message
353     ControlList *pControl = (ControlList*)self;
354     CGUIMessage msg(GUI_MSG_LABEL_RESET, pControl->iParentId, pControl->iControlId);
355
356     g_windowManager.SendThreadMessage(msg, pControl->iParentId);
357
358     // delete all items from vector
359     // delete all ListItem from vector
360     vector<ListItem*>::iterator it = self->vecItems.begin();
361     while (it != self->vecItems.end())
362     {
363       ListItem* pListItem = *it;
364       Py_DECREF(pListItem);
365       ++it;
366     }
367     self->vecItems.clear();
368
369     Py_INCREF(Py_None);
370     return Py_None;
371   }
372
373   // getSpinControl() method
374   PyDoc_STRVAR(getSpinControl__doc__,
375     "getSpinControl() -- returns the associated ControlSpin object.\n"
376     "\n"
377     "*Note, Not working completely yet -\n"
378     "       After adding this control list to a window it is not possible to change\n"
379     "       the settings of this spin control.\n"
380     "\n"
381     "example:\n"
382     "  - ctl = cList.getSpinControl()\n");
383
384   PyObject* ControlList_GetSpinControl(ControlList *self, PyObject *args)
385   {
386     Py_INCREF(self->pControlSpin);
387     return (PyObject*)self->pControlSpin;
388   }
389
390   // setImageDimensions() method
391   PyDoc_STRVAR(setImageDimensions__doc__,
392     "setImageDimensions(imageWidth, imageHeight) -- Sets the width/height of items icon or thumbnail.\n"
393     "\n"
394     "imageWidth         : [opt] integer - width of items icon or thumbnail.\n"
395     "imageHeight        : [opt] integer - height of items icon or thumbnail.\n"
396     "\n"
397     "example:\n"
398     "  - cList.setImageDimensions(18, 18)\n");
399
400   PyObject* ControlList_SetImageDimensions(ControlList *self, PyObject *args)
401   {
402     if (!PyArg_ParseTuple(args, (char*)"ll", &self->imageWidth, &self->imageHeight))
403     {
404       return NULL;
405     }
406
407     /*
408     PyXBMCGUILock();
409     if (self->pGUIControl)
410     {
411       CGUIListControl* pListControl = (CGUIListControl*) self->pGUIControl;
412       pListControl->SetImageDimensions((float)self->dwImageWidth, (float)self->dwImageHeight );
413     }
414     PyXBMCGUIUnlock();
415     */
416     Py_INCREF(Py_None);
417     return Py_None;
418   }
419
420   // setItemHeight() method
421   PyDoc_STRVAR(setItemHeight__doc__,
422     "setItemHeight(itemHeight) -- Sets the height of items.\n"
423     "\n"
424     "itemHeight         : integer - height of items.\n"
425     "\n"
426     "example:\n"
427     "  - cList.setItemHeight(25)\n");
428
429   PyObject* ControlList_SetItemHeight(ControlList *self, PyObject *args)
430   {
431     if (!PyArg_ParseTuple(args, (char*)"l", &self->itemHeight)) return NULL;
432
433     /*
434     PyXBMCGUILock();
435     if (self->pGUIControl)
436     {
437       CGUIListControl* pListControl = (CGUIListControl*) self->pGUIControl;
438       pListControl->SetItemHeight((float)self->dwItemHeight);
439     }
440     PyXBMCGUIUnlock();
441     */
442     Py_INCREF(Py_None);
443     return Py_None;
444   }
445
446
447   // setPageControlVisible() method
448   PyDoc_STRVAR(setPageControlVisible__doc__,
449     "setPageControlVisible(visible) -- Sets the spin control's visible/hidden state.\n"
450     "\n"
451     "visible            : boolean - True=visible / False=hidden.\n"
452     "\n"
453     "example:\n"
454     "  - cList.setPageControlVisible(True)\n");
455
456   PyObject* ControlList_SetPageControlVisible(ControlList *self, PyObject *args)
457   {
458     char isOn = true;
459
460     if (!PyArg_ParseTuple(args, (char*)"b", &isOn)) return NULL;
461
462     /*
463     PyXBMCGUILock();
464     if (self->pGUIControl)
465     {
466       ((CGUIListControl*)self->pGUIControl)->SetPageControlVisible((bool)isOn );
467     }
468     PyXBMCGUIUnlock();
469     */
470
471     Py_INCREF(Py_None);
472     return Py_None;
473   }
474
475   // setSpace() method
476   PyDoc_STRVAR(setSpace__doc__,
477     "setSpace(space) -- Set's the space between items.\n"
478     "\n"
479     "space              : [opt] integer - space between items.\n"
480     "\n"
481     "example:\n"
482     "  - cList.setSpace(5)\n");
483
484   PyObject* ControlList_SetSpace(ControlList *self, PyObject *args)
485   {
486     if (!PyArg_ParseTuple(args, (char*)"l", &self->space)) return NULL;
487
488     /*
489     PyXBMCGUILock();
490     if (self->pGUIControl)
491     {
492       CGUIListControl* pListControl = (CGUIListControl*) self->pGUIControl;
493       pListControl->SetSpaceBetweenItems((float)self->dwSpace);
494     }
495     PyXBMCGUIUnlock();
496     */
497
498     Py_INCREF(Py_None);
499     return Py_None;
500   }
501
502   // getSelectedPosition() method
503   PyDoc_STRVAR(getSelectedPosition__doc__,
504     "getSelectedPosition() -- Returns the position of the selected item as an integer.\n"
505     "\n"
506     "*Note, Returns -1 for empty lists.\n"
507     "\n"
508     "example:\n"
509     "  - pos = cList.getSelectedPosition()\n");
510
511   PyObject* ControlList_GetSelectedPosition(ControlList *self, PyObject *args)
512   {
513     // create message
514     ControlList *pControl = (ControlList*)self;
515     CGUIMessage msg(GUI_MSG_ITEM_SELECTED, pControl->iParentId, pControl->iControlId);
516     long pos = -1;
517
518     // send message
519     PyXBMCGUILock();
520     if ((self->vecItems.size() > 0) && pControl->pGUIControl)
521     {
522       pControl->pGUIControl->OnMessage(msg);
523       pos = msg.GetParam1();
524     }
525     PyXBMCGUIUnlock();
526
527     return Py_BuildValue((char*)"l", pos);
528   }
529
530   // getSelectedItem() method
531   PyDoc_STRVAR(getSelectedItem__doc__,
532     "getSelectedItem() -- Returns the selected item as a ListItem object.\n"
533     "\n"
534     "*Note, Same as getSelectedPosition(), but instead of an integer a ListItem object\n"
535     "       is returned. Returns None for empty lists.\n"
536     "       See windowexample.py on how to use this.\n"
537     "\n"
538     "example:\n"
539     "  - item = cList.getSelectedItem()\n");
540
541   PyObject* ControlList_GetSelectedItem(ControlList *self, PyObject *args)
542   {
543     // create message
544     ControlList *pControl = (ControlList*)self;
545     CGUIMessage msg(GUI_MSG_ITEM_SELECTED, pControl->iParentId, pControl->iControlId);
546     PyObject* pListItem = Py_None;
547
548     // send message
549     PyXBMCGUILock();
550     if ((self->vecItems.size() > 0) && pControl->pGUIControl)
551     {
552       pControl->pGUIControl->OnMessage(msg);
553       pListItem = (PyObject*)self->vecItems[msg.GetParam1()];
554     }
555     PyXBMCGUIUnlock();
556
557     Py_INCREF(pListItem);
558     return pListItem;
559   }
560
561   // size() method
562   PyDoc_STRVAR(size__doc__,
563     "size() -- Returns the total number of items in this list control as an integer.\n"
564     "\n"
565     "example:\n"
566     "  - cnt = cList.size()\n");
567
568   PyObject* ControlList_Size(ControlList *self)
569   {
570     return Py_BuildValue((char*)"l", self->vecItems.size());
571   }
572
573   // getListItem() method
574   PyDoc_STRVAR(getListItem__doc__,
575     "getListItem(index) -- Returns a given ListItem in this List.\n"
576     "\n"
577     "index           : integer - index number of item to return.\n"
578     "\n"
579     "*Note, throws a ValueError if index is out of range.\n"
580     "\n"
581     "example:\n"
582     "  - listitem = cList.getListItem(6)\n");
583
584   PyObject* ControlList_GetListItem(ControlList *self, PyObject *args)
585   {
586     int iPos = -1;
587     if (!PyArg_ParseTuple(args, (char*)"i", &iPos)) return NULL;
588
589     if (iPos < 0 || iPos >= (int)self->vecItems.size())
590     {
591       PyErr_SetString(PyExc_ValueError, "Index out of range");
592       return NULL;
593     }
594
595     PyObject* pListItem = (PyObject*)self->vecItems[iPos];
596
597     Py_INCREF(pListItem);
598     return pListItem;
599   }
600
601   // getItemHeight() Method
602   PyDoc_STRVAR(getItemHeight__doc__,
603     "getItemHeight() -- Returns the control's current item height as an integer.\n"
604     "\n"
605     "example:\n"
606     "  - item_height = self.cList.getItemHeight()\n");
607
608   PyObject* ControlList_GetItemHeight(ControlList *self)
609   {
610     return Py_BuildValue((char*)"l", self->itemHeight);
611   }
612
613   // getSpace() Method
614   PyDoc_STRVAR(getSpace__doc__,
615     "getSpace() -- Returns the control's space between items as an integer.\n"
616     "\n"
617     "example:\n"
618     "  - gap = self.cList.getSpace()\n");
619
620   PyObject* ControlList_GetSpace(ControlList *self)
621   {
622     return Py_BuildValue((char*)"l", self->space);
623   }
624
625 PyDoc_STRVAR(setStaticContent__doc__,
626     "setStaticContent(items) -- Fills a static list with a list of listitems.\n"
627     "\n"
628     "items                : List - list of listitems to add.\n"
629     "\n"
630     "*Note, You can use the above as keywords for arguments.\n"
631     "\n"
632     "example:\n"
633     "  - cList.setStaticContent(items=listitems)\n");
634
635   PyObject* ControlList_SetStaticContent(ControlList *self, PyObject *args, PyObject *kwds)
636   {
637     PyObject *pList = NULL;
638     static const char *keywords[] = { "items", NULL };
639
640     if (!PyArg_ParseTupleAndKeywords(
641       args,
642       kwds,
643       (char*)"O",
644       (char**)keywords,
645       &pList) || pList == NULL || !PyObject_TypeCheck(pList, &PyList_Type))
646     {
647       PyErr_SetString(PyExc_TypeError, "Object should be of type List");
648       return NULL;
649     }
650
651     vector<CGUIListItemPtr> items;
652
653     for (int item = 0; item < PyList_Size(pList); item++)
654     {
655       PyObject *pItem = PyList_GetItem(pList, item);
656       if (!ListItem_CheckExact(pItem))
657       {
658         PyErr_SetString(PyExc_TypeError, "Only ListItems can be passed");
659         return NULL;
660       }
661       // object is a listitem, and we set m_idpeth to 0 as this
662       // is used as the visibility condition for the item in the list
663       ListItem *listItem = (ListItem*)pItem;
664       listItem->item->m_idepth = 0;
665
666       items.push_back((CFileItemPtr &)listItem->item);
667     }
668     // set static list
669     ((CGUIBaseContainer *)self->pGUIControl)->SetStaticContent(items);
670
671     Py_INCREF(Py_None);
672     return Py_None;
673   }
674
675   PyMethodDef ControlList_methods[] = {
676     {(char*)"addItem", (PyCFunction)ControlList_AddItem, METH_VARARGS, addItem__doc__},
677     {(char*)"selectItem", (PyCFunction)ControlList_SelectItem, METH_VARARGS,  selectItem},
678     {(char*)"reset", (PyCFunction)ControlList_Reset, METH_VARARGS, reset__doc__},
679     {(char*)"getSpinControl", (PyCFunction)ControlList_GetSpinControl, METH_VARARGS, getSpinControl__doc__},
680     {(char*)"getSelectedPosition", (PyCFunction)ControlList_GetSelectedPosition, METH_VARARGS, getSelectedPosition__doc__},
681     {(char*)"getSelectedItem", (PyCFunction)ControlList_GetSelectedItem, METH_VARARGS, getSelectedItem__doc__},
682     {(char*)"setImageDimensions", (PyCFunction)ControlList_SetImageDimensions, METH_VARARGS, setImageDimensions__doc__},
683     {(char*)"setItemHeight", (PyCFunction)ControlList_SetItemHeight, METH_VARARGS, setItemHeight__doc__},
684     {(char*)"setSpace", (PyCFunction)ControlList_SetSpace, METH_VARARGS, setSpace__doc__},
685     {(char*)"setPageControlVisible", (PyCFunction)ControlList_SetPageControlVisible, METH_VARARGS, setPageControlVisible__doc__},
686     {(char*)"size", (PyCFunction)ControlList_Size, METH_VARARGS, size__doc__},
687     {(char*)"getItemHeight", (PyCFunction)ControlList_GetItemHeight, METH_VARARGS, getItemHeight__doc__},
688     {(char*)"getSpace", (PyCFunction)ControlList_GetSpace, METH_VARARGS, getSpace__doc__},
689     {(char*)"getListItem", (PyCFunction)ControlList_GetListItem, METH_VARARGS, getListItem__doc__},
690     {(char*)"setStaticContent", (PyCFunction)ControlList_SetStaticContent, METH_VARARGS|METH_KEYWORDS, setStaticContent__doc__},
691     {(char*)"addItems", (PyCFunction)ControlList_AddItems, METH_VARARGS|METH_KEYWORDS, addItems__doc__},
692     {NULL, NULL, 0, NULL}
693   };
694
695   PyDoc_STRVAR(controlList__doc__,
696     "ControlList class.\n"
697     "\n"
698     "ControlList(x, y, width, height[, font, textColor, buttonTexture, buttonFocusTexture,\n"
699     "            selectedColor, imageWidth, imageHeight, itemTextXOffset, itemTextYOffset,\n"
700     "            itemHeight, space, alignmentY])\n"//, shadowColor])\n"
701     "\n"
702     "x                  : integer - x coordinate of control.\n"
703     "y                  : integer - y coordinate of control.\n"
704     "width              : integer - width of control.\n"
705     "height             : integer - height of control.\n"
706     "font               : [opt] string - font used for items label. (e.g. 'font13')\n"
707     "textColor          : [opt] hexstring - color of items label. (e.g. '0xFFFFFFFF')\n"
708     "buttonTexture      : [opt] string - filename for focus texture.\n"
709     "buttonFocusTexture : [opt] string - filename for no focus texture.\n"
710     "selectedColor      : [opt] integer - x offset of label.\n"
711     "imageWidth         : [opt] integer - width of items icon or thumbnail.\n"
712     "imageHeight        : [opt] integer - height of items icon or thumbnail.\n"
713     "itemTextXOffset    : [opt] integer - x offset of items label.\n"
714     "itemTextYOffset    : [opt] integer - y offset of items label.\n"
715     "itemHeight         : [opt] integer - height of items.\n"
716     "space              : [opt] integer - space between items.\n"
717     "alignmentY         : [opt] integer - Y-axis alignment of items label - *Note, see xbfont.h\n"
718     //"shadowColor        : [opt] hexstring - color of items label's shadow. (e.g. '0xFF000000')\n"
719     "\n"
720     "*Note, You can use the above as keywords for arguments and skip certain optional arguments.\n"
721     "       Once you use a keyword, all following arguments require the keyword.\n"
722     "       After you create the control, you need to add it to the window with addControl().\n"
723     "\n"
724     "example:\n"
725     "  - self.cList = xbmcgui.ControlList(100, 250, 200, 250, 'font14', space=5)\n"
726   );
727
728 // Restore code and data sections to normal.
729 #ifndef __GNUC__
730 #pragma code_seg()
731 #pragma data_seg()
732 #pragma bss_seg()
733 #pragma const_seg()
734 #endif
735
736   PyTypeObject ControlList_Type;
737
738   void initControlList_Type()
739   {
740     PyXBMCInitializeTypeObject(&ControlList_Type);
741
742     ControlList_Type.tp_name = (char*)"xbmcgui.ControlList";
743     ControlList_Type.tp_basicsize = sizeof(ControlList);
744     ControlList_Type.tp_dealloc = (destructor)ControlList_Dealloc;
745     ControlList_Type.tp_compare = 0;
746     ControlList_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
747     ControlList_Type.tp_doc = controlList__doc__;
748     ControlList_Type.tp_methods = ControlList_methods;
749     ControlList_Type.tp_base = &Control_Type;
750     ControlList_Type.tp_new = ControlList_New;
751   }
752 }
753
754 #ifdef __cplusplus
755 }
756 #endif