Wiki Navigation
- Loading...
Overview
This page describes the SkinEngine, the MP2 module which renders and displays the GUI content for MediaPortal 2. To get a more general overview over the MediaPortal 2 architecture, please start at the Developers System Documentation.
Introduction
The Skin Engine is the component which produces the output for the main MP2 screen. It renders the skin files, which are shipped with MediaPortal or provided by installed plugins. It also provides the communication for the user with the rest of the system via keyboard, mouse and remote control.
The skin file format interpreted by the SkinEngine is XAML, very close to the specification of Microsoft. We use a control's library called "MediaPortal Presentation Foundation" – MPF. MPF controls can be used similar to those in Windows Presentation Foundation (WPF), but they have some subtle differences. Some features of WPF don't work for MP2. Those features are basically related to code-behind classes, which aren't an issue in the Skin Engine. There are also some additional features implemented in MPF, to support the communication of Skins with plugins or system components.
[Image of the rest of the MP2 system grayed out, with the Skin Engine highlighted]
To be continued
Architecture
The SkinEngine is integrated into MP2 as a plugin.
It consists of three main parts:
- XAML file parsing and generic handling of controls
- The MPF control's library
- The communication controller between the controls and the MediaPortal system
The XAML parsing and handling system ("XAML parser")
The XAML parser classes provide a generic system which was built to meet the requirements of a skinnable GUI which needs to communicate with an underlaying control's library, and which doesn't use code behind classes like WPF. It parses XAML input files, which comply to the Microsoft XAML specification. There isn't any MediaPortal specific code in the XAML parser part (except some explanation comments and very general dependencies like the usage of the Property class from MediaPortal.Common and the fact that the XAML parser is located in the MediaPortal namespaces). The XAML system consists of the parser itself, some helper classes and a set of interfaces to be implemented by controls of the underlaying control's library.
The MediaPortal specific control's library used in the SkinEngine isn't part of the XAML parsing system. It is separated from it, so the parsing system is completely self-contained. The XAML system could be used for other skinnable applications too. The control's library is built on top of the XAML parser interfaces and helper classes.
To go on reading, you should know what XAML is and how it can be used. The following chapters won't explain general XAML concepts. If you are not familiar with XAML, take a look at the Microsoft XAML Overview in the MSDN. It provides a very good and detailed overview and imparts a good knowledge of the basic concepts.
XAML interfaces
There are some interfaces which have to be implemented by special control classes to be supported by the XAML system. Those interfaces define one important way of communication, the XAML generic system uses to talk to the controls. There is an interface IContentEnabled, which tells the parser that the element's class provides a property with a "Content" meaning, without the need to specify a dedicated name for such a property, for example. Another interface, IAddChild, tells the parser that the element is able to accept child elements. Most of the interfaces are documented in detail in the sourcecode documentation.
XAML namespace handlers
Tags in a XAML file correspond to control implementations which are instanciated for them. Most often the control class names are the same as the tag names used in the XAML files. In XAML files, XML namespaces are used for further scoping of elements. For example in the WPF, there are two standard namespaces used: The WPF namespace (
"[http://schemas.microsoft.com/winfx/2...l/presentation|http://schemas.microsoft.com/winfx/2006/xaml/presentation]"
), which contains the WPF controls, and the XAML namespace (
"[http://schemas.microsoft.com/winfx/2006/xaml]"
), which contains additional general markup extensions and other items used by the XAML parser itself.
In the MediaPortal XAML parser, namespaces are modeled by writing namespace handlers for each namespace to be supported. A namespace handler is an instance of the interface INamespaceHandler, which contains callback methods for instanciating elements, querying their types and handling attached properties. Namespace handlers are published to the parser by returning an apropriate namespace handler instance to the parser as the result of an ImportNamespaceDlgt delegate call. A delegate of this type must be specified as an argument in the parser constructor call.
The SkinEngine control’s library (MPF)
The control library the SkinEngine uses is used almost identical to the Microsoft WPF library. We provide standard controls like Label, Button, panels (StackPanel, DockPanel, ...), some kinds of brushes, animations, styles, triggers etc.
As the control's library is still evolving much, a definite description of every single control doesn't make sense at this moment. Instead of this, a good starting point will be to look in the existing MediaPortal 2 skin files, which can act as a feature demonstration for the MPF controls.
Integration into the MediaPortal 2 system
The MediaPortal 2 architecture has a model-view approach, where the core system (main menu, players, media library, ...) as well as additional plugins all manage their own data. To access system/plugin data from a screen, plugins need to provide so called "models", which are actually a mixture of the classic "model" and "controller" in the MVC design pattern. Models in the MP2 jargon are needed to preprocess data to be presentable by the skin. Models are loaded either by accessing them directly from a skin file or by defining them as "workflow model" for a specific workflow state (see Workflow Manager).
Models each manage their own state. Every skin file is designed as a view for a one or more models. Screens show general controls like menu as well as model-specific controls like a list of available videos. The SkinEngine provides a means for binding skins to all of those datasources and for triggering commands in the MediaPortal system.
Most of those MediaPortal specific functions are realized as XAML markup extensions. So we use markup extensions to query the MediaPortal ServiceScope or to get references to model instances. Once a reference is specified, it can be used like every other data, for example it can be bound to controls. A special Command markup extension is used for creating Command instances used in MediaPortal to specify actions. Please refer to the Usage section for some examples.
Usage
This chapter should give a short overview of how the SkinEngine can be used by developers and skinners. It will explain how it is possible to switch screens, how skin files are found by MediaPortal in the file system, how they are referenced by other skin files or by models, and how they are written to display the desired information. This chapter will describe those aspects from the technical point of view; it should be seen as a technical addition to the Skin Design page.
MediaPortal 2 lookup algorithm for skin files
To be continued: Naming, file locations, interaction with plugin system, ...
Writing skin files for MediaPortal
In this chapter, I will describe, how a XAML skin file can be created for MediaPortal, especially how to use the MediaPortal specific markup extensions. You should be familiar with writing XAML forms and dialogs in general.
Simple dialogs can run without the need to employ special MediaPortal specific items. This includes controls, panels, layout information, styles and templates. Many of the controls available in WPF also exist in MPF, and they are used mostly the same. The main difference consists in the the availability of code-behind classes. In WPF, code-behind-classes are typically used when data is needed from the application, or when events should be handled.
In MediaPortal, we do not have code-behind-classes, so we need to map this functionallity to our model classes, which provide most of the data to be displayed at the GUI, and which provide the application logic behind the GUI.
To be used in the MediaPortal context skin files need to employ some markup extensions to query system data and to support the execution of commands in the application.
BindingMarkupExtension
To be continued
TemplateBindingMarkupExtension
To be continued
DynamicResourceMarkupExtension
To be continued
StaticResourceMarkupExtension
To be continued
ThemeResourceMarkupExtension
To be continued
GetModelMarkupExtension
To be continued
ServiceScopeMarkupExtension
To be continued
CommandMarkupExtension
To be continued
CommandStencilMarkupExtension
To be continued
PickupBindingMarkupExtension
To be continued
Reference of MPF element types
To be continued
This page has no comments.