- sdl is now default output
[enigma2.git] / lib / gui / ewidgetdesktop.cpp
1 #include <lib/gui/ewidgetdesktop.h>
2 #include <lib/gui/ewidget.h>
3 #include <lib/base/ebase.h>
4
5 void eWidgetDesktop::addRootWidget(eWidget *root, int top)
6 {
7         assert(!root->m_desktop);
8         if (!top)
9                 m_root.push_back(root);
10         else
11                 m_root.push_front(root);
12         root->m_desktop = this;
13 }
14
15 void eWidgetDesktop::removeRootWidget(eWidget *root)
16 {
17         m_root.remove(root);
18 }
19
20 void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible)
21 {
22                 /* start with our clip region, clipped with the parent's */
23         if (widget->m_vis & eWidget::wVisShow)
24         {
25                 widget->m_visible_region = widget->m_clip_region;
26                 widget->m_visible_region.moveBy(widget->position());
27                 widget->m_visible_region &= parent_visible; // in parent space!
28                         /* TODO: check transparency here! */
29                         /* remove everything this widget will contain from parent's visible list */
30                 parent_visible -= widget->m_visible_region; // will remove child regions too!
31
32                         /* now prepare for recursing to childs */
33                 widget->m_visible_region.moveBy(-widget->position());            // now in local space
34         } else
35                 widget->m_visible_region = gRegion();
36
37         widget->m_visible_with_childs = widget->m_visible_region;
38         
39         for (ePtrList<eWidget>::iterator i(widget->m_childs.begin()); i != widget->m_childs.end(); ++i)
40                 calcWidgetClipRegion(*i, widget->m_visible_region);
41 }
42
43 void eWidgetDesktop::recalcClipRegions()
44 {
45         m_background_region = gRegion(eRect(ePoint(0, 0), m_screen_size));
46         
47         for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
48                 calcWidgetClipRegion(*i, m_background_region);
49 }
50
51 void eWidgetDesktop::invalidate(const gRegion &region)
52 {
53         if (m_timer && m_dirty_region.empty())
54                 m_timer->start(0, 1); // start singleshot redraw timer
55         m_dirty_region |= region;
56 }
57
58 void eWidgetDesktop::setBackgroundColor(gColor col)
59 {
60         m_background_color = col;
61         
62                 /* if there's something visible from the background, redraw it with the new color. */
63         if (m_dc && m_background_region.valid() && !m_background_region.empty())
64         {
65                         /* todo: split out "setBackgroundColor / clear"... maybe? */
66                 gPainter painter(m_dc);
67                 painter.resetClip(m_background_region);
68                 painter.setBackgroundColor(m_background_color);
69                 painter.clear();
70         }
71 }
72
73 void eWidgetDesktop::paint()
74 {
75         gPainter painter(m_dc);
76                 /* walk all root windows. */
77         for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
78                 i->doPaint(painter, m_dirty_region);
79         m_dirty_region &= m_background_region;
80         
81         painter.resetClip(m_dirty_region);
82         painter.setBackgroundColor(m_background_color);
83         painter.clear();
84         
85         painter.flush();
86         
87         m_dirty_region = gRegion();
88 }
89
90 void eWidgetDesktop::setDC(gDC *dc)
91 {
92         m_dc = dc;
93 }
94
95 void eWidgetDesktop::setRedrawTask(eMainloop &ml)
96 {
97         if (m_mainloop)
98         {
99                 delete m_timer;
100                 m_timer = 0;
101                 m_mainloop = 0;
102         }
103         m_mainloop = &ml;
104         m_timer = new eTimer(m_mainloop);
105         CONNECT(m_timer->timeout, eWidgetDesktop::paint);
106         
107         if (!m_dirty_region.empty())
108                 m_timer->start(0, 1);
109 }
110
111 void eWidgetDesktop::makeCompatiblePixmap(gPixmap &pm)
112 {
113         eDebug("widgetDesktop: make compatible pixmap of %p\n", &pm);
114         if (!m_dc)
115         {
116                 eWarning("eWidgetDesktop: no DC to make pixmap compatible with!");
117                 return;
118         }
119         eDebug("painter..");
120         gPainter painter(m_dc);
121         eDebug("merge!");
122         painter.mergePalette(&pm);
123         eDebug("gone!");
124 }
125
126 eWidgetDesktop::eWidgetDesktop(eSize size): m_screen_size(size), m_mainloop(0), m_timer(0)
127 {
128 }
129
130 eWidgetDesktop::~eWidgetDesktop()
131 {
132 }
133