0b02522e6898c2b8da28bf39723f0026905ea13b
[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       char * searchString = findDialog.searchString;
116       if(id != 2 && searchString[0])
117       {
118          editBox.Find(searchString, findDialog.wholeWord, findDialog.matchCase, (bool)id);
119          return true;
120       }
121       findDialog.Create();
122       return true;
123    }
124
125    void Logf(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    void LogSprintf(char * entry)
137    {
138       char string[MAX_F_STRING];
139       sprintf(string, entry);
140       Log(string);
141    }
142    void LogRaw(char * entry)
143    {
144       Log(entry);
145    }
146    void Log(char * string)
147    {
148       EditLine line1;
149       EditLine line2;
150       int x1, y1, x2, y2;
151       Point scroll;
152       logging = true;
153       if(moved)
154       {
155          editBox.GetSelPos(&line1, &y1, &x1, &line2, &y2, &x2, false);
156          scroll = editBox.scroll;
157       }
158       editBox.End();
159       editBox.PutS(string);
160       editBox.Update(null);
161       if(moved)
162       {
163          editBox.scroll = scroll;
164          editBox.SetSelPos(line1, y1, x1, line2, y2, x2);
165       }
166       logging = false;
167    }
168    void Clear()
169    {
170       editBox.Clear();
171       moved = false;
172    }
173    void Home()
174    {
175       editBox.Home();
176    }
177    void Show()
178    {
179       visible = true;
180       ide.RepositionWindows(false);
181       Activate();
182    }
183
184    void OnRedraw(Surface surface)
185    {
186       int lineH;
187       int scrollY = editBox.scroll.y;
188       int boxH = clientSize.h;
189       int lineNumber;
190       int activeThread, hitThread, signalThread;
191       
192       if(OnGetThreadsInfo(&activeThread, &hitThread, &signalThread))
193       {
194          EditLine line;
195          BitmapResource bmpRes;
196          displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
197          for(line = editBox.firstLine, lineNumber = 1; line; line = line.next, lineNumber++)
198          {
199             if(strlen(line.text))
200             {
201                int id = atoi(line.text);
202                bmpRes = (id == signalThread) ? bmpTopFrameError : bmpTopFrame;
203                if(id == activeThread)
204                {
205                   DrawLineMarginIcon(surface,
206                         (id == signalThread) ? bmpCursorError : bmpCursor,
207                         lineNumber, lineH, scrollY, boxH);
208                }
209                else if(id == signalThread)
210                   DrawLineMarginIcon(surface, bmpRes, lineNumber, lineH, scrollY, boxH);
211             }
212          }
213          if(editBox.horzScroll && editBox.horzScroll.visible)
214          {
215             surface.SetBackground(control);
216             surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
217          }
218       }
219    }
220
221    void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
222    {
223       int lineY;
224       if(line)
225       {
226          lineY = (line - 1) * lineH;
227          if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
228          {
229             Bitmap bitmap = resource.bitmap;
230             if(bitmap)
231                surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
232          }
233       }
234    }
235 }