diff --git a/gfx/gfx.c b/gfx/gfx.c
index aca1933358386e2b4c3e2c0dd05bcc20f06373c1..da660733d390165061d46dba27fec27ad5c1bebe 100644
--- a/gfx/gfx.c
+++ b/gfx/gfx.c
@@ -11,31 +11,35 @@
 /// @param width Width of the window in pixels.
 /// @param height Height of the window in pixels.
 /// @return a pointer to the graphic context or NULL if it failed.
-struct gfx_context_t* gfx_create(char *title, uint width, uint height) {
-	if (SDL_Init(SDL_INIT_VIDEO) != 0) goto error;
-	SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
-		SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE);
-	SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
-	SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
-			SDL_TEXTUREACCESS_STREAMING, width, height);
-	uint32_t *pixels = malloc(width*height*sizeof(uint32_t));
-	struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t));
+struct gfx_context_t *gfx_create(char *title, uint width, uint height) {
+    if (SDL_Init(SDL_INIT_VIDEO) != 0)
+        goto error;
+    SDL_Window *window =
+        SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+                         width, height, SDL_WINDOW_RESIZABLE);
+    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
+    SDL_Texture *texture =
+        SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
+                          SDL_TEXTUREACCESS_STREAMING, width, height);
+    uint32_t *pixels = malloc(width * height * sizeof(uint32_t));
+    struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t));
 
-	if (!window || !renderer || !texture || !pixels || !ctxt) goto error;
+    if (!window || !renderer || !texture || !pixels || !ctxt)
+        goto error;
 
-	ctxt->renderer = renderer;
-	ctxt->texture = texture;
-	ctxt->window = window;
-	ctxt->width = width;
-	ctxt->height = height;
-	ctxt->pixels = pixels;
+    ctxt->renderer = renderer;
+    ctxt->texture = texture;
+    ctxt->window = window;
+    ctxt->width = width;
+    ctxt->height = height;
+    ctxt->pixels = pixels;
 
-	SDL_ShowCursor(SDL_DISABLE);
-	gfx_clear(ctxt, COLOR_BLACK);
-	return ctxt;
+    SDL_ShowCursor(SDL_ENABLE);
+    gfx_clear(ctxt, COLOR_BLACK);
+    return ctxt;
 
 error:
-	return NULL;
+    return NULL;
 }
 
 /// Draw a pixel in the specified graphic context.
@@ -44,52 +48,60 @@ error:
 /// @param y Y coordinate of the pixel.
 /// @param color Color of the pixel.
 void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color) {
-	if (x < ctxt->width && y < ctxt->height)
-		ctxt->pixels[ctxt->width*y+x] = color;
+    x = x < 0 ? 0 : x;
+    y = y < 0 ? 0 : y;
+    if (x < ctxt->width && y < ctxt->height)
+        ctxt->pixels[ctxt->width * y + x] = color;
 }
 
 /// Clear the specified graphic context.
 /// @param ctxt Graphic context to clear.
 /// @param color Color to use.
 void gfx_clear(struct gfx_context_t *ctxt, uint32_t color) {
-	int n = ctxt->width*ctxt->height;
-	while (n)
-		ctxt->pixels[--n] = color;
+    int n = ctxt->width * ctxt->height;
+    while (n)
+        ctxt->pixels[--n] = color;
 }
 
 /// Display the graphic context.
 /// @param ctxt Graphic context to clear.
 void gfx_present(struct gfx_context_t *ctxt) {
-	SDL_UpdateTexture(ctxt->texture, NULL, ctxt->pixels, ctxt->width*sizeof(uint32_t));
-	SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL);
-	SDL_RenderPresent(ctxt->renderer);
+    SDL_UpdateTexture(ctxt->texture, NULL, ctxt->pixels,
+                      ctxt->width * sizeof(uint32_t));
+    SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL);
+    SDL_RenderPresent(ctxt->renderer);
 }
 
 /// Destroy a graphic window.
 /// @param ctxt Graphic context of the window to close.
 void gfx_destroy(struct gfx_context_t *ctxt) {
-	SDL_ShowCursor(SDL_ENABLE);
-	SDL_DestroyTexture(ctxt->texture);
-	SDL_DestroyRenderer(ctxt->renderer);
-	SDL_DestroyWindow(ctxt->window);
-	free(ctxt->pixels);
-	ctxt->texture = NULL;
-	ctxt->renderer = NULL;
-	ctxt->window = NULL;
-	ctxt->pixels = NULL;
-	SDL_Quit();
-	free(ctxt);
+    SDL_ShowCursor(SDL_ENABLE);
+    SDL_DestroyTexture(ctxt->texture);
+    SDL_DestroyRenderer(ctxt->renderer);
+    SDL_DestroyWindow(ctxt->window);
+    free(ctxt->pixels);
+    ctxt->texture = NULL;
+    ctxt->renderer = NULL;
+    ctxt->window = NULL;
+    ctxt->pixels = NULL;
+    SDL_Quit();
+    free(ctxt);
 }
 
 /// If a key was pressed, returns its key code (non blocking call).
 /// List of key codes: https://wiki.libsdl.org/SDL_Keycode
 /// @return the key that was pressed or 0 if none was pressed.
 SDL_Keycode gfx_keypressed() {
-	SDL_Event event;
-	if (SDL_PollEvent(&event)) {
-		if (event.type == SDL_KEYDOWN)
-			return event.key.keysym.sym;
-	}
-	return 0;
+    SDL_Event event;
+    if (SDL_PollEvent(&event)) {
+        if (event.type == SDL_KEYDOWN)
+            return event.key.keysym.sym;
+    }
+    return 0;
 }
 
+SDL_Event gfx_event() {
+    SDL_Event event;
+    SDL_PollEvent(&event);
+    return event;
+}
diff --git a/gfx/gfx.h b/gfx/gfx.h
index a5bb5b341be20b1703f81b4187f306b4c83d03d1..49dcef81a60ee595a1da837c6017f358159877e3 100644
--- a/gfx/gfx.h
+++ b/gfx/gfx.h
@@ -1,41 +1,44 @@
 #ifndef _GFX_H_
 #define _GFX_H_
 
-#include <stdint.h>
-#include <stdbool.h> /* log() */
 #include <SDL2/SDL.h>
+#include <stdbool.h> /* log() */
+#include <stdint.h>
 
-#define MAKE_COLOR(r,g,b) ((uint32_t)b|((uint32_t)g<<8)|((uint32_t)r<<16))
+#define MAKE_COLOR(r, g, b)                                                    \
+    ((uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16))
 
 #define COLOR_GET_B(color) (color & 0xff)
 #define COLOR_GET_G(color) ((color >> 8) & 0xff)
 #define COLOR_GET_R(color) ((color >> 16) & 0xff)
 
-#define COLOR_BLACK  0x00000000
-#define COLOR_RED    0x00FF0000
-#define COLOR_GREEN  0x0000FF00
-#define COLOR_BLUE   0x000000FF
-#define COLOR_WHITE  0x00FFFFFF
+#define COLOR_BLACK 0x00000000
+#define COLOR_RED 0x00FF0000
+#define COLOR_GREEN 0x0000FF00
+#define COLOR_BLUE 0x000000FF
+#define COLOR_WHITE 0x00FFFFFF
 #define COLOR_YELLOW 0x00FFFF00
 
-typedef unsigned int  uint;
+typedef unsigned int uint;
 typedef unsigned long ulong;
 typedef unsigned char uchar;
 
 struct gfx_context_t {
-	SDL_Window *window;
-	SDL_Renderer *renderer;
-	SDL_Texture *texture;
-	uint32_t *pixels;
-	int width;
-	int height;
+    SDL_Window *window;
+    SDL_Renderer *renderer;
+    SDL_Texture *texture;
+    uint32_t *pixels;
+    int width;
+    int height;
 };
 
-extern void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color);
+extern void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y,
+                         uint32_t color);
 extern void gfx_clear(struct gfx_context_t *ctxt, uint32_t color);
-extern struct gfx_context_t* gfx_create(char *text, uint width, uint height);
+extern struct gfx_context_t *gfx_create(char *text, uint width, uint height);
 extern void gfx_destroy(struct gfx_context_t *ctxt);
 extern void gfx_present(struct gfx_context_t *ctxt);
 extern SDL_Keycode gfx_keypressed();
+extern SDL_Event gfx_event();
 
 #endif
diff --git a/main.c b/main.c
index 4395d884c2c3bffdf9244cd44e7a53a2929a0f4b..e20714fa06ac136af2341741f3650ab84b8de19b 100644
--- a/main.c
+++ b/main.c
@@ -11,6 +11,7 @@
 #include "charge/charge.h"
 #include "gfx/gfx.h"
 #include <math.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
@@ -25,9 +26,38 @@
 #define NB_POINTS 200
 #define DELTA (1 / sqrt(pow(WINDOW_WIDTH, 2) + pow(WINDOW_HEIGHT, 2)))
 
+void redraw_field(struct gfx_context_t *ctxt, int charge_count,
+                  vec2 pos[charge_count], double chs[charge_count]) {
+    // Generate all the charges
+    charge_t charges[charge_count];
+    for (int i = 0; i < charge_count; i++)
+        charges[i] = charge_create(chs[i], pos[i]);
+
+    draw_charges(ctxt, charges, charge_count, x0, x1, y0, y1);
+
+    // Generate all the points
+    vec2 points[NB_POINTS];
+    generate_points(points, NB_POINTS);
+    for (int i = 0; i < NB_POINTS; i++) {
+        coordinates_t c = position_to_coordinates(WINDOW_WIDTH, WINDOW_HEIGHT,
+                                                  x0, x1, y0, y1, points[i]);
+        draw_field_line(ctxt, charges, charge_count, DELTA, points[i], x0, x1,
+                        y0, y1);
+    }
+}
+
 int main(void) {
     srand(time(NULL));
 
+    int charge_count = NB_CHARGES;
+    vec2 pos[30];
+    double chs[30];
+
+    for (int i = 0; i < charge_count; i++) {
+        chs[i] = rand_one() / (rand_one() * 10 - 5);
+        pos[i] = vec2_create(rand_one(), rand_one());
+    }
+
     // GFX initialization
     struct gfx_context_t *ctxt =
         gfx_create("draw", WINDOW_WIDTH, WINDOW_HEIGHT);
@@ -36,26 +66,35 @@ int main(void) {
         return EXIT_FAILURE;
     }
 
-    // Generate all the charges
-    charge_t charges[NB_CHARGES];
-    for (int i = 0; i < NB_CHARGES; i++) {
-        charges[i] = charge_create(rand_one() / (rand_one() * 10 - 5),
-                                   vec2_create(rand_one(), rand_one()));
-    }
-    draw_charges(ctxt, charges, NB_CHARGES, x0, x1, y0, y1);
-
-    // Generate all the points
-    vec2 points[NB_POINTS];
-    generate_points(points, NB_POINTS);
-    for (int i = 0; i < NB_POINTS; i++) {
-        coordinates_t c = position_to_coordinates(WINDOW_WIDTH, WINDOW_HEIGHT,
-                                                  x0, x1, y0, y1, points[i]);
-        draw_field_line(ctxt, charges, NB_CHARGES, DELTA, points[i], x0, x1, y0,
-                        y1);
-    }
+    redraw_field(ctxt, charge_count, pos, chs);
 
+    bool running = true;
     // GFX Draw loop
-    while (gfx_keypressed() != SDLK_ESCAPE) {
+    while (running) {
+        SDL_Event event = gfx_event();
+
+        switch (event.type) {
+        case SDL_KEYDOWN:
+            if (event.key.keysym.sym == SDLK_ESCAPE)
+                running = false;
+            break;
+
+        case SDL_MOUSEBUTTONDOWN:
+            if (event.button.button == SDL_BUTTON_LEFT) {
+                charge_count += 1;
+                gfx_clear(ctxt, 0x000000);
+                int m_x, m_y;
+                SDL_GetMouseState(&m_x, &m_y);
+
+                pos[charge_count - 1] = vec2_create(
+                    (double)m_x / WINDOW_WIDTH, (double)m_y / WINDOW_HEIGHT);
+                chs[charge_count - 1] = rand_one() / (rand_one() * 10 - 5);
+
+                redraw_field(ctxt, charge_count, pos, chs);
+            }
+            break;
+        }
+
         gfx_present(ctxt);
     }