diff options
Diffstat (limited to 'draw.c')
-rw-r--r-- | draw.c | 109 |
1 files changed, 76 insertions, 33 deletions
@@ -31,30 +31,34 @@ static void drawGrid(cairo_t *cr, const RECTANGLE *rect) { cairo_move_to(cr, d, rect->y); cairo_line_to(cr, d, rect->y+rect->height); - if(step > 0.5) - string = g_strdup_printf("%i", (int)rint(d)); - else - string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10); - - cairo_move_to(cr, d+1/scale, rect->y+11/scale); - cairo_show_text(cr, string); - - g_free(string); + if(step > 0.005) { + if(step > 0.5) + string = g_strdup_printf("%i", (int)d); + else + string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10); + + cairo_move_to(cr, d+1/scale, rect->y+11/scale); + cairo_show_text(cr, string); + + g_free(string); + } } for(d = rect->y - fmod(rect->y, step) - step; d <= rect->y+rect->height; d+=step) { cairo_move_to(cr, rect->x, d); cairo_line_to(cr, rect->x+rect->width, d); - if(step > 0.5) - string = g_strdup_printf("%i", (int)rint(d)); - else - string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10); - - cairo_move_to(cr, rect->x+3/scale, d+11/scale); - cairo_show_text(cr, string); - - g_free(string); + if(step > 0.005) { + if(step > 0.5) + string = g_strdup_printf("%i", (int)d); + else + string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10); + + cairo_move_to(cr, rect->x+3/scale, d+11/scale); + cairo_show_text(cr, string); + + g_free(string); + } } cairo_stroke(cr); @@ -63,7 +67,7 @@ static void drawGrid(cairo_t *cr, const RECTANGLE *rect) { } } -static void polygon2path(cairo_t *cr, const POLYGON *polygon, const RECTANGLE *rect) { +static void polygon2path(cairo_t *cr, const POLYGON *polygon, const RECTANGLE *rect, gboolean close) { int i; POLYGON polygon2 = {0, NULL}; @@ -83,7 +87,8 @@ static void polygon2path(cairo_t *cr, const POLYGON *polygon, const RECTANGLE *r cairo_line_to(cr, polygon2.vertices[i].x, polygon2.vertices[i].y); } - cairo_close_path(cr); + if(close) + cairo_close_path(cr); if(rect && polygon2.vertices) free(polygon2.vertices); @@ -93,9 +98,11 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) { cairo_t *cr; VERTEX v1 = {-1, -1}, v2 = {widget->allocation.width+1, widget->allocation.height+1}; RECTANGLE rect; + gboolean vertexOk; static GdkPixmap *pixmap = NULL; static double lastImageWidth = 0.0, lastImageHeight = 0.0; static gint lastWidth = 0.0, lastHeight = 0.0; + static int lastEditMode = 0; int i; @@ -109,8 +116,8 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) { rect.width = v2.x-v1.x; rect.height = v2.y-v1.y; - if(pixmap == NULL || lastImageWidth != getImageWidth() || lastImageHeight != getImageHeight() || - lastWidth != widget->allocation.width || lastHeight != widget->allocation.height || repaint) + if(pixmap == NULL || fabs(lastImageWidth - getImageWidth()) >= 0.000001 || fabs(lastImageHeight - getImageHeight()) >= 0.000001 || + lastWidth != widget->allocation.width || lastHeight != widget->allocation.height || lastEditMode != getEditMode() || repaint) { if(pixmap != NULL) g_object_unref(G_OBJECT(pixmap)); @@ -121,15 +128,17 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) { lastImageHeight = getImageHeight(); lastWidth = widget->allocation.width; lastHeight = widget->allocation.height; + lastEditMode = getEditMode(); repaint = FALSE; + cr = gdk_cairo_create(GDK_DRAWABLE(pixmap)); cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate); cairo_scale(cr, scale, scale); cairo_set_line_width(cr, 1.0/scale); - cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_set_source_rgb(cr, 0, 0, 0); cairo_paint(cr); @@ -138,7 +147,7 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) { for(i = 0; i < getLevel()->nRooms; i++) { if(&getLevel()->rooms[i] != getActiveRoom()) - polygon2path(cr, &getLevel()->rooms[i].polygon, &rect); + polygon2path(cr, &getLevel()->rooms[i].polygon, &rect, TRUE); } cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.3); @@ -148,13 +157,14 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) { cairo_stroke(cr); if(getEditMode() == EDIT_MODE_SELECTED) { - polygon2path(cr, &getActiveRoom()->polygon, &rect); + polygon2path(cr, &getActiveRoom()->polygon, &rect, TRUE); cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.2); cairo_fill_preserve(cr); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.9); cairo_set_line_width(cr, 2.0/scale); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_stroke(cr); } @@ -163,25 +173,58 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) { gdk_draw_drawable(GDK_DRAWABLE(widget->window), widget->style->fg_gc[GTK_WIDGET_STATE(widget)], GDK_DRAWABLE(pixmap), 0, 0, 0, 0, -1, -1); + cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); + + cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate); + cairo_scale(cr, scale, scale); + + cairo_set_line_width(cr, 2.0/scale); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); + if(getHoveredRoom() != NULL && getHoveredRoom() != getActiveRoom() && (getEditMode() == EDIT_MODE_VIEW || getEditMode() == EDIT_MODE_SELECTED)) { - cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); + polygon2path(cr, &getHoveredRoom()->polygon, &rect, TRUE); - cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate); - cairo_scale(cr, scale, scale); + cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7); + cairo_stroke(cr); + } + else if(getEditMode() == EDIT_MODE_ADD) { + polygon2path(cr, &getActiveRoom()->polygon, NULL, FALSE); - cairo_set_line_width(cr, 2.0/scale); - cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); + if(isPolygonOk(&getActiveRoom()->polygon)) + cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.2); + else + cairo_set_source_rgba(cr, 1.0, 0.3, 0.3, 0.2); + cairo_fill_preserve(cr); - polygon2path(cr, &getHoveredRoom()->polygon, &rect); + if(getActiveRoom()->polygon.nVertices && getHoveredVertex()) { + vertexOk = isVertexOk(getHoveredVertex()); + + if(vertexOk) + cairo_line_to(cr, getHoveredVertex()->x, getHoveredVertex()->y); + } + + cairo_set_line_width(cr, 2.0/scale); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7); cairo_stroke(cr); - cairo_destroy (cr); + if(getActiveRoom()->polygon.nVertices && getHoveredVertex() && !vertexOk) { + cairo_set_source_rgba(cr, 1.0, 0.3, 0.3, 0.7); + + i = getActiveRoom()->polygon.nVertices - 1; + cairo_move_to(cr, getActiveRoom()->polygon.vertices[i].x, getActiveRoom()->polygon.vertices[i].y); + cairo_line_to(cr, getHoveredVertex()->x, getHoveredVertex()->y); + + cairo_stroke(cr); + } } + cairo_destroy (cr); + return FALSE; } @@ -191,7 +234,7 @@ double getScale() { } void setScale(double s) { - scale = s; + scale = MAX(0.005, MIN(s, 10000)); repaint = TRUE; } |