2013/09/30

Perl - Tickit - 0.40

Latest Tickit version (0.40) is now up on CPAN. Recent changes include:

  • Mouse drag-and-drop events (0.32)

    Windows now create more interesting events to represent mouse drag-and-drop operations. Starting, moving, and ending a mouse-drag all create events that can help widgets render more interesting behaviours.

  • Added Tickit::RenderBuffer (0.33)

    RenderBuffer is an in-memory buffer to store content that will eventually be rendered to the terminal. In effect it stores a double-buffer of content, allowing widgets to draw in whatever order is most convenient for them, before efficiently flushing it in a top-to-bottom manner.

    Being implemented in C/XS instead of Perl allows it to operate more efficiently than the previous-generation direct rendering to Windows. As it stores the content before rendering it also allows better handling of Unicode line-drawing characters; allowing for characters to be merged together out of multiple line segments, creating the ability for complex line-drawing shapes to be easily rendered.

  • Added timer support to core event loop (0.34)

    Widgets can now react to timed events, allowing for animation effects and other behaviours.

  • Focus management (0.34 and 0.35)

    Container widgets now provide management of the focus-chain order of their children, allowing the whole widget tree to maintain the "next" and "previous" direction of focusing. The base code handles the <Tab> and <Shift-Tab> key events to cycle input focus around the widget tree automatically.

  • Use RenderBuffer in favour of direct Window rendering (0.40)

    Now that RenderBuffer is in the core distribution, all widgets should be using it rather the previous render method to render directly on the window. This is a stepping-stone change to allow for further improvements.

  • New sizing model (0.40)

    New methods are provided by the base Tickit::Widget class that cache the requested size of the widget, and only inform the parent container when this size actually changes. This allows for more efficient reshaping and redrawing operations when widgets change their size requirements, without needing to recalculate the whole widget tree.

These final two changes help support a couple of interesting planned improvements:

  • Widget minimal/maximal size handling

    Because the base widget class now handles size information more directly, it can implement bounds on minimal and maximal widget size. These will be derived from Tickit::Style. It may also be possible to consider padding and margin controls in the base widget class and thus automatically apply to every widget.

  • Whole-tree rendering via RenderBuffer

    By adding area masks to RenderBuffer it should then support being used as a single buffer object to render the entire window hierarchy. Because the masking code will be implemented in C code, it will much more efficient than the current pure-perl Window-based solution involving visibility testing per character cell. This will allow for much more better redrawing performance.

    This will also allow RenderBuffer to move out of the Tickit.xs file and into libtickit itself, where it can be useful to non-Perl code (such as native C programs or other language bindings).