Bundle Creator

Caution: Technical Jargon Zone!

If you had been following my earlier blog posts, you would know that I rarely include any code in them. My focus has primarily been on explaining how things work rather than delving into the specifics of how I implemented them. But this time I will be taking a deeper dive into the code, so in case you want to skip code today, you better not start reading this. ;)

This blog post has been a bit of a learning exercise for me as I pushed myself to learn UML diagrams and study a few design patterns in Qt. Learning Qt itself has been a challenge, though I doubt I can barely say that I have learnt it - I think it’s safe to say that I have just got more comfortable not understanding most things in Qt and trying to understand the parts that concern me. Now that I’m a teeny tiny bit wiser, I feel learning Object-Oriented Programming with C++, and a few design patterns prior to learning Qt would have been a better idea. Things (read classes) make a lot more sense once you understand the core design patterns.

Bundle Creator Wizard

The plan was to split the bundle creator into four main components, each having a single responsibility (Single Responsibility Principle!). DlgCreateBundle is the main class for the Bundle Creator. Notice how it has all functions related to putting the resources, tags and metadata in the bundle.

Similarly, all the code regarding resource choosing is present in PageResourceChooser(well not all, some of it in WdgResourcePreview), PageTagChooser(and WdgTagPreview) deals with the bundle’s tags, and all the metadata logic is present in PageMetaDataInfo. These wizard pages are completely independent of each other. There is, however, a message passing between PageBundleSaver and the other wizard pages which I will discuss later.

Resource Item Viewer

The Bundle Creator’s Resource Item Viewer now shares the same user interface as the one used by the Resource Manager in Krita. However, in order to not upset existing users of Krita, a new View Mode Button has been added so that users can switch between grid view and list view as per their preference.

The WdgResourcePreview class only deals with the left half of the Bundle Creator and the Resource Manager. That said, it loads the resources from the Resource Database onto the viewer, and displays resources as filtered by text or tag. However, all the code related to what happens when a resource item is clicked is dealt within the PageResourceChooser class for the Bundle Creator and the DlgResourceManager for the Resource Manager.

To manipulate the working of the right half of the Resource Chooser Page, one would need to make modifications to PageResourceChooser. And even though the left and right halves of the Resource Chooser page look fairly identical, it is important to note that the left half is built upon a QListView (KisResourceItemListView) and the right one on a QListWidget (KisResourceItemListWidget). This is because the left half loads the data directly from the Resource Database, using KisResourceModel. And the right half provides a view of the resource items selected by the user. It does use KisResourceModel for fetching the icon and name of the relevant item, but it doesn’t use the model directly.

This is really how each class mentioned above looks like.

Common UI

Qt’s Model View Architecture in Bundle Creator

Similarly to MVC, Qt’s Model/view design pattern is essentially separated into three components: Model, View and Delegate.

Instead of utilizing controller classes, Qt’s view handles data updating through delegates. It serves two primary objectives: firstly, aiding the view in rendering each value, and secondly, facilitating user-initiated changes. As a result, the controller’s responsibilities have merged with the view, as the view now assumes some of the tasks traditionally assigned to the controller through Qt’s delegate mechanism.

The KisResourceModel, KisTagModel, KisStorageModel act as the models for the QComboBox-es in the Bundle Creator(and Resource Manager). The KisTagFilterResourceProxyModel is built on top of the KisResourceModel and KisTagModel, and serves as a model for the KisResourceItemView which displays the list of available resources. And the KisResourceItemDelegate renders the items of data. When an item is edited, the delegate communicates with the model directly using model indexes.

Model View
KisResourceModel QComboBox
KisTagModel QComboBox
KisStorageModel QComboBox
KisTagFilterResourceProxyModel KisResourceItemView

Signal Slot Mechanism in Bundle Creator

Very classic, but just a rough sketch showing how the wizard pages communicate with one another. This connection helps to update the summary in PageBundleSaver whenever the selected list of resources or tags changes.

A bit about the Tag Chooser

This is something I have been working on last week. The Tag Chooser page is updated to look similar to the Resource Manager’s tag section. The available tags are displayed using KisTagLabel and the selected ones are displayed(and selected) using KisTagSelectionWidget. In both the cases, the KisTagModel serves as the underlying model.

Merge Request

My merge request can be viewed here.

Important Commits

Plans post Mid-Term Evaluation

Post midterm, I would be working on adding the feature of editing bundles in Krita, which will allow artists to add and delete components from existing bundles, so that they won’t have to go through the process of creating a bundle from scratch whenever they want to make some changes. I’ve created a post on Krita Artists Forum to better understand the preferences of artists regarding bundle editing. Feel free to drop a comment if you want to talk about it! :D

This time a drawing on paper art since I have exhausted my collection of art I made using Krita - serves as a reminder that I should do this more often. :)

Hand Drawn