acbaff461494ed24121f6a632a8af4f0af1e0691
[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       int id = selection.id;
115       char * searchString = findDialog.searchString;
116       if(id != 2 && searchString[0])
117       {
118          editBox.Find(searchString, findDialog.wholeWord, findDialog.matchCase, 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       Activate();
181    }
182
183    void OnRedraw(Surface surface)
184    {
185       int lineH;
186       int scrollY = editBox.scroll.y;
187       int boxH = clientSize.h;
188       int lineNumber;
189       int activeThread, hitThread, signalThread;
190       
191       if(OnGetThreadsInfo(&activeThread, &hitThread, &signalThread))
192       {
193          EditLine line;
194          BitmapResource bmpRes;
195          displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
196          for(line = editBox.firstLine, lineNumber = 1; line; line = line.next, lineNumber++)
197          {
198             if(strlen(line.text))
199             {
200                int id = atoi(line.text);
201                bmpRes = (id == signalThread) ? bmpTopFrameError : bmpTopFrame;
202                if(id == activeThread)
203                {
204                   DrawLineMarginIcon(surface,
205                         (id == signalThread) ? bmpCursorError : bmpCursor,
206                         lineNumber, lineH, scrollY, boxH);
207                }
208                else if(id == signalThread)
209                   DrawLineMarginIcon(surface, bmpRes, lineNumber, lineH, scrollY, boxH);
210             }
211          }
212          if(editBox.horzScroll && editBox.horzScroll.visible)
213          {
214             surface.SetBackground(control);
215             surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
216          }
217       }
218    }
219
220    void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
221    {
222       int lineY;
223       if(line)
224       {
225          lineY = (line - 1) * lineH;
226          if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
227          {
228             Bitmap bitmap = resource.bitmap;
229             if(bitmap)
230                surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
231          }
232       }
233    }
234 }