Skip to content

Commit 7f9aabe

Browse files
author
mallo-m
committed
feat: add line drawing mode and exit-code 1 when app is exited with Q
1 parent 2aa3ae2 commit 7f9aabe

File tree

10 files changed

+102
-2
lines changed

10 files changed

+102
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ custom_color=rgba(193,125,17,1)
7979
- `r`: Switch to Rectangle
8080
- `o`: Switch to Ellipse
8181
- `a`: Switch to Arrow
82+
- `l`: Switch to Arrow
8283
- `d`: Switch to Blur (`d` stands for droplet)
8384

8485
<hr>

include/application.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void text_clicked_handler(GtkWidget *widget, struct swappy_state *state);
3333
void rectangle_clicked_handler(GtkWidget *widget, struct swappy_state *state);
3434
void ellipse_clicked_handler(GtkWidget *widget, struct swappy_state *state);
3535
void arrow_clicked_handler(GtkWidget *widget, struct swappy_state *state);
36+
void line_clicked_handler(GtkWidget *widget, struct swappy_state *state);
3637
void blur_clicked_handler(GtkWidget *widget, struct swappy_state *state);
3738

3839
void copy_clicked_handler(GtkWidget *widget, struct swappy_state *state);

include/swappy.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum swappy_paint_type {
2020
SWAPPY_PAINT_MODE_RECTANGLE, /* Rectangle shapes */
2121
SWAPPY_PAINT_MODE_ELLIPSE, /* Ellipse shapes */
2222
SWAPPY_PAINT_MODE_ARROW, /* Arrow shapes */
23+
SWAPPY_PAINT_MODE_LINE, /* Straight lines */
2324
SWAPPY_PAINT_MODE_BLUR, /* Blur mode */
2425
};
2526

@@ -127,6 +128,7 @@ struct swappy_state_ui {
127128
GtkRadioButton *rectangle;
128129
GtkRadioButton *ellipse;
129130
GtkRadioButton *arrow;
131+
GtkRadioButton *line;
130132
GtkRadioButton *blur;
131133

132134
GtkRadioButton *red;
@@ -187,4 +189,5 @@ struct swappy_state {
187189

188190
int argc;
189191
char **argv;
192+
int exit_code;
190193
};

res/swappy.glade

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,14 +153,26 @@
153153
<object class="GtkLabel">
154154
<property name="visible">True</property>
155155
<property name="can_focus">False</property>
156-
<property name="label" translatable="no">D</property>
156+
<property name="label" translatable="no">L</property>
157157
</object>
158158
<packing>
159159
<property name="expand">False</property>
160160
<property name="fill">True</property>
161161
<property name="position">5</property>
162162
</packing>
163163
</child>
164+
<child>
165+
<object class="GtkLabel">
166+
<property name="visible">True</property>
167+
<property name="can_focus">False</property>
168+
<property name="label" translatable="no">D</property>
169+
</object>
170+
<packing>
171+
<property name="expand">False</property>
172+
<property name="fill">True</property>
173+
<property name="position">6</property>
174+
</packing>
175+
</child>
164176
</object>
165177
<packing>
166178
<property name="expand">False</property>
@@ -255,6 +267,22 @@
255267
<property name="position">4</property>
256268
</packing>
257269
</child>
270+
<child>
271+
<object class="GtkRadioButton" id="line">
272+
<property name="label" translatable="no"><U+F055E></property>
273+
<property name="visible">True</property>
274+
<property name="can_focus">False</property>
275+
<property name="receives_default">False</property>
276+
<property name="draw_indicator">False</property>
277+
<property name="group">brush</property>
278+
<signal name="clicked" handler="line_clicked_handler" swapped="no"/>
279+
</object>
280+
<packing>
281+
<property name="expand">False</property>
282+
<property name="fill">True</property>
283+
<property name="position">6</property>
284+
</packing>
285+
</child>
258286
<child>
259287
<object class="GtkRadioButton" id="blur">
260288
<property name="label" translatable="no"></property>

src/application.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ static void switch_mode_to_arrow(struct swappy_state *state) {
156156
gtk_widget_set_sensitive(GTK_WIDGET(state->ui->fill_shape), false);
157157
}
158158

159+
static void switch_mode_to_line(struct swappy_state *state) {
160+
state->mode = SWAPPY_PAINT_MODE_LINE;
161+
gtk_widget_set_sensitive(GTK_WIDGET(state->ui->fill_shape), false);
162+
}
163+
159164
static void switch_mode_to_blur(struct swappy_state *state) {
160165
state->mode = SWAPPY_PAINT_MODE_BLUR;
161166
gtk_widget_set_sensitive(GTK_WIDGET(state->ui->fill_shape), false);
@@ -302,6 +307,10 @@ void arrow_clicked_handler(GtkWidget *widget, struct swappy_state *state) {
302307
switch_mode_to_arrow(state);
303308
}
304309

310+
void line_clicked_handler(GtkWidget *widget, struct swappy_state *state) {
311+
switch_mode_to_line(state);
312+
}
313+
305314
void blur_clicked_handler(GtkWidget *widget, struct swappy_state *state) {
306315
switch_mode_to_blur(state);
307316
}
@@ -374,6 +383,7 @@ void window_keypress_handler(GtkWidget *widget, GdkEventKey *event,
374383
case GDK_KEY_Escape:
375384
case GDK_KEY_q:
376385
maybe_save_output_file(state);
386+
state->exit_code = 1;
377387
gtk_main_quit();
378388
break;
379389
case GDK_KEY_b:
@@ -398,6 +408,10 @@ void window_keypress_handler(GtkWidget *widget, GdkEventKey *event,
398408
switch_mode_to_arrow(state);
399409
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->arrow), true);
400410
break;
411+
case GDK_KEY_l:
412+
switch_mode_to_line(state);
413+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->line), true);
414+
break;
401415
case GDK_KEY_d:
402416
switch_mode_to_blur(state);
403417
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->blur), true);
@@ -524,6 +538,7 @@ void draw_area_button_press_handler(GtkWidget *widget, GdkEventButton *event,
524538
case SWAPPY_PAINT_MODE_RECTANGLE:
525539
case SWAPPY_PAINT_MODE_ELLIPSE:
526540
case SWAPPY_PAINT_MODE_ARROW:
541+
case SWAPPY_PAINT_MODE_LINE:
527542
case SWAPPY_PAINT_MODE_TEXT:
528543
paint_add_temporary(state, x, y, state->mode);
529544
render_state(state);
@@ -554,6 +569,7 @@ void draw_area_motion_notify_handler(GtkWidget *widget, GdkEventMotion *event,
554569
case SWAPPY_PAINT_MODE_RECTANGLE:
555570
case SWAPPY_PAINT_MODE_ELLIPSE:
556571
case SWAPPY_PAINT_MODE_ARROW:
572+
case SWAPPY_PAINT_MODE_LINE:
557573
if (is_button1_pressed) {
558574
paint_update_temporary_shape(state, x, y, is_control_pressed);
559575
render_state(state);
@@ -765,6 +781,8 @@ static bool load_layout(struct swappy_state *state) {
765781
GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "ellipse"));
766782
GtkRadioButton *arrow =
767783
GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "arrow"));
784+
GtkRadioButton *line =
785+
GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "line"));
768786
GtkRadioButton *blur =
769787
GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "blur"));
770788

@@ -795,6 +813,7 @@ static bool load_layout(struct swappy_state *state) {
795813
state->ui->rectangle = rectangle;
796814
state->ui->ellipse = ellipse;
797815
state->ui->arrow = arrow;
816+
state->ui->line = line;
798817
state->ui->blur = blur;
799818
state->ui->area = area;
800819
state->ui->window = window;
@@ -832,6 +851,10 @@ static void set_paint_mode(struct swappy_state *state) {
832851
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->arrow), true);
833852
gtk_widget_set_sensitive(GTK_WIDGET(state->ui->fill_shape), false);
834853
break;
854+
case SWAPPY_PAINT_MODE_LINE:
855+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->line), true);
856+
gtk_widget_set_sensitive(GTK_WIDGET(state->ui->fill_shape), false);
857+
break;
835858
case SWAPPY_PAINT_MODE_BLUR:
836859
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->ui->blur), true);
837860
gtk_widget_set_sensitive(GTK_WIDGET(state->ui->fill_shape), false);

src/config.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ static void load_config_from_file(struct swappy_config *config,
213213
config->paint_mode = SWAPPY_PAINT_MODE_ELLIPSE;
214214
} else if (g_ascii_strcasecmp(paint_mode, "arrow") == 0) {
215215
config->paint_mode = SWAPPY_PAINT_MODE_ARROW;
216+
} else if (g_ascii_strcasecmp(paint_mode, "line") == 0) {
217+
config->paint_mode = SWAPPY_PAINT_MODE_LINE;
216218
} else if (g_ascii_strcasecmp(paint_mode, "blur") == 0) {
217219
config->paint_mode = SWAPPY_PAINT_MODE_BLUR;
218220
} else {

src/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ int main(int argc, char *argv[]) {
1010
state.argc = argc;
1111
state.argv = argv;
1212
state.mode = SWAPPY_PAINT_MODE_BRUSH;
13+
state.exit_code = 0;
1314

1415
if (!application_init(&state)) {
1516
g_critical("failed to initialize gtk application");
@@ -24,5 +25,5 @@ int main(int argc, char *argv[]) {
2425

2526
application_finish(&state);
2627

27-
return status;
28+
return state.exit_code;
2829
}

src/paint.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ void paint_add_temporary(struct swappy_state *state, double x, double y,
108108
case SWAPPY_PAINT_MODE_RECTANGLE:
109109
case SWAPPY_PAINT_MODE_ELLIPSE:
110110
case SWAPPY_PAINT_MODE_ARROW:
111+
case SWAPPY_PAINT_MODE_LINE:
111112
paint->can_draw = false; // need `to` vector
112113

113114
paint->content.shape.from.x = x;
@@ -181,6 +182,7 @@ void paint_update_temporary_shape(struct swappy_state *state, double x,
181182
paint->content.shape.to.y = y;
182183
break;
183184
case SWAPPY_PAINT_MODE_ARROW:
185+
case SWAPPY_PAINT_MODE_LINE:
184186
paint->can_draw = true; // all set
185187

186188
paint->content.shape.to.x = x;

src/render.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,40 @@ static void render_shape_arrow(cairo_t *cr, struct swappy_paint_shape shape) {
281281
cairo_restore(cr);
282282
}
283283

284+
static void render_shape_line(cairo_t *cr, struct swappy_paint_shape shape) {
285+
cairo_set_source_rgba(cr, shape.r, shape.g, shape.b, shape.a);
286+
cairo_set_line_width(cr, shape.w);
287+
288+
double ftx = shape.to.x - shape.from.x;
289+
double fty = shape.to.y - shape.from.y;
290+
double ftn = sqrt(ftx * ftx + fty * fty);
291+
292+
double scaling_factor = shape.w / 4;
293+
294+
double alpha = G_PI / 6;
295+
double ta = 5 * alpha;
296+
double xc = ftn - fabs(cos(ta)) * scaling_factor;
297+
298+
if (xc < DBL_EPSILON) {
299+
xc = 0;
300+
}
301+
302+
if (ftn < DBL_EPSILON) {
303+
return;
304+
}
305+
306+
double theta = copysign(1.0, fty) * acos(ftx / ftn);
307+
308+
// Draw line
309+
cairo_save(cr);
310+
cairo_translate(cr, shape.from.x, shape.from.y);
311+
cairo_rotate(cr, theta);
312+
cairo_move_to(cr, 0, 0);
313+
cairo_line_to(cr, xc, 0);
314+
cairo_stroke(cr);
315+
cairo_restore(cr);
316+
}
317+
284318
static void render_shape_ellipse(cairo_t *cr, struct swappy_paint_shape shape) {
285319
double x = fabs(shape.from.x - shape.to.x);
286320
double y = fabs(shape.from.y - shape.to.y);
@@ -373,6 +407,9 @@ static void render_shape(cairo_t *cr, struct swappy_paint_shape shape) {
373407
case SWAPPY_PAINT_MODE_ARROW:
374408
render_shape_arrow(cr, shape);
375409
break;
410+
case SWAPPY_PAINT_MODE_LINE:
411+
render_shape_line(cr, shape);
412+
break;
376413
default:
377414
break;
378415
}
@@ -484,6 +521,7 @@ static void render_paint(cairo_t *cr, struct swappy_paint *paint) {
484521
case SWAPPY_PAINT_MODE_RECTANGLE:
485522
case SWAPPY_PAINT_MODE_ELLIPSE:
486523
case SWAPPY_PAINT_MODE_ARROW:
524+
case SWAPPY_PAINT_MODE_LINE:
487525
render_shape(cr, paint->content.shape);
488526
break;
489527
case SWAPPY_PAINT_MODE_TEXT:

swappy.1.scd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ formats are: standard name (one of: https://github.com/rgb-x/system/blob/master/
9797
- *r*: Switch to Rectangle
9898
- *o*: Switch to Ellipse
9999
- *a*: Switch to Arrow
100+
- *l*: Switch to Arrow
100101
- *d*: Switch to Blur (d stands for droplet)
101102

102103
- *R*: Use Red Color

0 commit comments

Comments
 (0)