#include #include bool on_button_clicked(GtkWidget *button, gpointer data); static bool on_cell_renderer_text_editing_started( GtkCellRenderer *renderer, GtkCellEditable *editable, gchar *path, gpointer data); int main(int argc, char *argv[]) { gtk_init(&argc, &argv); // Creating entry GtkWidget *entry = gtk_entry_new(); GtkWidget *open_button = gtk_button_new_with_mnemonic("_Open"); g_signal_connect(G_OBJECT(open_button), "clicked", G_CALLBACK(on_button_clicked), entry); // Creating tree view stuff GtkListStore *store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING); GtkWidget *tree_view = gtk_tree_view_new(); gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(store)); // Creating columns GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view), -1, "Number", gtk_cell_renderer_text_new(), "text", 0, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view), -1, "Right", renderer, "text", 1, NULL); g_object_set(G_OBJECT(renderer), "editable", true, NULL); // Populating models GtkTreeIter iter; gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, 42, 1, "right 1", -1); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, 13, 1, "right 2", -1); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, 9, 1, "right 3", -1); // Callback for editing text g_signal_connect( G_OBJECT(renderer), "editing-started", G_CALLBACK(on_cell_renderer_text_editing_started), NULL); // Packing together GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL), *hbox = gtk_hbox_new(false, 0), *vbox = gtk_vbox_new(false, 0); gtk_container_add(GTK_CONTAINER(hbox), entry); gtk_container_add(GTK_CONTAINER(hbox), open_button); gtk_container_add(GTK_CONTAINER(vbox), hbox); gtk_container_add(GTK_CONTAINER(vbox), tree_view); gtk_container_add(GTK_CONTAINER(window), vbox); gtk_widget_show_all(window); gtk_main(); return 0; } bool on_button_clicked(GtkWidget *button, gpointer data) { GtkWidget *entry = data, *subwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL), *sublabel = gtk_label_new("This is a rather long message\n" "with many lines whose mere purpose is\n" "to test some stuff. It will appear in \n" "the RIGHT PLACE."); gtk_container_add(GTK_CONTAINER(subwindow), sublabel); gtk_window_set_decorated(GTK_WINDOW(subwindow), FALSE); gtk_window_set_modal(GTK_WINDOW(subwindow), TRUE); GtkWidget *window = gtk_widget_get_toplevel(entry); gtk_window_set_transient_for( GTK_WINDOW(subwindow), GTK_WINDOW(window)); gint dx, dy; gtk_window_get_position(GTK_WINDOW(window), &dx, &dy); GtkAllocation allocation; gtk_widget_get_allocation(entry, &allocation); gtk_window_move( GTK_WINDOW(subwindow), allocation.x+dx, allocation.y+allocation.height*2+dy); gtk_widget_show_all(subwindow); return false; } static bool on_cell_renderer_text_editing_started( GtkCellRenderer *renderer, GtkCellEditable *editable, gchar *path, gpointer data) { GtkWidget *subwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL), *sublabel = gtk_label_new("This is a rather long message\n" "with many lines whose mere purpose is\n" "to test some stuff. It will appear in\n" "the WRONG PLACE!"); gtk_container_add(GTK_CONTAINER(subwindow), sublabel); gtk_window_set_decorated(GTK_WINDOW(subwindow), FALSE); gtk_window_set_modal(GTK_WINDOW(subwindow), TRUE); GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(editable)); gtk_window_set_transient_for( GTK_WINDOW(subwindow), GTK_WINDOW(window)); gint dx, dy; gtk_window_get_position(GTK_WINDOW(window), &dx, &dy); GtkAllocation allocation; gtk_widget_get_allocation(GTK_WIDGET(editable), &allocation); gtk_window_move( GTK_WINDOW(subwindow), allocation.x+dx, allocation.y+allocation.height*2+dy); gtk_widget_show_all(subwindow); return false; }