14 Jun 2005 brouhaha   » (Journeyer)

More Nonpareil printer work, especially on the GUI

There's some bug that prevents the printer simulation from working on my Fujitsu Lifebook subnotebook (800 MHz Crusoe processsor), but I haven't yet had a chance to try to debug it. It works fine on my other machines, aside from the problem I noted yesterday with use of the Paper Advance button when the calculator is in program mode.

I added the double-size mode, selectable by a menu item. Internally there's an integer for the scale, so it could have values greater than 2, but right now the UI only allows toggling between 1 and 2.

I can't decide whether to use radio buttons for the printer mode (NORM/TRACE/MAN), or a menu with radio items. I've got both in the code now, with defines to select at compile time. For radio buttons, I think I prefer the three radio buttons arranged vertically, with the Print and Paper Advance buttons arranged vertically to the right of the radio button group. Anyhow, if buttons are used (even just for Print and Paper Advance), some effort needs to be put into making the layout aesthetically pleasing.

The arrows on the scroll bars on the printer output menu weren't working, though dragging the ``thumb'' or clicking in the paging regions (between the thumb and arrows) worked fine. It turns out that the default step_increment in the adjustments used by the GtkScrolledWindow and GtkLayout are zero! I would have expected them to be one (pixel), though that wouldn't have been much better. Anyhow, I'd never dealt with GtkAdjustments before, but they're fairly simple. I set the horizontal and vertical step_increments to the size of one character. Now that I think about it, they really need to be the size of a scaled character, and updated if the scale changes.

And once I did that, I realized that the GtkAdjustment was the key to making the printer output window automatically scroll as new output is added. I wanted that to happen only if the window was already scrolled to the end, so that if the user manually scrolls to some other part of the output, newly generated output doesn't keep jumping it to the end. At the beginning of gui_printer_update(), I do something like this:

  bool was_at_end = ((p->v_adjustment->value + p->v_adjustment->page_size) >=
		     p->v_adjustment->upper);

Then at the end, I do:

  if (was_at_end)
      gtk_adjustment_set_value (p->v_adjustment,
				p->v_adjustment->upper - p->v_adjustment->page_size);

It seems to work quite well. It would be nice to have examples like this in the GTK+ API documentation or the tutorial.

P.S. To anyone with a lot of GTK+ experience this stuff probably seems blindingly obvious, but GUIs aren't really my area of expertise (despite having hacked Macintosh code since late 1984). In the Nonpareil project, my main interest is the guts of the simulation, and the reverse-engineering aspects (figuring out the internals of the old HP calculators). I'm doing the GTK+ work because I didn't think I could find anyone else willing to do it for me, but it's turned out to be quite fun. And maybe GTK+ expertise is a marketable skill. I wonder what percentage of GTK+-based development is done in C, vs. C++? I normally avoid C++, which is exactly why I chose GTK+ over Qt or WxWidgets.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!