1 module dlangide.ui.stackpanel; 2 3 import dlangui; 4 5 import std.string : format; 6 import ddebug.common.debugger; 7 8 interface StackFrameSelectedHandler { 9 void onStackFrameSelected(ulong threadId, int frame); 10 } 11 12 class StackPanel : DockWindow, OnItemSelectedHandler, CellActivatedHandler { 13 14 Signal!StackFrameSelectedHandler stackFrameSelected; 15 16 this(string id) { 17 super(id); 18 _caption.text = "Stack"d; 19 } 20 21 override protected Widget createBodyWidget() { 22 layoutWidth = FILL_PARENT; 23 layoutHeight = FILL_PARENT; 24 VerticalLayout root = new VerticalLayout(); 25 root.layoutWidth = FILL_PARENT; 26 root.layoutHeight = FILL_PARENT; 27 _comboBox = new ComboBox("threadComboBox", ["Thread1"d]); 28 _comboBox.layoutWidth = FILL_PARENT; 29 _comboBox.selectedItemIndex = 0; 30 _comboBox.itemClick = this; 31 _grid = new StringGridWidget("stackGrid"); 32 _grid.cellActivated = this; 33 _grid.resize(2, 0); 34 _grid.showColHeaders = true; 35 _grid.showRowHeaders = false; 36 _grid.layoutHeight = FILL_PARENT; 37 _grid.layoutWidth = FILL_PARENT; 38 _grid.setColTitle(0, "Function"d); 39 _grid.setColTitle(1, "Address"d); 40 _grid.layoutWidth = FILL_PARENT; 41 _grid.layoutHeight = FILL_PARENT; 42 root.addChild(_comboBox); 43 root.addChild(_grid); 44 return root; 45 } 46 47 StringGridWidget _grid; 48 ComboBox _comboBox; 49 DebugThreadList _debugInfo; 50 DebugThread _selectedThread; 51 ulong _currentThreadId; 52 int _currentThreadIndex; 53 int _currentFrame; 54 void updateDebugInfo(DebugThreadList data, ulong currentThreadId, int currentFrame) { 55 import std.path; 56 _debugInfo = data; 57 if (currentThreadId == 0) 58 currentThreadId = data.currentThreadId; 59 _currentThreadId = currentThreadId; 60 _currentThreadIndex = -1; 61 _currentFrame = 0; 62 _selectedThread = null; 63 if (_debugInfo) { 64 _comboBox.enabled = true; 65 dstring[] threadNames; 66 for (int i = 0; i < _debugInfo.length; i++) { 67 threadNames ~= _debugInfo[i].displayName.toUTF32; 68 if (_debugInfo[i].id == _currentThreadId) { 69 _currentThreadIndex = i; 70 _selectedThread = _debugInfo[i]; 71 if (currentFrame <= _selectedThread.length) 72 _currentFrame = currentFrame; 73 } 74 } 75 _comboBox.items = threadNames; 76 if (_currentThreadIndex >= 0 && _selectedThread.length > 0) { 77 _comboBox.selectedItemIndex = _currentThreadIndex; 78 _grid.resize(2, _selectedThread.length); 79 for (int i = 0; i < _selectedThread.length; i++) { 80 if (_selectedThread[i].func) 81 _grid.setCellText(0, i, _selectedThread[i].func.toUTF32); 82 else if (_selectedThread[i].from) 83 _grid.setCellText(0, i, baseName(_selectedThread[i].from.toUTF32)); 84 else 85 _grid.setCellText(0, i, _selectedThread[i].file.toUTF32); 86 _grid.setCellText(1, i, _selectedThread[i].formattedAddress.toUTF32); 87 } 88 } else { 89 _grid.resize(2, 1); 90 _grid.setCellText(0, 0, "No info"d); 91 _grid.setCellText(1, 0, ""d); 92 } 93 } else { 94 _comboBox.enabled = false; 95 } 96 } 97 98 void onCellActivated(GridWidgetBase source, int col, int row) { 99 if (_debugInfo && _selectedThread && row < _selectedThread.length) { 100 if (stackFrameSelected.assigned) 101 stackFrameSelected(_currentThreadId, row); 102 } 103 } 104 105 bool onItemSelected(Widget source, int itemIndex) { 106 if (_debugInfo && itemIndex < _debugInfo.length && _currentThreadId != _debugInfo[itemIndex].id) { 107 _grid.selectCell(0, 0, true, null, false); 108 if (stackFrameSelected.assigned) 109 stackFrameSelected(_debugInfo[itemIndex].id, 0); 110 } 111 return true; 112 } 113 114 protected void onPopupMenuItem(MenuItem item) { 115 if (item.action) 116 handleAction(item.action); 117 } 118 119 /// override to handle specific actions 120 override bool handleAction(const Action a) { 121 return super.handleAction(a); 122 } 123 124 override void layout(Rect rc) { 125 if (visibility == Visibility.Gone) { 126 return; 127 } 128 super.layout(rc); 129 _grid.autoFitColumnWidth(2); 130 int w = _grid.clientRect.width - _grid.colWidth(2); 131 if (w < _grid.clientRect.width * 2 / 3) 132 w = _grid.clientRect.width * 2 / 3; 133 _grid.setColWidth(1, w); 134 _grid.layout(_grid.pos); 135 } 136 } 137