#include <gtk/gtk.h>
#include <stdbool.h>
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;
}