Fix animation
[xboard.git] / xoptions.c
index 2743f97..888fb65 100644 (file)
@@ -547,13 +547,77 @@ ICSKeyEvent(GtkWidget *widget, GdkEventKey *event)
 }
 
 void
+HighlightText (Option *opt, int from, int to, Boolean highlight)
+{
+#   define INIT 0x8000
+    static GtkTextIter start, end;
+
+    if(!(opt->min & INIT)) {
+       opt->min |= INIT; // each memo its own init flag!
+       gtk_text_buffer_create_tag(opt->handle, "highlight", "background", "yellow", NULL);
+       gtk_text_buffer_create_tag(opt->handle, "normal", "background", "white", NULL);
+    }
+    gtk_text_buffer_get_iter_at_offset(opt->handle, &start, from);
+    gtk_text_buffer_get_iter_at_offset(opt->handle, &end, to);
+    gtk_text_buffer_apply_tag_by_name(opt->handle, highlight ? "highlight" : "normal", &start, &end);
+}
+
+static gboolean
+MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
+{   // handle mouse clicks on text widgets that need it
+    int w, h;
+    int button=10, f=1;
+    Option *opt, *memo = (Option *) gdata;
+    MemoCallback *userHandler = (MemoCallback *) memo->choice;
+    GdkEventButton *bevent = (GdkEventButton *) event;
+    GdkEventMotion *mevent = (GdkEventMotion *) event;
+    GtkTextIter start, end;
+    String val = NULL;
+    gboolean res;
+    gint index, x, y;
+
+    switch(event->type) { // figure out what's up
+       case GDK_MOTION_NOTIFY:
+           f = 0;
+           w = mevent->x; h = mevent->y;
+           break;
+       case GDK_BUTTON_RELEASE:
+           f = -1; // release indicated by negative button numbers
+           w = bevent->x; h = bevent->y;
+           button = bevent->button;
+           break;
+       case GDK_BUTTON_PRESS:
+           w = bevent->x; h = bevent->y;
+           button = bevent->button;
+// GTK_TODO: is this really the most efficient way to get the character at the mouse cursor???
+           gtk_text_view_window_to_buffer_coords(widget, GTK_TEXT_WINDOW_WIDGET, w, h, &x, &y);
+           gtk_text_view_get_iter_at_location(widget, &start, x, y);
+           gtk_text_buffer_place_cursor(memo->handle, &start);
+           /* get cursor position into index */
+           g_object_get(memo->handle, "cursor-position", &index, NULL);
+           /* get text from textbuffer */
+           gtk_text_buffer_get_start_iter (memo->handle, &start);
+           gtk_text_buffer_get_end_iter (memo->handle, &end);
+           val = gtk_text_buffer_get_text (memo->handle, &start, &end, FALSE); 
+           break;
+       default:
+           return FALSE; // should not happen
+    }
+    button *= f;
+    // hand click parameters as well as text & location to user
+    res = (userHandler) (memo, button, w, h, val, index);
+    if(val) g_free(val);
+    return res;
+}
+
+void
 AddHandler (Option *opt, int nr)
 {
     switch(nr) {
       case 0: 
       case 1: 
       case 2: break;
-      case 3: g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (ICSKeyEvent), NULL); break;
+      case 3: g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (ICSKeyEvent), NULL); break; // Input Box
       case 4: 
       case 5: 
       case 6: break;
@@ -800,11 +864,15 @@ GraphEventProc(GtkWidget *widget, GdkEvent *event, gpointer gdata)
 void
 GraphExpose (Option *opt, int x, int y, int w, int h)
 {
+#if 0
+  GdkRectangle r;
+  r.x = x; r.y = y; r.width = w; r.height = h;
+  gdk_window_invalidate_rect(((GtkWidget *)(opt->handle))->window, &r, FALSE);
+#endif
   GdkEventExpose e;
   if(!opt->handle) return;
   e.area.x = x; e.area.y = y; e.area.width = w; e.area.height = h; e.count = -1; e.type = GDK_EXPOSE; // count = -1: kludge to suppress sizing
-  GraphEventProc(opt->handle, (GdkEvent//        gtk_check_menu_item_set_active((GtkCheckMenuItem *) item->handle, state);
- *) &e, (gpointer) opt); // fake expose event
+  GraphEventProc(opt->handle, (GdkEvent *) &e, (gpointer) opt); // fake expose event
 }
 
 void GenericCallback(GtkWidget *widget, gpointer gdata)
@@ -1184,6 +1252,12 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
                 else
                     gtk_text_buffer_set_text (textbuffer, "", -1); 
                 option[i].handle = (void*)textbuffer;
+                option[i].textValue = (char*)textview;
+               if(option[i].choice) { // textviews can request a handler for mouse events in the choice field
+                   g_signal_connect(textview, "button-press-event", G_CALLBACK (MemoEvent), (gpointer) &option[i] );
+                   g_signal_connect(textview, "button-release-event", G_CALLBACK (MemoEvent), (gpointer) &option[i] );
+                   g_signal_connect(textview, "motion-notify-event", G_CALLBACK (MemoEvent), (gpointer) &option[i] );
+               }
                 break; 
             }