From 87bfe5dfced0fb7a4e9839fdafa898261a39c86c Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Wed, 31 Aug 2005 03:05:27 +0000 Subject: [PATCH] - fix serious problems in widget code. fixup buffered mode. add animation support.lib/gui --- RecordTimer.py | 8 +- acinclude.m4 | 2 +- configure.ac | 7 +- debug | 3 +- debug.gdb | 4 +- keymapparser.py | 4 +- lib/driver/rc.cpp | 2 +- lib/driver/rcconsole.cpp | 8 +- lib/dvb/demux.cpp | 2 - lib/dvb/dvb.cpp | 3 +- lib/dvb/frontend.cpp | 32 +++---- lib/dvb/sec.cpp | 2 +- lib/dvb/specs.h | 4 +- lib/gui/Makefile.am | 6 +- lib/gui/ewidget.cpp | 27 +++--- lib/gui/ewidget.h | 2 + lib/gui/ewidgetanimation.cpp | 46 ++++++++++ lib/gui/ewidgetanimation.h | 25 ++++++ lib/gui/ewidgetdesktop.cpp | 153 ++++++++++++++++++++++++++++------ lib/gui/ewidgetdesktop.h | 14 +++- lib/python/Screens/InfoBar.py | 19 ++++- lib/python/enigma_python.i | 2 + main/enigma.cpp | 6 +- 23 files changed, 288 insertions(+), 93 deletions(-) create mode 100644 lib/gui/ewidgetanimation.cpp create mode 100644 lib/gui/ewidgetanimation.h diff --git a/RecordTimer.py b/RecordTimer.py index 37208ddc..286d523b 100644 --- a/RecordTimer.py +++ b/RecordTimer.py @@ -67,10 +67,10 @@ class RecordTimer(Timer): self.Filename = "timers.xml" -# try: - self.loadTimer() -# except: -# print "unable to load timers from file!" + try: + self.loadTimer() + except: + print "unable to load timers from file!" def loadTimer(self): diff --git a/acinclude.m4 b/acinclude.m4 index b92d02fa..0dcafdec 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -125,7 +125,7 @@ TUXBOX_APPS_DIRECTORY_ONE(fontdir,FONTDIR,datadir,/share,/fonts, TUXBOX_APPS_DIRECTORY_ONE(gamesdir,GAMESDIR,localstatedir,/var,/tuxbox/games, [--with-gamesdir=PATH ],[where games data is stored]) -TUXBOX_APPS_DIRECTORY_ONE(libdir,LIBDIR,libdir,/lib,/tuxbox, +TUXBOX_APPS_DIRECTORY_ONE(libdir,LIBDIR,libdir,/lib,, [--with-libdir=PATH ],[where to find the internal libs]) TUXBOX_APPS_DIRECTORY_ONE(plugindir,PLUGINDIR,libdir,/lib,/tuxbox/plugins, diff --git a/configure.ac b/configure.ac index eacbf2d9..a4ff2b1d 100644 --- a/configure.ac +++ b/configure.ac @@ -10,13 +10,13 @@ AC_PROG_RANLIB AC_ARG_WITH(pythonincdir, [ --with-pythonincdir=NAME dir [[...]]], - [PYTHON_INCDIR="$withval"],[PYTHON_INCDIR="/usr/include/python2.4"]) + [PYTHON_INCDIR="$withval"],[PYTHON_INCDIR="/home/dump/tmb/oe-mono/build/tmp/staging/mipsel-linux/include/python2.4/"]) AC_SUBST(PYTHON_INCDIR) AC_ARG_WITH(libsdl, AC_HELP_STRING([--with-libsdl], [use sdl, yes or no]), [[withsdl=$withval]], - [[withsdl=yes]] + [[withsdl=no]] ) TUXBOX_APPS_DVB @@ -30,6 +30,7 @@ TUXBOX_APPS_LIB_PKGCONFIG(MAD,mad) TUXBOX_APPS_LIB_PKGCONFIG(PNG,libpng) TUXBOX_APPS_LIB_PKGCONFIG(SIGC,sigc++-1.2) #TUXBOX_APPS_LIB_PKGCONFIG(XMLTREE,tuxbox-xmltree) + if test "$withsdl" = "yes" ; then TUXBOX_APPS_LIB_CONFIG(SDL,sdl-config) AC_DEFINE_UNQUOTED([WITH_SDL],[$withsdl],[With SDL]) @@ -37,7 +38,7 @@ fi # fixme: decent python stuff CPPFLAGS="$CPPFLAGS $MD5SUM_CFLAGS $FREETYPE_CFLAGS $FRIBIDI_CFLAGS $ID3TAG_CFLAGS $MAD_CFLAGS $PLUGINS_CFLAGS $PNG_CFLAGS $SIGC_CFLAGS $XMLTREE_CFLAGS -I$PYTHON_INCDIR -DHAVE_CPP_FILT -DMEMLEAK_CHECK" -CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions -Wall" +CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions -Wall -g" LDFLAGS="$LDFLAGS -rdynamic" TUXBOX_APPS_GETTEXT diff --git a/debug b/debug index d9b87717..d247b3ea 100755 --- a/debug +++ b/debug @@ -1,5 +1,4 @@ #!/bin/sh -powerpc-linux-gdb /dbox2/cdkroot/bin/enigma2 -x debug.gdb - +/home/dump/tmb/oe-mono/build/tmp/work/gdb-cross-6.3-r0/install/gdb-cross/usr/local/mipsel/oe/bin/mipsel-linux-gdb main/enigma2 -x debug.gdb diff --git a/debug.gdb b/debug.gdb index f2b4fca4..69cf5d04 100644 --- a/debug.gdb +++ b/debug.gdb @@ -1,3 +1,3 @@ -set solib-absolute-prefix /dbox2/cdkroot -target remote 10.0.0.82:1234 +set solib-absolute-prefix /home/tmbinc/mips/target +target remote 10.0.0.203:1234 continue diff --git a/keymapparser.py b/keymapparser.py index 11c8530a..7b64ae04 100644 --- a/keymapparser.py +++ b/keymapparser.py @@ -44,7 +44,7 @@ def readKeymap(): # try: flags = sum(map(flag_ascii_to_id, flags)) - print "-> " + str(flags) +# print "-> " + str(flags) # except: # raise str("%s: illegal flags '%s' specificed in context %s, id '%s'" % (filename, flags, context, id)) @@ -67,7 +67,7 @@ def readKeymap(): except: raise "key id '" + str(id) + "' is illegal" - print context + "::" + mapto + " -> " + device + "." + hex(keyid) +# print context + "::" + mapto + " -> " + device + "." + hex(keyid) p.bindKey(device, keyid, flags, context, mapto) parseKeys("generic", cmap) diff --git a/lib/driver/rc.cpp b/lib/driver/rc.cpp index ca0d62bc..d4664896 100644 --- a/lib/driver/rc.cpp +++ b/lib/driver/rc.cpp @@ -177,7 +177,7 @@ eRCInput::eRCInput() instance=this; handle = -1; locked = 0; - keyboardMode = kmNone; + keyboardMode = kmAll; } eRCInput::~eRCInput() diff --git a/lib/driver/rcconsole.cpp b/lib/driver/rcconsole.cpp index eae3a7a5..eaeeb586 100644 --- a/lib/driver/rcconsole.cpp +++ b/lib/driver/rcconsole.cpp @@ -42,12 +42,9 @@ void eRCConsoleDriver::keyPressed(int) char *d = data; int num = read(handle, data, 16); int code; - + int km = input->getKeyboardMode(); - if (km == eRCInput::kmNone) - return; - while (num--) { if (km == eRCInput::kmAll) @@ -78,7 +75,10 @@ void eRCConsoleDriver::keyPressed(int) if (code != -1) for (std::list::iterator i(listeners.begin()); i!=listeners.end(); ++i) + { + eDebug("ascii %08x", code); (*i)->handleCode(code | 0x8000); + } } } diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index 3e05065b..5a143c5e 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -83,10 +83,8 @@ RESULT eDVBDemux::getSTC(pts_t &pts) } pts = stc.stc; - eDebug("got demux stc: %08llx", pts); ::close(fd); - return 0; } diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 3e4c7bdc..90df7267 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -571,8 +571,7 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos) return -1; } - eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos); - +// eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos); /* when we are less than 10 seconds before the start, return 0. */ /* (we're just waiting for the timespam to start) */ if ((now < pos) && ((pos - now) < 90000 * 10)) diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 54c545ee..d4704a9d 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -428,18 +428,18 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer { case eSecCommand::SLEEP: delay = m_sec_sequence.current()++->msec; - eDebug("sleep %dms", delay); + eDebug("[SEC] sleep %dms", delay); break; case eSecCommand::GOTO: if ( !setSecSequencePos(m_sec_sequence.current()->steps) ) ++m_sec_sequence.current(); break; case eSecCommand::SET_VOLTAGE: - eDebug("setVoltage %d", m_sec_sequence.current()->voltage); + eDebug("[SEC] setVoltage %d", m_sec_sequence.current()->voltage); setVoltage(m_sec_sequence.current()++->voltage); break; case eSecCommand::SET_TONE: - eDebug("setTone %d", m_sec_sequence.current()->tone); + eDebug("[SEC] setTone %d", m_sec_sequence.current()->tone); setTone(m_sec_sequence.current()++->tone); break; case eSecCommand::SEND_DISEQC: @@ -447,36 +447,36 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer eDebugNoNewLine("sendDiseqc: "); for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i) eDebugNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]); - eDebug(""); + eDebug("[SEC] "); ++m_sec_sequence.current(); break; case eSecCommand::SEND_TONEBURST: - eDebug("sendToneburst: %d", m_sec_sequence.current()->toneburst); + eDebug("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst); sendToneburst(m_sec_sequence.current()++->toneburst); break; case eSecCommand::SET_FRONTEND: - eDebug("setFrontend"); + eDebug("[SEC] setFrontend"); setFrontend(); ++m_sec_sequence.current(); break; case eSecCommand::MEASURE_IDLE_INPUTPOWER: m_idleInputpower = readInputpower(); - eDebug("idleInputpower is %d", m_idleInputpower); + eDebug("[SEC] idleInputpower is %d", m_idleInputpower); ++m_sec_sequence.current(); break; case eSecCommand::MEASURE_RUNNING_INPUTPOWER: m_runningInputpower = readInputpower(); - eDebug("runningInputpower is %d", m_runningInputpower); + eDebug("[SEC] runningInputpower is %d", m_runningInputpower); ++m_sec_sequence.current(); break; case eSecCommand::SET_TIMEOUT: m_timeoutCount = m_sec_sequence.current()++->val; - eDebug("set timeout %d", m_timeoutCount); + eDebug("[SEC] set timeout %d", m_timeoutCount); break; case eSecCommand::UPDATE_CURRENT_ROTORPARAMS: m_data[5] = m_data[3]; m_data[6] = m_data[4]; - eDebug("update current rotorparams %d %04x %d", m_timeoutCount, m_data[5], m_data[6]); + eDebug("[SEC] update current rotorparams %d %04x %d", m_timeoutCount, m_data[5], m_data[6]); ++m_sec_sequence.current(); break; case eSecCommand::IF_TIMEOUT_GOTO: @@ -489,8 +489,8 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer { eSecCommand::rotor &cmd = m_sec_sequence.current()->measure; const char *txt = cmd.direction ? "running" : "stopped"; - eDebug("waiting for rotor %s", txt); - eDebug("%s %d, idle %d, delta %d", + eDebug("[SEC] waiting for rotor %s", txt); + eDebug("[SEC] %s %d, idle %d, delta %d", txt, m_runningInputpower, m_idleInputpower, @@ -499,17 +499,17 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer || (!cmd.direction && abs(m_runningInputpower - m_idleInputpower) <= cmd.deltaA) ) { ++cmd.okcount; - eDebug("rotor %s step %d ok", txt, cmd.okcount); + eDebug("[SEC] rotor %s step %d ok", txt, cmd.okcount); if ( cmd.okcount > 1 ) { - eDebug("rotor is %s", txt); + eDebug("[SEC] rotor is %s", txt); if (setSecSequencePos(cmd.steps)) break; } } else { - eDebug("rotor not %s... reset counter.. increase timeout", txt); + eDebug("[SEC] rotor not %s... reset counter.. increase timeout", txt); --m_timeoutCount; cmd.okcount=0; } @@ -518,7 +518,7 @@ void eDVBFrontend::tuneLoop() // called by m_tuneTimer } default: ++m_sec_sequence.current(); - eDebug("unhandled sec command"); + eDebug("[SEC] unhandled sec command"); } m_tuneTimer->start(delay,true); } diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp index be022a16..3d0bb90b 100644 --- a/lib/dvb/sec.cpp +++ b/lib/dvb/sec.cpp @@ -36,7 +36,7 @@ eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl() diseqc_ref.m_swap_cmds = false; diseqc_ref.m_toneburst_param = eDVBSatelliteDiseqcParameters::NO; diseqc_ref.m_uncommitted_cmd = 0; - diseqc_ref.m_use_fast = 1; + diseqc_ref.m_use_fast = 0; switch_ref.m_22khz_signal = eDVBSatelliteSwitchParameters::HILO; switch_ref.m_voltage_mode = eDVBSatelliteSwitchParameters::HV; diff --git a/lib/dvb/specs.h b/lib/dvb/specs.h index 5c26bfad..2e2eed9b 100644 --- a/lib/dvb/specs.h +++ b/lib/dvb/specs.h @@ -19,7 +19,7 @@ public: m_spec.pid = pid; m_spec.tid = ProgramMapTable::TID; m_spec.tidext = sid; - m_spec.timeout = ProgramMapTable::TIMEOUT; + m_spec.timeout = 20000; // ProgramMapTable::TIMEOUT; m_spec.flags = eDVBTableSpec::tfAnyVersion | eDVBTableSpec::tfHaveTID | eDVBTableSpec::tfHaveTIDExt | eDVBTableSpec::tfCheckCRC | eDVBTableSpec::tfHaveTimeout; @@ -95,7 +95,7 @@ public: { m_spec.pid = ProgramAssociationTable::PID; m_spec.tid = ProgramAssociationTable::TID; - m_spec.timeout = ProgramAssociationTable::TIMEOUT; + m_spec.timeout = 20000; // ProgramAssociationTable::TIMEOUT; m_spec.flags = eDVBTableSpec::tfAnyVersion | eDVBTableSpec::tfHaveTID | eDVBTableSpec::tfCheckCRC | eDVBTableSpec::tfHaveTimeout; diff --git a/lib/gui/Makefile.am b/lib/gui/Makefile.am index 951cc4f5..55a7e534 100644 --- a/lib/gui/Makefile.am +++ b/lib/gui/Makefile.am @@ -7,7 +7,5 @@ noinst_LIBRARIES = libenigma_gui.a libenigma_gui_a_SOURCES = \ ebutton.cpp elabel.cpp eslider.cpp ewidget.cpp ewidgetdesktop.cpp \ ewindow.cpp ewindowstyle.cpp elistbox.cpp elistboxcontent.cpp \ - epixmap.cpp ewindowstyleskinned.cpp einput.cpp einputstring.cpp einputnumber.cpp - - - + epixmap.cpp ewindowstyleskinned.cpp einput.cpp einputstring.cpp einputnumber.cpp \ + ewidgetanimation.cpp diff --git a/lib/gui/ewidget.cpp b/lib/gui/ewidget.cpp index 474e295d..8cb7d4ae 100644 --- a/lib/gui/ewidget.cpp +++ b/lib/gui/ewidget.cpp @@ -3,7 +3,7 @@ extern void dumpRegion(const gRegion ®ion); -eWidget::eWidget(eWidget *parent): m_parent(parent ? parent->child() : 0) +eWidget::eWidget(eWidget *parent): m_animation(this), m_parent(parent ? parent->child() : 0) { m_vis = 0; m_desktop = 0; @@ -13,7 +13,7 @@ eWidget::eWidget(eWidget *parent): m_parent(parent ? parent->child() : 0) if (m_parent) m_vis = wVisShow; - + if (m_parent) { m_parent->m_childs.push_back(this); @@ -26,20 +26,19 @@ eWidget::eWidget(eWidget *parent): m_parent(parent ? parent->child() : 0) void eWidget::move(ePoint pos) { - m_position = pos + m_client_offset; + pos = pos + m_client_offset; if (m_position == pos) return; + + m_position = pos; - /* we invalidate before and after the move to - cause a correct redraw. The area which is - included both before and after isn't redrawn - twice because a invalidate doesn't immediately - redraws the region. */ - invalidate(); event(evtChangedPosition); - recalcClipRegionsWhenVisible(); - invalidate(); + recalcClipRegionsWhenVisible(); + + /* try native move if supported. */ + if ((m_vis & wVisShow) && ((!m_desktop) || m_desktop->movedWidget(this))) + invalidate(); } void eWidget::resize(eSize size) @@ -110,7 +109,7 @@ void eWidget::show() abspos += root->position(); } - root->m_desktop->recalcClipRegions(); + root->m_desktop->recalcClipRegions(root); gRegion abs = m_visible_with_childs; abs.moveBy(abspos); @@ -144,7 +143,7 @@ void eWidget::hide() gRegion abs = m_visible_with_childs; abs.moveBy(abspos); - root->m_desktop->recalcClipRegions(); + root->m_desktop->recalcClipRegions(root); root->m_desktop->invalidate(abs); } @@ -228,7 +227,7 @@ void eWidget::recalcClipRegionsWhenVisible() break; if (t->m_desktop) { - t->m_desktop->recalcClipRegions(); + t->m_desktop->recalcClipRegions(t); break; } t = t->m_parent; diff --git a/lib/gui/ewidget.h b/lib/gui/ewidget.h index 8bd199f9..5cb139c5 100644 --- a/lib/gui/ewidget.h +++ b/lib/gui/ewidget.h @@ -4,6 +4,7 @@ #include /* for gRegion */ #include /* for eSmartPtrList */ #include /* for eWindowStyle */ +#include class eWidgetDesktop;class eWidgetDesktop; @@ -42,6 +43,7 @@ public: int isVisible() { return (m_vis & wVisShow) && ((!m_parent) || m_parent->isVisible()); } /* ... */ + eWidgetAnimation m_animation; private: eWidgetDesktop *m_desktop; diff --git a/lib/gui/ewidgetanimation.cpp b/lib/gui/ewidgetanimation.cpp new file mode 100644 index 00000000..3912d592 --- /dev/null +++ b/lib/gui/ewidgetanimation.cpp @@ -0,0 +1,46 @@ +#include +#include + +eWidgetAnimation::eWidgetAnimation(eWidget *widget): m_widget(widget) +{ + m_active = 0; +} + +void eWidgetAnimation::tick(int inc) +{ + if (!m_active) + return; + + // move animation + if (m_move_length) + { + if (m_move_current_tick >= m_move_length) + { + m_active = 0; + m_move_current_tick = m_move_length; + } + int xdiff = m_move_end.x() - m_move_start.x(); + int ydiff = m_move_end.y() - m_move_start.y(); + + xdiff *= m_move_current_tick; + xdiff /= m_move_length; + + ydiff *= m_move_current_tick; + ydiff /= m_move_length; + + ePoint res(m_move_start.x() + xdiff, m_move_start.y() + ydiff); + + m_move_current_tick += inc; + + m_widget->move(res); + } +} + +void eWidgetAnimation::startMoveAnimation(ePoint start, ePoint end, int length) +{ + m_move_current_tick = 0; + m_move_length = length; + m_move_start = start; + m_move_end = end; + m_active = 1; +} diff --git a/lib/gui/ewidgetanimation.h b/lib/gui/ewidgetanimation.h new file mode 100644 index 00000000..61d79e6d --- /dev/null +++ b/lib/gui/ewidgetanimation.h @@ -0,0 +1,25 @@ +#ifndef __lib_gui_ewidgetanimation_h +#define __lib_gui_ewidgetanimation_h + +#include +#include + +class eWidget; + +class eWidgetAnimation +{ +public: + eWidgetAnimation(eWidget *widget); + + void tick(int inc); + + void startMoveAnimation(ePoint start, ePoint end, int length); + + int m_active; +private: + int m_move_current_tick, m_move_length; + ePoint m_move_start, m_move_end; + eWidget *m_widget; +}; + +#endif diff --git a/lib/gui/ewidgetdesktop.cpp b/lib/gui/ewidgetdesktop.cpp index d4a02010..1c65d5d2 100644 --- a/lib/gui/ewidgetdesktop.cpp +++ b/lib/gui/ewidgetdesktop.cpp @@ -1,11 +1,19 @@ #include #include #include +#include + +extern void dumpRegion(const gRegion ®ion); void eWidgetDesktop::addRootWidget(eWidget *root, int top) { assert(!root->m_desktop); - if (!top) + + /* buffered mode paints back-to-front, while immediate mode is front-to-back. */ + if (m_comp_mode == cmBuffered) + top = !top; + + if (top) m_root.push_back(root); else m_root.push_front(root); @@ -23,13 +31,25 @@ void eWidgetDesktop::removeRootWidget(eWidget *root) m_root.remove(root); } -void eWidgetDesktop::calcWidgetClipRegion(struct eWidgetDesktopCompBuffer *comp, eWidget *widget, gRegion &parent_visible) +int eWidgetDesktop::movedWidget(eWidget *root) +{ + if ((m_comp_mode == cmBuffered) && (root->m_comp_buffer)) + { + root->m_comp_buffer->m_position = root->position(); + redrawComposition(0); + return 0; + } + + return -1; +} + +void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible) { /* start with our clip region, clipped with the parent's */ if (widget->m_vis & eWidget::wVisShow) { widget->m_visible_region = widget->m_clip_region; - widget->m_visible_region.moveBy(widget->position() - comp->m_position); + widget->m_visible_region.moveBy(widget->position()); widget->m_visible_region &= parent_visible; // in parent space! /* TODO: check transparency here! */ @@ -38,42 +58,71 @@ void eWidgetDesktop::calcWidgetClipRegion(struct eWidgetDesktopCompBuffer *comp, /* now prepare for recursing to childs */ widget->m_visible_region.moveBy(-widget->position()); // now in local space - } else widget->m_visible_region = gRegion(); widget->m_visible_with_childs = widget->m_visible_region; for (ePtrList::iterator i(widget->m_childs.begin()); i != widget->m_childs.end(); ++i) - calcWidgetClipRegion(comp, *i, widget->m_visible_region); + if (i->m_vis & eWidget::wVisShow) + calcWidgetClipRegion(*i, widget->m_visible_region); } -void eWidgetDesktop::recalcClipRegions() +void eWidgetDesktop::recalcClipRegions(eWidget *root) { if (m_comp_mode == cmImmediate) - m_screen.m_background_region = gRegion(eRect(ePoint(0, 0), m_screen.m_screen_size)); - - for (ePtrList::iterator i(m_root.begin()); i != m_root.end(); ++i) { - eWidgetDesktopCompBuffer *comp = (m_comp_mode == cmImmediate) ? &m_screen : i->m_comp_buffer; + gRegion background_before = m_screen.m_background_region; - if (m_comp_mode != cmImmediate) + m_screen.m_background_region = gRegion(eRect(ePoint(0, 0), m_screen.m_screen_size)); + + for (ePtrList::iterator i(m_root.begin()); i != m_root.end(); ++i) { - if (!comp) - { - createBufferForWidget(*i); - comp = i->m_comp_buffer; - } - - comp->m_background_region = gRegion(eRect(ePoint(0, 0), comp->m_screen_size)); + if (!(i->m_vis & eWidget::wVisShow)) + continue; + + gRegion visible_before = i->m_visible_with_childs; + + calcWidgetClipRegion(*i, m_screen.m_background_region); + + gRegion redraw = (i->m_visible_with_childs - visible_before) | (visible_before - i->m_visible_with_childs); + + redraw.moveBy(i->position()); + + invalidate(redraw); } - calcWidgetClipRegion(comp, *i, comp->m_background_region); + gRegion redraw = (background_before - m_screen.m_background_region) | (m_screen.m_background_region - background_before); + invalidate(redraw); + } else + { + if ((!root->m_comp_buffer) || (root->size() != root->m_comp_buffer->m_screen_size)) + createBufferForWidget(root); + + eWidgetDesktopCompBuffer *comp = root->m_comp_buffer; + + gRegion visible_before = root->m_visible_with_childs; + + comp->m_background_region = gRegion(eRect(comp->m_position, comp->m_screen_size)); + + gRegion visible_new = root->m_visible_with_childs - visible_before; + gRegion visible_lost = visible_before - root->m_visible_with_childs; + visible_new.moveBy(root->position()); + visible_lost.moveBy(root->position()); + + /* this sucks, obviously. */ + invalidate(visible_new); + invalidate(visible_lost); + + calcWidgetClipRegion(root, comp->m_background_region); } } void eWidgetDesktop::invalidate(const gRegion ®ion) { + if (region.empty()) + return; + if (m_timer && !m_require_redraw) m_timer->start(0, 1); // start singleshot redraw timer @@ -84,10 +133,12 @@ void eWidgetDesktop::invalidate(const gRegion ®ion) else for (ePtrList::iterator i(m_root.begin()); i != m_root.end(); ++i) { + if (!(i->m_vis & eWidget::wVisShow)) + continue; + eWidgetDesktopCompBuffer *comp = i->m_comp_buffer; gRegion mregion = region; - mregion.moveBy(-comp->m_position); comp->m_dirty_region |= mregion; } } @@ -118,7 +169,7 @@ void eWidgetDesktop::setBackgroundColor(gRGB col) void eWidgetDesktop::setPalette(gPixmap &pm) { - if (m_comp_mode == cmImmediate) +// if (m_comp_mode == cmImmediate) { ASSERT(m_screen.m_dc); gPainter painter(m_screen.m_dc); @@ -160,9 +211,14 @@ void eWidgetDesktop::paint() { eWidgetDesktopCompBuffer *comp = (m_comp_mode == cmImmediate) ? &m_screen : i->m_comp_buffer; + if (!(i->m_vis & eWidget::wVisShow)) + continue; + { gPainter painter(comp->m_dc); + painter.moveOffset(-comp->m_position); i->doPaint(painter, comp->m_dirty_region); + painter.resetOffset(); } if (m_comp_mode != cmImmediate) @@ -175,13 +231,15 @@ void eWidgetDesktop::paint() if (m_comp_mode == cmBuffered) { eDebug("redraw composition"); - redrawComposition(); + redrawComposition(0); } } void eWidgetDesktop::setDC(gDC *dc) { m_screen.m_dc = dc; + if (m_comp_mode == cmBuffered) + redrawComposition(1); } void eWidgetDesktop::setRedrawTask(eMainloop &ml) @@ -241,6 +299,7 @@ eWidgetDesktop::eWidgetDesktop(eSize size): m_mainloop(0), m_timer(0) m_screen.m_screen_size = size; m_require_redraw = 0; + CONNECT(gRC::getInstance()->notify, eWidgetDesktop::notify); setCompositionMode(cmImmediate); } @@ -256,12 +315,26 @@ void eWidgetDesktop::createBufferForWidget(eWidget *widget) eWidgetDesktopCompBuffer *comp = widget->m_comp_buffer = new eWidgetDesktopCompBuffer; - eRect bbox = widget->m_clip_region.extends; + eDebug("create buffer for widget, %d x %d\n", widget->size().width(), widget->size().height()); + + eRect bbox = eRect(widget->position(), widget->size()); comp->m_position = bbox.topLeft(); comp->m_dirty_region = gRegion(eRect(ePoint(0, 0), bbox.size())); comp->m_screen_size = bbox.size(); /* TODO: configurable bit depth. */ - comp->m_dc = new gDC(new gPixmap(comp->m_screen_size, 32)); + + /* clone palette. FIXME. */ + ePtr pm = new gPixmap(comp->m_screen_size, 32, 1), pm_screen; + pm->surface->clut.data = new gRGB[256]; + pm->surface->clut.colors = 256; + pm->surface->clut.start = 0; + + + m_screen.m_dc->getPixmap(pm_screen); + + memcpy(pm->surface->clut.data, pm_screen->surface->clut.data, 256 * sizeof(gRGB)); + + comp->m_dc = new gDC(pm); } void eWidgetDesktop::removeBufferForWidget(eWidget *widget) @@ -273,15 +346,41 @@ void eWidgetDesktop::removeBufferForWidget(eWidget *widget) } } -void eWidgetDesktop::redrawComposition() +void eWidgetDesktop::redrawComposition(int notified) { + if (m_comp_mode != cmBuffered) + return; + + assert(m_screen.m_dc); + gPainter p(m_screen.m_dc); - + p.resetClip(eRect(ePoint(0, 0), m_screen.m_screen_size)); + p.setBackgroundColor(m_screen.m_background_color); + p.clear(); + for (ePtrList::iterator i(m_root.begin()); i != m_root.end(); ++i) { + if (!i->isVisible()) + continue; ePtr pm; ASSERT(i->m_comp_buffer); i->m_comp_buffer->m_dc->getPixmap(pm); - p.blit(pm, i->m_comp_buffer->m_position, eRect(), gPixmap::blitAlphaTest); + p.blit(pm, i->m_comp_buffer->m_position, eRect(), gPixmap::blitAlphaBlend); } + + // flip activates on next vsync. + p.flip(); + p.waitVSync(); + + if (notified) + p.notify(); + + for (ePtrList::iterator i(m_root.begin()); i != m_root.end(); ++i) + if (i->m_animation.m_active) + i->m_animation.tick(1); +} + +void eWidgetDesktop::notify() +{ + redrawComposition(1); } diff --git a/lib/gui/ewidgetdesktop.h b/lib/gui/ewidgetdesktop.h index 58bff50a..117138bd 100644 --- a/lib/gui/ewidgetdesktop.h +++ b/lib/gui/ewidgetdesktop.h @@ -35,7 +35,14 @@ public: ~eWidgetDesktop(); void addRootWidget(eWidget *root, int top); void removeRootWidget(eWidget *root); - void recalcClipRegions(); + + /* try to move widget content. */ + /* returns -1 if there's no move support. */ + /* call this after recalcClipRegions for that widget. */ + /* you probably want to invalidate if -1 was returned. */ + int movedWidget(eWidget *root); + + void recalcClipRegions(eWidget *root); void invalidate(const gRegion ®ion); void paint(); @@ -58,7 +65,7 @@ public: void setCompositionMode(int mode); private: ePtrList m_root; - void calcWidgetClipRegion(eWidgetDesktopCompBuffer *comp, eWidget *widget, gRegion &parent_visible); + void calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible); void paintBackground(eWidgetDesktopCompBuffer *comp); eMainloop *m_mainloop; @@ -72,7 +79,8 @@ private: void createBufferForWidget(eWidget *widget); void removeBufferForWidget(eWidget *widget); - void redrawComposition(); + void redrawComposition(int notifed); + void notify(); }; #endif diff --git a/lib/python/Screens/InfoBar.py b/lib/python/Screens/InfoBar.py index 44484a51..da2509e2 100644 --- a/lib/python/Screens/InfoBar.py +++ b/lib/python/Screens/InfoBar.py @@ -19,6 +19,11 @@ import time from Menu import MainMenu, mdom class InfoBar(Screen): + STATE_HIDDEN = 0 + STATE_HIDING = 1 + STATE_SHOWING = 2 + STATE_SHOWN = 3 + def __init__(self, session): Screen.__init__(self, session) @@ -58,6 +63,8 @@ class InfoBar(Screen): self["Event_Next_Duration"] = EventInfo(self.session.nav, EventInfo.Next_Duration) self.recording = None + + self.pos = 0 def mainMenu(self): print "loading mainmenu XML..." @@ -78,9 +85,11 @@ class InfoBar(Screen): def toggleShow(self): if self.instance.isVisible(): - self.instance.hide() +# self.instance.hide() + self.startHide() else: - self.instance.show() +# self.instance.show() + self.startShow() def zapUp(self): self.servicelist.moveUp() @@ -97,6 +106,12 @@ class InfoBar(Screen): def volDown(self): eDVBVolumecontrol.getInstance().volumeDown() self.volumeBar.setValue(eDVBVolumecontrol.getInstance().getVolume()) + + def startShow(self): + self.instance.m_animation.startMoveAnimation(ePoint(0, 500), ePoint(0, 380), 100) + + def startHide(self): + self.instance.m_animation.startMoveAnimation(ePoint(0, 380), ePoint(0, 500), 100) def volMute(self): eDVBVolumecontrol.getInstance().volumeToggleMute() diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 01ba75b6..3e6c5db3 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -57,6 +57,7 @@ is usually caused by not marking PSignals as immutable. #include #include #include +#include #include #include #include @@ -119,6 +120,7 @@ extern PSignal1 &keyPressedSignal(); %include %include %include +%include %include %include %include diff --git a/main/enigma.cpp b/main/enigma.cpp index 3a728b8d..a798b727 100644 --- a/main/enigma.cpp +++ b/main/enigma.cpp @@ -52,6 +52,7 @@ void dumpRegion(const gRegion ®ion) fprintf(stderr, "extends: %d %d -> %d %d (%d rects)\n", region.extends.left(), region.extends.top(), region.extends.right(), region.extends.bottom(), region.rects.size()); +#if 0 for (int y=0; y m_pm; -- 2.30.2