ide/CodeEditor: Customizable color scheme support
[sdk] / ide / src / panels / BreakpointsView.ec
1 import "ide"
2
3 class BreakpointsView : Window
4 {
5    visible = false;
6    borderStyle = sizable;
7    background = { 224, 224, 224 };
8    hasClose = true;
9    text = $"Breakpoints";
10    clientSize = Size { 206, 624 };
11    //anchor = Anchor { left = 0.8, top = 200, right = 0, bottom = 200 };
12    //size = { 150 };
13    anchor = Anchor { left = 0, right = 0, bottom = 0 };
14    size.h = 240;
15
16    bool moved, logging;
17
18    ListBox listBox
19    {
20       parent = this, resizable = true, hasHeader = true, alwaysEdit = true, collapseControl = true, size = { 206, 624 };
21       anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 }; //visible = true
22       /*
23       background = colorScheme.viewsBackground;
24       foreground = colorScheme.viewsText;
25       selectionColor = colorScheme.selectionColor;
26       selectionText = colorScheme.selectionText;
27       */
28
29       bool NotifyChanged(ListBox listBox, DataRow row)
30       {
31          if(listBox.currentField == locationField)
32          {
33             char * location = (char *)row.GetData(locationField);
34             if(location && location[0])
35             {
36                TrimLSpaces(location, location);
37                TrimRSpaces(location, location);
38             }
39             if(location && location[0])
40             {
41                if(row == listBox.lastRow)
42                {
43                   DataRow newRow = listBox.AddRow();
44                   newRow.SetData(locationField, null);
45                }
46                ide.workspace.ChangeBreakpoint(row, location); // TODO make sure passing only unix style path
47             }
48             else
49             {
50                ide.workspace.RemoveBreakpoint((Breakpoint)(intptr)row.tag);
51                // This is already done by Workspace::RemoveBreakpoint!
52                // listBox.DeleteRow(null);
53             }
54          }
55          else if(listBox.currentField == ignoreField || listBox.currentField == levelField)
56          {
57             int value = 0;
58             char * string = (char *)row.GetData(listBox.currentField);
59             //char str[16];
60             if(string && string[0])
61             {
62                TrimLSpaces(string, string);
63                TrimRSpaces(string, string);
64                value = atoi(string);
65             }
66             else if(listBox.currentField == levelField)
67                value = -1;
68             //str[0] = '\0';
69             //sprintf(str, "%d", value);
70             //listBox.StopEditing(true);
71             //row.SetData(listBox.currentField, str);
72             if((listBox.currentField == ignoreField && value < 1) ||
73                   (listBox.currentField == levelField && value < 0))
74                row.SetData(listBox.currentField, null);
75             if(listBox.currentField == levelField && value == 0)
76                row.SetData(listBox.currentField, "0");
77             if(listBox.currentField == ignoreField)
78                ide.workspace.ChangeBreakpointIgnore(row, value);
79             else if(listBox.currentField == levelField)
80                ide.workspace.ChangeBreakpointLevel(row, value);
81          }
82          else if(listBox.currentField == conditionField)
83          {
84             char * condition = (char *)row.GetData(conditionField);
85             if(condition && condition[0])
86             {
87                TrimLSpaces(condition, condition);
88                TrimRSpaces(condition, condition);
89             }
90             ide.workspace.ChangeBreakpointCondition(row, (condition && condition[0]) ? condition : null);
91          }
92          return true;
93       }
94
95       bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
96       {
97          if((SmartKey)key == enter)
98             GoToBpLocation(listBox.currentRow);
99          return true;
100       }
101
102       bool NotifyKeyHit(ListBox listBox, DataRow row, Key key, unichar ch)
103       {
104          if(row && (SmartKey)key == del)
105          {
106             listBox.StopEditing(true);
107             ide.workspace.RemoveBreakpoint((Breakpoint)(intptr)row.tag);
108          }
109          return true;
110       }
111
112       bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods)
113       {
114          GoToBpLocation(listBox.currentRow);
115          return true;
116       }
117    };
118
119    // TODO: set field size based on font and i18n header string
120    // TODO: save column widths to ide settings
121    DataField locationField    { "char *", true , width = 220, header = $"Location" };
122    DataField hitsField        { "int"   , false, width =  28, header = $"Hits" };
123    DataField breaksField      { "int"   , false, width =  46, header = $"Breaks" };
124    DataField ignoreField      { "char *", true , width =  80, header = $"Ignore Count" };
125    DataField levelField       { "char *", true , width =  74, header = $"Stack Depth" };
126    DataField conditionField   { "char *", true , width = 130, header = $"Condition" };
127
128    BreakpointsView()
129    {
130       listBox.AddField(locationField);
131       listBox.AddField(hitsField);
132       listBox.AddField(breaksField);
133       listBox.AddField(ignoreField);
134       listBox.AddField(levelField);
135       listBox.AddField(conditionField);
136    }
137
138    bool OnKeyDown(Key key, unichar ch)
139    {
140       switch(key)
141       {
142          case escape: ide.ShowCodeEditor(); break;
143       }
144       return true;
145    }
146
147    bool OnClose(bool parentClosing)
148    {
149       visible = false;
150       if(!parentClosing)
151          ide.RepositionWindows(false);
152       return parentClosing;
153    }
154
155    void OnRedraw(Surface surface)
156    {
157       bool error;
158       int lineActive, lineUser;
159       int lineH;
160       //int scrollY = listBox.scroll.y;
161       //int boxH = clientSize.h;
162
163       displaySystem.FontExtent(listBox.font.font, " ", 1, null, &lineH);
164       //Window::OnRedraw(surface);
165       ide.debugger.GetCallStackCursorLine(&error, &lineActive, &lineUser);
166       // todo DrawLineMarginIcon(surface, error ? ide.bmpErrorActiveCursor : ide.bmpActiveCursor, lineActive, lineH, scrollY, boxH);
167    }
168
169    void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
170    {
171       int lineY;
172       if(line)
173       {
174          lineY = (line - 1) * lineH;
175          if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
176          {
177             Bitmap bitmap = resource.bitmap;
178             if(bitmap)
179                surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
180          }
181       }
182    }
183
184    void Show()
185    {
186       visible = true;
187       ide.RepositionWindows(false);
188       Activate();
189    }
190
191    void LoadFromWorkspace()
192    {
193       for(bp : ide.workspace.breakpoints; bp.type == user)
194          AddBreakpoint(bp);
195    }
196
197    void AddBreakpoint(Breakpoint bp)
198    {
199       DataRow row = listBox.AddRow();
200       row.tag = (int64)(intptr)bp;
201       bp.row = row;
202       UpdateBreakpoint(row);
203       ide.callStackView.Update(null);
204    }
205
206    void RemoveBreakpoint(Breakpoint bp)
207    {
208       listBox.DeleteRow(bp.row);
209       bp.row = null;
210       ide.callStackView.Update(null);
211       Update(null);
212    }
213
214    void UpdateBreakpoint(DataRow row)
215    {
216       if(row && row.tag)
217       {
218          char string[32];
219          char * location;
220          Breakpoint bp = (Breakpoint)(intptr)row.tag;
221          location = bp.CopyUserLocationString();
222 #if defined(__WIN32__)
223          ChangeCh(location, '/', '\\');
224 #endif
225          row.SetData(locationField, location);
226          delete location;
227          if(bp.ignore == 0)
228             string[0] = '\0';
229          else
230             sprintf(string, "%d", bp.ignore);
231          row.SetData(ignoreField, string);
232          if(bp.level == -1)
233             string[0] = '\0';
234          else
235             sprintf(string, "%d", bp.level);
236          row.SetData(levelField, string);
237          if(bp.condition)
238             row.SetData(conditionField, bp.condition.expression);
239          else
240             row.SetData(conditionField, null);
241          row.SetData(hitsField, bp.hits);
242          row.SetData(breaksField, bp.breaks);
243       }
244    }
245
246    void Clear()
247    {
248       listBox.Clear();
249    }
250
251 private:
252    void GoToBpLocation(DataRow row)
253    {
254       if(row)
255       {
256          char * location = (char *)row.GetData(locationField);
257          if(location)
258             ide.debugger.GoToCodeLine(location);
259       }
260    }
261
262 }
263