Skip to content
Snippets Groups Projects
Commit 2dfb4256 authored by Younes Oubkis's avatar Younes Oubkis
Browse files

Your branch is up to date with 'origin/main'.

yea
parent 365793e7
Branches
No related tags found
No related merge requests found
......@@ -6,7 +6,7 @@
"command": "make",
"args": [],
"options": {
"cwd": "${fileDirname}"
"cwd": "/home/youni/Documents/Uni/HP Praktikum/HP Praktikum - Graphics Editor/hp-praktikum-graphics-editor/src"
},
"problemMatcher": [
"$gcc"
......
File deleted
......@@ -2,14 +2,15 @@
#include <gtk-3.0/gtk/gtk.h>
#include "app.h"
GtkWidget *window;
GtkWidget *colorbtn;
GtkWidget *drawing_area;
GdkRGBA cur_col;
const GdkRGBA* current_color;
enum INPUTTYPE current_input;
t_shape shapes[MAX_SHAPES + 1];
int shape_type;
int click_count;
t_vertex click_positions[4];
GtkWidget *shapes_list;
t_custom_toolbar *toolbar;
......@@ -36,24 +37,69 @@ gboolean on_shape_choice(GtkWidget *button, gpointer user_data)
gboolean on_select_clicked(GtkWidget *button, gpointer user_data)
{
current_input = SELECTION;
return TRUE;
}
gboolean on_delete_clicked(GtkWidget *button, gpointer user_data)
{
if (!selected_shape)
return TRUE;
*selected_shape = NULL_SHAPE();
gtk_widget_queue_draw(drawing_area);
}
gboolean on_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
if (!selected_shape)
{
return;
}
switch (event->keyval)
{
case (GDK_KEY_Up):
{
move_shape(point(0, -1), selected_shape);
}
break;
case (GDK_KEY_Down):
{
move_shape(point(0, 1), selected_shape);
}
break;
case (GDK_KEY_Right):
{
move_shape(point(1, 0), selected_shape);
}
break;
case (GDK_KEY_Left):
{
move_shape(point(-1, 0), selected_shape);
}
break;
case (GDK_KEY_Delete):
{
on_delete_clicked(NULL, NULL);
}
}
gtk_widget_queue_draw(drawing_area);
static void
toolbar_auswerten(GtkWidget *button, gpointer data)
return FALSE;
}
gboolean on_scroll(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new(
GTK_WINDOW(data),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
"Es wurde ein Toolbar-Button betaetigt");
/* Sobald Dialog bestätigt, auch wieder zerstören */
g_signal_connect(dialog, "response",
G_CALLBACK(gtk_widget_destroy), NULL);
/* Dialogbox anzeigen */
gtk_widget_show(dialog);
if (!selected_shape)
return;
float dir = event->direction == GDK_SCROLL_DOWN ? 0.1 : -0.1;
rotate_shape(selected_shape, dir);
gtk_widget_queue_draw(drawing_area);
}
int create_window_layout(int argc, char **argv)
......@@ -84,28 +130,34 @@ int create_window_layout(int argc, char **argv)
drawing_area = gtk_drawing_area_new();
gtk_widget_add_events(drawing_area, GDK_BUTTON_PRESS_MASK);
gtk_widget_add_events(drawing_area, GDK_BUTTON_PRESS_MASK | GDK_SCROLL_MASK);
g_signal_connect(drawing_area, "draw", G_CALLBACK(draw), NULL);
g_signal_connect(GTK_WIDGET(drawing_area), "button-press-event", G_CALLBACK(drawing_area_click), NULL);
gtk_widget_set_size_request(drawing_area, width, height);
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(on_keypress), NULL);
g_signal_connect(drawing_area, "scroll-event", G_CALLBACK(on_scroll), NULL);
gtk_widget_set_size_request(drawing_area, width, height);
toolbar = create_toolbar(4);
GtkToolItem *triangle_btn = create_and_bind_toolbutton(toolbar, "Triangle");
GtkToolItem *rectangle_btn = create_and_bind_toolbutton(toolbar, "Rectangle");
GtkToolItem *circle_btn = create_and_bind_toolbutton(toolbar, "Circle");
GtkToolItem *clear_btn = create_and_bind_toolbutton(toolbar, "Clear");
GtkToolItem *select_btn = create_and_bind_toolbutton(toolbar, "Select");
GtkToolItem *delete_btn = create_and_bind_toolbutton(toolbar, "Delete Shape");
bind_click_signal(triangle_btn, on_shape_choice, TRIANGLE);
bind_click_signal(rectangle_btn, on_shape_choice, RECTANGLE);
bind_click_signal(circle_btn, on_shape_choice, CIRCLE);
bind_click_signal(clear_btn, on_clear, CIRCLE);
bind_click_signal(clear_btn, on_clear, NULL);
bind_click_signal(clear_btn, on_select_clicked, NULL);
bind_click_signal(delete_btn, on_delete_clicked, NULL);
shapes_list = gtk_list_box_new();
GtkWidget *lbTest = gtk_label_new("TestItem");
color_btn = gtk_color_button_new_with_rgba(current_color);
gtk_list_box_insert(GTK_LIST_BOX(shapes_list), lbTest, 0);
gtk_list_box_insert(GTK_LIST_BOX(shapes_list), color_btn, 1);
gtk_container_add(GTK_CONTAINER(hbox), GTK_WIDGET(drawing_area));
gtk_container_add(GTK_CONTAINER(hbox), GTK_WIDGET(shapes_list));
......@@ -120,6 +172,7 @@ int create_window_layout(int argc, char **argv)
int main(int argc, char **argv)
{
current_color = &cur_col;
current_input = SELECTION;
for (int i = 0; i < MAX_SHAPES; i++)
{
......
......@@ -4,6 +4,7 @@
#include <gtk-3.0/gtk/gtk.h>
#include "./lib/lib.h"
#include "math.h"
#define MAX_SHAPES 10
#define set_source_color gdk_cairo_set_source_rgba
......@@ -12,17 +13,18 @@
extern GtkWidget *window;
extern GtkWidget *drawing_area;
extern GtkWidget *color_btn;
extern enum INPUTTYPE current_input;
extern int shape_type;
extern int click_count;
extern t_vertex click_positions[4];
extern t_shape shapes[MAX_SHAPES + 1];
extern t_shape *selected_shape;
extern GtkWidget *shapes_list;
extern const GdkRGBA* current_color;
gboolean on_clear(GtkWidget *button, gpointer user_data);
gboolean drawing_area_click(GtkWidget *widget, GdkEventButton *event, gpointer data);
void add_shape(t_shape new_shape);
int add_shape(t_shape );
gboolean draw(GtkWidget *widget, cairo_t *c, gpointer data);
void handle_shape_click(float x, float y);
void handle_freehand_click(float x, float y);
......
......@@ -9,15 +9,18 @@ GdkRGBA black = {0.0, 0.0, 0.0, 1.0};
int selection_flag = 0;
float selectionX, selectionY;
t_shape *selected_shape;
t_vertex shape_points[10];
gboolean drawing_area_click(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
if (event->button != GDK_BUTTON_SECONDARY && event->button != GDK_BUTTON_PRIMARY) // Left Click
return FALSE;
if (event->button == GDK_BUTTON_SECONDARY) // Left Click
{
selection_flag = 1;
current_input = SELECTION;
selectionX = event->x;
selectionY = event->y;
gtk_widget_queue_draw(drawing_area);
......@@ -36,57 +39,79 @@ gboolean drawing_area_click(GtkWidget *widget, GdkEventButton *event, gpointer d
else
handle_freehand_click(clickX, clickY);
gtk_widget_queue_draw(drawing_area);
g_print("X%f Y%f clicked\n", clickX, clickY);
g_print("X%f Y%f clicked, current input: %d\n", clickX, clickY, current_input);
}
void handle_shape_click(float x, float y)
{
switch (shape_type)
{
case CIRCLE:
{
static t_vertex start;
static t_vertex end;
if (click_count == 0)
{
start = point(x, y);
click_positions[click_count++] = start;
shape_points[0] = point(x, y);
click_count++;
return;
}
if (click_count == 1)
{
end = point(x, y);
t_shape new_circle = create_circle(start, end);
shape_points[1] = point(x, y);
t_shape new_circle = create_circle(shape_points[0], shape_points[1]);
add_shape(new_circle);
click_count = 0;
return;
}
}
break;
case TRIANGLE:
{
static t_vertex p[3];
if (click_count < 2)
{
p[click_count] = point(x, y);
shape_points[click_count] = point(x, y);
click_count++;
}
else
{
t_shape new_triangle = create_triangle(p[0], p[1], point(x, y));
t_shape new_triangle = create_triangle(shape_points[0], shape_points[1], point(x, y));
g_print("tri drawn");
add_shape(new_triangle);
click_count = 0;
}
return;
}
break;
case RECTANGLE:
{
if (click_count == 0)
{
shape_points[0] = point(x, y);
click_count++;
return;
}
if (click_count == 1)
{
shape_points[1] = point(x, y);
t_shape new_rect = create_rectangle(shape_points[0], shape_points[1]);
add_shape(new_rect);
click_count = 0;
return;
}
}
break;
}
}
void handle_freehand_click(float x, float y)
{
}
void add_shape(t_shape new_shape)
int add_shape(t_shape new_shape)
{
for (int i = 0; i < MAX_SHAPES; i++)
{
......@@ -94,11 +119,13 @@ void add_shape(t_shape new_shape)
if (shapes[i].flag > 0)
continue;
gtk_color_button_get_rgba(color_btn,&(new_shape.color));
shapes[i] = new_shape;
gtk_widget_queue_draw(drawing_area);
click_count = 0;
return;
return 0;
}
return -1;
}
gboolean on_clear(GtkWidget *button, gpointer user_data)
{
......@@ -106,65 +133,164 @@ gboolean on_clear(GtkWidget *button, gpointer user_data)
{
shapes[i] = NULL_SHAPE();
}
for (int i = 0; i < 10; i++)
{
shape_points[i] = point(0, 0);
}
current_input = SELECTION;
click_count = 0;
gtk_widget_queue_draw(drawing_area);
}
void draw_shape(cairo_t *c, t_shape *shape)
{
// set_source_color(c, &shape->color);
if (shape->type == CIRCLE)
switch (shape->type)
{
case (CIRCLE):
{
float radius = hypotenuse(shape->vertices[0], shape->vertices[1]);
cairo_arc(c, shape->vertices[0].X, shape->vertices[0].Y, radius, 0, G_PI * 2);
g_print("Circle @ %f,%f\n", shape->vertices[0].X, shape->vertices[0].Y);
}
break;
if (shape->type == TRIANGLE)
{
for (int i = 0; i < 2; i++)
case (TRIANGLE):
{
cairo_move_to(c, shape->vertices[i].X, shape->vertices[i].Y);
cairo_line_to(c, shape->vertices[i + 1].X, shape->vertices[i + 1].Y);
g_print("%d X%f Y%f \n", i, shape->vertices[i].X, shape->vertices[i].Y);
g_print("Triangle @ %f,%f\n", shape->vertices[0].X, shape->vertices[0].Y);
cairo_move_to(c, shape->vertices[0].X, shape->vertices[0].Y);
cairo_line_to(c, shape->vertices[1].X, shape->vertices[1].Y);
cairo_line_to(c, shape->vertices[2].X, shape->vertices[2].Y);
cairo_line_to(c, shape->vertices[0].X, shape->vertices[0].Y);
}
cairo_close_path(c);
break;
case (RECTANGLE):
{
cairo_move_to(c, shape->vertices[0].X, shape->vertices[0].Y);
for (int i = 1; i < 4; i++)
{
cairo_line_to(c, shape->vertices[i].X, shape->vertices[i].Y);
}
cairo_line_to(c, shape->vertices[0].X, shape->vertices[0].Y);
}
break;
}
cairo_close_path(c);
}
gboolean draw(GtkWidget *widget, cairo_t *c, gpointer data)
{
int found_select = 0;
for (t_shape *s = shapes; s; s++)
{
if (s->flag == -1)
break;
if (!s->flag)
continue;
if (s->flag == -1)
{
break;
}
set_source_color(c, &red);
draw_shape(c, s);
if (!selection_flag || !cairo_in_fill(c, selectionX, selectionY))
if (current_input != SELECTION)
{
cairo_fill(c);
continue;
selected_shape = 0;
selection_flag = 0;
}
else if ((selection_flag && cairo_in_fill(c, selectionX, selectionY)) || (!selection_flag && selected_shape == s))
{
selected_shape = s;
selection_flag = 0;
found_select = 1;
set_source_color(c,&black);
cairo_set_line_width(c, 5.5);
cairo_set_source_rgb(c, 0, 0, 1);
cairo_stroke(c);
}
draw_shape(c, s);
set_source_color(c, &s->color);
cairo_fill(c);
}
if (current_input == CREATE_SHAPE)
{
set_source_color(c, &black);
for (int i = 0; i < click_count; i++)
{
cairo_arc(c, shape_points[i].X, shape_points[i].Y, 5, 0, G_PI * 2);
cairo_fill(c);
}
}
cairo_select_font_face(c, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size(c, 13);
cairo_set_line_width(c, 2.2);
char txt[100];
char *cur_inp;
if (current_input == SELECTION)
cur_inp = "SELECTION";
else if (current_input == CREATE_SHAPE)
cur_inp = "CREATE";
sprintf(txt, "%s", cur_inp);
cairo_move_to(c, 200, 200);
cairo_show_text(c, txt);
sprintf(txt, "Selected Shape: %d", (int)selected_shape);
cairo_move_to(c, 200, 220);
cairo_show_text(c, txt);
return FALSE; /* TRUE to stop other handlers from being invoked for the event.
FALSE to propagate the event further. */
}
void move_shape(t_vertex v, t_shape *s)
{
for (int i = 0; i < s->vertexCount; i++)
{
s->vertices[i].X += v.X;
s->vertices[i].Y += v.Y;
}
}
t_vertex get_center(t_shape *shape)
{
switch (shape->type)
{
case (TRIANGLE):
{
float x = (shape->vertices[0].X + shape->vertices[1].X + shape->vertices[2].X) / 3;
float y = (shape->vertices[0].Y + shape->vertices[1].Y + shape->vertices[2].Y) / 3;
return point(x, y);
}
case (RECTANGLE):
{
float x = (shape->vertices[0].X + shape->vertices[1].X) / 2;
float y = (shape->vertices[0].Y + shape->vertices[1].Y) / 2;
return point(x, y);
}
case (CIRCLE):
{
return point(shape->vertices[0].X, shape->vertices[0].Y);
}
}
return point(0, 0);
}
void rotate_shape(t_shape *shape, float angle)
{
t_vertex center = get_center(shape);
t_vertex *v = shape->vertices;
t_vertex temp;
for (int i = 0; i < shape->vertexCount; i++, v++)
{
temp.X = v->X - center.X;
temp.Y = v->Y - center.Y;
v->X = (cos(angle) * (temp.X) - sin(angle) * (temp.Y)) + center.X;
v->Y = (sin(angle) * (temp.X) + cos(angle) * (temp.Y)) + center.Y;
}
}
\ No newline at end of file
......@@ -33,8 +33,8 @@ typedef struct custom_toolbar
} t_custom_toolbar;
t_shape create_square(float x1,float y1,float x2, float y2);
t_shape create_triangle(t_vertex p1,t_vertex p2,t_vertex p3);
t_shape create_rectangle(t_vertex,t_vertex );
t_shape NULL_SHAPE();
t_custom_toolbar *create_toolbar(int length);
t_vertex point(float x, float y);
......@@ -42,6 +42,7 @@ GtkToolItem *create_and_bind_toolbutton(t_custom_toolbar *toolbar,const gchar *n
void bind_click_signal(GtkToolItem *item, SignalHandlerPointer sp, int data);
float hypotenuse(t_vertex a, t_vertex b);
t_shape create_circle(t_vertex start, t_vertex end);
void move_shape(t_vertex v, t_shape *s);
void rotate_shape(t_shape *shape, float angle);
#endif
\ No newline at end of file
......@@ -34,17 +34,7 @@ t_shape generic(int vertices)
t_shape create_square(float x1,float y1,float x2, float y2)
{
t_shape shape = generic(4);
shape.type = RECTANGLE;
shape.flag = 1;
t_vertex* v = shape.vertices;
v[0] = point(x1,y1);
v[1] = point(x1,y1);
v[2] = point(x1,y1);
v[3] = point(x1,y1);
return shape;
}
t_shape create_circle(t_vertex start, t_vertex end)
......@@ -58,6 +48,21 @@ t_shape create_circle(t_vertex start, t_vertex end)
return shape;
}
t_shape create_rectangle(t_vertex start, t_vertex end)
{
t_shape shape = generic(4);
shape.type = RECTANGLE;
shape.flag = 1;
t_vertex* v = shape.vertices;
v[0] = point(start.X,start.Y);
v[1] = point(start.X,end.Y);
v[2] = point(end.X,end.Y);
v[3] = point(end.X,start.Y);
return shape;
}
t_shape create_triangle(t_vertex p1,t_vertex p2, t_vertex p3)
{
t_shape shape = generic(3);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment