Blame c/gtk3/kaleidoscope/kaleidoscope.c

Ivan Mahonin 72a363
#include <math.h>
Ivan Mahonin 72a363
#include <gtk/gtk.h>
Ivan Mahonin 72a363
Ivan Mahonin 72a363
Ivan Mahonin 72a363
#define COUNT 16
Ivan Mahonin 72a363
Ivan Mahonin 72a363
const double pi = 3.141592653589793;
Ivan Mahonin 72a363
Ivan Mahonin 72a363
GtkWidget *window;
Ivan Mahonin 72a363
cairo_surface_t *surface;
Ivan Mahonin 72a363
cairo_t *context;
Ivan Mahonin 72a363
Ivan Mahonin 72a363
double mouse_x = 0.0;
Ivan Mahonin 72a363
double mouse_y = 0.0;
Ivan Mahonin 72a363
Ivan Mahonin 72a363
Ivan Mahonin 72a363
void line_polar(double x1, double y1, double x2, double y2) {
Ivan Mahonin 72a363
  double cx = cairo_image_surface_get_width(surface)/2.0;
Ivan Mahonin 72a363
  double cy = cairo_image_surface_get_height(surface)/2.0;
Ivan Mahonin 72a363
Ivan Mahonin 72a363
  x1 -= cx;
Ivan Mahonin 72a363
  y1 -= cy;
Ivan Mahonin 72a363
  x2 -= cx;
Ivan Mahonin 72a363
  y2 -= cy;
Ivan Mahonin 72a363
Ivan Mahonin 72a363
  double a1 = atan2(y1, x1);
Ivan Mahonin 72a363
  double r1 = sqrt(x1*x1 + y1*y1);
Ivan Mahonin 72a363
  double a2 = atan2(y2, x2);
Ivan Mahonin 72a363
  double r2 = sqrt(x2*x2 + y2*y2);
Ivan Mahonin 72a363
Ivan Mahonin 72a363
  cairo_set_source_rgba(context, 0, 0, 0, 1);
Ivan Mahonin 72a363
  cairo_set_line_width(context, 3.0);
Ivan Mahonin 72a363
  cairo_set_line_cap(context, CAIRO_LINE_CAP_ROUND);
Ivan Mahonin 72a363
  for(int sector = 0; sector < COUNT; ++sector) {
Ivan Mahonin 72a363
    x1 = r1 * cos(a1 + sector*2*pi/COUNT) + cx;
Ivan Mahonin 72a363
    y1 = r1 * sin(a1 + sector*2*pi/COUNT) + cy;
Ivan Mahonin 72a363
    x2 = r2 * cos(a2 + sector*2*pi/COUNT) + cx;
Ivan Mahonin 72a363
    y2 = r2 * sin(a2 + sector*2*pi/COUNT) + cy;
Ivan Mahonin 72a363
    cairo_move_to(context, x1, y1);
Ivan Mahonin 72a363
    cairo_line_to(context, x2, y2);
Ivan Mahonin 72a363
  }
Ivan Mahonin 72a363
  cairo_stroke(context);
Ivan Mahonin 72a363
}
Ivan Mahonin 72a363
Ivan Mahonin 72a363
gboolean motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) {
Ivan Mahonin 72a363
  if (event->state & GDK_BUTTON1_MASK) {
Ivan Mahonin 72a363
    line_polar(mouse_x, mouse_y, event->x, event->y);
Ivan Mahonin 72a363
    cairo_surface_flush(surface);
Ivan Mahonin 72a363
    gtk_widget_queue_draw(window);
Ivan Mahonin 72a363
  }
Ivan Mahonin 72a363
Ivan Mahonin 72a363
  if (event->state & GDK_BUTTON3_MASK) {
Ivan Mahonin 72a363
    cairo_save(context);
Ivan Mahonin 72a363
    cairo_set_operator(context, CAIRO_OPERATOR_CLEAR);
Ivan Mahonin 72a363
    cairo_paint(context);
Ivan Mahonin 72a363
    cairo_restore(context);
Ivan Mahonin 72a363
    cairo_surface_flush(surface);
Ivan Mahonin 72a363
    gtk_widget_queue_draw(window);
Ivan Mahonin 72a363
  }
Ivan Mahonin 72a363
Ivan Mahonin 72a363
  mouse_x = event->x;
Ivan Mahonin 72a363
  mouse_y = event->y;
Ivan Mahonin 72a363
  return TRUE;
Ivan Mahonin 72a363
}
Ivan Mahonin 72a363
Ivan Mahonin 72a363
gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
Ivan Mahonin 72a363
  cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1);
Ivan Mahonin 72a363
  cairo_paint(cr);
Ivan Mahonin 72a363
  cairo_set_source_surface(cr, surface, 0, 0);
Ivan Mahonin 72a363
  cairo_paint(cr);
Ivan Mahonin 72a363
  return TRUE;
Ivan Mahonin 72a363
}
Ivan Mahonin 72a363
Ivan Mahonin 72a363
void activate(GtkApplication* app, gpointer data) {
Ivan Mahonin 72a363
  window = gtk_application_window_new(app);
Ivan Mahonin 72a363
  g_signal_connect(window, "draw", G_CALLBACK(draw), NULL);
Ivan Mahonin 72a363
  g_signal_connect(window, "motion-notify-event", G_CALLBACK(motion), NULL);
Ivan Mahonin 72a363
  gtk_widget_add_events(window, GDK_POINTER_MOTION_MASK);
Ivan Mahonin 72a363
  gtk_window_set_default_size(
Ivan Mahonin 72a363
    GTK_WINDOW(window),
Ivan Mahonin 72a363
    cairo_image_surface_get_width(surface),
Ivan Mahonin 72a363
    cairo_image_surface_get_height(surface) );
Ivan Mahonin 72a363
  gtk_widget_show_all(window);
Ivan Mahonin 72a363
}
Ivan Mahonin 72a363
Ivan Mahonin 72a363
int main(int argc, char **argv) {
Ivan Mahonin 72a363
  surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 700, 500);
Ivan Mahonin 72a363
  context = cairo_create(surface);
Ivan Mahonin 72a363
Ivan Mahonin 72a363
  GtkApplication *application = gtk_application_new(NULL, 0);
Ivan Mahonin 72a363
  g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
Ivan Mahonin 72a363
  int status = g_application_run(G_APPLICATION(application), argc, argv);
Ivan Mahonin 72a363
  g_object_unref(application);
Ivan Mahonin 72a363
Ivan Mahonin 72a363
  cairo_destroy(context);
Ivan Mahonin 72a363
  cairo_surface_destroy(surface);
Ivan Mahonin 72a363
  return status;
Ivan Mahonin 72a363
}
Ivan Mahonin 72a363
Ivan Mahonin 72a363