Repository URL to install this package:
|
Version:
3.53-20211113 ▾
|
enigma2-plugin-extensions-xstreamity
/
usr
/
lib
/
enigma2
/
python
/
Components
/
Renderer
/
XStreamityRunningText.py
|
|---|
from __future__ import absolute_import
################################################################################
# RunningText.py - Running Text Renderer for Enigma2
# Version: 1.5 (04.04.2012 23:40)
# Copyright (C) 2010-2012 vlamo <vlamodev@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
################################################################################
################################################################################
# several changes made by Dr.Best <dr.best@dreambox-tools.info> (07-18-2013)
# - I got rid of eCanvas, instead I took a widget as a parent and scroll the label directly into the widget (this saves performance (about 30%))
# - new property: mShown --> this fixes the bug that this renderer keeps running in background when its not shown
# - this renderer can be used in OLED display with dmm oe2.0 images
# - due to changing to eWidget in combination with eLabel transparent flag is possible (still cpu killer!)
# - fixed left / right scrolling , fixed nowrap-mode
# take a look at the discussion: http://board.dreambox-tools.info/showthread.php?6050-Erweiterung-Running-Text-render
################################################################################
from enigma import eWidget, eLabel, eTimer, ePoint, eSize, gFont, \
RT_HALIGN_LEFT, RT_HALIGN_CENTER, RT_HALIGN_RIGHT, RT_HALIGN_BLOCK, \
RT_VALIGN_TOP, RT_VALIGN_CENTER, RT_VALIGN_BOTTOM, RT_WRAP
from Components.Renderer.Renderer import Renderer
from skin import parseColor, parseFont
# scroll type:
NONE = 0
RUNNING = 1
SWIMMING = 2
AUTO = 3
# direction:
LEFT = 0
RIGHT = 1
TOP = 2
BOTTOM = 3
# halign:
CENTER = 2
BLOCK = 3
class XStreamityRunningText(Renderer):
def __init__(self):
Renderer.__init__(self)
self.type = NONE
self.txfont = gFont("Regular", 14)
self.soffset = (0, 0)
self.txtflags = 0
self.txtext = ""
self.scroll_label = self.mTimer = self.mStartPoint = None
self.X = self.Y = self.W = self.H = self.mStartDelay = 0
self.mAlways = 1 # always move text
self.mStep = 1 # moving step: 1 pixel per 1 time
self.mStepTimeout = 50 # step timeout: 1 step per 50 milliseconds ( speed: 20 pixel per second )
self.direction = LEFT
self.mLoopTimeout = self.mOneShot = 0
self.mRepeat = 0
self.mPageDelay = self.mPageLength = 0
self.lineHeight = 0 # for text height auto correction on dmm-enigma2
self.mShown = 0
GUI_WIDGET = eWidget
def postWidgetCreate(self, instance):
for (attrib, value) in self.skinAttributes:
if attrib == "size":
x, y = value.split(',')
self.W, self.H = int(x), int(y)
self.instance.move(ePoint(0, 0))
self.instance.resize(eSize(self.W, self.H))
self.scroll_label = eLabel(instance)
self.mTimer = eTimer()
try:
self.mTimer.callback.append(self.movingLoop)
except:
try:
self.mTimer_conn = self.mTimer.timeout.connect(self.movingLoop)
except:
pass
def preWidgetRemove(self, instance):
self.mTimer.stop()
try:
self.mTimer.callback.remove(self.movingLoop)
except:
self.mTimer_conn = self.mTimer.timeout.disconnect(self.movingLoop)
self.mTimer = None
self.scroll_label = None
def applySkin(self, desktop, screen):
def retValue(val, limit, default, Min=False):
try:
if Min:
x = min(limit, int(val))
else:
x = max(limit, int(val))
except:
x = default
return x
def setWrapFlag(attrib, value):
if (attrib.lower() == "wrap" and value == "0") or \
(attrib.lower() == "nowrap" and value != "0"):
self.txtflags &= ~RT_WRAP
else:
self.txtflags |= RT_WRAP
self.halign = valign = eLabel.alignLeft
if self.skinAttributes:
attribs = []
for (attrib, value) in self.skinAttributes:
if attrib == "font":
self.txfont = parseFont(value, ((1, 1), (1, 1)))
elif attrib == "foregroundColor":
self.scroll_label.setForegroundColor(parseColor(value))
elif attrib in ("shadowColor", "borderColor"): # fake for openpli-enigma2
self.scroll_label.setShadowColor(parseColor(value))
elif attrib == "shadowOffset":
x, y = value.split(',')
self.soffset = (int(x), int(y))
self.scroll_label.setShadowOffset(ePoint(self.soffset))
elif attrib == "borderWidth": # fake for openpli-enigma2
self.soffset = (-int(value), -int(value))
elif attrib == "valign" and value in ("top", "center", "bottom"):
valign = {"top": eLabel. alignTop, "center": eLabel. alignCenter, "bottom": eLabel. alignBottom}[value]
self.txtflags |= {"top": RT_VALIGN_TOP, "center": RT_VALIGN_CENTER, "bottom": RT_VALIGN_BOTTOM}[value]
elif attrib == "halign" and value in ("left", "center", "right", "block"):
self.halign = {"left": eLabel.alignLeft, "center": eLabel.alignCenter, "right": eLabel.alignRight, "block": eLabel.alignBlock}[value]
self.txtflags |= {"left": RT_HALIGN_LEFT, "center": RT_HALIGN_CENTER, "right": RT_HALIGN_RIGHT, "block": RT_HALIGN_BLOCK}[value]
elif attrib == "noWrap":
setWrapFlag(attrib, value)
elif attrib == "options":
options = value.split(',')
for o in options:
if '=' in o:
opt, val = (x.strip() for x in o.split('=', 1))
else:
opt, val = o.strip(), ""
if opt == "":
continue
elif opt in ("wrap", "nowrap"):
setWrapFlag(opt, val)
elif opt == "movetype" and val in ("none", "running", "swimming"):
self.type = {"none": NONE, "running": RUNNING, "swimming": SWIMMING}[val]
elif opt == "direction" and val in ("left", "right", "top", "bottom"):
self.direction = {"left": LEFT, "right": RIGHT, "top": TOP, "bottom": BOTTOM}[val]
elif opt == "step" and val:
self.mStep = retValue(val, 1, self.mStep)
elif opt == "steptime" and val:
self.mStepTimeout = retValue(val, 25, self.mStepTimeout)
elif opt == "startdelay" and val:
self.mStartDelay = retValue(val, 0, self.mStartDelay)
elif opt == "pause" and val:
self.mLoopTimeout = retValue(val, 0, self.mLoopTimeout)
elif opt == "oneshot" and val:
self.mOneShot = retValue(val, 0, self.mOneShot)
elif opt == "repeat" and val:
self.mRepeat = retValue(val, 0, self.mRepeat)
elif opt == "always" and val:
self.mAlways = retValue(val, 0, self.mAlways)
elif opt == "startpoint" and val:
self.mStartPoint = int(val)
elif opt == "pagedelay" and val:
self.mPageDelay = retValue(val, 0, self.mPageDelay)
elif opt == "pagelength" and val:
self.mPageLength = retValue(val, 0, self.mPageLength)
else:
attribs.append((attrib, value))
if attrib == "backgroundColor":
self.scroll_label.setBackgroundColor(parseColor(value))
elif attrib == "transparent":
self.scroll_label.setTransparent(int(value))
self.skinAttributes = attribs
ret = Renderer.applySkin(self, desktop, screen)
if self.mOneShot:
self.mOneShot = max(self.mStepTimeout, self.mOneShot)
if self.mLoopTimeout:
self.mLoopTimeout = max(self.mStepTimeout, self.mLoopTimeout)
if self.mPageDelay:
self.mPageDelay = max(self.mStepTimeout, self.mPageDelay)
self.scroll_label.setFont(self.txfont)
if not (self.txtflags & RT_WRAP):
self.scroll_label.setNoWrap(1)
self.scroll_label.setVAlign(valign)
self.scroll_label.setHAlign(self.halign)
self.scroll_label.move(ePoint(0, 0))
self.scroll_label.resize(eSize(self.W, self.H))
# test for auto correction text height:
if self.direction in (TOP, BOTTOM):
from enigma import fontRenderClass
flh = int(fontRenderClass.getInstance().getLineHeight(self.txfont) or self.txfont.pointSize / 6 + self.txfont.pointSize)
self.scroll_label.setText("WQq")
if flh > self.scroll_label.calculateSize().height():
self.lineHeight = flh
self.scroll_label.setText("")
return ret
def doSuspend(self, suspended):
self.mShown = 1 - suspended
if suspended:
self.changed((self.CHANGED_CLEAR,))
else:
self.changed((self.CHANGED_DEFAULT,))
def connect(self, source):
Renderer.connect(self, source)
def changed(self, what):
if self.mTimer is not None:
self.mTimer.stop()
if what[0] == self.CHANGED_CLEAR:
self.txtext = ""
if self.instance:
self.scroll_label.setText("")
else:
if self.mShown:
self.txtext = self.source.text or ""
if self.instance and not self.calcMoving():
self.scroll_label.resize(eSize(self.W, self.H))
self.moveLabel(self.X, self.Y)
def moveLabel(self, X, Y):
self.scroll_label.move(ePoint(X - self.soffset[0], Y - self.soffset[1]))
def calcMoving(self):
self.X = self.Y = 0
if not (self.txtflags & RT_WRAP):
self.txtext = self.txtext.replace("\xe0\x8a", " ").replace(chr(0x8A), " ").replace("\n", " ").replace("\r", " ")
self.scroll_label.setText(self.txtext)
if self.txtext == "" or \
self.type == NONE or \
self.scroll_label is None:
return False
if self.direction in (LEFT, RIGHT) or not (self.txtflags & RT_WRAP):
self.scroll_label.resize(eSize(self.txfont.pointSize * len(self.txtext), self.H)) # stupid workaround, have no better idea right now...
text_size = self.scroll_label.calculateSize()
text_width = text_size.width()
text_height = text_size.height()
if self.direction in (LEFT, RIGHT) or not (self.txtflags & RT_WRAP):
text_width += 10
self.mStop = None
# text height correction if necessary:
if self.lineHeight and self.direction in (TOP, BOTTOM):
text_height = max(text_height, (text_height + self.lineHeight - 1) / self.lineHeight * self.lineHeight)
# self.type = 0 - NONE; 1 - RUNNING; 2 - SWIMMING; 3 - AUTO(???)
# self.direction = 0 - LEFT; 1 - RIGHT; 2 - TOP; 3 - BOTTOM
# self.halign = 0 - LEFT; 1 - RIGHT; 2 - CENTER; 3 - BLOCK
if self.direction in (LEFT, RIGHT):
if not self.mAlways and text_width <= self.W:
return False
if self.type == RUNNING:
self.A = self.X - text_width - self.soffset[0] - abs(self.mStep)
self.B = self.W - self.soffset[0] + abs(self.mStep)
if self.direction == LEFT:
self.mStep = -abs(self.mStep)
self.mStop = self.X
self.P = self.B
else:
self.mStep = abs(self.mStep)
self.mStop = self.B - text_width + self.soffset[0] - self.mStep
self.P = self.A
if self.mStartPoint is not None:
if self.direction == LEFT:
self.mStop = self.P = max(self.A, min(self.W, self.mStartPoint))
else:
self.mStop = self.P = max(self.A, min(self.B, self.mStartPoint - text_width + self.soffset[0]))
elif self.type == SWIMMING:
if text_width < self.W:
self.A = self.X + 1 # incomprehensible indent '+ 1' ???
self.B = self.W - text_width - 1 # incomprehensible indent '- 1' ???
if self.halign == LEFT:
self.P = self.A
self.mStep = abs(self.mStep)
elif self.halign == RIGHT:
self.P = self.B
self.mStep = -abs(self.mStep)
else: # if self.halign in (CENTER, BLOCK):
self.P = int(self.B / 2)
self.mStep = (self.direction == RIGHT) and abs(self.mStep) or -abs(self.mStep)
else:
if text_width == self.W:
text_width += max(2, text_width / 20)
self.A = self.W - text_width
self.B = self.X
if self.halign == LEFT:
self.P = self.B
self.mStep = -abs(self.mStep)
elif self.halign == RIGHT:
self.P = self.A
self.mStep = abs(self.mStep)
else: # if self.halign in (CENTER, BLOCK):
self.P = int(self.A / 2)
self.mStep = (self.direction == RIGHT) and abs(self.mStep) or -abs(self.mStep)
else:
return False
elif self.direction in (TOP, BOTTOM):
if not self.mAlways and text_height <= self.H:
return False
if self.type == RUNNING:
self.A = self.Y - text_height - self.soffset[1] - abs(self.mStep)
self.B = self.H - self.soffset[1] + abs(self.mStep)
if self.direction == TOP:
self.mStep = -abs(self.mStep)
self.mStop = self.Y
self.P = self.B
else:
self.mStep = abs(self.mStep)
self.mStop = self.B - text_height + self.soffset[1] - self.mStep
self.P = self.A
if self.mStartPoint is not None:
if self.direction == TOP:
self.mStop = self.P = max(self.A, min(self.H, self.mStartPoint))
else:
self.mStop = self.P = max(self.A, min(self.B, self.mStartPoint - text_height + self.soffset[1]))
elif self.type == SWIMMING:
if text_height < self.H:
self.A = self.Y
self.B = self.H - text_height
if self.direction == TOP:
self.P = self.B
self.mStep = -abs(self.mStep)
else:
self.P = self.A
self.mStep = abs(self.mStep)
else:
if text_height == self.H:
text_height += max(2, text_height / 40)
self.A = self.H - text_height
self.B = self.Y
if self.direction == TOP:
self.P = self.B
self.mStep = -abs(self.mStep)
self.mStop = self.B
else:
self.P = self.A
self.mStep = abs(self.mStep)
self.mStop = self.A
else:
return False
else:
return False
self.xW = max(self.W, text_width)
self.xH = max(self.H, text_height)
self.scroll_label.resize(eSize(self.xW, self.xH))
if self.mStartDelay:
if self.direction in (LEFT, RIGHT):
self.moveLabel(self.P, self.Y)
else: # if self.direction in (TOP,BOTTOM):
self.moveLabel(self.X, self.P)
self.mCount = self.mRepeat
self.mTimer.start(self.mStartDelay, True)
return True
def movingLoop(self):
if self.A <= self.P <= self.B:
if self.direction in (LEFT, RIGHT):
self.moveLabel(self.P, self.Y)
else: # if self.direction in (TOP,BOTTOM)
self.moveLabel(self.X, self.P)
timeout = self.mStepTimeout
if (self.mStop is not None) and (self.mStop + abs(self.mStep) > self.P >= self.mStop):
if (self.type == RUNNING) and (self.mOneShot > 0):
if (self.mRepeat > 0) and (self.mCount - 1 <= 0):
return
timeout = self.mOneShot
elif (self.type == SWIMMING) and (self.mPageLength > 0) and (self.mPageDelay > 0):
if (self.direction == TOP) and (self.mStep < 0):
self.mStop -= self.mPageLength
if self.mStop < self.A:
self.mStop = self.B
timeout = self.mPageDelay
elif (self.direction == BOTTOM) and (self.mStep > 0):
self.mStop += self.mPageLength
if self.mStop > self.B:
self.mStop = self.A
timeout = self.mPageDelay
else:
if self.mRepeat > 0:
self.mCount -= 1
if self.mCount == 0:
return
timeout = self.mLoopTimeout
if self.type == RUNNING:
if self.P < self.A:
self.P = self.B + abs(self.mStep)
else:
self.P = self.A - abs(self.mStep)
else:
self.mStep = -self.mStep
self.P += self.mStep
self.mTimer.start(timeout, True)