2 --------------------------------------------------------------------------------
3 widgets.py - S.Fourmanoit <syfou@users.sourceforge.net>, 2005
5 This shows a simple way to use Python object-orientedness to implement a
6 simple MVC (Model-View-Control) model, usable with adesklets to implements
9 The beauty of this code is that, while being compact (the core Widget class
10 is seventeen lines of code), it gives a way to dynamically create and modify
11 an arbitrary tree of small graphical elements (widgets) embedding at the
12 same place all their data and the methods needed to display them.
13 --------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
18 Simple class creating a generic widget that can have any numbers
19 of descendants, storable in a tree-like structure. It implements:
21 - A breadth first iterator, usable to visit a complete widget tree
22 or subtree in top to bottom, first to last child order (a widget can
23 also contain non widget-derived objects -- they will simply be skipped
26 - A 'static' config class attribute that can be used to store
27 a configuration shared by all instances of Widget, or
28 Widget derivated classes.
30 - An 'execute' function, that can be used as a shortcut to __iter__
31 to perform arbitrary code execution on a whole widget tree.
33 Obviously, this is completely independent from adesklets...
38 def __init__(self
,config
=None):
39 if not config
is None:
44 for elem
in list.__iter
__(self
):
45 if hasattr(elem
,'_Widget__name'):
46 for child
in elem
.__iter
__():
49 def execute(self
, func
, args
=[]):
51 widget
.__getattribute
__(func
)(*args
)
53 #-------------------------------------------------------------------------------
54 # Now, as a demonstration, let's create a few very simple classes derived
55 # from Widget able to specifically deal with adesklets.
57 # Here, we always create a 'draw' method in every one of them, that can be used
58 # later on to display the element using 'execute' from the root widget element.
59 # Real-life widgets would probably create at least two methods for this
60 # (one writing to foreground and the other one to background),
61 # that would be used appropriately (or arguments would be used).
67 def __init__(self
,coords
):
71 adesklets
.context_set_color(0,0,0,0)
72 adesklets
.context_set_blend(False)
73 adesklets
.image_fill_rectangle(*self
.coords
)
74 adesklets
.context_set_blend(True)
75 adesklets
.context_set_color(*self
.config
['box_color'])
76 adesklets
.image_draw_rectangle(*self
.coords
)
79 """ Text label widget"""
80 def __init__(self
,coords
, text
):
85 font
=adesklets
.load_font(self
.config
['text_font'])
86 adesklets
.context_set_font(font
)
87 adesklets
.context_set_color(*self
.config
['text_color'])
88 adesklets
.text_draw(self
.coords
[0],self
.coords
[1],self
.text
)
89 adesklets
.free_font(font
)
91 font
=adesklets
.load_font(self
.config
['text_font'])
92 adesklets
.context_set_font(font
)
93 result
=adesklets
.get_text_size(self
.text
)
94 adesklets
.free_font(font
)
97 return "<Text label at %s, being '%s'>" % (self
.coords
, self
.text
)
99 class BoxedText(Widget
):
100 """Compound boxed text widget"""
101 def __init__(self
,coords
,text
):
102 Widget
.__init
__(self
)
104 self
.append(Box(coords
+ list(t
.size())))
114 #-------------------------------------------------------------------------------
117 from signal
import pause
118 from random
import randint
121 """Iterator generating pseudo-random (x, y) coordinates in [0,100]"""
123 yield [randint(0,100),randint(0,100)]
125 #-------------------------------------------------------------------------------
129 # Here is the configuration: of course, it could as well be an
130 # adesklets.ConfigFile class or anything else.
132 config
= { 'text_font' : 'Vera/20', 'text_color' : [0,255,0,200] ,
133 'box_color': [255,255,255,200] }
135 # Create dynamically a bunch of randomly positionned widgets
138 for coords
, caption
in zip(rcoords(),'Some text to put on screen'.split()):
139 canva
.append(BoxedText(coords
,caption
))
143 adesklets
.window_resize(150,150)
144 adesklets
.window_set_transparency(True)
145 adesklets
.window_reset(adesklets
.WINDOW_MANAGED
)
146 adesklets
.window_show()
148 # Now let's draw everything once...
150 canva
.execute('draw')
152 # ... Printout all existing Text widget properties descending from
153 # our root 'window' desklet, just to show off...
156 if widget
.__class
__ is Text
:
159 # ... and finally, sleep forever.
163 #-------------------------------------------------------------------------------