1Prima::Docks(3) User Contributed Perl Documentation Prima::Docks(3)
2
3
4
6 Prima::Docks - dockable widgets
7
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
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
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
270 A simple dock widget; accepts any widget that geometrically fits into.
271 Allows overlapping of the docked widgets.
272
274 A simple dock widget; accepts any widget that can be fit to cover all
275 dock's interior.
276
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
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
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
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
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
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
668 Dmitry Karasik, <dmitry@karasik.eu.org>.
669
671 Prima, Prima::Widget, Prima::MDI, Prima::DockManager, examples/dock.pl
672
673
674
675perl v5.38.0 2023-07-21 Prima::Docks(3)