kde-extraapps/kdeplasma-addons/containments/groupingdesktop
Ivailo Monev 7ddfeb4410 kdeplasma-addons: unload the data engines from WeatherPopupApplet destructor
because the data engines are not parented to anything the destruction
happens too late otherwise and triggers fatal message in
Plasma::DataEngineManager that it is accessed after destruction

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2023-08-14 15:41:37 +03:00
..
desktop kdeplasma-addons: unload the data engines from WeatherPopupApplet destructor 2023-08-14 15:41:37 +03:00
griddesktop kdeplasma-addons: unload the data engines from WeatherPopupApplet destructor 2023-08-14 15:41:37 +03:00
lib generic: preperations for kdelibs changes 2023-06-17 23:28:51 +03:00
panel generic: remove dead and irrelevant links references 2023-08-10 16:01:25 +03:00
CMakeLists.txt generic: generate export headers 2021-07-28 14:58:10 +03:00
README initial import of kde-plasma-addons (4.14.3) 2015-01-15 17:07:43 +00:00

Just a quick overview about the goals of this thing:

This little project will provide the user the ability to layout his applets
in a more advanced way. He will be able to group them inside special
QGraphicsWidgets called - can you believe it? - Groups, in a way that depends on the specific group.
So, e.g. there is a grid group that layouts the applets in a grid, a
floating group that leaves them free to move inside the group, and so on.
I developed a Desktop and a panel containment, that share a lib that manages the groups.
The applets are added to a group dropping them from the Add Widgets Explorer
or moving them over the group. If it is necessary (like in the grid group) a
drop zone will be shown (like the one in the panel).

 =====================================================================

More technical stuff:

This is composed of a library and two containments.
The library consists of a base class for the containments,
GroupingContainment, a base class for the groups, AbstractGroup, and a base class
for the handles, Handle, 'cause I realised that the normal Handle doesn't fit, e.g., for the
applets in the GridGroup.
This classes provide all the things needed to write a group or
a containment with grouping support and they co-operate well
together.

In order to be able to have many types of groups with their different needs
when speaking of saving the configuration, I moved this from the containment
to the groups: AbstractGroup has two pure virtual methods,
saveChildLayoutInfo(QGraphicsWidget *child, KConfigGroup &group) and
restoreChildLayoutInfo(QGraphicsWidget *child, KConfigGroup &group) which its subclasses
must reimplement, which actually save and restore the configuration. This
way it isn't the containment that saves, but it delegates this to the
specific groups that know how the applets are arranged and so they know the best
way to save the configuration. The grid group saves "Row" and "Column", the
tab group saves a "Index" and so on. These information are saved in the config section of
every applet inside a group called [GroupInformation].
The containment saves for each Applet under the [GroupInformation] group the numerical
identifier of the group in which it was placed.
The configuration of the groups are instead saved in [Containments][Id][Groups][Id], following
the pattern used by Applet.

There is support for groups-in-groups too. Every group can contain every other group like
if it were an applet, follwing the above-said rules for the configuration.

The Handle class, which was stripped down from AppletHandle in kdelibs,
allow every group to define an handle that will be used for the widgets inside it.
AbstractGroup has a virtual function - Handle *createHandleForChild(QGraphicsWidget *child) -
called by the containment when an applet or group receives an hover event that creates an handle
for that child. AbstractGroup returns by default a FreeHandle (that actually is AppletHandle
modified to make it work with groups too) but GridGroup returns a GridHandle instead.
Unfortunately the class Handle isn't how i would like it to be. Since AppletHandle is quite
complex I don't understand well its internals, and there still needs to be a good separation
of the work between Handle and its derived classes. (Moreover, AppletHandle emits the Applet signal
appletTransformedByUser(), which is protected, so nor Handle nor its derived classes can't emit it.)

GroupingContainment has the support for a so-called MainGroup. That is, a group without the background
as big as the containment. This way I avoid to duplicate code. I mean, the panel containment
layouts its applets and groups in a grid. Instead of implementing in the panel code the grid
layout, the panels uses GroupingContainment::useMainGroup(const QString &groupType).
This way the panel sets a GridGroup as main group, so it delegates all the grid layouting to it.
On boot-up the containmnent looks for a "mainGroupId" entry in its config. If it finds it, it will
set the group with that id as main group, otherwise it will build a new one.
To simplify a bit the code, GroupingContainment assumes there is always a main group, and it sets
a FloatingGroup, which isn't noticeable, as the default.
Currently this main group system assumes the main group won't change, but I could modify it
to let it change in runtime, selected by the user. I have to think about it.

I built a factory which creates the groups. The groups register themselves to the factory with
the macro REGISTER_GROUP(name, class name), then GroupingContainment asks the factory for the list
of the names associated with the groups and builds them calling AbstractGroup::load(name).
Every group must have a static function - static QSet<Plasma::FormFactor> availableOnFormFactors() -
that returns the form factors in which the group makes sense. E.g. in the panel there isn't the space
for a tabbing group, so it returns only Plasma::Planar and Plasma::MediaCenter.

There are four groups right now, a grid group, a stack group, a floating group, and a tabbing group,
one desktop containment and a panel containment.

You might find AbstractGroup's API to be quite similar to the Applet's one. In fact I tried to keep
it more similar as possible to ease the development of groups.

======================================================================

Things still to investigate:
    -different form factors in different groups;
    -create a nice interface to add groups;
    -decide if make the groups pluginnable.