The development of SlideViewer A QML-based presentation program

Introduction

At Qt developer Days in Berlin 2013 I had an Aha! moment. I saw a presentation written in QML rather than the usual Powerpoint/LibreOffice/Keynote. It wasn’t that I did not imagine this was possible, rather the contrary, after all in KDAB we have more than 3000 slides on Qt-related topics, all written in …. LaTeX. It was nevertheless an Aha! moment for me, as it showed me a way out of a corner I had painted myself into.

Over the years I’ve insisted on us staying with LaTeX rather than going to LibreOffice, as that allowed me to apply numerous tools that we all knew from development, most importantly the capability to store a whole slide deck in git and have multiple people working on it at once, possibly on different branches. Just imagine you were developing a Qt application, and you were forced to store all of the application’s source files in one binary blob that could not easily be merged.

The downside with LaTeX was, however, that only a few of us knew how to operate its corner cases – It isn’t really efficient that you only have one person, the training director, who is capable of writing a macro that puts a rounded blue box around text. (And trust me that macro took me a whole day to get right).

Unfortunately the system I saw at Qt Developer Days lacked numerous key features I needed, so I decided to give it a shot myself, to implement a system that would do exactly what I needed.

Today we have such a system, and I have to admit that there were quite a few people who helped me out with the effort. Over the following four blog posts you will meet them, each telling their story about a specific piece they composed.

One person you will, however, not meet is Michel Giroday, who nonetheless deserves to be mentioned. He single-handedly rewrote most of the 3000 slides from LaTeX to the new QML-based system.

In this blog I will tell you a bit about what SlideViewer is and some of the design decisions made, but I won’t dive too deep into the technical bit. Stay tuned for the remaining four blogs for that.

Let me introduce to you: SlideViewer

So SlideViewer was born. The beauty of it is that all our Qt developers can help to add features and fix bugs, and even more importantly, we no longer have to stare at incomprehensible error messages from LaTeX, or hunt down a book that will tell us how to get page numbers in the table of contents.

SlideViewer in action looks something like this:

The above slide was written with this QML code:

Slide { slideId: 1902 title: "QCoreApplication, QGuiApplication & QApplication" topRight: SVImage { source: "images/QApplication.png" } text: "* In addition to QCoreApplication * QGuiApplication ** Window management ** Mouse cursor handling ** Clipboard interaction ** Keep track of system properties *** Palette *** Fonts *** Style Hints * Non-Widget(Qt Quick) applications" QtDoc { link: "qtgui/qguiapplication.html" text: "QGuiApplication" } }

As you can see the QML snippet is straight forward, and it displays QML’s power to be extended to a domain-specific language very well. A few notes to the above slide:

The first and foremost design goal was that it should be as easy as possible to write slides. I would under no circumstances accept any complexity in implementation that made it harder.

As an example of this design decision, the Slide element, for example, has an implicit row layout which means that elements added will automatically be stacked. The simple case must be simple.

Slide, SVImage, and QtDoc are all elements we’ve created in regular QML/C++.

A SVText element also exists which can be used like this: SVText { text: "* bullet 1 * bullet 2 * ..." } The Slide element has such an element implicit already, to which the text property links. (The simple case must be simple).

The only unexpected thing above is the slideId property which we enforce on all slides. This is simply for internal tooling, such as checking that the slide deck does not contain the same slide twice, and to allow us to jump directly from a slide displayed in SlideViewer to the slide itself in Qt Creator.

What other features does it have?

My goal from the very beginning was that it should not be more restrictive than what we already had in LaTeX. A rather ambitious goal, given that the LaTeX slides represented almost 15 years of development, and as mentioned we had more than 3000 of them! At the same time, I wanted to avoid the problems that WYSIWYG tools have, resulting in each slide looking vastly different from the others. I believe we succeeded with those two goals, and here are just a few of the features SlideViewer offers:

Code blocks are highlighted for any of the possible languages included in the slides, including QML, C++, XML, Python, and shell commands. A code block simply looks like this: QMLCode { code: "NumberAnimation on x { from: 0; to: 150 duration: 1000 }" } The highlighting happens in C++ with the help of Python for QML code and a JavaScript engine for other code snippets. This part will be discussed in detail in one of the coming blog posts. Here is another example of a slide with a code example on it: Slide { slideId: 2009 title: "Using Identities" topRight: EmbeddedQml { codeItem: exIdentity } QMLCode { id: exIdentity fileName: "../../addon/qml-intro/ex-identity/ex-identity.qml" } } In this example the code is read directly from a file, so we don’t have diverging slides and examples, and furthermore the example is instantiated directly on the slide. This is nice for two reasons: 1) No more diverging slides/code examples and images 2) If the example is interactive the trainer can show it in action directly on the slide.

Arbitrary depth of sections, subsections, sub-subsections… are possible. These levels are introduced with a simple SlideSet element: SlideSet { title: "Introduction to Qt" Slide { ... } Slide { ... } SlideSet { title: "..." ... } } And of course the slide deck can be split over multiple files. The table of contents is generated with a simple element: TOCSlide { section: "part-intro-to-qq" depth: 2 verticalCompression: 0.6 } The above results in a table of contents for the slide set with the label part-intro-to-qq to a max depth of two levels (sub-subsections) and compresses the bulleted points a bit. Each point is a link to the actual section.

We have a large Config file where the individual trainer can specify which sections he wants included and which he doesn’t. That way changing a single property in that Config file (which of course also is a QML file), he can exclude entire sections of the material, or simply individual elements: SlideSet { title: "Network Programming" include: config.includeNetworkProgramming Slide { ... title: "Error Handling" text: "..." Text { visible: config.includeSSL text: "* ..." } } }

The road ahead

When I started this mission I had two goals: 1) Get us away from LaTeX 2) Create a foundation we could use to make our trainings more interactive, more fun, and a greater learning experience. We’ve now migrated all the material, so we are on par with what we had in LaTeX. Ahead are all the fun parts.

Further, we can make any kind of interactive improvements, say a remote controller running on an Android device, where the presenter can see the next slide and/or instructor notes that will remind him of a key point on a given slide.

Another cool idea would be a test where students use their own computers to answer say a Q/A section, the statistics being shown directly in the slides as they answer.

Controlling the tools also makes it much easier for us to ensure quality in all the slides. Today, We for example already have a unit test suite that extracts single slides as PNG files for comparison against a baseline. I dare to declare that we are the first people in history to have continuous integration tests of our slide deck!

Another tool I’d like to see would enable the recording of which slides are used in which trainings, so we can improve precisely those slides used more often than others, or split out slides that most trainers spend a lot of time presenting.

In the coming blogs

This blog sets out the stage for four blogs to come which will go into details with specific technical issues we had when implementing SlideViewer, and which we believe many of you may also have in your projects. Stay tuned.