89fbfe95f59dfa3d79e8a18f863dd9aae83c54c6
[enigma2.git] / lib / gui / ewidget.cpp
1 #include <lib/gui/ewidget.h>
2 #include <lib/gui/ewidgetdesktop.h>
3
4 extern void dumpRegion(const gRegion &region);
5
6 eWidget::eWidget(eWidget *parent): m_parent(parent)
7 {
8         m_vis = 0;
9         m_desktop = 0;
10         
11         if (parent)
12                 m_vis = wVisShow;
13         
14         if (parent)
15                 parent->m_childs.push_back(this);
16 }
17
18 void eWidget::move(ePoint pos)
19 {
20         m_position = pos;
21         
22         event(evtChangedPosition);
23 }
24
25 void eWidget::resize(eSize size)
26 {
27         event(evtWillChangeSize, &size);
28         event(evtChangedSize);
29 }
30
31 void eWidget::invalidate(const gRegion &region)
32 {
33         gRegion res = /* region & */ m_visible_with_childs;
34         if (res.empty())
35                 return;
36         
37         eWidget *root = this;
38         ePoint abspos = position();
39         while (root && !root->m_desktop)
40         {
41                 root = root->m_parent;
42                 assert(root);
43                 abspos += root->position();
44         }
45         
46         res.moveBy(abspos);
47 //      eDebug("region to invalidate:");
48 //      dumpRegion(res);
49         root->m_desktop->invalidate(res);
50 }
51
52 void eWidget::show()
53 {
54         if (m_vis & wVisShow)
55                 return;
56         
57         m_vis |=  wVisShow;
58
59                 /* TODO: optimize here to only recalc what's required. possibly merge with hide. */
60         eWidget *root = this;
61         ePoint abspos = position();
62         while (root && !root->m_desktop)
63         {
64                 root = root->m_parent;
65                 assert(root);
66                 abspos += root->position();
67         }
68
69         root->m_desktop->recalcClipRegions();
70
71         gRegion abs = m_visible_with_childs;
72         abs.moveBy(abspos);
73         root->m_desktop->invalidate(abs);
74 }
75
76 void eWidget::hide()
77 {
78         m_vis &= ~wVisShow;
79
80                 /* TODO: optimize here to only recalc what's required. possibly merge with show. */
81         eWidget *root = this;
82         ePoint abspos = position();
83         while (root && !root->m_desktop)
84         {
85                 root = root->m_parent;
86                 abspos += root->position();
87         }
88         assert(root->m_desktop);
89
90         gRegion abs = m_visible_with_childs;
91         abs.moveBy(abspos);
92
93         root->m_desktop->recalcClipRegions();
94         root->m_desktop->invalidate(abs);
95 }
96
97 void eWidget::destruct()
98 {
99         if (m_parent)
100                 m_parent->m_childs.remove(this);
101         delete this;
102 }
103
104 eWidget::~eWidget()
105 {
106                 /* destroy all childs */
107         ePtrList<eWidget>::iterator i(m_childs.begin());
108         while (i != m_childs.end())
109         {
110                 delete *i;
111                 i = m_childs.erase(i);
112         }
113 }
114
115 void eWidget::doPaint(gPainter &painter, const gRegion &r)
116 {
117         if (m_visible_with_childs.empty())
118                 return;
119         
120         gRegion region = r;
121                         /* we were in parent's space, now we are in local space */
122         region.moveBy(-position());
123         
124         painter.moveOffset(position());
125                 /* walk all childs */
126         for (ePtrList<eWidget>::iterator i(m_childs.begin()); i != m_childs.end(); ++i)
127                 i->doPaint(painter, region);
128         
129                 /* check if there's anything for us to paint */
130         region &= m_visible_region;
131         
132         painter.resetClip(region);
133         event(evtPaint, &region, &painter);
134         
135         painter.moveOffset(-position());
136 }
137
138 int eWidget::event(int event, void *data, void *data2)
139 {
140         switch (event)
141         {
142         case evtPaint:
143         {
144                 static int counter = 0x18;
145                 gPainter &painter = *(gPainter*)data2;
146 //              eDebug("eWidget::evtPaint %d", counter);
147 //              dumpRegion(*(gRegion*)data);
148                 painter.setBackgroundColor(gColor(++counter));
149                 painter.clear();
150                 break;
151         }
152         case evtKey:
153                 break;
154         case evtWillChangeSize:
155                 m_size = *static_cast<eSize*>(data);
156                 break;
157         case evtChangedSize:
158         {
159                 m_clip_region = gRegion(eRect(ePoint(0, 0),  m_size));
160                 break;
161         }
162         default:
163                 return -1;
164         }
165         return 0;
166 }
167