diff options
Diffstat (limited to 'src/gtk-info-popup.gob')
-rw-r--r-- | src/gtk-info-popup.gob | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/src/gtk-info-popup.gob b/src/gtk-info-popup.gob new file mode 100644 index 0000000..914647a --- /dev/null +++ b/src/gtk-info-popup.gob @@ -0,0 +1,165 @@ +requires 2.0.16 + +%privateheader{ +#include <gdk/gdk.h> +%} + +%h{ +#include <gtk/gtk.h> +%} + +enum GTK_INFO_POPUP { + PLAIN, + FILE, + DIRECTORY +} Gtk:Info:Popup:Entry:Type; + +class Gtk:Info:Popup from Gtk:Window { + private GtkWidget *parent; + + init(self) + { + GtkWidget *vbox; + + //gtk_window_set_gravity(GTK_WINDOW(self), GDK_GRAVITY_SOUTH_WEST); + gtk_container_set_border_width(GTK_CONTAINER(self), 10); + + vbox = gtk_vbox_new(FALSE, 5); + gtk_container_set_resize_mode(GTK_CONTAINER(vbox), GTK_RESIZE_PARENT); + gtk_container_add(GTK_CONTAINER(self), vbox); + gtk_widget_show(vbox); + } + + public GtkWidget * + new(Gtk:Widget *parent) + { + Self *widget; + GtkWidget *toplevel; + + widget = GET_NEW_VARG("type", GTK_WINDOW_POPUP, NULL); + widget->_priv->parent = parent; + + g_signal_connect(parent, "size-allocate", + G_CALLBACK(self_size_allocate_cb), widget); + toplevel = gtk_widget_get_toplevel(parent); + g_signal_connect(toplevel, "configure-event", + G_CALLBACK(self_configure_cb), widget); + + return GTK_WIDGET(widget); + } + + private void + position(self) + { + GdkWindow *window = gtk_widget_get_window(self->_priv->parent); + gint x, y; + gint w, h; + + if (!window) + return; + + gdk_window_get_origin(window, &x, &y); + gtk_window_get_size(GTK_WINDOW(self), &w, &h); + + gtk_window_move(GTK_WINDOW(self), x, y - h); + } + + private void + size_allocate_cb(Gtk:Widget *parent, + Gtk:Allocation *alloc, gpointer user_data) + { + self_position(SELF(user_data)); + } + + private gboolean + configure_cb(Gtk:Widget *toplevel, + Gdk:Event:Configure *event, gpointer user_data) + { + self_position(SELF(user_data)); + return FALSE; + } + + override (Gtk:Widget) void + show(Gtk:Widget *self) + { + GtkRequisition req; + + gtk_widget_size_request(self, &req); + gtk_window_resize(GTK_WINDOW(self), req.width, req.height); + self_position(SELF(self)); + + PARENT_HANDLER(self); + } + + public void + add(self, Gtk:Info:Popup:Entry:Type type, + const gchar *name, gboolean highlight) + { + static const gchar *type2stock[] = { + [GTK_INFO_POPUP_PLAIN] = NULL, + [GTK_INFO_POPUP_FILE] = GTK_STOCK_FILE, + [GTK_INFO_POPUP_DIRECTORY] = GTK_STOCK_DIRECTORY + }; + + GtkWidget *vbox = gtk_bin_get_child(GTK_BIN(self)); + GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(self)); + GtkRequisition req; + + GtkWidget *hbox; + GtkWidget *label; + gchar *markup; + + gtk_widget_size_request(GTK_WIDGET(self), &req); + if (req.height > gdk_screen_get_height(screen)) + return; + + hbox = gtk_hbox_new(FALSE, 5); + + if (type2stock[type]) { + GtkWidget *image; + + image = gtk_image_new_from_stock(type2stock[type], + GTK_ICON_SIZE_MENU); + gtk_box_pack_start(GTK_BOX(hbox), image, + FALSE, FALSE, 0); + } + + /* + * FIXME: setting Pango attributes directly would be + * much more efficient + */ + label = gtk_label_new(NULL); + markup = g_markup_printf_escaped("<span weight=\"%s\">%s</span>", + highlight ? "bold" : "normal", + name); + gtk_label_set_markup(GTK_LABEL(label), markup); + g_free(markup); + gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); + + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show_all(hbox); + + gtk_widget_size_request(GTK_WIDGET(self), &req); + if (req.height > gdk_screen_get_height(screen)) { + label = gtk_label_new("..."); + gtk_box_pack_start(GTK_BOX(vbox), label, + FALSE, FALSE, 0); + gtk_widget_show(label); + } + } + + public void + clear(self) + { + GtkWidget *vbox = gtk_bin_get_child(GTK_BIN(self)); + GList *children; + + children = gtk_container_get_children(GTK_CONTAINER(vbox)); + for (GList *cur = g_list_first(children); + cur != NULL; + cur = g_list_next(cur)) + gtk_widget_destroy(GTK_WIDGET(cur->data)); + g_list_free(children); + } +} |