From 956131c3f38ab1dde4b7d49062ffc53a955d9b35 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Tue, 1 Apr 2025 07:00:46 +0200 Subject: [PATCH] Always redraw entire spiral --- src/dvdisaster.h | 2 +- src/read-adaptive-window.c | 21 +++------ src/read-linear-window.c | 2 - src/spiral.c | 87 ++++++++++---------------------------- 4 files changed, 29 insertions(+), 83 deletions(-) diff --git a/src/dvdisaster.h b/src/dvdisaster.h index 68fc160..167f5b6 100644 --- a/src/dvdisaster.h +++ b/src/dvdisaster.h @@ -1533,7 +1533,7 @@ typedef struct _Spiral int diameter; int segmentClipping; int cursorPos; - GdkColor *colorUnderCursor; + gint lastRenderedCursorPos; /* use with atomic operations */ } Spiral; #ifdef WITH_GUI_YES diff --git a/src/read-adaptive-window.c b/src/read-adaptive-window.c index bf09551..2cbf017 100644 --- a/src/read-adaptive-window.c +++ b/src/read-adaptive-window.c @@ -217,31 +217,20 @@ void GuiClipReadAdaptiveSpiral(int segments) /* * Change the segment color. - * Segment numbers are passed with an offset of 100, - * since another routine is occasionally doing an - * g_idle_remove_by_data(GINT_TO_POINTER(REDRAW_PROGRESS)), - * with REDRAW_PROGRESS being 4 which would make segment 4 fail to redraw. - * One of the many places where the Gtk+ API is not well thought out. + * We can't ask for a redraw when not an the main thread, but can set an idle + * function to do so. */ static gboolean segment_idle_func(gpointer data) -{ int segment = GPOINTER_TO_INT(data); - - segment-=100; - GuiDrawSpiralSegment(Closure->readAdaptiveSpiral, - Closure->readAdaptiveSpiral->segmentColor[segment], - 0, - segment); - +{ + GuiDrawSpiral(Closure->readAdaptiveSpiral); return FALSE; } void GuiChangeSegmentColor(GdkColor *color, int segment) { Closure->readAdaptiveSpiral->segmentColor[segment] = color; - if(Closure->readAdaptiveSpiral->cursorPos == segment) - Closure->readAdaptiveSpiral->colorUnderCursor = color; - else g_idle_add(segment_idle_func, GINT_TO_POINTER(100+segment)); + g_idle_add(segment_idle_func, 0); } /* diff --git a/src/read-linear-window.c b/src/read-linear-window.c index b4d97b2..b0f876a 100644 --- a/src/read-linear-window.c +++ b/src/read-linear-window.c @@ -260,8 +260,6 @@ void GuiMarkExistingSectors(void) x = Closure->readLinearCurve->rightX + 20; Closure->additionalSpiralColor = 3; - GuiDrawSpiralLabel(Closure->readLinearSpiral, Closure->readLinearCurve->layout, - _("Already present"), Closure->darkSector, x, -1); for(i=0; i<1000; i++) if(Closure->readLinearSpiral->segmentColor[i] == Closure->greenSector) diff --git a/src/spiral.c b/src/spiral.c index 60f8b33..e8f179c 100644 --- a/src/spiral.c +++ b/src/spiral.c @@ -53,6 +53,7 @@ Spiral* GuiCreateSpiral(GdkColor *outline, GdkColor *fill, spiral->segmentColor = g_malloc(n_segments * sizeof(GdkColor*)); spiral->segmentOutline = g_malloc(n_segments * sizeof(GdkColor*)); spiral->cursorPos = -1; + spiral->lastRenderedCursorPos = -1; for(i=0; isegmentCount; i++) spiral->segmentColor[i] = color; + + spiral->cursorPos = -1; } /* @@ -143,7 +147,10 @@ void GuiDrawSpiral(Spiral *spiral) GdkColor *outline = spiral->segmentOutline[i] ? spiral->segmentOutline[i] : Closure->grid; - gdk_gc_set_rgb_fg_color(Closure->drawGC, spiral->segmentColor[i]); + if (i == spiral->cursorPos) + gdk_gc_set_rgb_fg_color(Closure->drawGC, Closure->blueSector); + else + gdk_gc_set_rgb_fg_color(Closure->drawGC, spiral->segmentColor[i]); gdk_draw_polygon(d, Closure->drawGC, TRUE, points, 4); gdk_gc_set_rgb_fg_color(Closure->drawGC, outline); gdk_draw_polygon(d, Closure->drawGC, FALSE, points, 4); @@ -158,42 +165,15 @@ void GuiDrawSpiral(Spiral *spiral) */ void GuiDrawSpiralSegment(Spiral *spiral, GdkColor *color, GdkColor *outline, int segment) -{ GdkDrawable *d = gtk_widget_get_window(spiral->widget); - double a; - double scale_i,scale_o,ring_expand; - GdkPoint points[4]; - +{ if(segment<0 || segment>=spiral->segmentClipping) return; - a = spiral->segmentPos[segment]; - - ring_expand = ((double)spiral->segmentSize * a) / (2.0*M_PI); - - scale_i = (double)spiral->startRadius + ring_expand; - scale_o = scale_i + spiral->segmentSize; - points[0].x = spiral->mx + scale_i*cos(a); - points[0].y = spiral->my + scale_i*sin(a); - points[1].x = spiral->mx + scale_o*cos(a); - points[1].y = spiral->my + scale_o*sin(a); - - a += atan((double)spiral->segmentSize / scale_o); - - ring_expand = ((double)spiral->segmentSize * a) / (2.0*M_PI); - - scale_i = (double)spiral->startRadius + ring_expand; - scale_o = scale_i + spiral->segmentSize; - points[3].x = spiral->mx + scale_i*cos(a); - points[3].y = spiral->my + scale_i*sin(a); - points[2].x = spiral->mx + scale_o*cos(a); - points[2].y = spiral->my + scale_o*sin(a); - - spiral->segmentColor[segment] = color; - spiral->segmentOutline[segment] = outline; - gdk_gc_set_rgb_fg_color(Closure->drawGC, color); - gdk_draw_polygon(d, Closure->drawGC, TRUE, points, 4); - gdk_gc_set_rgb_fg_color(Closure->drawGC, outline); - gdk_draw_polygon(d, Closure->drawGC, FALSE, points, 4); + if (spiral->segmentColor[segment] != color || spiral->segmentOutline[segment] != outline) + { spiral->segmentColor[segment] = color; + spiral->segmentOutline[segment] = outline; + gtk_widget_queue_draw(spiral->widget); + } } /* @@ -232,58 +212,37 @@ void GuiMoveSpiralCursor(Spiral *spiral, int to_segment) if(to_segment > spiral->segmentClipping) return; - /* Erase old cursor */ - - if(spiral->cursorPos >= 0) - GuiDrawSpiralSegment(spiral, spiral->colorUnderCursor, 0, spiral->cursorPos); - - /* Moving to -1 means cursor off */ - spiral->cursorPos = to_segment; - if(to_segment < 0) - return; - if(to_segment > spiral->segmentCount-1) { spiral->cursorPos = -1; return; } - /* Draw cursor at new place */ - - spiral->colorUnderCursor = spiral->segmentColor[to_segment]; - GuiDrawSpiralSegment(spiral, Closure->blueSector, 0, to_segment); + gtk_widget_queue_draw(spiral->widget); } /* * Wrapper for moving the spiral cursor from non-GUI thread */ -typedef struct _cursor_info -{ Spiral *spiral; - int segment; -} cursor_info; - static gboolean cursor_idle_func(gpointer data) -{ cursor_info *ci = (cursor_info*)data; +{ Spiral *spiral = (Spiral*)data; - GuiMoveSpiralCursor(ci->spiral, ci->segment); - g_free(ci); + gint cursorPos = g_atomic_int_get(&spiral->cursorPos); + if (spiral->lastRenderedCursorPos != cursorPos) { + spiral->lastRenderedCursorPos = cursorPos; + gtk_widget_queue_draw(spiral->widget); + } return FALSE; } - void GuiChangeSpiralCursor(Spiral *spiral, int segment) { if(!Closure->guiMode) return; - - if(segment != spiral->cursorPos) - { cursor_info *ci = g_malloc(sizeof(cursor_info)); - ci->spiral = spiral; - ci->segment = segment; - g_idle_add(cursor_idle_func, ci); - } + g_atomic_int_set(&spiral->cursorPos, segment); + g_idle_add(cursor_idle_func, spiral); } #endif /* WITH_GUI_YES */