Skip to content

Instantly share code, notes, and snippets.

@pce
Created March 11, 2013 13:19
Show Gist options
  • Select an option

  • Save pce/5134167 to your computer and use it in GitHub Desktop.

Select an option

Save pce/5134167 to your computer and use it in GitHub Desktop.
gcc -Wall drawarea.c -o drawarea `pkg-config --cflags --libs gtk+-2.0`
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
static gboolean button_pressed (GtkWidget*, GdkEventButton*, GArray*);
static gboolean motion_notify (GtkWidget*, GdkEventMotion*, GPtrArray*);
static gboolean key_pressed (GtkWidget*, GdkEventKey*, GPtrArray*);
static gboolean expose_event (GtkWidget*, GdkEventExpose*, GArray*);
static gboolean ui_draw_grid (GtkWidget *area);
static gboolean ui_draw_boxes (GtkWidget *area);
static gboolean ui_redraw (GtkWidget *area, GArray *steparray);
int main (int argc,
char *argv[])
{
GtkWidget *window, *area;
GPtrArray *parray;
GArray *steparray;
GArray *garray;
gint i;
gtk_init (&argc, &argv);
gtk_rc_parse(".gtkrc");
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "iobb");
gtk_widget_set_size_request (window, 400, 300);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
/* Create a pointer array to hold image data. Then, add event masks to the new
* drawing area widget. */
parray = g_ptr_array_sized_new (5000);
steparray = g_array_new (FALSE, FALSE, sizeof (guint));
area = gtk_drawing_area_new ();
GTK_WIDGET_SET_FLAGS (area, GTK_CAN_FOCUS);
gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_MOTION_MASK |
GDK_KEY_PRESS_MASK);
g_signal_connect (G_OBJECT (area), "button_press_event",
G_CALLBACK (button_pressed), steparray);
g_signal_connect (G_OBJECT (area), "motion_notify_event",
G_CALLBACK (motion_notify), parray);
g_signal_connect (G_OBJECT (area), "key_press_event",
G_CALLBACK (key_pressed), parray);
g_signal_connect (G_OBJECT (area), "expose_event",
G_CALLBACK (expose_event), steparray);
gtk_container_add (GTK_CONTAINER (window), area);
gtk_widget_show_all (window);
/* You must do this after the widget is visible because it must first
* be realized for the GdkWindow to be valid! */
gdk_window_set_cursor (area->window, gdk_cursor_new (GDK_PENCIL));
gtk_main ();
g_array_free (steparray, TRUE);
return 0;
}
/* Redraw all of the points when an expose-event occurs. If you do not do this,
* the drawing area will be cleared. */
static gboolean
expose_event (GtkWidget *area,
GdkEventExpose *event,
GArray *steparray)
{
guint i, j, x, y, w, h;
/*
w = SEQ_WIDTH/SEQ_STEPS;
h = SEQ_HEIGHT/SEQ_TRACKS;
*/
w = 9;
h = 9;
/* Loop through steps. */
for (i = 0; i < steparray->len; i = i + 2) {
/* x = GPOINTER_TO_INT (steparray->data[i]);
y = GPOINTER_TO_INT (steparray->data[i+1]); */
x = g_array_index (steparray, guint, i);
y = g_array_index (steparray, guint, i+1);
for (i = 10; i < 400; i+=10) {
for (j = 10; j < 300; j+=10) {
if (i == x && j == y) {
gdk_draw_rectangle(area->window,
area->style->fg_gc[GTK_WIDGET_STATE (area)],
TRUE,
i+1,j+1,w,h);
}
}
}
}
ui_draw_grid (area);
return TRUE;
}
/* Redraw all of the points when an expose-event occurs. If you do not do this,
* the drawing area will be cleared. */
static gboolean
ui_redraw (GtkWidget *area,
GArray *steparray)
{
guint step, i, j, x, y, w, h;
w = 9;
h = 9;
/* iobb Loop through steps. */
for (step = 0; step < steparray->len; step = step + 2) {
/* x = steparray->data[i];
y = steparray->data[i+1]; */
x = g_array_index (steparray, guint, step);
y = g_array_index (steparray, guint, step+1);
g_print ("[redraw][%d] x:%d, y:%d\n", step, x, y);
for (i = 10; i < 400; i+=10) {
for (j = 10; j < 300; j+=10) {
if (i == x && j == y) {
gdk_draw_rectangle(area->window,
area->style->fg_gc[GTK_WIDGET_STATE (area)],
TRUE,
i+1,j+1,w,h);
}
}
}
}
ui_draw_grid (area);
return TRUE;
}
static gboolean
ui_draw_boxes (GtkWidget *area)
{
guint i, j, w, h;
w = 5;
h = 5;
for (i = 0; i < 400; i+=10)
for (j = 0; j < 300; j+=10)
gdk_draw_rectangle(area->window,
area->style->fg_gc[GTK_WIDGET_STATE (area)],
TRUE,
i,j,w,h);
return TRUE;
}
static gboolean
ui_draw_grid (GtkWidget *area)
{
guint i, j, x, y, w, h;
w = 9;
h = 9;
for (i = 10; i < 400; i+=10) {
for (j = 10; j < 300; j+=10) {
if (i == 20 && j == 40) {
gdk_draw_rectangle(area->window,
area->style->fg_gc[GTK_WIDGET_STATE (area)],
TRUE,
i+1,j+1,w,h);
}
gdk_draw_point(area->window,
area->style->fg_gc[GTK_WIDGET_STATE (area)],
i,j);
}
}
return TRUE;
}
/* Draw a point where the user pressed the mouse and points on each of the
* four sides of that point. */
static gboolean
button_pressed (GtkWidget *area,
GdkEventButton *event,
GArray *steparray)
{
guint x = event->x, y = event->y, track, step, i, j;
gboolean track_set, step_set;
track_set = FALSE;
step_set = FALSE;
g_print("[button_pressed] x:%d, y:%d\n", x, y);
for (i = 10; i < 400; i+=10) {
for (j = 10; j < 300; j+=10) {
if (i > x && !track_set) {
track = i -10;
track_set = TRUE;
}
if (j > y && !step_set) {
step = j -10;
step_set = TRUE;
}
}
}
g_array_append_val (steparray, track);
g_array_append_val (steparray, step);
g_print("[button_pressed] steps:%d\n", steparray->len);
g_print("[button_pressed] track:%d, step:%d\n", track, step);
ui_redraw (area, steparray);
return FALSE;
}
/* Draw a point where the moved the mouse pointer while a button was
* pressed along with points on each of the four sides of that point. */
static gboolean
motion_notify (GtkWidget *area,
GdkEventMotion *event,
GPtrArray *parray)
{
guint x = event->x, y = event->y;
GdkPoint points[5] = { {x,y}, {x+1,y}, {x-1,y}, {x,y+1}, {x,y-1} };
gdk_draw_points (area->window,
area->style->fg_gc[GTK_WIDGET_STATE (area)],
points, 5);
g_ptr_array_add (parray, GINT_TO_POINTER (x));
g_ptr_array_add (parray, GINT_TO_POINTER (y));
return FALSE;
}
/* Clear the drawing area when the user presses the Delete key. */
static gboolean
key_pressed (GtkWidget *area,
GdkEventKey *event,
GPtrArray *parray)
{
if (event->keyval == GDK_Delete)
{
gdk_window_clear (area->window);
g_ptr_array_remove_range (parray, 0, parray->len);
}
return FALSE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment