1 #include <lib/gui/ewidget.h>
2 #include <lib/gui/ewidgetdesktop.h>
4 extern void dumpRegion(const gRegion ®ion);
6 eWidget::eWidget(eWidget *parent): m_parent(parent ? parent->child() : 0)
16 m_parent->m_childs.push_back(this);
17 m_parent->getStyle(m_style);
21 void eWidget::move(ePoint pos)
23 if (m_position == pos)
28 /* we invalidate before and after the move to
29 cause a correct redraw. The area which is
30 included both before and after isn't redrawn
31 twice because a invalidate doesn't immediately
32 redraws the region. */
34 event(evtChangedPosition);
35 recalcClipRegionsWhenVisible();
39 void eWidget::resize(eSize size)
41 /* same strategy as with move: we first check if
42 the size changed at all, and if it did, we
43 invalidate both the old and new area.
44 TODO: check if either the old or new area
45 fits into the other completely, and invalidate
47 eSize old_size = m_size;
48 event(evtWillChangeSize, &size);
49 if (old_size == m_size)
53 event(evtChangedSize);
54 recalcClipRegionsWhenVisible();
58 void eWidget::invalidate(const gRegion ®ion)
60 /* we determine the area to redraw, and re-position this
61 area to the absolute position, and then call the
62 desktop's invalidate() with that, which adds this
63 area into the dirty region. */
64 gRegion res = m_visible_with_childs;
72 ePoint abspos = position();
73 while (root && !root->m_desktop)
75 root = root->m_parent;
77 abspos += root->position();
81 // eDebug("region to invalidate:");
83 root->m_desktop->invalidate(res);
93 /* TODO: optimize here to only recalc what's required. possibly merge with hide. */
95 ePoint abspos = position();
96 while (root && !root->m_desktop)
98 root = root->m_parent;
100 abspos += root->position();
103 root->m_desktop->recalcClipRegions();
105 gRegion abs = m_visible_with_childs;
107 root->m_desktop->invalidate(abs);
114 /* TODO: optimize here to only recalc what's required. possibly merge with show. */
115 eWidget *root = this;
116 ePoint abspos = position();
117 while (root && !root->m_desktop)
119 root = root->m_parent;
120 abspos += root->position();
122 assert(root->m_desktop);
124 gRegion abs = m_visible_with_childs;
127 root->m_desktop->recalcClipRegions();
128 root->m_desktop->invalidate(abs);
131 void eWidget::destruct()
134 m_parent->m_childs.remove(this);
141 m_parent->m_childs.remove(this);
143 /* destroy all childs */
144 ePtrList<eWidget>::iterator i(m_childs.begin());
145 while (i != m_childs.end())
149 i = m_childs.erase(i);
153 void eWidget::doPaint(gPainter &painter, const gRegion &r)
155 if (m_visible_with_childs.empty())
159 /* we were in parent's space, now we are in local space */
160 region.moveBy(-position());
162 painter.moveOffset(position());
163 /* walk all childs */
164 for (ePtrList<eWidget>::iterator i(m_childs.begin()); i != m_childs.end(); ++i)
165 i->doPaint(painter, region);
167 /* check if there's anything for us to paint */
168 region &= m_visible_region;
172 painter.resetClip(region);
173 event(evtPaint, ®ion, &painter);
176 painter.moveOffset(-position());
179 void eWidget::recalcClipRegionsWhenVisible()
184 if (!(t->m_vis & wVisShow))
188 t->m_desktop->recalcClipRegions();
196 int eWidget::event(int event, void *data, void *data2)
202 gPainter &painter = *(gPainter*)data2;
204 // eDebug("eWidget::evtPaint");
205 // dumpRegion(*(gRegion*)data);
206 ePtr<eWindowStyle> style;
207 if (!getStyle(style))
208 style->paintBackground(painter, ePoint(0, 0), size());
213 case evtWillChangeSize:
214 m_size = *static_cast<eSize*>(data);
218 m_clip_region = gRegion(eRect(ePoint(0, 0), m_size));