NAME

Rui::Widget::Base - abstract widget base class


SYNOPSIS

  # using widgets
  
  use MyWidgets::WhiteButton;
  # you can create widgets in windows or composites
  $window      = Rui::Window->new;
  $widget      = $window->Panel->MyWidgets__WhiteButton;
  $newWidget   = $window->Panel->MyWidgets__WhiteButton(
     value           => 'click to change value',
     style           => {padding => '2px 3px 1px 2px', color => '#FF0000'},
     layoutHint      => {minHeight => 100, minWidth => 50},
     disabled        => 0, # this is default: widget is enabled
     tooltip         => 'foo',
     events          => {Click => sub { shift->source->value('foo') }},
     cssClass        => 'MyButtonStyleClass',
     backgroundImage => $image,
  );
  # you can create windows from widgets
  $newWindow = $widget->Window(width => 200, height => 200);
  
  $widget->style(fontWeight => 'bold', color => '#00FF00');
  $widget->cssClass('MyButtonStyleClass');
  $widget->backgroundImage($image);
  $widget->disabled(1);
  $widget->tooltip('bar');
  $widget->layoutHint(hAlign => 'fill');
  print $widget->tooltip;
  print $widget->style('color');
  print $widget->cssClass;
  print $widget->backgroundImage;
  $widget->addListener(Click => $someListener);
  $widget->removeListener(Click => $someListener);
  $widget->destroy;
  # subclassing: a white button widget
  
  package MyWidgets::WhiteButton;
  use Rui::Event;
  use base 'Rui::Widget::Base';
  sub init
  {
     my ($self, %params) = @_;
     $self->SUPER::init(%params);
     $self->value($params{value}) if exists $params{value};
     $self->sendToClient(style => 'backgroundColor', '#FFFFFF');
  }
  sub value { shift->attribute(value => @_) }
  sub handleClientEvent_Click : Protected
  {
     my ($self, %params) = @_;
     # widgets are listenable so you can fire events
     $self->fireEvent(Rui::Event->new(
        name   => 'Click',
        source => $self,
     );
  }
  sub getDefaultWidgetClass { 'Button' }
  
=head1 SUPERCLASS

the Rui::Event::Listenable manpage


DESCRIPTION

A proxy on some widget running on the client. The server side of the widget. Supports sending arbitrary messages to subject, and listening to subject events.

You create widgets by calling a method named after their type.

  $button = $parent->Button(value => 'foo');

Will create a button widget inside the parent widget. The widget constructor takes an optional hash of named parameters, so you can configure everything about the widget (except its children) at once.

Widgets are destroyed with destroy().

Widgets are styled using the CSS standard:

  $button->style(backgroundColor => '#FF00FF');
  $button->cssClass('MyButtonClass');

You can configure layout hints for the widget. These are used by the layout manager of the parent. E.g. If the parent was configured with a grid layout manager, then this could be done:

  $button->layoutHint(flex => 1);

Different layout managers will look for different hints. See the Rui::Widget::Panel manpage for possible values.

Widgets collaborate with a the Rui::Remote::Session manpage. The session is used for communication with the client side of the widget: appending to the session buffer, and receiving client events. It is also used to get the next available widget id.

Widgets collaborate with a the Rui::Widget::Factory manpage, which they get from their parent. They use it to create child widgets. They get it from their window, which they get from their parent.


CSS

These are the style keys that you can use when styling widgets. See the W3C CSS documentation for more information. Note that you cannot set position or sizing keys (e.g. height, top), as these are managed by the layout manager.

font, textDecoration, letterSpacing
You can also use more specific keys: fontFamily, fontSize, fontVariant, fontWeight.

backgroundAttachment, backgroundPosition, backgroundRepeat
These effect how the background image is shown.

backgroundColor, color
Color must be set as a hex RGB value. Here we set the color of the label text to blue:
  $label->color('#0000FF');

border
You can specify borderBottom, borderBottomColor, etc. to change specific attributes of a border. You must specify width in pixels, by adding px to the value. Here we set the left border width to 2 pixels:
  $widget->style(borderLeftWidth => '2px');

margin, padding
You can access specific paddings and margins using marginBottom, paddingLeft, etc. You must specify width in pixels, by adding px to the value, as with borders.

overflow, overflowX, overflowY
These determine whether the widget content is hidden or can be scrolled, when it exceeds the size of the widget. There are 3 options: hidden (default), auto, and scroll. You cannot set overflow to visible.

cursor


SUBCLASSING

You may have to create a new client-side peer for your new widget, if the peer of the superclass is not good enough.

You can set attributes or complex attributes using attribute(), or complexAttribute().

Sending messages to the client-side peer is done through sendToClient().

Overriding:

If you create your own widgets, they will NOT be mapped to nice short names like the Rui classes. For example a the Rui::Widget::Label manpage, can be created using $parent->Label, because there is a type-to-class mapping in the widget factory, from Label to Rui::Widget::Label. Your class does not have a mapping there, so it will not work.

In this case you construct the type from the class name by going s/::/__/g on the class name to get the type. E.g. if your class is Buttons::GreenButton, you could instantiate it with:

  $greenButton = $parent->Buttons__GreenButton(value => 'foo');

You can add type-to-class mappings by subclassing the widget factory.


METHODS

CREATING

Widget type name, or class name after s/::/__/g

parameters
Hash of optional named parameters. Every method can be called by using the method name as a key in the constructor hash.

returns
New widget.

description
You create widgets by calling a method, named after their class name, on some composite. The following 2 lines are equivalent:
  $parent->Label(value => 'foo');
  $parent->Rui__Widget__Label(value => 'foo');

Creating widgets by type (vs. by class) is done by the widget factory, according to its mapping.

destroy

description
Widget and children will be destroyed.

Window

parameters
Hash of named parameters passed to the window constructor.

returns
the Rui::Window manpage. The new window.

description
Window constructor.

STYLING

style

parameters
Getting: key - Scalar. CSS style key.

Setting: style - Hash or hash ref. CSS key/value pairs.

description
Get/set style values. You can only get one at a time, but you can set several together. See CSS guide for possible values.

NOTE: do not set size and position keys, except padding/border/margin, because these are set by the parent layout manager.

cssClass

parameters
Setting: CSS class - Scalar. Name of CSS class to add to widget.

description
Add a CSS class to the widget. Instead of setting specific style keys, it is usually better to create style classes. You define the CSS class in a .css file, that you place at $Rui::PROJECT_HOME/web/style. You also need to reference the stylesheet from the launcher page.

backgroundImage

parameters
Setting: image (the Rui::Image manpage)

description
Set a background image on the widget. Set as undefined to remove it.

layoutHint

parameters
Getting: key - Scalar. layout hint key.

Setting: style - Hash or hash ref. Layout hint key/value pairs.

description
Get/set layoutHint values. You can only get one at a time, but you can set several together. Each layout manager defines different possible layout hints for children. See the Rui::Widget::Panel manpage for possible values.

ACCESSING

disabled

parameters
Setting: disabled - Boolean.

description
Get/set the disabled state of this widget. Disabled widgets will not receive events from the user.

tooltip

parameters
Setting: tooltip - Scalar.

description
Get/set tooltip.