Meego Wiki
Views

Theming in MeeGo Touch

From MeeGo wiki
Revision as of 18:39, 21 December 2010 by Ayanes (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

MeeGo Touch Themes in Practice

Code & API links

MeeGo Touch Theme is released under LGPL. You can find the "source code" in this url:

http://meego.gitorious.org/meegotouch/meegotouch-theme

If you have planned some development is highly-recommended to read the styling practices at libmeegotouch:

http://apidocs.meego.com/git-tip/mtf/

How does this theme stuff work?

The MeeGo Touch framework is extensively themeable. Themes support inheritance, which means you can extend and modify existing themes easily. Part of the theme system is similar to GTK toolkit themes, but there are quite a few differences. The setup is powerful, but also quite complex, thus this document tries to explain how the system works with practical examples.

Most of the theming builds on the styles of common components (“widgets”) that are used throughout the system, thus keeping things consistent. It is however possible to have custom themes for a specific application if desired, to achieve some specific visual goal, or to style a new custom component present only in a particular application or a library.

There is a special theme called "base" which is used as a foundation for defining the framework. All other themes inherit "base" and can then benefit from all the stuff defined there. However, it is also possible to have a theme inherit another theme (which in itself inherits base). This can be useful for example if you want to create a number of themes that share a lot of their look and feel.

For Developers

As an application developer, the best practice is to use common components with default styling as much as possible. You can find in the common components most of the things that you need for your application. This practice provides a consistent look across the whole system, and makes your application adapt better to the currently used system-wide theme. Applications however can have their own custom theme if desired, this is possible by application-specific stylesheets and graphics.

As a widget developer, when creating new user interface components, you need to create style attributes and create a visual style for your component. This involves writing the CSS (some specific properties could implies non-standard CSS) file and possibly SVG graphics assets as well, possibly working together with a designer.

For general consistency of the user experience, it is especially important to use the #Common Styles when defining your user interface. This also frees you from having to write your own CSS and automatically gives you a consistent look compared to the rest of the platform.

For Designers

As a designer there are two ways you can alter the look of the theme:

1. Modify an existing theme by editing the SVG graphics to your liking. You can use Inkscape or some other SVG-capable vector graphics tool to open and modify the theme svg assets. Pay particular attention to graphic assets ID names in groups, as these are used to assign certain graphic elements to widgets. Please see the section about SVG files below for more information.

2. Edit the CSS files to change the sizes and margins of components. You can also extend the style rules by adding your own CSS code, for a specific application or common components shared by all applications. Consult the section about CSS files below for style matching rules and other information about the CSS syntax. The file called "commonlayouts.css" inside meegotouchcore contains margin and layout styling of common styles, whereas the margins and other #Constants are defined centrally in the constants.ini, and used throughout the CSS files.

It is also possible to create entirely new views for components in a theme, but that is outside the scope of this document. Consult the libmeegotouch developer documentation for coverage on that area.

Basic concepts

Theme Folder Structure

MeeGo Touch themes are organized inside a folder. The theme folder name should be unique in the system, and defines the theme name, for example "mytheme". The name should contain only lowercase alphanumeric characters and no whitespace.

/usr/share/themes/ (install prefix)
   + base/
        index.theme
      + meegotouch/
         + feedbacks/
         + icons/
         + images/
         + libmeegotouchcore/
         + libmeegotouchextensions/
         + libmeegotouchviews/
         + locale/
         + svg/
           constants.ini
           ids.txt

Directly inside the theme folder is a text file called "index.theme". This contains the theme metadata, for example the inheritance information and a user-friendly display name for your theme. The display name can contain any UTF-8 characters, though it's probably a good idea to try to stick with something that is likely to be found in the font of your users current theme.. :-)

[Desktop Entry]
Type=X-MeeGoTouch-Metatheme
Name=My Cool Theme
Encoding=UTF-8

[X-MeeGoTouch-Metatheme]
X-Inherits=base
X-Visible=true
X-Icon="icon-l-mythemeicon"
X-Libraries=meegotouchviews

A theme can also specify an icon which could be shown by a theme switcher. You need to install it inside the "base" theme's icons-folder.

So far we have a working, complete theme which shows up in the theme selector and can be used. Naturally it is just a clone of the parent theme, which is not useful in real life, so you likely want to add some content to override or extend the parent theme.

Theme Inheritance

A theme can inherit another theme. This is very useful if you want to create a theme variant. Lets assume you want to change only the fonts or colors or the look of the button widget in the default theme. The inheritance system allows you to create an empty theme folder with just the index.theme file and set it to inherit the default system theme. Now, anything you add to your own theme will override properties and graphics etc from the parent theme. Everything else is loaded from the parent automatically. Just make sure you don't do an infinite loop in the inheritance chain :-)

Common Styles

To achieve consistent look and alignment with different user interface elements, we have introduced the concept of "common styles".

Common styles are created to fit user interface elements different scenarios. For example, a text label can be in several different views and can have different properties depending on the place, common layouts cover the styles for "standard" user interface views and free application developers from worrying about spacing and alignment. So common styles are like "lego bricks" that fit widgets together nicely without custom styling.

For example, there is CommonSingleTitle which is something you want to use if you have one line of text you want to display in a list item:

+------------------------------+
|                              |
|   Hello World!               |
|                              |
+------------------------------+

There is also CommonTitle and CommonSubTitle for cases where you need to show two lines of text - common style could style them like this for you:

+------------------------------+
|   CommonTitle text*          | <- normal font
|   CommonSubTitle text        | <- smaller font, light colour
+------------------------------+

Limitations of plain text representation make these two list items different size, which is not significant. The point is, the margins of CommonTitle and CommonSingleTitle are defined so that they fit the particular view in question, and things look consistent.

Common Layouts are defined in the file "commonlayouts.css" in the theme and are used by developers by setting the correct object name with setStyleName() function.

Graphics Assets - SVG Files and Bitmaps

Most theme graphics are vector graphics in SVG format. It is also possible to have assets in bitmap formats (jpeg and png are supported) if needed.

SVG graphics are accessed by the svg group id - so if you want to have an image for your button widget, you draw it with the graphics editor of your choice and group the objects that belong to your asset together. You then name the group ID with an unique ID (the default theme uses "meegotouch-button-background" for example) and this is the "handle" you refer to in your CSS to access that graphics piece. You can have all your theme assets in one SVG file or you can split them up into logical parts if you like, whatever works best for you.

SVG files are in "meegotouch/svg" -folder under the theme root folder.

Cascading Stylesheet (CSS) files

This is the "glue" of the theming system where everything happens. The basic idea is very similar to web development, where a style definition in the stylesheet file matches a particular element in the document, and various style attributes are assigned to it.

MButtonStyle {
   background-image: meegotouch-button-background 10px 10px 10px 10px;
}
MButtonStyle:pressed {
   background-image: meegotouch-button-background-pressed 10px 10px 10px 10px;
}

The example above basically sets the SVG group "meegotouch-button-background" as the background image of MButton, and the -pressed graphics to the pressed state of the same widget.

Our CSS syntax is somewhat similar to the W3C CSS, but has differences, so do not assume all your web developer tricks work - however it should be familiar enough to be helpful if you have background in HTML and CSS. Due to various reasons there are quite a bit of custom selectors not found in the web CSS standard, thus it might be best to learn by example and study the CSS files in the meegotouch-theme package. Those examples list all the supported style parameters for each widget.

See section "CSS Matching Rules" below on how to map certain widgets and states into your style.

The CSS files are in "meegotouch/*/style" -folders, where * is libmeegotouchcore, libmeegotouchviews and libmeegotouchextensions - these libraries form the MeeGo Touch framework and each has a style folder for the widgets contained within that library. As a theme designer you dont need to worry about that any more than to look into three places when you check through the stylesheet files.

CSS Matching Rules

There are basically two ways to match styles: widget class and named styles. Certain named styles are used a lot in application views for consistency, and are explained more in the Common Styles -section. You can also style a whole widget class. This can be useful when you want to give some common properties to all widgets and then define specific styles for certain instances of the widgets.

Example of a common style:

MLabelStyle {
  color: #000000;
  font: "Sans" normal 3mm;
}

A named style:

#MyWarningLabel {
  color: #cc0000;
}

In this case, all text labels are styled black. Any label which has setStyleName("MyWarningLabel"); set, gets the red color instead. All labels however use the font "Sans" in 3mm tall normal variant, because the label class style is assigned first to all label widgets, whichafter the named style (MyWarningLabel) is mapped to those labels that have the special style name set.

#Warning { /* generic styles for all widgets that use "warning" style */ }
MLabelStyle#Warning { /* all labels that use "warning" style */ }
MButtonStyle#Warning { /* button widgets that use "warning" style */ }

It is also possible to match simple widget parent/child rules, to for example style all buttons inside a dialog widget.

MDialog MButtonStyle { }

Note the use of widget names in the beginning (MDialog, not MDialogStyle) - the style name is used only for the actual style being matched, at the end of the chain.

See the Styling > Stylesheet syntax reference & examples chapter in libmeegotouch documentation for a more through reference of the syntax and parameters.

Portrait and Landscape and Widget States

Sometimes it is useful to define different style for a widget depending on whether the screen is rotated in portrait or landscape orientation. This is supported when you specify your style like this:

MyWidgetStyle.Portrait { /* style for portrait orientation */ }
MyWidgetStyle.Landscape { /* style for landscape orientation */ }

If you don't specify an orientation, the style applies for all rotations.

Widget states can also be styled, there are three states: normal, pressed and selected. Normal state does not require any identifier in the CSS rule, it is the default style for a widget. You can specify a different style for pressed and selected states like this:

MButtonStyle:pressed { /* user has pressed finger on the widget */ }
MButtonStyle:selected { /* widget was toggled active */ }

Constants

Many times it is useful to define certain key properties once and then use them throughout the theme for consistency. This is possible by using "constants". Constants are simply property values that are given a name. They are defined in the text file "constants.ini" and can be something like this:

COLOR_FOREGROUND            = #000000;
MARGIN_MEDIUM   = 0.6mm;

The file format uses the common "windows ini file" format with name - value pairs separated by the equals sign. The capitalized names are just a convention we are currently using and not mandatory.

Personal tools