EditorBar.cpp

MouseMove instead of MouseLeave... - Zbigniew Rebacz, 04/25/2014 09:37 PM

Download (11.6 KB)

 
1
#include "CodeEditor.h"
2

    
3
NAMESPACE_UPP
4

    
5
void Renumber(LineInfo& lf)
6
{
7
        LineInfo tf;
8
        int l = 0;
9
        if(lf.GetCount()) {
10
                LineInfoRecord& t = tf.Add();
11
                t.breakpoint = lf[0].breakpoint;
12
                t.lineno = 0;
13
                t.count = lf[0].count;
14
                t.error = lf[0].error;
15
                t.firstedited = lf[0].firstedited;
16
                t.edited = lf[0].edited;
17
                l += t.count;
18
        }
19
        for(int i = 1; i < lf.GetCount(); i++) {
20
                LineInfoRecord& r = lf[i];
21
                if(r.breakpoint.IsEmpty() && r.error == 0 && r.edited == 0 &&
22
                        tf.Top().breakpoint.IsEmpty() && tf.Top().error == 0 && tf.Top().edited == 0)
23
                        tf.Top().count += r.count;
24
                else {
25
                        LineInfoRecord& t = tf.Add();
26
                        t.breakpoint = r.breakpoint;
27
                        t.error = r.error;
28
                        t.firstedited = r.firstedited;
29
                        t.edited = r.edited;
30
                        t.count = r.count;
31
                        t.lineno = l;
32
                }
33
                l += r.count;
34
        }
35
        lf = pick(tf);
36
}
37

    
38
void ClearBreakpoints(LineInfo& lf)
39
{
40
        for(int i = 0; i < lf.GetCount(); i++)
41
                lf[i].breakpoint.Clear();
42
}
43

    
44
void ValidateBreakpoints(LineInfo& lf)
45
{
46
        for(int i = 0; i < lf.GetCount(); i++)
47
                if(lf[i].breakpoint[0] == 0xe)
48
                        lf[i].breakpoint = "1";
49
}
50

    
51
void EditorBar::sPaintImage(Draw& w, int y, int fy, const Image& img)
52
{
53
        w.DrawImage(0, y + (fy - img.GetSize().cy) / 2, img);
54
}
55

    
56
void EditorBar::Paint(Draw& w)
57
{
58
        static Image (*numeri[])() = {
59
                CodeEditorImg::N0, CodeEditorImg::N1, CodeEditorImg::N2, CodeEditorImg::N3, CodeEditorImg::N4,
60
                CodeEditorImg::N5, CodeEditorImg::N6, CodeEditorImg::N7, CodeEditorImg::N8, CodeEditorImg::N9,
61
        };
62
        Size sz = GetSize();
63
        w.DrawRect(0, 0, sz.cx, sz.cy, SColorLtFace);
64
        if(!editor) return;
65
        int fy = editor->GetFontSize().cy;
66
        int hy = fy >> 1;
67
        int y = 0;
68
        int i = editor->GetScrollPos().y;
69
        int cy = GetSize().cy;
70
        bool hi_if = (hilite_if_endif && (editor->highlight == CodeEditor::HIGHLIGHT_CPP
71
                || editor->highlight == CodeEditor::HIGHLIGHT_CS
72
                || editor->highlight == CodeEditor::HIGHLIGHT_JAVA));
73
        Vector<CodeEditor::IfState> previf;
74
        if(hi_if)
75
                previf <<= editor->ScanSyntax(i).ifstack;
76
        int ptri[2];
77
        for(int q = 0; q < 2; q++)
78
                ptri[q] = ptrline[q] >= 0 ? GetLineNo(ptrline[q]) : -1;
79
        while(y < cy) {
80
                String b;
81
                int err = 0;
82
                int edit = 0;
83
                String ann;
84
                Image  icon;
85
                if(i < li.GetCount()) {
86
                        const LnInfo& l = li[i];
87
                        b = l.breakpoint;
88
                        err = l.error;
89
                        edit = l.edited;
90
                        icon = l.icon;
91
                        ann = l.annotation;
92
                }
93
                if(editor->GetCaret().top == y && editor->barline)
94
                        w.DrawRect(0, y, sz.cx, fy, Blend(SColorHighlight(), SColorLtFace(), 200));
95
                if(line_numbers && i < editor->GetLineCount()) {
96
                        String n = AsString(i + 1);
97
                        for(int q = 0; q < 4 && q < n.GetLength(); q++) {
98
                                w.DrawImage(sz.cx - 8 - q * 6,
99
                                        y + (fy - CodeEditorImg::N0().GetSize().cy) / 2,
100
                                        numeri[n[n.GetLength() - 1 - q] - '0'],
101
                                        // CodeEditorImg::Vector[n[n.GetLength() - 1 - q] - '0' + CodeEditorImg::I_N0],
102
                                        Brown);
103
                        }
104
                }
105
                if(hi_if) {
106
                        Vector<CodeEditor::IfState> nextif;
107
                        if(i < li.GetCount())
108
                                nextif <<= editor->ScanSyntax(i + 1).ifstack;
109
                        int pifl = previf.GetCount(), nifl = nextif.GetCount();
110
                        int dif = max(pifl, nifl);
111
                        if(--dif >= 0) {
112
                                char p = (dif < pifl ? previf[dif].state : 0);
113
                                char n = (dif < nifl ? nextif[dif].state : 0);
114
                                int wd = min(2 * (dif + 1), sz.cx);
115
                                int x = sz.cx - wd;
116
                                Color cn = CodeEditor::SyntaxState::IfColor(n);
117
                                if(p == n)
118
                                        w.DrawRect(x, y, 1, fy, cn);
119
                                else {
120
                                        Color cp = CodeEditor::SyntaxState::IfColor(p);
121
                                        w.DrawRect(x, y, 1, hy, cp);
122
                                        w.DrawRect(x, y + hy, wd, 1, Nvl(cn, cp));
123
                                        w.DrawRect(x, y + hy, 1, fy - hy, cn);
124
                                        if(--dif >= 0) {
125
                                                x = sz.cx - min(2 * (dif + 1), sz.cx);
126
                                                if(!p)
127
                                                        w.DrawRect(x, y, 1, hy, CodeEditor::SyntaxState::IfColor(dif < pifl ? previf[dif].state : 0));
128
                                                if(!n)
129
                                                        w.DrawRect(x, y + hy, 1, fy - hy, CodeEditor::SyntaxState::IfColor(dif < nifl ? nextif[dif].state : 0));
130
                                        }
131
                                }
132
                        }
133
                        previf = pick(nextif);
134
                }
135
                if(editor->GetMarkLines()) {
136
                        int width = CodeEditorImg::Breakpoint().GetWidth() >> 1;
137
                        if(edit)
138
                        {
139
                                int age = (int)(log((double)(editor->GetUndoCount() + 1 - edit)) * 30);
140
                                w.DrawRect(0, y, width, fy, Blend(LtBlue, SColorLtFace(), min(220, age)));
141
                        }
142
                        if(err)
143
                                w.DrawRect(width, y, width, fy, err == 1 ? LtRed : (err == 2 ? Color(255, 175, 0) : Green));
144
                }
145

    
146
                if(!b.IsEmpty())
147
                        sPaintImage(w, y, fy, b == "1"   ? CodeEditorImg::Breakpoint() :
148
                                              b == "\xe" ? CodeEditorImg::InvalidBreakpoint() :
149
                                                           CodeEditorImg::CondBreakpoint());
150
                for(int q = 0; q < 2; q++)
151
                        if(ptri[q] == i)
152
                                sPaintImage(w, y, fy, ptrimg[q]);
153

    
154
                if(annotations && !IsNull(icon))
155
                        w.DrawImage(sz.cx - annotations, y + (fy - icon.GetSize().cy) / 2, icon);
156

    
157
                y += fy;
158
                i++;
159
        }
160
}
161

    
162
void EditorBar::MouseMove(Point p, dword flags)
163
{
164
        int pa = active_annotation;
165
        if(p.x > GetSize().cx - annotations)
166
                active_annotation = p.y / editor->GetFont().Info().GetHeight() + editor->GetScrollPos().y;
167
        else
168
                active_annotation = -1;
169
        if(active_annotation >= editor->GetLineCount())
170
                active_annotation = -1;
171
        if(pa != active_annotation)
172
                WhenAnnotationMove();
173
        if(editor)
174
                editor->MouseMove(Point(0, p.y), flags);
175
}
176

    
177
void EditorBar::MouseLeave()
178
{
179
        int pa = active_annotation;
180
        active_annotation = -1;
181
        if(pa != active_annotation)
182
                WhenAnnotationMove();
183
}
184

    
185
void EditorBar::LeftDown(Point p, dword flags)
186
{
187
        if(p.x > GetSize().cx - annotations)
188
                WhenAnnotationClick();
189
        else
190
        if(editor)
191
                editor->LeftDown(Point(0, p.y), flags);
192
}
193

    
194
String& EditorBar::PointBreak(int& y)
195
{
196
        y = minmax(y / editor->GetFont().Info().GetHeight()
197
                + editor->GetScrollPos().y, 0, editor->GetLineCount());
198
        return li.At(y).breakpoint;
199
}
200

    
201
void EditorBar::LeftDouble(Point p, dword flags)
202
{
203
        if(!editor || !bingenabled) return;
204
        String& b = PointBreak(p.y);
205
        if(b.IsEmpty())
206
                b = "1";
207
        else
208
                b.Clear();
209
        WhenBreakpoint(p.y);
210
        Refresh();
211
}
212

    
213
void EditorBar::RightDown(Point p, dword flags)
214
{
215
        if(p.x > GetSize().cx - annotations)
216
                WhenAnnotationRightClick();
217
}
218

    
219
void EditorBar::MouseWheel(Point p, int zdelta, dword keyflags)
220
{
221
        if(editor) {
222
                int i = editor->GetScrollPos().y;
223
                editor->MouseWheel(p, zdelta, keyflags);
224
                if(i != editor->GetScrollPos().y)
225
                        MouseMove(p, keyflags);
226
        }
227
}
228

    
229
void EditorBar::InsertLines(int i, int count)
230
{
231
        li.InsertN(minmax(i + 1, 0, li.GetCount()), max(count, 0));
232
        if(editor->GetCheckEdited()) {
233
                if(editor->IsUndoOp() && li_removed.GetCount() >= count) {
234
                        for(int t = 0; t < count; t++) {
235
                                li.At(i + t).firstedited = li_removed[li_removed.GetCount() - count + t].firstedited;
236
                                li[i + t].edited = li_removed[li_removed.GetCount() - count + t].edited;
237
                        }
238
                        li_removed.Drop(count);
239
                        SetEdited(i + count, 1);
240
                        ignored_next_edit = true;
241
                }
242
                else {
243
                        if (li[i].firstedited == 0) {
244
                                bool fe = li[i].firstedited;
245
                                li.At(i + count).firstedited = fe;
246
                        }
247
                        SetEdited(i + 1, count);
248
                }
249
        }
250
        Refresh();
251
}
252

    
253
void EditorBar::RemoveLines(int i, int count)
254
{
255
        if(editor->GetCheckEdited() && !editor->IsUndoOp()) {
256
                for(int t = i - 1; t < i + count - 1; t++) {
257
                        LineInfoRemRecord& rm = li_removed.Add();
258
                        rm.firstedited = li[t].firstedited;
259
                        rm.edited = li[t].edited;
260
                }
261
                if(li.At(i + count - 1).firstedited)
262
                        next_age = li[i + count - 1].firstedited;
263
                else
264
                        next_age = editor->GetUndoCount();
265
        }
266
        i = minmax(i, 0, li.GetCount());
267
        li.Remove(i, minmax(count, 0, li.GetCount() - i));
268
        Refresh();
269
}
270

    
271
void EditorBar::ClearLines()
272
{
273
        li.Clear();
274
        li.Shrink();
275
        li_removed.Clear();
276
        li_removed.Shrink();
277
        Refresh();
278
}
279

    
280
LineInfo EditorBar::GetLineInfo() const
281
{
282
        LineInfo lf;
283
        int l = -2;
284
        for(int i = 0; i < li.GetCount(); i++) {
285
                const LnInfo& ln = li[i];
286
                if(!ln.breakpoint.IsEmpty() || ln.error || ln.edited) {
287
                        LineInfoRecord& r = lf.Add();
288
                        r.lineno = ln.lineno;
289
                        r.count = 1;
290
                        r.breakpoint = ln.breakpoint;
291
                        r.error = ln.error;
292
                        r.firstedited = ln.firstedited;
293
                        r.edited = ln.edited;
294
                        l = -2;
295
                }
296
                else
297
                if(ln.lineno != l) {
298
                        LineInfoRecord& r = lf.Add();
299
                        r.lineno = l = ln.lineno;
300
                        r.count = 1;
301
                }
302
                else
303
                        lf.Top().count++;
304
                if(l >= 0) l++;
305
        }
306
        return lf;
307
}
308

    
309
void EditorBar::SetLineInfo(const LineInfo& lf, int total)
310
{
311
        li.Clear();
312
        if(lf.GetCount() == 0) {
313
                for(int i = 0; i < total; i++)
314
                        li.Add().lineno = i;
315
        }
316
        else {
317
                for(int i = 0; i < lf.GetCount() && (total < 0 || li.GetCount() < total); i++) {
318
                        const LineInfoRecord& r = lf[i];
319
                        int l = r.lineno;
320
                        for(int j = r.count; j-- && li.GetCount() < total;) {
321
                                LnInfo& ln = li.Add();
322
                                ln.lineno = l;
323
                                ln.breakpoint = r.breakpoint;
324
                                ln.error = r.error;
325
                                ln.firstedited = r.firstedited;
326
                                ln.edited = r.edited;
327
                                if(l >= 0) l++;
328
                        }
329
                }
330
                while(li.GetCount() < total)
331
                        li.Add().lineno = -1;
332
        }
333
}
334

    
335
void EditorBar::Renumber(int linecount)
336
{
337
        li.SetCount(linecount);
338
        for(int i = 0; i < linecount; i++)
339
                li[i].lineno = i;
340
}
341

    
342
void EditorBar::ClearBreakpoints()
343
{
344
        for(int i = 0; i < li.GetCount(); i++)
345
                li[i].breakpoint.Clear();
346
        Refresh();
347
}
348

    
349
void EditorBar::ValidateBreakpoints()
350
{
351
        for(int i = 0; i < li.GetCount(); i++)
352
                if(li[i].breakpoint[0] == 0xe)
353
                        li[i].breakpoint = "1";
354
        Refresh();
355
}
356

    
357
String EditorBar::GetBreakpoint(int ln)
358
{
359
        return ln < li.GetCount() ? li[ln].breakpoint : Null;
360
}
361

    
362
void EditorBar::SetAnnotation(int line, const Image& img, const String& ann)
363
{
364
        if(line >= 0 && line < li.GetCount()) {
365
                li[line].icon = img;
366
                li[line].annotation = ann;
367
        }
368
}
369

    
370
String EditorBar::GetAnnotation(int line) const
371
{
372
        return line >= 0 && line < li.GetCount() ? li[line].annotation : String();
373
}
374

    
375
void EditorBar::SetBreakpoint(int ln, const String& s)
376
{
377
        li.At(ln).breakpoint = s;
378
        WhenBreakpoint(ln);
379
}
380

    
381
void EditorBar::SetEdited(int ln, int count)
382
{
383
        if(ignored_next_edit) {
384
                ignored_next_edit = false;
385
                return;
386
        }
387
        int age = editor->GetUndoCount() + 1;
388
        bool undo = editor->IsUndoOp();
389
        for(int i = 0; i < count; i++) {
390
                if(undo) {
391
                        if (li.At(ln + i).firstedited >= age - 1) {
392
                                li[ln + i].firstedited = 0;
393
                                li[ln + i].edited = 0;
394
                        }
395
                }
396
                else {
397
                        if(next_age) {
398
                                li[ln + i].firstedited = next_age;
399
                                li[ln + i].edited = age;
400
                                next_age = 0;
401
                        }
402
                        else {
403
                                if(li.At(ln + i).firstedited == 0)
404
                                        li[ln + i].firstedited = age;
405
                                li[ln + i].edited = age;
406
                        }
407
                }
408
        }
409
        Refresh();
410
}
411

    
412
void EditorBar::ClearEdited()
413
{
414
        for(int i = 0; i < li.GetCount(); i++) {
415
                li.At(i).firstedited = 0;
416
                li[i].edited = 0;
417
        }
418
        li_removed.Clear();
419
        li_removed.Shrink();
420
        Refresh();
421
}
422

    
423
void EditorBar::SetError(int ln, int err)
424
{
425
        li.At(ln).error = err;
426
}
427

    
428
void EditorBar::ClearErrors(int line)
429
{
430
        int count;
431
        if(line < 0) {
432
                line = 0;
433
                count = li.GetCount();
434
        }
435
        else
436
        if(line >= li.GetCount())
437
                return;
438
        else
439
                count = line + 1;
440

    
441
        for(int i = line; i < count; i++)
442
                li[i].error = 0;
443
}
444

    
445
int  EditorBar::GetLineNo(int lineno) const {
446
        for(int i = 0; i < li.GetCount(); i++) {
447
                if(lineno <= li[i].lineno)
448
                        return i;
449
        }
450
        return lineno;
451
}
452

    
453
int  EditorBar::GetNoLine(int line) const {
454
        int n = 0;
455
        for(int i = 0; i < li.GetCount(); i++) {
456
                if(li[i].lineno >= 0)
457
                        n = li[i].lineno;
458
                if(i == line) return n;
459
        }
460
        return n;
461
}
462

    
463
void EditorBar::SetPtr(int line, const Image& img, int i)
464
{
465
        ASSERT(i >= 0 && i < 2);
466
        ptrline[i] = line;
467
        ptrimg[i] = img;
468
        Refresh();
469
}
470

    
471
void EditorBar::HidePtr()
472
{
473
        ptrline[0] = ptrline[1] = -1;
474
        Refresh();
475
}
476

    
477
void EditorBar::SyncWidth()
478
{
479
        Width((line_numbers ? 27 : 12) + annotations);
480
        Refresh();
481
}
482

    
483
void EditorBar::LineNumbers(bool b)
484
{
485
        line_numbers = b;
486
        SyncWidth();
487
}
488

    
489
void EditorBar::Annotations(int width)
490
{
491
        annotations = width;
492
        SyncWidth();
493
}
494

    
495
EditorBar::EditorBar()
496
{
497
        LineNumbers(false);
498
        editor = NULL;
499
        bingenabled = true;
500
        hilite_if_endif = true;
501
        line_numbers = false;
502
        annotations = 0;
503
        ignored_next_edit = false;
504
        next_age = 0;
505
        SyncWidth();
506
}
507

    
508
EditorBar::~EditorBar()
509
{
510
}
511

    
512
void ClearErrors(LineInfo& li)
513
{
514
        for(int i = 0; i < li.GetCount(); i++)
515
                li[i].error = 0;
516
}
517

    
518
void SetError(LineInfo& li, int line, int err)
519
{
520
        li.At(line).error = err;
521
}
522

    
523
END_UPP_NAMESPACE