Rui::Widget::Base - abstract widget base class
# 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
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.
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.
fontFamily
, fontSize
,
fontVariant
, fontWeight
.
$label->color('#0000FF');
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');
marginBottom
,
paddingLeft
, etc. You must specify width in pixels, by adding px
to the value, as with borders.
hidden
(default), auto
, and scroll
. You cannot set overflow to
visible
.
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:
handleClientEvent_SomeClientEventName
- will be called with event
data hash as only parameter whenever the client side of this widget
fires an event. The name of the event determines the method name called.
The name of the event is decided on the client side of the widget, where
the event originates.
getDefaultWidgetClass
- must return scalar name of the client side class
that will be used for this widget.
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.
s/::/__/g
$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.
Setting: style - Hash or hash ref. CSS key/value pairs.
NOTE: do not set size and position keys, except padding/border/margin, because these are set by the parent layout manager.
.css
file, that you place at $Rui::PROJECT_HOME/web/style
.
You also need to reference the stylesheet from the launcher page.
Setting: style - Hash or hash ref. Layout hint key/value pairs.