One element of themes in Sencha Touch 2.2 is the new use of icons as fonts. This is an awesome feature, because this offers the following new features:
  • size can be easily changed. 
  • color can be easily changed. 
  • shadow can be easily added to their shape. 
  • transparency nearly everywhere, unlike transparent png's in ie6. 
  • smaller in file size 
  • infinitely scaleable (because vector) 
The goal of using icon fonts is to replace the need to render icons on a web page using images.

Requirements

To use this new feature it is mandatory to setup your project with SASS. If your project not yet including SASS, take a look at this article "Theming Sencha Touch with SASS".

Out-of-the-box icons

The lightweight Sencha Touch 2.2 default theme already includes some basic icons. It is shipped with 27 icons in total.

The default icon set includes:
action, add, arrow_down, arrow_left, arrow_right, arrow_up, bookmarks, compose, delete, download, favorites, home, info, locate, maps, more, organize, refresh, reply, search, settings, star, team, time, trash and user.
Use the default icons above by typing:
{  xtype: 'button',  iconCls: 'user',  title: 'User'  }

Extend the Out-of-the-box icons

Sencha Touch 2.2 is now using the http://www.pictos.cc/font/ library. When you checkout this website, you'll find out that they have more to offer in terms of icons.

At the first glance, the icon collections on the website might be a little bit confusing. You might ask yourself how does the mapping works between the "iconCls" and the pictos.

Well, when you take a look inside the framework of Sencha Touch 2.2, you will find the following mapping in "Sencha Touch SDK/resources/themes/stylesheets/sencha-touch/base/mixins/_Class.scss":
@function icon-character-for-name($name) {
    // http://pictos.cc/font/

    // Row 1
    @if ($name == "anchor") { @return "a"; }
    @else if ($name == "box") { @return "b"; }
    @else if ($name == "upload") { @return "c"; }
    @else if ($name == "forbidden") { @return "d"; }
    @else if ($name == "lightning") { @return "e"; }
    @else if ($name == "rss") { @return "f"; }
    @else if ($name == "team") { @return "g"; }
    @else if ($name == "help") { @return "h"; }
    @else if ($name == "info") { @return "i"; }
    @else if ($name == "attachment") { @return "j"; }
    @else if ($name == "heart") { @return "k"; }
    @else if ($name == "list") { @return "l"; }
    @else if ($name == "music") { @return "m"; }
    @else if ($name == "table") { @return "n"; }
    @else if ($name == "folder") { @return "o"; }
    @else if ($name == "pencil") { @return "p"; }
    @else if ($name == "chat2") { @return "q"; }
    @else if ($name == "retweet") { @return "r"; }
    @else if ($name == "search") { @return "s"; }
    @else if ($name == "time") { @return "t"; }
    @else if ($name == "switch") { @return "u"; }
    @else if ($name == "camera") { @return "v"; }
    @else if ($name == "chat") { @return "w"; }
    @else if ($name == "settings2") { @return "x"; }
    @else if ($name == "settings") { @return "y"; }
    @else if ($name == "tags") { @return "z"; }

    // Row 2
    @else if ($name == "attachment2") { @return "A"; }
    @else if ($name == "bird") { @return "B"; }
    @else if ($name == "cloud") { @return "C"; }
    @else if ($name == "delete_black1") { @return "D"; }
    @else if ($name == "eye") { @return "E"; }
    @else if ($name == "file") { @return "F"; }
    @else if ($name == "browser") { @return "G"; }
    @else if ($name == "home") { @return "H"; }
    @else if ($name == "inbox") { @return "I"; }
    @else if ($name == "network") { @return "J"; }
    @else if ($name == "key") { @return "K"; }
    @else if ($name == "radio") { @return "L"; }
    @else if ($name == "mail") { @return "M"; }
    @else if ($name == "news") { @return "N"; }
    @else if ($name == "case") { @return "O"; }
    @else if ($name == "photos") { @return "P"; }
    @else if ($name == "power") { @return "Q"; }
    @else if ($name == "action") { @return "R"; }
    @else if ($name == "favorites") { @return "S"; }
    @else if ($name == "plane") { @return "T"; }
    @else if ($name == "user") { @return "U"; }
    @else if ($name == "video") { @return "V"; }
    @else if ($name == "compose") { @return "W"; }
    @else if ($name == "truck") { @return "X"; }
    @else if ($name == "chart2") { @return "Y"; }
    @else if ($name == "chart") { @return "Z"; }

    // Row 3
    @else if ($name == "expand") { @return "`"; }
    @else if ($name == "refresh") { @return "1"; }
    @else if ($name == "check") { @return "2"; }
    @else if ($name == "check2") { @return "3"; }
    @else if ($name == "play") { @return "4"; }
    @else if ($name == "pause") { @return "5"; }
    @else if ($name == "stop") { @return "6"; }
    @else if ($name == "forward") { @return "7"; }
    @else if ($name == "rewind") { @return "8"; }
    @else if ($name == "play2") { @return "9"; }
    @else if ($name == "refresh2") { @return "0"; }
    @else if ($name == "minus") { @return "-"; }
    @else if ($name == "battery") { @return "="; }
    @else if ($name == "left") { @return "["; }
    @else if ($name == "right") { @return "]"; }
    @else if ($name == "calendar") { @return "\005C"; }
    @else if ($name == "shuffle") { @return ";"; }
    @else if ($name == "wireless") { @return "'"; }
    @else if ($name == "speedometer") { @return ","; }
    @else if ($name == "more") { @return "."; }
    @else if ($name == "print") { @return "/"; }


    // Row 4
    @else if ($name == "download") { @return "~"; }
    @else if ($name == "warning_black") { @return "!"; }
    @else if ($name == "locate") { @return "@"; }
    @else if ($name == "trash") { @return "#"; }
    @else if ($name == "cart") { @return "$"; }
    @else if ($name == "bank") { @return "%"; }
    @else if ($name == "flag") { @return "^"; }
    @else if ($name == "add") { @return "&"; }
    @else if ($name == "delete") { @return "*"; }
    @else if ($name == "lock") { @return "("; }
    @else if ($name == "unlock") { @return ")"; }
    @else if ($name == "minus2") { @return "_"; }
    @else if ($name == "add2") { @return "+"; }
    @else if ($name == "up") { @return "{"; }
    @else if ($name == "down") { @return "}"; }
    @else if ($name == "screens") { @return "|"; }
    @else if ($name == "bell") { @return ":"; }
    @else if ($name == "quote") { @return "\""; }
    @else if ($name == "volume_mute") { @return "<"; }
    @else if ($name == "volume") { @return ">"; }
    @else if ($name == "help") { @return "?"; }

    // Backwards compat; icons that are not in the font
    @else if ($name == "arrow_left") { @return "["; }
    @else if ($name == "arrow_right") { @return "]"; }
    @else if ($name == "arrow_up") { @return "{"; }
    @else if ($name == "arrow_down") { @return "}"; }
    @else if ($name == "organize") { @return "I"; }
    @else if ($name == "bookmarks") { @return "I"; }
    @else if ($name == "loop2") { @return "r"; }
    @else if ($name == "star") { @return "S"; }
    @else if ($name == "maps") { @return "@"; }
    @else if ($name == "reply") { @return "R"; }

    @else {
        @return null;
    }
}
Ok, lets try this:
{  xtype: 'button',  iconCls: 'speedometer',  title: 'Speedometer'  }
But as you see in the result, the icon is still missing! This is because we did not included the icon in our "*.scss" file yet (because it is not in the range of the default icon set). To do this, add the following line to your "*.scss" file:
@include icon('speedometer');

Change the color or size of an icon

Changing the color of an icon is easier now than ever. All you need to do is adding the following line to your "*.scss" file:
.x-button-icon {
    color: #fff;
}
Now the color of your icon should change to white.

In case you want to change the size of the icon:
.x-button-icon {
    font-size: 50px;
}
Pretty simple, isn't it?

Add a icon to Ext.List

If you want to add a icon to Ext.List you need to define your own css class, because Ext.List do not have the iconCls config attribute.

In this example we add an user icon to Ext.List.

Open your "*.scss" file and add the following lines:
.userCls:before {
    font-family: "Pictos";
    content: "U";
    font-size: 1.5em;
}
Using the ":before" selector in CSS you can insert the user icon before the anchor text. Similarly, you can also use the :after selector to insert the icon after the text.

Ext.List item:
xtype : 'list',
store : 'your store',
itemTpl : new Ext.XTemplate(
 '<span class="userCls"></span>',
 '<span>{name}</span>',
 ...

Add more custom Icon-Fonts

If you need more icons, you can also attach icons from http://icomoon.io/app/ or checkout more icon collections.

The way to add custom Icon-Fonts is explained in this video: http://vimeo.com/66191690

Conclusion

Well, I hope this article helps. If you have any question, please contact me. In the mean time - let's keep developing apps guys.
Today at work I faced an interesting issue, I spent so much time looking for an instruction of how to implement the Ext.Logger in Sencha Touch application. Unfortunately, there is no information about this in the official documentation. Therefore, just to save you some time I would like to explain some details that I found out during my research.

First of all, the described technique for implementing the Ext.Logger works for Debug-Mode only, which means, the created Log messages are not visible when you use one of the following build-modes:
  • testing 
  • production 
  • native 
  • package 
The initial Logger setup is done, by putting the following lines to your app.js file:
    //<debug>
    logger: {
        enabled: true,
        xclass: 'Ext.log.Logger',
        minPriority: 'verbose',
        writers: {
            console: {
                xclass: 'Ext.log.writer.Console',
                throwOnErrors: true,
                formatter: {
                    xclass: 'Ext.log.formatter.Default'
                }
            }
        }
    },
    //</debug>

Pay attention that you put these lines between the //<debug> comment tags. Anything between //<debug> and //</debug> will be removed after you do a build with Sencha Cmd. If you are not putting your Logger setup between these lines, you won't be able to build your application with Sencha Cmd again.

For further information also checkout src/log/writter. There you can see how to Log in browsers document title or how to do a remote Log.

After the main configuration is done, the Log messages can be implemented like:
    //<debug>
    Ext.Logger.info('Hello World!');
    //</debug>
Take also a look at http://docs.sencha.com/touch/2.2.1/#!/api/Ext.Logger for a complete list of the Ext.Logger methods.

While Sencha Cmd is removing all code between //debug, your application should also run a little bit faster after building it. At least when you are using a huge amount of logging information.
Happy Logging...