3a60a26ae99ea9bf845ec3043e6d0e4dfb1e938c
[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(gRGB 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::setPalette(gPixmap &pm)
74 {
75         ASSERT(m_dc);
76         gPainter painter(m_dc);
77         painter.setPalette(&pm);
78 }
79
80 void eWidgetDesktop::paint()
81 {
82         gPainter painter(m_dc);
83                 /* walk all root windows. */
84         for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i)
85                 i->doPaint(painter, m_dirty_region);
86         m_dirty_region &= m_background_region;
87         
88         painter.resetClip(m_dirty_region);
89         painter.setBackgroundColor(m_background_color);
90         painter.clear();
91         
92         painter.flush();
93         
94         m_dirty_region = gRegion();
95 }
96
97 void eWidgetDesktop::setDC(gDC *dc)
98 {
99         m_dc = dc;
100 }
101
102 void eWidgetDesktop::setRedrawTask(eMainloop &ml)
103 {
104         if (m_mainloop)
105         {
106                 delete m_timer;
107                 m_timer = 0;
108                 m_mainloop = 0;
109         }
110         m_mainloop = &ml;
111         m_timer = new eTimer(m_mainloop);
112         CONNECT(m_timer->timeout, eWidgetDesktop::paint);
113         
114         if (!m_dirty_region.empty())
115                 m_timer->start(0, 1);
116 }
117
118 void eWidgetDesktop::makeCompatiblePixmap(gPixmap &pm)
119 {
120         eDebug("widgetDesktop: make compatible pixmap of %p\n", &pm);
121         if (!m_dc)
122         {
123                 eWarning("eWidgetDesktop: no DC to make pixmap compatible with!");
124                 return;
125         }
126
127         ePtr<gDC> pixmap_dc = new gDC(&pm);
128         gPainter pixmap_painter(pixmap_dc);
129         
130         ePtr<gPixmap> target_pixmap;
131         m_dc->getPixmap(target_pixmap);
132         
133         assert(target_pixmap);
134         
135         pixmap_painter.mergePalette(target_pixmap);
136 }
137
138 eWidgetDesktop::eWidgetDesktop(eSize size): m_screen_size(size), m_mainloop(0), m_timer(0)
139 {
140         m_dirty_region = gRegion(eRect(ePoint(0, 0), m_screen_size));
141 }
142
143 eWidgetDesktop::~eWidgetDesktop()
144 {
145 }
146