summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-27 11:05:51 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-27 11:05:51 +0300
commiteae15cea6528eac0f3c0f78607781ee7960df31e (patch)
tree68126841b586c335c60e5d84b14237a21e10da94 /src
parentd7a3e153e83cba0a98233fde7e173de1408dfc77 (diff)
DocumentWidget: Drawing marked ranges
Diffstat (limited to 'src')
-rw-r--r--src/ui/documentwidget.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index d0fa60ab..091673b8 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -32,6 +32,7 @@ struct Impl_DocumentWidget {
32 iGmRequest *request; 32 iGmRequest *request;
33 iAtomicInt isSourcePending; /* request has new content, need to parse it */ 33 iAtomicInt isSourcePending; /* request has new content, need to parse it */
34 iGmDocument *doc; 34 iGmDocument *doc;
35 iRangecc selectMark;
35 iRangecc foundMark; 36 iRangecc foundMark;
36 int pageMargin; 37 int pageMargin;
37 int scrollY; 38 int scrollY;
@@ -53,6 +54,7 @@ void init_DocumentWidget(iDocumentWidget *d) {
53 d->request = NULL; 54 d->request = NULL;
54 d->isSourcePending = iFalse; 55 d->isSourcePending = iFalse;
55 d->doc = new_GmDocument(); 56 d->doc = new_GmDocument();
57 d->selectMark = iNullRange;
56 d->foundMark = iNullRange; 58 d->foundMark = iNullRange;
57 d->pageMargin = 5; 59 d->pageMargin = 5;
58 d->scrollY = 0; 60 d->scrollY = 0;
@@ -535,9 +537,32 @@ struct Impl_DrawContext {
535 const iDocumentWidget *widget; 537 const iDocumentWidget *widget;
536 iRect bounds; 538 iRect bounds;
537 iPaint paint; 539 iPaint paint;
538 int insideMark; 540 iBool inSelectMark;
541 iBool inFoundMark;
539}; 542};
540 543
544static void fillRange_DrawContext_(iDrawContext *d, const iGmRun *run, enum iColorId color,
545 iRangecc mark, iBool *isInside) {
546 if ((!*isInside && contains_Range(&run->text, mark.start)) || *isInside) {
547 int x = 0;
548 if (!*isInside) {
549 x = advanceRange_Text(run->font, (iRangecc){ run->text.start, mark.start }).x;
550 }
551 int w = width_Rect(run->bounds) - x;
552 if (contains_Range(&run->text, mark.end) || run->text.end == mark.end) {
553 w = advanceRange_Text(run->font,
554 !*isInside ? mark : (iRangecc){ run->text.start, mark.end }).x;
555 *isInside = iFalse;
556 }
557 else {
558 *isInside = iTrue; /* at least until the next run */
559 }
560 const iInt2 visPos = add_I2(run->bounds.pos, addY_I2(d->bounds.pos, -d->widget->scrollY));
561 fillRect_Paint(&d->paint, (iRect){ addX_I2(visPos, x),
562 init_I2(w, height_Rect(run->bounds)) }, color);
563 }
564}
565
541static void drawRun_DrawContext_(void *context, const iGmRun *run) { 566static void drawRun_DrawContext_(void *context, const iGmRun *run) {
542 iDrawContext *d = context; 567 iDrawContext *d = context;
543 iString text; 568 iString text;
@@ -556,9 +581,7 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
556 int descWidth = measure_Text(default_FontId, desc).x + gap_UI; 581 int descWidth = measure_Text(default_FontId, desc).x + gap_UI;
557 iRect linkRect = expanded_Rect(moved_Rect(run->bounds, origin), init_I2(gap_UI, 0)); 582 iRect linkRect = expanded_Rect(moved_Rect(run->bounds, origin), init_I2(gap_UI, 0));
558 linkRect.size.x += descWidth; 583 linkRect.size.x += descWidth;
559 fillRect_Paint(&d->paint, 584 fillRect_Paint(&d->paint, linkRect, teal_ColorId);
560 linkRect,
561 teal_ColorId);
562 drawAlign_Text(default_FontId, 585 drawAlign_Text(default_FontId,
563 addX_I2(topRight_Rect(linkRect), -gap_UI), 586 addX_I2(topRight_Rect(linkRect), -gap_UI),
564 cyan_ColorId, 587 cyan_ColorId,
@@ -567,31 +590,9 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) {
567 desc); 590 desc);
568 } 591 }
569 const iInt2 visPos = add_I2(run->bounds.pos, origin); 592 const iInt2 visPos = add_I2(run->bounds.pos, origin);
570 /* Found text marker. */ 593 /* Text markers. */
571 if ((!d->insideMark && contains_Range(&run->text, d->widget->foundMark.start)) || 594 fillRange_DrawContext_(d, run, teal_ColorId, d->widget->foundMark, &d->inFoundMark);
572 d->insideMark) { 595 fillRange_DrawContext_(d, run, brown_ColorId, d->widget->selectMark, &d->inSelectMark);
573 int x = 0;
574 if (!d->insideMark) {
575 x = advanceRange_Text(run->font, (iRangecc){ run->text.start,
576 d->widget->foundMark.start }).x;
577 }
578 int w = width_Rect(run->bounds) - x;
579 if (contains_Range(&run->text, d->widget->foundMark.end) ||
580 run->text.end == d->widget->foundMark.end) {
581 w = advanceRange_Text(run->font,
582 !d->insideMark
583 ? d->widget->foundMark
584 : (iRangecc){ run->text.start, d->widget->foundMark.end })
585 .x;
586 d->insideMark = iFalse;
587 }
588 else {
589 d->insideMark = iTrue; /* at least until the next run */
590 }
591 fillRect_Paint(&d->paint,
592 (iRect){ addX_I2(visPos, x), init_I2(w, height_Rect(run->bounds)) },
593 teal_ColorId);
594 }
595 drawString_Text(run->font, visPos, run->color, &text); 596 drawString_Text(run->font, visPos, run->color, &text);
596 deinit_String(&text); 597 deinit_String(&text);
597} 598}