++ed by:

4 PAUSE users
3 non-PAUSE users.

Author image Scott Smith
and 1 contributors


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


    $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
    $object2 = Acme::Rocket->get($another_id);    

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

View Interface


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


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.


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


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


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


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.


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


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:


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


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


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

Subject Interface


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


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


Returns a reference to the current "subject" object.


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

Toolkit Interface


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.


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


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:

     \          /           \    /      \
     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.


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().


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.


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


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