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);
112 /* TODO: when hiding an upper level widget, widgets get hidden but keep the */
113 /* wVisShow flag (because when the widget is shown again, the widgets must */
114 /* become visible again. */
115 if (!(m_vis & wVisShow))
119 /* this is a workaround to the above problem. when we are in the delete phase,
120 don't hide childs. */
121 if (!(m_parent || m_desktop))
124 /* TODO: optimize here to only recalc what's required. possibly merge with show. */
125 eWidget *root = this;
126 ePoint abspos = position();
127 while (root && !root->m_desktop)
129 root = root->m_parent;
130 abspos += root->position();
132 assert(root->m_desktop);
134 gRegion abs = m_visible_with_childs;
137 root->m_desktop->recalcClipRegions();
138 root->m_desktop->invalidate(abs);
141 void eWidget::destruct()
144 m_parent->m_childs.remove(this);
153 m_parent->m_childs.remove(this);
157 /* destroy all childs */
158 ePtrList<eWidget>::iterator i(m_childs.begin());
159 while (i != m_childs.end())
163 i = m_childs.erase(i);
167 void eWidget::doPaint(gPainter &painter, const gRegion &r)
169 if (m_visible_with_childs.empty())
173 /* we were in parent's space, now we are in local space */
174 region.moveBy(-position());
176 painter.moveOffset(position());
177 /* walk all childs */
178 for (ePtrList<eWidget>::iterator i(m_childs.begin()); i != m_childs.end(); ++i)
179 i->doPaint(painter, region);
181 /* check if there's anything for us to paint */
182 region &= m_visible_region;
186 painter.resetClip(region);
187 event(evtPaint, ®ion, &painter);
190 painter.moveOffset(-position());
193 void eWidget::recalcClipRegionsWhenVisible()
198 if (!(t->m_vis & wVisShow))
202 t->m_desktop->recalcClipRegions();
210 int eWidget::event(int event, void *data, void *data2)
216 gPainter &painter = *(gPainter*)data2;
218 // eDebug("eWidget::evtPaint");
219 // dumpRegion(*(gRegion*)data);
220 ePtr<eWindowStyle> style;
221 if (!getStyle(style))
222 style->paintBackground(painter, ePoint(0, 0), size());
227 case evtWillChangeSize:
228 m_size = *static_cast<eSize*>(data);
232 m_clip_region = gRegion(eRect(ePoint(0, 0), m_size));