ide/CodeEditor: Customizable color scheme support
[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       /*
54       background = colorScheme.viewsBackground;
55       foreground = colorScheme.viewsText;
56       selectionColor = colorScheme.selectionColor;
57       selectionText = colorScheme.selectionText;
58       */
59
60       bool NotifyDoubleClick(EditBox editBox, EditLine line, Modifiers mods)
61       {
62          int id = GetThreadId();
63          OnSelectThread(id);
64          return true;
65       }
66
67       bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
68       {
69          if((SmartKey)key == enter)
70          {
71             int id = GetThreadId();
72             OnSelectThread(id);
73             return false;
74          }
75          return true;
76       }
77
78       void NotifyCaretMove(EditBox editBox, int line, int charPos)
79       {
80          if(!logging)
81          {
82             int y1, y2;
83             editBox.GetSelPos(null, &y1, null, null, &y2, null, false);
84             moved = (y1 == editBox.numLines - 1 && y2 == y1) ? false : true;
85          }
86       }
87
88       void OnVScroll(ScrollBarAction action, int position, Key key)
89       {
90          int boxH = clientSize.h;
91          Box box = { 0,0, 19, boxH - 1 };
92          parent.Update(box);
93          EditBox::OnVScroll(action, position, key);
94       }
95
96    };
97
98    Menu editMenu { menu, $"Edit", e };
99    MenuItem item;
100
101    MenuItem copyItem
102    {
103       editMenu, $"Copy", c, ctrlC;
104       bool NotifySelect(MenuItem selection, Modifiers mods)
105       {
106          editBox.Copy();
107          return true;
108       }
109    };
110    MenuDivider { editMenu };
111    MenuItem { editMenu, $"Find Previous", e, Key { f3, shift = true }, NotifySelect = MenuEditFind, id = 0 };
112    MenuItem { editMenu, $"Find Next", n, f3, NotifySelect = MenuEditFind, id = 1 };
113    MenuItem { editMenu, $"Find", f, ctrlF, NotifySelect = MenuEditFind, id = 2 };
114
115    bool MenuEditFind(MenuItem selection, Modifiers mods)
116    {
117       int64 id = selection.id;
118       const char * searchString = findDialog.searchString;
119       if(id != 2 && searchString[0])
120       {
121          editBox.Find(searchString, findDialog.wholeWord, findDialog.matchCase, id != 0);
122          return true;
123       }
124       findDialog.Create();
125       return true;
126    }
127
128    void Logf(const char * format, ...)
129    {
130       char string[MAX_F_STRING*10];
131       va_list args;
132       va_start(args, format);
133       vsnprintf(string, sizeof(string), format, args);
134       string[sizeof(string)-1] = 0;
135       va_end(args);
136
137       Log(string);
138    }
139
140    void LogRaw(const char * entry)
141    {
142       Log(entry);
143    }
144    void Log(const char * string)
145    {
146       EditLine line1;
147       EditLine line2;
148       int x1, y1, x2, y2;
149       Point scroll;
150       logging = true;
151       if(moved)
152       {
153          editBox.GetSelPos(&line1, &y1, &x1, &line2, &y2, &x2, false);
154          scroll = editBox.scroll;
155       }
156       editBox.End();
157       editBox.PutS(string);
158       editBox.Update(null);
159       if(moved)
160       {
161          editBox.scroll = scroll;
162          editBox.SetSelPos(line1, y1, x1, line2, y2, x2);
163       }
164       logging = false;
165    }
166    void Clear()
167    {
168       editBox.Clear();
169       moved = false;
170    }
171    void Home()
172    {
173       editBox.Home();
174    }
175    void Show()
176    {
177       visible = true;
178       ide.RepositionWindows(false);
179       Activate();
180    }
181
182    void OnRedraw(Surface surface)
183    {
184       int lineH;
185       int scrollY = editBox.scroll.y;
186       int boxH = clientSize.h;
187       int lineNumber;
188       int activeThread, hitThread, signalThread;
189
190       if(OnGetThreadsInfo(&activeThread, &hitThread, &signalThread))
191       {
192          EditLine line;
193          BitmapResource bmpRes;
194          displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
195          for(line = editBox.firstLine, lineNumber = 1; line; line = line.next, lineNumber++)
196          {
197             if(strlen(line.text))
198             {
199                int id = atoi(line.text);
200                bmpRes = (id == signalThread) ? bmpTopFrameError : bmpTopFrame;
201                if(id == activeThread)
202                {
203                   DrawLineMarginIcon(surface,
204                         (id == signalThread) ? bmpCursorError : bmpCursor,
205                         lineNumber, lineH, scrollY, boxH);
206                }
207                else if(id == signalThread)
208                   DrawLineMarginIcon(surface, bmpRes, lineNumber, lineH, scrollY, boxH);
209             }
210          }
211          if(editBox.horzScroll && editBox.horzScroll.visible)
212          {
213             surface.SetBackground(control);
214             surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
215          }
216       }
217    }
218
219    void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
220    {
221       int lineY;
222       if(line)
223       {
224          lineY = (line - 1) * lineH;
225          if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
226          {
227             Bitmap bitmap = resource.bitmap;
228             if(bitmap)
229                surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
230          }
231       }
232    }
233 }