table of contents
Prima::Docks(3) | User Contributed Perl Documentation | Prima::Docks(3) |
NAME¶
Prima::Docks - dockable widgets
DESCRIPTION¶
The module contains a set of classes and an implementation of the dockable widgets interface. The interface assumes two parties, the dockable widget, and the dock widget; the generic methods for the dock widget class are contained in the "Prima::AbstractDocker::Interface" package.
USAGE¶
A dockable widget is required to take particular steps before it may land on a dock widget. It needs to talk to the dock and find out if it is allowed to land, or if the dock contains children dock widgets that might suit better for the docking. If there's more than one dock widget in the program, the dockable widget can select between the targets; this is especially actual when a dockable widget is dragged by the mouse and the landing arbitration is based on geometrical distance.
The interface implies that there exists at least one tree-like hierarchy of dock widgets, linked up to a root dock widget. The hierarchy is not required to follow parent-child relationships although this is the default behavior. All dockable widgets are expected to know explicitly what hierarchy tree they wish to dock to. "Prima::InternalDockerShuttle" introduces the "dockingRoot" property for this purpose.
The conversation between parties starts when a dockable widget calls the "open_session" method of the dock. The dockable widget passes a set of parameters signaling if the widget is ready to change its size in case the dock widget requires so, and how. The "open_session" method can either refuse or accept the widget. In case of the positive answer from "open_session", the dockable widget calls the "query" method, which either returns a new rectangle or another dock widget. In the latter case, the caller can enumerate all available dock widgets by repetitive calls to the "next_docker" method. The session is closed by a "close_session" call; after that, the widget is allowed to land by setting its "owner" to the dock widget, the "rect" property to the negotiated position and size, and finally calling the "dock" method.
The "open_session"/"close_session" brackets cache all necessary calculations once, making the "query" call as light as possible. This design allows a dockable widget when dragged, to repeatedly ask all reachable docks in an optimized way. The docking sessions are kept open until the drag session is finished.
The conversation can be schematized in the following code:
my $dock = $self-> dockingRoot; my $session_id = $dock-> open_session({ self => $self }); return unless $session_id; my @result = $dock-> query( $session_id, $self-> rect ); if ( 4 == scalar @result) { # new rectangle is returned if ( ..... is new rectangle acceptable ? ... ) { $dock-> close_session( $session_id); $dock-> dock( $self); return; } } elsif ( 1 == scalar @result) { # another dock returned my $next = $result[0]; while ( $next) { if ( ... is new docker acceptable? ....) { $dock-> close_session( $session_id); $next-> dock( $self); return; } $next = $dock-> next_docker( $session_id, $self-> origin ); } } $dock-> close_session( $session_id);
Since even the simplified code is quite cumbersome, direct calls to "open_session" are rare. Instead, "Prima::InternalDockerShuttle" implements the "find_docking" method which performs the arbitration automatically and returns the appropriate dock widget.
"Prima::InternalDockerShuttle" is the class that implements the dockable widget functionality. It also provides a top-level window-like wrapper widget for the dockable widget that hosts the widget automatically if it is not docked. By default, "Prima::ExternalDockerShuttle" is used as the wrapper widget class.
It is not required, however, to use either "Prima::InternalDockerShuttle" or "Prima::AbstractDocker::Interface" to implement a dockable widget; the only requirement is to respect the "open_session"/"close_session" protocol.
The full hierarchy of widgets participating in the mechanism is as follows:
Prima::AbstractDocker::Interface Prima::SimpleWidgetDocker Prima::ClientWidgetDocker Prima::LinearWidgetDocker Prima::SingleLinearWidgetDocker Prima::FourPartDocker Prima::InternalDockerShuttle Prima::LinearDockerShuttle Prima::ExternalDockerShuttle
All docker widget classes are derived from "Prima::AbstractDocker::Interface". Depending on the specialization, they employ more or less sophisticated schemes for arranging dockable widgets inside themselves. The most complicated scheme is implemented in "Prima::LinearWidgetDocker"; it does not allow children to overlap, can rearrange the children, and resize itself when a widget is docked or undocked.
The package provides only basic functionality. Module "Prima::DockManager" provides common dockable controls, - toolbars, panels, speed buttons, etc. based on the "Prima::Docks" module. See Prima::DockManager.
Prima::AbstractDocker::Interface¶
Implements generic functionality of a docket widget. The class is not derived from "Prima::Widget"; is used as a secondary ascendant class for the dock widget classes.
Properties¶
Since the class is not a "Prima::Object" descendant, it provides only run-time implementation of its properties. It is up to the descendant object whether the properties are recognized during the creation stage or not.
- fingerprint INTEGER
- A custom bit mask used by docking widgets to reject inappropriate dock
widgets at an early stage. The
"fingerprint" property is not a part of
the protocol and is not required to be present in the implementation of a
dockable widget.
Default value: 0x0000FFFF
- dockup DOCK_WIDGET
- Selects the upper link in the dock widgets hierarchy tree. The upper link
is required to be a dock widget but is not required to be a direct or an
indirect parent. In this case, however, the maintenance of the link must
be implemented separately, for example:
$self-> dockup( $upper_dock_not_parent ); $upper_dock_not_parent-> add_notification( 'Destroy', sub { return unless $_[0] == $self-> dockup; undef $self-> {dockup_event_id}; $self-> dockup( undef ); }, $self); $self-> {destroy_id} = $self-> add_notification( 'Destroy', sub { $self-> dockup( undef ); } unless $self-> {destroy_id};
Methods¶
- add_subdocker SUBDOCK
- Appends SUBDOCK to the list of children docker widgets. The items of the list are returned by the "next_docker" method.
- check_session SESSION
- A debugging procedure. Checks SESSION hash, and warns if its members are invalid or incomplete. Returns 1 if no fatal errors were encountered; 0 otherwise.
- close_session SESSION
- Closes docking SESSION and frees the associated resources.
- dock WIDGET
- Called after WIDGET successfully finished negotiations with the dock
widget and changed its "owner" property.
The method adapts the dock widget layout and lists the WIDGET into the
list of docked widgets. The method does not change the
"owner" property of the WIDGET.
The method must not be called directly.
- dock_bunch @WIDGETS
- Effectively docks set of WIDGETS by updating internal structures and calling "rearrange".
- docklings
- Returns an array of docked widgets
- next_docker SESSION, [ X, Y ]
- Enumerates children docker widgets inside the SESSION; returns one docker
widget at a time. After the last widget returns
"undef".
The enumeration pointer is reset by the "query" call.
X and Y are the coordinates of the point of interest.
- open_session PROFILE
- Opens a new docking session with parameters stored in the PROFILE hash. Returns a session ID scalar in case of success, or "undef" otherwise. The following keys must be set in PROFILE:
- position ARRAY
- Contains two integer coordinates of the desired position of a widget in (X,Y) format in the screen coordinate system.
- self WIDGET
- The widget that is about to dock.
- sizeable ARRAY
- Contains two boolean flags, representing if the widget can be resized to an arbitrary size, horizontally and vertically. The arbitrary resize option is used as a last resort if the "sizes" key does not contain the desired size.
- sizeMin ARRAY
- Two integers; the minimal size that the widget can accept.
- sizes ARRAY
- Contains an array of points in the (X,Y) format; each point represents an acceptable widget size. If both of the "sizeable" flags are set to 0 and none of the "sizes" can be accepted by the dock widget, "open_session" fails.
- query SESSION [ X1, Y1, X2, Y2 ]
- Checks if a dockable widget can be landed on the dock. If it can, returns
a rectangle that the widget must be set to. If coordinates ( X1 .. Y2 )
are specified, returns the rectangle closest to these. If
"sizes" or
"sizeable" keys of the
"open_session" profile were set, the
returned size might be different from the current docking widget size.
Once the caller finds the result appropriate, it is allowed to reparent under the dock; after that, it must change its origin and size correspondingly to the result, and then call "dock".
If the dock cannot accept the widget but contains children dock widgets, returns the first child widget. The caller can use subsequent calls to "next_docker" to enumerate all the children docks. A call to "query" resets the internal enumeration pointer.
If the widget may not be landed, an empty array is returned.
- rearrange
- Effectively re-docks all the docked widgets. The effect is as same as of
$self-> redock_widget($_) for $self-> docklings;
but usually "rearrange" is faster.
- redock_widget WIDGET
- Effectively re-docks the docked WIDGET. If WIDGET has a "redock" method in its namespace, it is called instead.
- remove_subdocker SUBDOCK
- Removes SUBDOCK from the list of children docker widgets. See also add_subdocker.
- replace FROM, TO
- Assigns the widget TO the same owner and size as FROM. The FROM widget must be a docked widget.
- undock WIDGET
- Removes WIDGET from the list of docked widgets. The layout of the dock
widget can be changed after the execution of this method. The method does
not change the "owner" property of
WIDGET.
The method must not be called directly.
Prima::SimpleWidgetDocker¶
A simple dock widget; accepts any widget that geometrically fits into it. Allows overlapping of the docked widgets.
Prima::ClientWidgetDocker¶
A simple dock widget; accepts any widget that can cover all dock's interior.
Prima::LinearWidgetDocker¶
A toolbar-like docking widget class. The implementation does not allow tiling but can reshape the dock widget and rearrange the docked widgets if necessary.
"Prima::LinearWidgetDocker" is orientation-dependent; its main axis, managed by the "vertical" property, aligns the docked widgets in 'lines', which in turn are aligned by the opposite axis ( 'major' and 'minor' terms are used in the code for the axes ).
Properties¶
- growable INTEGER
- A combination of the "grow::XXX"
constants that describes how the dock widget can be resized. The constants
are divided into two sets, direct and indirect, or,
"vertical" property independent and
dependent.
The first set contains explicitly named constants:
grow::Left grow::ForwardLeft grow::BackLeft grow::Down grow::ForwardDown grow::BackDown grow::Right grow::ForwardRight grow::BackRight grow::Up grow::ForwardUp grow::BackUp
that select if the widget can grow in the direction shown. These do not change meaning when "vertical" changes, though they do change the dock widget behavior. The second set does not affect dock widget behavior when "vertical" changes, however, the names are not that illustrative:
grow::MajorLess grow::ForwardMajorLess grow::BackMajorLess grow::MajorMore grow::ForwardMajorMore grow::BackMajorMore grow::MinorLess grow::ForwardMinorLess grow::BackMinorLess grow::MinorMore grow::ForwardMinorMore grow::BackMinorMore
The "Forward" and "Back" prefixes select if the dock widget can be respectively expanded or shrunk in the given direction. "Less" and "More" are equivalent to "Left" and "Right" when "vertical" is 0, and to "Up" and "Down" otherwise.
The use of constants from the second set is preferred.
Default value: 0
- hasPocket BOOLEAN
- A boolean flag, affects the possibility of a docked widget to reside
outside the dock widget inferior. If 1, a docked widget is allowed to stay
docked ( or dock into a position ) further on the major axis ( to the
right when "vertical" is 0, up otherwise
) as if there's a 'pocket'. If 0, a widget is neither allowed to dock
outside the inferior nor is allowed to stay docked ( and is undocked
automatically ) when the dock widget shrinks so that the docked widget
cannot stay in the dock boundaries.
Default value: 1
- vertical BOOLEAN
- Selects the major axis of the dock widget. If 1, it is vertical,
horizontal otherwise.
Default value: 0
Events¶
- Dock
- Called when the "dock" method is successfully finished.
- DockError WIDGET
- Called when the "dock" method is unsuccessfully finished. This only happens if WIDGET does not follow the docking protocol, and inserts itself into a non-approved area.
- Undock
- Called when "undock" is finished.
Prima::SingleLinearWidgetDocker¶
Descendant of "Prima::LinearWidgetDocker". In addition to the constraints introduced by the ascendant class, "Prima::SingleLinearWidgetDocker" allows only one row ( or column, depending on the "vertical" property value ) of docked widgets.
Prima::FourPartDocker¶
Implementation of a docking widget that hosts four children docker widgets on its sides and one in the center. All of the children docks can grow and shrink automatically so that the whole setup has an effect as if the dock borders are dynamic.
Properties¶
- indents ARRAY
- Contains four integers specifying the breadth of offset for each side. The first integer is the width of the left side, the second - the height of the bottom side, the third is the width of the right side, and the fourth - height of the top side.
- dockerClassLeft STRING
- Assigns the class of the left-side dock window.
Default value: "Prima::LinearWidgetDocker". Create-only property.
- dockerClassRight STRING
- Assigns the class of the right-side dock window.
Default value: "Prima::LinearWidgetDocker". Create-only property.
- dockerClassTop STRING
- Assigns the class of the top-side dock window.
Default value: "Prima::LinearWidgetDocker". Create-only property.
- dockerClassBottom STRING
- Assigns the class of the bottom-side dock window.
Default value: "Prima::LinearWidgetDocker". Create-only property.
- dockerClassClient STRING
- Assigns the class of the center dock window.
Default value: "Prima::ClientWidgetDocker". Create-only property.
- dockerProfileLeft HASH
- Assigns a hash of properties, passed to the left-side dock widget during
the creation.
Create-only property.
- dockerProfileRight HASH
- Assigns a hash of properties, passed to the right-side dock widget during
the creation.
Create-only property.
- dockerProfileTop HASH
- Assigns a hash of properties, passed to the top-side dock widget during
the creation.
Create-only property.
- dockerProfileBottom HASH
- Assigns a hash of properties, passed to the bottom-side dock widget during
the creation.
Create-only property.
- dockerProfileClient HASH
- Assigns a hash of properties, passed to the center dock widget during the
creation.
Create-only property.
- dockerDelegationsLeft ARRAY
- Assigns delegated notifications of the left-side dock.
Create-only property.
- dockerDelegationsRight ARRAY
- Assigns delegated notifications of the right-side dock.
Create-only property.
- dockerDelegationsTop ARRAY
- Assigns delegated notifications of the top-side dock.
Create-only property.
- dockerDelegationsBottom ARRAY
- Assigns delegated notifications of the bottom-side dock.
Create-only property.
- dockerDelegationsClient ARRAY
- Assigns delegated notifications of the bottom-side dock.
Create-only property.
- dockerCommonProfile HASH
- Assigns a hash of properties, passed to all the five dock widgets during
the creation.
Create-only property.
Prima::InternalDockerShuttle¶
The class provides a container, or a 'shuttle', for a client widget, while is docked to a "Prima::AbstractDocker::Interface" descendant instance. The functionality includes communicating with dock widgets, the user interface for dragging and interactive dock selection, and a client widget container for the non-docked state. The latter is implemented by reparenting the client widget to an external shuttle widget, selected by the "externalDockerClass" property. Both user interfaces for the docked and the non-docked shuttle states are minimal.
The class implements dockable widget functionality, served by "Prima::AbstractDocker::Interface", and is derived from "Prima::Widget".
See also: "Prima::ExternalDockerShuttle".
Properties¶
- client WIDGET
- Provides access to the client widget, which always resides either in the
internal or the external shuttle. By default, there is no client, and any
widget capable of changing its parent can be set as one. After a widget is
assigned as a client, its "owner" and
"clipOwner" properties must not be used.
Run-time only property.
- dock WIDGET
- Selects the dock widget that the shuttle is landed on. If
"undef", the shuttle is in the
non-docked state.
Default value: "undef"
- dockingRoot WIDGET
- Selects the root of the dock widgets hierarchy. If
"undef", the shuttle can only exist in
the non-docked state.
Default value: "undef"
See "USAGE" for reference.
- externalDockerClass STRING
- Assigns the class of the external shuttle widget.
Default value: "Prima::ExternalDockerShuttle"
- externalDockerModule STRING
- Assigns the module that contains the external shuttle widget class.
Default value: "Prima::MDI" ( "Prima::ExternalDockerShuttle" is derived from "Prima::MDI" ).
- externalDockerProfile HASH
- Assigns a hash of properties, passed to the external shuttle widget during the creation.
- fingerprint INTEGER
- A custom bit mask used to reject inappropriate dock widgets at an early
stage.
Default value: 0x0000FFFF
- indents ARRAY
- Contains four integers, specifying the breadth of offset in pixels for
each widget side in the docked state.
Default value: "5,5,5,5".
- snapDistance INTEGER
- A maximum offset, in pixels, between the actual shuttle coordinates and
the coordinates proposed by the dock widget, where the shuttle is allowed
to land. In other words, it is the distance between the dock and the
shuttle when the latter 'snaps' to the dock during the dragging session.
Default value: 10
- x_sizeable BOOLEAN
- Selects whether the shuttle can change its width in case the dock widget
suggests so.
Default value: 0
- y_sizeable BOOLEAN
- Selects whether the shuttle can change its height in case the dock widget
suggests so.
Default value: 0
Methods¶
- client2frame X1, Y1, X2, Y2
- Returns the rectangle that the shuttle would occupy if its client rectangle is assigned to X1, Y1, X2, Y2 .
- dock_back
- Docks to the recent dock widget, if it is still available.
- drag STATE, RECT, ANCHOR_X, ANCHOR_Y
- Initiates or aborts the dragging session, depending on the STATE boolean
flag.
If it is 1, RECT is an array with the coordinates of the shuttle rectangle before the session has started; ANCHOR_X and ANCHOR_Y are coordinates of the aperture point where the mouse event occurred that has initiated the session. Depending on how the drag session ended, the shuttle can be relocated to another dock, undocked, or left intact. Also, "Dock", "Undock", or "FailDock" notifications can be triggered.
If the STATE is 0, RECT, ANCHOR_X ,and ANCHOR_Y parameters are not used.
- find_docking DOCK, [ POSITION ]
- Opens a session with DOCK, unless it is already opened, and negotiates
about the possibility of landing ( at the POSITION if this parameter is
present ).
"find_docking" caches the dock widget sessions and provides a possibility to select different parameters passed to "open_session" for different dock widgets. To achieve this, the "GetCaps" request notification is triggered, which is expected to fill the parameters. The default action sets the "sizeable" option according to the "x_sizeable" and "y_sizeable" properties.
In case an appropriate landing area is found, the "Landing" notification is triggered with the proposed dock widget and the target rectangle. The area can be rejected at this stage if "Landing" returns a negative answer.
On success, returns a dock widget found and the target rectangle; the widget is not docked though. On failure returns an empty array.
This method is used by the mouse dragging routine to provide visual feedback to the user, to indicate that a shuttle may or may not land in a particular area.
- frame2client X1, Y1, X2, Y2
- Returns the rectangle that the client would occupy if the shuttle rectangle is assigned to X1, Y1, X2, Y2 .
- redock
- Undocks from the dock widget and immediately tries to land back. If not docked, does not do anything.
Events¶
- Dock
- Called when the shuttle was docked.
- EDSClose
- Triggered when the user presses the close button or otherwise activates the "close" function of the EDS ( external docker shuttle ) pseudo-window. To cancel the window closing "clear_event" must be called inside the event handler.
- FailDock X, Y
- Called after the dragging session in the non-docked stage was finished but did not result in docking. X and Y are the coordinates of the new external shuttle position.
- GetCaps DOCK, PROFILE
- Called before the shuttle opens a docking session with the DOCK widget.
PROFILE is a hash reference, which is to be filled inside the event
handler. After that PROFILE is passed to an
"open_session" call.
The default action sets the "sizeable" option according to the "x_sizeable" and "y_sizeable" properties.
- Landing DOCK, X1, Y1, X2, Y2
- Called inside the docking session, after an appropriate dock widget is selected and the landing area is defined as X1, Y1, X2, Y2. To reject the landing on either DOCK or area, "clear_event" must be called.
- Undock
- Called when the shuttle is switched to the non-docked state.
Prima::ExternalDockerShuttle¶
A shuttle class, hosts a client of the "Prima::InternalDockerShuttle" widget when it is in the non-docked state. The widget is a pseudo-window with some minimal decorations that can be moved, resized ( this feature is not on by default though ), and closed.
"Prima::ExternalDockerShuttle" is inherited from the "Prima::MDI" class, and its window-emulating functionality is a subset of its ascendant. See also Prima::MDI.
Properties¶
- shuttle WIDGET
- Contains the reference to the dockable WIDGET
Prima::LinearDockerShuttle¶
A simple descendant of "Prima::InternalDockerShuttle", used for toolbars. Introduces orientation and draws a tiny header along the minor shuttle axis.
Properties¶
- headerBreadth INTEGER
- The breadth of the header in pixels.
Default value: 8
- indent INTEGER
- A wrapper to the "indents" property; besides the space for the header, all indents are assigned to the "indent" property value.
- vertical BOOLEAN
- If 1, the shuttle is drawn as a vertical bar. If 0, the shuttle is drawn
as a horizontal bar.
Default value: 0
AUTHOR¶
Dmitry Karasik, <dmitry@karasik.eu.org>.
SEE ALSO¶
Prima, Prima::Widget, Prima::MDI, Prima::DockManager, examples/dock.pl
2024-08-20 | perl v5.40.0 |