mirror of
https://github.com/gryf/wmdocklib.git
synced 2025-12-18 12:00:20 +01:00
1751441: cleaning up the oo module
as requested, the two classes wmoo.Label and wmoo.Button, the method wmoo.Application.addWidget. widgets can be retrieved as dictionary entries of the application.
This commit is contained in:
@@ -22,8 +22,8 @@ class Application(wmoo.Application):
|
||||
self._buffering = 0
|
||||
self._flash = 0
|
||||
self._muting = 0
|
||||
if 'pause' in self._buttons:
|
||||
self.setButtonPattern('pause', (11, 10))
|
||||
if 'pause' in self._widgets:
|
||||
self['pause'].setPattern((11, 10))
|
||||
self.showCacheLevel()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -101,7 +101,7 @@ class Application(wmoo.Application):
|
||||
#print 'in previousRadio'
|
||||
if self.currentRadio == 0: self.currentRadio = len(self.radioList)
|
||||
self.currentRadio -= 1
|
||||
self.setLabelText('name', self.radioList[self.currentRadio][0])
|
||||
self['name'].setText(self.radioList[self.currentRadio][0])
|
||||
if self.child:
|
||||
self.stopPlayer()
|
||||
self.startPlayer()
|
||||
@@ -110,7 +110,7 @@ class Application(wmoo.Application):
|
||||
#print 'in nextRadio'
|
||||
self.currentRadio += 1
|
||||
if self.currentRadio == len(self.radioList): self.currentRadio = 0
|
||||
self.setLabelText('name', self.radioList[self.currentRadio][0])
|
||||
self['name'].setText(self.radioList[self.currentRadio][0])
|
||||
if self.child:
|
||||
self.stopPlayer()
|
||||
self.startPlayer()
|
||||
@@ -138,7 +138,7 @@ class Application(wmoo.Application):
|
||||
#print 'in muteStream'
|
||||
if self.child and self._buffering == 0:
|
||||
self.child.stdin.write('m')
|
||||
self.setButtonPattern('mute', (33-11*self._muting, 0))
|
||||
self['mute'].setPattern((33-11*self._muting, 0))
|
||||
self._muting = 1 - self._muting
|
||||
|
||||
def showCacheLevel(self):
|
||||
@@ -169,7 +169,7 @@ class Application(wmoo.Application):
|
||||
return
|
||||
if self._paused:
|
||||
colour = self._colour = 4 - self._colour
|
||||
self.setButtonPattern('pause', (self._colour*11, 10))
|
||||
self['pause'].setPattern((self._colour*11, 10))
|
||||
self._count = 0
|
||||
if self.child:
|
||||
import select
|
||||
@@ -303,15 +303,16 @@ def main():
|
||||
background = background,
|
||||
patterns = patterns)
|
||||
# maxCharsPerLine = (width-2*xOffset) / char width
|
||||
app.addLabel('name', (5, 16), (54, 10), app.radioList[app.currentRadio][0])
|
||||
app.addWidget('name', wmoo.Label,
|
||||
(5, 16), (54, 10), app.radioList[app.currentRadio][0])
|
||||
|
||||
app.addButton('prev', ( 6,31), (9, 10), app.previousRadio, pattern=(0,0))
|
||||
app.addButton('next', (21,31), (9, 10), app.nextRadio, pattern=(11,0))
|
||||
app.addButton('mute', (36,31), (9, 10), app.muteStream, pattern=(22,0))
|
||||
app.addWidget('prev', wmoo.Button, ( 6,31), (9, 10), app.previousRadio, pattern=(0,0))
|
||||
app.addWidget('next', wmoo.Button, (21,31), (9, 10), app.nextRadio, pattern=(11,0))
|
||||
app.addWidget('mute', wmoo.Button, (36,31), (9, 10), app.muteStream, pattern=(22,0))
|
||||
|
||||
app.addButton('play', ( 6,47), (9, 10), app.playStream, pattern=(0,10))
|
||||
app.addButton('pause', (21,47), (9, 10), app.pauseStream, pattern=(11,10))
|
||||
app.addButton('stop', (36,47), (9, 10), app.stopStream, pattern=(22,10))
|
||||
app.addWidget('play', wmoo.Button, ( 6,47), (9, 10), app.playStream, pattern=(0,10))
|
||||
app.addWidget('pause',wmoo.Button, (21,47), (9, 10), app.pauseStream, pattern=(11,10))
|
||||
app.addWidget('stop', wmoo.Button, (36,47), (9, 10), app.stopStream, pattern=(22,10))
|
||||
|
||||
app.addCallback(app.previousRadio, 'keypress', key='k')
|
||||
app.addCallback(app.nextRadio, 'keypress', key='j')
|
||||
|
||||
@@ -7,6 +7,131 @@ LEFT = 0
|
||||
CENTRE = 1
|
||||
RIGHT = 2
|
||||
|
||||
class Widget:
|
||||
"""
|
||||
a widget is a graphical object able to display itself.
|
||||
|
||||
a wiget stores its graphical representation in a Drawable. it gets the
|
||||
chance to update its Drawable periodically, since the application will
|
||||
scan all its widgets and call their 'update' method.
|
||||
|
||||
a callback can be associated to a widget during its creation. all that
|
||||
happens behind the scenes is that the callback is registered on the area
|
||||
of the widget, but it is not really directly associated to it.
|
||||
"""
|
||||
def __init__(self):
|
||||
'''do not call ancestor constructor in derived classes!'''
|
||||
raise NotImplementedError('Widget is not instantiable')
|
||||
def update(self):
|
||||
pass
|
||||
pass
|
||||
|
||||
class Label(Widget):
|
||||
|
||||
def __init__(self, container, orig, size=None, text='', align=LEFT):
|
||||
"""a label is a tuple with...
|
||||
text: string; mutable
|
||||
viewport: (orig: int, int, size: int, int); inmutable
|
||||
pixmap: drawable; not user mutable, large enough to contain the text
|
||||
align: one of LEFT, CENTRE, RIGHT
|
||||
|
||||
if size is not given, it is inferred from text.
|
||||
"""
|
||||
# print container, orig, size, text, align
|
||||
if size is None:
|
||||
size = (container._char_width * len(text), container._char_height)
|
||||
pixmapwidth = max(container._char_width * len(text), size[0])
|
||||
import pywmgeneral
|
||||
labelPixmap = pywmgeneral.Drawable(pixmapwidth, container._char_height)
|
||||
self.orig = orig
|
||||
self.size = size
|
||||
self.pixw = pixmapwidth
|
||||
self.offset = 0
|
||||
self.pixmap = labelPixmap
|
||||
self.align = align
|
||||
self.container = container
|
||||
self.setText(text)
|
||||
|
||||
def update(self):
|
||||
(orig_x,orig_y) = self.orig
|
||||
(size_x, size_y) = self.size
|
||||
if self.size[0] < self.pixw:
|
||||
self.pixmap.xCopyAreaToWindow(self.offset, 0, size_x, size_y, orig_x, orig_y)
|
||||
if self.offset == self.pixw:
|
||||
self.offset = -size_x
|
||||
else:
|
||||
self.offset += 1
|
||||
|
||||
def setText(self, text):
|
||||
(orig_x,orig_y) = self.orig
|
||||
(size_x, size_y) = self.size
|
||||
newwidth = self.container._char_width * len(text)
|
||||
if newwidth > self.pixw:
|
||||
import pywmgeneral
|
||||
self.pixmap = pywmgeneral.Drawable(newwidth, self.container._char_height)
|
||||
self.pixw = newwidth
|
||||
self.offset = 0
|
||||
self.pixmap.xClear()
|
||||
self.pixmap.xCopyAreaToWindow(0, 0, size_x, size_y, orig_x, orig_y)
|
||||
w = pywmhelpers.addString(text, 0, 0, drawable=self.pixmap)
|
||||
dx = 0
|
||||
if w < size_x:
|
||||
spare = size_x - w
|
||||
if self.align == RIGHT:
|
||||
dx = spare
|
||||
elif self.align == CENTRE:
|
||||
dx = int(spare/2)
|
||||
else:
|
||||
w = size_x
|
||||
self.pixmap.xCopyAreaToWindow(0, 0, w, size_y, orig_x+dx, orig_y)
|
||||
|
||||
class Button(Widget):
|
||||
|
||||
def __init__(self, container, orig, size,
|
||||
callback1, callback2=None, callback3=None,
|
||||
pattern=None):
|
||||
"""adds an area sensitive to the click of the mouse buttons
|
||||
|
||||
the graphical appearance can be specified in the pattern or left as
|
||||
in the background. in both cases, it can later be modified by
|
||||
calling setButtonPattern
|
||||
"""
|
||||
# print container, orig, size, callback1, callback2, callback3, pattern
|
||||
|
||||
orig_x, orig_y = orig
|
||||
dx, dy = size
|
||||
area = (orig_x, orig_y, orig_x + dx, orig_y + dy)
|
||||
container.addCallback(callback1, 'buttonrelease', area=area)
|
||||
if callback2 is not None:
|
||||
container.addCallback(callback2, 'buttonrelease', area=area)
|
||||
if callback3 is not None:
|
||||
container.addCallback(callback3, 'buttonrelease', area=area)
|
||||
self.area = (orig_x, orig_y, dx, dy)
|
||||
if pattern is not None:
|
||||
self.setPattern(pattern)
|
||||
|
||||
def setPattern(self, patternOrig):
|
||||
"""paints the pattern on top of the button
|
||||
"""
|
||||
|
||||
(x, y, w, h) = self.area
|
||||
pywmhelpers.copyXPMArea(patternOrig[0], patternOrig[1] + 64, w, h, x, y)
|
||||
pass
|
||||
|
||||
class ProgressBar(Widget):
|
||||
"""a bit more generic than a progress bar...
|
||||
|
||||
it shows as a progress bar, a percentage, an absolute quantity or a custom pixmap.
|
||||
|
||||
properties (all are mutable)
|
||||
size: the total 'capacity'.
|
||||
used: the amount completed.
|
||||
style: one of [size, used, free, bar, percent, empty]
|
||||
fg, bg: the colours for the bar.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
class Application:
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""initializes the object
|
||||
@@ -18,8 +143,7 @@ class Application:
|
||||
'area': if the pointer is here, the event is considered,
|
||||
|
||||
"""
|
||||
self._elements = {}
|
||||
self._buttons = {}
|
||||
self._widgets = {}
|
||||
self._events = []
|
||||
self._sleep = 0.1
|
||||
self._cycle = 0
|
||||
@@ -38,98 +162,22 @@ class Application:
|
||||
pywmhelpers.copyXPMArea(sourceX, sourceY+64, width, height,
|
||||
targetX, targetY)
|
||||
|
||||
def addLabel(self, labelId, orig, size=None, text='', align=LEFT):
|
||||
"""a label is a tuple with a
|
||||
text: string; mutable
|
||||
viewport: (orig: int, int, size: int, int); inmutable
|
||||
pixmap: drawable; not user mutable, large enough to contain the text
|
||||
align: one of LEFT, CENTRE, RIGHT
|
||||
def addWidget(self, widgetId, widgetClass, *args, **kwargs):
|
||||
# print widgetId, widgetClass, args, kwargs
|
||||
self._widgets[widgetId] = widgetClass(self, *args, **kwargs)
|
||||
|
||||
if size is not given, it is inferred from text.
|
||||
"""
|
||||
if size is None:
|
||||
size = (self._char_width * len(text), self._char_height)
|
||||
pixmapwidth = max(self._char_width * len(text), size[0])
|
||||
import pywmgeneral
|
||||
labelPixmap = pywmgeneral.Drawable(pixmapwidth, self._char_height)
|
||||
self._elements[labelId] = {
|
||||
'orig': orig,
|
||||
'size': size,
|
||||
'pixw': pixmapwidth,
|
||||
'offset': 0,
|
||||
'pixmap': labelPixmap,
|
||||
'align': align}
|
||||
self.setLabelText(labelId, text)
|
||||
def widget(self, name):
|
||||
return self._widgets[name]
|
||||
|
||||
def setLabelText(self, labelId, text):
|
||||
"""updates the drawable associated with labelId
|
||||
"""
|
||||
lbl = self._elements[labelId]
|
||||
(orig_x,orig_y) = lbl['orig']
|
||||
(size_x, size_y) = lbl['size']
|
||||
newwidth = self._char_width * len(text)
|
||||
if newwidth > lbl['pixw']:
|
||||
import pywmgeneral
|
||||
lbl['pixmap'] = pywmgeneral.Drawable(newwidth, self._char_height)
|
||||
lbl['pixw'] = newwidth
|
||||
lbl['offset'] = 0
|
||||
lbl['pixmap'].xClear()
|
||||
lbl['pixmap'].xCopyAreaToWindow(0, 0, size_x, size_y, orig_x, orig_y)
|
||||
w = pywmhelpers.addString(text, 0, 0, drawable=lbl['pixmap'])
|
||||
dx = 0
|
||||
if w < size_x:
|
||||
spare = size_x - w
|
||||
if lbl['align'] == RIGHT:
|
||||
dx = spare
|
||||
elif lbl['align'] == CENTRE:
|
||||
dx = int(spare/2)
|
||||
else:
|
||||
w = size_x
|
||||
|
||||
lbl['pixmap'].xCopyAreaToWindow(0, 0, w, size_y, orig_x+dx, orig_y)
|
||||
|
||||
def addButton(self, buttonId, orig, size,
|
||||
callback1, callback2=None, callback3=None,
|
||||
pattern=None):
|
||||
"""adds an area sensitive to the click of the mouse buttons
|
||||
|
||||
the graphical appearance can be specified in the pattern or left as
|
||||
in the background. in both cases, it can later be modified by
|
||||
calling setButtonPattern
|
||||
"""
|
||||
|
||||
orig_x, orig_y = orig
|
||||
dx, dy = size
|
||||
area = (orig_x, orig_y, orig_x + dx, orig_y + dy)
|
||||
self.addCallback(callback1, 'buttonrelease', area=area)
|
||||
if callback2 is not None:
|
||||
self.addCallback(callback2, 'buttonrelease', area=area)
|
||||
if callback3 is not None:
|
||||
self.addCallback(callback3, 'buttonrelease', area=area)
|
||||
self._buttons[buttonId] = (orig, size)
|
||||
if pattern is not None:
|
||||
self.setButtonPattern(buttonId, pattern)
|
||||
|
||||
def setButtonPattern(self, buttonId, patternOrig):
|
||||
"""paints the pattern on top of the button
|
||||
"""
|
||||
|
||||
(x, y), (w, h) = self._buttons[buttonId]
|
||||
pywmhelpers.copyXPMArea(patternOrig[0], patternOrig[1] + 64, w, h, x, y)
|
||||
def __getitem__(self, key):
|
||||
return self._widgets[key]
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
def redraw(self):
|
||||
for lbl in self._elements.values():
|
||||
(orig_x,orig_y) = lbl['orig']
|
||||
(size_x, size_y) = lbl['size']
|
||||
if lbl['size'][0] < lbl['pixw']:
|
||||
lbl['pixmap'].xCopyAreaToWindow(lbl['offset'], 0, size_x, size_y, orig_x, orig_y)
|
||||
if lbl['offset'] == lbl['pixw']:
|
||||
lbl['offset'] = -size_x
|
||||
else:
|
||||
lbl['offset'] += 1
|
||||
for item in self._widgets.values():
|
||||
item.update()
|
||||
self.update()
|
||||
pywmhelpers.redraw()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user