summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-09-03 19:15:43 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-09-03 19:15:43 +0300
commit814c513984965d2732ef36215ba3fad97875af51 (patch)
tree115a3f56c18300693f6700ee5f788939b0a4e55f /src
parent4d39c1b06742d73efcdb9a64a213c927580dcf48 (diff)
SidebarWidget: Faster hover change redraw
Don't redraw all the items, only the affected ones.
Diffstat (limited to 'src')
-rw-r--r--src/ui/sidebarwidget.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index 40c3f55e..a919fca6 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
35#include "util.h" 35#include "util.h"
36#include "visited.h" 36#include "visited.h"
37 37
38#include <the_Foundation/intset.h>
38#include <the_Foundation/stringarray.h> 39#include <the_Foundation/stringarray.h>
39#include <SDL_clipboard.h> 40#include <SDL_clipboard.h>
40#include <SDL_mouse.h> 41#include <SDL_mouse.h>
@@ -89,6 +90,7 @@ struct Impl_SidebarWidget {
89 iWidget *resizer; 90 iWidget *resizer;
90 SDL_Cursor *resizeCursor; 91 SDL_Cursor *resizeCursor;
91 iWidget *menu; 92 iWidget *menu;
93 iIntSet invalidItems;
92 SDL_Texture *visBuffer; 94 SDL_Texture *visBuffer;
93 iBool visBufferValid; 95 iBool visBufferValid;
94}; 96};
@@ -98,6 +100,7 @@ iDefineObjectConstruction(SidebarWidget)
98static void invalidate_SidebarWidget_(iSidebarWidget *d) { 100static void invalidate_SidebarWidget_(iSidebarWidget *d) {
99 d->visBufferValid = iFalse; 101 d->visBufferValid = iFalse;
100 refresh_Widget(as_Widget(d)); 102 refresh_Widget(as_Widget(d));
103 clear_IntSet(&d->invalidItems); /* all will be drawn */
101} 104}
102 105
103static iBool isResizing_SidebarWidget_(const iSidebarWidget *d) { 106static iBool isResizing_SidebarWidget_(const iSidebarWidget *d) {
@@ -375,6 +378,7 @@ void init_SidebarWidget(iSidebarWidget *d) {
375 setBackgroundColor_Widget(d->resizer, none_ColorId); 378 setBackgroundColor_Widget(d->resizer, none_ColorId);
376 d->resizeCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); 379 d->resizeCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
377 d->menu = NULL; 380 d->menu = NULL;
381 init_IntSet(&d->invalidItems);
378 d->visBuffer = NULL; 382 d->visBuffer = NULL;
379 d->visBufferValid = iFalse; 383 d->visBufferValid = iFalse;
380} 384}
@@ -441,8 +445,10 @@ static void setHoverItem_SidebarWidget_(iSidebarWidget *d, size_t index) {
441 } 445 }
442 } 446 }
443 if (d->hoverItem != index) { 447 if (d->hoverItem != index) {
448 insert_IntSet(&d->invalidItems, d->hoverItem);
449 insert_IntSet(&d->invalidItems, index);
444 d->hoverItem = index; 450 d->hoverItem = index;
445 invalidate_SidebarWidget_(d); 451 refresh_Widget(as_Widget(d));
446 } 452 }
447} 453}
448 454
@@ -841,14 +847,14 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
841 processContextMenuEvent_Widget(d->menu, ev, {}); 847 processContextMenuEvent_Widget(d->menu, ev, {});
842 switch (processEvent_Click(&d->click, ev)) { 848 switch (processEvent_Click(&d->click, ev)) {
843 case started_ClickResult: 849 case started_ClickResult:
844 invalidate_SidebarWidget_(d); 850 //invalidate_SidebarWidget_(d);
845 break; 851 break;
846 case finished_ClickResult: 852 case finished_ClickResult:
847 if (contains_Rect(contentBounds_SidebarWidget_(d), pos_Click(&d->click)) && 853 if (contains_Rect(contentBounds_SidebarWidget_(d), pos_Click(&d->click)) &&
848 d->hoverItem != iInvalidSize) { 854 d->hoverItem != iInvalidSize) {
849 itemClicked_SidebarWidget_(d, d->hoverItem); 855 itemClicked_SidebarWidget_(d, d->hoverItem);
850 } 856 }
851 invalidate_SidebarWidget_(d); 857// invalidate_SidebarWidget_(d);
852 break; 858 break;
853 default: 859 default:
854 break; 860 break;
@@ -881,17 +887,24 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) {
881 const int bg = 887 const int bg =
882 d->mode == documentOutline_SidebarMode ? tmBackground_ColorId : uiBackground_ColorId; 888 d->mode == documentOutline_SidebarMode ? tmBackground_ColorId : uiBackground_ColorId;
883 fillRect_Paint(&p, bounds_Widget(w), bg); /* TODO: should do only the mode buttons area */ 889 fillRect_Paint(&p, bounds_Widget(w), bg); /* TODO: should do only the mode buttons area */
884 if (!d->visBufferValid) { 890 if (!d->visBufferValid || !isEmpty_IntSet(&d->invalidItems)) {
885 allocVisBuffer_SidebarWidget_(iConstCast(iSidebarWidget *, d)); 891 allocVisBuffer_SidebarWidget_(iConstCast(iSidebarWidget *, d));
886 iRect bufBounds = bounds; 892 iRect bufBounds = bounds;
887 bufBounds.pos = zero_I2(); 893 bufBounds.pos = zero_I2();
888 beginTarget_Paint(&p, d->visBuffer); 894 beginTarget_Paint(&p, d->visBuffer);
889 fillRect_Paint(&p, bufBounds, bg); 895 if (!d->visBufferValid) {
896 fillRect_Paint(&p, bufBounds, bg);
897 }
890 /* Draw the items. */ { 898 /* Draw the items. */ {
891 const int font = uiContent_FontId; 899 const int font = uiContent_FontId;
892 const iRanges visRange = visRange_SidebarWidget_(d); 900 const iRanges visRange = visRange_SidebarWidget_(d);
893 iInt2 pos = addY_I2(topLeft_Rect(bufBounds), -(d->scrollY % d->itemHeight)); 901 iInt2 pos = addY_I2(topLeft_Rect(bufBounds), -(d->scrollY % d->itemHeight));
894 for (size_t i = visRange.start; i < visRange.end; i++) { 902 for (size_t i = visRange.start; i < visRange.end; i++) {
903 if (d->visBufferValid && !contains_IntSet(&d->invalidItems, i)) {
904 /* TODO: Refactor to loop through invalidItems only. */
905 pos.y += d->itemHeight;
906 continue;
907 }
895 const iSidebarItem *item = constAt_Array(&d->items, i); 908 const iSidebarItem *item = constAt_Array(&d->items, i);
896 const iRect itemRect = { pos, init_I2(width_Rect(bufBounds), d->itemHeight) }; 909 const iRect itemRect = { pos, init_I2(width_Rect(bufBounds), d->itemHeight) };
897 const iBool isHover = isHover_Widget(w) && (d->hoverItem == i); 910 const iBool isHover = isHover_Widget(w) && (d->hoverItem == i);
@@ -905,6 +918,9 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) {
905 isPressing ? uiBackgroundPressed_ColorId 918 isPressing ? uiBackgroundPressed_ColorId
906 : uiBackgroundFramelessHover_ColorId); 919 : uiBackgroundFramelessHover_ColorId);
907 } 920 }
921 else if (d->visBufferValid) {
922 fillRect_Paint(&p, itemRect, bg);
923 }
908 if (d->mode == documentOutline_SidebarMode) { 924 if (d->mode == documentOutline_SidebarMode) {
909 const int fg = isHover ? (isPressing ? uiTextPressed_ColorId 925 const int fg = isHover ? (isPressing ? uiTextPressed_ColorId
910 : uiTextFramelessHover_ColorId) 926 : uiTextFramelessHover_ColorId)
@@ -1016,7 +1032,11 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) {
1016 } 1032 }
1017 } 1033 }
1018 endTarget_Paint(&p); 1034 endTarget_Paint(&p);
1019 iConstCast(iSidebarWidget *, d)->visBufferValid = iTrue; 1035 /* Update state. */ {
1036 iSidebarWidget *m = iConstCast(iSidebarWidget *, d);
1037 m->visBufferValid = iTrue;
1038 clear_IntSet(&m->invalidItems);
1039 }
1020 } 1040 }
1021 SDL_RenderCopy( 1041 SDL_RenderCopy(
1022 renderer_Window(get_Window()), d->visBuffer, NULL, (const SDL_Rect *) &bounds); 1042 renderer_Window(get_Window()), d->visBuffer, NULL, (const SDL_Rect *) &bounds);