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