Modify framebuffer and NGA framebuffer to read screen size from board model dtb file. Optimise memory usuage of frame buffer
Add example minigui application with hooks to profiler (which writes results to S:\). Modified NGA framebuffer to run its own dfc queue at high priority
# The options of a widget are described by the following attributes
# of the Pack and Widget dialogs:
#
# Dialog.current: {name: value}
# -- changes during Widget's lifetime
#
# Dialog.options: {name: (default, klass)}
# -- depends on widget class only
#
# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
# -- totally static, though different between PackDialog and WidgetDialog
# (but even that could be unified)
from Tkinter import *
class Option:
varclass = StringVar # May be overridden
def __init__(self, dialog, option):
self.dialog = dialog
self.option = option
self.master = dialog.top
self.default, self.klass = dialog.options[option]
self.var = self.varclass(self.master)
self.frame = Frame(self.master)
self.frame.pack(fill=X)
self.label = Label(self.frame, text=(option + ":"))
self.label.pack(side=LEFT)
self.update()
self.addoption()
def refresh(self):
self.dialog.refresh()
self.update()
def update(self):
try:
self.current = self.dialog.current[self.option]
except KeyError:
self.current = self.default
self.var.set(self.current)
def set(self, e=None): # Should be overridden
pass
class BooleanOption(Option):
varclass = BooleanVar
def addoption(self):
self.button = Checkbutton(self.frame,
text='on/off',
onvalue=1,
offvalue=0,
variable=self.var,
relief=RAISED,
borderwidth=2,
command=self.set)
self.button.pack(side=RIGHT)
class EnumOption(Option):
def addoption(self):
self.button = Menubutton(self.frame,
textvariable=self.var,
relief=RAISED, borderwidth=2)
self.button.pack(side=RIGHT)
self.menu = Menu(self.button)
self.button['menu'] = self.menu
for v in self.dialog.classes[self.klass]:
self.menu.add_radiobutton(
label=v,
variable=self.var,
value=v,
command=self.set)
class StringOption(Option):
def addoption(self):
self.entry = Entry(self.frame,
textvariable=self.var,
width=10,
relief=SUNKEN,
borderwidth=2)
self.entry.pack(side=RIGHT, fill=X, expand=1)
self.entry.bind('<Return>', self.set)
class ReadonlyOption(Option):
def addoption(self):
self.label = Label(self.frame, textvariable=self.var,
anchor=E)
self.label.pack(side=RIGHT)
class Dialog:
def __init__(self, master):
self.master = master
self.fixclasses()
self.refresh()
self.top = Toplevel(self.master)
self.top.title(self.__class__.__name__)
self.top.minsize(1, 1)
self.addchoices()
def refresh(self): pass # Must override
def fixclasses(self): pass # May override
def addchoices(self):
self.choices = {}
list = []
for k, dc in self.options.items():
list.append((k, dc))
list.sort()
for k, (d, c) in list:
try:
cl = self.classes[c]
except KeyError:
cl = 'unknown'
if type(cl) == TupleType:
cl = self.enumoption
elif cl == 'boolean':
cl = self.booleanoption
elif cl == 'readonly':
cl = self.readonlyoption
else:
cl = self.stringoption
self.choices[k] = cl(self, k)
# Must override:
options = {}
classes = {}
# May override:
booleanoption = BooleanOption
stringoption = StringOption
enumoption = EnumOption
readonlyoption = ReadonlyOption
class PackDialog(Dialog):
def __init__(self, widget):
self.widget = widget
Dialog.__init__(self, widget)
def refresh(self):
self.current = self.widget.info()
self.current['.class'] = self.widget.winfo_class()
self.current['.name'] = self.widget._w
class packoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
apply(self.dialog.widget.pack, (),
{self.option: self.current})
except TclError, msg:
print msg
self.refresh()
class booleanoption(packoption, BooleanOption): pass
class enumoption(packoption, EnumOption): pass
class stringoption(packoption, StringOption): pass
class readonlyoption(packoption, ReadonlyOption): pass
options = {
'.class': (None, 'Class'),
'.name': (None, 'Name'),
'after': (None, 'Widget'),
'anchor': ('center', 'Anchor'),
'before': (None, 'Widget'),
'expand': ('no', 'Boolean'),
'fill': ('none', 'Fill'),
'in': (None, 'Widget'),
'ipadx': (0, 'Pad'),
'ipady': (0, 'Pad'),
'padx': (0, 'Pad'),
'pady': (0, 'Pad'),
'side': ('top', 'Side'),
}
classes = {
'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
'Boolean': 'boolean',
'Class': 'readonly',
'Expand': 'boolean',
'Fill': (NONE, X, Y, BOTH),
'Name': 'readonly',
'Pad': 'pixel',
'Side': (TOP, RIGHT, BOTTOM, LEFT),
'Widget': 'readonly',
}
class RemotePackDialog(PackDialog):
def __init__(self, master, app, widget):
self.master = master
self.app = app
self.widget = widget
self.refresh()
self.top = Toplevel(self.master)
self.top.title(self.app + ' PackDialog')
self.top.minsize(1, 1)
self.addchoices()
def refresh(self):
try:
words = self.master.tk.splitlist(
self.master.send(self.app,
'pack',
'info',
self.widget))
except TclError, msg:
print msg
return
dict = {}
for i in range(0, len(words), 2):
key = words[i][1:]
value = words[i+1]
dict[key] = value
dict['.class'] = self.master.send(self.app,
'winfo',
'class',
self.widget)
dict['.name'] = self.widget
self.current = dict
class remotepackoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
self.dialog.master.send(
self.dialog.app,
'pack',
'config',
self.dialog.widget,
'-'+self.option,
self.dialog.master.tk.merge(
self.current))
except TclError, msg:
print msg
self.refresh()
class booleanoption(remotepackoption, BooleanOption): pass
class enumoption(remotepackoption, EnumOption): pass
class stringoption(remotepackoption, StringOption): pass
class readonlyoption(remotepackoption, ReadonlyOption): pass
class WidgetDialog(Dialog):
def __init__(self, widget):
self.widget = widget
self.klass = widget.winfo_class()
Dialog.__init__(self, widget)
def fixclasses(self):
if self.addclasses.has_key(self.klass):
classes = {}
for c in (self.classes,
self.addclasses[self.klass]):
for k in c.keys():
classes[k] = c[k]
self.classes = classes
def refresh(self):
self.configuration = self.widget.config()
self.update()
self.current['.class'] = self.widget.winfo_class()
self.current['.name'] = self.widget._w
def update(self):
self.current = {}
self.options = {}
for k, v in self.configuration.items():
if len(v) > 4:
self.current[k] = v[4]
self.options[k] = v[3], v[2] # default, klass
self.options['.class'] = (None, 'Class')
self.options['.name'] = (None, 'Name')
class widgetoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
self.dialog.widget[self.option] = self.current
except TclError, msg:
print msg
self.refresh()
class booleanoption(widgetoption, BooleanOption): pass
class enumoption(widgetoption, EnumOption): pass
class stringoption(widgetoption, StringOption): pass
class readonlyoption(widgetoption, ReadonlyOption): pass
# Universal classes
classes = {
'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
'Aspect': 'integer',
'Background': 'color',
'Bitmap': 'bitmap',
'BorderWidth': 'pixel',
'Class': 'readonly',
'CloseEnough': 'double',
'Command': 'command',
'Confine': 'boolean',
'Cursor': 'cursor',
'CursorWidth': 'pixel',
'DisabledForeground': 'color',
'ExportSelection': 'boolean',
'Font': 'font',
'Foreground': 'color',
'From': 'integer',
'Geometry': 'geometry',
'Height': 'pixel',
'InsertWidth': 'time',
'Justify': (LEFT, CENTER, RIGHT),
'Label': 'string',
'Length': 'pixel',
'MenuName': 'widget',
'Name': 'readonly',
'OffTime': 'time',
'OnTime': 'time',
'Orient': (HORIZONTAL, VERTICAL),
'Pad': 'pixel',
'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
'RepeatDelay': 'time',
'RepeatInterval': 'time',
'ScrollCommand': 'command',
'ScrollIncrement': 'pixel',
'ScrollRegion': 'rectangle',
'ShowValue': 'boolean',
'SetGrid': 'boolean',
'Sliderforeground': 'color',
'SliderLength': 'pixel',
'Text': 'string',
'TickInterval': 'integer',
'To': 'integer',
'Underline': 'index',
'Variable': 'variable',
'Value': 'string',
'Width': 'pixel',
'Wrap': (NONE, CHAR, WORD),
}
# Classes that (may) differ per widget type
_tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
_bistate = {'State': (NORMAL, DISABLED)}
addclasses = {
'Button': _tristate,
'Radiobutton': _tristate,
'Checkbutton': _tristate,
'Entry': _bistate,
'Text': _bistate,
'Menubutton': _tristate,
'Slider': _bistate,
}
class RemoteWidgetDialog(WidgetDialog):
def __init__(self, master, app, widget):
self.app = app
self.widget = widget
self.klass = master.send(self.app,
'winfo',
'class',
self.widget)
Dialog.__init__(self, master)
def refresh(self):
try:
items = self.master.tk.splitlist(
self.master.send(self.app,
self.widget,
'config'))
except TclError, msg:
print msg
return
dict = {}
for item in items:
words = self.master.tk.splitlist(item)
key = words[0][1:]
value = (key,) + words[1:]
dict[key] = value
self.configuration = dict
self.update()
self.current['.class'] = self.klass
self.current['.name'] = self.widget
class remotewidgetoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
self.dialog.master.send(
self.dialog.app,
self.dialog.widget,
'config',
'-'+self.option,
self.current)
except TclError, msg:
print msg
self.refresh()
class booleanoption(remotewidgetoption, BooleanOption): pass
class enumoption(remotewidgetoption, EnumOption): pass
class stringoption(remotewidgetoption, StringOption): pass
class readonlyoption(remotewidgetoption, ReadonlyOption): pass
def test():
import sys
root = Tk()
root.minsize(1, 1)
if sys.argv[1:]:
remotetest(root, sys.argv[1])
else:
frame = Frame(root, name='frame')
frame.pack(expand=1, fill=BOTH)
button = Button(frame, name='button', text='button')
button.pack(expand=1)
canvas = Canvas(frame, name='canvas')
canvas.pack()
fpd = PackDialog(frame)
fwd = WidgetDialog(frame)
bpd = PackDialog(button)
bwd = WidgetDialog(button)
cpd = PackDialog(canvas)
cwd = WidgetDialog(canvas)
root.mainloop()
def remotetest(root, app):
from listtree import listtree
list = listtree(root, app)
list.bind('<Any-Double-1>', opendialogs)
list.app = app # Pass it on to handler
def opendialogs(e):
import string
list = e.widget
sel = list.curselection()
for i in sel:
item = list.get(i)
widget = string.split(item)[0]
RemoteWidgetDialog(list, list.app, widget)
if widget == '.': continue
try:
RemotePackDialog(list, list.app, widget)
except TclError, msg:
print msg
test()