1 module dlangide.ui.watchpanel;
2 
3 import dlangui;
4 
5 import std..string : format;
6 import ddebug.common.debugger;
7 
8 class VariablesWindow : StringGridWidget {
9     DebugFrame _frame;
10     this(string ID = null) {
11         super(ID);
12         resize(3, 0);
13         showColHeaders = true;
14         showRowHeaders = false;
15         layoutHeight = FILL_PARENT;
16         layoutWidth = FILL_PARENT;
17         setColTitle(0, "Variable"d);
18         setColTitle(1, "Value"d);
19         setColTitle(2, "Type"d);
20         autoFit();
21     }
22     void setFrame(DebugFrame frame) {
23         _frame = frame;
24         if (frame && frame.locals) {
25             resize(3, frame.locals.length);
26             for (int i = 0; i < frame.locals.length; i++) {
27                 DebugVariable var = frame.locals[i];
28                 setCellText(0, i, var.name.toUTF32);
29                 setCellText(1, i, var.value.toUTF32);
30                 setCellText(2, i, var.type.toUTF32);
31             }
32             autoFit();
33         } else {
34             resize(3, 0);
35             autoFit();
36         }
37     }
38 
39     override void layout(Rect rc) {
40         if (visibility == Visibility.Gone) {
41             return;
42         }
43         super.layout(rc);
44         int cw = clientRect.width;
45         setColWidth(1, cw * 40 / 100);
46         setColWidth(2, cw * 45 / 100);
47         setColWidth(3, cw * 25 / 100);
48         super.layout(_pos);
49     }
50 }
51 
52 class WatchPanel : DockWindow {
53 
54     this(string id) {
55         _showCloseButton = false;
56         dockAlignment = DockAlignment.Bottom;
57         super(id);
58     }
59 
60     protected TabWidget _tabs;
61     protected VariablesWindow _locals;
62     protected VariablesWindow _autos;
63 
64     override protected Widget createBodyWidget() {
65         layoutWidth = FILL_PARENT;
66         layoutHeight = FILL_PARENT;
67         _tabs = new TabWidget("WatchPanelTabs", Align.Bottom);
68         _tabs.setStyles(null, STYLE_TAB_DOWN_DARK, STYLE_TAB_DOWN_BUTTON_DARK, STYLE_TAB_UP_BUTTON_DARK_TEXT);
69         _tabs.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
70         _tabs.tabHost.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
71 
72         _locals = new VariablesWindow("watchLocals");
73         _autos = new VariablesWindow("watchAutos");
74         _tabs.addTab(_locals, "Locals"d);
75         _tabs.addTab(_autos, "Autos"d);
76         _tabs.selectTab("watchAutos");
77 
78         return _tabs;
79     }
80 
81     override protected void initialize() {
82         //styleId = STYLE_DOCK_WINDOW;
83         styleId = null;
84         //_caption.text = "Watch"d;
85         _bodyWidget = createBodyWidget();
86         //_bodyWidget.styleId = STYLE_DOCK_WINDOW_BODY;
87         addChild(_bodyWidget);
88     }
89 
90     protected void onPopupMenuItem(MenuItem item) {
91         if (item.action)
92             handleAction(item.action);
93     }
94 
95     /// override to handle specific actions
96     override bool handleAction(const Action a) {
97         return super.handleAction(a);
98     }
99 
100     DebugThreadList _debugInfo;
101     DebugThread _selectedThread;
102     DebugFrame _frame;
103     ulong _currentThreadId;
104     int _currentThreadIndex;
105     int _currentFrame;
106     void updateDebugInfo(DebugThreadList data, ulong currentThreadId, int currentFrame) {
107         _debugInfo = data;
108         if (currentThreadId == 0)
109             currentThreadId = data.currentThreadId;
110         _currentThreadId = currentThreadId;
111         _currentThreadIndex = -1;
112         _currentFrame = 0;
113         _selectedThread = null;
114         _frame = null;
115 
116         if (_debugInfo) {
117             for (int i = 0; i < _debugInfo.length; i++) {
118                 if (_debugInfo[i].id == _currentThreadId) {
119                     _currentThreadIndex = i;
120                     _selectedThread = _debugInfo[i];
121                     if (currentFrame <= _selectedThread.length) {
122                         _currentFrame = currentFrame;
123                         _frame = _selectedThread[_currentFrame];
124                     }
125                 }
126             }
127         }
128         _locals.setFrame(_frame);
129         _autos.setFrame(_frame);
130     }
131 }
132