Yesterday we pushed a small but significant clean-up to a feature set we've been working on for a couple of years now which is perhaps one of the more interesting things we're doing in Plasma: the idea of "one code base, multiple form factors."
The idea is that whether your application is running as a widget on the desktop, docked in a panel, running full screen as part of a mediacenter, running in a touch based environment or as a regular ol' app-in-a-window, much of the code can be shared. We often put the non-graphical bits into shared libraries, and traditional we've built multiple front ends that are optimized for different form factors and input methods which use these libraries.
What would be even nicer would be, at least where possible, to raise the level of code sharing a bit and make it possible to also have the user interface adapt. Instead of having multiple user interfaces, you'd write one and it would be adapted depending on where it is running at the time.
One piece of the puzzle has been to communicate to the application this form factor information. In Plasma we let a component know when it is in horizontally or vertically constrainted presentation (usually a panel), when it has full run of a 2D surface, when it is full screen, etc. That's just the start, however.
For apps written with Qt Quick using a mix of QML, Javascript and perhaps some C++ bits behind the scenes, we ship the interface in a Package. Inside that package is a contents directory where all the individual QML, Javascript, image and other data files reside. There's also an optional "platformcontents" directory, and beneath that you can put platform customizations.
For example, if the interface should be laid out differently depending on whether it is on a tablet or a desktop, you can have a platformcontents/tablet/ directory. If you want to provide customizations for touch, platformcontents/touch/. Any files that are requested (be it QML, JS, images or whatever) that exist in those directories will be used instead of the version in contents/ when on that platform. In fact, on a tablet, anything in platformcontents/tablet will supersede platformcontents/touch.
Furthermore, the form factor also controls the QML components that are used to build the interface. For example, on touch we use thin scrollbars that fade out when not in use, as is typical on mobile devices, while on the desktop we use a much more traditional (and easier to use with a mouse) always-visible scrollbar.
How does this look in QML? Very boringly, it's transparent:
Will grab the correct Foo.js depending on the current form factor. Same for SVGs or other images requested or other QML files that are loaded.
This is controlled either by putting an the kdeglobals configuration file like this:
Or by setting the PLASMA_PLATFORM environment variable:
There is no limit as to how many form factors can be defined in the list, and it goes from most specific to least specific, finished up by the input style. The last entry controls which set of default components are used, and the other entries are used to define where in Packages to search for form factor specifics.
More documentation here.
The idea is that whether your application is running as a widget on the desktop, docked in a panel, running full screen as part of a mediacenter, running in a touch based environment or as a regular ol' app-in-a-window, much of the code can be shared. We often put the non-graphical bits into shared libraries, and traditional we've built multiple front ends that are optimized for different form factors and input methods which use these libraries.
What would be even nicer would be, at least where possible, to raise the level of code sharing a bit and make it possible to also have the user interface adapt. Instead of having multiple user interfaces, you'd write one and it would be adapted depending on where it is running at the time.
One piece of the puzzle has been to communicate to the application this form factor information. In Plasma we let a component know when it is in horizontally or vertically constrainted presentation (usually a panel), when it has full run of a 2D surface, when it is full screen, etc. That's just the start, however.
For apps written with Qt Quick using a mix of QML, Javascript and perhaps some C++ bits behind the scenes, we ship the interface in a Package. Inside that package is a contents directory where all the individual QML, Javascript, image and other data files reside. There's also an optional "platformcontents" directory, and beneath that you can put platform customizations.
For example, if the interface should be laid out differently depending on whether it is on a tablet or a desktop, you can have a platformcontents/tablet/ directory. If you want to provide customizations for touch, platformcontents/touch/. Any files that are requested (be it QML, JS, images or whatever) that exist in those directories will be used instead of the version in contents/ when on that platform. In fact, on a tablet, anything in platformcontents/tablet will supersede platformcontents/touch.
Furthermore, the form factor also controls the QML components that are used to build the interface. For example, on touch we use thin scrollbars that fade out when not in use, as is typical on mobile devices, while on the desktop we use a much more traditional (and easier to use with a mouse) always-visible scrollbar.
How does this look in QML? Very boringly, it's transparent:
import "plasmapackage:/code/Foo.js" as Foo
Will grab the correct Foo.js depending on the current form factor. Same for SVGs or other images requested or other QML files that are loaded.
This is controlled either by putting an the kdeglobals configuration file like this:
[General] runtimePlatform=tablet,touchOr by setting the PLASMA_PLATFORM environment variable:
PLASMA_PLATFORM=desktop myApp export PLASMA_PLATFORM=tablet:touchThere is no limit as to how many form factors can be defined in the list, and it goes from most specific to least specific, finished up by the input style. The last entry controls which set of default components are used, and the other entries are used to define where in Packages to search for form factor specifics.
This actually works in Plasma Workspaces 4.9, but was a little harder to configure and get the expected results. Now there is just the one setting in either the configuration file or environment variable and any application can get at this information if needed via libkdeclarative.
From here, we want to make it easier to switch to full window presentation (aka "traditional desktop app style"), continue to improve the individual QML components for different targets and hopefully also find a way to hook directly into QML's import statements to make this feature absolutely ubiquitous. We're already miles ahead of most of the competition here, though, and we know it works because, even if you didn't notice it, you've been using a system with these features for a while now. And if the user doesn't notice it, then we've succeeded, as that's the entire point. :)
More documentation here.



