Archive for September, 2009

Palapeli: The new window layout

Palapeli has reached about 2000 lines of code. Today, I combined both the puzzle library and the puzzle table into one window. This is how the application looks like now:

The Palapeli window, showing the puzzle library

The Palapeli window, showing the puzzle library

The Palapeli window, showing the puzzle table

The Palapeli window, showing the puzzle table

The new interface layout is based on two fundamental findings:

  1. All actions (except for the standard actions like “Help” and “About…”) do only make sense when one of the two views (puzzle library, puzzle table) is visible. I’ve therefore decided to place the toolbars for those actions inside the tab pages.
  2. With this change, the only remaining interface parts outside the tabs are the tab bar and the menu bar. Those are both concentrated at the left side, wasting much space at the top right corner. To save space, I’ve put the menu bar into the tab bar. After this change, I found that the new order is much more intuitive (at least to me): The tabs are at the place where the user expects menu items, and also feel much the same. The only difference is that they do not open a submenu, but another part of the application.

There are two problems left with this layout: The menu bar is now always at the right end of the window, while I would like it right next to the tabs to emphasize the altered role of the tabs. I’m still investigating on how to solve this issue. The other issue which I also couldn’t solve yet is that good ol’ “Configure toolbars” dialog does not work.

Update: Issue 1 is solved.

Apart from that, the next tasks are library management (i.e. import new puzzles, delete puzzles from the library, and KNewStuff integration).

Comments (9) »

Palapeli: Four days of work

Welcome to another part in my series of progress reports on rewriting Palapeli (see here and here for the previous parts).

Since yesterday, the code has increased from 1367 to 1822 LOC (a quite steady growth). Palapeli now has again a nice interface for its puzzle library (level names are not hardcoded anymore). Also, the progress on the puzzle table is now saved automagically again. (One note: If you want to try Palapeli from trunk, note that there is a delay of about half a second when loading a puzzle for the first time. This is no bug.)

State of the new Palapeli after four days

State of the new Palapeli after four days

Of course, this GIMP-like interface is in no way final. Everything will be combined into one single window in a clever way, as you’ll probably see tomorrow.

Comments (4) »

Palapeli: Three days of work

Since yesterday’s post, the code of Palapeli has increased from 863 to 1367 LOC, with many user-visible changes: The puzzle table textures are back (not in the picture: the texture selection menu), the jigsaw slicer is back, and the view is more clever about scaling the viewport.

State of the new Palapeli after three days

State of the new Palapeli after three days

Coming up next: loading and saving progress, and an interface for the library.

Comments (3) »

Palapeli: Two days of work

Just a quick update: I’m progressing quite well with rewriting Palapeli. After two days, there are 863 LOC (measured with sloccount), which includes the slicing library, the puzzle file generator, and the main application. The latter is currently capable of loading arbitrary puzzles into a quite functional puzzle table, though there is no interface to select puzzles yet (“citrus-fruits.pala” is hardcoded). The next tasks are some comfort stuff in the view and saving progress.

State of the new Palapeli after two days

State of the new Palapeli after two days

Comments (5) »

Kolf, Palapeli: Total change of course

What’s a clear sign of craziness? Scheduling a project to be finished in two weeks, and then completely rewriting it.

Long story short Short story long: I’ve noticed that I’ve (effectively) only seven to eight days left until university courses start again. This is not enough time to get Kolf 2 into a state that allows us to release it. The editor is (from a user’s perspective) nearly useless (though many important foundations have been laid), the terrain has weird collision bugs (I hoped that these problems stop with usage of an external physics engine *sigh*), we’re lacking good textures and of course courses (pun intended).

So, we’ve (more or less) decided to not release Kolf 2.0 with KDE 4.4. I’m not sure about when Kolf 2.0 will first appear. We might do some preview releases before the KDE 4.5 alpha/beta cycle starts, but that has not been decided yet.

Instead, I’m doing something that could be achieved in seven to eight days of intense work. Some months ago, I wrote libpala, a new library as a foundation for Palapeli (my jigsaw puzzle game). Unfortunately, libpala is so different from the old libpalapelibase that I effectively have to rewrite the whole game. Still, this task is much easier than getting Kolf 2 ready, and I’m confident to get everything finished in time to get Palapeli included in KDE 4.4.

Leave a comment »

Say hello to Utils::SelectionDialog

Preface: In my new series “Say hello to…”, I regularly present you additions to my Git-based collection of useful helper classes and smaller projects (see its very simple homepage for more information).


Today, I needed a dialog for Kolf that shows a list view to the user, and lets him select some items from that (plus the “OK/Cancel” buttons which you’re used to from modal dialogs). I had to create a new class, complete with own header and source file, because I needed to declare a new KDialog subclass with a slot.

Incidentally, I’ve already created such dialogs for Palapeli. And much of them. So this is a task that should clearly be simplified. This is how the SelectionDialog class came into life. See the APIDOX in its header for details on how to use it.

Leave a comment »

RFC: Texture range selector design

Here’s your chance to help KDE: I need some quick opinions on the design of a widget, for which I’ve made a mockup.

Basic situation: Kolf needs a new configuration interface for its texture blender. The task of this texture blender is to create a texture for a given heightmap. It uses several base textures and inserts these base textures into the result at different height ranges. For example, low heights might be painted with a water texture, medium heights with a grass texture, and high heights with some stone texture. That’s what the interface looks like currently:

Current state of the texture blender (click to enlarge)

Current state of the texture blender (click to enlarge)

On the left side is a list of all base textures. Each base texture has three values (out of a range from 0 to 255, where 0 is the lowest height level, and 255 is the highest one). The left and right value are the minimum and maximum height where this base texture is used. The middle value is the height where the base texture is inserted in the texture in a completely unaltered manner. (I call this “median height” from now on. Above and below this height, the texture is darkened and lightened to create a depth impression.) Everyone here should agree that this configuration interface is completely obscure (would you have guessed that you have to click on the textures to edit these heights?) and much too techy.

Gladly, one of our artists has proposed a new interface, and I have made a simple mockup (only for the left side, the texture preview at the right which will stay there):

Mockup for the new texture blender (click to enlarge)

Mockup for the new texture blender (click to enlarge)

This design is based on a layered “stack” of base textures (at the left). The higher a base texture is in this stack, the higher are the heights at which this base texture is used. One can drag the textures along the vertical axis to re-order them. The right side is the actual height range selection. The first, third and fifth marker stand for the aforementioned median heights, while the second and fourth marker denote the area where one texture is gradually replaced by the next one.

One special note: The textures on the left axis are not on the same height as the median markers on the right axis. This is intentional because this restriction might cause texture images on the left axis to overlap, which is something which I want to avoid.

Here is my RFC: What do you like and dislike this mockup? Do you have further ideas on how I can improve this interface? How should user interaction be implemented? I have some basic ideas for the last point, but am eager to hear your ideas and do not want to bias you. Apart from the obvious mouse interaction (i.e., dragging the base textures to reorder them, and dragging the markers to change the height ranges), the user needs to be able to add new base textures, and delete base textures from the stack. Also, keyboard control might be good for accessibility and convenience.

Comments (3) »

Say hello to StaticVector!

I present you the second addition to my Git-based collection of smaller code pieces (which now also has a very simple homepage).

This time, I show you a generic container class. There is already a big bunch of container classes in Qt, but I had to make one that fits my needs: the StaticVector.

Its API and purpose is similar to QVector, but it behaves quite differently: A StaticVector does never reallocate or resize its data unless it’s explicity told to do so. Also, any copy of a StaticVector will be read-only, because the data is implicitly shared for performance reasons, but write operations would require the copy to detach from the original data (which is an implicit reallocation, which is forbidden).

The usecase for this is quite simple: In Kolf, we are regularly passing big data arrays to OpenGL and ODE. And passing big arrays to methods from C libraries almost always requires one to pass a base pointer and a size, i.e., two parameters. With such data encapsuled into classes (such as QImage), you might end up with a situation like the following:


void passData(uint* data, int size);

class MyContainer
{
QVector m_payload;
public:
QVector payload() const { return m_data; }
//...
};

MyContainer container;
//...
passData(container.payload().data(), container.payload().size());

This is asking for trouble. The two calls to MyContainer::payload() in the last line create two temporary objects. The latter one is not problematic, because QVector::size() is a const method, but QVector::data() is a non-const method (because the C library wants a modifiable pointer). Calling it causes this temporary QVector instance to detach from the original payload, i.e., allocate new memory and copy the data to there. The C library will remember the pointer to this newly allocated data. After the passData method call, the temporary QVector instances are deleted, which causes the newly allocated data to be deallocated. When the C library tries to access this data later on, we’ll get a SIGSEGV or even uglier things.

That’s where StaticVector comes in. If you substitute QVector with StaticVector in the above example, everything works well, because the temporary StaticVector instances are read-only, but (for this usecase) may return a non-const raw data pointer.

If you ever need to use C libraries which want non-const data pointers, StaticVector might be a good choice for you, because it allows to get this non-const pointer even from const or read-only StaticVector instances, while it minimises misuse of this pointer as much as possible.

Comments (3) »

Say hello to QRangeSelector!

As suggested yesterday, I’ve set up a Git repository for “a broad collection of smaller code pieces which I’ve acquired over the course of my life”. Find it at http://github.com/majewsky/majewsky-misc/, and clone it from git://github.com/majewsky/majewsky-misc.git.

As some first entry, I actually put some stuff I’m currently working on. In line with Andreas Marschke writing about his recent work on a generic video widget, I’m announcing QRangeSelector. This class is similar to a normal slider, but it does not only allow to select a single value, but to select a range of values from some bigger range. (One may also, given some big range, select a small range from it, and select a value within this range.) QRangeSelector also allows for arbitrary contents to be drawn inside its slider area. This screenshot illustrates some usecases which I need in Kolf. (If you do not see the benefit yet, I’ll do a screencast once the QRangeSelector is used in Kolf.)

Testcase for QRangeSelector widget

Testcase for QRangeSelector widget

Note: The white widgets at the top and inbetween the two QRangeSelectors are simple line edits. I needed those to test keyboard focus.

Comments (8) »

Anticipation

In a programmer’s life, one acquires many smaller code pieces which one might want to share. In my case, I have two sources of smaller code:

  1. In my home directory is a huge directory called “code”. Inside this directory is some directory called “misc”, with other 30 smaller programs (most of them tests for some smaller feature, or a calculation program for some university task).
  2. Esp. during my work on Kolf 2, I’ve written many small utility classes which might also be usable in other situations (most prominently the range selector widget which I’m currently working on).

Over the course of the next days, I’ll select some code from these sources, and make it available publicly in a Git repo under the MIT license (a simplified form of the BSD license and a very liberal and easy-to-use license). Stay tuned.

Comments (3) »