summaryrefslogtreecommitdiffstats
path: root/draw.c
diff options
context:
space:
mode:
authorneoraider <devnull@localhost>2007-06-25 18:55:01 +0200
committerneoraider <devnull@localhost>2007-06-25 18:55:01 +0200
commitb8549034bef0de090547f32af07df248e68c7064 (patch)
tree2cf8128807a5d9e4b53e1461492b4930a2743ad3 /draw.c
parenta686a31daece494006e3ce841a5883472a0f412a (diff)
downloadzoomedit-b8549034bef0de090547f32af07df248e68c7064.tar
zoomedit-b8549034bef0de090547f32af07df248e68c7064.zip
zoomedit: Added Pixmap to drawing; added "point in polygon" checker; rooms are now selectable
Diffstat (limited to 'draw.c')
-rw-r--r--draw.c143
1 files changed, 111 insertions, 32 deletions
diff --git a/draw.c b/draw.c
index f68725b..dc37f19 100644
--- a/draw.c
+++ b/draw.c
@@ -1,4 +1,5 @@
#include "draw.h"
+#include "edit.h"
#include "level.h"
#include "geometry.h"
#include <math.h>
@@ -9,6 +10,7 @@
static double scale = 100.0;
static double xTranslate = 0.0, yTranslate = 0.0;
+static gboolean repaint = FALSE;
static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
@@ -17,13 +19,13 @@ static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
double step = pow(0.1, depth2);
double d;
int i;
- gchar buffer[10];
+ gchar buffer[20];
cairo_set_font_size(cr, 10.0/scale);
- for(i = 0; 0.2*(depth-depth2+i-1) < 0.3; i++) {
- d = MIN(0.2*(depth-depth2+i), 0.3);
+ for(i = 0; 0.4*(depth-depth2+i-1) < 0.5; i++) {
+ d = MIN(0.4*(depth-depth2+i), 0.5);
cairo_set_source_rgb(cr, d, d, d);
for(d = rect->x - fmod(rect->x, step) - step; d <= rect->x+rect->width; d+=step) {
@@ -87,58 +89,129 @@ static void room2path(cairo_t *cr, const ROOM *room, const RECTANGLE *rect) {
}
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
- VERTEX vertices[4] = {{-1,-1}, {-1,1}, {1,1}, {1,-1}};
- ROOM room = {sizeof(vertices)/sizeof(vertices[0]), vertices};
- LEVEL lvl = {1, &room};
cairo_t *cr;
RECTANGLE rect = {-1, -1, widget->allocation.width+2, widget->allocation.height+2};
+ static GdkPixmap *pixmap = NULL;
+ static double lastImageWidth = 0.0, lastImageHeight = 0.0;
+ static gint lastWidth = 0.0, lastHeight = 0.0;
int i;
- cr = gdk_cairo_create(widget->window);
+ if(getLevel() == NULL) return;
- gdk_cairo_region(cr, event->region);
- cairo_clip(cr);
-
- cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate);
- cairo_scale(cr, scale, scale);
-
- cairo_device_to_user(cr, &rect.x, &rect.y);
- cairo_device_to_user_distance(cr, &rect.width, &rect.height);
-
- cairo_set_line_width(cr, 1.0/scale);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
-
- drawGrid(cr, &rect);
-
- for(i = 0; i < lvl.nRooms; i++)
- room2path(cr, &lvl.rooms[i], &rect);
-
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.3);
- cairo_fill_preserve(cr);
-
- cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7);
- cairo_stroke(cr);
+ if(pixmap == NULL || lastImageWidth != getImageWidth() || lastImageHeight != getImageHeight() ||
+ lastWidth != widget->allocation.width || lastHeight != widget->allocation.height || repaint)
+ {
+ if(pixmap != NULL)
+ g_object_unref(G_OBJECT(pixmap));
+
+ pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1);
+
+ lastImageWidth = getImageWidth();
+ lastImageHeight = getImageHeight();
+ lastWidth = widget->allocation.width;
+ lastHeight = widget->allocation.height;
+ repaint = FALSE;
+
+ cr = gdk_cairo_create(GDK_DRAWABLE(pixmap));
+
+ cairo_set_source_rgb(cr, 0, 0, 0);
+ cairo_rectangle(cr, 0, 0, widget->allocation.width, widget->allocation.height);
+ cairo_fill(cr);
+
+ cairo_translate(cr, getImageWidth()/2-xTranslate, getImageHeight()/2-yTranslate);
+ cairo_scale(cr, scale, scale);
+
+ cairo_device_to_user(cr, &rect.x, &rect.y);
+ cairo_device_to_user_distance(cr, &rect.width, &rect.height);
+
+ cairo_set_line_width(cr, 1.0/scale);
+ cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
+
+ drawGrid(cr, &rect);
+
+ for(i = 0; i < getLevel()->nRooms; i++) {
+ if(&getLevel()->rooms[i] != getActiveRoom())
+ room2path(cr, &getLevel()->rooms[i], &rect);
+ }
+
+ cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.3);
+ cairo_fill_preserve(cr);
+
+ cairo_set_source_rgba(cr, 0.0, 0.7, 1.0, 0.7);
+ cairo_stroke(cr);
+
+ if(getEditMode() == EDIT_MODE_SELECTED) {
+ room2path(cr, getActiveRoom(), &rect);
+
+ 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, 1.5/scale);
+ cairo_stroke(cr);
+ }
+
+ cairo_destroy (cr);
+ }
- cairo_destroy (cr);
+ gdk_draw_drawable(GDK_DRAWABLE(widget->window), widget->style->fg_gc[GTK_WIDGET_STATE(widget)], GDK_DRAWABLE(pixmap), 0, 0, 0, 0, -1, -1);
return FALSE;
}
+
double getScale() {
return scale;
}
void setScale(double s) {
scale = s;
+ repaint = TRUE;
+}
+
+void imageToView(VERTEX *v) {
+ v->x = v->x*scale+getImageWidth()/2-xTranslate;
+ v->y = v->y*scale+getImageHeight()/2-yTranslate;
+}
+
+void viewToImage(VERTEX *v) {
+ v->x = (v->x-getImageWidth()/2+xTranslate)/scale;
+ v->y = (v->y-getImageHeight()/2+yTranslate)/scale;
}
double getImageWidth() {
- return 5*scale;
+ const LEVEL *level = getLevel();
+ double min = 0.0, max = 0.0;
+ int i, j;
+
+ if(level) {
+ for(i = 0; i < level->nRooms; i++) {
+ for(j = 0; j < level->rooms[i].nVertices; j++) {
+ min = MIN(min, level->rooms[i].vertices[j].x);
+ max = MAX(max, level->rooms[i].vertices[j].x);
+ }
+ }
+ }
+
+ return (max-min+10)*scale;
}
double getImageHeight() {
- return 5*scale;
+ const LEVEL *level = getLevel();
+ double min = 0.0, max = 0.0;
+ int i, j;
+
+ if(level) {
+ for(i = 0; i < level->nRooms; i++) {
+ for(j = 0; j < level->rooms[i].nVertices; j++) {
+ min = MIN(min, level->rooms[i].vertices[j].y);
+ max = MAX(max, level->rooms[i].vertices[j].y);
+ }
+ }
+ }
+
+ return (max-min+10)*scale;
}
double getXTranslate() {
@@ -147,6 +220,7 @@ double getXTranslate() {
void setXTranslate(double x) {
xTranslate = x;
+ repaint = TRUE;
}
double getYTranslate() {
@@ -155,4 +229,9 @@ double getYTranslate() {
void setYTranslate(double y) {
yTranslate = y;
+ repaint = TRUE;
+}
+
+void redraw() {
+ repaint = TRUE;
}