draw: ability to draw circles

This commit is contained in:
Jeremy Attali 2019-12-21 14:43:17 -05:00
parent d50972278c
commit f0413d2c8c
3 changed files with 72 additions and 20 deletions

View File

@ -19,6 +19,7 @@ swappy_inc = include_directories('include')
cc = meson.get_compiler('c')
cairo = dependency('cairo')
math = cc.find_library('m')
realtime = cc.find_library('rt')
gtk = dependency('gtk+-wayland-3.0', version: '>=3.22.0')
gtk_layer_shell = dependency('gtk-layer-shell-0', version: '>= 0.1.0')
@ -49,6 +50,7 @@ executable(
gtk,
gtk_layer_shell,
libnotify,
math,
realtime,
wayland_client,
wayland_cursor,

View File

@ -260,6 +260,9 @@ static void paint_commit_temporary(struct swappy_state *state, double x,
g_memdup(state->temp_shape, sizeof(struct swappy_shape));
state->shapes = g_slist_append(state->shapes, shape);
g_free(state->temp_shape);
state->temp_shape = NULL;
}
static void draw_area_button_press_handler(GtkWidget *widget,
@ -271,9 +274,14 @@ static void draw_area_button_press_handler(GtkWidget *widget,
}
if (event->button == 1) {
if (state->mode == SWAPPY_PAINT_MODE_RECTANGLE) {
paint_add_temporary(state, event->x, event->y,
SWAPPY_PAINT_MODE_RECTANGLE);
switch (state->mode) {
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);
break;
default:
return;
}
}
}
@ -291,8 +299,9 @@ static void draw_area_button_release_handler(GtkWidget *widget,
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);
draw_state(state);
break;
@ -309,18 +318,26 @@ static void draw_area_motion_notify_handler(GtkWidget *widget,
GdkCursor *crosshair = gdk_cursor_new_for_display(display, GDK_CROSSHAIR);
gdk_window_set_cursor(window, crosshair);
if (state->mode == SWAPPY_PAINT_MODE_BRUSH) {
if (event->state & GDK_BUTTON1_MASK) {
brush_add_point(state, event->x, event->y, SWAPPY_BRUSH_POINT_WITHIN);
draw_state(state);
}
} else if (state->mode == SWAPPY_PAINT_MODE_RECTANGLE) {
if (event->state & GDK_BUTTON1_MASK) {
paint_update_temporary(state, event->x, event->y);
draw_state(state);
}
} else {
gdk_window_set_cursor(window, NULL);
gboolean is_button1_pressed = event->state & GDK_BUTTON1_MASK;
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:
if (is_button1_pressed) {
paint_update_temporary(state, event->x, event->y);
draw_state(state);
}
break;
default:
// gdk_window_set_cursor(window, NULL);
return;
}
}

View File

@ -1,9 +1,14 @@
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include "swappy.h"
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
static cairo_format_t get_cairo_format(enum wl_shm_format wl_fmt) {
switch (wl_fmt) {
case WL_SHM_FORMAT_ARGB8888:
@ -27,8 +32,23 @@ static void apply_output_transform(enum wl_output_transform transform,
*height = tmp;
}
}
static void draw_shape_ellipse(cairo_t *cr, struct swappy_shape *shape) {
double x = fabs(shape->from.x - shape->to.x);
double y = fabs(shape->from.y - shape->to.y);
double xc = shape->from.x + ((shape->to.x - shape->from.x) / 2);
double yc = shape->from.y + ((shape->to.y - shape->from.y) / 2);
static void draw_shape(cairo_t *cr, struct swappy_shape *shape) {
double r = sqrt(x * x + y * y) / 2;
cairo_set_source_rgba(cr, 1, 0, 0, 1);
cairo_set_line_width(cr, 2);
cairo_arc(cr, xc, yc, r, 0, 2 * M_PI);
cairo_stroke(cr);
cairo_close_path(cr);
}
static void draw_shape_rectangle(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);
@ -38,18 +58,31 @@ static void draw_shape(cairo_t *cr, struct swappy_shape *shape) {
cairo_set_line_width(cr, 2);
cairo_rectangle(cr, x, y, w, h);
cairo_stroke_preserve(cr);
// cairo_fill(cr);
cairo_close_path(cr);
cairo_stroke(cr);
}
static void draw_shape(cairo_t *cr, struct swappy_shape *shape) {
switch (shape->type) {
case SWAPPY_PAINT_MODE_RECTANGLE:
draw_shape_rectangle(cr, shape);
break;
case SWAPPY_PAINT_MODE_ELLIPSE:
draw_shape_ellipse(cr, shape);
break;
default:
g_debug("unknown shape type: %d", shape->type);
}
}
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) {
g_debug("drawing temporary shape");
draw_shape(cr, state->temp_shape);
}
}