Intro a Sencha Touch

December 9th, 2010

Sencha Touch es un framework para el desarrollo de aplicaciones mobile centrado en WebKit, Sencha Touch hace uso extensivo de CSS3 para todo lo referente a las animaciones y los styles que por suerte son fácilmente personalizables y mas aun si usan Sass, ya que cambiando el valor de unas cuantas variables podemos modificar totalmente la apariencia de una aplicación, estas características y funcionalidades han sido tremendamente optimizadas para lograr que todo quepa en aproximadamente 80k.

Sencha Touch esta disponible tanto en un versión con licencia comercial como con una licencia Open Source, mas precisamente la GPL v3.

Componentes

Una de las principales ventajas de Sencha Touch es la cantidad de controles que incluye, todos ellos muy fáciles de usar y personalizar.

Touch Events

Sencha Touch incluye los eventos que comúnmente mas se usan en dispositivos touch:

Sencha Touch Events

Layouts

Existe dos conceptos utilizados por Sencha Touch, uno es el de panel, el cual actúa de contenedor de componentes, el otro es el de layout el cual se aplica a un panel y especifica como deben mostrarse lo objetos que se encuentran dentro de el.

Los layouts que incluye Sencha Touch son:

Sencha Touch Layouts

Models, Stores & DataViews

Quizás las características mas poderosas de Sencha Touch son todas aquellas relacionadas con el manejo de datos, por un lado tenemos los Models que nos permiten representar un objeto, las validaciones que se deben aplicar cuando se usa en un formulario y las relaciones que este tiene con otros objetos.

Los Stores son una colección de registros los cuales utilizan un proxy para leer y escribir data, por ultimo los DataView nos permite poblar de data una template con los datos de un Store.

Manos a la obra

En el siguiente ejemplo pueden ver como utilizamos los diferentes elementos antes detallados para crear una simple liste anidada.

index.js
Ext.setup({
    onReady: function() {
        Ext.regModel('Player', {
	    fields: [
		{name : "name"},
		{name : "position"},
		{name : "number"},
		{name : "caps"},
		{name : "age"},
		{name : "picture"}
	    ]
        });

        var itemTemplate = new Ext.XTemplate(
            '<tpl for=".">',
             '{number}',' {name}',
            '</tpl>');
            
        var detailTemplate = new Ext.XTemplate(
            '<div class="detail">',
            	'<img src="{picture}"/><br/>',
                '{number}', ' {name} <br/>',
                'Position: {position} <br/>',
                'Age: {age} ',
                'Caps: {caps} ',
            '</div>'
        );

        var playersStore = new Ext.data.Store({
            model: "Player",
            proxy: {
                type: 'ajax',
                url: 'http://localhost:3000/players.json',
            	reader: {
                	type: 'json',
                	record: 'player'
                }
            },
            autoLoad:true
        });

        var navBar = new Ext.Toolbar({
            itemId: 'navBar',
            ui: 'light',
            dock: 'top',
            items: [
                {
                    text: 'Back',
                    ui: 'back',
                    handler: function(){
                    panel.layout.prev({type: 'slide', direction: 'right'});
                    }
                }
            ]
        });
        
        var detailPanel = new Ext.Panel({
            tpl: detailTemplate,
            dockedItems: [ navBar ]
        });
           
        var showDetail = function(record, btn, index) {
            navBar.setTitle(record.get('name'));
            detailPanel.update(record.data);
            panel.setActiveItem(1);
        }
        
        var listPanel = {
            dockedItems: [
                {
                    title: 'Players',
                    xtype: 'toolbar',
                    ui: 'light',
                    dock: 'top'
                }
            ],
            layout: 'fit',
            scroll: 'vertical',
            items: [
                {
                    xtype: 'list',
                    store: playersStore,
                    itemTpl:itemTemplate,
                    singleSelect: true,
                    onItemDisclosure: showDetail
                }
            ]
        };
        
        panel = new Ext.Panel({
	    fullscreen: true,
	    layout: 'card',
	    cardSwitchAnimation: 'slide',
	    items: [ listPanel, detailPanel ]
	    });
	}
});

Al correr el ejemplo, veremos algo como esto:

Sencha Touch

Sencha Touch, viene con un style por default, que es el que usamos en el ejemplo anterior, pero ademas viene con dos styles mas, uno que se ajusta mejor al look and feel de Android y otro para iOS, cambiar entro uno y otro es solo cuestión de reemplazar la stylesheet.

Sencha Touch styles

Only for WebKit

Sencha Touch tiene muchas cosas a favor, es fácil de usar, es flexible y cuenta con muchas características y funciones interesantes, pero solo funciona con WebKit, y es algo que para mi es molesto, porque muchas de estas funciones y características, podrían funcionar en Firefox, Fennec y en menor medida Opera si ademas de usar las extensiones de WebKit usaran las de los demás fabricantes, o podrían simularse usando Javascript, así que tengan en cuenta esta restricción ante de lanzarse de lleno a desarrollar con el. Quizás en un futuro esto cambie, pero por ahora, si usamos un browser que no se base en WebKit, solo obtendremos este resultado.

Sencha Touch running on Fennec

Recursos

User Interface, Web Design , , , 4 responses

MeeGo Developers site (Beta)

December 8th, 2010

Ya es posible acceder a una preview de la nueva y renovada sección para desarrolladores en meego.com, comparado con el actual sitio, el nuevo diseño es mucho mas limpio, ordenado y fácil de navegar.

Para acceder al sitio solo necesitan visitar http://developer.meego.com y utilizar el usuario meego y el password developer para ingresar, si lo desean, pueden seguir el estado del proyecto o reportar algún bug aquí

developers.meego.com – Homepage

developers.meego.com Homepage

developers.meego.com – Community Resources

developers.meego.com  - Community Resources

Community No response

Master Details View con QML

November 22nd, 2010

Lo bueno de QML es que permite que casos de uso como una simple vista Maestro Detalle pueda ser mejorada agregando animaciones y layouts personalizados con muy poco esfuerzo.

El ejemplo a implementar es muy simple, vamos a usar un archivo XML como data source y para presentar los datos vamos a usar un GridView en donde seleccionaremos el item a mostrar en en el ListView que hace las veces de details view.

La acción central ocurren en el delegate usado para poblar el GridView el cual espera a que se haga click en alguno de los items, para pasar el index al ListView y disparar la animación que remueve el GridView de la escena para cambiar la opacidad del ListView de 0 a 1 para poder hacerlo visible, por ultimo hay en elemento Text que hará de botón para volver a la vista original.

import Qt 4.7

Rectangle {
    width: 360
    height: 640
    id:container

    XmlListModel {
        id: oranjeModel
        source: "http://localhost:3002/players.xml"
        query: "/players/player"
        XmlRole {
            name: "name"
            query: "name/string()"
        }
        XmlRole {
            name: "number"
            query: "number/string()"
        }
        XmlRole {
            name: "position"
            query: "position/string()"
        }
        XmlRole {
            name: "picture"
            query: "picture/string()"
        }
        XmlRole {
            name: "bio"
            query: "bio/string()"
        }
    }

    Component {
        id: oranjeDelegate
        Item {
            width: 80
            height: 110
            Image {
                source: picture
                width: parent.width
                height: parent.height
                fillMode: "Stretch"
                opacity: 0.5
            }
            MouseArea {
                anchors.fill: parent
                focus: true
                onClicked: {
                    oranjeDetails.currentIndex = index
                    container.state = "detailsView"
                }
            }
        }
    }

    Component {
        id: oranjeDetailsDelegate
        Grid {
            rows: 3
            spacing: 6

            Row {
                Image {
                    source: picture
                    width: 160
                    height: 230
                    fillMode: "Stretch"
                }

                Column {
                    Text {
                        text: number
                        font.pointSize: 24
                    }
                    Text {
                        text: name
                        font.pointSize: 18
                    }
                    Text {
                        text: position
                        font.pointSize: 14
                    }
                }
            }

            Row {
                Text {
                    text: bio
                    font.pointSize: 8
                    width: container.width
                    wrapMode: "Wrap"
                }
            }

            Row {
                Text {
                    text: "Back"
                    font.pointSize: 12
                    color: "#ed1e24"
                    width: container.width
                    MouseArea {
                        anchors.fill: parent
                        onClicked: container.state = ""
                    }
                }
            }

        }
    }

    GridView {
        id: oranjeList
        model: oranjeModel
        delegate: oranjeDelegate
        width: container.width
        height: container.height
        cellWidth:90
        cellHeight: 120
    }

    ListView{
        id: oranjeDetails
        model: oranjeModel
        delegate: oranjeDetailsDelegate
        opacity: 0
    }

    states: [
        State {
            name: "detailsView"
            PropertyChanges {
                target: oranjeList
                x: -container.width
            }
        }
    ]

    transitions: [
        Transition {
            from: ""
            to: "detailsView"
            NumberAnimation {
                properties: "x"
                easing.type: "OutBounce"
            }
            PropertyAnimation {
                target: oranjeDetails
                property: "opacity"
                to: 1
            }
        },
        Transition {
            from: "detailsView"
            to: ""
            NumberAnimation {
                properties: "x"
                easing.type: "OutSine"
                duration: 250
            }
            PropertyAnimation {
                target: oranjeDetails
                property: "opacity"
                to: 0
            }
        }
    ]
}
Development, User Interface , , No response

Consumiendo XML con QML

November 19th, 2010

Consumir XML en QML es algo casi trivial, para ello contamos con el elemento XmlListModel que hará de data source de un ListView en el ejemplo a continuación, el XmlListModel cuenta con una id, un source, que en este caso hace uso de la Weather API de Yahoo, luego vienen los XmlRole los cuales describen los datos expuestos, cada uno de ellos tiene un name que sera usado luego para poder acceder a la data del role.

A continuación tenemos un delegate, en donde especificamos que datos vamos a consumir, el layout y la apariencia que tendran, por ultimo el ListView usa el model y el delegate que previamente configuramos, en este caso solo muestra un item (ver imagen abajo) ya que nuestra query solo devuelve un dato, pero si el data source devolviese mas items, cada uno de ellos poblarían el ListView, como bonus, el ListView cuenta con kinetic scroll, el cual nos da unos puntos extras en el apartado de UX con 0 esfuerzo por parte nuestra.

import Qt 4.7

Rectangle {
    width: 640
    height: 360

    XmlListModel {
        id: weatherModel
        source: "http://weather.yahooapis.com/forecastrss?w=468739&amp;amp;amp;amp;amp;amp;amp;amp;u=c"
        query: "/rss/channel/item"
        XmlRole {
            name: "title"
            query: "title/string()"
        }
        XmlRole {
            name: "description"
            query: "description/string()"
        }
    }

    Component {
        id: weatherDelegate
            Item {
                anchors.fill: parent
                Column {
                    Text {
                        text:title
                    }
                    Text {
                        text:description
                    }
                }
            }
        }

    ListView {
        id: weatherList
        anchors.fill: parent
        model: weatherModel
        delegate: weatherDelegate
    }
}

Consumiendo XML con QML

Development , , No response

Novedades desde la MeeGo Conference 2010

November 17th, 2010

MeeGo Conference 2010 ready!
Photo Credits: Quim Gil – Photo License: AttributionShare Alike Attribution, Share Alike

Entre ayer y hoy en Dublin se llevo a cabo la MeeGo Conference 2010, con un concurrencia de mas de 1000 developers y con muchas novedades desde el principio, quizás la noticia mas importante la dio AMD anunciando su ingreso al proyecto, algo lógico de cara al próximo lanzamiento de sus procesadores AMD Zacate orientados al mercado de la netbooks, mercado en el cual Intel quiere empezar a posicionar a MeeGo el año que viene.

También se hizo el anuncio de que para el próximo año se van a realizar dos MeeGo Conferences las primera de ellas en Mayo en San Francisco que va a estar orientada a los partners de hardware y la segunda se realizara a finales de año y estará enfocada en los developers, ademas de estos anuncios se pudieron ver los planes para las próximas versiones de Qt y Meego.

Pasando a las charlas, la temática ha sido variada, tocando todas las versiones de MeeGo (Netbook, Handset, Connected TV e IVI) y por suerte todas ellas han sido grabadas, en este momento ya se encuentran disponibles los vídeos de casi todas las charlas dadas el Día 1 y próximamente estarán disponibles las del Día 2, pueden ver el listado de las mismas aquí, para ver los vídeos o bajar los slides solo hagan click en la charla de su interés, sino pueden ir a la pagina de la Linux Foundation donde también se han subido los vídeos.

Como verán, la comunidad y las empresas que giran en torno de MeeGo no paran de crecer, así que les dejo algunos links con recursos por si están interesados en investigar mas y probar MeeGo.

Community , , , , No response