Implement auto-creation of ICS logon file
[xboard.git] / gtk / xoptions.c
index c58bb26..f60f6a3 100644 (file)
@@ -244,7 +244,10 @@ SetWidgetState (Option *opt, int state)
 void
 SetWidgetLabel (Option *opt, char *buf)
 {
-    gtk_label_set_text(opt->handle, buf);
+    if(opt->type == Button) // Chat window uses this routine for changing button labels
+       gtk_button_set_label(opt->handle, buf);
+    else
+       gtk_label_set_text(opt->handle, buf);
 }
 
 void
@@ -438,7 +441,7 @@ CreateMenuPopup (Option *opt, int n, int def)
       return menu;
 }
 
-Option *typeIn; // kludge to distinguish type-in callback from input-box callback
+Option *icsBox; // kludge to distinguish type-in callback from input-box callback
 
 void
 CursorAtEnd (Option *opt)
@@ -447,21 +450,9 @@ CursorAtEnd (Option *opt)
 }
 
 static gboolean
-ICSKeyEvent(GtkWidget *widget, GdkEventKey *event, gpointer g)
-{
-    Option *opt = (Option *) g;
-    if(opt == typeIn) {
-       if(event->keyval == GDK_Return) {
-           char *val;
-           GetWidgetText(opt, &val);
-           TypeInDoneEvent(val);
-           PopDown(TransientDlg);
-           return TRUE;
-       }
-       return FALSE;
-    }
-
-    switch(event->keyval) {
+ICSKeyEvent (int keyval)
+{   // TODO_GTK: arrow-handling should really be integrated in type-in proc, and this should be a backe-end OK handler
+    switch(keyval) {
       case GDK_Return: IcsKey(0); return TRUE;
       case GDK_Up:     IcsKey(1); return TRUE;
       case GDK_Down:  IcsKey(-1); return TRUE;
@@ -566,8 +557,6 @@ MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
     gboolean res;
     gint index, x, y;
 
-    if(memo->type == Label) { ((ButtonCallback*) memo->target)(memo->value); return TRUE; } // only clock widgets use this
-
     switch(event->type) { // figure out what's up
        case GDK_MOTION_NOTIFY:
            f = 0;
@@ -583,6 +572,10 @@ MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
            button = bevent->button;
            shiftState = bevent->state & GDK_SHIFT_MASK;
            controlState = bevent->state & GDK_CONTROL_MASK;
+           if(memo->type == Label) { // only clock widgets use this
+               ((ButtonCallback*) memo->target)(button == 1 ? memo->value : -memo->value);
+               return TRUE;
+           }
 // GTK_TODO: is this really the most efficient way to get the character at the mouse cursor???
            gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_WIDGET, w, h, &x, &y);
            gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &start, x, y);
@@ -611,10 +604,10 @@ AddHandler (Option *opt, DialogClass dlg, int nr)
       case 0: // history (now uses generic textview callback)
       case 1: // comment (likewise)
        break;
-      case 2: // move type-in
-       typeIn = opt;
       case 3: // input box
-       g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (ICSKeyEvent), (gpointer) opt);
+       icsBox = opt;
+      case 2: // move type-in
+       g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (TypeInProc), (gpointer) (dlg<<16 | (opt - dialogOptions[dlg])));
        break;
       case 5: // game list
        g_signal_connect(opt->handle, "button-press-event", G_CALLBACK (GameListEvent), (gpointer) 0 );
@@ -1058,7 +1051,7 @@ static int
 SameRow (Option *opt)
 {
     return (opt->min & SAME_ROW && (opt->type == Button || opt->type == SaveButton || opt->type == Label
-                                || opt->type == ListBox || opt->type == BoxBegin || opt->type == Icon));
+                                || opt->type == ListBox || opt->type == BoxBegin || opt->type == Icon || opt->type == Graph));
 }
 
 static void
@@ -1174,7 +1167,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width);
            if(SameRow(&option[i+1])) {
                GtkAttachOptions x = GTK_FILL;
                // make sure hbox is always available when we have more options on same row
-                hbox = gtk_hbox_new (option[i].type == Button && option[i].textValue, 0);
+                hbox = gtk_hbox_new (option[i].type == Button && option[i].textValue || option[i].type == Graph, 0);
                if(!currentCps && option[i].value > 80) x |= GTK_EXPAND; // only vertically extended widgets should size vertically
                 if (strcmp(option[i].name, "") == 0 || option[i].type == Label || option[i].type == Button)
                     // for Label and Button name is contained inside option
@@ -1203,7 +1196,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width);
             w = option[i].type == Spin || option[i].type == Fractional ? 70 : option[i].max ? option[i].max : 205;
            if(option[i].type == FileName || option[i].type == PathName) w -= 55;
 
-            if (option[i].type==TextBox && option[i].value > 80){                
+            if (option[i].type==TextBox && option[i].value > 80){
                 textview = gtk_text_view_new();                
                 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), option[i].min & T_WRAP ? GTK_WRAP_WORD : GTK_WRAP_NONE);
 #ifdef TODO_GTK
@@ -1217,6 +1210,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width);
                                                option[i].min & T_VSCRL ? GTK_POLICY_ALWAYS : GTK_POLICY_NEVER);
                 gtk_container_add(GTK_CONTAINER(sw), textview);
                 gtk_widget_set_size_request(GTK_WIDGET(sw), w, -1);
+                gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_OUT);
  
                 textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));                
                 /* check if label is empty */ 
@@ -1298,11 +1292,15 @@ printf("n=%d, h=%d, w=%d\n",n,height,width);
                label = frame;
            }
             gtk_widget_set_size_request(label, option[i].max ? option[i].max : -1, -1);
-            Pack(hbox, table, label, left, left+2, top, 0);
            if(option[i].target) { // allow user to specify event handler for button presses
+               button = gtk_event_box_new();
+                gtk_container_add(GTK_CONTAINER(button), label);
+               label = button;
                gtk_widget_add_events(GTK_WIDGET(label), GDK_BUTTON_PRESS_MASK);
                g_signal_connect(label, "button-press-event", G_CALLBACK(MemoEvent), (gpointer) &option[i]);
+               gtk_widget_set_sensitive(label, TRUE);
            }
+            Pack(hbox, table, label, left, left+2, top, 0);
            break;
           case SaveButton:
           case Button:
@@ -1383,6 +1381,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width);
                 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
                 gtk_container_add(GTK_CONTAINER(sw), list);
                 gtk_widget_set_size_request(GTK_WIDGET(sw), option[i].max ? option[i].max : -1, option[i].value ? option[i].value : -1);
+                gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_OUT);
  
                 if(option[i].textValue) // generic callback for double-clicking listbox item
                     g_signal_connect(list, "button-press-event", G_CALLBACK(ListCallback), (gpointer) (dlgNr<<16 | i) );
@@ -1403,9 +1402,9 @@ printf("n=%d, h=%d, w=%d\n",n,height,width);
             g_signal_connect (graph, "button-press-event", G_CALLBACK (GraphEventProc), (gpointer) &option[i]);
             g_signal_connect (graph, "button-release-event", G_CALLBACK (GraphEventProc), (gpointer) &option[i]);
             g_signal_connect (graph, "motion-notify-event", G_CALLBACK (GraphEventProc), (gpointer) &option[i]);
-           if(0) {
-               GtkWidget *frame = gtk_aspect_frame_new(NULL, 0, 0, 1, FALSE);
-//             gtk_frame_set_shadow_type(frame, GTK_SHADOW_NONE);
+           if(option[i].min & FIX_H) { // logo
+               GtkWidget *frame = gtk_aspect_frame_new(NULL, 0.5, 0.5, option[i].max/(float)option[i].value, FALSE);
+               gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
                 gtk_container_add(GTK_CONTAINER(frame), graph);
                graph = frame;
            }
@@ -1486,9 +1485,12 @@ printf("n=%d, h=%d, w=%d\n",n,height,width);
     gtk_widget_show_all( dialog );    
 
     /* hide OK/cancel buttons */
-    if((option[i].min & 2)) {
+    if((option[i].min & NO_OK)) {
         actionarea = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
         gtk_widget_hide(actionarea);
+    } else if((option[i].min & NO_CANCEL)) {
+        button = gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), GTK_RESPONSE_REJECT);
+        gtk_widget_hide(button);
     }
 
     g_signal_connect (dialog, "response",
@@ -1557,9 +1559,7 @@ SetInsertPos (Option *opt, int pos)
 void
 HardSetFocus (Option *opt)
 {
-#ifdef TODO_GTK
-    XSetInputFocus(xDisplay, XtWindow(opt->handle), RevertToPointerRoot, CurrentTime);
-#endif
+    FocusOnWidget(opt, 0); // second arg not used in GDK
 }