ide/CodeEditor: Customizable color scheme support
[sdk] / ide / src / panels / WatchesView.ec
1 import "ide"
2
3 class WatchesView : Window
4 {
5    visible = false;
6    text = $"Watches";
7    borderStyle = sizable;
8    background = { 224, 224, 224 };
9    hasClose = true;
10    anchor = Anchor { left = 0, right = 0, bottom = 0 };
11    size.h = 240;
12
13    bool moved, logging;
14
15    ListBox listBox
16    {
17       parent = this, hasHeader = true, hasVertScroll = true, alwaysEdit = true, collapseControl = true, resizable = true;
18       anchor = Anchor { left = 0, right = 0, top = 0, bottom = 0 };
19       /*
20       background = colorScheme.viewsBackground;
21       foreground = colorScheme.viewsText;
22       selectionColor = colorScheme.selectionColor;
23       selectionText = colorScheme.selectionText;
24       */
25
26       bool NotifyChanged(ListBox listBox, DataRow row)
27       {
28          char * expression = row.GetData(expressionField);
29
30          if(expression && expression[0])
31          {
32             TrimLSpaces(expression, expression);
33             TrimRSpaces(expression, expression);
34          }
35
36          if(expression && expression[0])
37          {
38             row.SetData(valueField, null);
39             if(row == listBox.lastRow)
40             {
41                DataRow newRow = listBox.AddRow();
42                newRow.SetData(expressionField, null);
43                newRow.SetData(valueField, null);
44                listBox.currentRow = newRow;
45             }
46             ide.debugger.ChangeWatch(row, expression);
47          }
48          else
49          {
50             ide.debugger.ChangeWatch(row, expression);
51             if(row != listBox.lastRow)
52             {
53                //Type type = (Type)row.GetData(typeField);
54                //if(type) FreeType(type);
55                listBox.DeleteRow(row);
56             }
57             else
58                row.SetData(valueField, null);
59          }
60          return true;
61       }
62
63       bool NotifyKeyHit(ListBox listBox, DataRow row, Key key, unichar ch)
64       {
65          if((SmartKey)key == del)
66          {
67             listBox.StopEditing(true);
68             if(row && row != listBox.lastRow)
69             {
70                //Type type = (Type)row.GetData(typeField);
71                ide.debugger.ChangeWatch(row, null);
72                //if(type) FreeType(type);
73                listBox.DeleteRow(null);
74             }
75          }
76          return true;
77       }
78
79       bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
80       {
81          if(listBox.currentField != expressionField)
82             listBox.currentField = expressionField;
83          return true;
84       }
85    };
86    DataField expressionField { "char *", true, width = 130, header = $"Expression" };
87    DataField typeField { "Type", false, width = 180, header = $"Type" };
88    //DataField addressField { "char *", true, width = 80, header = $"Symbol Address" };
89    DataField valueField { class(WatchMultiLineString), true, width = 330, header = $"Value", freeData = false };
90
91    WatchesView()
92    {
93       listBox.AddField(expressionField);
94       listBox.AddField(typeField);
95       listBox.AddField(valueField);
96    }
97
98    bool OnKeyDown(Key key, unichar ch)
99    {
100       switch(key)
101       {
102          case escape: ide.ShowCodeEditor(); break;
103       }
104       return true;
105    }
106
107    bool OnClose(bool parentClosing)
108    {
109       visible = false;
110       if(!parentClosing)
111          ide.RepositionWindows(false);
112       return parentClosing;
113    }
114
115    void Show()
116    {
117       visible = true;
118       ide.RepositionWindows(false);
119       Activate();
120    }
121
122    void LoadFromWorkspace()
123    {
124       for(wh : ide.workspace.watches)
125          AddWatch(wh);
126    }
127
128    void AddWatch(Watch wh)
129    {
130       DataRow row = listBox.AddRowAfter(listBox.lastRow.previous);
131       row.tag = (int64)(intptr)wh;
132       wh.row = row;
133       UpdateWatch(wh);
134    }
135
136    void UpdateWatch(Watch wh)
137    {
138       if(wh)
139       {
140          DataRow row = wh.row;
141          if(row && row.tag)
142          {
143             row.SetData(expressionField, wh.expression);
144             row.SetData(typeField, wh.type);
145             //row.SetData(addressField, wh.address);
146             row.SetData(valueField, wh.value);
147          }
148       }
149    }
150
151    void Clear()
152    {
153       DataRow row;
154       listBox.Clear();
155       row = listBox.AddRow();
156       row.SetData(expressionField, null);
157       row.SetData(typeField, null);
158       row.SetData(valueField, null);
159       if(ide.workspace)
160       {
161          for(w : ide.workspace.watches)
162             w.row = null;
163       }
164    }
165 }
166
167 class WatchMultiLineString : String
168 {
169    Window OnEdit(DataBox dataBox, DataBox obsolete, int x, int y, int w, int h, void * userData)
170    {
171       if(this && strchr(this, '\n'))
172       {
173          // Don't show the editbox right away so that the text is highlighted by default
174          EditBox editBox
175          {
176             parent = dataBox, master = obsolete, visible = false,
177             borderStyle = contour,
178             //interim = true,
179             hasHorzScroll = true, hasVertScroll = true,
180             modifyVirtualArea = false,
181             anchor = { 0, 0, 0, 0 };
182             //position = { x + dataBox.absPosition.x, y + dataBox.absPosition.y };
183             //size = { w, h * 4 };
184             multiLine = true;
185
186             bool OnKeyDown(Key key, unichar ch)
187             {
188                /*if(key == escape)
189                {
190                   ((ListBox)master.master).currentField = ((ListBox)master.master).firstField;
191                   return false;
192                }*/
193                return EditBox::OnKeyDown(key, ch);
194             }
195
196             bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
197             {
198                if(active) SelectAll(); else Deselect();
199                return EditBox::OnActivate(active, previous, goOnWithActivation, direct);
200             }
201
202             void DataBox::NotifyUpdate(EditBox editBox)
203             {
204                Modified();
205
206             }
207          };
208          dataBox.size = { w, h * 4 + 2 };
209          if(dataBox.size.h + dataBox.position.y > dataBox.parent.clientSize.h)
210             dataBox.position.y = dataBox.parent.clientSize.h - dataBox.size.h;
211          if(dataBox.size.w + dataBox.position.x > dataBox.parent.clientSize.w)
212             dataBox.position.x = dataBox.parent.clientSize.w - dataBox.size.w;
213
214          editBox.contents = this;
215          editBox.visible = true;
216          editBox.Create();
217          if(!dataBox.active)
218          {
219             editBox.Deselect();
220             editBox.Home();
221          }
222          return editBox;
223       }
224       else
225          return String::OnEdit(dataBox, obsolete, x, y, w,h, userData);
226    }
227
228    bool OnSaveEdit(Window window, void * object)
229    {
230       bool changed = false;
231       EditBox editBox = (EditBox)window;
232       if(editBox.modifiedDocument)
233       {
234       /*
235          EditLine line;
236          int size = 0;
237          char * string;
238
239          delete this;
240
241          for(line = editBox.firstLine; line; line = line.next)
242             size += line.count+1;
243          this = string = new char[size+1];
244          size = 0;
245          for(line = editBox.firstLine; line; line = line.next)
246          {
247             memcpy(string + size, line.text, line.count);
248             size += line.count;
249             string[size] = '\n';
250             size++;
251          }
252          string[size] = '\0';
253 */
254          changed = true;
255       }
256       return changed;
257    }
258
259    void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
260    {
261       if(this)
262       {
263          char ch;
264          char * string = this;
265          char actualString[8196];
266          int c, len = 0;
267          for(c = 0; (ch = string[c]) && len < sizeof(actualString)-1; c++)
268          {
269             if(ch == '\t') { actualString[len++] = '\\'; actualString[len++] = 't'; }
270             else if(ch == '\r') { actualString[len++] = '\\'; actualString[len++] = 'r'; }
271             else if(ch == '\n') { actualString[len++] = '\\'; actualString[len++] = 'n'; }
272             else actualString[len++] = ch;
273          }
274          actualString[len] = 0;
275          ((void (*)(void *, void *, void *, int, int, int, void *, uint, uint))(void *)class(String)._vTbl[__ecereVMethodID_class_OnDisplay])(class(String), actualString, surface, x, y, width, null, alignment, displayFlags);
276       }
277    }
278 };