Plasma/ShellDesign
Introduction
Creating a full featured Plasma shell involves pulling together a number of standard components from libplasma into a single interface. There are also several optional components that can be used to improve the overall user experience.
Whether you are creating a full screen interface such as Plasma Desktop or Plasma Netbook, or an application helper like the Plasma KPart or Plasma Media Center, this tutorial, which documents each of these components and how they fit together, can get you started in the right direction.
An Overview Of A Plasma Shell
Plasma is a model/view approach to user interfaces, much as the QGraphicsView framework it is based on. Nearly all of the user interface is kept on a canvas which can be thought of as an infinite Cartesian plane. This plane is called the "Corona", and is a QGraphicsScene subclass.
The Corona serves as a top-level manager for Containments, which are QGraphicsWidgets that manage collections of Applets. Containments are not nested, and Applet nesting is also discouraged due to being error-prone and nearly never actually needed. This creates a nice hierarchy of Corona->Containments->Applets within the scene. Note that "plain" QGraphicsWidgets may exist between Containments and Applets in the scene, and that they are transparent in terms of the Plasma hierarchy.
Within the scene, items are placed in the four quadrants of the plane according to their functions: full window / screen Containments are kept in quadrant III, panel Containments in quadrants II and IV (to accomodate their most natural direction of growth, e.g horizontal panel Containments grow horizontally more often that vertically so appear in quadrant II) and other items such as contents for popup windows in quadrant I (often referred to as "offscreen widgets").
To present this to the user, Views are created which show sections of the Corona. Views usually are set to display the geometry of a Containment or an offscreen widget. There is no correlation between the location of a View in the user interface or on the computer screen and where the contents it is viewing are on the screen. It is also possible to have more than one View showing the same area on the scene at once.
So the primary job of a Plasma shell is to provide a collection of Views on the Corona scene arranged in a way that makes sense for the application. The default layout of the items on the scene is also managed by the Plasma shell, but storing and loading once set up is handled by libplasma.
In addition to Views and the use of stock Containments and Applets, shells may want to provide customized Containments and/or Applets. These custom additions can themselves also be plugins (which can be shared with other Plasma shells or not) or built-in to the shell itself using the PluginLoader class.
There are also a host of optional components that a shell can provide that allow a more customized presentation, such as the AccessManager which allows the shell to provide a custom user interface for remote access requests, the DialogManager which forwards requests for dialogs such as configuration interfaces to be shown, etc.
Each of these components is covered in detail below.
Core Presentation
The Base Canvas: Corona
Corona is a subclass of QGraphicsScene, however provides several additional facilities:
- There will be only and only one Corona instance per application
- It manages Containments (all items added directly to a Corona are Containments), including saving and restoring the whole layout into KConfig
- It manages the association between Containments and screens: the mapped ones will be displayed by a Plasma::View
- It manages the concept of available space for screen (reimplementations of screenGeometry() and availableScreenRegion() can take into account position and size of panels for instance)
- QActions can be assigned to the corona: they can be visualized by the Containments ToolBox, but unlike the Containments Actions, those are global
- It has the concept of Immutability: part of the user interaction can be blocked, to prevent accidental data loss or for kiosk environments
Views
Plasma::View is a subclass of QGraphicsView. It has some peculiarities over its base class:
- Its scene will be always the global unique scene: the Corona
- It will always have an 1:1 association with a Containment
- Its sceneRect() will always be synchronized with its Containment geometry()
- It has a screen and desktop property: a view will be associated to a phisical screen and a virtual desktop, and will be syncronized with the Containment. Not all reimplementations need to actually associate physical screens: for instance in an application dashboardthere won't be this physical->logic association of screens
- It has its own configuration, of all values that don't depend on scene items, but from actual window geometry/properties (such as panel position, or showing the view on all virtual desktops)
Custom Containments
Containments implementations can have several types:
- DesktopContainment: dafault desktop containment, it will have standard applet handles and the Corona will assign a ToolBox to it.
- PanelContainment : default panel containment, won't have applet handles and the Corona will assign a ToolBox to it.
- CustomContainment: won't have applet handles and the Corona won't assign a ToolBox by default (it's possible to assign one into the containment implementation tough)
- CustomPanelContainment: for custom panels: won't have applet handles and the Corona won't assign a ToolBox by default (it's possible to assign one into the containment implementation tough)
A Containment reimplementation manages the way the applets are laid out inside it, so it will have to react to new applets being added or removed into the containment, by connecting to the appletAdded(Plasma::Applet *applet) and appletRemoved(Plasma::Applet *applet) signals.
If the applets in the containment can grow in any direction they want, the containment will have a 'Plasma::Planar FormFactor, otherwise will be Plasma::Horizontal if they can grow only horizontally and Plasma::Vertical if they can grow only vertically.
A typical use case is to set a Planar FormFactor when the Location is Plasma::Floating, Plasma::Desktop or Plasma::FullScreen. While will be Horizontal for a BottomEdge or TopEdge Location and Vertical for a LeftEdge or RightEdge Location.
PluginLoader
Window Dressings
Containment Tool Boxes
Each containment shown by the Plasma Shell, can have a central place to show the main actions that can be performed.
A default set of toolbox actions is present in the base Containment implementation. Containment subclasses, as well as the Corona implementation of the Plasma shell can add their own.
The method Containment::AddToolBoxAction(QAction *a) adds the action a to the toolbox.
The action can contain metadata about its category, to help the toolbox implementations to visually group together similar actions, to do that call
QAction::setData(AbstractToolBox::ToolType)
A ToolBox is a subclass of Plasma::AbstractToolBox and is usually loaded as a plugin, whose desktop file will have the entry X-KDE-ServiceTypes=Plasma/ToolBox
A Containment implementation can force its own ToolBox implementation, but this is discouraged, especially in containments of type DesktopContainment or PanelContainment.
By default, containments will load the ToolBox plugin the Corona tells them. To set a default ToolBox plugin, use the function
Corona::setDefaultToolBoxPlugin(const QString &PluginName, Plasma::ContainmentType type)
in the constructor of your Corona implementation.
Applet Handles
Containment Actions
Add Widgets Interface
User Interface Management
Containment and View Configuration
Remote Access Management
Dialog Positioning
If an Applet wants to show a QGraphicsWidget into a standalone window, it can use a Plasma::Dialog. It is a QWidget subclass and must be created without a parent, in order to be a top level window. A QGraphicsWidget (or a subclass) can be associated to a Dialog with Dialog::setGraphicsWidget(widget). The widget will be automatically positioned in an offscreen area of the Corona, with Corona::addOffScreenWidget(widget), that is not necessary to call it manually.
Animation Customization
Configuration and Automation
Configuration Files
A Plasma shell uses 3 configuration files: given the shell executable is called plasma-foo, there will be
- plasmarc: common to all Plasma shells, at the moment it contains the configuration about the used theme
- plasma-foorc: configuration specific of the application. It contains global shell-widge configuration values, such as the information about the configuration of the views
- plasma-foo-appletsrc: this is the saved layout of all the Containments and the Applets inside each containment, with all their individual configuration