QuickPost: Quitar la decoración de una ventana Cocoa

diciembre 28, 2009

Con este post inaguramos la sección “QuickPost”. Serán entradas muy pequeñas que den solución a problemas concretos.

Normalmente una ventana consta de la barra de titulo (title bar), opcionalmente una barra de scroll ( scroll bar ) y un control para cambiar el tamaño de la ventana ( resize control ) situado en la parte inferior derecha.

Además dentro de la zona de la barra de titulo se muestran diversos botones, que nos sirven para minimizar, maximizar, cerrar o ocultar la barra de herramientas ( tool bar ).

En algunas ocasiones podemos querer mostar una ventana que no tenga todas estas decoraciones. Para ello usaremos el atributo styleMask asociado a la ventana.

Los posibles valores para este atributos se pueden consultar en la referencia, básicamente tenemos:

enum {
    NSBorderlessWindowMask = 0,
    NSTitledWindowMask = 1 << 0,
    NSClosableWindowMask = 1 << 1,
    NSMiniaturizableWindowMask = 1 << 2,
    NSResizableWindowMask = 1 << 3,
    NSTexturedBackgroundWindowMask = 1 << 8
};

Estos valores se pueden sumar usando la operación lógica OR. En nuestro caso, queremos una ventana sin decoración, por lo que usaremos NSBorderlessWindowMask.

Este atributo se lo pasaremos cuando construyamos dicha ventana, usando el método

    initWithContentRect:styleMask:backing:defer:

o bien, usando el método setStyleMask sobre una ventana ya creada, por ejemplo:

- (void)applicationDidFinishLaunching:
                               (NSNotification *)aNotification
{
    [window setStyleMask:NSBorderlessWindowMask];
}

Siendo window una variable ligada a una ventana construida con Interface Builder.


Dashcode, como hacer widgets para OSX

diciembre 20, 2009

Cuando hablamos sobre desarrollo en OSX, raudo y veloz aparece en nuestra mente el nombre de XCode. Si bien es cierto que es la herramienta de referencia ( Sin olvidarnos de Interface Builder, claro), hay otra alternativa para desarrollar software en OSX.

Esta otra manera es mas o menos reciente, y la aplicación que nos va ayudar a crearla se llama Dashcode. La primera versión del sistema operativo de apple en el que podemos usar esta herramienta es en Leopard 10.5, y forma parte del grupo de herramientas para desarrolladores. Actualmente se puede usar Dashcode tanto para crear widgets para el Dashboard como para crear webs personalizadas para el iPhone. Este último dato es lo que lo convierte en una alternativa para desarrollar aplicaciones para el smartphone de apple.

Esta aproximación al desarrollo de aplicaciones para el iPhone tiene como gran punto negativo las limitaciones que impone el que realmente estas desarrollando una aplicacion web, pero pero como puntos positivos tiene el hecho de que no hace falta comprar ninguna licencia para desarrollar, y que la dificultad de desarrollo con respecto a la programación de aplicaciones nativas es bastante mas asequible.

Uno de los aspectos que hacen el desarrollo más sencillo es el lenguaje escogido para desarrollar dichas aplicaciones. HTML + Javascript hacen las veces de Objective-C en Dashcode, nuestros widgets realmente se pueden asemejar a porciones de páginas web. Aún así esta eleccion no nos debe hacer pensar que estamos limitando las posibilidades, pues en el caso de los widgets para el dashboard podremos usar mucha de la funcionalidad que tambien podemos acceder desde una aplicación Cocoa, ya que desde javascript podemos acceder a estos modulos mas cercanos al Sistema Operativo.

Para muestra, un boton, en el siguiente enlace podreis ver algunos de los widgets actuales para dashcode.

Junto con Dashcode se incorpora un montón de componentes “prefabricados” como listas, botones, paneles, que podemos usar en el desarrollo de nuestros widgets.

El propio IDE también nos facilita mucho el trabajo, sin tener mucha idea de como funciona todo podemos realizar ejemplo sencillo en cuestion de minutos. Estas ayudas se traducen en autocompleting de Javascript y HTML, edición gráfica de los widgets, y debugger incluido.

Aunque tampoco debemos dejarnos engañar, como con casi todo, manejar a fondo los componentes ( llamados “parts” ) que se pueden insertar en los widgets lleva su tiempo de aprendizaje.

En general podemos concluir que siendo consciente de sus limitaciones, es una gran alternativa al desarrollo tradicional de aplicaciones.


Incorporar Modelos ManyToMany al Backend en Django

diciembre 10, 2009

Uno de los beneficios de usar django para crear nuestra aplicación web es que como por arte de mágia, todo el backoffice de nuestra aplicación se generará ante nuestros ojos sin tirar ni una linea de código.

Parafraseando a Uderzo y Goscinny, ¿Ni una sola linea?, No, alguna, cual aldea Gala indestructible, habrá que tirar, pero ni mucho menos comparable a lo que sería hacerlo desde cero.

Hasta hace poco, si en nuestro modelo exitía una relación Muchos a Muchos, la edición desde la interfaz de administración no era todo lo intuitiva que esperaríamos, pero en la última versión de django este aspecto esta solucionado, proporcionandonos una flexibilidad absoluta.

Supongamos un modelo de un sencillo bloc de notas, inicialmente tendremos dos entidades, una que será las notas y otra que serán los tags que asociamos a dichas notas. La relación entre los tags y las notas es de Muchos a Muchos, el código de dichos modelos sería algo como:

class Note(models.Model):
  title = models.CharField(max_length=200)
  pub_date = models.DateTimeField('date created')
  body = models.TextField()
  tags = models.ManyToManyField('Tag', related_name='notes')

  def __unicode__(self):
    return self.title</div>

class Tag(models.Model):
  name = models.CharField(max_length=100)

  def __unicode__(self):
    return self.name

Por defecto, django nos genera una interfaz de administración que podemos ver si entramos a la aplicación “admin” una vez lanzado el servidor. Si usamos el servidor de desarrollo, la URL habitual es http://localhost:8000/admin/

Como deciamos anteriormente, en las versiones anteriores de django, solo podíamos editar (y personalizar usando Inlines por ejemplo) los elementos de la clase asociada donde se definía la relacion ManyToMany. En nuestro caso, solo podriamos asociar y añadir tags desde la gestión de notas, pero no viceversa. Al ser una relación bidireccional, como vemos esto no es muy útil.

Para personalizar las interfaces de administración debemos editar el fichero admin.py que esta dentro de nuestro proyecto.

Si queremos que la lista de objetos de la clase asociada aparezca de forma linear, podemos crear un objeto derivado de algun sabor de Inline, como por ejemplo TabularInline. La novedad en la nueva versión de django es que a la clase que modela la relación ManyToMany posee un atributo que representa la asociación.

Este atributo se conoce como through, en versiones anteriores, ese parámetro nos servía para indicar un modelo extendido asociado a la relación muchos a muchos, a la hora de declarar la propia relación en el modelo.

Así si usamos las siguientes clases:

class TagNoteInline(admin.TabularInline):
  model = Note.tags.through

class TagAdmin(admin.ModelAdmin):
  inlines = [
    TagNoteInline,
  ]

class NoteAdmin(admin.ModelAdmin):
  inlines = [
    TagNoteInline,
  ]
  exlude = ('tags',)

admin.site.register(Note, NoteAdmin)
admin.site.register(Tag, TagAdmin)

Podremos editar en ambas interfaces la clase correspondiente asociada.

Para finalizar, si no has entendido nada 😉 quizás te interese el maravilloso tutorial que esta en la propia web del django y concretamente la relacionada con la parte de administración: http://docs.djangoproject.com/en/dev/intro/tutorial02/#intro-tutorial02

Navegadores y futuro de las aplicaciones web

diciembre 3, 2009

Poco a poco nos estamos dando cuenta que el futuro de las aplicaciones apuntan a “la nube”. Google ha apostado por ello con cosas como GMail, Wave o el reciente Chrome OS. Como elemento imprescindible en esta migración, estan los navegadores, los “vehiculos” hacia la nube. Pero, ¿están preparados los navegadores para esta migración?

Cuando la web empezo a ser web, nadie se podía plantear que de aquel lenguaje de marcado derivado del SGML como era el HTML se podría crear todo una plataforma de desarrollo de aplicaciones. Para que esto fuera posible se incorporó un lenguaje que dotara de dinamismo a las, por aquel entonces novedosas, paginas webs. Estamos hablando de ECMAScript, mas conocido con el “desafortunado” nombre Javascript. Desafortunado por su parecido con Java, del que no tiene nada que ver.

Indudablemente se podría hablar mucho de Javascript, como por ejemplo de las primeras implementaciones en los navegadores, de JScript, de su caprichosa sintaxis, etc., pero este, no es el objetivo de esta entrada 😉

Javascript ha sido uno de los grandes “culpables” de que hoy contemplemos como futuro las nuevas aplicaciones web, sin embargo, también ha sido el culpable de muchos quebraderos de cabeza para los desarrolladores de navegadores. Dichos navegadores llevan intentando optimizar el motor que se encarga de interpretar el Javascript desde hace mucho tiempo, sin embargo el desarrollo de dichas aplicaciones ha acelerado mas rápido que la esperada optimización.

Google juega uno de los papeles mas importantes en esta evolución y es muy consciente que a día de hoy, Javascript es un “problema” desde el punto de vista del rendimiento. Uno de los pilares de la presentacion de Chrome fué precisamente un nuevo motor opensource de javascript, el V8. Sin embargo, actúalmente parece que el problema sigue latente.

Además de la nueva implementación de google existen multitud de motores de Javascript, como Rhino de la fundación Mozilla, JavaScriptCore que implementa Safari o Carakan en Opera, pero a vista de los resultados actuales parece que mas de uno sigue sufriendo cuando debe ejecutar una aplicación compleja.

Para darse cuenta de todo esto, solo hace falta escoger un navegador y ponerse a dar vueltas por la aplicación web de moda, Google Wave. Si bien es cierto que la propia aplicación esta en una fase muy previa a considerarse estable, es cierto que el problema también se presenta en otros casos similares como por ejemplo Google Maps, aunque es cierto que de una manera mucho menos acusada. En el caso de Google Wave el problema es tan grave que deja el navegador totalmente inusable, en el caso de navegadores “monoproceso” como firefox, la unica solucion es “matar” al propio navegador.

Para probarlo en nuestras carnes, solo hace falta introducir una busqueda que incluya waves publicos, como por ejemplo introducciendo el texto “rpg with:public” y empezar a navegar por los waves. Rápidamente obtendremos resultados como los de las siguientes imágenes.

Firefox en linux ejecutando wave

Safari en OSX ejecutando wave

Chrome en Windows ejecutando wave

Por tanto a la pregunta del inicio del post, yo de momento tengo que decir, no, los navegadores aún no estan preparados para un salto total a la nube. Y si además introducimos en la ecuación los navegadores de dispositivos menos potentes como smartphones y versiones “light” de chrome o safari, aún la situacion se complica mas.