1Prima::Docks(3)       User Contributed Perl Documentation      Prima::Docks(3)
2
3
4

NAME

6       Prima::Docks - dockable widgets
7

DESCRIPTION

9       The module contains a set of classes and an implementation of dockable
10       widgets interface. The interface assumes two parties, the dockable
11       widget and the dock widget; the generic methods for the dock widget
12       class are contained in "Prima::AbstractDocker::Interface" package.
13

USAGE

15       A dockable widget is required to take particular steps before it can
16       dock to a dock widget. It needs to talk to the dock and find out if it
17       is allowed to land, or if the dock contains lower-level dock widgets
18       that might suit better for docking. If there's more than one dock
19       widget in the program, the dockable widget can select between the
20       targets; this is especially actual when a dockable widget is dragged by
21       mouse and the arbitration is performed on geometrical distance basis.
22
23       The interface implies that there exists at least one tree-like
24       hierarchy of dock widgets, linked up to a root dock widget. The
25       hierarchy is not required to follow parent-child relationships,
26       although this is the default behavior.  All dockable widgets are
27       expected to know explicitly what hierarchy tree they wish to dock to.
28       "Prima::InternalDockerShuttle" introduces "dockingRoot" property for
29       this purpose.
30
31       The conversation between parties starts when a dockable widget calls
32       "open_session" method of the dock. The dockable widget passes set of
33       parameters signaling if the widget is ready to change its size in case
34       the dock widget requires so, and how. "open_session" method can either
35       refuse or accept the widget.  In case of the positive answer from
36       "open_session", the dockable widget calls "query" method, which either
37       returns a new rectangle, or another dock widget.  In the latter case,
38       the caller can enumerate all available dock widgets by repetitive calls
39       to "next_docker" method. The session is closed by "close_session" call;
40       after that, the widget is allowed to dock by setting its "owner" to the
41       dock widget, the "rect" property to the negotiated position and size,
42       and calling "dock" method.
43
44       "open_session"/"close_session" brackets are used to cache all necessary
45       calculations once, making "query" call as light as possible. This
46       design allows a dockable widget, when dragged, repeatedly ask all
47       reachable docks in an optimized way. The docking sessions are kept open
48       until the drag session is finished.
49
50       The conversation can be schematized in the following code:
51
52               my $dock = $self-> dockingRoot;
53               my $session_id = $dock-> open_session({ self => $self });
54               return unless $session_id;
55               my @result = $dock-> query( $session_id, $self-> rect );
56               if ( 4 == scalar @result) {       # new rectangle is returned
57                       if ( ..... is new rectangle acceptable ? ... ) {
58                               $dock-> close_session( $session_id);
59                               $dock-> dock( $self);
60                               return;
61                       }
62               } elsif ( 1 == scalar @result) {  # another dock returned
63                       my $next = $result[0];
64                       while ( $next) {
65                               if ( ... is new docker acceptable? ....) {
66                                       $dock-> close_session( $session_id);
67                                       $next-> dock( $self);
68                                       return;
69                               }
70                               $next = $dock-> next_docker( $session_id, $self-> origin );
71                       }
72               }
73               $dock-> close_session( $session_id);
74
75       Since even the simplified code is quite cumbersome, direct calls to
76       "open_session" are rare. Instead, "Prima::InternalDockerShuttle"
77       implements "find_docking" method which performs the arbitration
78       automatically and returns the appropriate dock widget.
79
80       "Prima::InternalDockerShuttle" is a class that implements dockable
81       widget functionality. It also employs a top-level window-like wrapper
82       widget for the dockable widget when it is not docked.  By default,
83       "Prima::ExternalDockerShuttle" is used as the wrapper widget class.
84
85       It is not required, however, to use neither
86       "Prima::InternalDockerShuttle" nor "Prima::AbstractDocker::Interface"
87       to implement a dockable widget; the only requirements to one is to
88       respect "open_session"/"close_session" protocol.
89
90       "Prima::InternalDockerShuttle" initiates a class hierarchy of dockable
91       widgets.  Its descendants are "Prima::LinearWidgetDocker" and, in turn,
92       "Prima::SingleLinearWidgetDocker".  "Prima::SimpleWidgetDocker" and
93       "Prima::LinearWidgetDocker", derived from
94       "Prima::AbstractDocker::Interface", begin hierarchy of dock widgets.
95       The full hierarchy is as follows:
96
97               Prima::AbstractDocker::Interface
98                       Prima::SimpleWidgetDocker
99                       Prima::ClientWidgetDocker
100                       Prima::LinearWidgetDocker
101                       Prima::FourPartDocker
102
103               Prima::InternalDockerShuttle
104                       Prima::LinearDockerShuttle
105                       Prima::SingleLinearWidgetDocker
106
107               Prima::ExternalDockerShuttle
108
109       All docker widget classes are derived from
110       "Prima::AbstractDocker::Interface".  Depending on the specialization,
111       they employ more or less sophisticated schemes for arranging dockable
112       widgets inside. The most complicated scheme is implemented in
113       "Prima::LinearWidgetDocker"; it does not allow children overlapping and
114       is able to rearrange with children and resize itself when a widget is
115       docked or undocked.
116
117       The package provides only basic functionality. Module
118       "Prima::DockManager" provides common dockable controls, - toolbars,
119       panels, speed buttons etc.  based on "Prima::Docks" module. See
120       Prima::DockManager.
121

Prima::AbstractDocker::Interface

123       Implements generic functionality of a docket widget. The class is not
124       derived from "Prima::Widget"; is used as a secondary ascendant class
125       for dock widget classes.
126
127   Properties
128       Since the class is not "Prima::Object" descendant, it provides only
129       run-time implementation of its properties. It is up to the descendant
130       object whether the properties are recognized on the creation stage or
131       not.
132
133       fingerprint INTEGER
134           A custom bit mask, to be used by docking widgets to reject
135           inappropriate dock widgets on early stage. The "fingerprint"
136           property is not part of the protocol, and is not required to be
137           present in a dockable widget implementation.
138
139           Default value: 0x0000FFFF
140
141       dockup DOCK_WIDGET
142           Selects the upper link in dock widgets hierarchy tree. The upper
143           link is required to be a dock widget, but is not required to be a
144           direct or an indirect parent. In this case, however, the
145           maintenance of the link must be implemented separately, for
146           example:
147
148                   $self-> dockup( $upper_dock_not_parent );
149
150                   $upper_dock_not_parent-> add_notification( 'Destroy', sub {
151                           return unless $_[0] == $self-> dockup;
152                           undef $self-> {dockup_event_id};
153                           $self-> dockup( undef );
154                   }, $self);
155
156                   $self-> {destroy_id} = $self-> add_notification( 'Destroy', sub {
157                           $self-> dockup( undef );
158                   } unless $self-> {destroy_id};
159
160   Methods
161       add_subdocker SUBDOCK
162           Appends SUBDOCK to the list of lower-level docker widgets. The
163           items of the list are returned by "next_docker" method.
164
165       check_session SESSION
166           Debugging procedure; checks SESSION hash, warns if its members are
167           invalid or incomplete. Returns 1 if no fatal errors were
168           encountered; 0 otherwise.
169
170       close_session SESSION
171           Closes docking SESSION and frees the associated resources.
172
173       dock WIDGET
174           Called after WIDGET is successfully finished negotiation with the
175           dock widget and changed its "owner" property. The method adapts the
176           dock widget layout and lists WIDGET into list of docked widgets.
177           The method does not change "owner" property of WIDGET.
178
179           The method must not be called directly.
180
181       dock_bunch @WIDGETS
182           Effectively docks set of WIDGETS by updating internal structures
183           and calling "rearrange".
184
185       docklings
186           Returns array of docked widgets.
187
188       next_docker SESSION, [ X, Y ]
189           Enumerates lower-level docker widgets within SESSION; returns one
190           docker widget at a time. After the last widget returns "undef".
191
192           The enumeration pointer is reset by "query" call.
193
194           X and Y are coordinates of the point of interest.
195
196       open_session PROFILE
197           Opens docking session with parameters stored in PROFILE and returns
198           session ID scalar in case of success, or "undef" otherwise.  The
199           following keys must be set in PROFILE:
200
201           position ARRAY
202               Contains two integer coordinates of the desired position of a
203               widget in (X,Y) format in screen coordinate system.
204
205           self WIDGET
206               Widget that is about to dock.
207
208           sizeable ARRAY
209               Contains two boolean flags, representing if the widget can be
210               resized to an arbitrary size, horizontally and vertically. The
211               arbitrary resize option used as last resort if "sizes" key does
212               not contain the desired size.
213
214           sizeMin ARRAY
215               Two integers; minimal size that the widget can accept.
216
217           sizes ARRAY
218               Contains arrays of points in (X,Y) format; each point
219               represents an acceptable size of the widget. If "sizeable"
220               flags are set to 0, and none of "sizes" can be accepted by the
221               dock widget, "open_session" fails.
222
223       query SESSION [ X1, Y1, X2, Y2 ]
224           Checks if a dockable widget can be landed into the dock.  If it
225           can, returns a rectangle that the widget must be set to.  If
226           coordinates ( X1 .. Y2 ) are specified, returns the rectangle
227           closest to these. If "sizes" or "sizeable" keys of "open_session"
228           profile were set, the returned size might be different from the
229           current docking widget size.
230
231           Once the caller finds the result appropriate, it is allowed to
232           change its owner to the dock; after that, it must change its origin
233           and size correspondingly to the result, and then call "dock".
234
235           If the dock cannot accept the widget, but contains lower-lever dock
236           widgets, returns the first lower-lever widget. The caller can use
237           subsequent calls to "next_docker" to enumerate all lower-level dock
238           widgets. A call to "query" resets the internal enumeration pointer.
239
240           If the widget cannot be landed, an empty array is returned.
241
242       rearrange
243           Effectively re-docks all the docked widgets. The effect is as same
244           as of
245
246                   $self-> redock_widget($_) for $self-> docklings;
247
248           but usually "rearrange" is faster.
249
250       redock_widget WIDGET
251           Effectively re-docks the docked WIDGET. If WIDGET has "redock"
252           method in its namespace, it is called instead.
253
254       remove_subdocker SUBDOCK
255           Removes SUBDOCK from the list of lower-level docker widgets.  See
256           also add_subdocker.
257
258       replace FROM, TO
259           Assigns widget TO same owner and rectangle as FROM. The FROM widget
260           must be a docked widget.
261
262       undock WIDGET
263           Removes WIDGET from list of docked widgets. The layout of the dock
264           widget can be changed after execution of this method. The method
265           does not change "owner" property of WIDGET.
266
267           The method must not be called directly.
268

Prima::SimpleWidgetDocker

270       A simple dock widget; accepts any widget that geometrically fits into.
271       Allows overlapping of the docked widgets.
272

Prima::ClientWidgetDocker

274       A simple dock widget; accepts any widget that can be fit to cover all
275       dock's interior.
276

Prima::LinearWidgetDocker

278       A toolbar-like docking widget class. The implementation does not allow
279       tiling, and can reshape the dock widget and rearrange the docked
280       widgets if necessary.
281
282       "Prima::LinearWidgetDocker" is orientation-dependent; its main axis,
283       governed by "vertical" property, is used to align docked widgets in
284       'lines', which in turn are aligned by the opposite axis ( 'major' and
285       'minor' terms are used in the code for the axes ).
286
287   Properties
288       growable INTEGER
289           A combination of "grow::XXX" constants, that describes how the dock
290           widget can be resized. The constants are divided in two sets,
291           direct and indirect, or, "vertical" property independent and
292           dependent.
293
294           The first set contains explicitly named constants:
295
296                   grow::Left       grow::ForwardLeft       grow::BackLeft
297                   grow::Down       grow::ForwardDown       grow::BackDown
298                   grow::Right      grow::ForwardRight      grow::BackRight
299                   grow::Up         grow::ForwardUp         grow::BackUp
300
301           that select if the widget can be grown to the direction shown.
302           These do not change meaning when "vertical" changes, though they do
303           change the dock widget behavior. The second set does not affect
304           dock widget behavior when "vertical" changes, however the names are
305           not that illustrative:
306
307                   grow::MajorLess  grow::ForwardMajorLess  grow::BackMajorLess
308                   grow::MajorMore  grow::ForwardMajorMore  grow::BackMajorMore
309                   grow::MinorLess  grow::ForwardMinorLess  grow::BackMinorLess
310                   grow::MinorMore  grow::ForwardMinorMore  grow::BackMinorMore
311
312           "Forward" and "Back" prefixes select if the dock widget can be
313           respectively expanded or shrunk in the given direction. "Less" and
314           "More" are equivalent to "Left" and "Right" when "vertical" is 0,
315           and to "Up" and "Down" otherwise.
316
317           The use of constants from the second set is preferred.
318
319           Default value: 0
320
321       hasPocket BOOLEAN
322           A boolean flag, affects the possibility of a docked widget to
323           reside outside the dock widget inferior. If 1, a docked wigdet is
324           allowed to stay docked ( or dock into a position ) further on the
325           major axis ( to the right when "vertical" is 0, up otherwise ), as
326           if there's a 'pocket'. If 0, a widget is neither allowed to dock
327           outside the inferior, nor is allowed to stay docked ( and is
328           undocked automatically ) when the dock widget shrinks so that the
329           docked widget cannot stay in the dock boundaries.
330
331           Default value: 1
332
333       vertical BOOLEAN
334           Selects the major axis of the dock widget. If 1, it is vertical,
335           horizontal otherwise.
336
337           Default value: 0
338
339   Events
340       Dock
341           Called when "dock" is successfully finished.
342
343       DockError WIDGET
344           Called when "dock" is unsuccessfully finished. This only happens if
345           WIDGET does not follow the docking protocol, and inserts itself
346           into a non-approved area.
347
348       Undock
349           Called when "undock" is finished.
350

Prima::SingleLinearWidgetDocker

352       Descendant of "Prima::LinearWidgetDocker". In addition to the
353       constraints, introduced by the ascendant class,
354       "Prima::SingleLinearWidgetDocker" allows only one line ( or row,
355       depending on "vertical" property value ) of docked widgets.
356

Prima::FourPartDocker

358       Implementation of a docking widget, with its four sides acting as
359       'rubber' docking areas.
360
361   Properties
362       indents ARRAY
363           Contains four integers, specifying the breadth of offset for each
364           side. The first integer is width of the left side, the second -
365           height of the bottom side, the third - width of the right side, the
366           fourth - height of the top side.
367
368       dockerClassLeft STRING
369           Assigns class of left-side dock window.
370
371           Default value: "Prima::LinearWidgetDocker".  Create-only property.
372
373       dockerClassRight STRING
374           Assigns class of right-side dock window.
375
376           Default value: "Prima::LinearWidgetDocker".  Create-only property.
377
378       dockerClassTop STRING
379           Assigns class of top-side dock window.
380
381           Default value: "Prima::LinearWidgetDocker".  Create-only property.
382
383       dockerClassBottom STRING
384           Assigns class of bottom-side dock window.
385
386           Default value: "Prima::LinearWidgetDocker".  Create-only property.
387
388       dockerClassClient STRING
389           Assigns class of center dock window.
390
391           Default value: "Prima::ClientWidgetDocker".  Create-only property.
392
393       dockerProfileLeft HASH
394           Assigns hash of properties, passed to the left-side dock widget
395           during the creation.
396
397           Create-only property.
398
399       dockerProfileRight HASH
400           Assigns hash of properties, passed to the right-side dock widget
401           during the creation.
402
403           Create-only property.
404
405       dockerProfileTop HASH
406           Assigns hash of properties, passed to the top-side dock widget
407           during the creation.
408
409           Create-only property.
410
411       dockerProfileBottom HASH
412           Assigns hash of properties, passed to the bottom-side dock widget
413           during the creation.
414
415           Create-only property.
416
417       dockerProfileClient HASH
418           Assigns hash of properties, passed to the center dock widget during
419           the creation.
420
421           Create-only property.
422
423       dockerDelegationsLeft ARRAY
424           Assigns the left-side dock list of delegated notifications.
425
426           Create-only property.
427
428       dockerDelegationsRight ARRAY
429           Assigns the right-side dock list of delegated notifications.
430
431           Create-only property.
432
433       dockerDelegationsTop ARRAY
434           Assigns the top-side dock list of delegated notifications.
435
436           Create-only property.
437
438       dockerDelegationsBottom ARRAY
439           Assigns the bottom-side dock list of delegated notifications.
440
441           Create-only property.
442
443       dockerDelegationsClient ARRAY
444           Assigns the center dock list of delegated notifications.
445
446           Create-only property.
447
448       dockerCommonProfile HASH
449           Assigns hash of properties, passed to all five dock widgets during
450           the creation.
451
452           Create-only property.
453

Prima::InternalDockerShuttle

455       The class provides a container, or a 'shuttle', for a client widget,
456       while is docked to an "Prima::AbstractDocker::Interface" descendant
457       instance. The functionality includes communicating with dock widgets,
458       the user interface for dragging and interactive dock selection, and a
459       client widget container for non-docked state. The latter is implemented
460       by reparenting of the client widget to an external shuttle widget,
461       selected by "externalDockerClass" property. Both user interfaces for
462       the docked and the non-docked shuttle states are minimal.
463
464       The class implements dockable widget functionality, served by
465       "Prima::AbstractDocker::Interface", while itself it is derived from
466       "Prima::Widget" only.
467
468       See also: "Prima::ExternalDockerShuttle".
469
470   Properties
471       client WIDGET
472           Provides access to the client widget, which always resides either
473           in the internal or the external shuttle. By default there is no
474           client, and any widget capable of changing its parent can be set as
475           one.  After a widget is assigned as a client, its "owner" and
476           "clipOwner" properties must not be used.
477
478           Run-time only property.
479
480       dock WIDGET
481           Selects the dock widget that the shuttle is landed on. If "undef",
482           the shuttle is in the non-docked state.
483
484           Default value: "undef"
485
486       dockingRoot WIDGET
487           Selects the root of dock widgets hierarchy.  If "undef", the
488           shuttle can only exist in the non-docked state.
489
490           Default value: "undef"
491
492           See "USAGE" for reference.
493
494       externalDockerClass STRING
495           Assigns class of external shuttle widget.
496
497           Default value: "Prima::ExternalDockerShuttle"
498
499       externalDockerModule STRING
500           Assigns module that contains the external shuttle widget class.
501
502           Default value: "Prima::MDI" ( "Prima::ExternalDockerShuttle" is
503           derived from "Prima::MDI" ).
504
505       externalDockerProfile HASH
506           Assigns hash of properties, passed to the external shuttle widget
507           during the creation.
508
509       fingerprint INTEGER
510           A custom bit mask, used to reject inappropriate dock widgets on
511           early stage.
512
513           Default value: 0x0000FFFF
514
515       indents ARRAY
516           Contains four integers, specifying the breadth of offset in pixels
517           for each widget side in the docked state.
518
519           Default value: "5,5,5,5".
520
521       snapDistance INTEGER
522           A maximum offset, in pixels, between the actual shuttle coordinates
523           and the coordinates proposed by the dock widget, where the shuttle
524           is allowed to land.  In other words, it is the distance between the
525           dock and the shuttle when the latter 'snaps' to the dock during the
526           dragging session.
527
528           Default value: 10
529
530       x_sizeable BOOLEAN
531           Selects whether the shuttle can change its width in case the dock
532           widget suggests so.
533
534           Default value: 0
535
536       y_sizeable BOOLEAN
537           Selects whether the shuttle can change its height in case the dock
538           widget suggests so.
539
540           Default value: 0
541
542   Methods
543       client2frame X1, Y1, X2, Y2
544           Returns a rectangle that the shuttle would occupy if its client
545           rectangle is assigned to X1, Y1, X2, Y2 rectangle.
546
547       dock_back
548           Docks to the recent dock widget, if it is still available.
549
550       drag STATE, RECT, ANCHOR_X, ANCHOR_Y
551           Initiates or aborts the dragging session, depending on STATE
552           boolean flag.
553
554           If it is 1, RECT is an array with the coordinates of the shuttle
555           rectangle before the drag has started; ANCHOR_X and ANCHOR_Y are
556           coordinates of the aperture point where the mouse event occurred
557           that has initiated the drag.  Depending on how the drag session
558           ended, the shuttle can be relocated to another dock, undocked, or
559           left intact. Also, "Dock", "Undock", or "FailDock" notifications
560           can be triggered.
561
562           If STATE is 0, RECT, ANCHOR_X ,and ANCHOR_Y parameters are not
563           used.
564
565       find_docking DOCK, [ POSITION ]
566           Opens a session with DOCK, unless it is already opened, and
567           negotiates about the possibility of landing ( at particular
568           POSITION, if this parameter is present ).
569
570           "find_docking" caches the dock widget sessions, and provides a
571           possibility to select different parameters passed to "open_session"
572           for different dock widgets. To achieve this, "GetCaps" request
573           notification is triggered, which fills the parameters. The default
574           action sets "sizeable" options according to "x_sizeable" and
575           "y_sizeable" properties.
576
577           In case an appropriate landing area is found, "Landing"
578           notification is triggered with the proposed dock widget and the
579           target rectangle. The area can be rejected on this stage if
580           "Landing" returns negative answer.
581
582           On success, returns a dock widget found and the target rectangle;
583           the widget is never docked though. On failure returns an empty
584           array.
585
586           This method is used by the dragging routine to provide a visual
587           feedback to the user, to indicate that a shuttle may or may not
588           land in a particular area.
589
590       frame2client X1, Y1, X2, Y2
591           Returns a rectangle that the client would occupy if the shuttle
592           rectangle is assigned to X1, Y1, X2, Y2 rectangle.
593
594       redock
595           If docked, undocks form the dock widget and docks back.  If not
596           docked, does not perform anything.
597
598   Events
599       Dock
600           Called when shuttle is docked.
601
602       EDSClose
603           Triggered when the user presses close button or otherwise activates
604           the "close" function of the EDS ( external docker shuttle ). To
605           cancel the closing, "clear_event" must be called inside the event
606           handler.
607
608       FailDock X, Y
609           Called after the dragging session in the non-docked stage is
610           finished, but did not result in docking. X and Y are the
611           coordinates of the new external shuttle position.
612
613       GetCaps DOCK, PROFILE
614           Called before the shuttle opens a docking session with DOCK widget.
615           PROFILE is a hash reference, which is to be filled inside the event
616           handler. After that PROFILE is passed to "open_session" call.
617
618           The default action sets "sizeable" options according to
619           "x_sizeable" and "y_sizeable" properties.
620
621       Landing DOCK, X1, Y1, X2, Y2
622           Called inside the docking session, after an appropriate dock widget
623           is selected and the landing area is defined as X1, Y1, X2, Y2. To
624           reject the landing on either DOCK or area, "clear_event" must be
625           called.
626
627       Undock
628           Called when shuttle is switched to the non-docked state.
629

Prima::ExternalDockerShuttle

631       A shuttle class, used to host a client of
632       "Prima::InternalDockerShuttle" widget when it is in the non-docked
633       state. The class represents an emulation of a top-level window, which
634       can be moved, resized ( this feature is not on by default though ), and
635       closed.
636
637       "Prima::ExternalDockerShuttle" is inherited from "Prima::MDI" class,
638       and its window emulating functionality is a subset of its ascendant.
639       See also Prima::MDI.
640
641   Properties
642       shuttle WIDGET
643           Contains reference to the dockable WIDGET
644

Prima::LinearDockerShuttle

646       A simple descendant of "Prima::InternalDockerShuttle", used for
647       toolbars. Introduces orientation and draws a tiny header along the
648       minor shuttle axis. All its properties concern only the way the shuttle
649       draws itself.
650
651   Properties
652       headerBreadth INTEGER
653           Breadth of the header in pixels.
654
655           Default value: 8
656
657       indent INTEGER
658           Provides a wrapper to "indents" property; besides the space for the
659           header, all indents are assigned to "indent" property value.
660
661       vertical BOOLEAN
662           If 1, the shuttle is drawn as a vertical bar.  If 0, the shuttle is
663           drawn as a horizontal bar.
664
665           Default value: 0
666

AUTHOR

668       Dmitry Karasik, <dmitry@karasik.eu.org>.
669

SEE ALSO

671       Prima, Prima::Widget, Prima::MDI, Prima::DockManager, examples/dock.pl
672
673
674
675perl v5.32.0                      2020-07-28                   Prima::Docks(3)
Impressum