NAME

UR::Object::Viewer - a base class for viewer/editors of UR::Object

SYNOPSIS

$object = Acme::Rocket->get($some_id);

$viewer = $object->create_viewer(
    perspective => "flight path"    # optional, default is "default"
    aspects => \@these_properties,  # optional, default is set in perspective
    toolkit => "gtk"                # optional, default is set by App::UI
);

$view->show_modal();


$object2 = Acme::Rocket->get($another_id);    

$viewer->set_subject($object2);
$viewer->show_modal();    

$viewer->show();
App::UI->event_loop();

$viewer = $object->create_viewer(
    perspective => "flight path"    # optional, default is "default"
    aspects => [
        'property1',
        'parts' => {  
            perspective => "ordered list",
            aspects => [qw/make model mileage/],
        },
        'property3',
    ]
    toolkit => "gtk"                # optional, default is set by App::UI
);

View Interface

create

The constructor requires the following params to be specified as key-value pairs:

subject_class_name

The class of subject this viewer will view. Constant for any given viewer, but this may be any abstract class up-to UR::Object itself.

perspective

Used to describe the layout engine which gives logical content to the viewer.

toolkit

The specific (typically graphical) toolkit used to construct the UI. Examples are Gtk, Gkt2, Qt, Tk, HTML, Curses.

delete

The destructor deletes subordinate components, and the related widget, removing them all from the view of the user.

show

For stand-alone viewers, this puts the viewer in its own window. For viewers which are part of a larger viewer, this makes the viewer widget visible in the parent.

hide

Makes the viewer invisible. This means hiding the window, or hiding the viewer widget in the parent widget for subordinate viewers.

show_modal

This method shows the viewer in a window, and only returns after the window is closed. It should only be used for viewers which are a full interface capable of closing itself when done.

get_visible_aspects / add_visible_aspect / remove_visible_aspect

An "aspect" is some characteristic of the "subject" which is rendered in the viewer. Properties of an aspect specifyable in the above methods are:

method

The name of the method on the subject which returns the data to be rendered.

position

The position within the viewer of this aspect. The actual meaning will depend on the logic behind the perspective.

perspective

If a subordinate viewer will be used to render this aspect, this perspective will be used to for that viewer.

Subject Interface

subject_class_name

This is constant for a given viewer. Any assigned subject must be of this class directly or indirectly.

subject_id

This indicates WHICH object of the class subject_class_name is visible. This value can be changed directly, or indirecly by calling set_subject().

get_subject

Returns a reference to the current "subject" object.

set_subject

Sets the specified object to be the "subject" of the viewer.

Toolkit Interface

toolkit

A class method indicating what toolkit is used to render the view. Possible values are Gtk, and hopefully Gtk2, Tk, Qt, HTML, Curses, text, etc.

get_widget

Returns the "widget" which is the rendered view. The actual object type depends on the toolkit named above.

_toolkit_class

Returns the name of a class which is derived from UR::Object::Toolkit which implements certain utility methods for viewers of a given toolkit.

Perspective Interface

When writing a new viewer, these methods should be implemented to handle the tasks described. The class can be named anything, though the recommended naming structure for a viewer is something like:

Acme::Rocket::Viewer::FlightPath::Gtk2
\          /           \    /      \
subject class        perspective    toolkit
 

A module like ::FlightPath::Gtk2 might keep most logic in Acme::Rocket::Viewer::FlightPath, and only toolkit specifics in Gtk2, but this is not required as long as the module functions.

_create_widget

This should be implemented in a given perspective/toolkit module to actually create the GUI using the appropriate toolkit. It will be called before the specific subject is known, so all widget creation which is subject-specific should be done in _bind_subject().

_bind_subject

This method has a default implementation which does a general subscription to changes on the subject. It propbably does not need to be overridden in custom viewers.

This does additional changes to the widget when a subject is set, unset, or switched. Implementations should take an undef subject, and also expect to un-bind a previously existing subject if there is one set.

_update_widget_from_subject

If when the subject changes this method will be called on all viewers which render the changed aspect of the subject.

_update_subject_from_widget

When the widget changes, it should call this method to save the GUI changes to the subject.