X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=gtk%2Fxoptions.c;h=f60f6a3734d91580c812d192c8172c84d4fc8982;hb=8baea05c6e9e63f8b1b57891b67b5ac0e1961b81;hp=f5d223c365b7da3c60c414bbf4576a0a7c7e98f8;hpb=0d88b7c20af19de163b648898ec8d3ed4c31d796;p=xboard.git diff --git a/gtk/xoptions.c b/gtk/xoptions.c index f5d223c..f60f6a3 100644 --- a/gtk/xoptions.c +++ b/gtk/xoptions.c @@ -151,7 +151,7 @@ void GetWidgetTextGTK(GtkWidget *w, char **buf) GtkTextIter end; if (GTK_IS_ENTRY(w)) { - *buf = gtk_entry_get_text(GTK_ENTRY (w)); + *buf = (char *) gtk_entry_get_text(GTK_ENTRY (w)); } else if (GTK_IS_TEXT_BUFFER(w)) { gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(w), &start); @@ -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 @@ -290,15 +293,11 @@ LoadListBox (Option *opt, char *emptyText, int n1, int n2) void HighlightItem (Option *opt, int index, int scroll) { - char *value, **data = (char **) (opt->target); GtkWidget *list = (GtkWidget *) (opt->handle); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); - GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); - GtkListStore *store = GTK_LIST_STORE(model); GtkTreePath *path = gtk_tree_path_new_from_indices(index, -1); - GtkTreeIter iter; gtk_tree_selection_select_path(selection, path); - if(scroll) gtk_tree_view_scroll_to_cell(list, path, NULL, 0, 0, 0); + if(scroll) gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list), path, NULL, 0, 0, 0); gtk_tree_path_free(path); } @@ -425,7 +424,7 @@ CreateMenuPopup (Option *opt, int n, int def) if(!(opt->min & NO_GETTEXT)) msg = _(msg); if(mb[i].handle) { entry = gtk_check_menu_item_new_with_label(msg); // should be used for items that can be checkmarked - if(mb[i].handle == RADIO) gtk_check_menu_item_set_draw_as_radio(entry, True); + if(mb[i].handle == RADIO) gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(entry), True); } else entry = gtk_menu_item_new_with_label(msg); gtk_signal_connect_object (GTK_OBJECT (entry), "activate", GTK_SIGNAL_FUNC(MenuSelect), (gpointer) (n<<16)+i); @@ -442,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) @@ -451,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; @@ -561,7 +548,7 @@ 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; + Option *memo = (Option *) gdata; MemoCallback *userHandler = (MemoCallback *) memo->choice; GdkEventButton *bevent = (GdkEventButton *) event; GdkEventMotion *mevent = (GdkEventMotion *) event; @@ -570,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; @@ -587,9 +572,13 @@ 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(widget, GTK_TEXT_WINDOW_WIDGET, w, h, &x, &y); - gtk_text_view_get_iter_at_location(widget, &start, x, y); + 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); gtk_text_buffer_place_cursor(memo->handle, &start); /* get cursor position into index */ g_object_get(memo->handle, "cursor-position", &index, NULL); @@ -615,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 ); @@ -638,7 +627,7 @@ GtkWidget *shells[NrOfDialogs]; DialogClass parents[NrOfDialogs]; WindowPlacement *wp[NrOfDialogs] = { // Beware! Order must correspond to DialogClass enum NULL, &wpComment, &wpTags, NULL, NULL, NULL, NULL, &wpMoveHistory, &wpGameList, &wpEngineOutput, &wpEvalGraph, - NULL, NULL, NULL, NULL, /*&wpMain*/ NULL + NULL, NULL, NULL, NULL, &wpMain }; int @@ -683,21 +672,9 @@ PopDown (DialogClass n) //Arg args[10]; if (!shellUp[n] || !shells[n]) return 0; -#ifdef TODO_GTK -// Not sure this is still used if(n && wp[n]) { // remember position - j = 0; - XtSetArg(args[j], XtNx, &windowX); j++; - XtSetArg(args[j], XtNy, &windowY); j++; - XtSetArg(args[j], XtNheight, &windowH); j++; - XtSetArg(args[j], XtNwidth, &windowW); j++; - XtGetValues(shells[n], args, j); - wp[n]->x = windowX; - wp[n]->x = windowY; - wp[n]->width = windowW; - wp[n]->height = windowH; + GetActualPlacement(shells[n], wp[n]); } -#endif gtk_widget_hide(shells[n]); shellUp[n]--; // count rather than clear @@ -793,7 +770,7 @@ static void GraphEventProc(GtkWidget *widget, GdkEvent *event, gpointer gdata) { // handle expose and mouse events on Graph widget int w, h; - int j, button=10, f=1, sizing=0; + int button=10, f=1, sizing=0; Option *opt, *graph = (Option *) gdata; PointerCallback *userHandler = graph->target; GdkEventExpose *eevent = (GdkEventExpose *) event; @@ -833,16 +810,15 @@ GraphEventProc(GtkWidget *widget, GdkEvent *event, gpointer gdata) // to give drawing routines opportunity to use it before first expose event // (which are only processed when main gets to the event loop, so after all init!) // so only change when size is no longer good -#ifdef TODO_GTK if(graph->choice) cairo_surface_destroy((cairo_surface_t *) graph->choice); graph->choice = (char**) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); -#endif break; } w = eevent->area.width; if(eevent->area.x + w > graph->max) w--; // cut off fudge pixel cr = gdk_cairo_create(((GtkWidget *) (graph->handle))->window); cairo_set_source_surface(cr, (cairo_surface_t *) graph->choice, 0, 0); +//cairo_set_source_rgb(cr, 1, 0, 0); cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); cairo_rectangle(cr, eevent->area.x, eevent->area.y, w, eevent->area.height); cairo_fill(cr); @@ -993,18 +969,17 @@ ListCallback (GtkWidget *widget, GdkEventButton *event, gpointer gdata) return TRUE; } +#ifdef TODO_GTK +// This is needed for color pickers? static char *oneLiner = "Return: redraw-display() \n \ Tab: TabProc() \n "; -static char scrollTranslations[] = - "(2): WheelProc(0 0 A) \n \ - : WheelProc(-1) \n \ - : WheelProc(1) \n "; +#endif +#ifdef TODO_GTK static void SqueezeIntoBox (Option *opt, int nr, int width) { // size buttons in bar to fit, clipping button names where necessary -#ifdef TODO_GTK int i, wtot = 0; Dimension widths[20], oldWidths[20]; Arg arg; @@ -1026,8 +1001,8 @@ SqueezeIntoBox (Option *opt, int nr, int width) XtSetValues(opt[i].handle, &arg, 1); } opt->min = wtot; -#endif } +#endif #ifdef TODO_GTK int @@ -1076,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 @@ -1173,7 +1148,7 @@ printf("n=%d, h=%d, w=%d\n",n,height,width); for (i=0;option[i].type != EndMark;i++) { if(option[i].type == -1) continue; top++; -printf("option =%2d, top =%2d\n", i, top); +//printf("option =%2d, top =%2d\n", i, top); if (top >= height) { gtk_table_resize(GTK_TABLE(table), height, r); if(!pane) { // multi-column: put tables in intermediate hbox @@ -1192,7 +1167,7 @@ printf("option =%2d, top =%2d\n", i, top); 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 @@ -1221,7 +1196,7 @@ printf("option =%2d, top =%2d\n", i, top); 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 @@ -1235,6 +1210,7 @@ printf("option =%2d, top =%2d\n", i, top); 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 */ @@ -1316,11 +1292,15 @@ printf("option =%2d, top =%2d\n", i, top); 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: @@ -1401,6 +1381,7 @@ printf("option =%2d, top =%2d\n", i, top); 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) ); @@ -1411,13 +1392,23 @@ printf("option =%2d, top =%2d\n", i, top); break; case Graph: option[i].handle = (void*) (graph = gtk_drawing_area_new()); - gtk_widget_set_size_request(graph, option[i].max, option[i].value); - Pack(hbox, GTK_TABLE(table), graph, left, left+r, top, GTK_EXPAND); +// gtk_widget_set_size_request(graph, option[i].max, option[i].value); + if(0){ GtkAllocation a; + a.x = 0; a.y = 0; a.width = option[i].max, a.height = option[i].value; + gtk_widget_set_allocation(graph, &a); + } g_signal_connect (graph, "expose-event", G_CALLBACK (GraphEventProc), (gpointer) &option[i]); gtk_widget_add_events(GTK_WIDGET(graph), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK); 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(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; + } + Pack(hbox, table, graph, left, left+r, top, GTK_EXPAND); #ifdef TODO_GTK if(option[i].min & SAME_ROW) last = forelast, forelast = lastrow; @@ -1489,13 +1480,17 @@ printf("option =%2d, top =%2d\n", i, top); option[i].handle = (void *) table; // remember last table in EndMark handle (for hiding Engine-Output pane). + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_NONE); /* Show dialog */ 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", @@ -1506,6 +1501,13 @@ printf("option =%2d, top =%2d\n", i, top); (gpointer)(intptr_t) dlgNr); shellUp[dlgNr]++; + if(dlgNr && wp[dlgNr] && wp[dlgNr]->width > 0) { // if persistent window-info available, reposition + gtk_window_move(GTK_WINDOW(dialog), wp[dlgNr]->x, wp[dlgNr]->y); +//printf("moved %d to (%d,%d)\n", dlgNr, wp[dlgNr]->x, wp[dlgNr]->y); + gtk_window_resize(GTK_WINDOW(dialog), wp[dlgNr]->width, wp[dlgNr]->height); +//printf("resized %d to %dx%d\n", dlgNr, wp[dlgNr]->width, wp[dlgNr]->height); + } + return 1; // tells caller he must do initialization (e.g. add specific event handlers) } @@ -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 }