NAME

XUL::Gui - render cross platform gui applications with firefox from perl

VERSION

version 0.20

this module is under active development, interfaces may change.

this code is currently in alpha, use in production environments at your own risk

the code will be considered production ready, and interfaces finalized at version 0.50

this documentation is a work in progress

SYNOPSIS

use XUL::Gui;
display Label 'hello, world!';

# short enough? s/Label/P/ for bonus points

use XUL::Gui;
display Window title => "XUL::Gui's long hello", minwidth=>300,
    GroupBox(
        Caption('XUL'),
        Button( label=>'click me', oncommand=> sub {shift->label = 'ouch'} ),
        Button( id=>'btn',
            label=>'automatic id registration',
            oncommand=>sub{
                $ID{btn}->label = 'means no more variable clutter';
                $ID{txt}->value = 'and makes cross tag updates easy';
        }),
        Button( type=>'menu', label=>'menu button',
            MenuPopup map {MenuItem label=>$_} qw/first second third/
        ),
        TextBox( id=>'txt', FILL ),
        ProgressMeter(mode=>'undetermined'),
    ),
    GroupBox(
        Caption('HTML too'),
        TABLE( border=>1, TR map {TD $_} 'one', I('two'), B('three'), U('four'), SUP('five') ),
        HR,
        P('all the HTML tags are in CAPS'),
    );

DESCRIPTION

this module exposes the entire functionality of mozilla firefox's rendering engine to perl by providing all of the XUL and HTML tags as functions and allowing you to interact with those objects directly from perl. gui applications created with this toolkit are cross platform, fully support CSS styling, inherit firefox's rich assortment of web technologies (browser, canvas and video tags, flash and other plugins), and are even easier to write than HTML.

this module is written in pure perl, and only depends upon core modules, making it easy to distribute your application.

all XUL and HTML objects in perl are exact mirrors of their javascript counterparts and can be acted on as such. for anything not written in this document or XUL::Gui::Manual, developer.mozilla.com is the official source of documentation:

gui's created with this module are event driven. an arbitrarily complex (and runtime mutable) object tree is passed to display, which then creates the gui in firefox and starts the event loop. display will wait for and respond to events until the quit function is called, or the user closes the firefox window.

all of javascript's event handlers are available, and can be written in perl (normally) or javascript (for handlers that need to be very fast such as image rollovers with onmouseover or the like). This is not to say that perl side handlers are slow, but with rollovers and fast mouse movements, there are sometimes slightly noticeable delays due to protocol overhead.

the goal of this module is to make gui development as easy as possible. XUL's widgets and nested design structure gets us most of the way there, and this module with its light weight syntax, and "Do What I Mean" nature hopefully finishes the job. everything has sensible defaults with minimal boilerplate, and nested design means a logical code flow that isn't littered with variables. now you can focus on your gui's design and functionality, and not on the deficiencies of your toolkit. if XUL::Gui doesn't get you all the way there yet, give it time, I'm still working on it.

Tags

all tags (XUL, HTML, or user defined widgets) are parsed the same way, and can fit into one of four templates

  • HR()

  • Label('some text')

    in the special case of a tag with one argument, which is not another tag, that argument is added to that tag as a text node. this is mostly used for HTML tags: B('bold text')

  • Label( value=>'some text', style=>'color: red' )

  • Hbox( id=>'mybox', Label('hello'), B('world'), style=>'border: 1px solid black')

    attribute pairs and children can be mixed in any order

setting the 'id' attribute enters that id into the %ID hash.

$object = Button( id=>'btn', label=>'OK' );

#  $ID{btn} == $object

any tag attribute name that matches /^on/ is an event handler (onclick, onfocus....), and expects a sub{...} (perl event handler) or function q{...} (javascript event handler).

perl event handlers get passed a reference to themselves, and an event object

Button( label=>'click me', oncommand=> sub {
    my ($self, $event) = @_;
    $self->label = $event->type;
})

javascript event handlers have event and this set for you

Button( label=>'click me', oncommand=> function q{
    this.label = event.type;
})

EXPORT

all functions listed here are exported by default, this may change in the future

all XUL tags: (also exported as Titlecase)
    Action ArrowScrollBox Assign BBox Binding Bindings Box Broadcaster BroadcasterSet Browser Button Caption
    CheckBox ColorPicker Column Columns Command CommandSet Conditions Content DatePicker Deck Description Dialog
    DialogHeader DropMarker Editor Grid Grippy GroupBox HBox IFrame Image Key KeySet Label ListBox ListCell ListCol
    ListCols ListHead ListHeader ListItem Member Menu MenuBar MenuItem MenuList MenuPopup MenuSeparator Notification
    NotificationBox Observes Overlay Page Panel Param PopupSet PrefPane PrefWindow Preference Preferences ProgressMeter
    Query QuerySet Radio RadioGroup Resizer RichListBox RichListItem Row Rows Rule Scale Script ScrollBar ScrollBox
    ScrollCorner Separator Spacer SpinButtons Splitter Stack StatusBar StatusBarPanel StringBundle StringBundleSet Tab
    TabBox TabPanel TabPanels Tabs Template TextBox TextNode TimePicker TitleBar ToolBar ToolBarButton ToolBarGrippy
    ToolBarItem ToolBarPalette ToolBarSeparator ToolBarSet ToolBarSpacer ToolBarSpring ToolBox ToolTip Tree TreeCell
    TreeChildren TreeCol TreeCols TreeItem TreeRow TreeSeparator Triple VBox Where Window Wizard WizardPage

all HTML tags: (also exported as html_lowercase)
    A ABBR ACRONYM ADDRESS APPLET AREA AUDIO B BASE BASEFONT BDO BGSOUND BIG BLINK BLOCKQUOTE BODY BR BUTTON CANVAS
    CAPTION CENTER CITE CODE COL COLGROUP COMMENT DD DEL DFN DIR DIV DL DT EM EMBED FIELDSET FONT FORM FRAME FRAMESET
    H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME ILAYER IMG INPUT INS ISINDEX KBD LABEL LAYER LEGEND LI LINK LISTING MAP
    MARQUEE MENU META MULTICOL NOBR NOEMBED NOFRAMES NOLAYER NOSCRIPT OBJECT OL OPTGROUP OPTION P PARAM PLAINTEXT PRE
    Q RB RBC RP RT RTC RUBY S SAMP SCRIPT SELECT SMALL SOURCE SPACER SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD
    TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR VIDEO WBR XML XMP

display widget extends Code quit buffered alert now cached noevents dialog zip attribute hashif gui
tag object delay run function XUL FLEX FIT FILL genid doevents trace mapn apply toggle lf

FUNCTIONS

utility functions

mapn {CODE} NUMBER LIST

map over n elements at a time in @_ and $_ == $_[0]

print mapn {$_ % 2 ? "@_" : " [@_] "} 3 => 1..20;
> 1 2 3 [4 5 6] 7 8 9 [10 11 12] 13 14 15 [16 17 18] 19 20
zip LIST of ARRAYREF
%hash = zip [qw/a b c/], [1..3];
apply {CODE} LIST

apply a function to a list and return that list

print join ", " => apply {s/$/ one/} "this", "and that";
> this one, and that one
toggle TARGET OPT1 OPT2

alternate a variable between two states

toggle $state => 0, 1;

gui functions

display LIST

starts the http server, launches firefox, waits for events

takes a list of gui objects, and several optional parameters:

OPTION    VALUES  DEFAULT  DESCRIPTION
debug     0 - 3   0        adjust verbosity to stderr
nolaunch  BOOL    0        disables launching firefox, connect manually to http://localhost:8888
nochrome  BOOL    0        chrome mode disables all normal firefox gui elements, setting this
                           option will turn those elements back on.

if $_[0] is a Window, that window is created, otherwise a default one is added. gui objects from @_ are then added to the window.

display will not return until the the gui quits

see SYNOPSYS and XUL::Gui::Manual for more details

quit

shuts down the server (causes a call to display to return at the end of the current event cycle)

object TAGNAME LIST

creates a gui proxy object, allows run time addition of custom tags

object('Label', value=>'hello') is the same as Label( value=>'hello' )
tag NAME

returns a CODEREF that generates proxy objects, allows for user defined tag functions

*mylabel = tag 'label';

\&mylabel == \&Label
widget {CODE} HASH

group tags together into common patterns, with methods and inheritance

*MyWidget = widget {
    Hbox(
        Label( value=> $A{label} ),
        Button( label=>'OK', attribute 'oncommand' ),
        @C
    )
}   method  => sub{ ... },
    method2 => sub{ ... };

$ID{someobject}->appendChild( MyWidget( label=>'widget', oncommand=>\&event_handler ) );

inside widgets, several variables are defined
variable    contains the passed in
   %A           attributes
   @C           children
   %M           methods
   $W           a reference to the current widget

much more detail in XUL::Gui::Manual
extends OBJECT

indicate that a widget inherits from another widget or tag

*MySubWidget = widget {extends MyWidget}
    submethod => sub{...};

more details in XUL::Gui::Manual
attribute NAME

includes an attribute name if it exists, only works inside of widgets

attribute 'value'; # is syntactic sugar for
exists $A{value} ? ( value => $A{value} ) : ()
XUL STRING

converts an XUL string to XUL::Gui objects

alert STRING

open an alert message box

trace LIST

carps LIST with object details, and then returns LIST unchanged

function JAVASCRIPT

create a javascript function, useful for functions that need to be very fast, such as rollovers

Button( label=>'click me', oncommand=> function q{
    this.label = 'ouch';
    alert('hello from javascript');
})
gui JAVASCRIPT

executes JAVASCRIPT

PRAGMATIC BLOCKS

the following functions all apply pragmas to their CODE blocks. in some cases, they also take a list. this list will be @_ when the CODE block executes. this is useful for sending in values from the gui, if you don't want to use a now {block}

buffered {CODE} LIST

delays sending gui updates

buffered {
    $ID{$_}->value = '' for qw/a bunch of labels/
};
cached {CODE}

turns on caching of gets from the gui

now {CODE}

execute immediately, from inside a buffered or cached block

delay {CODE} LIST

delays executing its CODE until the next gui refresh

useful for triggering widget initialization code that needs to run after the gui objects are rendered

noevents {CODE} LIST

disable event handling

doevents

force a gui update before an event handler finishes

METHODS

# access attributes and properties

    $object->value = 5;     # sets the value in the gui
    print $object->value;   # gets the value from the gui

# the attribute is set if it exists, otherwise the property is set

    $object->_value = 7;    # sets the property directly

# function calls

    $object->focus;                         # void context
    $object->appendChild( H2('title') );    # or any arguments are always function calls

in addition to mirroring all of an object's existing javascript methods / attributes / and properties to perl (with identical spelling / capitalization), several default methods have been added to all objects

->removeChildren( LIST )

removes the children in LIST, or all children if none given

->removeItems( LIST )

removes the items in LIST, or all items if none given

->appendChildren( LIST )

appends the children in LIST

->prependChild( CHILD, [INDEX] )

inserts CHILD at INDEX (defaults to 0) in the parent's child list

->appendItems( LIST )

append a list of items

->replaceItems( LIST )

removes all items, then appends LIST

AUTHOR

Eric Strom, <ejstrom at gmail.com>

BUGS

please report any bugs or feature requests to bug-xul-gui at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=XUL-Gui. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGEMENTS

COPYRIGHT & LICENSE

copyright 2009 Eric Strom.

this program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

see http://dev.perl.org/licenses/ for more information.