draw: ability to draw rectangles

This commit is contained in:
Jeremy Attali 2019-12-21 11:09:34 -05:00
parent 9a85ea2f79
commit d50972278c
3 changed files with 71 additions and 24 deletions

View File

@ -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;

View File

@ -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;
}
}

View File

@ -1,5 +1,6 @@
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#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);