GtkWidget * get_notebook_page(GtkWidget * widget) { g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL); while (widget && widget->parent && !gtk_type_is_a(GTK_WIDGET_TYPE(widget->parent), GTK_TYPE_NOTEBOOK)) widget = widget->parent; if (!(widget && widget->parent && gtk_type_is_a(GTK_WIDGET_TYPE(widget->parent), GTK_TYPE_NOTEBOOK))) return NULL; return widget; }
static gboolean on_FileSelect_key_release_event( GtkWidget * widget, GdkEvent * event, gpointer user_data ) { if ( GTK_WIDGET_TYPE( widget ) == GTK_TYPE_BUTTON ) { if (event->key.keyval == GDK_Return) gtk_button_released( GTK_BUTTON( widget ) ); } else { switch ( event->key.keyval ) { case GDK_Escape: gtk_button_released( GTK_BUTTON( fsCancel ) ); break; case GDK_Return: gtk_button_released( GTK_BUTTON( fsOk ) ); break; case GDK_BackSpace: gtk_button_released( GTK_BUTTON( fsUp ) ); gtk_widget_grab_focus( fsFNameList ); break; } } return FALSE; }
static gboolean maybe_clear_popup_image (GtkWidget *widget, GdkEventMotion *event, maybe_clear_popup_image_args_t *args) { //g_message ("Doing %s", __func__); GdkWindow *popup_to_kill = args->popup; GtkTreeView *tree_view = args->tree_view; GdkRegion *tn_region = args->thumbnail_region; /* Thumbnail region. */ g_assert (GDK_IS_WINDOW (popup_to_kill)); g_assert (GTK_IS_TREE_VIEW (tree_view)); if ( !gdk_region_point_in (tn_region, (int) event->x, (int) event->y) ) { //g_message ("Clearing popup state!"); gdk_window_destroy (popup_to_kill); /* Disconnect self. */ guint signal_id = g_signal_lookup ("motion-notify-event", GTK_WIDGET_TYPE (tree_view)); guint disconnect_count = g_signal_handlers_disconnect_matched (tree_view, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, signal_id, (GQuark) 0, NULL, maybe_clear_popup_image, args); g_assert (disconnect_count == 1); /* Update the popup process to reflect the current position of the pointer (i.e. deal with the event that got us in this handler. */ update_thumbnail_popup_process (widget, event); /* Unblock the handler for motion events on the files list. */ gulong unblock_count = g_signal_handlers_unblock_by_func (tree_view, files_list_motion_notify_event_handler, NULL); g_assert (unblock_count == 1); } return FALSE; }
CLIP_DLLEXPORT C_widget * _register_widget(ClipMachine * cm, GtkWidget * wid, ClipVar * cv) { int handle = -1; C_widget * cwid = (C_widget*)calloc(1,sizeof(C_widget)); WTypeTable *wt_item; long clip_wtype = GTK_WIDGET_UNKNOWN; cwid->widget = wid; cwid->objtype = GTK_OBJ_WIDGET; cwid->cmachine = cm; cwid->type = wid ? GTK_WIDGET_TYPE(wid) : GTK_TYPE_INVALID; wt_item = _wtype_table_get(cwid->type); if (wt_item && wt_item->fclip_type) clip_wtype = wt_item->fclip_type(); if (wt_item && wt_item->ftype_name) cwid->type_name = wt_item->ftype_name(); cwid->sigenabled = TRUE; cwid->usersigenabled = TRUE; cwid->evntenabled = TRUE; cwid->destroy = NULL; if (cv && cv->t.type == MAP_t) //_clip_mclone(cm, &cwid->obj, cv); cwid->obj = *cv; else _clip_map(cm, &cwid->obj); /* Saving widget info into CLIP state machine * and it`s handle to a map HANDLE property */ handle = _clip_store_c_item(cm, cwid, _C_ITEM_TYPE_WIDGET, NULL); cwid->handle = handle; _clip_mputn(cm, &cwid->obj, HASH_HANDLE, handle); _clip_mputn(cm, &cwid->obj, HASH_TYPE, clip_wtype); /* Store C_widget pointer in list of widgets */ _list_put_cwidget(cm, wid, cwid); //if (wid && GTK_IS_OBJECT(wid)) if (wid && GTK_IS_WIDGET(wid)) g_object_set_data_full(G_OBJECT(wid),"destructor",cwid, (GDestroyNotify)widget_destructor); return cwid; }
static gboolean plKeyReleased( GtkWidget * widget, GdkEventKey * event, gpointer user_data ) { if (event->keyval == GDK_Return) { if ( GTK_WIDGET_TYPE( widget ) == GTK_TYPE_BUTTON ) plButtonReleased( NULL, user_data ); else { switch ( (int) user_data ) { case 0: plButtonReleased( NULL, (void *) 3 ); break; case 1: plButtonReleased( NULL, (void *) 2 ); break; } } } return FALSE; }
/* assign a unique name */ static G_CONST_RETURN gchar * get_widget_name (GtkWidget *w) { const gchar *name; name = gtk_widget_get_name (w); g_return_val_if_fail (name != NULL, NULL); if (strcmp (name, g_type_name (GTK_WIDGET_TYPE (w))) == 0) { static guint d = 0; gchar *n; n = g_strdup_printf ("%s_%u_%u", name, d, g_random_int()); d++; gtk_widget_set_name (w, n); g_free (n); name = gtk_widget_get_name (w); } return name; }
static void update_thumbnail_popup_process (GtkWidget *widget, GdkEventMotion *event) { //g_message ("Doing %s, event = %p", __func__, event); static gboolean witn = FALSE; /* "Was in thumbnail". */ static GtkTreePath *otp = NULL; static GtkTreeViewColumn *otc = NULL; static GTimer *hover_timer = NULL; if ( hover_timer == NULL ) { hover_timer = g_timer_new (); } /* Fos some crazy reason, drawing the popup image changes the result of in_thumbnail (I suspect because gdk is reusing event structures in some strange way). So memorize in_thumbnail up front. */ // Also, this assertion should pass, but doesn't... synthesizing // motion events is apparently a bit harder than I realized. // g_assert (event->type == GDK_MOTION_NOTIFY); //g_message ("event x: %lf, event y: %lf", event->x, event->y); gboolean event_in_thumbnail = in_thumbnail (widget, event); /* Hover time in milliseconds required before a popup image is displayed. */ const gint hover_time = 70; // FIXME: It would be nice to allow popup images of both the input // and output thumbnails, but it requires more hassle keeping track // of where we were, where we are now, etc., so its not going to // happen until someone asks. if ( !witn && in_input_thumbnail (widget, event) ) { witn = TRUE; otp = thumbnail_path (widget, event); g_assert (gtk_tree_path_get_depth (otp) == 1); otc = thumbnail_column (widget, event); g_timer_start (hover_timer); //g_message ("Adding timeout from !with && in_input_thumbnail"); fake_motion_signal_args_t *fmsa = g_new (fake_motion_signal_args_t, 1); fmsa->widget = widget; fmsa->event = event; fmsa->is_valid = TRUE; g_timeout_add (hover_time, (GSourceFunc) emit_fake_motion_signal, fmsa); } if ( witn && in_input_thumbnail (widget, event) ) { //g_message ("in_thumbnail: %d", in_thumbnail (widget, event)); GtkTreePath *ctp = thumbnail_path (widget, event); g_assert (gtk_tree_path_get_depth (ctp) == 1); GtkTreeViewColumn *ctc = thumbnail_column (widget, event); if ( gtk_tree_path_compare (ctp, otp) == 0 && ctc == otc ) { /* Sometimes the timeout handler seems to go off a bit before timer has measured the correct amount of time, so we add a small margin here. */ const gint slop_time = 5; const gint seconds_to_mseconds_factor = 1000; /* If we hover for this long or longer, we should show the popup. */ if ( g_timer_elapsed (hover_timer, NULL) * seconds_to_mseconds_factor >= hover_time - slop_time) { //g_message ("elapsed time: %lf\n", g_timer_elapsed (hover_timer, NULL)); //g_message ("Do popup!!!"); //g_message ("in_thumbnail: %d", in_thumbnail (widget, event)); GdkRegion *tr = thumbnail_region (widget, event); //g_message ("bpw in_thumbnail: %d", in_thumbnail (widget, event)); //g_message ("widget: %p", widget); GdkWindow *popup_window = draw_popup_image (widget, ctp, ctc, tr); //g_message ("apw in_thumbnail: %d", in_thumbnail (widget, event)); //g_message ("widget: %p", widget); /* We don't want continuous redrawing of the popup, so we disable the handler that triggers it until the popup is removed. */ if (popup_window) { guint signal_id = g_signal_lookup ("motion-notify-event", GTK_WIDGET_TYPE (widget)); gulong handler_id = g_signal_handler_find (widget, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, signal_id, (GQuark) 0, NULL, files_list_motion_notify_event_handler, NULL); g_assert (handler_id != 0); g_signal_handler_block (widget, handler_id); /* We want to get rid of the popup window as soon as the user moves the mouse outside of the original thumbnail space. */ maybe_clear_popup_image_args.popup = popup_window; maybe_clear_popup_image_args.tree_view = GTK_TREE_VIEW (widget); if ( maybe_clear_popup_image_args.thumbnail_region != NULL ) { gdk_region_destroy (maybe_clear_popup_image_args.thumbnail_region); } //g_message ("in_thumbnail: %d", in_thumbnail (widget, event)); maybe_clear_popup_image_args.thumbnail_region = tr; g_signal_connect (widget, "motion-notify-event", G_CALLBACK (maybe_clear_popup_image), &maybe_clear_popup_image_args); //g_message ("in_thumbnail: %d", in_thumbnail (widget, event)); } } else { gtk_tree_path_free (ctp); } } else { gtk_tree_path_free (otp); otp = ctp; otc = ctc; g_timer_start (hover_timer); //g_message ("Adding timeout from 'different thumbnails'"); fake_motion_signal_args_t *fmsa = g_new (fake_motion_signal_args_t, 1); fmsa->widget = widget; fmsa->event = event; fmsa->is_valid = TRUE; g_timeout_add (hover_time, (GSourceFunc) emit_fake_motion_signal, fmsa); } } if ( witn && !event_in_thumbnail ) { //g_message ("in_thumbnail: %d", in_thumbnail (widget, event)); //g_message ("Setting witn false"); witn = FALSE; } }
static int _signal_connect(ClipMachine *cm, gboolean after) { C_widget *cwid = _fetch_cw_arg(cm); SignalTable *sig_table = NULL; int ret=-1; CHECKCWID(cwid,GTK_IS_OBJECT); CHECKARG2(2,CHARACTER_t,NUMERIC_t); CHECKARG2(3,PCODE_t,CCODE_t); if (_clip_parinfo(cm,2) == CHARACTER_t) sig_table = _sig_table_by_name(cwid, _clip_parc(cm,2)); else sig_table = _sig_table_by_id(cwid, _clip_parni(cm,2)); if (sig_table && sig_table->sigfunction) { GtkSignalFunc sfunc = sig_table->sigfunction; gchar *signame = sig_table->signame; long sid = sig_table->sigid; int sigfound = gtk_signal_lookup(signame, GTK_WIDGET_TYPE(cwid->widget)); int extra_sigfound = _extra_signal_lookup(signame, GTK_WIDGET_TYPE(cwid->widget)); C_signal *cs = 0; if (sigfound || extra_sigfound || sid < 1000) /* sid<1000 - event */ { if (!cwid->siglist) { cwid->siglist = NEW(C_signal); cs = cwid->siglist; } else { for (cs = cwid->siglist; cs && cs->next; cs = cs->next); cs->next = NEW(C_signal); cs = cs->next; } cs->cw = cwid; cs->signame = sig_table->signame; cs->sigid = sig_table->sigid; _clip_mclone(cm, &cs->cfunc, _clip_spar(cm,3)); } if ( (sid == GTK_BUTTON_PRESS || sid == GTK_2BUTTON_PRESS || sid == GTK_3BUTTON_PRESS)) { //cwid->event_connected = TRUE; if (after) ret = gtk_signal_connect_after(GTK_OBJECT(cwid->widget), "button-press-event",GSF(sfunc),cs); else ret = gtk_signal_connect(GTK_OBJECT(cwid->widget), "button-press-event",GSF(sfunc),cs); } if (sigfound && sid != GTK_BUTTON_PRESS) { if (after) ret = gtk_signal_connect_after(GTK_OBJECT(cwid->widget), signame,GSF(sfunc),cs); else { ret = gtk_signal_connect(GTK_OBJECT(cwid->widget), signame,GSF(sfunc),cs); } } } _clip_retni(cm,ret); return 0; err: _clip_retni(cm,ret); return 1; }
void ui_menu_create(GtkWidget *w, GtkAccelGroup *accel, const char *menu_name, ui_menu_entry_t *list) { static int level = 0; unsigned int i, j; ui_menu_cb_obj *obj = NULL; level++; #ifdef DEBUG_MENUS printf("allocate new: %s\t(%p)\t%s\n", gtk_type_name(GTK_WIDGET_TYPE(w)), w, menu_name); #endif for (i = j = 0; list[i].string; i++) { GtkWidget *new_item = NULL; int do_right_justify = 0; char name[256]; sprintf(name, "MenuItem%d", j); /* ugly... */ switch (*list[i].string) { case '-': /* line */ new_item = gtk_menu_item_new(); break; case '*': /* toggle */ { /* Add this item to the list of calls to perform to update the menu status. */ char *label = make_menu_label(&list[i]); if (list[i].callback) { checkmark_t *cmt; new_item = gtk_check_menu_item_new_with_label(label + 1); cmt = (checkmark_t *)lib_malloc(sizeof(checkmark_t)); cmt->name = lib_stralloc(list[i].string+1); cmt->w = new_item; cmt->cb = list[i].callback; cmt->obj.value = (void*) list[i].callback_data; cmt->obj.status = CB_NORMAL; cmt->handlerid = g_signal_connect(G_OBJECT(new_item),"activate", G_CALLBACK(list[i].callback), (gpointer) &(cmt->obj)); g_signal_connect(G_OBJECT(new_item), "destroy", G_CALLBACK(delete_checkmark_cb), (gpointer) cmt); checkmark_list = g_list_prepend(checkmark_list, cmt); obj = &cmt->obj; } else new_item = gtk_menu_item_new_with_label(label + 1); j++; lib_free(label); break; } case 0: break; default: { char *item, *itemp; item = itemp = make_menu_label(&list[i]); if (strncmp(item, "RJ", 2) == 0) { do_right_justify = 1; item += 2; } new_item = gtk_menu_item_new_with_label(item); if (list[i].callback) { obj = (ui_menu_cb_obj*)lib_malloc(sizeof(ui_menu_cb_obj)); obj->value = (void*) list[i].callback_data; g_signal_connect(G_OBJECT(new_item),"activate", G_CALLBACK(list[i].callback), (gpointer) obj); } lib_free(itemp); j++; } } if (new_item) { gtk_menu_shell_append(GTK_MENU_SHELL(w), new_item); gtk_widget_show(new_item); if (do_right_justify) gtk_menu_item_set_right_justified(GTK_MENU_ITEM(new_item), TRUE); #ifdef DEBUG_MENUS printf("allocate new: %s\t(%p)\t%s\n", gtk_type_name(GTK_WIDGET_TYPE(new_item)), new_item, list[i].string); #endif } if (list[i].sub_menu) { GtkWidget *sub; if (new_item && *list[i].string != '-') { sub = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(new_item),sub); } else { sub = w; } ui_menu_create(sub, accel, list[i].string, list[i].sub_menu); } else { /* no submenu */ if (accel && list[i].hotkey_keysym != KEYSYM_NONE && list[i].callback != NULL && new_item != NULL) add_accelerator(new_item, accel, list[i].hotkey_keysym, list[i].hotkey_modifier); } } level--; }