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.tree;
8 import w4d.layout.placer.lineup,
9        w4d.layout.fill,
10        w4d.style.scalar,
11        w4d.task.window,
12        w4d.widget.base,
13        w4d.widget.list,
14        w4d.widget.panel;
15 import gl3n.linalg;
16 
17 /// A widget of tree list item.
18 class TreeListItemWidget : ListItemWidget
19 {
20     protected class ContentsWidget : PanelWidget
21     {
22         override bool handleMouseButton ( MouseButton btn, bool status, vec2 pos )
23         {
24             if ( super.handleMouseButton(btn,status,pos) ) return true;
25 
26             if ( btn == MouseButton.Right && status ) {
27                 (_opened? &close: &open)();
28                 return true;
29             }
30             return false;
31         }
32         this ()
33         {
34             super();
35             style.box.size.width = Scalar.Auto;
36         }
37     }
38     protected class TreeListWidget : ListWidget
39     {
40         override void selectItem ( ListItemWidget w )
41         {
42             _parent.selectItem( w );
43         }
44         override void unselectItem ( ListItemWidget w )
45         {
46             _parent.unselectItem( w );
47         }
48         this ()
49         {
50             super();
51             style.box.paddings.left = 5.mm;
52         }
53 
54         override @property bool trackable () { return false; }
55         override @property bool focusable () { return false; }
56     }
57     protected class CustomPanelWidget : PanelWidget
58     {
59         override @property Widget[] children ()
60         {
61             if ( _opened ) {
62                 return [_contents, _childList];
63             } else {
64                 return [_contents];
65             }
66         }
67         this ()
68         {
69             super();
70         }
71     }
72 
73     protected ListWidget _parent;
74     protected bool       _opened;
75 
76     /// Whether the tree item is expanded.
77     @property opened () { return _opened; }
78 
79     protected ContentsWidget _contents;
80     protected TreeListWidget _childList;
81 
82     /// Contents panel of the tree item.
83     @property contents () { return _contents; }
84     /// Children list of the tree item.
85     @property list () { return _childList; }
86 
87     ///
88     this ()
89     {
90         super();
91 
92         _parent = null;
93         _opened = false;
94 
95         _contents  = new ContentsWidget;
96         _childList = new TreeListWidget;
97 
98         super.setChild( new CustomPanelWidget );
99 
100         setLayout!( FillLayout, VerticalLineupPlacer );
101     }
102     mixin DisableModifyChild;
103 
104     ///
105     override @property ListItemWidget[] selectedItems ()
106     {
107         return list.selectedItems;
108     }
109 
110     ///
111     override void setParent ( ListWidget w )
112     {
113         _parent = w;
114     }
115     ///
116     override void deselect ()
117     {
118         return list.deselect();
119     }
120 
121     /// Expands and reveals the children list.
122     void open ()
123     {
124         _opened = true;
125         requestLayout();
126     }
127     /// Closes and hides the children list.
128     void close ()
129     {
130         _opened = false;
131         requestLayout();
132     }
133 }