fix partial clipping for eListboxPythonMultiContent
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 25 Sep 2007 14:03:46 +0000 (14:03 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 25 Sep 2007 14:03:46 +0000 (14:03 +0000)
lib/gui/elistbox.cpp
lib/gui/elistbox.h
lib/gui/elistboxcontent.cpp
lib/gui/elistboxcontent.h
lib/python/Plugins/Extensions/GraphMultiEPG/GraphMultiEpg.py

index b7b1e3ff595a6538e3d571f1a2bb3f532bebaf1e..c7a46baaef497e04ffe415129fd504d72fa6f7bc 100644 (file)
@@ -226,7 +226,6 @@ void eListbox::moveSelection(int dir)
    /* redraw the old and newly selected */
                gRegion inv = eRect(0, m_itemheight * (m_selected-m_top), size().width(), m_itemheight);
                inv |= eRect(0, m_itemheight * (oldsel-m_top), size().width(), m_itemheight);
-               
                invalidate(inv);
        }
 }
@@ -294,6 +293,11 @@ void eListbox::updateScrollBar()
        }
 }
 
+int eListbox::getEntryTop()
+{
+       return (m_selected - m_top) * m_itemheight;
+}
+
 int eListbox::event(int event, void *data, void *data2)
 {
        switch (event)
@@ -318,7 +322,7 @@ int eListbox::event(int event, void *data, void *data2)
                
                gRegion entryrect = eRect(0, 0, size().width(), m_itemheight);
                const gRegion &paint_region = *(gRegion*)data;
-               
+
                for (int y = 0, i = 0; i <= m_items_per_page; y += m_itemheight, ++i)
                {
                        gRegion entry_clip_rect = paint_region & entryrect;
@@ -495,6 +499,14 @@ void eListbox::setSelectionPicture(ePtr<gPixmap> &pm)
        m_style.m_selection = pm;
 }
 
+void eListbox::invalidate(const gRegion &region)
+{
+       gRegion tmp(region);
+       if (m_content)
+               m_content->updateClip(tmp);
+       eWidget::invalidate(tmp);
+}
+
 struct eListboxStyle *eListbox::getLocalStyle(void)
 {
                /* transparency is set directly in the widget */
index 1cadf74b75085d4c0b8537fbc9471f1c73b1fc21..20f23b5b9a5a66d0b68f5236890a26fd8e6a4f3e 100644 (file)
@@ -26,6 +26,7 @@ public:
 protected:
        iListboxContent();
        friend class eListbox;
+       virtual void updateClip(gRegion &){ };
        virtual void cursorHome()=0;
        virtual void cursorEnd()=0;
        virtual int cursorMove(int count=1)=0;
@@ -134,6 +135,8 @@ public:
                /* the complete list changed. you should not attemp to keep the current index. */
        void entryReset(bool cursorHome=true);
 
+       int getEntryTop();
+       void invalidate(const gRegion &region = gRegion::invalidRegion());
 protected:
        int event(int event, void *data=0, void *data2=0);
        void recalcSize();
index 5a2613f56160620af73ca86981c09de26c326f37..8c7a5005e17c13bbbb9d9aaba71be7bf1fec71aa 100644 (file)
@@ -445,7 +445,7 @@ int eListboxPythonConfigContent::currentCursorSelectable()
 RESULT SwigFromPython(ePtr<gPixmap> &res, PyObject *obj);
 
 eListboxPythonMultiContent::eListboxPythonMultiContent()
-       :m_temp_clip(gRegion::invalidRegion())
+       :m_clip(gRegion::invalidRegion()), m_old_clip(gRegion::invalidRegion())
 {
 }
 
@@ -457,42 +457,42 @@ eListboxPythonMultiContent::~eListboxPythonMultiContent()
 
 void eListboxPythonMultiContent::setSelectionClip(eRect &rect, bool update)
 {
-       if (update && m_selection_clip.valid())
-       {
-               m_temp_clip = m_selection_clip;
-               m_temp_clip |= rect;
-               m_selection_clip = rect;
-               if (m_listbox)
-                       m_listbox->entryChanged(m_cursor);
-       }
+       m_selection_clip = rect;
+       if (m_listbox)
+               rect.moveBy(ePoint(0, m_listbox->getEntryTop()));
+       if (m_clip.valid())
+               m_clip |= rect;
        else
-               m_selection_clip = rect;
+               m_clip = rect;
+       if (update && m_listbox)
+               m_listbox->entryChanged(m_cursor);
 }
 
 static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *local_style, ePyObject pforeColor, ePyObject pbackColor, ePyObject pbackColorSelected, int selected, gRegion &rc, eRect &sel_clip)
 {
-               /* if we have a local background color set, use that. */
-       if (local_style && local_style->m_background_color_set)
-               painter.setBackgroundColor(local_style->m_background_color);
-
        if (selected && sel_clip.valid())
        {
-               /* if we have no transparent background */
-               if (!local_style || !local_style->m_transparent_background)
+               bool clear=true;
+               painter.clip(rc-sel_clip);
+               if (pbackColor)
                {
-                       painter.clip(rc-sel_clip);
-                       if (pbackColor)
-                       {
-                               int color = PyInt_AsLong(pbackColor);
-                               painter.setBackgroundColor(gRGB(color));
-                       }/* if we have a local background color set, use that. */
-                       else if (local_style && local_style->m_background_color_set)
+                       int color = PyInt_AsLong(pbackColor);
+                       painter.setBackgroundColor(gRGB(color));
+               }
+               else if (local_style)
+               {
+                       // transparent background?
+                       if (local_style->m_transparent_background) 
+                               clear=false;
+                       // if we have a local background color set, use that. 
+                       else if (local_style->m_background_color_set)
                                painter.setBackgroundColor(local_style->m_background_color);
-                       else
-                               style.setStyle(painter, eWindowStyle::styleListboxNormal);
-                       painter.clear();
-                       painter.clippop();
                }
+               else
+                       style.setStyle(painter, eWindowStyle::styleListboxNormal);
+               if (clear)
+                       painter.clear();
+               painter.clippop();
                painter.clip(rc&sel_clip);
                style.setStyle(painter, eWindowStyle::styleListboxSelected);
                if (pbackColorSelected)
@@ -517,16 +517,22 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
                }
                else
                {
+                       bool clear=true;
                        style.setStyle(painter, eWindowStyle::styleListboxNormal);
                        if (pbackColor)
                        {
                                int color = PyInt_AsLong(pbackColor);
                                painter.setBackgroundColor(gRGB(color));
                        }/* if we have a local background color set, use that. */
-                       else if (local_style && local_style->m_background_color_set)
-                               painter.setBackgroundColor(local_style->m_background_color);
+                       else if (local_style)
+                       {
+                               if (local_style->m_transparent_background)
+                                       clear=false;
+                               else if (local_style->m_background_color_set)
+                                       painter.setBackgroundColor(local_style->m_background_color);
+                       }
                        /* if we have no transparent background */
-                       if (!local_style || !local_style->m_transparent_background)
+                       if (clear)
                                painter.clear();
                }
        }
@@ -547,13 +553,6 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
        if (sel_clip.valid())
                sel_clip.moveBy(offset);
 
-       if (m_temp_clip.valid())
-       {
-               m_temp_clip.moveBy(offset);
-               itemregion &= m_temp_clip;
-               m_temp_clip = eRect();
-       }
-
                /* get local listbox style, if present */
        if (m_listbox)
                local_style = m_listbox->getLocalStyle();
@@ -933,3 +932,22 @@ void eListboxPythonMultiContent::setItemHeight(int height)
        if (m_listbox)
                m_listbox->setItemHeight(height);
 }
+
+void eListboxPythonMultiContent::setList(ePyObject list)
+{
+       m_old_clip = m_clip = gRegion::invalidRegion();
+       eListboxPythonStringContent::setList(list);
+}
+
+void eListboxPythonMultiContent::updateClip(gRegion &clip)
+{
+       if (m_clip.valid())
+       {
+               clip &= m_clip;
+               if (m_old_clip.valid() && !(m_clip-m_old_clip).empty())
+                       m_clip -= m_old_clip;
+               m_old_clip = m_clip;
+       }
+       else
+               m_old_clip = m_clip = gRegion::invalidRegion();
+}
index d69beb759364b31dca9d492074c40df3027538ad..118ed3020c3c2164d2abe4ede7b6325d4dfabbf9 100644 (file)
@@ -64,19 +64,20 @@ class eListboxPythonMultiContent: public eListboxPythonStringContent
        ePyObject m_buildFunc;
        ePyObject m_selectableFunc;
        eRect m_selection_clip;
-       gRegion m_temp_clip;
+       gRegion m_clip, m_old_clip;
 public:
        eListboxPythonMultiContent();
        ~eListboxPythonMultiContent();
        enum { TYPE_TEXT, TYPE_PROGRESS, TYPE_PIXMAP, TYPE_PIXMAP_ALPHATEST };
        void paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected);
        int currentCursorSelectable();
-       
+       void setList(SWIG_PYOBJECT(ePyObject) list);
        void setFont(int fnt, gFont *fnt);
        void setBuildFunc(SWIG_PYOBJECT(ePyObject) func);
        void setSelectableFunc(SWIG_PYOBJECT(ePyObject) func);
        void setItemHeight(int height);
        void setSelectionClip(eRect &rect, bool update=false);
+       void updateClip(gRegion &);
 private:
        std::map<int, ePtr<gFont> > m_font;
 };
index e1481276c6bcc73679a11cbb261e424c29d6630e..648d4f1135c0f9e1496e8b43a5acf3dcbe0e72ab 100644 (file)
@@ -159,7 +159,7 @@ class EPGList(HTMLComponent, GUIComponent):
                xpos += w;
                w = width/10*8;
                self.event_rect = Rect(xpos, 0, w, height)
-               self.l.setSelectionClip(eRect(xpos, 0, w, height), False)
+               self.l.setSelectionClip(eRect(0,0,0,0), False)
 
        def calcEntryPosAndWidthHelper(self, stime, duration, start, end, width):
                xpos = (stime - start) * width / (end - start)