Adding a List View to Boxes

boxes

A list view was a requested feature for Boxes, I decided to commit myself to implement this during this GSoC.

March: exploring the idea

I started working on adding a list view to Boxes in march 2015. By that time, the expected columns for the list view where:

  • the thumbnail;
  • the machine’s name;
  • a system monitor;
  • the machine’s IP;
  • the OS’ icon;
  • an icon to display show a favorite machine.

Implementing such a view using libgd’s MainView (the same widget responsible of the icon view) required me:

  • to learn how to write a custom GtkCellRenderer for the system monitor;
  • to find how to get a machine’s IP adress;
  • to find how to OS icons are retrieved in Boxes.

Unfortunately, I had to pause the implementation of this feature to focus on my studies.

July 6–12: designing the list view

I joined a chat on Google Hangout where Alan Day, Jakub Steiner and Zeeshan Ali on july 8th. During this talk, Zeeshan stated its desire to stop using libgd—suggesting to use GtkFlowBox and GtkListBox to implement the icon view and the list view respectively—and Jakub produced the following mockup. Even though I didn’t talked much (if at all), it was really enriching to follow such a discussion.

As you can see, there is no system monitor nor the OS’ logo, and columns to show the machine’s state and a selection state have been added. I then scrapped the system monitor cell renderer I implemented and integrated the previous days.

With this new design, I had enough material to start implementing the list view.

I needed the content of the widget to be sortable and filterable, hence I implemented the BoxesSortedListModel and BoxesListModelFilter classes to allow me to do so, as I didn’t notice at that time that both GtkFlowBox and GtkListBox offered such capabilities.

I started producing the BoxesCollectionItemListView widget to render a collection item in the list view and the BoxesCollectionListView to implement the list view. By that time, most of the expected features worked but annoying bugs were remaining and the look was far from being polished.

July 13–19: polishing the list view

I removed the ListModelFilter and SortedListModel classes to favoritize GtkListBox’s filtering and sorting functionalities.

The theme have been refined using CSS, the selection mode have been added and several bugs have been discovered and fixed.

Bug #752615 in GtkListBox have been discovered, a workaround have been added in Boxed.

July 20th: submitting patches

On july 20th, I reorganized the patches and polished their logs to look nicer, then I attached them to bug #733252. Their review is in progress and I hope they will be committed before the UI freeze.

GUADEC: reworking the thumbnails

During the 2015 edition of the GUADEC, I’ve been able to meet my mentor, Zeeshan, to more easily discuss the design of my code and more importantly, the disturbance created by the changes I made.

Following is a list of the problems I encountered and how I tried to solve them.

    • Problem: The MachineThumbnailer class have been created because the icon view needed a GdkPixbuf as a thumbnail, and the list view’s thumbnail is expected to have a different style than the one harcoded in MachineThumbnailer.
    • Solution: Create the custom MachineThumbnail widget, responsible of rendering a machine’s thumbnail, taking advantage of the CSS styling and the states to offer a more refined view.
    • Problem: We now have two very close yet slightly different objects, some refactoring may be a good idea.
    • Solution: Add and use the MachineThumbnailDrawer class, allowing to draw a thumbnail on any Cairo context — hence on a GdkPixbuf or a widget — and with a given style and state. The MachineThumbnail and MachineThumbnailer classes used it to draw.
    • Problem: MachineThumbnail have different behaviours depending on its states, while MachineThumbnailer always draw with the same style.
    • Solution: Use the same style for MachineThumbnail, whatever its state is.
    • Problem: We now have two objects with a really close behaviour now, it may be simpler to only use one.
    • Solution: Make MachineThumbnailer customizable enough to be able to render pixbufs for both thumbnails, and make the list view’s thumbnail a simple GtkImage.
    • Problem: The list view thumbnail’s spinner make the whole thumbnail spin now!
    • Solution: Use a proper GtkSpinner and switch between it and the real thumbnail when needed.

Conclusion

This feature have been really interesting to implement, it improved my understanding of what behaviours are good to have when introducing new code, and even if I still struggle to write really good commit messages, I feel like I nonetheless got better at it.

I also learned an awful lot about GTK+: I learned:

  • how to use GListModel,
  • how to use GtkListBox,
  • how to use GtkFlowBox,
  • how to implement custom spinners,
  • how to theme a widget with CSS,
  • how to use the widget states,
  • and so many more!