diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-12 23:15:15 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-09-12 23:15:15 +0300 |
commit | 6480b31451f919bd4f4c08c124fd47621c39dd8e (patch) | |
tree | bc95761e380516628bbd046fe712870ba22bcffe /src | |
parent | 8824963c806ce80ed919feeb8cae41dbf3116e50 (diff) |
DocumentWidget: Drawing marked ranges
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/documentwidget.c | 155 |
1 files changed, 46 insertions, 109 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index edfab0be..2dd50e5b 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -1632,9 +1632,17 @@ static void fillRange_DrawContext_(iDrawContext *d, const iGmRun *run, enum iCol | |||
1632 | } | 1632 | } |
1633 | } | 1633 | } |
1634 | 1634 | ||
1635 | static void drawMark_DrawContext_(void *context, const iGmRun *run) { | ||
1636 | iDrawContext *d = context; | ||
1637 | if (!run->imageId) { | ||
1638 | fillRange_DrawContext_(d, run, uiMatching_ColorId, d->widget->foundMark, &d->inFoundMark); | ||
1639 | fillRange_DrawContext_(d, run, uiMarked_ColorId, d->widget->selectMark, &d->inSelectMark); | ||
1640 | } | ||
1641 | } | ||
1642 | |||
1635 | static void drawRun_DrawContext_(void *context, const iGmRun *run) { | 1643 | static void drawRun_DrawContext_(void *context, const iGmRun *run) { |
1636 | iDrawContext *d = context; | 1644 | iDrawContext *d = context; |
1637 | const iInt2 origin = d->viewPos; //addY_I2(d->bounds.pos, -d->widget->scrollY); | 1645 | const iInt2 origin = d->viewPos; |
1638 | if (run->imageId) { | 1646 | if (run->imageId) { |
1639 | /*if (d->pass == static_DrawRunPass)*/ { | 1647 | /*if (d->pass == static_DrawRunPass)*/ { |
1640 | SDL_Texture *tex = imageTexture_GmDocument(d->widget->doc, run->imageId); | 1648 | SDL_Texture *tex = imageTexture_GmDocument(d->widget->doc, run->imageId); |
@@ -1646,17 +1654,6 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
1646 | } | 1654 | } |
1647 | return; | 1655 | return; |
1648 | } | 1656 | } |
1649 | #if 0 | ||
1650 | /* Text markers. */ | ||
1651 | /*if (d->pass == dynamic_DrawRunPass)*/ { | ||
1652 | SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), | ||
1653 | isDark_ColorTheme(colorTheme_App()) ? SDL_BLENDMODE_ADD | ||
1654 | : SDL_BLENDMODE_BLEND); | ||
1655 | fillRange_DrawContext_(d, run, uiMatching_ColorId, d->widget->foundMark, &d->inFoundMark); | ||
1656 | fillRange_DrawContext_(d, run, uiMarked_ColorId, d->widget->selectMark, &d->inSelectMark); | ||
1657 | SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_NONE); | ||
1658 | } | ||
1659 | #endif | ||
1660 | enum iColorId fg = run->color; | 1657 | enum iColorId fg = run->color; |
1661 | const iGmDocument *doc = d->widget->doc; | 1658 | const iGmDocument *doc = d->widget->doc; |
1662 | /* Matches the current drawing pass? */ | 1659 | /* Matches the current drawing pass? */ |
@@ -1671,9 +1668,9 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
1671 | fillRect_Paint(&d->paint, | 1668 | fillRect_Paint(&d->paint, |
1672 | (iRect){ visPos, | 1669 | (iRect){ visPos, |
1673 | /* Links have additional hover info on the right side. */ | 1670 | /* Links have additional hover info on the right side. */ |
1674 | init_I2(run->linkId && ~run->flags & decoration_GmRunFlag | 1671 | // init_I2(run->linkId && ~run->flags & decoration_GmRunFlag |
1675 | ? d->widgetBounds.size.x - visPos.x | 1672 | // ? d->widgetBounds.size.x - visPos.x : |
1676 | : run->visBounds.size.x, | 1673 | init_I2(run->visBounds.size.x, |
1677 | run->visBounds.size.y) }, | 1674 | run->visBounds.size.y) }, |
1678 | tmBackground_ColorId); | 1675 | tmBackground_ColorId); |
1679 | if (run->linkId && ~run->flags & decoration_GmRunFlag) { | 1676 | if (run->linkId && ~run->flags & decoration_GmRunFlag) { |
@@ -1848,27 +1845,16 @@ static void drawRun_DrawContext_(void *context, const iGmRun *run) { | |||
1848 | static void draw_DocumentWidget_(const iDocumentWidget *d) { | 1845 | static void draw_DocumentWidget_(const iDocumentWidget *d) { |
1849 | const iWidget *w = constAs_Widget(d); | 1846 | const iWidget *w = constAs_Widget(d); |
1850 | const iRect bounds = bounds_Widget(w); | 1847 | const iRect bounds = bounds_Widget(w); |
1851 | // const iInt2 origin = topLeft_Rect(bounds); | ||
1852 | //const iRangei visRange = visibleRange_DocumentWidget_(d); | ||
1853 | iVisBuf * visBuf = d->visBuf; /* will be updated now */ | 1848 | iVisBuf * visBuf = d->visBuf; /* will be updated now */ |
1854 | draw_Widget(w); | 1849 | draw_Widget(w); |
1855 | allocVisBuffer_DocumentWidget_(d); | 1850 | allocVisBuffer_DocumentWidget_(d); |
1856 | const iRect ctxWidgetBounds = init_Rect( | 1851 | const iRect ctxWidgetBounds = init_Rect( |
1857 | 0, 0, width_Rect(bounds) - constAs_Widget(d->scroll)->rect.size.x, height_Rect(bounds)); | 1852 | 0, 0, width_Rect(bounds) - constAs_Widget(d->scroll)->rect.size.x, height_Rect(bounds)); |
1858 | // adjusted_Rect(bounds, zero_I2(), init_I2(-constAs_Widget(d->scroll)->rect.size.x, 0)), | 1853 | const iRect docBounds = documentBounds_DocumentWidget_(d); |
1859 | // neg_I2(origin)); /* omit scrollbar width */ | 1854 | iDrawContext ctx = { |
1860 | const iRect docBounds = documentBounds_DocumentWidget_(d); | 1855 | .widget = d, |
1861 | // const iRect ctxBounds = moved_Rect(documentBounds_DocumentWidget_(d), neg_I2(origin)); | ||
1862 | iDrawContext ctx = { | ||
1863 | // .pass = dynamic_DrawRunPass, | ||
1864 | .widget = d, | ||
1865 | .showLinkNumbers = d->showLinkNumbers, | 1856 | .showLinkNumbers = d->showLinkNumbers, |
1866 | }; | 1857 | }; |
1867 | // iDrawContext ctxStatic = ctxDynamic; | ||
1868 | // ctxStatic.pass = static_DrawRunPass; | ||
1869 | // subv_I2(&ctx.widgetBounds.pos, origin); | ||
1870 | // subv_I2(&ctx.bounds.pos, origin); | ||
1871 | // SDL_Renderer *render = get_Window()->render; | ||
1872 | /* Currently visible region. */ | 1858 | /* Currently visible region. */ |
1873 | const iRangei vis = visibleRange_DocumentWidget_(d); | 1859 | const iRangei vis = visibleRange_DocumentWidget_(d); |
1874 | const iRangei full = { 0, size_GmDocument(d->doc).y }; | 1860 | const iRangei full = { 0, size_GmDocument(d->doc).y }; |
@@ -1878,101 +1864,47 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) { | |||
1878 | /* Redraw the invalid ranges. */ { | 1864 | /* Redraw the invalid ranges. */ { |
1879 | iPaint *p = &ctx.paint; | 1865 | iPaint *p = &ctx.paint; |
1880 | init_Paint(p); | 1866 | init_Paint(p); |
1881 | // const int vbSrc = visBuf->index; | ||
1882 | // const int vbDst = visBuf->index ^ 1; | ||
1883 | // iRangei drawRange = visRange; | ||
1884 | iForIndices(i, visBuf->buffers) { | 1867 | iForIndices(i, visBuf->buffers) { |
1885 | iBool isTargetSet = iFalse; | ||
1886 | iVisBufTexture *buf = &visBuf->buffers[i]; | 1868 | iVisBufTexture *buf = &visBuf->buffers[i]; |
1887 | ctx.widgetBounds = moved_Rect(ctxWidgetBounds, init_I2(0, -buf->origin)); | 1869 | ctx.widgetBounds = moved_Rect(ctxWidgetBounds, init_I2(0, -buf->origin)); |
1888 | ctx.viewPos = init_I2(left_Rect(docBounds) - left_Rect(bounds), -buf->origin); | 1870 | ctx.viewPos = init_I2(left_Rect(docBounds) - left_Rect(bounds), -buf->origin); |
1889 | if (!isEmpty_Rangei(invalidRange[i])) { | 1871 | if (!isEmpty_Rangei(invalidRange[i])) { |
1890 | if (!isTargetSet) { | 1872 | beginTarget_Paint(p, buf->texture); |
1891 | beginTarget_Paint(p, buf->texture); | ||
1892 | isTargetSet = iTrue; | ||
1893 | } | ||
1894 | if (isEmpty_Rangei(buf->validRange)) { | 1873 | if (isEmpty_Rangei(buf->validRange)) { |
1895 | fillRect_Paint(p, (iRect){ zero_I2(), visBuf->texSize }, tmBackground_ColorId); | 1874 | fillRect_Paint(p, (iRect){ zero_I2(), visBuf->texSize }, tmBackground_ColorId); |
1896 | } | 1875 | } |
1897 | render_GmDocument(d->doc, invalidRange[i], drawRun_DrawContext_, &ctx); | 1876 | render_GmDocument(d->doc, invalidRange[i], drawRun_DrawContext_, &ctx); |
1898 | } | 1877 | } |
1899 | /* Draw any invalidated runs that fall within this buffer. */ | 1878 | /* Draw any invalidated runs that fall within this buffer. */ { |
1900 | const iRangei bufRange = { buf->origin, buf->origin + visBuf->texSize.y }; | 1879 | const iRangei bufRange = { buf->origin, buf->origin + visBuf->texSize.y }; |
1901 | iConstForEach(PtrSet, r, d->invalidRuns) { | 1880 | /* Clear full-width backgrounds first in case there are any dynamic elements. */ { |
1902 | const iGmRun *run = *r.value; | 1881 | iConstForEach(PtrSet, r, d->invalidRuns) { |
1903 | if (!isEmpty_Rangei(intersect_Rangei( | 1882 | const iGmRun *run = *r.value; |
1904 | bufRange, | 1883 | if (isOverlapping_Rangei(bufRange, ySpan_Rect(run->visBounds))) { |
1905 | (iRangei){ top_Rect(run->visBounds), bottom_Rect(run->visBounds) }))) { | 1884 | beginTarget_Paint(p, buf->texture); |
1906 | if (!isTargetSet) { | 1885 | fillRect_Paint(&ctx.paint, |
1886 | init_Rect(0, | ||
1887 | run->visBounds.pos.y - buf->origin, | ||
1888 | visBuf->texSize.x, | ||
1889 | run->visBounds.size.y), | ||
1890 | tmBackground_ColorId); | ||
1891 | } | ||
1892 | } | ||
1893 | } | ||
1894 | iConstForEach(PtrSet, r, d->invalidRuns) { | ||
1895 | const iGmRun *run = *r.value; | ||
1896 | if (isOverlapping_Rangei(bufRange, ySpan_Rect(run->visBounds))) { | ||
1907 | beginTarget_Paint(p, buf->texture); | 1897 | beginTarget_Paint(p, buf->texture); |
1908 | isTargetSet = iTrue; | 1898 | drawRun_DrawContext_(&ctx, run); |
1909 | } | 1899 | } |
1910 | drawRun_DrawContext_(&ctx, run); | ||
1911 | } | 1900 | } |
1912 | } | 1901 | } |
1913 | if (isTargetSet) { | 1902 | endTarget_Paint(&ctx.paint); |
1914 | endTarget_Paint(&ctx.paint); | ||
1915 | } | ||
1916 | fflush(stdout); | 1903 | fflush(stdout); |
1917 | } | 1904 | } |
1918 | validate_VisBuf(visBuf); | 1905 | validate_VisBuf(visBuf); |
1919 | clear_PtrSet(d->invalidRuns); | 1906 | clear_PtrSet(d->invalidRuns); |
1920 | } | 1907 | } |
1921 | #if 0 | ||
1922 | // iAssert(visBuf->texture[vbDst]); | ||
1923 | beginTarget_Paint(p, visBuf->texture[vbDst]); | ||
1924 | const iRect visBufferRect = { zero_I2(), visBuf->size }; | ||
1925 | iRect drawRect = visBufferRect; | ||
1926 | if (!isEmpty_Rangei(intersect_Rangei(visRange, visBuf->validRange))) { | ||
1927 | if (visRange.start < visBuf->validRange.start) { | ||
1928 | drawRange = (iRangei){ visRange.start, visBuf->validRange.start }; | ||
1929 | } | ||
1930 | else { | ||
1931 | drawRange = (iRangei){ visBuf->validRange.end, visRange.end }; | ||
1932 | } | ||
1933 | if (isEmpty_Range(&drawRange)) { | ||
1934 | SDL_RenderCopy(render, visBuf->texture[vbSrc], NULL, NULL); | ||
1935 | } | ||
1936 | else { | ||
1937 | SDL_RenderCopy( | ||
1938 | render, | ||
1939 | visBuf->texture[vbSrc], | ||
1940 | NULL, | ||
1941 | &(SDL_Rect){ 0, | ||
1942 | documentToWindowY_DocumentWidget_(d, visBuf->validRange.start) - | ||
1943 | origin.y, | ||
1944 | visBuf->size.x, | ||
1945 | visBuf->size.y }); | ||
1946 | drawRect = | ||
1947 | init_Rect(0, | ||
1948 | documentToWindowY_DocumentWidget_(d, drawRange.start) - origin.y, | ||
1949 | visBuf->size.x, | ||
1950 | size_Range(&drawRange)); | ||
1951 | } | ||
1952 | } | ||
1953 | if (!isEmpty_Range(&drawRange)) { | ||
1954 | setClip_Paint(p, drawRect); | ||
1955 | fillRect_Paint(p, drawRect, tmBackground_ColorId); // vbDst == 1 ? blue_ColorId : red_ColorId | ||
1956 | render_GmDocument(d->doc, drawRange, drawRun_DrawContext_, &ctxStatic); | ||
1957 | unsetClip_Paint(p); | ||
1958 | } | ||
1959 | endTarget_Paint(p); | ||
1960 | SDL_RenderCopy(render, visBuf->texture[vbDst], NULL, | ||
1961 | &(SDL_Rect){ origin.x, origin.y, bounds.size.x, bounds.size.y } ); | ||
1962 | visBuf->validRange = visRange; | ||
1963 | visBuf->index = vbDst; | ||
1964 | } | ||
1965 | /* Dynamic content. */ { | ||
1966 | extern int enableKerning_Text; | ||
1967 | enableKerning_Text = iFalse; /* need to be fast, these is redone on every redraw */ | ||
1968 | iPaint *p = &ctxDynamic.paint; | ||
1969 | init_Paint(p); | ||
1970 | setClip_Paint(p, bounds); | ||
1971 | render_GmDocument(d->doc, visRange, drawRun_DrawContext_, &ctxDynamic); | ||
1972 | unsetClip_Paint(p); | ||
1973 | enableKerning_Text = iTrue; | ||
1974 | } | ||
1975 | #endif | ||
1976 | setClip_Paint(&ctx.paint, bounds); | 1908 | setClip_Paint(&ctx.paint, bounds); |
1977 | const int yTop = docBounds.pos.y - d->scrollY; | 1909 | const int yTop = docBounds.pos.y - d->scrollY; |
1978 | draw_VisBuf(visBuf, init_I2(bounds.pos.x, yTop)); | 1910 | draw_VisBuf(visBuf, init_I2(bounds.pos.x, yTop)); |
@@ -1990,10 +1922,15 @@ static void draw_DocumentWidget_(const iDocumentWidget *d) { | |||
1990 | init_Rect(bounds.pos.x, yBottom, bounds.size.x, bottom_Rect(bounds) - yBottom), | 1922 | init_Rect(bounds.pos.x, yBottom, bounds.size.x, bottom_Rect(bounds) - yBottom), |
1991 | tmBackground_ColorId); | 1923 | tmBackground_ColorId); |
1992 | } | 1924 | } |
1993 | // drawRect_Paint(&ctx.paint, | 1925 | /* Text markers. */ |
1994 | // moved_Rect((iRect){ zero_I2(), size_GmDocument(d->doc) }, | 1926 | if (!isEmpty_Range(&d->foundMark) || !isEmpty_Range(&d->selectMark)) { |
1995 | // add_I2(topLeft_Rect(ctx.bounds), init_I2(0, -d->scrollY))), | 1927 | SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), |
1996 | // green_ColorId); | 1928 | isDark_ColorTheme(colorTheme_App()) ? SDL_BLENDMODE_ADD |
1929 | : SDL_BLENDMODE_BLEND); | ||
1930 | ctx.viewPos = topLeft_Rect(docBounds); | ||
1931 | render_GmDocument(d->doc, vis, drawMark_DrawContext_, &ctx); | ||
1932 | SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_NONE); | ||
1933 | } | ||
1997 | draw_Widget(w); | 1934 | draw_Widget(w); |
1998 | } | 1935 | } |
1999 | 1936 | ||