1 // Written in the D programming language.
2 /++
3  + Authors: KanzakiKino
4  + Copyright: KanzakiKino 2018
5  + License: LGPL-3.0
6 ++/
7 module w4d.widget.mdi.host;
8 import w4d.layout.placer.fill,
9        w4d.layout.fill,
10        w4d.style.color,
11        w4d.style.widget,
12        w4d.task.window,
13        w4d.widget.base,
14        w4d.exception;
15 import gl3n.linalg;
16 import std.algorithm,
17        std.array;
18 
19 /// A host widget for MDI.
20 class MdiHostWidget : Widget
21 {
22     protected MdiClient[] _clients;
23     /// Child clients.
24     @property clients () { return _clients; }
25 
26     ///
27     override @property Widget[] children ()
28     {
29         return _clients.map!"a.widget".array;
30     }
31 
32     ///
33     this ()
34     {
35         super();
36         setLayout!( FillLayout, FillPlacer );
37 
38         _clients = [];
39     }
40 
41     /// Adds the client widget.
42     void addClient ( MdiClient cli )
43     {
44         enforce( cli, "The client is invalid." );
45         cli.setHost( this );
46         _clients ~= cli;
47         infectWindowContext();
48 
49         unfocusAllClients();
50         cli.widget.enableState( WidgetState.Focused );
51         requestRedraw();
52     }
53     /// Removes the client widget.
54     void removeClient ( MdiClient cli )
55     {
56         _context.forget( cli.widget );
57         _clients = _clients.remove!( x => x is cli );
58         requestRedraw();
59     }
60 
61     protected void unfocusAllClients ()
62     {
63         foreach ( cli; _clients ) {
64             cli.widget.disableState( WidgetState.Focused );
65         }
66     }
67     /// Focuses to the client.
68     void focusClient ( MdiClient cli )
69     {
70         enforce( cli, "The client is invalid." );
71         removeClient( cli );
72         addClient( cli );
73         requestRedraw();
74     }
75 
76     ///
77     override vec2 layout ( vec2 basept, vec2 parentSize )
78     {
79         return super.layout( basept, parentSize );
80     }
81 
82     ///
83     override void draw ( Window w, in ColorSet parent )
84     {
85         auto leftTop = style.translate +
86             style.box.borderInsideLeftTop;
87 
88         w.clip.pushRect( leftTop,
89                 style.box.borderInsideSize );
90         super.draw( w, parent );
91         w.clip.popRect();
92     }
93 }
94 
95 /// An interface of clients for MDI..
96 interface MdiClient
97 {
98     /// Position of the client.
99     @property vec2 pos  ();
100     /// Size of the client.
101     @property vec2 size ();
102 
103     /// This property returns thiself that is casted to Widget.
104     /// To prove the casting is safe.
105     @property Widget widget ();
106 
107     /// Changes the host widget.
108     void setHost ( MdiHostWidget );
109 }