import of enigma2
[enigma2.git] / lib / gui / ewidget.h
1 #ifndef __ewidget_h
2 #define __ewidget_h
3
4 #include <lib/base/ebase.h>
5 #include <lib/base/estring.h>
6 #include <lib/gdi/epoint.h>
7 #include <lib/gdi/esize.h>
8 #include <lib/gdi/erect.h>
9 #include <lib/base/eptrlist.h>
10 #include <libsig_comp.h>
11 #include <lib/gdi/grc.h>
12 #include <lib/driver/rc.h>
13 #include <lib/gui/actions.h>
14
15 class eWidgetEvent
16 {
17 public:
18         enum eventType
19         {
20                 evtKey,
21                 willShow, willHide,
22                 execBegin, execDone,
23                 gotFocus, lostFocus,
24                 
25                 changedText, changedFont, changedForegroundColor, changedBackgroundColor,
26                 changedSize, changedPosition, changedPixmap, childChangedHelpText,
27
28                 evtAction, evtShortcut
29         } type;
30         union
31         {
32                 int parameter;
33                 const eAction *action;
34                 const eRCKey *key;
35         }; 
36         eWidgetEvent(eventType type, int parameter=0): type(type), parameter(parameter) { }
37         eWidgetEvent(eventType type, const eAction *action): type(type), action(action) { }
38         eWidgetEvent(eventType type, const eRCKey &key): type(type), key(&key) { }
39         
40         /**
41          * \brief Event should be delivered to the focused widget.
42          *
43          * \return true if the event should be delivered to the focused widget instead of the widget itself.
44          */
45         int toFocus() const
46         {
47                 switch (type)
48                 {
49                 case evtKey:
50                         return 1;
51                 default:
52                         return 0;
53                 }
54         }
55 };
56
57 /** \brief The main widget class. All widgets inherit this class.
58  * eWidget handles focus management.
59  */
60 class eWidget: public Object
61 {
62         enum
63         {
64                 /// Widget was shown with show() or implicit show()
65                 stateShow=1,
66                 /// Widget is visible on screen. Implies stateShow.
67                 stateVisible=2
68         };
69         
70 public:
71         /**
72          * \brief Exits a (model) widget.
73          *
74          * Quit the local event loop, thus returning the control to the function which called \a exec.
75          * \sa eWidget::accept
76          * \sa eWidget::reject
77          */
78         void close(int result);
79         
80         /**
81          * \brief Closes with a returncode of 0 (success).
82          *
83          * Synonym to \a close(0);. Useful to use as a slot.
84          * \sa eWidget::close
85          */
86         void accept();
87
88         /**
89          * \brief Closes with a returncode of -1 (failure).
90          *
91          * Synonym to \a close(-1);. Useful to use as a slot.
92          * \sa eWidget::close
93          */
94         void reject();
95         /**
96          * \brief Signal is send, when the focus Changed
97          *
98          * used from a existing statusbar.
99          * \sa eWidget::focusChanged
100          */
101         Signal1<void, const eWidget*> focusChanged;
102         static Signal2< void, ePtrList<eAction>*, int > showHelp;
103 protected:
104         ePtrList<eAction> actionHelpList;
105         int helpID;
106         ePtrList<eWidget> childlist;
107         static eWidget *root;
108         eWidget *parent;
109         eString name;
110         eString helptext;
111         ePoint position;
112         ePoint absPosition;
113         eSize size;
114         eRect clientrect;
115         eRect clientclip;
116         
117         eAction *shortcut;
118         eWidget *shortcutFocusWidget;
119
120         ePtrList<eWidget> _focusList;
121         
122         ePtrList<eWidget> actionListener;
123         eWidget *focus, *TLW;
124
125                 /// old top-level focus
126         eWidget *oldTLfocus;
127         int takefocus;
128         int state;
129         
130         gDC *target;
131
132         inline eWidget *getTLW() // pseudoTLW !!
133         {
134                 return TLW ? TLW : (TLW = (parent && parent->parent) ? parent->getTLW() : this );
135         }
136         int result, in_loop, have_focus, just_showing;
137         void takeFocus();
138         void releaseFocus();
139
140         void _willShow();
141         void _willHide();
142         
143         virtual void willShow();
144         virtual void willHide();
145         
146         virtual void setPalette();
147
148         void willShowChildren();
149         void willHideChildren();
150         
151         /**
152          * \brief Hi priority event filter.
153          *
154          * This event filter is called before the event is delivered via \a event.
155          * \return 1 if the event should NOT be forwarded.
156          */
157         virtual int eventFilter(const eWidgetEvent &event);
158
159         /**
160          * \brief Handles an event.
161          *
162          * If re-implemented in a widget-sub-class, \c eWidget::event should be called whenever the event is
163          * not processed by the widget.
164          * \return 1 if the event was processed, 0 if ignored. it might be forwarded to other widgets then.
165          */
166
167         virtual int keyDown(int rc);
168         virtual int keyUp(int rc);
169
170         virtual void gotFocus();
171         virtual void lostFocus();
172         
173         virtual void recalcClientRect();
174         void recalcClip();
175         void checkFocus();
176
177         typedef ePtrList<eActionMap> actionMapList;
178
179         void findAction(eActionPrioritySet &prio, const eRCKey &key, eWidget *context);
180         void addActionMap(eActionMap *map);
181         void removeActionMap(eActionMap *map);
182         actionMapList actionmaps;
183         static actionMapList globalActions;
184
185                         // generic properties
186         gFont font;
187         eString text;
188         gColor backgroundColor, foregroundColor;
189         
190         ePtr<gPixmap> pixmap;
191
192         eString descr;
193
194 public:
195         virtual int eventHandler(const eWidgetEvent &event);
196         static void addGlobalActionMap(eActionMap *map);
197         static void removeGlobalActionMap(eActionMap *map);
198         inline eWidget *getNonTransparentBackground()
199         {
200                 if (backgroundColor >= 0)
201                         return this;
202                 return parent?parent->getNonTransparentBackground():this;
203         }
204
205 #ifndef DISABLE_LCD
206         eWidget *LCDTitle;
207         eWidget *LCDElement;
208         eWidget *LCDTmp;
209 #endif
210
211         void recalcAbsolutePosition();
212
213         inline const ePoint &getAbsolutePosition() const
214         {
215                 return absPosition;
216         }
217
218         inline ePoint getRelativePosition(eWidget *e) const
219         {
220                 ePoint pos=position;
221                 if (this != e)
222                         for (eWidget *a=parent; a && (a != e); a=a->parent)
223                                 pos+=a->clientrect.topLeft();
224                 return pos;
225         }
226
227         virtual void redrawWidget(gPainter *target, const eRect &area);
228
229         virtual void eraseBackground(gPainter *target, const eRect &area);
230
231         /**
232          * \brief Constructs a new eWidget. 
233          * \param parent The parent widget. The widget gets automatically removed when the parent gets removed.
234          * \param takefocus Specifies if the widget should be appended to the focus list of the TLW, i.e. if it can
235                   receive keys.
236          */
237         eWidget(eWidget *parent=0, int takefocus=0);
238
239         /**
240          * \brief Destructs an eWidget and all its childs.
241          *
242          * hide() is called when the widget is shown. The set ePixmap is \e not
243          * freed. If the widget acquired focus, it will be removed from the focuslist.
244          * \sa eWidget::setPixmap
245          */
246         virtual ~eWidget();
247         
248         /**
249          * \brief Returns a pointer to the focus list.
250          *
251          * The focus list is the list of childs which have the \c takefocus flag set.
252          * This list is only maintained for TLWs.
253          */
254         ePtrList<eWidget> *focusList() { return &_focusList; }
255
256         /**
257          * \brief Resizes the widget.
258          *
259          * Sets the size of the widget to the given size. The event \c changedSize event will be generated.
260          * \param size The new size, relative to the position.
261          */
262         void resize(const eSize& size);
263         
264         /**
265          * \brief Resizes clientrect (and the widget).
266          *
267          * Sets the clientrect of the widget to the given size. The real size of the widget will be set to met
268          * these requirement. The event \c changedSize event will be generated.
269          * \param size The new size of the clientrect, relative to the position.
270          */
271         void cresize(const eSize& size);
272         
273         /**
274          * \brief Moves the widget.
275          *
276          * Set the new position of the widget to the given position. The \c changedPosition event will be generated.
277          * \param position The new position, relative to the parent's \c clientrect.
278          */
279         void move(const ePoint& position);
280         
281         /**
282          * \brief Moves the clientrect (and the widget).
283          *
284          * Set the new position of the clientrect to the given position. The \c changedPosition event will be generated.
285          * \param position The new position, relative to the parent's \c clientrect.
286          */
287         void cmove(const ePoint& position);
288         
289         /**
290          * \brief Returns the current size.
291          *
292          * \return Current size of the widget, relative to the position.
293          */
294         const eSize& getSize() const { return size; }
295         
296         /** 
297          * \brief Returns the current position.
298          *
299          * \return Current position, relative to the parent's \c clientrect.
300          */
301         const ePoint& getPosition() const { return position; }
302         
303         /**
304          * \brief Returns the size of the clientrect.
305          *
306          * \return The usable size for the childwidgets.
307          */
308         eSize getClientSize() const { return clientrect.size(); }
309         
310         /**
311          * \brief Returns the clientrect.
312          *
313          * \return The area usable for the childwidgets.
314          */
315         const eRect& getClientRect() const { return clientrect; }
316
317         /**
318          * \brief Recursive redraw of a widget.
319          *
320          * All client windows get repaint too, but no widgets above. Unless you have a good reason, you shouldn't
321          * use this function and use \c invalidate().
322          * \param area The area which should be repaint. The default is to repaint the whole widget.
323          * \sa eWidget::invalidate
324          */
325         void redraw(eRect area=eRect());
326         
327         /**
328          * \brief Recursive (complete) redraw of a widget.
329          *
330          * Redraws the widget including background. This is the function to use if you want to manually redraw something!
331          * \param area The area which should be repaint. The default is to repaint the whole widget.
332          * \param force Forces a parent-invalidate even on non-visible widgets. Shouldn't be used outside eWidget.
333          * \sa eWidget::redraw
334          */
335         void invalidate(eRect area=eRect(), int force=0);
336         
337         /**
338          * \brief Enters modal message loop.
339          *
340          * A new event loop will be launched. The function returns when \a close is called.
341          * \return The argument of \a close.
342          * \sa eWidget::close
343          */
344         int exec();
345         
346         /**
347          * \brief Visually clears the widget.
348          *
349          * Clears the widget. This is done on \a hide().
350          * \sa eWidget::hide
351          */
352         void clear();
353         
354         /**
355          * \brief Delivers a widget-event.
356          *
357          * Internally calles \a eventFilter, then \a eventHandler() (in some cases of the focused widget)
358          * \param event The event to deliver.
359          */
360         int event(const eWidgetEvent &event);
361         
362         /**
363          * \brief Shows the widget.
364          *
365          * If necessary, the widget will be linked into the TLW's active focus list. The widget will
366          * visually appear.
367          * \sa eWidget::hide
368          */
369         void show();
370         
371         /** 
372          * \brief Hides the widget.
373          *
374          * The widget will be removed from the screen. All childs will be hidden too.
375          * \sa eWidget::show
376          */
377         void hide();
378         
379         /** 
380          * \brief Returns if the widget is vissible.
381          *
382          * \return If the widget and all parents are visible, \c true is returned, else false.
383          */
384         int isVisible() {               return (state&stateVisible) && ( (!parent) || parent->isVisible() );    }
385         
386         /**
387          * \brief Possible focus directions.
388          */
389         enum focusDirection
390         {
391                 focusDirNext, focusDirPrev, focusDirN, focusDirE, focusDirS, focusDirW
392         };
393
394         /**
395          * \brief changes the focused widget.
396          *
397          * Focuses the next or previous widget of the \c focuslist. An \c gotFocus and \c lostFocus event will be
398          * generated.
399          * \param dir The direction, \c focusDirection.
400          */
401         void focusNext(int dir=0);
402         
403         /**
404          * \brief Gives focus to a widget.
405          *
406          * Set the focus to the specified widget. The \c focuslist is updated, too.
407          * An \c gotFocus and \c lostFocus event will be generated.
408          * \param newfocus The new widget to focus.
409          */
410         void setFocus(eWidget *newfocus);
411         
412         /**
413          * \brief Sets the widget font.
414          *
415          * The font is used for example by the \c eLabel.
416          * \sa eLabel
417          * \param font The new font used by widget-specific drawing code.
418          */
419         void setFont(const gFont &font);
420         
421         /**
422          * \brief Sets the widget caption or text.
423          *
424          * \param label The text to assign to the widget.
425          */
426         void setText(const eString &label);
427         
428         const eString& getText() const { return text; }
429         void setBackgroundColor(const gColor& color, bool inv=true);
430         void setForegroundColor(const gColor& color, bool inv=true);
431         void setPixmap(gPixmap *pmap);
432         void setTarget(gDC *target);
433         gDC *getTarget() { return target; }
434
435 #ifndef DISABLE_LCD
436         void setLCD(eWidget *lcdtitle, eWidget *lcdelement);
437 #endif
438
439         void setName(const char *name);
440         const eString& getName() const { return name; }
441         eWidget*& getParent() { return parent; }
442         const gFont& getFont() const { return font; }
443         
444         const gColor& getBackgroundColor() const { return backgroundColor; }
445         const gColor& getForegroundColor() const { return foregroundColor; }
446         
447         int width() { return getSize().width(); }
448         int height() { return getSize().height(); }
449         
450         gPainter *getPainter(eRect area);
451
452         const eString& getHelpText() const      {       return helptext;        }
453
454         void setHelpText( const eString&);
455         /**
456          * \brief Sets a property.
457          *
458          * A property is a value/data pair which is used for serializing widgets (like in skinfiles).
459          * These properties are available to all \c "eWidget"-based classes.
460          * \arg \c position, the position of the widget, relative to the parent's childarea. Consider using csize for TLWs.
461          * Positions are specified in a "x:y" manner.
462          * \arg \c cposition, the position of the widget's clientrect (upper left). 
463          * This is useful for specifing a position independant of a decoration which might be
464          * different sized. The real position will be calculated to match the requested position.
465          * \arg \c size, the size of the widget. Consider using csize for TLWs. Sizes are specified in a "width:height" manner.
466          * \arg \c csize, the size of the clientrect. The real size will be calculated to match the requested size.
467          * \arg \c text, the text/caption of the widget.
468          * \arg \c font, the primary font used in the widget.
469          * \arg \c name, the name of the widget for referring them.
470          * \arg \c pixmap, an already loaded, named pixmap to be used as the widget's pixmap.
471          * \arg \c foregroundColor, a named color, which will be used for the widget's foreground color.
472          * \arg \c backgroundColor
473          * \param prop The property to be set.
474          * \param value The value to be set.
475          */
476         virtual int setProperty(const eString &prop, const eString &value);
477         
478         eWidget *search(const eString &name);
479
480         eWidget* getFocus() { return focus; }
481         
482         void makeRoot();
483         
484         void zOrderLower();
485         void zOrderRaise();
486         
487         /**
488          * \brief sets the shortcut (generate evtShortcut)
489          */
490         void setShortcut(const eString &shortcut);
491         void setShortcutFocus(eWidget *focus);
492         
493         void addActionToHelpList(eAction *action);
494         void clearHelpList();
495         void setHelpID(int fHelpID);
496 };
497
498 #endif