]> git.llucax.com Git - z.facultad/66.09/etherled.git/commitdiff
Primer draft de la aplicación cliente.
authorLeandro Lucarella <llucax@gmail.com>
Fri, 28 Oct 2005 06:32:11 +0000 (06:32 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 28 Oct 2005 06:32:11 +0000 (06:32 +0000)
Por ahora sólo responde a los eventos de dibujado. Falta hacer la parte de
cliente-servidor para que reciba y envie las cosas. En el futuro habrá que
extenderlo (o no?) para que se pueda cambiar el tamaño de la matriz (depende de
si llegamos a implementar esto en el dispositivo o no).

cliente/etherled.glade [new file with mode: 0644]
cliente/etherled.py [new file with mode: 0755]
cliente/led-off.png [new file with mode: 0644]
cliente/led-on.png [new file with mode: 0644]
cliente/led.py [new file with mode: 0644]
cliente/simplegladeapp.py [new file with mode: 0644]
cliente/svg/led-off.svg [new file with mode: 0644]
cliente/svg/led-on.svg [new file with mode: 0644]
cliente/svg/leds.svg [new file with mode: 0644]

diff --git a/cliente/etherled.glade b/cliente/etherled.glade
new file mode 100644 (file)
index 0000000..3a720df
--- /dev/null
@@ -0,0 +1,281 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="main_window">
+  <property name="border_width">10</property>
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Etherled</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <signal name="delete_event" handler="on_main_window_delete_event" last_modification_time="Thu, 27 Oct 2005 23:58:35 GMT"/>
+
+  <child>
+    <widget class="GtkVBox" id="vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">10</property>
+
+      <child>
+       <widget class="GtkHBox" id="hbox3">
+         <property name="visible">True</property>
+         <property name="homogeneous">False</property>
+         <property name="spacing">5</property>
+
+         <child>
+           <widget class="GtkLabel" id="label3">
+             <property name="visible">True</property>
+             <property name="label" translatable="yes">IP:</property>
+             <property name="use_underline">False</property>
+             <property name="use_markup">False</property>
+             <property name="justify">GTK_JUSTIFY_LEFT</property>
+             <property name="wrap">False</property>
+             <property name="selectable">False</property>
+             <property name="xalign">0.5</property>
+             <property name="yalign">0.5</property>
+             <property name="xpad">0</property>
+             <property name="ypad">0</property>
+             <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+             <property name="width_chars">-1</property>
+             <property name="single_line_mode">False</property>
+             <property name="angle">0</property>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkEntry" id="entry_ip">
+             <property name="visible">True</property>
+             <property name="can_focus">True</property>
+             <property name="editable">True</property>
+             <property name="visibility">True</property>
+             <property name="max_length">0</property>
+             <property name="text" translatable="yes"></property>
+             <property name="has_frame">True</property>
+             <property name="invisible_char">*</property>
+             <property name="activates_default">False</property>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">True</property>
+             <property name="fill">True</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">True</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkTable" id="table_leds">
+         <property name="visible">True</property>
+         <property name="n_rows">16</property>
+         <property name="n_columns">16</property>
+         <property name="homogeneous">False</property>
+         <property name="row_spacing">0</property>
+         <property name="column_spacing">0</property>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">True</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkHButtonBox" id="hbuttonbox1">
+         <property name="visible">True</property>
+         <property name="layout_style">GTK_BUTTONBOX_END</property>
+         <property name="spacing">0</property>
+
+         <child>
+           <widget class="GtkButton" id="btn_salir">
+             <property name="visible">True</property>
+             <property name="can_default">True</property>
+             <property name="can_focus">True</property>
+             <property name="label">gtk-quit</property>
+             <property name="use_stock">True</property>
+             <property name="relief">GTK_RELIEF_NORMAL</property>
+             <property name="focus_on_click">True</property>
+             <signal name="clicked" handler="on_btn_salir_clicked" last_modification_time="Thu, 27 Oct 2005 23:58:13 GMT"/>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="GtkButton" id="btn_recibir">
+             <property name="visible">True</property>
+             <property name="can_default">True</property>
+             <property name="can_focus">True</property>
+             <property name="relief">GTK_RELIEF_NORMAL</property>
+             <property name="focus_on_click">True</property>
+             <signal name="clicked" handler="on_btn_recibir_clicked" last_modification_time="Thu, 27 Oct 2005 23:58:03 GMT"/>
+
+             <child>
+               <widget class="GtkAlignment" id="alignment1">
+                 <property name="visible">True</property>
+                 <property name="xalign">0.5</property>
+                 <property name="yalign">0.5</property>
+                 <property name="xscale">0</property>
+                 <property name="yscale">0</property>
+                 <property name="top_padding">0</property>
+                 <property name="bottom_padding">0</property>
+                 <property name="left_padding">0</property>
+                 <property name="right_padding">0</property>
+
+                 <child>
+                   <widget class="GtkHBox" id="hbox1">
+                     <property name="visible">True</property>
+                     <property name="homogeneous">False</property>
+                     <property name="spacing">2</property>
+
+                     <child>
+                       <widget class="GtkImage" id="image1">
+                         <property name="visible">True</property>
+                         <property name="stock">gtk-go-down</property>
+                         <property name="icon_size">4</property>
+                         <property name="xalign">0.5</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">False</property>
+                         <property name="fill">False</property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label1">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">_Recibir</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0.5</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">False</property>
+                         <property name="fill">False</property>
+                       </packing>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+         </child>
+
+         <child>
+           <widget class="GtkButton" id="btn_enviar">
+             <property name="visible">True</property>
+             <property name="can_default">True</property>
+             <property name="can_focus">True</property>
+             <property name="relief">GTK_RELIEF_NORMAL</property>
+             <property name="focus_on_click">True</property>
+             <signal name="clicked" handler="on_btn_enviar_clicked" last_modification_time="Thu, 27 Oct 2005 23:58:08 GMT"/>
+
+             <child>
+               <widget class="GtkAlignment" id="alignment2">
+                 <property name="visible">True</property>
+                 <property name="xalign">0.5</property>
+                 <property name="yalign">0.5</property>
+                 <property name="xscale">0</property>
+                 <property name="yscale">0</property>
+                 <property name="top_padding">0</property>
+                 <property name="bottom_padding">0</property>
+                 <property name="left_padding">0</property>
+                 <property name="right_padding">0</property>
+
+                 <child>
+                   <widget class="GtkHBox" id="hbox2">
+                     <property name="visible">True</property>
+                     <property name="homogeneous">False</property>
+                     <property name="spacing">2</property>
+
+                     <child>
+                       <widget class="GtkImage" id="image2">
+                         <property name="visible">True</property>
+                         <property name="stock">gtk-go-up</property>
+                         <property name="icon_size">4</property>
+                         <property name="xalign">0.5</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">False</property>
+                         <property name="fill">False</property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label2">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">_Enviar</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0.5</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">False</property>
+                         <property name="fill">False</property>
+                       </packing>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">True</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/cliente/etherled.py b/cliente/etherled.py
new file mode 100755 (executable)
index 0000000..d766768
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+# vim: set expandtab tabstop=4 shiftwidth=4 :
+#----------------------------------------------------------------------------
+#                               Etherled
+#----------------------------------------------------------------------------
+# This file is part of etherled.
+#
+# etherled 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.
+#
+# etherled 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 etherled; if not, write to the Free Software Foundation, Inc., 59
+# Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#----------------------------------------------------------------------------
+# Creado:  vie oct 27 22:16:20 ART 2005
+# Autores: Leandro Lucarella <llucare@fi.uba.ar>
+#----------------------------------------------------------------------------
+
+import os
+import gtk
+from simplegladeapp import SimpleGladeApp
+from simplegladeapp import bindtextdomain
+from dispatcher import Dispatcher
+from led import Led
+
+app_name = "etherled"
+app_version = "1.0"
+glade_dir = ""
+locale_dir = ""
+
+bindtextdomain(app_name, locale_dir)
+
+
+class MainWindow(SimpleGladeApp):
+
+    def __init__(self, path="etherled.glade", root="main_window",
+            domain=app_name, **kwargs):
+        #notificar = Dispatcher(self.actualizar)
+        path = os.path.join(glade_dir, path)
+        SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
+
+    def new(self):
+        for i in xrange(16):
+            for j in xrange(16):
+                led = Led()
+                self.table_leds.attach(led, i, i+1, j, j+1)
+                led.show()
+
+    def on_btn_salir_clicked(self, widget, *args):
+        self.quit()
+
+    def on_main_window_delete_event(self, widget, event, *args):
+        self.quit()
+
+
+
+def main():
+    gtk.threads_init()
+    main_window = MainWindow()
+    gtk.threads_enter()
+    main_window.run()
+    gtk.threads_leave()
+
+
+if __name__ == '__main__':
+    main()
+
diff --git a/cliente/led-off.png b/cliente/led-off.png
new file mode 100644 (file)
index 0000000..c1fa097
Binary files /dev/null and b/cliente/led-off.png differ
diff --git a/cliente/led-on.png b/cliente/led-on.png
new file mode 100644 (file)
index 0000000..97b033c
Binary files /dev/null and b/cliente/led-on.png differ
diff --git a/cliente/led.py b/cliente/led.py
new file mode 100644 (file)
index 0000000..6bc338a
--- /dev/null
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-1 -*-
+# vim: set expandtab tabstop=4 shiftwidth=4 :
+#----------------------------------------------------------------------------
+#                               Etherled
+#----------------------------------------------------------------------------
+# This file is part of etherled.
+#
+# etherled 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.
+#
+# etherled 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 etherled; if not, write to the Free Software Foundation, Inc., 59
+# Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#----------------------------------------------------------------------------
+# Creado:  vie oct 27 23:36:22 ART 2005
+# Autores: Leandro Lucarella <llucare@fi.uba.ar>
+#----------------------------------------------------------------------------
+
+import gtk
+
+class Led(gtk.DrawingArea):
+       def __init__(self, prendido=False, file_on='led-on.png',
+                       file_off='led-off.png', width = 24, height = 24):
+               self.prendido = prendido
+               self.width = width
+               self.height = height
+               self.pixbuf_on = gtk.gdk.pixbuf_new_from_file(file_on)
+               self.pixbuf_off = gtk.gdk.pixbuf_new_from_file(file_off)
+               gtk.DrawingArea.__init__(self)
+               self.set_size_request(width, height)
+               self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
+               self.connect("expose-event", self.on_expose_event)
+               self.connect("button-press-event", self.on_button_press_event)
+
+       def on_expose_event(self, widget, event):
+               gc = self.style.fg_gc[gtk.STATE_NORMAL]
+               if self.prendido:
+                       pixbuf = self.pixbuf_on
+               else:
+                       pixbuf = self.pixbuf_off
+               self.window.draw_pixbuf(gc, pixbuf, 0, 0, 0, 0)
+               return False
+
+       def on_button_press_event(self, widget, event):
+               self.prendido = not self.prendido
+               self.queue_draw()
+
diff --git a/cliente/simplegladeapp.py b/cliente/simplegladeapp.py
new file mode 100644 (file)
index 0000000..90c598c
--- /dev/null
@@ -0,0 +1,341 @@
+"""
+ SimpleGladeApp.py
+ Module that provides an object oriented abstraction to pygtk and libglade.
+ Copyright (C) 2004 Sandino Flores Moreno
+"""
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+
+import os
+import sys
+import re
+
+import tokenize
+import gtk
+import gtk.glade
+import weakref
+import inspect
+
+__version__ = "1.0"
+__author__ = 'Sandino "tigrux" Flores-Moreno'
+
+def bindtextdomain(app_name, locale_dir=None):
+    """    
+    Bind the domain represented by app_name to the locale directory locale_dir.
+    It has the effect of loading translations, enabling applications for different
+    languages.
+
+    app_name:
+        a domain to look for translations, tipically the name of an application.
+
+    locale_dir:
+        a directory with locales like locale_dir/lang_isocode/LC_MESSAGES/app_name.mo
+        If omitted or None, then the current binding for app_name is used.
+    """    
+    try:
+        import locale
+        import gettext
+        locale.setlocale(locale.LC_ALL, "")
+        gtk.glade.bindtextdomain(app_name, locale_dir)
+        gettext.install(app_name, locale_dir, unicode=1)
+    except (IOError,locale.Error), e:
+        print "Warning", app_name, e
+        __builtins__.__dict__["_"] = lambda x : x
+
+
+class SimpleGladeApp:
+
+    def __init__(self, path, root=None, domain=None, **kwargs):
+        """
+        Load a glade file specified by glade_filename, using root as
+        root widget and domain as the domain for translations.
+
+        If it receives extra named arguments (argname=value), then they are used
+        as attributes of the instance.
+
+        path:
+            path to a glade filename.
+            If glade_filename cannot be found, then it will be searched in the
+            same directory of the program (sys.argv[0])
+
+        root:
+            the name of the widget that is the root of the user interface,
+            usually a window or dialog (a top level widget).
+            If None or ommited, the full user interface is loaded.
+
+        domain:
+            A domain to use for loading translations.
+            If None or ommited, no translation is loaded.
+
+        **kwargs:
+            a dictionary representing the named extra arguments.
+            It is useful to set attributes of new instances, for example:
+                glade_app = SimpleGladeApp("ui.glade", foo="some value", bar="another value")
+            sets two attributes (foo and bar) to glade_app.
+        """        
+        if os.path.isfile(path):
+            self.glade_path = path
+        else:
+            glade_dir = os.path.dirname( sys.argv[0] )
+            self.glade_path = os.path.join(glade_dir, path)
+        for key, value in kwargs.items():
+            try:
+                setattr(self, key, weakref.proxy(value) )
+            except TypeError:
+                setattr(self, key, value)
+        self.glade = None
+        self.install_custom_handler(self.custom_handler)
+        self.glade = self.create_glade(self.glade_path, root, domain)
+        if root:
+            self.main_widget = self.get_widget(root)
+        else:
+            self.main_widget = None
+        self.normalize_names()
+        self.add_callbacks(self)
+        self.new()
+
+    def __repr__(self):
+        class_name = self.__class__.__name__
+        if self.main_widget:
+            root = gtk.Widget.get_name(self.main_widget)
+            repr = '%s(path="%s", root="%s")' % (class_name, self.glade_path, root)
+        else:
+            repr = '%s(path="%s")' % (class_name, self.glade_path)
+        return repr
+
+    def new(self):
+        """
+        Method called when the user interface is loaded and ready to be used.
+        At this moment, the widgets are loaded and can be refered as self.widget_name
+        """
+        pass
+
+    def add_callbacks(self, callbacks_proxy):
+        """
+        It uses the methods of callbacks_proxy as callbacks.
+        The callbacks are specified by using:
+            Properties window -> Signals tab
+            in glade-2 (or any other gui designer like gazpacho).
+
+        Methods of classes inheriting from SimpleGladeApp are used as
+        callbacks automatically.
+
+        callbacks_proxy:
+            an instance with methods as code of callbacks.
+            It means it has methods like on_button1_clicked, on_entry1_activate, etc.
+        """        
+        self.glade.signal_autoconnect(callbacks_proxy)
+
+    def normalize_names(self):
+        """
+        It is internally used to normalize the name of the widgets.
+        It means a widget named foo:vbox-dialog in glade
+        is refered self.vbox_dialog in the code.
+
+        It also sets a data "prefixes" with the list of
+        prefixes a widget has for each widget.
+        """
+        for widget in self.get_widgets():
+            widget_name = gtk.Widget.get_name(widget)
+            prefixes_name_l = widget_name.split(":")
+            prefixes = prefixes_name_l[ : -1]
+            widget_api_name = prefixes_name_l[-1]
+            widget_api_name = "_".join( re.findall(tokenize.Name, widget_api_name) )
+            gtk.Widget.set_name(widget, widget_api_name)
+            if hasattr(self, widget_api_name):
+                raise AttributeError("instance %s already has an attribute %s" % (self,widget_api_name))
+            else:
+                setattr(self, widget_api_name, widget)
+                if prefixes:
+                    gtk.Widget.set_data(widget, "prefixes", prefixes)
+
+    def add_prefix_actions(self, prefix_actions_proxy):
+        """
+        By using a gui designer (glade-2, gazpacho, etc)
+        widgets can have a prefix in theirs names
+        like foo:entry1 or foo:label3
+        It means entry1 and label3 has a prefix action named foo.
+
+        Then, prefix_actions_proxy must have a method named prefix_foo which
+        is called everytime a widget with prefix foo is found, using the found widget
+        as argument.
+
+        prefix_actions_proxy:
+            An instance with methods as prefix actions.
+            It means it has methods like prefix_foo, prefix_bar, etc.
+        """        
+        prefix_s = "prefix_"
+        prefix_pos = len(prefix_s)
+
+        is_method = lambda t : callable( t[1] )
+        is_prefix_action = lambda t : t[0].startswith(prefix_s)
+        drop_prefix = lambda (k,w): (k[prefix_pos:],w)
+
+        members_t = inspect.getmembers(prefix_actions_proxy)
+        methods_t = filter(is_method, members_t)
+        prefix_actions_t = filter(is_prefix_action, methods_t)
+        prefix_actions_d = dict( map(drop_prefix, prefix_actions_t) )
+
+        for widget in self.get_widgets():
+            prefixes = gtk.Widget.get_data(widget, "prefixes")
+            if prefixes:
+                for prefix in prefixes:
+                    if prefix in prefix_actions_d:
+                        prefix_action = prefix_actions_d[prefix]
+                        prefix_action(widget)
+
+    def custom_handler(self,
+            glade, function_name, widget_name,
+            str1, str2, int1, int2):
+        """
+        Generic handler for creating custom widgets, internally used to
+        enable custom widgets (custom widgets of glade).
+
+        The custom widgets have a creation function specified in design time.
+        Those creation functions are always called with str1,str2,int1,int2 as
+        arguments, that are values specified in design time.
+
+        Methods of classes inheriting from SimpleGladeApp are used as
+        creation functions automatically.
+
+        If a custom widget has create_foo as creation function, then the
+        method named create_foo is called with str1,str2,int1,int2 as arguments.
+        """
+        try:
+            handler = getattr(self, function_name)
+            return handler(str1, str2, int1, int2)
+        except AttributeError:
+            return None
+
+    def gtk_widget_show(self, widget, *args):
+        """
+        Predefined callback.
+        The widget is showed.
+        Equivalent to widget.show()
+        """
+        widget.show()
+
+    def gtk_widget_hide(self, widget, *args):
+        """
+        Predefined callback.
+        The widget is hidden.
+        Equivalent to widget.hide()
+        """
+        widget.hide()
+
+    def gtk_widget_grab_focus(self, widget, *args):
+        """
+        Predefined callback.
+        The widget grabs the focus.
+        Equivalent to widget.grab_focus()
+        """
+        widget.grab_focus()
+
+    def gtk_widget_destroy(self, widget, *args):
+        """
+        Predefined callback.
+        The widget is destroyed.
+        Equivalent to widget.destroy()
+        """
+        widget.destroy()
+
+    def gtk_window_activate_default(self, window, *args):
+        """
+        Predefined callback.
+        The default widget of the window is activated.
+        Equivalent to window.activate_default()
+        """
+        widget.activate_default()
+
+    def gtk_true(self, *args):
+        """
+        Predefined callback.
+        Equivalent to return True in a callback.
+        Useful for stopping propagation of signals.
+        """
+        return True
+
+    def gtk_false(self, *args):
+        """
+        Predefined callback.
+        Equivalent to return False in a callback.
+        """
+        return False
+
+    def gtk_main_quit(self, *args):
+        """
+        Predefined callback.
+        Equivalent to self.quit()
+        """
+        self.quit()
+
+    def main(self):
+        """
+        Starts the main loop of processing events.
+        The default implementation calls gtk.main()
+
+        Useful for applications that needs a non gtk main loop.
+        For example, applications based on gstreamer needs to override
+        this method with gst.main()
+
+        Do not directly call this method in your programs.
+        Use the method run() instead.
+        """
+        gtk.main()
+
+    def quit(self):
+        """
+        Quit processing events.
+        The default implementation calls gtk.main_quit()
+        
+        Useful for applications that needs a non gtk main loop.
+        For example, applications based on gstreamer needs to override
+        this method with gst.main_quit()
+        """
+        gtk.main_quit()
+
+    def run(self):
+        """
+        Starts the main loop of processing events checking for Control-C.
+
+        The default implementation checks wheter a Control-C is pressed,
+        then calls on_keyboard_interrupt().
+
+        Use this method for starting programs.
+        """
+        try:
+            self.main()
+        except KeyboardInterrupt:
+            self.on_keyboard_interrupt()
+
+    def on_keyboard_interrupt(self):
+        """
+        This method is called by the default implementation of run()
+        after a program is finished by pressing Control-C.
+        """
+        pass
+
+    def install_custom_handler(self, custom_handler):
+        gtk.glade.set_custom_handler(custom_handler)
+
+    def create_glade(self, glade_path, root, domain):
+        return gtk.glade.XML(self.glade_path, root, domain)
+
+    def get_widget(self, widget_name):
+        return self.glade.get_widget(widget_name)
+
+    def get_widgets(self):
+        return self.glade.get_widget_prefix("")        
diff --git a/cliente/svg/led-off.svg b/cliente/svg/led-off.svg
new file mode 100644 (file)
index 0000000..2c4c69b
--- /dev/null
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.34"
+   inkscape:version="0.42.2"
+   sodipodi:docbase="/home/luca/facultad/66.09/proyecto/cliente/"
+   sodipodi:docname="/home/luca/facultad/66.09/proyecto/cliente/led-off.svg">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient2364">
+      <stop
+         style="stop-color:#646464;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2366" />
+      <stop
+         id="stop2372"
+         offset="0.34999999"
+         style="stop-color:#b65953;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#641e1e;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2368" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2314">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2316" />
+      <stop
+         id="stop2362"
+         offset="0.34999999"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2318" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2267">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2269" />
+      <stop
+         id="stop2275"
+         offset="0.34999999"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2271" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2255">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2257" />
+      <stop
+         id="stop2265"
+         offset="0.40983605"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2259" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2231">
+      <stop
+         style="stop-color:#e6cccc;stop-opacity:0;"
+         offset="0"
+         id="stop2233" />
+      <stop
+         id="stop2277"
+         offset="1"
+         style="stop-color:#a69999;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2210">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2212" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2214" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2146">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2148" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop2150" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2116">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2118" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2120" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2152"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.802632,0.000000,0.000000,0.802632,17.41071,51.71150)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2210"
+       id="radialGradient2216"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.802632,0.000000,0.000000,0.802632,40.24905,58.05549)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2229"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.575472,0.000000,0.000000,0.575472,71.65432,122.8727)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2231"
+       id="radialGradient2237"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-1.637459,-1.819398)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.616162,0.000000,0.000000,0.616162,64.05482,112.5156)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2267"
+       id="radialGradient2273"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2314"
+       id="radialGradient2320"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.148741,0.000000,0.000000,1.148741,-32.77391,-46.41704)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2267"
+       id="radialGradient2338"
+       gradientUnits="userSpaceOnUse"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2340"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.616162,0.000000,0.000000,0.616162,64.05482,112.5156)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2231"
+       id="radialGradient2342"
+       gradientUnits="userSpaceOnUse"
+       cx="212.087921"
+       cy="302.130371"
+       fx="212.087921"
+       fy="302.130371"
+       r="10.1285906"
+       gradientTransform="translate(-2.745055e-7,-2.031269e-5)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2344"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.575472,0.000000,0.000000,0.575472,71.65432,122.8727)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2364"
+       id="radialGradient2370"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.7065368"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-2.001347,-2.183287)" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6000000"
+     inkscape:cx="224.25711"
+     inkscape:cy="759.22290"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1086"
+     inkscape:window-height="820"
+     inkscape:window-x="0"
+     inkscape:window-y="19" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <path
+     transform="matrix(33.78688,0,0,33.78687,-6833.881,-9785.124)"
+     d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+     sodipodi:ry="9.6428576"
+     sodipodi:rx="9.6428576"
+     sodipodi:cy="303.79074"
+     sodipodi:cx="213.57143"
+     id="path1379"
+     style="font-size:12;fill:#ffbfbf;stroke:#000000;stroke-width:0.625;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:0;fill-opacity:1;"
+     sodipodi:type="arc" />
+  <path
+     transform="matrix(30.97132,0,0,30.97131,-6301.94,-9005.201)"
+     d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+     sodipodi:ry="9.6428576"
+     sodipodi:rx="9.6428576"
+     sodipodi:cy="303.79074"
+     sodipodi:cx="213.57143"
+     id="path2126"
+     style="font-size:12;fill:url(#radialGradient2338);stroke:url(#radialGradient2340);stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:0;"
+     sodipodi:type="arc" />
+  <path
+     transform="matrix(33.16122,0,0,33.16121,-6697.587,-9595.05)"
+     d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+     sodipodi:ry="9.6428576"
+     sodipodi:rx="9.6428576"
+     sodipodi:cy="303.79074"
+     sodipodi:cx="213.57143"
+     id="path2225"
+     style="font-size:12;fill:url(#radialGradient2342);stroke:url(#radialGradient2344);stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:0;"
+     sodipodi:type="arc" />
+</svg>
diff --git a/cliente/svg/led-on.svg b/cliente/svg/led-on.svg
new file mode 100644 (file)
index 0000000..728862a
--- /dev/null
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.34"
+   inkscape:version="0.42.2"
+   sodipodi:docbase="/home/luca/facultad/66.09/proyecto/cliente"
+   sodipodi:docname="/home/luca/facultad/66.09/proyecto/cliente/led-on.svg">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient2364">
+      <stop
+         style="stop-color:#646464;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2366" />
+      <stop
+         id="stop2372"
+         offset="0.34999999"
+         style="stop-color:#b65953;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#641e1e;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2368" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2314">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2316" />
+      <stop
+         id="stop2362"
+         offset="0.34999999"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2318" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2267">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2269" />
+      <stop
+         id="stop2275"
+         offset="0.34999999"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2271" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2255">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2257" />
+      <stop
+         id="stop2265"
+         offset="0.40983605"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2259" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2231">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2233" />
+      <stop
+         id="stop2277"
+         offset="0.34426230"
+         style="stop-color:#ff3324;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#6d0000;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2235" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2210">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2212" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2214" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2146">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2148" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop2150" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2116">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2118" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2120" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2152"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.802632,0.000000,0.000000,0.802632,17.41071,51.71150)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2210"
+       id="radialGradient2216"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.802632,0.000000,0.000000,0.802632,40.24905,58.05549)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2229"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.575472,0.000000,0.000000,0.575472,71.65432,122.8727)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2231"
+       id="radialGradient2237"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-1.637459,-1.819398)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.616162,0.000000,0.000000,0.616162,64.05482,112.5156)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2267"
+       id="radialGradient2273"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2314"
+       id="radialGradient2320"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.148741,0.000000,0.000000,1.148741,-32.77391,-46.41704)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2267"
+       id="radialGradient2338"
+       gradientUnits="userSpaceOnUse"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2340"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.616162,0.000000,0.000000,0.616162,64.05482,112.5156)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2231"
+       id="radialGradient2342"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-1.637459,-1.819398)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2344"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.575472,0.000000,0.000000,0.575472,71.65432,122.8727)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2364"
+       id="radialGradient2370"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.7065368"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-2.001347,-2.183287)" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6000000"
+     inkscape:cx="224.25711"
+     inkscape:cy="759.22290"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1086"
+     inkscape:window-height="820"
+     inkscape:window-x="0"
+     inkscape:window-y="19" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="g2349"
+     transform="matrix(33.78688,0,0,33.78687,-6845.948,-9791.157)"
+     style="font-size:12;">
+    <path
+       transform="translate(0.357143,0.178571)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path1379"
+       style="opacity:1.0000000;fill:#ec0000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-width:0.62500000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.916667,0.000000,0.000000,0.916667,16.10116,23.26218)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path2126"
+       style="opacity:1.0000000;fill:url(#radialGradient2338);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient2340);stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.981482,0.000000,0.000000,0.981482,4.490676,5.804250)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path2225"
+       style="opacity:1.0000000;fill:url(#radialGradient2342);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient2344);stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+  </g>
+</svg>
diff --git a/cliente/svg/leds.svg b/cliente/svg/leds.svg
new file mode 100644 (file)
index 0000000..35c8f7e
--- /dev/null
@@ -0,0 +1,361 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.34"
+   inkscape:version="0.42.2"
+   sodipodi:docbase="/home/luca/facultad/66.09/proyecto/cliente/"
+   sodipodi:docname="/home/luca/facultad/66.09/proyecto/cliente/leds.svg">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient2364">
+      <stop
+         style="stop-color:#646464;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2366" />
+      <stop
+         id="stop2372"
+         offset="0.34999999"
+         style="stop-color:#b65953;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#641e1e;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2368" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2314">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2316" />
+      <stop
+         id="stop2362"
+         offset="0.34999999"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2318" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2267">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2269" />
+      <stop
+         id="stop2275"
+         offset="0.34999999"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2271" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2255">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2257" />
+      <stop
+         id="stop2265"
+         offset="0.40983605"
+         style="stop-color:#ffffff;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2259" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2231">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2233" />
+      <stop
+         id="stop2277"
+         offset="0.34426230"
+         style="stop-color:#ff3324;stop-opacity:0.49803922;" />
+      <stop
+         style="stop-color:#6d0000;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2235" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2210">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop2212" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop2214" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2146">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2148" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop2150" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2116">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.0000000;"
+         offset="0.0000000"
+         id="stop2118" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1.0000000;"
+         offset="1.0000000"
+         id="stop2120" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2152"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.802632,0.000000,0.000000,0.802632,17.41071,51.71150)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2210"
+       id="radialGradient2216"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.802632,0.000000,0.000000,0.802632,40.24905,58.05549)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2229"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.575472,0.000000,0.000000,0.575472,71.65432,122.8727)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2231"
+       id="radialGradient2237"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-1.637459,-1.819398)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2245"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.616162,0.000000,0.000000,0.616162,64.05482,112.5156)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2267"
+       id="radialGradient2273"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2314"
+       id="radialGradient2320"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.148741,0.000000,0.000000,1.148741,-32.77391,-46.41704)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2267"
+       id="radialGradient2338"
+       gradientUnits="userSpaceOnUse"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2340"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.616162,0.000000,0.000000,0.616162,64.05482,112.5156)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2231"
+       id="radialGradient2342"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-1.637459,-1.819398)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2146"
+       id="radialGradient2344"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.575472,0.000000,0.000000,0.575472,71.65432,122.8727)"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.6428576" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2364"
+       id="radialGradient2370"
+       cx="213.57143"
+       cy="303.79074"
+       fx="213.57143"
+       fy="303.79074"
+       r="9.7065368"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-2.001347,-2.183287)" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.6000000"
+     inkscape:cx="224.25711"
+     inkscape:cy="759.22290"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1086"
+     inkscape:window-height="820"
+     inkscape:window-x="0"
+     inkscape:window-y="19" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="g2349"
+     style="font-size:12;"
+     transform="matrix(16.7391,0,0,16.5948,-3211.135,-4714.47)">
+    <path
+       transform="translate(0.357143,0.178571)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path1379"
+       style="opacity:1.0000000;fill:#ec0000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-width:0.62500000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.916667,0.000000,0.000000,0.916667,16.10116,23.26218)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path2126"
+       style="opacity:1.0000000;fill:url(#radialGradient2338);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient2340);stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.981482,0.000000,0.000000,0.981482,4.490676,5.804250)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path2225"
+       style="opacity:1.0000000;fill:url(#radialGradient2342);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient2344);stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+  </g>
+  <g
+     id="g2374"
+     style="font-size:12;"
+     transform="matrix(17.82407,0,0,17.82407,-3987.231,-4912.303)">
+    <path
+       transform="translate(30.29016,17.70093)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path2284"
+       style="opacity:1.0000000;fill:#969696;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-width:0.62500000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.797975,0.000000,0.000000,0.797975,72.18696,77.82418)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path2286"
+       style="opacity:1.0000000;fill:url(#radialGradient2320);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.981482,0.000000,0.000000,0.981482,34.24514,23.32660)"
+       d="M 223.2143 303.7907 A 9.642858 9.642858 0 1 0 203.9286 303.7907 A 9.642858 9.642858 0 1 0  223.2143 303.7907 z"
+       sodipodi:ry="9.6428576"
+       sodipodi:rx="9.6428576"
+       sodipodi:cy="303.79074"
+       sodipodi:cx="213.57143"
+       id="path2288"
+       style="opacity:1.0000000;fill:url(#radialGradient2370);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-width:0.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000"
+       sodipodi:type="arc" />
+  </g>
+</svg>