Accéder au contenu principal

Extracting Boxes' wizard's pages

A few days ago, Zeeshan suggested me to extract Boxes' wizard's pages out of the Wizard class and to make them full fledged widgets/classes. This idea is very welcome as it would move a lot of complexity out of the Wizard class (as it is currently implementing most of the pages) and, in the long run, make its port to GtkAssistant easier.

I spent the last few days playing with the pages, discovering how they are implemented and extracting some of them.

Boxes' wizard's page graph
Extracting pages, kind of

The current state of Boxes' installation wizard

Here is the wizard's page flow as presented to the user:

Boxes' wizard's page graph
The current page flow

The wizard is currently implemented with such a widget hierarchy:

  • the WizardWindow class
    • the WizardToolbar class
    • the Wizard class, a stack of pages
      • the WizardSource class
        • the source selection page
        • the URL entry page
      • the preparation page
      • the setup page
      • the review page
    • the file chooser page
    • the customization page

The wizard has three layers of pages, most of them behaving slightly differently: the WizardSource class is composed of the source selection page and of the URL entry page; the preparation, setup and review pages are directly implemented by the Wizard class; and the file chooser and customization pages are implemented by the WizardWindow class. Also, the URL entry page have its own back button and doesn't use the common one in the headerbar to go back to the source selection page, which is inconsistent with every other page's behaviour.

Most pages are directly implemented by the Wizard class, making of it a mishmash of intertwined behaviours and responsibilities, especially as every page is directly modifying the wizard's state. Some other are handled by the WizardWindow and WizardSource classes, but in the end, no page exist as a single class. All of this lead to a great complexity which should be corrected in order to make the wizard more maintainable and to port it to GtkAssistant.

Where to go

I want to keep the page flow the same while changing the implementation drastically: the Wizard should inherit GtkAssistant, each page should be a widget with its own class and no page should be nested. Here is what I want to achieve:

  • Wizard
    • WizardSourceSelectionPage
    • WizardFileChooserPage
    • WizardUrlEntryPage
    • WizardPreparationPage
    • WizardSetupPage
    • WizardCustomizationPage
    • WizardReviewPage

This refactoring has to be done properly: what's the point of moving from known code to something not inherently better and known only by the person who wrote it?

In order to untangle the pages from the wizard without changing their code too much, I want to use more event-driven programming so that the pages don't change the wizard's state directly but notify it of changes, letting it react accordingly. It will help to uncouple the wizard's behaviour from the implementations of the pages, hence making its code simpler and its porting to GtkAssistant easier.

Going there

What have been done:

  • spliting the model of the WizardSource class from the widget: patch submitted
  • renaming WizardSource as WizardSourcePage to keep the page names consistent
  • extracting the preparation page from the Wizard class: patch submitted
  • extracting the setup page from the Wizard class: patch submitted
  • extracting the review page from the Wizard class: patch submitted

What has to be done:

  • editing the Wizard class' API to mimick GtkAssistant's one: in progress
  • extracting the source selection page from the WizardSourcePage class
  • extracting the URL entry page from the WizardSourcePage class
  • removing the WizardSourcePage class
  • extracting the file chooser page from the WizardWindow
  • extracting the customization page from the WizardWindow
  • merging the Wizard, WizardToolbar and WizardWindow classes
  • making the Wizard class inherit from GtkAssistant

As pointed out in my last article, GtkAssistant forced a padding to its pages which was problematic as some of Boxes' wizard's pages need to take all the available space to display complex widgets or infobars. This bug have been solved pretty quickly by Matthias Classen who added a way to disable the padding for specific pages. Thanks Matthias, it will be useful. =)

Other stuff

I started working on other stuff too.

I tried to add support for the application/x-cd-image MIME type to Boxes but without success. Starting Boxes with a path or an URI pointing to an ISO file works perfectly, but trying to open one with Boxes via Nautilus or xdg-open didn't work. I need to investigate this.

Last march I started adding a list view to Boxes' collection view. It worked well except for a warning that I didn't understand and didn't have time to investigate. The warning was still present and I tracked it as coming from libgd, I then opened a ticket and submitted a patch, which so far are still waiting for reviews.

I have no time to get bored when working on Boxes! =D


Posts les plus consultés de ce blog

GTK+ Apps on Phones

As some of you may already know, I recently joined Purism to help developing GTK+ apps for the upcoming Librem 5 phone.Purism and GNOME share a lot of ideas and values, so the GNOME HIG and GNOME apps are what we will focus on primarily: we will do all we can to not fork nor to reinvent the wheel but to help allowing existing GTK+ applications to work on phones.How Fit are Existing GTK+ Apps?Phones are very different from laptops and even tablets: their screen is very small and their main input method is a single thumb on a touchscreen. Luckily, many GNOME applications are touch-friendly and are fit for small screens. Many applications present you a tree of information you can browse and I see two main layouts used by for GNOME applications to let you navigate it.A first kind of layout is found in applications like Documents, I'll call it stack UI: it uses all the available space to display the collection of information sources (in that case, documents), clicking an element from t…

The Path to GNOME Games 3.26

Games received a non-negligible amount of changes that you will find in 3.26. These changes can be big as much small, and more are to come!Building the Games CollectionGames presents your games collection and if everything goes as expected, it does so without the need of any input from you. From an implementation point of view it sounds simple to do, just ask Tracker “Hey, gimme all the games” and it’s done. If only it was that simple! 😃 The system has no idea which files represent games and which doesn’t, but it can associate a MIME type to each file thanks to shared-mime-info. shared-mime-info already had a few video game related MIME types and we added a lot more such as application/x-genesis-rom.That done, we can query Tracker for files having specific MIME types that we know to often represent video game files. Unfortunately, each of these files doesn’t necessarily represent a game and a game isn’t necessarily represented by a single file: some files may be invalid and hence rep…

One Widget to Adapt Them All and to The Librem 5 Port Them

In my previous article I shared my plans to help porting existing GTK+ applications to Purism's upcoming Librem 5 phone without having to fork them. This article will present the GTK+ widget I developed for Purism to make this happen.For more information on what Purism is working on for the Librem 5, please check Nicole Faerber's latest article.C'est pas sorcierThe underlying idea is to allow applications to dynamically switch between the two main GNOME application layouts: a row of panels — each panel being the view of an element from the previous one — and a stack of panels. The goal isn't to changes applications using the stack paradigm but the ones using the row one, allowing them to reach smaller sizes and to be usable on constrained sizes while keeping their initial paradigm and design when the screen space is sufficient. The development cost to port the applications to this adaptive design should be as low as possible.To achieve that, I wrote a GTK+ widget which…