r4918 - developers/charlie/Tests/Evas
charlie at docs.openmoko.org
charlie at docs.openmoko.org
Tue Feb 10 05:36:40 CET 2009
Author: charlie
Date: 2009-02-10 05:36:39 +0100 (Tue, 10 Feb 2009)
New Revision: 4918
Added:
developers/charlie/Tests/Evas/object.py
Modified:
developers/charlie/Tests/Evas/test.edc
developers/charlie/Tests/Evas/test.edj
developers/charlie/Tests/Evas/test.py
Log:
Change in evas tests
Added: developers/charlie/Tests/Evas/object.py
===================================================================
--- developers/charlie/Tests/Evas/object.py (rev 0)
+++ developers/charlie/Tests/Evas/object.py 2009-02-10 04:36:39 UTC (rev 4918)
@@ -0,0 +1,159 @@
+# Tichy
+#
+# copyright 2008 Guillaume Chereau (charlie at openmoko.org)
+#
+# This file is part of Tichy.
+#
+# Tichy 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 3 of the License, or
+# (at your option) any later version.
+#
+# Tichy 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 Tichy. If not, see <http://www.gnu.org/licenses/>.
+
+"""Object module
+
+This module define the Object class, that provides signal mechanism in
+a way similar to gobject.
+"""
+
+__docformat__ = 'reStructuredText'
+
+import os
+
+from types import GeneratorType
+
+class Object(object):
+ """This class implements the observer patern
+
+ I could use gobject.GObject instead. But i think gobject may
+ be overkill there... still thinking about it...
+ """
+
+ def __new__(cls, *args, **kargs):
+ ret = object.__new__(cls)
+ ret.__listeners = {}
+ return ret
+
+ def __init__(self, *kargs): # TODO: see why I hava to use __init__
+ # even with the __new__
+ if not hasattr(self, '_Object__listeners'):
+ self.__listeners = {}
+
+ @classmethod
+ def path(cls, path=None):
+ """return the path of a file situated in the same directory than the
+ source code of the object.
+
+ :Parameters:
+
+ `path` : str or None
+ The name of the file, if set to None, then return
+ the directory of the object.
+ """
+ # XXX: this path method sucks
+ module_str = cls.__module__
+ module = __import__(module_str)
+ ret = os.path.dirname(module.__file__)
+ if path:
+ ret = os.path.join(ret, path)
+ if os.path.exists(ret):
+ return ret
+ # If we didn't find the file then we check in the system dir
+ for base in ['/usr/tichy', '/usr/share/tichy']:
+ ret = os.path.join(base, path)
+ if os.path.exists(ret):
+ return ret
+
+ @classmethod
+ def open(cls, path):
+ """Open a file that is located in the same directory than the object
+ source code
+
+ :Parameters:
+
+ `path` : str
+ The file name
+ """
+ return open(cls.path(path))
+
+ def connect(self, event, callback, *args):
+ """Connect the object to a given event
+
+ This method has the same syntax than the gobject equivalent.
+
+ :Parameters:
+
+ `event` : str
+ the name of the vent we connect to
+
+ `callback` : callback method
+ the method called when the event is emitted. The first
+ argument of the method will be the calling object. All
+ arguments passed to the connect method will be passed
+ as well
+
+ :Returns: The id of the connection
+ """
+ return self.connect_object(event, callback, self, *args)
+
+ def connect_object(self, event, callback, obj, *args):
+ """Connect an event using a given object instead of self"""
+ connection = (callback, obj, args)
+ self.__listeners.setdefault(event, []).append(connection)
+ return id(connection)
+
+ def disconnect(self, oid):
+ """remove a connection from the listeners
+
+ :Parameters:
+
+ oid : int
+ The id returned by `Object.connect` method
+ """
+ for listener in self.__listeners.itervalues():
+ for connection in listener:
+ if id(connection) == oid:
+ listener.remove(connection)
+ return
+
+ raise Exception("trying to disconnect a bad id")
+
+ def emit(self, event, *args):
+ """Emit a signal
+
+ All the listeners will be notified.
+
+ All extra arguments will be passed to the listeners
+ callback method.
+
+ :Parameters:
+ `event` : str
+ The name of the event to emit.
+ """
+ for callback, obj, extra_args in self.__listeners.get(event, []):
+ eargs = args + extra_args
+ call = callback(obj, *eargs)
+ # Now in case the callback is a generator, we turn it into a task
+ # This allow us to directly connect to generators
+ if type(call) is GeneratorType:
+ Tasklet(generator=call).start()
+
+ def monitor(self, obj, event, callback, *args):
+ """connect an object to a callback, and automatically disconnect it
+ when this object is destroyed.
+
+ WARNING: This is still experimental, and should only be used
+ with objects that have a 'destroy' signal.
+ """
+ connection = obj.connect(event, callback, *args)
+
+ def on_destroyed(self, obj, connection):
+ obj.disconnect(connection)
+ self.connect('destroyed', on_destroyed, obj, connection)
Modified: developers/charlie/Tests/Evas/test.edc
===================================================================
--- developers/charlie/Tests/Evas/test.edc 2009-02-09 01:50:55 UTC (rev 4917)
+++ developers/charlie/Tests/Evas/test.edc 2009-02-10 04:36:39 UTC (rev 4918)
@@ -13,118 +13,124 @@
}
collections {
- group {
- name: "test";
- parts {
- part {
- name: "background";
- type: RECT;
- description {
- state: "default" 0.0;
- color: 0 0 0 255;
- }
+ group {
+ name: "test";
+ parts {
+ part {
+ name: "background";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ color: 0 128 0 255;
}
-
-
- part {
- name: "main-menu";
- type: SWALLOW;
- description {
- state: "default" 0.0;
- rel1 {
- relative: 0.1 0.1;
- offset: 0 0;
- }
- rel2 {
- relative: 0.9 0.9;
- offset: 0 0;
- }
- }
+ }
+
+
+ part {
+ name: "main-menu";
+ type: SWALLOW;
+ description {
+ state: "default" 0.0;
+ rel1 {
+ relative: 0.1 0.1;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 0.9 0.9;
+ offset: 0 0;
+ }
}
- }
- }
-
-
- group {
- name: "label";
- min: 440 80;
- max: 440 80;
- parts {
- part {
- name: "label";
- type: TEXT;
- description {
- fixed: 1 1;
- text {
- align: 0.0 0.5;
- min: 1 1;
- size: 48;
- text: "Hello";
- font: "Sans";
- }
- rel1 {
- relative: 0.1 0.1;
- offset: 0 0;
- }
- rel2 {
- relative: 0.9 0.9;
- offset: 0 0;
- }
- state: "default" 0.0;
- color: 255 255 255 255;
- }
+ }
+ }
+ }
+
+
+ group {
+ name: "label";
+ min: 440 64;
+ max: 440 64;
+ parts {
+ part {
+ name: "label";
+ type: TEXT;
+ description {
+ fixed: 1 1;
+ text {
+ align: 0.0 0.5;
+ min: 1 1;
+ size: 48;
+ text: "Hello";
+ font: "Sans";
+ }
+ rel1 {
+ relative: 0.1 0.1;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 0.9 0.9;
+ offset: 0 0;
+ }
+ state: "default" 0.0;
+ color: 255 255 255 255;
}
- }
- }
-
- group {
- name: "button";
- min: 440 80;
- max: 440 80;
- parts {
- part {
- name: "rect";
- type: RECT;
- description {
- rel1 {
- relative: 0.1 0.1;
- offset: 0 0;
- }
- rel2 {
- relative: 0.9 0.9;
- offset: 0 0;
- }
- state: "default" 0.0;
- color: 255 0 0 128;
- }
+ }
+ }
+ }
+
+ group {
+ name: "button";
+ min: 440 80;
+ max: 440 80;
+ parts {
+ part {
+ name: "rect";
+ type: RECT;
+ description {
+ rel1 {
+ relative: 0.1 0.1;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 0.9 0.9;
+ offset: 0 0;
+ }
+ state: "default" 0.0;
+ color: 255 255 0 128;
}
- }
- }
-
-
- group {
- name: "frame";
- min: 440 80;
-// max: 440 80;
- parts {
- part {
- name: "rect";
- type: RECT;
- description {
- rel1 {
- relative: 0.1 0.1;
- offset: 0 0;
- }
- rel2 {
- relative: 0.9 0.9;
- offset: 0 0;
- }
- state: "default" 0.0;
- color: 255 0 0 255;
- }
+ }
+ }
+ programs {
+ program {
+ signal: "mouse,up,1";
+ source: "rect";
+ action: SIGNAL_EMIT "clicked" "rect";
+ }
+ }
+ }
+
+
+ group {
+ name: "frame";
+ min: 440 80;
+ // max: 440 80;
+ parts {
+ part {
+ name: "rect";
+ type: RECT;
+ description {
+ rel1 {
+ relative: 0.1 0.1;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 0.9 0.9;
+ offset: 0 0;
+ }
+ state: "default" 0.0;
+ color: 255 255 0 255;
}
- }
- }
+ }
+ }
+ }
}
-
Modified: developers/charlie/Tests/Evas/test.edj
===================================================================
(Binary files differ)
Modified: developers/charlie/Tests/Evas/test.py
===================================================================
--- developers/charlie/Tests/Evas/test.py 2009-02-09 01:50:55 UTC (rev 4917)
+++ developers/charlie/Tests/Evas/test.py 2009-02-10 04:36:39 UTC (rev 4918)
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
import e_dbus
import evas
@@ -8,10 +9,15 @@
import ecore.evas
import etk
-class Widget(object):
- def __init__(self, parent, **kargs):
+from object import Object
+
+class Widget(Object):
+ def __init__(self, parent, etk_obj=None, expand=False, **kargs):
+ super(Widget, self).__init__()
+ self.etk_obj = etk_obj
self.parent = parent
- self.children = []
+ self.expand=expand
+ self.children = [] # Not sure we really need that
if parent is not None:
parent.add(self)
self.show()
@@ -26,20 +32,47 @@
class Window(Widget):
def __init__(self, parent, **kargs):
- self.etk_obj = etk.VBox()
- super(Window, self).__init__(parent, **kargs)
+ etk_obj = etk.VBox() # XXX: use a more appropriate container
+ super(Window, self).__init__(parent, etk_obj, **kargs)
def add(self, child):
- self.etk_obj.append(child.etk_obj, etk.VBox.START, etk.VBox.NONE, 0)
+ if child.expand:
+ policy = etk.VBox.EXPAND_FILL
+ self.etk_obj.append(child.etk_obj, etk.VBox.START, policy, 0)
-
+
+class EdjeSource(object):
+ def __init__(self, edje, source):
+ self.edje = edje
+ self.source = source
+ def callback(self, info, signal, source, callback, *args):
+ callback(self, *args)
+ def connect(self, signal, callback, *args):
+ self.edje._edje_obj.signal_callback_add(signal, self.source,
+ self.callback, callback,
+ *args)
+
+
+class Edje(Widget):
+ def __init__(self, parent, file, group, **kargs):
+ self.file = file
+ self.group = group
+ etk_obj = etk.Canvas()
+ self._edje_obj = edje.Edje(parent.get_evas(), file=file, group=group)
+ etk_obj.object_add(self._edje_obj)
+ super(Edje, self).__init__(parent, etk_obj, **kargs)
+
+ def source(self, name):
+ return EdjeSource(self, name)
+
+
class Screen(Widget):
def __init__(self):
self.etk_window = ecore.evas.SoftwareX11(w=640, h=480)
self.edje = edje.Edje(self.etk_window.evas, file='test.edj', group="test")
self.edje.size = self.etk_window.evas.size
self.etk_window.data["edje"] = self.edje
- self.etk_obj = etk.Embed(self.etk_window.evas)
- Widget.__init__(self, None)
+ etk_obj = etk.Embed(self.etk_window.evas)
+ Widget.__init__(self, None, etk_obj)
def get_evas(self):
return self.etk_window.evas
@@ -53,41 +86,53 @@
class Frame(Widget):
def __init__(self, parent, **kargs):
- self.etk_obj = etk.Canvas()
+ etk_obj = etk.Canvas()
edje_obj = edje.Edje(parent.get_evas(), file='test.edj', group="frame")
- self.etk_obj.object_add(edje_obj)
- super(Frame, self).__init__(parent, **kargs)
+ etk_obj.object_add(edje_obj)
+ super(Frame, self).__init__(parent, etk_obj, **kargs)
edje_obj.show()
class Box(Widget):
def __init__(self, parent, axis=0, **kargs):
- self.etk_obj = etk.VBox()
- super(Box, self).__init__(parent, **kargs)
+ if axis == 0:
+ etk_obj = etk.VBox()
+ else:
+ etk_obj = etk.HBox()
+ super(Box, self).__init__(parent, etk_obj, **kargs)
def add(self, child):
- self.etk_obj.append(child.etk_obj, etk.VBox.START, etk.VBox.NONE, 0)
+ policy = etk.VBox.FILL
+ if child.expand:
+ policy = etk.VBox.EXPAND_FILL
+ self.etk_obj.append(child.etk_obj, etk.VBox.START, policy, 0)
class Scrolled(Widget):
def __init__(self, parent, **kargs):
- self.etk_obj = etk.ScrolledView()
- super(Scrolled, self).__init__(parent, **kargs)
+ etk_obj = etk.ScrolledView()
+ super(Scrolled, self).__init__(parent, etk_obj, **kargs)
def add(self, child):
self.etk_obj.add_with_viewport(child.etk_obj)
-class Button(Widget):
+class Button(Edje):
def __init__(self, parent, **kargs):
- self.etk_obj = etk.Canvas()
- edje_obj = edje.Edje(parent.get_evas(), file='test.edj', group="button")
- self.etk_obj.object_add(edje_obj)
- super(Button, self).__init__(parent, **kargs)
- edje_obj.show()
+ super(Button, self).__init__(parent, 'test.edj', 'button')
+ self.source('rect').connect('clicked', self._on_click)
+ def _on_click(self, *args):
+ self.emit('clicked')
+
+
+class Edit(Widget):
+ def __init__(self, parent, **kargs):
+ etk_obj = etk.TextView()
+ super(Edit, self).__init__(parent, etk_obj, **kargs)
+
class Label(Widget):
def __init__(self, parent, text, **kargs):
- self.etk_obj = etk.Canvas()
+ etk_obj = etk.Canvas()
self.edje_obj = edje.Edje(parent.get_evas(), file='test.edj', group="label")
self.edje_obj.part_text_set("label", text)
- self.etk_obj.object_add(self.edje_obj)
- super(Label, self).__init__(parent, **kargs)
+ etk_obj.object_add(self.edje_obj)
+ super(Label, self).__init__(parent, etk_obj, **kargs)
self.edje_obj.show()
def __get_text(self):
@@ -98,8 +143,8 @@
class Spring(Widget):
def __init__(self, parent, **kargs):
- self.etk_obj = etk.HSeparator()
- super(Spring, self).__init__(parent, **kargs)
+ etk_obj = etk.HSeparator()
+ super(Spring, self).__init__(parent, etk_obj, **kargs)
@@ -110,29 +155,34 @@
screen = Screen()
window = Window(screen)
- frame = Frame(window)
+ # frame = Frame(window)
-# vbox = Box(window)
-# Label(vbox, "hello")
-# Spring(vbox)
-# Label(vbox, "hello")
+ vbox = Box(window, expand=True)
+ Label(vbox, "Text")
+ # Spring(vbox)
+ Label(vbox, "hi")
+ Edit(vbox, expand=True)
-
-# scrolled = Scrolled(screen)
-# window.etk_obj.size_request_set(10,10)
-#
-# vbox = Box(scrolled)
-#
-# for i in range(10):
-# b = Button(vbox)
-# l = Label(b, "hello %d" % i)
-
- # screen.show()
-
-
+ scrolled = Scrolled(vbox, expand=True)
+# # window.etk_obj.size_request_set(10,10)
+
+ vbox = Box(scrolled)
+
+ for i in range(10):
+ b = Button(vbox)
+ # b = Edje(vbox, 'test.edj', 'button')
+ # b.source("rect").connect('clicked', self.on_click)
+ b.connect('clicked', self.on_click)
+ l = Label(b, "hello %d" % i)
+
+ screen.show()
+
+ def on_click(self, *args):
+ print "click", args
+
+
def run(self):
ecore.main_loop_begin()
-
+
gui = Gui()
gui.run()
-
More information about the commitlog
mailing list