diff --git a/include/swappy.h b/include/swappy.h index db74fe7..5207d7a 100644 --- a/include/swappy.h +++ b/include/swappy.h @@ -34,7 +34,7 @@ struct swappy_point { gdouble y; }; -struct swappy_paint { +struct swappy_shape { struct swappy_point from; struct swappy_point to; enum swappy_paint_mode_type type; @@ -106,7 +106,8 @@ struct swappy_state { struct swappy_box *geometry; GSList *brushes; - struct swappy_paint *temp_paint; // Temporary paint + GSList *shapes; + struct swappy_shape *temp_shape; // Temporary shape int argc; char **argv; diff --git a/src/application.c b/src/application.c index 7b8a974..7860fa9 100644 --- a/src/application.c +++ b/src/application.c @@ -16,6 +16,16 @@ static void swappy_overlay_clear(struct swappy_state *state) { g_slist_free_full(state->brushes, g_free); state->brushes = NULL; } + + if (state->shapes) { + g_slist_free_full(state->shapes, g_free); + state->shapes = NULL; + } + + if (state->temp_shape) { + g_free(state->temp_shape); + state->temp_shape = NULL; + } } static void switch_mode_to_brush(struct swappy_state *state) { @@ -67,7 +77,7 @@ void application_finish(struct swappy_state *state) { g_debug("application is shutting down"); swappy_overlay_clear(state); cairo_surface_destroy(state->cairo_surface); - g_free(state->temp_paint); + g_free(state->temp_shape); g_free(state->storage_path); g_free(state->geometry_str); g_free(state->geometry); @@ -209,42 +219,47 @@ static void brush_add_point(struct swappy_state *state, double x, double y, static void paint_add_temporary(struct swappy_state *state, double x, double y, enum swappy_paint_mode_type type) { - struct swappy_paint *temp = g_new(struct swappy_paint, 1); + struct swappy_shape *temp = g_new(struct swappy_shape, 1); temp->from.x = x; temp->from.y = y; temp->type = type; - if (state->temp_paint) { - g_free(state->temp_paint); - state->temp_paint = NULL; + if (state->temp_shape) { + g_free(state->temp_shape); + state->temp_shape = NULL; } - state->temp_paint = temp; + state->temp_shape = temp; } static void paint_update_temporary(struct swappy_state *state, double x, double y) { - if (!state->temp_paint) { + if (!state->temp_shape) { return; } - state->temp_paint->to.x = x; - state->temp_paint->to.y = y; + state->temp_shape->to.x = x; + state->temp_shape->to.y = y; } static void paint_commit_temporary(struct swappy_state *state, double x, double y) { - if (!state->temp_paint) { + if (!state->temp_shape) { return; } - state->temp_paint->to.x = x; - state->temp_paint->to.y = y; + state->temp_shape->to.x = x; + state->temp_shape->to.y = y; g_debug("commit temp paint: from: %lf,%lf to: %lf,%lf", - state->temp_paint->from.x, state->temp_paint->from.y, - state->temp_paint->to.x, state->temp_paint->to.y); + state->temp_shape->from.x, state->temp_shape->from.y, + state->temp_shape->to.x, state->temp_shape->to.y); + + struct swappy_shape *shape = + g_memdup(state->temp_shape, sizeof(struct swappy_shape)); + + state->shapes = g_slist_append(state->shapes, shape); } static void draw_area_button_press_handler(GtkWidget *widget, @@ -259,7 +274,6 @@ static void draw_area_button_press_handler(GtkWidget *widget, if (state->mode == SWAPPY_PAINT_MODE_RECTANGLE) { paint_add_temporary(state, event->x, event->y, SWAPPY_PAINT_MODE_RECTANGLE); - draw_state(state); } } } @@ -272,14 +286,18 @@ static void draw_area_button_release_handler(GtkWidget *widget, return; } - if (state->mode == SWAPPY_PAINT_MODE_BRUSH) { - brush_add_point(state, event->x, event->y, SWAPPY_BRUSH_POINT_LAST); - draw_state(state); - } + switch (state->mode) { + case SWAPPY_PAINT_MODE_BRUSH: + brush_add_point(state, event->x, event->y, SWAPPY_BRUSH_POINT_LAST); + draw_state(state); + break; - if (state->mode == SWAPPY_PAINT_MODE_RECTANGLE) { - paint_commit_temporary(state, event->x, event->y); - draw_state(state); + case SWAPPY_PAINT_MODE_RECTANGLE: + paint_commit_temporary(state, event->x, event->y); + draw_state(state); + break; + default: + return; } } diff --git a/src/draw.c b/src/draw.c index 009ea3d..9f001c4 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1,5 +1,6 @@ #include #include +#include #include "swappy.h" @@ -27,6 +28,32 @@ static void apply_output_transform(enum wl_output_transform transform, } } +static void draw_shape(cairo_t *cr, struct swappy_shape *shape) { + double x = fmin(shape->from.x, shape->to.x); + double y = fmin(shape->from.y, shape->to.y); + double w = fabs(shape->from.x - shape->to.x); + double h = fabs(shape->from.y - shape->to.y); + + cairo_set_source_rgba(cr, 1, 0, 0, 1); + cairo_set_line_width(cr, 2); + + cairo_rectangle(cr, x, y, w, h); + cairo_stroke_preserve(cr); + // cairo_fill(cr); +} + +static void draw_shapes(cairo_t *cr, struct swappy_state *state) { + for (GSList *elem = state->shapes; elem; elem = elem->next) { + struct swappy_shape *shape = elem->data; + + draw_shape(cr, shape); + } + + if (state->temp_shape) { + draw_shape(cr, state->temp_shape); + } +} + static void draw_buffer(cairo_t *cr, struct swappy_state *state) { // FIXME This is wrong, the geometry here is not quite valid // It must be based on output, but will work fine on single screen @@ -116,6 +143,7 @@ void draw_state(struct swappy_state *state) { draw_buffer(cr, state); draw_brushes(cr, state); + draw_shapes(cr, state); // Drawing is finised, notify the GtkDrawingArea it needs to be redrawn. gtk_widget_queue_draw(state->area);