92a058af3594dc73cb773e40ce209f072148604b
[sdk] / ide / src / panels / ThreadsView.ec
1 #include <stdarg.h>
2
3 import "ecere"
4 import "CodeEditor"
5
6 class ThreadsView : Window
7 {
8    visible = false;
9    borderStyle = sizableDeep;
10    background = { 224, 224, 224 };
11    hasClose = true;
12    hasClose = true;
13    mergeMenus = false;
14    text = "Threads";
15    menu = Menu { };
16    anchor = Anchor { left = 0.8, right = 0, top = 0 };
17    size.h = 200;
18
19    bool moved, logging;
20    FindDialog findDialog { master = this, editBox = editBox, isModal = true, autoCreate = false, text = "Find" };
21
22    BitmapResource bmpCursor            { ":codeMarks/cursor.png", window = this };
23    BitmapResource bmpCursorError       { ":codeMarks/cursorError.png", window = this };
24    BitmapResource bmpTopFrame          { ":codeMarks/topFrame.png", window = this };
25    BitmapResource bmpTopFrameError     { ":codeMarks/topFrameError.png", window = this };
26
27    virtual void OnSelectThread(int threadId);
28    virtual bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread);
29
30    int GetThreadId()
31    {
32       return atoi(editBox.line.text);
33    }
34
35    int FindThreadId(int threadId)
36    {
37       int lineNumber;
38       EditLine line;
39       for(line = editBox.firstLine, lineNumber = 1; line; line = line.next, lineNumber++)
40       {
41          int id = atoi(line.text);
42          if(id && id == threadId)
43             return lineNumber;
44       }
45       return 0;
46    }
47
48    EditBox editBox
49    {
50       parent = this, freeCaret = true, autoEmpty = true, multiLine = true, readOnly = true;
51       hasVertScroll = true, hasHorzScroll = true, borderStyle = none;
52       anchor = { left = 20, right = 0, top = 0, bottom = 0 };
53       background = viewsBackground;
54       foreground = viewsText;
55       selectionColor = selectionColor, selectionText = selectionText;
56
57       bool NotifyDoubleClick(EditBox editBox, EditLine line, Modifiers mods)
58       {
59          int id = GetThreadId();
60          OnSelectThread(id);
61          return true;
62       }
63
64       bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
65       {
66          if((SmartKey)key == enter)
67          {
68             int id = GetThreadId();
69             OnSelectThread(id);
70             return false;
71          }
72          return true;
73       }
74
75       void NotifyCaretMove(EditBox editBox, int line, int charPos)
76       {
77          if(!logging)
78          {
79             int y1, y2;
80             editBox.GetSelPos(null, &y1, null, null, &y2, null, false);
81             moved = (y1 == editBox.numLines - 1 && y2 == y1) ? false : true;
82          }
83       }
84
85       void OnVScroll(ScrollBarAction action, int position, Key key)
86       {
87          int boxH = clientSize.h;
88          Box box = { 0,0, 19, boxH - 1 };
89          parent.Update(box);
90          EditBox::OnVScroll(action, position, key);
91       }
92
93    };
94
95    Menu editMenu { menu, $"Edit", e };
96    MenuItem item;
97
98    MenuItem copyItem
99    {
100       editMenu, $"Copy", c, ctrlC;
101       bool NotifySelect(MenuItem selection, Modifiers mods)
102       {
103          editBox.Copy();
104          return true;
105       }
106    };
107    MenuDivider { editMenu };
108    MenuItem { editMenu, $"Find Previous", e, Key { f3, shift = true }, NotifySelect = MenuEditFind, id = 0 };
109    MenuItem { editMenu, $"Find Next", n, f3, NotifySelect = MenuEditFind, id = 1 };
110    MenuItem { editMenu, $"Find", f, ctrlF, NotifySelect = MenuEditFind, id = 2 };
111
112    bool MenuEditFind(MenuItem selection, Modifiers mods)
113    {
114       int64 id = selection.id;
115       const char * searchString = findDialog.searchString;
116       if(id != 2 && searchString[0])
117       {
118          editBox.Find(searchString, findDialog.wholeWord, findDialog.matchCase, id != 0);
119          return true;
120       }
121       findDialog.Create();
122       return true;
123    }
124
125    void Logf(const char * format, ...)
126    {
127       char string[MAX_F_STRING*10];
128       va_list args;
129       va_start(args, format);
130       vsnprintf(string, sizeof(string), format, args);
131       string[sizeof(string)-1] = 0;
132       va_end(args);
133
134       Log(string);
135    }
136
137    void LogRaw(const char * entry)
138    {
139       Log(entry);
140    }
141    void Log(const char * string)
142    {
143       EditLine line1;
144       EditLine line2;
145       int x1, y1, x2, y2;
146       Point scroll;
147       logging = true;
148       if(moved)
149       {
150          editBox.GetSelPos(&line1, &y1, &x1, &line2, &y2, &x2, false);
151          scroll = editBox.scroll;
152       }
153       editBox.End();
154       editBox.PutS(string);
155       editBox.Update(null);
156       if(moved)
157       {
158          editBox.scroll = scroll;
159          editBox.SetSelPos(line1, y1, x1, line2, y2, x2);
160       }
161       logging = false;
162    }
163    void Clear()
164    {
165       editBox.Clear();
166       moved = false;
167    }
168    void Home()
169    {
170       editBox.Home();
171    }
172    void Show()
173    {
174       visible = true;
175       ide.RepositionWindows(false);
176       Activate();
177    }
178
179    void OnRedraw(Surface surface)
180    {
181       int lineH;
182       int scrollY = editBox.scroll.y;
183       int boxH = clientSize.h;
184       int lineNumber;
185       int activeThread, hitThread, signalThread;
186
187       if(OnGetThreadsInfo(&activeThread, &hitThread, &signalThread))
188       {
189          EditLine line;
190          BitmapResource bmpRes;
191          displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
192          for(line = editBox.firstLine, lineNumber = 1; line; line = line.next, lineNumber++)
193          {
194             if(strlen(line.text))
195             {
196                int id = atoi(line.text);
197                bmpRes = (id == signalThread) ? bmpTopFrameError : bmpTopFrame;
198                if(id == activeThread)
199                {
200                   DrawLineMarginIcon(surface,
201                         (id == signalThread) ? bmpCursorError : bmpCursor,
202                         lineNumber, lineH, scrollY, boxH);
203                }
204                else if(id == signalThread)
205                   DrawLineMarginIcon(surface, bmpRes, lineNumber, lineH, scrollY, boxH);
206             }
207          }
208          if(editBox.horzScroll && editBox.horzScroll.visible)
209          {
210             surface.SetBackground(control);
211             surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
212          }
213       }
214    }
215
216    void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
217    {
218       int lineY;
219       if(line)
220       {
221          lineY = (line - 1) * lineH;
222          if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
223          {
224             Bitmap bitmap = resource.bitmap;
225             if(bitmap)
226                surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
227          }
228       }
229    }
230 }