How to Center Dialogs or Popups Over Any Widget (Source Code Included)
- From: Paul Serice <serice bigfoot com>
- To: gtk-app-devel Mailing List <gtk-app-devel-list gnome org>
- Subject: How to Center Dialogs or Popups Over Any Widget (Source Code Included)
- Date: Thu, 14 Sep 2000 14:48:42 -0500
/*
* One of my biggest complaints about Gtk+-based programs is that
* popups never popup centered over the correct window. At best they
* come up in the middle of the display or over the mouse. More
* commonly, they quietly come up in some random location on the
* display.
*
* The correct way, IMHO, to popup a dialog is to place it in the
* center of the window responsible for popping it. The fact that it
* is centered over the window tells me that, yes, this pop up is part
* of the program underneath it. When a dialog popups up over a
* different program, it is confusing because the program underneath
* the popup has no relationship with the popup itself.
*
* What follows is an example of how to popup a dialog centered over
* any widget including a GTK_WINDOW widget. It also shows how to
* raise an iconified popup to the same place where it was originally
* iconified.
*
* If you find a better way of doing this, please let me know.
*
* Paul Serice
* September 13, 2000
*/
#include <gtk/gtk.h>
static gint dialog_delete_cb(GtkWidget *w, GdkEventAny *data)
{
gtk_widget_hide(w);
return 1;
}
static GtkWidget* dialog_instance()
{
static GtkWidget* dialog = 0;
if( dialog == 0 ) {
dialog = gtk_dialog_new();
if( dialog ) {
gtk_widget_set_usize(dialog, 100, 100);
gtk_signal_connect(GTK_OBJECT(dialog),
"delete_event",
GTK_SIGNAL_FUNC(dialog_delete_cb),
NULL);
gtk_widget_realize(dialog); /* gdk_window_get_size() needs a window */
}
}
return dialog;
}
static void window_manager_decides_cb(GtkWidget *w, gpointer data)
{
GtkWidget *dialog;
dialog = dialog_instance();
if( dialog ) {
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_NONE);
gtk_widget_show(dialog);
/*
* Either I'm not doing something right or I'm not thinking about
* something right or . . . , but it seems to me that
* "gtk_widget_show()" should raise iconified windows. It does
* not. So, we have to also call gdk_window_show().
*/
gdk_window_show(dialog->window);
}
}
static void center_over_display_cb(GtkWidget *w, gpointer data)
{
GtkWidget *dialog;
dialog = dialog_instance();
if( dialog ) {
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
gtk_widget_show(dialog);
/* See note in window_manager_decides_cb(). */
gdk_window_show(dialog->window);
}
}
static void center_over_pointer_cb(GtkWidget *w, gpointer data)
{
GtkWidget *dialog;
dialog = dialog_instance();
if( dialog ) {
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
gtk_widget_show(dialog);
/* See note in window_manager_decides_cb(). */
gdk_window_show(dialog->window);
}
}
static void center_over_widget_cb(GtkWidget* w, gpointer data)
{
GtkWidget *dialog;
GtkWidget *target = GTK_WIDGET(data);
dialog = dialog_instance();
if( dialog ) {
if( !GTK_WIDGET_MAPPED(dialog) ) {
int x, y, w, h; /* target's relevant dimensions */
int dw, dh; /* popup's relevant dimensions */
int centerX, centerY; /* popup's x and y so that it appears centered */
gdk_window_get_origin(target->window, &x, &y);
gdk_window_get_size(target->window, &w, &h);
gdk_window_get_size(dialog->window, &dw, &dh);
centerX = x + w/2 - dw/2;
centerY = y + h/2 - dh/2;
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_NONE);
gtk_widget_set_uposition(dialog, centerX, centerY);
gtk_widget_show(dialog);
}
/* See note in window_manager_decides_cb(). */
gdk_window_show(dialog->window);
}
}
static void destroy_cb (GtkWidget *w, gpointer data)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
GtkWidget *win;
GtkWidget *mainBox;
GtkWidget *leftBox; /* spacer */
GtkWidget *rightBox; /* spacer */
GtkWidget *topBox; /* spacer */
GtkWidget *bottomBox; /* spacer */
GtkWidget *centralBox;
GtkWidget *eventBox;
GtkWidget *label;
GtkWidget *window_manager_decides_button = 0;
GtkWidget *center_over_display_button = 0;
GtkWidget *center_over_pointer_button = 0;
GtkWidget *center_over_widget_button = 0;
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize(win, 480, 360);
gtk_signal_connect(GTK_OBJECT(win),
"destroy",
GTK_SIGNAL_FUNC(destroy_cb),
NULL);
mainBox = gtk_hbox_new( /* homogeneous */ FALSE, /* spacing */ 0);
leftBox = gtk_vbox_new( /* homogeneous */ FALSE, /* spacing */ 0);
rightBox = gtk_vbox_new( /* homogeneous */ FALSE, /* spacing */ 0);
topBox = gtk_vbox_new( /* homogeneous */ FALSE, /* spacing */ 0);
bottomBox = gtk_vbox_new( /* homogeneous */ FALSE, /* spacing */ 0);
centralBox = gtk_vbox_new( /* homogeneous */ FALSE, /* spacing */ 0);
/*
* Place "label" in an event box so that a GdkWindow will be
* associated with the label.
*/
eventBox = gtk_event_box_new();
label = gtk_label_new("Center over me");
gtk_container_add(GTK_CONTAINER(eventBox), label);
/*
* Install the control buttons.
*/
window_manager_decides_button
= gtk_button_new_with_label("Window Manager Decides");
gtk_signal_connect(GTK_OBJECT(window_manager_decides_button),
"clicked",
GTK_SIGNAL_FUNC(window_manager_decides_cb),
NULL);
center_over_display_button
= gtk_button_new_with_label("Center Over Display");
gtk_signal_connect(GTK_OBJECT(center_over_display_button),
"clicked",
GTK_SIGNAL_FUNC(center_over_display_cb),
NULL);
center_over_pointer_button
= gtk_button_new_with_label("Center Over Pointer");
gtk_signal_connect(GTK_OBJECT(center_over_pointer_button),
"clicked",
GTK_SIGNAL_FUNC(center_over_pointer_cb),
NULL);
/*
* Generally, you will pass in a top-level window as client data.
* This will let your popup appear centered over the window. In
* this example, I'm passing in a label just to show that it does
* work with any GtkWidget.
*/
center_over_widget_button
= gtk_button_new_with_label("Center Over Widget");
gtk_signal_connect(GTK_OBJECT(center_over_widget_button),
"clicked",
GTK_SIGNAL_FUNC(center_over_widget_cb),
eventBox);
/*
* Pack.
*/
gtk_box_pack_start(GTK_BOX(centralBox), topBox,
/* expand */ TRUE, /* fill */ TRUE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(centralBox), window_manager_decides_button,
/* expand */ FALSE, /* fill */ FALSE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(centralBox), center_over_display_button,
/* expand */ FALSE, /* fill */ FALSE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(centralBox), center_over_pointer_button,
/* expand */ FALSE, /* fill */ FALSE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(centralBox), center_over_widget_button,
/* expand */ FALSE, /* fill */ FALSE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(centralBox), bottomBox,
/* expand */ TRUE, /* fill */ TRUE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(centralBox), eventBox,
/* expand */ FALSE, /* fill */ FALSE, /* padding */ 12);
gtk_box_pack_start(GTK_BOX(mainBox), leftBox,
/* expand */ TRUE, /* fill */ TRUE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(mainBox), centralBox,
/* expand */ FALSE, /* fill */ FALSE, /* padding */ 0);
gtk_box_pack_start(GTK_BOX(mainBox), rightBox,
/* expand */ TRUE, /* fill */ TRUE, /* padding */ 0);
/*
* Add.
*/
gtk_container_add(GTK_CONTAINER(win), mainBox);
/*
* Show.
*/
gtk_widget_show(window_manager_decides_button);
gtk_widget_show(center_over_display_button);
gtk_widget_show(center_over_pointer_button);
gtk_widget_show(center_over_widget_button);
gtk_widget_show(label);
gtk_widget_show(eventBox);
gtk_widget_show(bottomBox);
gtk_widget_show(topBox);
gtk_widget_show(centralBox);
gtk_widget_show(rightBox);
gtk_widget_show(leftBox);
gtk_widget_show(mainBox);
gtk_widget_show(win);
gtk_main();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]