\section{Interfaces gráficas con Mono}
	\subsection{Introducción a la programación de interfaces gráficas con Mono}
		\subsubsection{Introducción}
			\begin{itemize}
				\item Mono puede utilizar \href{http://www.mono-project.com/Gui_Toolkits}{varias} librerías de widgets:
				\begin{itemize}
					\item GTK\#. Es la más utilizada y la única que se cubrirá en el cursillo. Es la única que el Proyecto Mono mantiene de manera directa
					\item wx.NET
					\item Windows Forms
					\item Cocoa\#
					\item QT\#
					\item Sharp WT
				\end{itemize}
			\end{itemize}
		\newpage
		\subsubsection{wx.NET}
			\begin{itemize}
				\item \href{http://wxnet.sourceforge.net/}{wx.NET} es un wrapper para la \texttt{CLI} de \href{http://www.wxwidgets.org/}{wxWidgets}
				\begin{itemize}
					\item wxWidgets es una librería de widgets cuya finalidad es proveer un API sencillo para crear GUIs en múltiples plataformas, utilizando el UI nativo de cada plataforma:
					\begin{itemize}
						\item \href{http://www.wxwidgets.org/faqgen.htm#platforms}{Utiliza} librerías nativas en cada plataforma (ya sea Windows, GTK para GNU/Linux, etc. etc. \ldots)
					\end{itemize}
					\item Se puede ver en los \href{http://wxnet.sourceforge.net/screenshots/}{screenshots}.
				\end{itemize}
			\end{itemize}
		\newpage
		\subsubsection{Windows Forms}
			\begin{itemize}
				\item \href{http://www.mono-project.com/WinForms}{Windows Forms} es la librería de Widgets que viene por defecto en Microsoft .NET
				\item Su especificación no está recogida como estándar en el ECMA o ISO
				\item A pesar de ello, está siendo implementada para Mono (\href{http://svn.myrealbox.com/mwf/class-status-System.Windows.Forms.html}{Aquí} está su estado actual)
				\item Mono está tardando más en implementar Windows Forms que \href{http://www.dotgnu.org}{DotGNU}:
				\begin{enumerate}
					\item Se intentó utilizando implementar Windows Forms encima de Gtk
					\item Se intentó más tarde implementarlo encima de Wine
					\item Finalmente, se está desarrollando trabajando encima de la implementación de System.Drawing, la cual
					\begin{itemize}
						\item en Windows utiliza GDI+
						\item en otros sistemas utiliza la implementación de Mono de gdiplus, que está implementada sobre Cairo
					\end{itemize}
				\end{enumerate}
			\end{itemize}
			\begin{center}
				\includegraphics{figuras/winforms.png}
				~\\
				\emph{Código en /interfacesGraficas/winforms/Samples}
				~\\
				Código sacado del \href{http://svn.myrealbox.com/viewcvs/trunk/old-code/mcs-class-System.Windows.Forms/Samples/}{svn de Mono}
			\end{center}
	\subsection{La familia GTK\#}
		\subsubsection{Introducción}
			\begin{itemize}
				\item \href{http://gtk-sharp.sourceforge.net/}{GTK\#} es el binding para Mono de las populares \href{http://www.gtk.org}{GTK+} (Gimp Tool Kit)
				\begin{itemize}
					\item Con diferencia la librería de widgets más usada en Mono
				\end{itemize}
				\item Intimamente ligada al proyecto \href{http://www.gnome.org/}{Gnome}
				\item En el svn de gtk-sharp tenemos disponible \texttt{GtkDemo}, en el que vemos
				\begin{itemize}
					\item ejemplos interesantes de uso de Gtk\#
					\item tanto el código para ver cómo se hace como el propio widget en funcionamiento
				\end{itemize}
			\end{itemize}
			\newpage
			\begin{center}
				\includegraphics[scale=0.78]{figuras/GtkDemo.png}
				\small GtkDemo en acción
			\end{center}
		\newpage
		\subsubsection{Comenzando con GTK\#: el bucle de eventos}
			\begin{itemize}
				\item Antes de instanciar nada de GTK\# debemos llamar a:
				\begin{verbatim}
					Application.Init()
				\end{verbatim}
				\item Después iniciaremos lo que necesitemos (iniciar el GUI)
				\item Una vez iniciado todo, para pasar a visualizarlo, llamaremos a:
				\begin{verbatim}
					Application.Run()
				\end{verbatim}
				\item En ese momento Gtk pasará a procesar todo
				\begin{itemize}
					\item No continuará la ejecución después de esa función
					\item Cada vez que Gtk reciba un evento, llamará al \textit{callback} correspondiente
					\begin{itemize}
						\item Mientras está procesando el \textit{callback} de un evento
						\begin{itemize}
							\item no puede procesar otro evento
							\item no se redibujan los widgets, etc
						\end{itemize}
					\end{itemize}
				\end{itemize}
				\item Este proceso finalizará cuando se llame a:
				\begin{verbatim}
					Application.Quit()
				\end{verbatim}
				\item \emph{Ejemplo: interfacesGraficas/gtk/eventloop/holamundo.cs}
			\end{itemize}
		\newpage
		\subsubsection{Nuestra primera ventana}
			\begin{itemize}
				\item Primero creamos una ventana (\texttt{Gtk.Window}):
				\begin{verbatim}
					Window w = new Window("titulo");
				\end{verbatim}
				\item La clase Window tiene una serie de métodos para modificar su relación con el Window Manager, como por ejemplo:
				\begin{itemize}
					\item \texttt{void Fullscreen()}: Hace que la ventana ocupe la pantalla completa
					\item \texttt{void Maximize()}: Maximiza la ventana
					\item \texttt{void Iconify()}: Minimiza la ventana
					\item \texttt{void Deiconify()}: Vuelve a mostrarse la ventana
				\end{itemize}
				\item Una vez tenemos la ventana, podemos añadir diferentes Widgets, como por ejemplo \texttt{Label}s, \texttt{Button}s\ldots
				\item Los \texttt{string}s en Gtk son especiales
				\begin{itemize}
					\item En labels, se puede utilizar "\texttt{HTML}" (\verb+<+b\verb+>+hola\verb+<+/b\verb+>+)
					\begin{itemize}
						\item Para ello, hay que tener la propiedad \texttt{UseMarkup} a \texttt{true}
						\item Realmente, no es \texttt{HTML}, sino el \texttt{Pango Text Markup Language}. Más información \href{http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html}{aquí}
					\end{itemize}
					\item En menús, un \_ por delante significa que es la letra identificadora (ALT + letra)
					\item etc.
				\end{itemize}
				\item \emph{Ejemplo: interfacesGraficas/gtk/simple/simple.cs}
			\end{itemize}
		\newpage
		\subsubsection{Añadiendo widgets manualmente}
			\begin{itemize}
				\item Para colocar los widgets en una ventana, con GTK\# normalmente utilizas \emph{boxes}.
				\begin{itemize}
					\item Esto es, divides las diferentes áreas de la pantalla en nuevas áreas verticales u horizontales, las cuales a su vez puedes ir dividiendo nuevamente
					\item Esto lo unimos a una serie de propiedades que ajustamos según nos interese
				\end{itemize}
				\item Las \emph{boxes} horizontales son \texttt{Gtk.HBox}, y las verticales \texttt{Gtk.VBox}:
				\begin{verbatim}
					VBox vb = new VBox();
					vb.Add(w1);
					vb.Add(w2);
					vb.Add(w3);
					//...
					algo.Add(vb);
				\end{verbatim}
				dentro del contenedor \texttt{algo}, ponemos el \texttt{Gtk.Widget} \texttt{w1} arriba, justo debajo el \texttt{w2} y justo debajo el \texttt{w3}.
				~\\
				\item Para poner cosas en un punto fijo de un contenedor, se utiliza \texttt{Gtk.Layout}
				\begin{itemize}
					\item El efecto al redimensionar es bastante más feo
				\end{itemize}
				\item \emph{Ejemplo: interfacesGraficas/gtk/boxes/boxes.cs}
			\end{itemize}
		\newpage
		\subsubsection{Glade\#}
			\begin{itemize}
				\item Programar lo anterior está bien para cosas dinámicas y para aprender y entender cómo funciona GTK\#, pero puede
				\begin{itemize}
					\item Cansar
					\item Resultar ser dificil
					\item Añadir código innecesario al programa
				\end{itemize}
				\item Para evitarlo está \href{http://glade.gnome.org/}{Glade}
				\begin{itemize}
					\item Es una herramienta interactiva para diseño de GUIs con GTK+ y Gnome
					\item Guarda en un .glade (XML) el diseño del interfaz gráfico del programa
					\item Dinámicamente cargará el \texttt{.glade} y generará los widgets
					\item Si queremos acceder a un widget concreto, deberemos declarar la variable con el mismo nombre, unida al atributo \texttt{[Widget]}
					\item Además, permite manejar señales, de manera que podemos asignar a qué funciones se llamará para capturar qué señal
				\end{itemize}
				\item \emph{Ejemplo: interfacesGraficas/gtk/glade/usandoGlade.cs}
			\end{itemize}
		\newpage
		\subsubsection{Mostrando imágenes}
			\begin{itemize}
				\item La manera más simple es utilizar un \texttt{Image}:
				\begin{verbatim}
					Window w = new Window("titulo");
					Image img = new Image("ghost.jpg");
					w.Add(img);
				\end{verbatim}
				\item Pero podemos también utilizar GDK\# para ello, accediendo a una API con muchas más funciones
				\begin{verbatim}
					Window w = new Window("titulo");
					//accediendo a un fichero
					Image img = new Image(Gdk.Pixbuf("ghost.jpg"));
					w.Add(img);
				\end{verbatim}
				\item Por ejemplo, para incluirlo en el mismo \texttt{.exe}:
				\begin{verbatim}
					Window w = new Window("titulo");
					//accediendo a un recurso (-res:ghost.jpg)
					Image img = new Image(Gdk.Pixbuf(null,"ghost.jpg"));
					w.Add(img);
				\end{verbatim}
				\item \emph{Ejemplos: interfacesGraficas/gtk/imagenes/imagenes1.cs y imagenes2.cs}
			\end{itemize}
		\newpage
		\subsubsection{Sacando más provecho a Gdk\#}
			\begin{itemize}
				\item GDK es el \texttt{Graphics Development Kit}, que nos permitirá llevar a cabo muchas más cosas
				\begin{itemize}
					\item Sólo hay que echar un vistazo en monodoc al espacio de nombres Gdk para ver la cantidad de posibilidades que nos da
				\end{itemize}
				\item Creando un área para dibujar:
				\begin{verbatim}
					Window w new Window("titulo");
					DrawingArea d = new DrawingArea);
					d.SetSizeRequest(150,150);
					w.Add(d);
				\end{verbatim}
				\item DrawingArea tiene varios eventos heredados de \texttt{Gtk.Widget}, como:
				\begin{itemize}
					\item \texttt{ConfigureEvent}: es llamado cuando se modifica el tamaño del Widget
					\item \texttt{ExposeEvent}: es llamado cuando se tiene que redibujar al menos alguna parte del widget
				\end{itemize}
				\item \emph{Ejemplo: interfacesGraficas/gtk/imagenes/imagenes3.cs}
				\item \emph{Ejercicio: implementar interfacesGraficas/gtk/imagenes/imagenes4.exe}
				\item Mucha más información en las apis \href{http://developer.gnome.org/doc/API/gdk/}{1} y \href{http://developer.gnome.org/doc/API/2.0/gdk/}{2} y la \href{http://en.wikipedia.org/wiki/GDK}{wikipedia}, además de en \texttt{Monodoc}
			\end{itemize}
		\newpage
		\subsubsection{TreeViews}
			\begin{itemize}
				\item Un widget muy usado es el \texttt{TreeView}
				\begin{itemize}
					\item Permite mostrar listas de datos
					\item Permite además mostrar árboles
				\end{itemize}
				\item El \texttt{TreeView} sólo se encarga de lo que es el widget que se ve, no del contenido del mismo
				\item Para el contenido, debe utilizar un \texttt{TreeModal}, como \texttt{ListStore} (para listas) o \texttt{TreeStore} (para árboles)
				\item \emph{Ejemplo ListStore: interfacesGraficas/gtk/listas/lista.cs}
				\item \emph{Ejemplo TreeStore: interfacesGraficas/gtk/arboles/arbol.cs}
			\end{itemize}
		\newpage
		\subsubsection{Manteniéndo nuestra aplicación Gtk thread-safe}
			\begin{itemize}
				\item Mientras se ejecuta el código de respuesta a un evento, el resto de la aplicación queda bloqueada, sin redibujarse
				\item Para evitar este efecto, hay que utilizar hilos:
				\begin{enumerate}
					\item Un evento exige una respuesta
					\item Si la respuesta puede ser larga, se lanza en otro hilo
					\item Desde el otro hilo se va actualizando del interfaz de usuario
				\end{enumerate}
				\item El problema es que GTK\#, al igual que Windows Forms (incluso en la implementación de Microsoft .NET), no es \emph{thread-safe}:
				\begin{itemize}
					\item Si desde otro hilo se modifica el interfaz, el programa puede cascar
				\end{itemize}
				\item Para ello hay que utilizar una clase llamada \texttt{ThreadNotify}, tal que:
				\begin{verbatim}
					ThreadNotify tn = new ThreadNotify(new Gtk.ReadyEvent(metodo));
					Timer tm = new Timer(new
					TimerCallback(metodo2),null,1000,System.Threading.Timeout.Infinite);

					...
					
					void metodo2(object o){
					    tn.WakeupMain(); //hey, GTK#, cuando toque, haz "eso"
					}
					
					void metodo(){
					    web.LoadUrl("http://www.msc.deusto.es"); //"eso" es esto
					}
				\end{verbatim}
				\item \emph{Ejemplo: interfacesGraficas/gtk/hilos/hilos.cs}
				\item \emph{Ejemplo de problemas si eliminamos las medidas de protección: interfacesGraficas/gtk/hilos/mal.cs}
			\end{itemize}
		\newpage
		\subsubsection{Drag and Drop}
			\begin{itemize}
				\item \texttt{Drag and drop} es una técnica de incrementar sustancialmente la usabilidad de un programa y su comunicación con el resto del entorno, de manera sencilla
				\item Para utilizarlo desde Mono basta con declarar en un widget qué \texttt{TargetEntry}s puede recibir y qué \texttt{TargetEntry}s puede enviar
				\begin{itemize}
					\item Un \texttt{Gtk.TargetEntry} define un tipo de dato declarándose tal que:
					\begin{verbatim}
						TargetEntry te = new TargetEntry("text/uri-list",0,0);
					\end{verbatim}
					\item En lugar de \texttt{text/uri}\verb+-+\texttt{list}, podemos enviar y recibir otros muchos tipos de datos, nuestros incluso
				\end{itemize}
				\item Una vez declarado un \texttt{array} de \texttt{TargetEntry}s, se debe declarar el \texttt{Widget} que los puede recibir/enviar, llamando al método:
				\begin{verbatim}
					//para recibir. Para enviar Gtk.Drag.SourceSet
					Gtk.Drag.DestSet(widget,DestDefaults.All,targets,
						Gdk.DragAction.Copy);
				\end{verbatim}
				\item Por último, para poder realizar una acción cuando esto ocurre, hay que definir qué se debe ejecutar cuando ocurre los siguientes eventos:
				\begin{itemize}
					\item Cuando se recibe algo:
					\begin{itemize}
						\item \texttt{DragDataReceived}
					\end{itemize}
					\item Cuando se envía algo:
					\begin{itemize}
						\item \texttt{DragDataGet}
						\item \texttt{DragBegin}
					\end{itemize}
				\end{itemize}
				\item \emph{Ejemplo: interfacesGraficas/gtk/dnd/dnd.cs}
			\end{itemize}
		\newpage
		\subsubsection{Stetic}
			\begin{itemize}
				\item \href{http://www.mono-project.com/Stetic}{Stetic} es un nuevo diseñador de GUIs con GTK
				\begin{itemize}
					\item Integrado en MonoDevelop, con Mono en mente
					\begin{itemize}
						\item El editor de GUI genera un \texttt{xml} (con extensión \texttt{.stetic})
						\item A la hora de construir el proyecto, se generará un \texttt{.cs} que construye el .cs
						\item Genera todo, por lo que no aporta dependencias
						\begin{itemize}
							\item Funciona donde \texttt{gtk-sharp} funcione
							\item La única dependencia es, en caso de que queramos modificar el interfaz, la propia herramienta
						\end{itemize}
						\item No podremos reutilizarlo fuera de Mono
					\end{itemize}
					\item Trae mejoras respecto a glade 2:
					\begin{itemize}
						\item Herramienta en una única ventana que es la de MonoDevelop
						\item Alta integración en MonoDevelop:
						\begin{itemize}
							\item Añado un campo, se añade el tipo de dato \texttt{Gtk\#} en mi código
							\item Añado un evento, se añade el handler correcto en mi código
							\item No tengo que andar poniendo un nombre en el editor y luego el tipo de dato correspondiente a Gtk\# en mi código, o buscar los parámetros del handler correspondiente etc.
						\end{itemize}
						\item Posibilidad de creación de Widgets reutilizables
						\begin{itemize}
							\item Puedo definir un widget (no necesariamente dentro de una ventana)
							\item Puedo definir unos comportamientos y un interfaz externo de ese widget
							\item Puedo utilizar tantas veces como necesite ese widget en diferentes ventanas
						\end{itemize}
					\end{itemize}
				\end{itemize}
			\end{itemize}

	\subsection{Otros componentes gráficos}
		\subsubsection{Druid}
			\begin{itemize}
				\item Para hacer asistentes para pedir información al usuario, está druids
				\item De manera fácil vamos añadiendo páginas al druid, y pidiendo información
				\item Es un componente de gnome\#
				\item \emph{Ejemplo: interfacesGraficas/nome/druids/druids.cs}
			\end{itemize}
		\newpage
		\subsubsection{gecko\#}
			\begin{itemize}
				\item \texttt{Gtk} tiene su propio componente para renderizado de \texttt{HTML} (\texttt{Gtk.HTML})
				\item Sin embargo, este componente no es tan avanzado como \texttt{Gecko} (el motor de \href{http://www.mozilla.org}{Mozilla})
				\item Gecko\# es un componente fácil de usar que permite utilizar la potencia de \texttt{gecko} desde nuestra aplicación Mono
				\item \emph{Ejemplo: interfacesGraficas/gnome/gecko/}
			\end{itemize}

	\subsection{Poniendo todo en orden}
		\begin{itemize}
			\item Hasta aquí hemos visto todo lo que vamos a ver en el cursillo de desarrollo gráfico con mono
			\item Nos hemos centrado únicamente en unas herramientas que existen, y en cómo utilizarlas (por encima) a nivel técnico
			\item Pero a la hora de crear una solución que utilice estas herramientas deberíamos utilizar las \href{http://en.wikipedia.org/wiki/Human_Interface_Guidelines}{HIG} de Gnome
			\begin{itemize}
				\item Human Interface Guidelines
				\item Las de Gnome disponibles \href{http://developer.gnome.org/projects/gup/hig/}{aquí}
				\item Nos indican cómo deberíamos hacer nuestras ventanas, menúes, toolbars, mensajes de aviso y de error\ldots
				\item Basadas en estudios de usabilidad
			\end{itemize}
		\end{itemize}

	\subsection{Otras herramientas}
		\subsubsection{gconf\#}
			\begin{itemize}
				\item GConf\# es un binding para Mono de \href{http://www.gnome.org/projects/gconf/}{GConf}
				\item GConf permite almacenar la configuración de tus aplicaciones en GNU/Linux de una manera centralizada
				\begin{itemize}
					\item Además tiene muchas más características
					\begin{itemize}
						\item Configuración por red
						\item Notificación a las aplicaciones cada vez que se cambia un valor en la configuración
						\item \ldots
					\end{itemize}
					\item en GNU/Linux: no funciona ni en Mac OS X ni en Microsoft Windows
				\end{itemize}
				\item Mucha más información en la \href{http://www.gnome.org/projects/gconf/}{web de GConf}
			\end{itemize}
		\newpage
		\subsubsection{nunit}
			\begin{itemize}
				\item \href{http://www.nunit.org/}{Nunit} es una plataforma libre de tests unitarios para .NET (y Mono)
				\item Permite fácilmente hacer tests con tan sólo poner atributos \texttt{[Test]} a los métodos que queramos que se ejecuten, dentro de clases con atributo \texttt{[TestFixture]}
				\begin{itemize}
					\item A nivel básico: luego ya mirar la docu de \href{http://www.nunit.org/}{su web}
				\end{itemize}
				\item Para llevar a cabo los tests, dos formas:
				\begin{itemize}
					\item En modo consola: \texttt{nunit-console ensamblado}, genera un \texttt{TestResult.xml}
					\item En modo gráfico: desde el add-in de nunit para MonoDevelop :-)
				\end{itemize}
			\end{itemize}
		\newpage
		\subsubsection{I18n con Mono}
			\begin{itemize}
				\item Existen varias formas de llevar a cabo la internacionalización de nuestras aplicaciones
				\begin{itemize}
					\item Por un lado, las APIs de .NET para este propósito (\texttt{System.Globalization}\ldots)
					\item Por otro lado, en Mono.Unix contamos con herramientas basadas en \texttt{gettext} para esta tarea:
					\subitem Más información en la \href{http://www.mono-project.com/Internationalization}{la página de i18n de Mono}
				\end{itemize}
				\item Utilizaremos esta última:
				\begin{itemize}
					\item Creamos nuestro código compilando contra Mono.Posix
					\item Utilizaremos Mono.Unix.Catalog.GetString para los strings que queramos traducir
					\item \texttt{xgettext --from-code=UTF-8 Main.cs -o es.po}
					\item Traducimos el es.po
					\item Creamos el directorio: \texttt{locale/es/LC\_MESSAGES/}
					\item Generamos: \texttt{msgfmt es.po -o locale/es/LC\_MESSAGES/i18n.mo}
				\end{itemize}

			\end{itemize}
