static gboolean on_focus_in( GtkWidget *entry, GdkEventFocus* evt, gpointer user_data ) { GtkEntryCompletion* completion = gtk_entry_completion_new(); GtkListStore* list = gtk_list_store_new( N_COLS, G_TYPE_STRING, G_TYPE_STRING ); GtkCellRenderer* render; gtk_entry_completion_set_minimum_key_length( completion, 1 ); gtk_entry_completion_set_model( completion, GTK_TREE_MODEL(list) ); g_object_unref( list ); /* gtk_entry_completion_set_text_column( completion, COL_PATH ); */ // Following line causes GTK3 to show both columns, so skip this and use // custom match-selected handler to insert COL_PATH //g_object_set( completion, "text-column", COL_PATH, NULL ); render = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start( (GtkCellLayout*)completion, render, TRUE ); gtk_cell_layout_add_attribute( (GtkCellLayout*)completion, render, "text", COL_NAME ); //gtk_entry_completion_set_inline_completion( completion, TRUE ); gtk_entry_completion_set_popup_set_width( completion, TRUE ); gtk_entry_set_completion( GTK_ENTRY(entry), completion ); g_signal_connect( G_OBJECT(entry), "changed", G_CALLBACK(on_changed), NULL ); g_signal_connect( G_OBJECT( completion ), "match-selected", G_CALLBACK( on_match_selected ), entry ); g_signal_connect( G_OBJECT( completion ), "insert-prefix", G_CALLBACK( on_insert_prefix ), entry ); g_object_unref( completion ); return FALSE; }
static gboolean on_focus_in( GtkWidget *entry, GdkEventFocus* evt, gpointer user_data ) { GtkEntryCompletion* completion = gtk_entry_completion_new(); GtkListStore* list = gtk_list_store_new( COUNT_COLS, G_TYPE_STRING, G_TYPE_STRING ); GtkCellRenderer* render; gtk_entry_completion_set_minimum_key_length( completion, 1 ); gtk_entry_completion_set_model( completion, GTK_TREE_MODEL(list) ); g_object_unref( list ); // gtk_entry_completion_set_text_column( completion, COL_PATH ); // g_object_set( completion, "text-column", COL_PATH, NULL );VV g_object_set( completion, "text-column", COL_NAME, NULL ); render = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start( (GtkCellLayout*)completion, render, TRUE ); gtk_cell_layout_add_attribute( (GtkCellLayout*)completion, render, "text", COL_NAME ); gtk_entry_completion_set_inline_completion( completion, TRUE ); #if GTK_CHECK_VERSION( 2, 8, 0) // gtk+ prior to 2.8.0 doesn't have this API gtk_entry_completion_set_popup_set_width( completion, TRUE ); #endif gtk_entry_set_completion( GTK_ENTRY(entry), completion ); g_signal_connect( G_OBJECT(entry), "changed", G_CALLBACK(on_changed), NULL ); g_object_unref( completion ); return FALSE; }
static void setup_auto_complete_with_data(ThreadData* data) { GtkListStore* store; GSList *l; GtkEntryCompletion* comp = gtk_entry_completion_new(); gtk_entry_completion_set_minimum_key_length( comp, 2 ); gtk_entry_completion_set_inline_completion( comp, TRUE ); #if GTK_CHECK_VERSION( 2, 8, 0 ) gtk_entry_completion_set_popup_set_width( comp, TRUE ); gtk_entry_completion_set_popup_single_match( comp, FALSE ); #endif store = gtk_list_store_new( 1, G_TYPE_STRING ); for( l = data->files; l; l = l->next ) { const char *name = (const char*)l->data; GtkTreeIter it; gtk_list_store_append( store, &it ); gtk_list_store_set( store, &it, 0, name, -1 ); } gtk_entry_completion_set_model( comp, (GtkTreeModel*)store ); g_object_unref( store ); gtk_entry_completion_set_text_column( comp, 0 ); gtk_entry_set_completion( (GtkEntry*)data->entry, comp ); /* trigger entry completion */ gtk_entry_completion_complete(comp); g_object_unref( comp ); }
static void fm_path_entry_init(FmPathEntry *entry) { FmPathEntryPrivate *priv = FM_PATH_ENTRY_GET_PRIVATE(entry); GtkEntryCompletion* completion = gtk_entry_completion_new(); GtkCellRenderer* render; priv->model = NULL; priv->completion_model = NULL; priv->completion_len = 0; priv->in_change = FALSE; priv->completion = completion; priv->highlight_completion_match = TRUE; priv->common_suffix_append_idle_id = -1; priv->common_suffix[0] = 0; gtk_entry_completion_set_minimum_key_length(completion, 1); gtk_entry_completion_set_match_func(completion, fm_path_entry_match_func, NULL, NULL); g_signal_connect(G_OBJECT(completion), "match-selected", G_CALLBACK(fm_path_entry_match_selected), (gpointer)NULL); g_object_set(completion, "text-column", COL_FILE_NAME, NULL); render = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start( (GtkCellLayout*)completion, render, TRUE ); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(completion), render, fm_path_entry_completion_render_func, entry, NULL); gtk_entry_completion_set_inline_completion(completion, TRUE); gtk_entry_completion_set_popup_set_width(completion, TRUE); g_signal_connect(G_OBJECT(entry), "key-press-event", G_CALLBACK(fm_path_entry_key_press), NULL); gtk_entry_set_completion(GTK_ENTRY(entry), completion); }
static void fm_path_entry_init(FmPathEntry *entry) { FmPathEntryPrivate *priv = FM_PATH_ENTRY_GET_PRIVATE(entry); GtkEntryCompletion* completion = gtk_entry_completion_new(); GtkCellRenderer* render; priv->model = fm_path_entry_model_new(entry); priv->completion = completion; priv->cancellable = g_cancellable_new(); priv->highlight_completion_match = TRUE; gtk_entry_completion_set_minimum_key_length(completion, 1); gtk_entry_completion_set_match_func(completion, fm_path_entry_match_func, NULL, NULL); g_object_set(completion, "text_column", COL_FULL_PATH, NULL); gtk_entry_completion_set_model(completion, priv->model); render = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start( (GtkCellLayout*)completion, render, TRUE ); gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(completion), render, fm_path_entry_completion_render_func, entry, NULL); /* NOTE: this is to avoid a bug of gtk+. * The inline selection provided by GtkEntry is buggy. * If we change the content of the entry, it still stores * the old prefix sometimes so things don't work as expected. * So, unfortunately, we're not able to use this nice feature. * * Please see gtk_entry_completion_key_press() of gtk/gtkentry.c * and look for completion->priv->completion_prefix. */ gtk_entry_completion_set_inline_selection(completion, FALSE); gtk_entry_completion_set_inline_completion(completion, TRUE); gtk_entry_completion_set_popup_set_width(completion, TRUE); /* gtk_entry_completion_set_popup_single_match(completion, FALSE); */ /* connect to these signals rather than overriding default handlers since * we want to invoke our handlers before the default ones provided by Gtk. */ g_signal_connect(entry, "key-press-event", G_CALLBACK(fm_path_entry_key_press), NULL); g_signal_connect(entry, "activate", G_CALLBACK(fm_path_entry_on_activate), NULL); g_signal_connect(entry, "populate-popup", G_CALLBACK(fm_path_entry_populate_popup), NULL); }
static gboolean _lib_tagging_tag_show(GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval, GdkModifierType modifier, dt_lib_module_t* self) { int mouse_over_id = -1; int zoom = dt_conf_get_int("plugins/lighttable/images_in_row"); // the order is: // if(zoom == 1) => currently shown image // else if(selection not empty) => selected images // else if(cursor over image) => hovered image // else => return if(zoom == 1 || dt_collection_get_selected_count(darktable.collection) == 0) { DT_CTL_GET_GLOBAL(mouse_over_id, lib_image_mouse_over_id); if(mouse_over_id < 0) return TRUE; } dt_lib_tagging_t *d = (dt_lib_tagging_t*)self->data; d->floating_tag_imgid = mouse_over_id; gint x, y; gint px, py, w, h; GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkWidget *center = dt_ui_center(darktable.gui->ui); gdk_window_get_origin(gtk_widget_get_window(center), &px, &py); w = gdk_window_get_width(gtk_widget_get_window(center)); h = gdk_window_get_height(gtk_widget_get_window(center)); x = px + 0.5*(w-FLOATING_ENTRY_WIDTH); y = py + h - 50; /* put the floating box at the mouse pointer */ // gint pointerx, pointery; // gtk_widget_get_pointer(center, &pointerx, &pointery); // x = px + pointerx + 1; // y = py + pointery + 1; d->floating_tag_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); /* stackoverflow.com/questions/1925568/how-to-give-keyboard-focus-to-a-pop-up-gtk-window */ gtk_widget_set_can_focus(d->floating_tag_window, TRUE); gtk_window_set_decorated(GTK_WINDOW(d->floating_tag_window), FALSE); gtk_window_set_type_hint(GTK_WINDOW(d->floating_tag_window), GDK_WINDOW_TYPE_HINT_POPUP_MENU); gtk_window_set_transient_for(GTK_WINDOW(d->floating_tag_window), GTK_WINDOW(window)); gtk_window_set_opacity(GTK_WINDOW(d->floating_tag_window), 0.8); gtk_window_move(GTK_WINDOW(d->floating_tag_window), x, y); GtkWidget *entry = gtk_entry_new(); gtk_widget_set_size_request(entry, FLOATING_ENTRY_WIDTH, -1); gtk_widget_add_events(entry, GDK_FOCUS_CHANGE_MASK); GtkEntryCompletion *completion = gtk_entry_completion_new(); gtk_entry_completion_set_model(completion, gtk_tree_view_get_model(GTK_TREE_VIEW(d->related))); gtk_entry_completion_set_text_column(completion, 0); gtk_entry_completion_set_inline_completion(completion, TRUE); gtk_entry_completion_set_popup_set_width(completion, FALSE); gtk_entry_set_completion(GTK_ENTRY(entry), completion); gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1); gtk_container_add(GTK_CONTAINER(d->floating_tag_window), entry); g_signal_connect_swapped(entry, "focus-out-event", G_CALLBACK(gtk_widget_destroy), d->floating_tag_window); g_signal_connect(entry, "key-press-event", G_CALLBACK(_lib_tagging_tag_key_press), self); gtk_widget_show_all(d->floating_tag_window); gtk_widget_grab_focus(entry); gtk_window_present(GTK_WINDOW(d->floating_tag_window)); return TRUE; }
GtkWidget* create_tool_item( GtkAction* action ) { GtkWidget* item = 0; if ( IS_EGE_SELECT_ONE_ACTION(action) && EGE_SELECT_ONE_ACTION(action)->private_data->model ) { EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(action); item = GTK_WIDGET( gtk_tool_item_new() ); if ( act->private_data->appearanceMode == APPEARANCE_FULL ) { #if GTK_CHECK_VERSION(3,0,0) GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(holder), FALSE); #else GtkWidget* holder = gtk_hbox_new( FALSE, 0 ); #endif GtkRadioAction* ract = 0; GSList* group = 0; GtkTreeIter iter; gboolean valid = FALSE; gint index = 0; { gchar* sss = 0; g_object_get( G_OBJECT(action), "short_label", &sss, NULL ); // If short_label not defined, g_object_get will return label. // This hack allows a label to be used with a drop-down menu when // no label is used with a set of icons that are self-explanatory. if (sss && strcmp( sss, "NotUsed" ) != 0 ) { GtkWidget* lbl = gtk_label_new(sss); gtk_box_pack_start( GTK_BOX(holder), lbl, FALSE, FALSE, 4 ); } g_free( sss ); sss = 0; } valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter ); while ( valid ) { gchar* str = 0; gchar* tip = 0; gchar* iconId = 0; gboolean sens = true; /* gint size = 0; */ gtk_tree_model_get( act->private_data->model, &iter, act->private_data->labelColumn, &str, -1 ); if ( act->private_data->iconColumn >= 0 ) { gtk_tree_model_get( act->private_data->model, &iter, act->private_data->iconColumn, &iconId, -1 ); } if ( act->private_data->tooltipColumn >= 0 ) { gtk_tree_model_get( act->private_data->model, &iter, act->private_data->tooltipColumn, &tip, -1 ); } if ( act->private_data->sensitiveColumn >= 0 ) { gtk_tree_model_get( act->private_data->model, &iter, act->private_data->sensitiveColumn, &sens, -1 ); } if ( act->private_data->radioActionType ) { void* obj = g_object_new( act->private_data->radioActionType, "name", "Name 1", "label", str, "tooltip", tip, "value", index, /* "iconId", iconId, "iconSize", size, */ NULL ); if ( iconId ) { g_object_set( G_OBJECT(obj), act->private_data->iconProperty, iconId, NULL ); } if ( act->private_data->iconProperty ) { /* TODO get this string to be set instead of hardcoded */ if ( act->private_data->iconSize >= 0 ) { g_object_set( G_OBJECT(obj), "iconSize", act->private_data->iconSize, NULL ); } } ract = GTK_RADIO_ACTION(obj); } else { ract = gtk_radio_action_new( "Name 1", str, tip, iconId, index ); } if ( act->private_data->sensitiveColumn >= 0 ) { gtk_action_set_sensitive( GTK_ACTION(ract), sens ); } gtk_radio_action_set_group( ract, group ); group = gtk_radio_action_get_group( ract ); if ( index == act->private_data->active ) { gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(ract), TRUE ); } g_signal_connect( G_OBJECT(ract), "changed", G_CALLBACK( proxy_action_chagned_cb ), act ); GtkWidget* sub = gtk_action_create_tool_item( GTK_ACTION(ract) ); gtk_activatable_set_related_action( GTK_ACTIVATABLE (sub), GTK_ACTION(ract) ); gtk_tool_item_set_tooltip_text( GTK_TOOL_ITEM(sub), tip ); gtk_box_pack_start( GTK_BOX(holder), sub, FALSE, FALSE, 0 ); g_free( str ); g_free( tip ); g_free( iconId ); index++; valid = gtk_tree_model_iter_next( act->private_data->model, &iter ); } g_object_set_data( G_OBJECT(holder), "ege-proxy_action-group", group ); gtk_container_add( GTK_CONTAINER(item), holder ); } else { #if GTK_CHECK_VERSION(3,0,0) GtkWidget* holder = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); gtk_box_set_homogeneous(GTK_BOX(holder), FALSE); #else GtkWidget *holder = gtk_hbox_new( FALSE, 4 ); #endif GtkEntry *entry = 0; GtkWidget *normal; if (act->private_data->selectionMode == SELECTION_OPEN) { normal = gtk_combo_box_new_with_model_and_entry (act->private_data->model); gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (normal), act->private_data->labelColumn); GtkWidget *child = gtk_bin_get_child( GTK_BIN(normal) ); if (GTK_IS_ENTRY(child)) { int maxUsed = scan_max_width( act->private_data->model, act->private_data->labelColumn ); GtkEntryCompletion *complete = 0; entry = GTK_ENTRY(child); gtk_entry_set_width_chars(entry, maxUsed); /* replace with property */ complete = gtk_entry_completion_new(); gtk_entry_completion_set_model( complete, act->private_data->model ); gtk_entry_completion_set_text_column( complete, act->private_data->labelColumn ); gtk_entry_completion_set_inline_completion( complete, FALSE ); gtk_entry_completion_set_inline_selection( complete, FALSE ); gtk_entry_completion_set_popup_completion( complete, TRUE ); gtk_entry_completion_set_popup_set_width( complete, FALSE ); gtk_entry_set_completion( entry, complete ); g_signal_connect( G_OBJECT(child), "activate", G_CALLBACK(combo_entry_changed_cb), act ); g_signal_connect( G_OBJECT(child), "focus-out-event", G_CALLBACK(combo_entry_focus_lost_cb), act ); } } else { GtkCellRenderer * renderer = NULL; normal = gtk_combo_box_new_with_model( act->private_data->model ); if ( act->private_data->iconColumn >= 0 ) { renderer = gtk_cell_renderer_pixbuf_new(); gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE ); /* "icon-name" */ gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(normal), renderer, "stock-id", act->private_data->iconColumn ); } renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE ); gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(normal), renderer, "text", act->private_data->labelColumn ); } gtk_combo_box_set_active( GTK_COMBO_BOX(normal), act->private_data->active ); if ( entry && (act->private_data->active == -1) ) { gtk_entry_set_text( entry, act->private_data->activeText ); } g_signal_connect( G_OBJECT(normal), "changed", G_CALLBACK(combo_changed_cb), action ); g_object_set_data( G_OBJECT(holder), "ege-combo-box", normal ); g_object_set_data( G_OBJECT(act), "ege-combo-box", normal ); if (act->private_data->appearanceMode == APPEARANCE_COMPACT) { gchar* sss = 0; g_object_get( G_OBJECT(action), "short_label", &sss, NULL ); if (sss) { GtkWidget* lbl = gtk_label_new(sss); gtk_box_pack_start( GTK_BOX(holder), lbl, FALSE, FALSE, 4 ); g_free( sss ); sss = 0; } } gtk_box_pack_start( GTK_BOX(holder), normal, FALSE, FALSE, 0 ); { #if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_halign(holder, GTK_ALIGN_START); gtk_container_add(GTK_CONTAINER(item), holder); #else GtkWidget *align = gtk_alignment_new(0, 0.5, 0, 0); gtk_container_add( GTK_CONTAINER(align), holder); gtk_container_add( GTK_CONTAINER(item), align ); #endif } } gtk_widget_show_all( item ); } else { item = GTK_ACTION_CLASS(ege_select_one_action_parent_class)->create_tool_item( action ); } return item; }