mercredi 21 octobre 2015

Games 3.18.0 released

Do you like video games but don't like how inconsistent and annoying it can be to enjoy them on a personal computer? Then read on, I have something for you! And if you're not such a gamer, you'll probably learn fun things in the article nonetheless.

In this article I'll present you the new GNOME application called Games, whose first preview version (labelled 3.18.0) just came out.

Your games library

Video games on personal computers exist in lots of shapes and formats, each of these being accessible in very different ways:

  • games installed from Software are found alongside the applications,
  • Steam games are listed in the Steam client,
  • video game consoles and retro computers games are handled as ROM files, disk images or archives, each one playable with a different application depending on the original platform,
  • some game engines have their games distributed as packages that have to be run with the correct engine, such as LÖVE or the Doom engine,
  • Web based games are available on Web browsers,
  • and there are probably more formats we didn't thought of!

There is no consistent way to access them all, which hide the fact that games are more than files or applications: they all represent the same kind of media, meaning they all share lots of metadata types which could be used to ease your life!

Games tries to solve this problem by automatically listing and presenting you the games available on your computer, letting you browse your collection and play the game you want very easily!

Currently, Games handle these game types:

  • your regular desktop games,
  • your Steam games,
  • your LÖVE games,
  • your NES/Famicom games,
  • your SNES/Super Famicom games,
  • your Game Boy/Game Boy Color games,
  • your PC-Engine/TurboGrafx-16 games.

More games are listed but are not playable yet, and more will come in the future!

Game integration

Games tries to integrate games as tightly as possible. An example of that is the usage of the Libretro API (via the Retro and RetroGtk libraries) which allow it to integrate some gaming console emulators and some video game engines directly into the application, making them installable as plug-ins and avoiding to cripple your file system with support for gaming platforms you don't care about. Thanks to this API, Games can treat emulators and engines just as a music player would treat audio codecs and play the games itself, controlling lots of details in the process, such as:

  • the execution of the game,
  • the outputs (the audio, the video, the gamepad's vibrations, ...),
  • the inputs (the pressed buttons, a camera, ...),
  • serializing the emulator/engine's state,
  • and more!

An obvious feature is that we can integrate the inputs and the outputs into Games' window, but a particularly interesting feature we can offer by leveraging the serialization capabilities of the API is to propose you to resume the game where you left it!

For this release, only the NES, SNES, Game Boy and PC-Engine games are integrated. You can control them using your keyboard with the following hardcoded mappings:

Keyboard NES/Game Boy SNES PC-Engine
Arrow keys D-pad D-pad D-pad
Return key Start button Start button Run button
Backspace key Select button Select button Select button
D key A button A button Ⅰ button
S key B button B button Ⅱ button
W key - X button -
A key - Y button -
Q key - L button -
E key - R button -

Future

Covers, icons and other metadata

Currently, the listed games have very few available metadata, some don't even have an icon or a cover. We obviously want to offer covers or icons for all the games, but we also want to go further by using metadata to offer interesting features such as refined search.

Game controllers

Game controllers can range from regular gamepads to dance mats, via light guns and guitars. Unlike keyboards and mice, game controllers are available in very different shapes and sizes and have equally different kinds of inputs (analog or digital buttons, direction pads, analog or digital joysticks, triggers, spinners, motion sensors...), making them really hard to handle by developers. Even controllers that are very similar — such as the Xbox and PlayStation gamepads — can have buttons placed similarly have different hardware button numbers in the drivers: even wired and wireless Xbox 360 controllers have different button numbers!

These details make game controllers hard to handle, as you have to know the type of the controller, the number and kind of inputs it has, and its layout.

You probably want gamepad support, and not to configure it if possible. To do that we will have to add a gamepad configuration facility — preferably in the Control Center — and to gather the gamepads' layout descriptions and button mappings.

More games

Currently, only a handful of game types are playable and barely more are listed. We want to support (and integrate) as much games as we can!

Improved search

Looking for games should be refined: we want you to be able to filter games depending on their genre, on the allowed number of players, on the required controllers, on their developers...

Deeper integration into GNOME

Games could be a Shell search provider, allowing you to quickly search and run any game.

Also, the Control Center should be leveraged to configure the gamepads.

Help wanted

If you want to test the application, you have some crazy ideas we could implement, you know some crazy game formats and consoles we didn't think of, you know an awesome video game database website we could use, you are a specialist of some particular format/architecture (MD-DOS games, ScummVM, ...), you know OpenGL, GtkGLArea, PulseAudio...: we need your help!

Cake, and grief counseling, will be available at the conclusion of the test.

mercredi 26 août 2015

GUADEC 2015 was awesome!

I went to GUADEC 2015 which was help in Gothenburg between friday 08/07 and wednesday 08/12, here is what I did there.

Deserved thanks

First of all, I would like to sincerely thank the organizers of this GUADEC, they made an amazing job! =)

I also would like to thanks the GNOME Foundation, the GNOME Travel Committee and the persons volunteering to work for this committee as I wouldn't have been able to attend the conference without their sponsorship.

Volunteering

I volunteered to help during this GUADEC and it was a great experience. I only had few work to do as there was a ton of volunteers, all I did is to help cleaning the rooms and to be in charge of presenting the speaker, filming its talk and give him a gift for two talks on sunday.

Being able to see the Beamer theme I wrote used was quite pleasing too. =)

The core days

On Friday

  • Alexander Larsson's talk on xdg-app got me really excited about this big shift the Linux desktop is taking,
  • Emmanuele Bassi's talk on GSK showed us how it will be used as an intermediate layer between GTK+ and GDK,
  • Caolán McNamara taught me about the relation between LibreOffice and GTK+3,
  • Matthias Clasen showed some pretty interesting stuff that GTK+ can do,
  • Alexander Bokovoy's talk taught me a LOT of stuff I didn't now about like double factor identification, and how they are use by GNOME for enterprise desktops,
  • I gave a lightning talk on my work on Boxes this summer.

On Saturday

  • Frédéric Crozat talked about what have been done at SUSE to adapt GNOME to their enterprise customers,
  • Christian Hergert made me actually use Builder =),
  • Jan-Christoph Borchardt gave a engaging talk on how ownCloud and GNOME would have a tighter relationship.

On Sunday

  • Jonas Danielsson got me excited about the future of GNOME Maps =),
  • Pamela Chestek gave an awesome talk on how she helped GNOME to stay GNOME,
  • Jussi Pakkanen talked about the Meson build system,
  • I filmed Markus Mohrhard's talk on LibreOffice integration within GNOME Document, with an interesting first part by Pranav Kant who showed his summer work on LibreOffice and GTK+3,
  • I filmed David King's talk on logging and statistics,
  • The lightning talks were awesome: they features a troll and an helicopter pilot.

The BoF sessions

On Monday

  • I attended the informal GNOME Maps BoF, it was extremely interesting to get more information on the future of the project. I looked at the Mapbox GL C++/ vector tile library to check if it was interesting to bind it/port it to C/GObject.

On Tuesday and Wednesday

  • I hacked on Boxes with my mentor Zeeshan Ali, improving my patches for the new collection filter and the list view.

The faces

  • It was a great pleasure to see lots of known faces,
  • And obviously discovering lots of new ones was great too, =)
  • My face—name—nickname relationships got improved!

The places

  • The free ferry was great =),
  • The Slottsskogen park and its zoo were really cool to visit,
  • The city is full of interesting pubs,
  • Walking in Gothenburg is really enjoyable once you understood were are the bike lane and that you should never ever put a foot on one =p,
  • There are lots of vegetarian and vegan restaurants, and the ones which are not have good veg(etari)an offers, which is nice when you want to eat as a group,
  • Staying at the hostel was a nice experience as you never stop to be in the GNOME communitythis way!

lundi 17 août 2015

Adding a list view to 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!

Writing a custom spinner

What are spinners

A spinner is a widget in charge of displaying some indefinite amount of activity via a spinning circle-ish image. They use de "spinner" style class and are visible when the "active" state flag is set.

Turning a widget into a spinner

Turning a widget into a spinner is pretty simple, just add the "spinner" style class to the widget's style context! But now your widget is probably invisible, and that's normal: as said just before, spinners are drawn only if they have the "active" state flag on, just set your widget's state flags and you're done!

Now, depending on the widget you make spin you may have very different results. If your widget is a GtkImage, it will start spinning as if it was a spinner itself, funky results (and vomit) guaranteed! All the other widgets I tested (GtkLabel, GtkBox, …) don't change (they are visible and they don't spin).

If you want to render a spinner on an existing widget, you'll have to subclass it and to override its gtk_widget_draw() method to draw it and then render the spinner with gtk_render_activity().

If you want to render a spinner on an image, you'll unfortunately have to write a custom widget drawing the image and then the spinner on top of it.

Writing a custom spinner widget

Now that we know how to turn a widget into a spinner, we can build our very own custom spinner widgets!

I wrote a widget rendering a thumbnail for Boxes' list view. To do so:

  • I inherited GtkDrawingArea,
  • I overrode its gtk_widget_draw() method to draw it as I wanted,
  • I added the "spinner" style class to the widget so it can render the spinner,
  • I set the widget as active so it can be visible despite the "spinner" style class,
  • I drew the base of my widget as I wanted it to be,
  • I drew the spinner with gtk_render_activity() on top when I wanted it to be drawn.

Unfortunately you can't use the "active" state as a trigger without removing the "spinner" style class, hence it is simpler to just let them always on and add a custom trigger to draw the spinner itself or not.

Customizing the spinner

You can customize a spinner with CSS! As an exemple, if you want to slow down the spinner a bit, you can write the following "slow-spinner" class and add it to any spinner's style context:

.slow-spinner {
    animation-duration: 2s;
}

If you know or learn anything interesting about spinners, don't hesitate to share you knowledge in the comments! =)

mardi 28 juillet 2015

See you in Gothenburg!

I'm glad to announce that I'm going to the 2015 edition of GUADEC!

I'm delighted to be able to attend GUADEC for the second time, as my first experience in Strasbourg was extremely enriching. I hope I'll see lots of known and new faces. =) As an intern, I'll give a lightning talk about what I've done so far for GNOME Boxes.

I would like to warmly thanks thanks the GNOME foundation for sponsoring by travel, especially the donors and the GUADEC team and the travel committee.

It will be the first time I go to Sweden, I'm sure the trip will be fun.

Vi ses i Göteborg!

mercredi 15 juillet 2015

GUADEC 2015 get its Beamer template!

Lasse and I spent some time recently to produce a Beamer template for GUADEC 2015. You can find it here: github.com/sils1297/guadec-presentation-templates.

You can use it with Pandoc or directly with LaTeX. Example are shipped too:

  • 2015/presentation.md is a Pandoc example, build it with make pandoc to produce 2015/presentation.pdf;
  • 2015/guadec-example.tex is a LaTeX example, build it with make tex to produce 2015/guadec-example.pdf.

I hope you'll enjoy it, feedback is welcome and if you have any problem don't hesitate to contact me (Kekun) or Lasse (sils) GIMPNet #guadec on GIMPNet.

samedi 11 juillet 2015

Monster and Naoki Urasawa

Monster

Thanks to summer granting me some free time, I've finally been able to complete the Naoki Urasawa's Monster manga series.

If you don't know Monster, it's a psychological thriller telling the story of Dr. Kenzō Tenma, a young Japanese neurosurgeon working in Düsseldorf, who decided to save the life of the young Johan Liebert rather than the the one of the mayor the city who arrived at the hospital roughly later. His life then changed when a series of murders happened in the hospital, all of persons whose death would improve the hero's career, making him the prime suspect of these cases. But it turns out that the little boy he saved may not be innocent to this cases…

This very well paced story—full of thrills and mystery and served on a background of dreadful psychological experiments—asks lots of questions about the price of life, the right to choose which life to save, the good, the bad, humanity, and ultimately, the price of death. All of that is very well presented by beautiful graphics and interesting characters.

Naoki Urasawa's works

Naoki Urasawa's mangas clearly follow a pattern: 20th Century Boys and Pluto, two other series by him that I read, have very similar stories, abord similar topics, contain similar characters with similar development and a global "end of all good in humanity" tone; but all of present different universes and are very well executed. 20th Century Boys deals more about suspicions and sects, while Pluto is more about humanity in robots.

If you want to try out some of its work, I would definitely recommend you to do so, starting either with 20th Century Boys if you want to try out "pure" Urasawa, or Pluto if you want a shorter series and to be presented to Astro Boys universe in a darker tone.

vendredi 3 juillet 2015

Boxes' thumbnails overhaul

I recently spent quite some time reworking the overall look of Boxes' machine thumbnails. Here is the result.

Boxes' new thumbnails

Stopped boxes

Up until now, Boxes' stopped machines were represented by a black box. It was nice as it represented the idea of a shut down screen, but it was pretty hard to differentiate a stopped machine from a running one displaying a black screen. This was stated in bug #730258 where Jimmac suggested to follow this design where thumbnails are draw as gray frames with a medium sized emblem in their center, using the system-shutdown-symbolic icon to suggest the stopped state.

Boxes' old thumbnail for stopped machines Boxes' new thumbnail for stopped machines
Boxes' thumbnail for stopped machines: old (left) and new (right)

Updating the other thumbnails

Machines under construction used to simply display their thumbnail with a spinner on top. This doesn't change but stopped machines being constructed now display their spinner in a frame, to be consistent with the new thumbnail for stopped machines.

Boxes' old thumbnail for machines being imported Boxes' new thumbnail for machines being imported
Boxes' thumbnail for machines being imported: old (left) and new (right)

The default thumbnail for machines was a big computer-symbolic icon. It have been changed to the new gray frame style, keeping the computer-symbolic icon as the thumbnail's emblem.

Boxes' old default machine thumbnail Boxes' new default machine thumbnail
Boxes' default machine thumbnail: old (left) and new (right)

Thumnails are now consistent, elegant, and the machine's status is more understandable.

Working on this feature helped me to discover bug #751494: GDMainIconView draw pictures without their last column of pixel.

Favorites

The way a machine is shown as favorite has also been revamped. A big heart shaped icon (the emblem-favorite-symbolic icon) was added to the bottom right corner of the thumbnail, and this was causing multiple problems (see bug #745757):

  • the standard icon to show something is favorited is a star (the starred-symbolic icon),
  • and more importantly, its position was conflicting with the one of the selection checkbox!
Boxes' old emblem for favorite machines Boxes' new emblem for favorite machines
Boxes' emblem for favorite machines: old (left) and new (right)

A machine is now shown as favorited by adding a tiny star to the bottom left corner of its thumbnail.

Unfortunately, problems still exist as the white star becomes invisible on a white thumbnail (see bug #751478). I tried to solve this problem, by making the star casting a shadow, which worked well but it required me to implement a blurring function into Boxes' code, adding 100 lines of Vala to an already complex codebase for one tiny functionality which has nothing to do with the application's domain, hence this solution haven't been retained.

The emblem for favorite machines is invisible on a white thumbnail Adding a shadow under the emblem solves this problem
The 'favorites' emblem with and without a shadow

Zeeshan suggested trying to solve this by using the image's energy, as the code to do such a thing already exists. This solution still has to be explored.

mercredi 17 juin 2015

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

mardi 9 juin 2015

Playing with GtkAssistant

I decided to spend some time today to play with GtkAssistant, more precisely, I tried to build a mock installation wizard mimicking Boxes' one in order to test how I could adapt its behaviour to make it GtkAssistant ready.

Overall, I enjoyed using GtkAssistant, it is a quite well thought out widget offering a lot of potential for a small API.

But despite how good GtkAssistant is, I encountered problems adapting it to my need. Here follows a list of what bogged me down.

A sequence of pages

GtkAssistant is great at implementing a sequence of pages, unfortunately, Boxes' wizard is more like a graph of pages.

Boxes' wizard's page graph
Boxes' wizard's page graph

Such a configuration is clearly out of GtkAssistant's scope and it can easily be solved by arranging the pages as a sequence and setting a custom "forward" function, so it's not that much of a problem.

Action area

GtkAssistant allows you to mark a page as custom, which will show no button in the action area when visiting this page. You can then add buttons to the action area in order to give some controls to the user. Unfortunately, I found no way to add buttons to the left side of the action area, usually containing the "back" and "cancel" buttons, which is pretty annoying.

Adding a way to add widgets to the left side or to hide only the buttons of the right side of the action area would help. In the end, I didn't found a way to make the "custom" page type useful to my case (which may just be better in the long run).

Content padding

GtkAssistant sourround its pages with some padding, which most of the time is a good idea, unfortunately one of the pages I want to use is a big and complex widget (a GtkFileChooserWidget) which need to take as much space as possible for the user's ease, but also not to look ugly.

In red, the unwanted padding
In red, the unwanted padding

Cancelling a progressing page

You can't cancel (and go back from) a page typed as "progress" if it haven't been completed. It may make sense if the work in progress must be finished properly, but it's not always the case.

For example, Boxes use a progress bar to indicate that an installation medium is being downloaded, but such a task should be cancellable by the user (he could notice that he isn't downloading the right image), so even if the "progress" page type seems to correspond to this use case, it can't be used because it doesn't allow you to cancel a possibly wrong and probably long task.

It's not that much of a problem though as a regular page can be tweaked to have the desired behaviour.

Transition animations

There is no transition animation when moving between pages. It's not a huge problem but having some animation could make the page transitions more understandable. I would love to have a left to right animation when progressing forward and vice versa when progressing backward. =)

Help wanted

If you are a Gtk+ developer or that you know how to fix some of these problems, especially the padding one, I would greatly appreciate you help! =D

dimanche 7 juin 2015

Boxes' hardening sprint: two weeks in

Finishing my 4th year of CS studies

I spent the last two weeks working hard on the report and the presentation of the project my colleagues and I worked on all the semester long: creating the Stibbons multi-agent system programming language and development environment.

I am very proud of what we accomplished and I’ll probably present it to you in the upcoming weeks. =)

Planning the port of Boxes' installation wizard to GtkAssistant

All this work unfortunately let me little time to work on Boxes, but I nonetheless took some time to look at how its installation wizard is implemented and planned how to port it to GtkAssistant.

Boxes' installation wizard

Currently, the wizard is ordered that way:

  • WizardWindow
    • WizardToolbar: the toolbar containing the navigation buttons
    • Wizard: the stack of pages

Most of the wizard’s intelligence seems to lie in Wizard and its pages, I’ll have to dig further into Boxes' code in order to fully understand how the wizard work.

GtkAssistant

A GtkAssistant is a window which allow a developer to guide the end users through complex configuration processes by splitting them into several steps represented by pages that can be completed.

GtkAssistant’s API is pretty simple, you can:

  • add or remove pages to the assistant
  • navigate through them
  • set the title of a page
  • set the type of a page
  • set whether a page has been completed or not

If a page has been completed, the toolbar allow the end user to move to the next page, except if it is the last page in which case it will allow him to complete the whole configuration process.

The plan

Despite a similar behaviour from the end user’s perspective, the wizard’s behaviour differ significantly from the one of GtkAssistant. Some tailoring will be required to make them match.

To smoothly pass from the current wizard to a new one using GtkAssistant, I plan to follow these steps:

  • implement one by one the needed components (understand “logical sets of public methods”) of GtkAssistant into WizardWindow:
    • setting and getting the current page
    • setting and getting a page’s title
    • setting and getting whether a page have been completed or not
  • once all the necessary components have been implemented, make WizardWindow inherit from GtkAssistant and remove the custom method implementations
  • remove the now unneeded WizardToolbar and Wizard classes.

Hopefully, next week will be enough to implement such a change!