Always redraw entire spiral

This commit is contained in:
Paul Dicker
2025-04-01 07:00:46 +02:00
committed by Stéphane Lesimple
parent ed8d9cfd66
commit 956131c3f3
4 changed files with 29 additions and 83 deletions

View File

@@ -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

View File

@@ -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);
}
/*

View File

@@ -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)

View File

@@ -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; i<n_segments; i++)
{
@@ -92,6 +93,7 @@ void GuiFreeSpiral(Spiral *spiral)
/*
* Fill spiral segments with given color
* Also resets the cursor (this function serves to reset the spiral)
*/
void GuiFillSpiral(Spiral *spiral, GdkColor *color)
@@ -100,6 +102,8 @@ void GuiFillSpiral(Spiral *spiral, GdkColor *color)
if(spiral)
for(i=0; i<spiral->segmentCount; 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 */