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 diameter;
|
||||||
int segmentClipping;
|
int segmentClipping;
|
||||||
int cursorPos;
|
int cursorPos;
|
||||||
GdkColor *colorUnderCursor;
|
gint lastRenderedCursorPos; /* use with atomic operations */
|
||||||
} Spiral;
|
} Spiral;
|
||||||
|
|
||||||
#ifdef WITH_GUI_YES
|
#ifdef WITH_GUI_YES
|
||||||
|
|||||||
@@ -217,31 +217,20 @@ void GuiClipReadAdaptiveSpiral(int segments)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the segment color.
|
* Change the segment color.
|
||||||
* Segment numbers are passed with an offset of 100,
|
* We can't ask for a redraw when not an the main thread, but can set an idle
|
||||||
* since another routine is occasionally doing an
|
* function to do so.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static gboolean segment_idle_func(gpointer data)
|
static gboolean segment_idle_func(gpointer data)
|
||||||
{ int segment = GPOINTER_TO_INT(data);
|
{
|
||||||
|
GuiDrawSpiral(Closure->readAdaptiveSpiral);
|
||||||
segment-=100;
|
|
||||||
GuiDrawSpiralSegment(Closure->readAdaptiveSpiral,
|
|
||||||
Closure->readAdaptiveSpiral->segmentColor[segment],
|
|
||||||
0,
|
|
||||||
segment);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiChangeSegmentColor(GdkColor *color, int segment)
|
void GuiChangeSegmentColor(GdkColor *color, int segment)
|
||||||
{
|
{
|
||||||
Closure->readAdaptiveSpiral->segmentColor[segment] = color;
|
Closure->readAdaptiveSpiral->segmentColor[segment] = color;
|
||||||
if(Closure->readAdaptiveSpiral->cursorPos == segment)
|
g_idle_add(segment_idle_func, 0);
|
||||||
Closure->readAdaptiveSpiral->colorUnderCursor = color;
|
|
||||||
else g_idle_add(segment_idle_func, GINT_TO_POINTER(100+segment));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -260,8 +260,6 @@ void GuiMarkExistingSectors(void)
|
|||||||
x = Closure->readLinearCurve->rightX + 20;
|
x = Closure->readLinearCurve->rightX + 20;
|
||||||
|
|
||||||
Closure->additionalSpiralColor = 3;
|
Closure->additionalSpiralColor = 3;
|
||||||
GuiDrawSpiralLabel(Closure->readLinearSpiral, Closure->readLinearCurve->layout,
|
|
||||||
_("Already present"), Closure->darkSector, x, -1);
|
|
||||||
|
|
||||||
for(i=0; i<1000; i++)
|
for(i=0; i<1000; i++)
|
||||||
if(Closure->readLinearSpiral->segmentColor[i] == Closure->greenSector)
|
if(Closure->readLinearSpiral->segmentColor[i] == Closure->greenSector)
|
||||||
|
|||||||
83
src/spiral.c
83
src/spiral.c
@@ -53,6 +53,7 @@ Spiral* GuiCreateSpiral(GdkColor *outline, GdkColor *fill,
|
|||||||
spiral->segmentColor = g_malloc(n_segments * sizeof(GdkColor*));
|
spiral->segmentColor = g_malloc(n_segments * sizeof(GdkColor*));
|
||||||
spiral->segmentOutline = g_malloc(n_segments * sizeof(GdkColor*));
|
spiral->segmentOutline = g_malloc(n_segments * sizeof(GdkColor*));
|
||||||
spiral->cursorPos = -1;
|
spiral->cursorPos = -1;
|
||||||
|
spiral->lastRenderedCursorPos = -1;
|
||||||
|
|
||||||
for(i=0; i<n_segments; i++)
|
for(i=0; i<n_segments; i++)
|
||||||
{
|
{
|
||||||
@@ -92,6 +93,7 @@ void GuiFreeSpiral(Spiral *spiral)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill spiral segments with given color
|
* Fill spiral segments with given color
|
||||||
|
* Also resets the cursor (this function serves to reset the spiral)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void GuiFillSpiral(Spiral *spiral, GdkColor *color)
|
void GuiFillSpiral(Spiral *spiral, GdkColor *color)
|
||||||
@@ -100,6 +102,8 @@ void GuiFillSpiral(Spiral *spiral, GdkColor *color)
|
|||||||
if(spiral)
|
if(spiral)
|
||||||
for(i=0; i<spiral->segmentCount; i++)
|
for(i=0; i<spiral->segmentCount; i++)
|
||||||
spiral->segmentColor[i] = color;
|
spiral->segmentColor[i] = color;
|
||||||
|
|
||||||
|
spiral->cursorPos = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -143,6 +147,9 @@ void GuiDrawSpiral(Spiral *spiral)
|
|||||||
|
|
||||||
GdkColor *outline = spiral->segmentOutline[i] ? spiral->segmentOutline[i] : Closure->grid;
|
GdkColor *outline = spiral->segmentOutline[i] ? spiral->segmentOutline[i] : Closure->grid;
|
||||||
|
|
||||||
|
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_gc_set_rgb_fg_color(Closure->drawGC, spiral->segmentColor[i]);
|
||||||
gdk_draw_polygon(d, Closure->drawGC, TRUE, points, 4);
|
gdk_draw_polygon(d, Closure->drawGC, TRUE, points, 4);
|
||||||
gdk_gc_set_rgb_fg_color(Closure->drawGC, outline);
|
gdk_gc_set_rgb_fg_color(Closure->drawGC, outline);
|
||||||
@@ -158,42 +165,15 @@ void GuiDrawSpiral(Spiral *spiral)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void GuiDrawSpiralSegment(Spiral *spiral, GdkColor *color, GdkColor *outline, int segment)
|
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)
|
if(segment<0 || segment>=spiral->segmentClipping)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
a = spiral->segmentPos[segment];
|
if (spiral->segmentColor[segment] != color || spiral->segmentOutline[segment] != outline)
|
||||||
|
{ spiral->segmentColor[segment] = color;
|
||||||
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;
|
spiral->segmentOutline[segment] = outline;
|
||||||
gdk_gc_set_rgb_fg_color(Closure->drawGC, color);
|
gtk_widget_queue_draw(spiral->widget);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -232,58 +212,37 @@ void GuiMoveSpiralCursor(Spiral *spiral, int to_segment)
|
|||||||
if(to_segment > spiral->segmentClipping)
|
if(to_segment > spiral->segmentClipping)
|
||||||
return;
|
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;
|
spiral->cursorPos = to_segment;
|
||||||
|
|
||||||
if(to_segment < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(to_segment > spiral->segmentCount-1)
|
if(to_segment > spiral->segmentCount-1)
|
||||||
{ spiral->cursorPos = -1;
|
{ spiral->cursorPos = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw cursor at new place */
|
gtk_widget_queue_draw(spiral->widget);
|
||||||
|
|
||||||
spiral->colorUnderCursor = spiral->segmentColor[to_segment];
|
|
||||||
GuiDrawSpiralSegment(spiral, Closure->blueSector, 0, to_segment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper for moving the spiral cursor from non-GUI thread
|
* 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)
|
static gboolean cursor_idle_func(gpointer data)
|
||||||
{ cursor_info *ci = (cursor_info*)data;
|
{ Spiral *spiral = (Spiral*)data;
|
||||||
|
|
||||||
GuiMoveSpiralCursor(ci->spiral, ci->segment);
|
gint cursorPos = g_atomic_int_get(&spiral->cursorPos);
|
||||||
g_free(ci);
|
if (spiral->lastRenderedCursorPos != cursorPos) {
|
||||||
|
spiral->lastRenderedCursorPos = cursorPos;
|
||||||
|
gtk_widget_queue_draw(spiral->widget);
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiChangeSpiralCursor(Spiral *spiral, int segment)
|
void GuiChangeSpiralCursor(Spiral *spiral, int segment)
|
||||||
{
|
{
|
||||||
if(!Closure->guiMode)
|
if(!Closure->guiMode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(segment != spiral->cursorPos)
|
g_atomic_int_set(&spiral->cursorPos, segment);
|
||||||
{ cursor_info *ci = g_malloc(sizeof(cursor_info));
|
g_idle_add(cursor_idle_func, spiral);
|
||||||
|
|
||||||
ci->spiral = spiral;
|
|
||||||
ci->segment = segment;
|
|
||||||
g_idle_add(cursor_idle_func, ci);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* WITH_GUI_YES */
|
#endif /* WITH_GUI_YES */
|
||||||
|
|||||||
Reference in New Issue
Block a user