mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 10:52:53 +00:00
.. | ||
desktop | ||
griddesktop | ||
lib | ||
panel | ||
CMakeLists.txt | ||
README |
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.