1=head1 NAME
2
3Prima::Window - top-level window management
4
5=head1 SYNOPSIS
6
7   use Prima;
8   use Prima::Application;
9
10   # this window, when closed, terminated the application
11   my $main = Prima::MainWindow-> new( text => 'Hello world' );
12
13   # this is a modal window
14   my $dialog = Prima::Dialog->create( size => [ 100, 100 ]);
15   my $result = $dialog-> execute;
16   $dialog-> destroy;
17
18   run Prima;
19
20=head1 DESCRIPTION
21
22Prima::Window is a descendant of Prima::Widget class.
23It deals with top-level windows, the windows that
24are specially treated by the system. Its major
25difference from Prima::Widget is that instances of
26Prima::Window can only be inferior by the
27screen, not the other windows, and that the system or window manager add
28decorations to these - usually menus, buttons and title
29bars. Prima::Window provides methods that communicate
30with the system and hint these decorations.
31
32=head1 USAGE
33
34A typical program communicates with the user with aid
35of widgets, collected upon one or more top-level windows.
36Prima::Widget already has all functionality required for
37these child-parent operations, so Prima::Window is not
38special in respect of widget grouping and relationship.
39Its usage therefore is straightforward:
40
41   my $w = Prima::Window-> create(
42       size => [300,300],
43       text => 'Startup window',
44   );
45
46There are more about Prima::Window in areas, that it is
47specifically designed to - the system window management and
48the dialog execution.
49
50=head2 System window management
51
52As noted before, top-level windows are special for the system,
53not only in their 'look', but also in 'feel': the system adds
54specific functions to the windows, aiding the user to navigate through
55the desktop. The system ofter dictates the size and position for
56windows, and some times these rules are hard or even impossible to
57circumvent. This document will be long if it would venture to describe the features
58of different window management systems, and the task would be
59never accomplished - brand new window managers emerge every month,
60and the old change their behavior in an unpredictable way. The only
61golden rule is to never rely on the behavior of one window manager,
62and test programs with at least two.
63
64The Prima toolkit provides simple access to buttons, title bar
65and borders of a window. Buttons and title bar are managed by
66the C<::borderIcons> property, and borders by the C<::borderStyle>
67property. These operate with set of predefined constants, C<bi::XXX>
68and C<bs::XXX>, correspondingly. The button constants can be combined with
69each other, but not all combinations may be granted by the system.
70The same is valid also for the border constant, except that they can
71not be combined - the value of C<::borderStyle> is one of the integer constants.
72
73There are other hints that the toolkit can set for a window manager.
74The system can be supplied with an icon that a window is bound to; the icon
75dimensions are much different, and although can be requested via
76C<sv::XIcon> and C<sv::YIcon> system values, the C<::icon> property
77scales the image automatically to the closest system-recognizable
78dimension. The window icon is not shown by the toolkit, it is usually
79resides in the window decorations and sometimes on a task bar, along
80with the window's name. The system can be hinted to not reflect the window
81on the task bar, by setting the C<::taskListed> property to 0.
82
83Another issue is the window positioning. Usually, if no explicit
84position was given, the window is positioned automatically
85by the system. The same is valid for the size.  But some window
86managers bend it to the extreme - for example, default CDE
87setup force the user to set newly created windows' positions explicitly.
88However, there is at least one point of certainty.
89Typically, when the initial size and/or position of a top-level window
90are expected to be set by the system, the C<::originDontCare> and
91C<::sizeDontCare> properties can be set to 1 during window creation.
92If these set, the system is asked to size/position a window regarding
93its own windowing policy. The reverse is not always true, unfortunately.
94Either if these properties set to 0, or explicit size or positions are given,
95the system is hinted to use these values instead, but this does not
96always happen. Actually, this behavior is expected by the user and often does
97not get even noticed as something special. Therefore it is a good practice to test
98a top-level windowing code with several window managers.
99
100There are different policies about window positioning and sizing;
101some window managers behave best when the position is given to the window
102with the system-dependent decorations. It is hardly can be called a good
103policy, since it is not possible to calculate the derived window coordinates
104with certainty. This problem results in that it is impossible to
105be sure about window position and size before these are set explicitly.
106The only, not much efficient help the toolkit can provide is the property
107pair C<::frameOrigin> and C<::frameSize>, which along with C<::origin>
108and C<::size> reflect the position and size of a window, but taking into
109account the system-dependent decorations.
110
111=head2 Dialog execution
112
113Method of Prima::Window, C<execute()> brings a window
114in a modal state on top of other toolkit windows, and
115returns after the window is dismissed in one or another way.
116This method is special as it is an implicit event loop,
117similar to
118
119  run Prima;
120
121code. The event flow is not disrupted, but the windows and
122widgets that do not belong to the currently executed, the
123'modal' window group can not be activated. There can be many
124modal windows on top of each other, but only one is accessible.
125As an example a message box can be depicted, a window that prevents
126the user to work with the application windows until dismissed.
127There can be other message boxes on top of each other, preventing
128the windows below from operation as well.
129This scheme is called the 'exclusive' modality.
130
131The toolkit also provides the shared modality scheme, where
132there can be several stacks of modal windows, not interfering
133with each other. Each window stack is distinct and contains its own windows.
134An example analogy is when several independent applications run with
135modal message boxes being activated. This scheme, however, can not be achieved
136with single execute()-like call without creating interlocking
137conditions. The shared model call, C<execute_shared()>,
138inserts the window into the shared modal stack, activates the window and returns immediately.
139
140The both kinds of modal windows can coexist, but the exclusive
141windows prevents the shared from operation; while there are
142exclusive windows, the shared have same rights as the usual windows.
143
144The stacking order for these two models is slightly different.  A window after
145execute() call is set on top of the last exclusive modal window, or, in other
146words, is added to the exclusive window stack. There can be only one exclusive
147window stack, but many shared window stacks; a window after execute_shared()
148call is added to a shared window stack, to the one the window's owner belongs
149to. The shared window stacks are rooted in so-called modal horizons, windows
150with boolean property C<::modalHorizon> set to C<true>. The default horizon is
151C<::application>.
152
153A window in modal state can return to the normal (non-modal) state by calling
154C<end_modal()> method. The window is then hidden and disabled, and the windows
155below are accessible to the user. If the window was in the exclusive modal
156state, the execute() call is finished and returns the exit code, the value of
157C<::modalResult> property. There two shortuct methods that end modal state,
158setting C<::modalResult> to the basic 'ok' and 'not ok' code, correspondingly
159C<ok()> and C<cancel()> methods. Behavior of C<cancel()> is identical to when
160the user closes the modal window by clicking the system close button, pressing
161Escape key, or otherwise cancelling the dialog execution. C<ok()> sets
162C<::modalResult> to C<mb::OK>, C<cancel()> to C<mb::Cancel>, correspondingly.
163There are more C<mb::XXX> constants, but these have no special meaning, any
164integer value can be passed. For example, C<Prima::MsgBox::message> method uses
165these constants so the message window can return up to four different C<mb>
166codes.
167
168=head2 Menu
169
170A top-level window can be equipped with a menu bar. Its outlook
171is system-dependent, but can be controlled by the toolkit up to
172a certain level. The C<::menuItems> property, that manages the menu items
173of a C<::menu> object of L<Prima::Menu> class, arrange the layout
174of the menu. The syntax of the items-derived properties is described in
175L<Prima::Menu>, but it must be reiterated that menu items contain only
176hints, not requests for their exact representation. The same is valid for
177the color and font properties, C<::menuColorIndex> and C<::menuFont>.
178
179Only one menu at a time can be displayed in a top-level window, although
180a window can be an owner for many menu objects. The key property is
181C<Prima::Menu::selected> - if a menu object is selected on a widget
182or a window object, it refers to the default menu actions, which, in
183case of Prima::Window is being displayed as menu bar.
184
185NB: A window can be an owner for several menu objects and still do not
186have a menu bar displayed, if no menu objects are marked as selected.
187
188=head2 Prima::Dialog
189
190Prima::Dialog, a descendant from Prima::Window, introduces no
191new functionality. It has its default values adjusted so
192the colors use more appropriate system colors, and hints
193the system that the outlook of a window is to be different,
194to resemble the system dialogs on systems where such are
195provided.
196
197=head2 Prima::MainWindow
198
199The class is a simple descendant of Prima::Window, which overloads
200C<on_destroy> notification and calls C<$application-E<gt>close> inside it. The
201purpose of declaration of a separate class for such a trifle difference is that
202many programs are designed under a paradigm where these is a main window, which
203is most 'important' to the user. As such the construct is used more often than
204any other, it is considered an optimization to write
205
206   Prima::MainWindow-> create( ... )
207
208rather than
209
210   Prima::Window-> create( ...,
211      mainWindow => 1,
212      onDestroy  => sub { $::application-> close }
213   )
214
215, although these lines are equivalent.
216
217Also, the C<$::main_window> is pointed to a newly created main window.
218
219See also C<mainWindow>.
220
221=head1 API
222
223=head2 Properties
224
225=over
226
227=item borderIcons INTEGER
228
229Hints the system about window's decorations, by
230selecting the combination of C<bi::XXX> constants.
231The constants are:
232
233   bi::SystemMenu  - system menu button and/or close button
234                     ( usually with icon ) is shown
235   bi::Minimize    - minimize button
236   bi::Maximize    - maximize ( and eventual restore )
237   bi::TitleBar    - window title
238   bi::All         - all of the above
239
240Not all systems respect these hints, and many systems
241provide more navigating decoration controls than these.
242
243=item borderStyle STYLE
244
245Hints the system about window's border style, by selecting
246one of C<bs::XXX> constants. The constants are:
247
248   bs::None      - no border
249   bs::Single    - thin border
250   bs::Dialog    - thick border
251   bs::Sizeable  - thick border with interactive resize capabilities
252
253C<bs::Sizeable> is an unique window mode. If selected, the user
254can resize the window, not only by dragging the window borders with
255the mouse but by other system-dependent means. The other border styles
256disallow interactive resizing.
257
258Not all systems recognize all these hints, although many recognize
259interactive resizing flag.
260
261=item effects HASH or undef
262
263This generic property implements system-specific window effects, not necessarily portable. The format of the hash
264is also system-specific. The only portable behavior here is that setting the value to C<undef> cancels all effects.
265
266Example:
267
268   $window->effects({
269       effect1 => {
270          key1 => $value1,
271          ...
272       },
273   });
274
275Previously this was the mechanism for setting the DWM blur on Windows 7 and 8, but as Windows 10 removed it,
276this capability was also removed, so as for now this is basically an empty call.
277
278=item frameHeight HEIGHT
279
280Maintains the height of a window, including
281the window decorations.
282
283=item frameOrigin X_OFFSET, Y_OFFSET
284
285Maintains the left X and bottom Y boundaries of a window's
286decorations relative to the screen.
287
288=item frameSize WIDTH, HEIGHT
289
290Maintains the width and height of a window, including
291the window decorations.
292
293=item frameWidth WIDTH
294
295Maintains the width of a window, including
296the window decorations.
297
298
299=item icon OBJECT
300
301Hints the system about an icon, associated with a window.
302If OBJECT is C<undef>, the system-default icon is assumed.
303
304See also: C<ownerIcon>
305
306=item mainWindow BOOLEAN
307
308Tells the system that the window is the main window for the application.  When
309dialogs and modal windows are not anchored to any specific window, the main
310window is used. In this context, anchoring means that if, for example, a window
311spawns a dialog, and then is minimized or obscured, and then the user clicks on
312either window, both can be brought forward (also in correct Z-order) by the system
313window manager.
314
315=item menu OBJECT
316
317Manages a Prima::Menu object associated with a window.
318Prima::Window can host many Prima::Menu objects,
319but only the one that is set in
320C<::menu> property will be seen as a menu bar.
321
322See also: C<Prima::Menu>, C<menuItems>
323
324=item menuColorIndex INDEX, COLOR
325
326Maintains eight color properties of a menu,
327associated with a window. INDEX must be one of C<ci::XXX> constants
328( see L<Prima::Widget>, I<colorIndex> section ).
329
330See also: C<menuItems>, C<menuFont>, C<menu>
331
332=item menuColor COLOR
333
334Basic foreground menu color.
335
336See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
337
338=item menuBackColor COLOR
339
340Basic background menu color.
341
342See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
343
344=item menuDark3DColor COLOR
345
346Color for drawing dark shadings in menus.
347
348See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
349
350=item menuDisabledColor COLOR
351
352Foreground color for disabled items in menus.
353
354See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
355
356=item menuDisabledBackColor COLOR
357
358Background color for disabled items in menus.
359
360See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
361
362=item menuFont %FONT
363
364Maintains the font of a menu, associated with a window.
365
366See also: C<menuItems>, C<menuColorIndex>, C<menu>
367
368=item menuHiliteColor COLOR
369
370Foreground color for selected items in menus.
371
372See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
373
374=item menuHiliteBackColor COLOR
375
376Background color for selected items in menus.
377
378See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
379
380=item menuItems [ ITEM_LIST ]
381
382Manages items of a Prima::Menu object associated with a window.
383The ITEM_LIST format is same as C<Prima::AbstractMenu::items>
384and is described in L<Prima::Menu>.
385
386See also: C<menu>, C<menuColorIndex>, C<menuFont>
387
388=item menuLight3DColor COLOR
389
390Color for drawing light shadings in menus.
391
392See also: C<menuItems>, C<menuColorIndex>, C<menuFont>, C<menu>
393
394=item modalHorizon BOOLEAN
395
396Reflects if a window serves as root to the shared modal window stack.  A window
397with C<::modalHorizon> set to 1 in shared modal state groups its children
398windows in a window stack, separate from other shared modal stacks. The
399C<::modalHorizon> is therefore useful only when several shared modal window
400stacks are needed.
401
402The property also serves as an additional grouping factor for widgets and
403windows. For example, default keyboard navigation by tab and arrow keys is
404limited to the windows and widgets of a single window stack.
405
406=item modalResult INTEGER
407
408Maintains a custom integer value, returned by C<execute()>.
409Historically it is one of C<mb::XXX> constants, but any
410integer value can be used. The most useful C<mb::> constants are:
411
412   mb::OK, mb::Ok
413   mb::Cancel
414   mb::Yes
415   mb::No
416   mb::Abort
417   mb::Retry
418   mb::Ignore
419   mb::Help
420
421NB: These constants are defined so they can be bitwise-or'ed,
422and I<Prima::MsgBox> package uses this feature, where one
423of its functions parameters is a combination of C<mb::> constants.
424
425=item onTop BOOLEAN
426
427If set, the window is hinted to stay on top of all other windows.
428
429Default value: 0
430
431=item ownerIcon BOOLEAN
432
433If 1, the icon is synchronized with the owner's.
434Automatically set to 0 if C<::icon> property is explicitly set.
435Default value is 1, so assigning an icon to $::application
436spawns the icon to all windows.
437
438=item taskListed BOOLEAN
439
440If set to 0, hints the system against
441reflecting existence of a window into a system task bar,
442or a top-level window list, or otherwise lower the window's
443value before the other windows. If 1, does not hint anything.
444
445Default value: 1
446
447=item windowState STATE
448
449A three-state property, that governs the state of a window.
450STATE can be one of three C<ws::XXX> constants:
451
452   ws::Normal
453   ws::Minimized
454   ws::Maximized
455
456There can be more or less, or other window states
457provided by the system, but these three were chosen as
458a 'least common denominator'.  The property can be changed
459either by explicit set-mode call or by the user. In either case,
460a C<WindowState> notification is triggered.
461
462The property has three convenience wrappers: C<maximize()>,
463C<minimize()> and C<restore()>.
464
465See also: C<WindowState>
466
467=back
468
469=head2 Methods
470
471=over
472
473=item cancel
474
475A standard method to dismiss a modal window with C<mb::Cancel>
476result. The effect of calling this method is equal to when
477the user selects a 'close window' action with system-provided
478menu, button or other tool.
479
480See also: C<ok>, C<modalResult>, C<execute>, C<execute_shared>
481
482
483=item end_modal
484
485If a window is in modal state, the C<EndModal>
486notification is activated.
487Then the window is returned from the modal state,
488gets hidden and disabled.
489If the window was on top in the exclusive modal state,
490the last called C<execute()> function finishes.
491If the window was not on top in the exclusive modal state,
492the corresponding C<execute()> function finishes after
493all subsequent execute() calls are finished.
494
495=item execute INSERT_BEFORE = undef
496
497A window is turned to the exclusive modal state
498and is put on top of non-modal and shared-modal windows.
499By default, if INSERT_BEFORE object is undef, the window
500is also put on top of other exclusive-modal windows;
501if INSERT_BEFORE is one of the exclusive-modal windows
502the window is placed in queue before the INSERT_BEFORE window.
503The window is showed and enabled, if necessary, and
504C<Execute> notification is triggered.
505
506The function is returned when a window is dismissed,
507or if the system-dependent 'exit'-event is triggered by the
508user ( the latter case falls through all execute() calls
509and terminates C<run Prima;> call, exiting gracefully).
510
511=item execute_shared INSERT_BEFORE = undef
512
513A window is turned to the shared modal state
514and is put on top of non-modal windows in the stack
515of its C<::modalHorizon>. A window with C<::modalHorizon>
516set to 1 starts its own stack, independent of all other
517window stacks.
518
519By default, if INSERT_BEFORE object is undef, the window
520is also put on top of other shared-modal windows in its stack.
521If INSERT_BEFORE is one of the shared-modal windows in its stack,
522the window is placed in queue before the INSERT_BEFORE window.
523
524The window is showed and enabled, if necessary, and
525C<Execute> notification is triggered.
526
527The function is returned immediately.
528
529=item get_client_handle
530
531Returns a system handle for a system window that is inserted in top-level windows and
532covers all of its area. Is different from C<Window::get_handle> in that it returns the
533system handle of the top-level window itself. In other terms, window returned by
534this function is a child of the window returned by C<Window::get_handle>.
535
536See also: C<get_handle>
537
538=item get_default_menu_font
539
540Returns the default font for a Prima::Menu class.
541
542=item get_modal
543
544Returns one of three constants, reflecting the modal
545state of a window:
546
547   mt::None
548   mt::Shared
549   mt::Exclusive
550
551Value of C<mt::None> is 0, so result of get_modal() can be
552also treated as a boolean value, if only the fact of modality
553is needed to check.
554
555=item get_modal_window MODALITY_TYPE = mt::Exclusive, NEXT = 1
556
557Returns a modal window, that is next to the given window in the
558modality chain. MODALITY_TYPE selects the chain, and can be either
559C<mt::Exclusive> or C<mt::Shared>. NEXT is a boolean flag, selecting
560the lookup direction; if it is 1, the 'upper' window is returned,
561if 0, the 'lower' one ( in a simple case when window A is made modal
562(executed) after modal window B, the A window is the 'upper' one ).
563
564If a window has no immediate modal relations,  C<undef> is returned.
565
566=item maximize
567
568Maximizes window. A shortcut for C<windowState(ws::Maximized)>.
569
570=item minimize
571
572Minimizes window. A shortcut for C<windowState(ws::Minimized)>.
573
574=item ok
575
576A standard method to dismiss a modal window with C<mb::OK>
577result. Typically the effect of calling this method is equal to when
578the user presses the enter key of a modal window, signaling that
579the default action is to be taken.
580
581See also: C<cancel>, C<modalResult>, C<execute>, C<execute_shared>
582
583
584=item restore
585
586Restores window to normal state from
587minimized or maximized state. A shortcut for C<windowState(ws::Normal)>.
588
589=back
590
591=head2 Events
592
593=over
594
595=item Activate
596
597Triggered when a window is activated by the user.
598Activation mark is usually resides on a window that
599contains keyboard focus, and is usually reflected by
600highlighted system decorations.
601
602The toolkit does not provide standalone activation
603functions; C<select()> call is used instead.
604
605=item Deactivate
606
607Triggered when a window is deactivated by the user.
608Window is usually marked inactive, when it contains
609no keyboard focus.
610
611The toolkit does not provide standalone de-activation
612functions; C<deselect()> call is used instead.
613
614=item EndModal
615
616Called before a window leaves modal state.
617
618=item Execute
619
620Called after a window enters modal state.
621
622=item SysHandle
623
624Same as in C<Widget>, but it addition to the Widget properties that may trigger
625the event, the following C<Window> properties can trigger it as well:
626L<taskListed>, L<borderIcons>, L<borderStyle>, L<onTop>
627
628=item WindowState STATE
629
630Triggered when window state is changed, either by
631an explicit C<windowState()> call, or by the user.
632STATE is the new window state, one of three C<ws::XXX>
633constants.
634
635=back
636
637=head1 AUTHOR
638
639Dmitry Karasik, E<lt>dmitry@karasik.eu.orgE<gt>.
640
641
642=head1 SEE ALSO
643
644L<Prima>, L<Prima::Object>, L<Prima::Drawable>,
645L<Prima::Widget>.
646
647
648