mirror of
https://github.com/jtheoof/swappy.git
synced 2024-08-16 18:20:45 +03:00
refactor: insert in a union type
This commit is contained in:
parent
a855e3b370
commit
f0600e55e7
@ -46,18 +46,17 @@ struct swappy_paint_shape {
|
||||
};
|
||||
|
||||
struct swappy_paint_brush {
|
||||
double x;
|
||||
double y;
|
||||
double r;
|
||||
double g;
|
||||
double b;
|
||||
double a;
|
||||
double w;
|
||||
enum swappy_brush_point_kind kind;
|
||||
GSList *points;
|
||||
};
|
||||
|
||||
struct swappy_paint {
|
||||
enum swappy_paint_type type;
|
||||
bool can_draw;
|
||||
union {
|
||||
struct swappy_paint_brush brush;
|
||||
struct swappy_paint_shape shape;
|
||||
@ -119,10 +118,8 @@ struct swappy_state {
|
||||
|
||||
struct swappy_box *geometry;
|
||||
|
||||
GSList *brushes;
|
||||
GSList *paints;
|
||||
struct swappy_paint_shape *temp_shape; // Temporary shape
|
||||
struct swappy_paint *temp_paint; // Temporary pain
|
||||
struct swappy_paint *temp_paint;
|
||||
|
||||
int argc;
|
||||
char **argv;
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <glib-2.0/glib.h>
|
||||
#include <gtk-layer-shell/gtk-layer-shell.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <include/swappy.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "clipboard.h"
|
||||
@ -12,21 +11,30 @@
|
||||
#include "swappy.h"
|
||||
#include "wayland.h"
|
||||
|
||||
static void swappy_overlay_clear(struct swappy_state *state) {
|
||||
if (state->brushes) {
|
||||
g_slist_free_full(state->brushes, g_free);
|
||||
state->brushes = NULL;
|
||||
static void paint_free(gpointer data) {
|
||||
struct swappy_paint *paint = (struct swappy_paint *)data;
|
||||
|
||||
if (paint == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (paint->type) {
|
||||
case SWAPPY_PAINT_MODE_BRUSH:
|
||||
g_slist_free_full(paint->content.brush.points, g_free);
|
||||
break;
|
||||
default:
|
||||
g_free(paint);
|
||||
}
|
||||
}
|
||||
|
||||
static void paint_free_all(struct swappy_state *state) {
|
||||
if (state->paints) {
|
||||
g_slist_free_full(state->paints, g_free);
|
||||
g_slist_free_full(state->paints, paint_free);
|
||||
state->paints = NULL;
|
||||
}
|
||||
|
||||
if (state->temp_paint) {
|
||||
g_free(state->temp_paint);
|
||||
state->temp_paint = NULL;
|
||||
}
|
||||
paint_free(state->temp_paint);
|
||||
state->temp_paint = NULL;
|
||||
}
|
||||
|
||||
static void switch_mode_to_brush(struct swappy_state *state) {
|
||||
@ -76,9 +84,8 @@ void arrow_clicked_handler(GtkWidget *widget, struct swappy_state *state) {
|
||||
|
||||
void application_finish(struct swappy_state *state) {
|
||||
g_debug("application is shutting down");
|
||||
swappy_overlay_clear(state);
|
||||
paint_free_all(state);
|
||||
cairo_surface_destroy(state->cairo_surface);
|
||||
g_free(state->temp_shape);
|
||||
g_free(state->storage_path);
|
||||
g_free(state->geometry_str);
|
||||
g_free(state->geometry);
|
||||
@ -152,7 +159,7 @@ static void tools_menu_button_save_clicked_handler(GtkButton *button,
|
||||
|
||||
static void tools_menu_button_clear_clicked_handler(
|
||||
GtkWidget *widget, struct swappy_state *state) {
|
||||
swappy_overlay_clear(state);
|
||||
paint_free_all(state);
|
||||
draw_state(state);
|
||||
}
|
||||
|
||||
@ -204,30 +211,34 @@ static void keypress_handler(GtkWidget *widget, GdkEventKey *event,
|
||||
}
|
||||
}
|
||||
|
||||
static void brush_add_point(struct swappy_state *state, double x, double y,
|
||||
enum swappy_brush_point_kind kind) {
|
||||
struct swappy_paint_brush *point = g_new(struct swappy_paint_brush, 1);
|
||||
point->x = x;
|
||||
point->y = y;
|
||||
point->r = 1;
|
||||
point->g = 0;
|
||||
point->b = 0;
|
||||
point->a = 1;
|
||||
point->w = 2;
|
||||
point->kind = kind;
|
||||
|
||||
state->brushes = g_slist_append(state->brushes, point);
|
||||
}
|
||||
|
||||
static void paint_add_temporary(struct swappy_state *state, double x, double y,
|
||||
enum swappy_paint_type type) {
|
||||
struct swappy_paint *paint = g_new(struct swappy_paint, 1);
|
||||
struct swappy_point *brush;
|
||||
|
||||
paint->type = type;
|
||||
|
||||
switch (type) {
|
||||
case SWAPPY_PAINT_MODE_BRUSH:
|
||||
paint->can_draw = true;
|
||||
|
||||
paint->content.brush.r = 1;
|
||||
paint->content.brush.g = 0;
|
||||
paint->content.brush.b = 0;
|
||||
paint->content.brush.a = 1;
|
||||
paint->content.brush.w = 2;
|
||||
|
||||
brush = g_new(struct swappy_point, 1);
|
||||
brush->x = x;
|
||||
brush->y = y;
|
||||
|
||||
paint->content.brush.points = g_slist_append(NULL, brush);
|
||||
break;
|
||||
case SWAPPY_PAINT_MODE_RECTANGLE:
|
||||
case SWAPPY_PAINT_MODE_ELLIPSE:
|
||||
case SWAPPY_PAINT_MODE_ARROW:
|
||||
paint->can_draw = false; // need `to` vector
|
||||
|
||||
paint->content.shape.from.x = x;
|
||||
paint->content.shape.from.y = y;
|
||||
paint->content.shape.r = 1;
|
||||
@ -251,47 +262,51 @@ static void paint_add_temporary(struct swappy_state *state, double x, double y,
|
||||
|
||||
static void paint_update_temporary(struct swappy_state *state, double x,
|
||||
double y) {
|
||||
if (!state->temp_paint) {
|
||||
struct swappy_paint *paint = state->temp_paint;
|
||||
struct swappy_point *brush;
|
||||
GSList *points;
|
||||
|
||||
if (!paint) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state->temp_paint->type) {
|
||||
switch (paint->type) {
|
||||
case SWAPPY_PAINT_MODE_BRUSH:
|
||||
points = paint->content.brush.points;
|
||||
brush = g_new(struct swappy_point, 1);
|
||||
brush->x = x;
|
||||
brush->y = y;
|
||||
|
||||
paint->content.brush.points = g_slist_append(points, brush);
|
||||
break;
|
||||
case SWAPPY_PAINT_MODE_RECTANGLE:
|
||||
case SWAPPY_PAINT_MODE_ELLIPSE:
|
||||
case SWAPPY_PAINT_MODE_ARROW:
|
||||
state->temp_paint->content.shape.to.x = x;
|
||||
state->temp_paint->content.shape.to.y = y;
|
||||
paint->content.shape.to.x = x;
|
||||
paint->content.shape.to.y = y;
|
||||
paint->can_draw = true; // all set
|
||||
break;
|
||||
default:
|
||||
g_info("unable to update temporary paint: %d", state->temp_paint->type);
|
||||
g_info("unable to update temporary paint: %d", paint->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void paint_commit_temporary(struct swappy_state *state, double x,
|
||||
double y) {
|
||||
if (!state->temp_paint) {
|
||||
static void paint_commit_temporary(struct swappy_state *state) {
|
||||
struct swappy_paint *paint = state->temp_paint;
|
||||
|
||||
if (!paint) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state->temp_paint->type) {
|
||||
case SWAPPY_PAINT_MODE_RECTANGLE:
|
||||
case SWAPPY_PAINT_MODE_ELLIPSE:
|
||||
case SWAPPY_PAINT_MODE_ARROW:
|
||||
state->temp_paint->content.shape.to.x = x;
|
||||
state->temp_paint->content.shape.to.y = y;
|
||||
|
||||
struct swappy_paint *paint =
|
||||
g_memdup(state->temp_paint, sizeof(struct swappy_paint));
|
||||
|
||||
state->paints = g_slist_append(state->paints, paint);
|
||||
break;
|
||||
default:
|
||||
g_info("unable to commit temporary paint: %d", state->temp_paint->type);
|
||||
break;
|
||||
if (!paint->can_draw) {
|
||||
paint_free(paint);
|
||||
} else {
|
||||
state->paints = g_slist_append(state->paints, paint);
|
||||
}
|
||||
|
||||
g_free(state->temp_paint);
|
||||
// Set the temporary paint to NULL but keep the content in memory
|
||||
// because it's now part of the GSList.
|
||||
state->temp_paint = NULL;
|
||||
}
|
||||
|
||||
@ -305,10 +320,12 @@ static void draw_area_button_press_handler(GtkWidget *widget,
|
||||
|
||||
if (event->button == 1) {
|
||||
switch (state->mode) {
|
||||
case SWAPPY_PAINT_MODE_BRUSH:
|
||||
case SWAPPY_PAINT_MODE_RECTANGLE:
|
||||
case SWAPPY_PAINT_MODE_ELLIPSE:
|
||||
case SWAPPY_PAINT_MODE_ARROW:
|
||||
paint_add_temporary(state, event->x, event->y, state->mode);
|
||||
draw_state(state);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@ -326,13 +343,10 @@ static void draw_area_button_release_handler(GtkWidget *widget,
|
||||
|
||||
switch (state->mode) {
|
||||
case SWAPPY_PAINT_MODE_BRUSH:
|
||||
brush_add_point(state, event->x, event->y, SWAPPY_BRUSH_POINT_LAST);
|
||||
draw_state(state);
|
||||
break;
|
||||
case SWAPPY_PAINT_MODE_RECTANGLE:
|
||||
case SWAPPY_PAINT_MODE_ELLIPSE:
|
||||
case SWAPPY_PAINT_MODE_ARROW:
|
||||
paint_commit_temporary(state, event->x, event->y);
|
||||
paint_commit_temporary(state);
|
||||
draw_state(state);
|
||||
break;
|
||||
default:
|
||||
@ -352,11 +366,6 @@ static void draw_area_motion_notify_handler(GtkWidget *widget,
|
||||
|
||||
switch (state->mode) {
|
||||
case SWAPPY_PAINT_MODE_BRUSH:
|
||||
if (is_button1_pressed) {
|
||||
brush_add_point(state, event->x, event->y, SWAPPY_BRUSH_POINT_WITHIN);
|
||||
draw_state(state);
|
||||
}
|
||||
break;
|
||||
case SWAPPY_PAINT_MODE_RECTANGLE:
|
||||
case SWAPPY_PAINT_MODE_ELLIPSE:
|
||||
case SWAPPY_PAINT_MODE_ARROW:
|
||||
|
40
src/draw.c
40
src/draw.c
@ -185,30 +185,35 @@ static void draw_buffer(cairo_t *cr, struct swappy_state *state) {
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_brushes(cairo_t *cr, struct swappy_state *state) {
|
||||
for (GSList *brush = state->brushes; brush; brush = brush->next) {
|
||||
GSList *brush_next = brush->next;
|
||||
struct swappy_paint_brush *point = brush->data;
|
||||
static void draw_brush(cairo_t *cr, struct swappy_paint_brush brush) {
|
||||
cairo_set_source_rgba(cr, brush.r, brush.g, brush.b, brush.a);
|
||||
cairo_set_line_width(cr, brush.w);
|
||||
cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
|
||||
|
||||
if (brush_next && point->kind == SWAPPY_BRUSH_POINT_WITHIN) {
|
||||
struct swappy_paint_brush *next = brush_next->data;
|
||||
cairo_set_source_rgba(cr, point->r, point->g, point->b, point->a);
|
||||
cairo_set_line_width(cr, point->w);
|
||||
cairo_move_to(cr, point->x, point->y);
|
||||
cairo_line_to(cr, next->x, next->y);
|
||||
cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
|
||||
cairo_stroke(cr);
|
||||
} else {
|
||||
cairo_set_source_rgba(cr, point->r, point->g, point->b, point->a);
|
||||
cairo_set_line_width(cr, point->w);
|
||||
cairo_rectangle(cr, point->x, point->y, 1, 1);
|
||||
cairo_stroke(cr);
|
||||
guint l = g_slist_length(brush.points);
|
||||
|
||||
if (l == 1) {
|
||||
struct swappy_point *point = g_slist_nth_data(brush.points, 0);
|
||||
cairo_rectangle(cr, point->x, point->y, brush.w, brush.w);
|
||||
cairo_fill(cr);
|
||||
} else {
|
||||
for (GSList *elem = brush.points; elem; elem = elem->next) {
|
||||
struct swappy_point *point = elem->data;
|
||||
cairo_line_to(cr, point->x, point->y);
|
||||
}
|
||||
cairo_stroke(cr);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_paint(cairo_t *cr, struct swappy_paint *paint) {
|
||||
if (!paint->can_draw) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (paint->type) {
|
||||
case SWAPPY_PAINT_MODE_BRUSH:
|
||||
draw_brush(cr, paint->content.brush);
|
||||
break;
|
||||
case SWAPPY_PAINT_MODE_RECTANGLE:
|
||||
case SWAPPY_PAINT_MODE_ELLIPSE:
|
||||
case SWAPPY_PAINT_MODE_ARROW:
|
||||
@ -237,7 +242,6 @@ void draw_state(struct swappy_state *state) {
|
||||
cairo_set_source_rgb(cr, 1, 1, 1);
|
||||
|
||||
draw_buffer(cr, state);
|
||||
draw_brushes(cr, state);
|
||||
draw_paints(cr, state);
|
||||
|
||||
// Drawing is finished, notify the GtkDrawingArea it needs to be redrawn.
|
||||
|
Loading…
Reference in New Issue
Block a user