Always redraw entire spiral
This commit is contained in:
committed by
Stéphane Lesimple
parent
ed8d9cfd66
commit
956131c3f3
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
87
src/spiral.c
87
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; 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 */
|
||||
|
||||
Reference in New Issue
Block a user