[PATCH] GtkMenu popup
| From: | Steph | Date: | Thu, 08 Sep 2005 12:51:03 +0000 |
| Subject: | [PATCH] GtkMenu popup | ||
| Groups: | php.gtk.dev | ||
| Request: | Send a blank email to php-gtk-dev+get-1609@lists.php.net to get a copy of this message | ||
Been mucking about with C again.
This works on my box, but I'm not sure how you'll feel about the
implementation Andrei, the lack of technical know-how notwithstanding.
I've made all the parameters optional so you can just call $menu->popup();
in any kind of callback and it'll give the default 'at the mouse pointer'
positioning. The hard part was getting positioning to work at all when it
was given, but it's picking up the user callback properly now (here at
least).
Pls adv,
- Steph
ps Did you come to any decision about making use_underline = true the
default in menuitem/button constructors? I've a small patch for that
sitting here too.
Index: ext/gtk+/gtk.overrides =================================================================== RCS file: /repository/php-gtk/ext/gtk+/gtk.overrides,v retrieving revision 1.116 diff -u -r1.116 gtk.overrides --- ext/gtk+/gtk.overrides 4 Sep 2005 08:16:20 -0000 1.116 +++ ext/gtk+/gtk.overrides 8 Sep 2005 12:41:00 -0000 @@ -948,6 +948,69 @@ } %% }}} +%% {{{ GtkMenu +%% +override gtk_menu_popup +static void php_gtk_menu_position(GtkMenu *menu, int *x, int *y, int *push_in, gpointer data) +{ + phpg_cb_data_t *cbd = (phpg_cb_data_t *) data; + char *callback_name; + zval *retval; + zval ***args = NULL; + TSRMLS_FETCH(); + + if (!zend_is_callable(cbd->callback, 0, &callback_name)) { + php_error(E_WARNING, "unable to call menu position callback '%s' specified in %s on line %d", callback_name, cbd->src_filename, cbd->src_lineno); + efree(callback_name); + return; + } + + call_user_function_ex(EG(function_table), NULL, cbd->callback, &retval, 0, args, 0, NULL TSRMLS_CC); + + if (retval) { + if (Z_TYPE_P(retval) == IS_ARRAY && !php_gtk_parse_args_hash_quiet(retval, "iii", x, y, push_in)) { + php_error(E_WARNING, "unable to parse result of menu position callback"); + } + zval_ptr_dtor(&retval); + } +} + +PHP_METHOD +{ + GtkWidget *pms = NULL, *pmi = NULL; + zval *php_pms = NULL, *php_pmi = NULL; + zval *callback, *extra = NULL; + phpg_cb_data_t *data; + int button = 0, time = 0; + + NOT_STATIC_METHOD(); + + if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "|NNVii", &php_pms, gtkwidget_ce, &php_pmi, gtkwidget_ce, &callback, &button, &time)) { + return; + } + + if (php_pms && Z_TYPE_P(php_pms) != IS_NULL) + pms = GTK_WIDGET(PHPG_GOBJECT(php_pms)); + if (php_pmi && Z_TYPE_P(php_pmi) != IS_NULL) + pmi = GTK_WIDGET(PHPG_GOBJECT(php_pmi)); + if (!time) + time = gtk_get_current_event_time(); + + if (callback && Z_TYPE_P(callback) != IS_NULL) { + + zval_add_ref(&callback); + data = phpg_cb_data_new(callback, extra TSRMLS_CC); + + gtk_menu_popup(GTK_MENU(PHPG_GOBJECT(this_ptr)), pms, pmi, + (GtkMenuPositionFunc)php_gtk_menu_position, data, button, time); + + } else { + + gtk_menu_popup(GTK_MENU(PHPG_GOBJECT(this_ptr)), pms, pmi, NULL, NULL, button, time); + } +} +%% }}} + %% {{{ GtkMessageDialog %% add-arginfo GtkMessageDialog __construct
Index: ext/gtk+/gtk.overrides =================================================================== RCS file: /repository/php-gtk/ext/gtk+/gtk.overrides,v retrieving revision 1.116 diff -u -r1.116 gtk.overrides --- ext/gtk+/gtk.overrides 4 Sep 2005 08:16:20 -0000 1.116 +++ ext/gtk+/gtk.overrides 8 Sep 2005 12:41:00 -0000 @@ -948,6 +948,69 @@ } %% }}} +%% {{{ GtkMenu +%% +override gtk_menu_popup +static void php_gtk_menu_position(GtkMenu *menu, int *x, int *y, int *push_in, gpointer data) +{ + phpg_cb_data_t *cbd = (phpg_cb_data_t *) data; + char *callback_name; + zval *retval; + zval ***args = NULL; + TSRMLS_FETCH(); + + if (!zend_is_callable(cbd->callback, 0, &callback_name)) { + php_error(E_WARNING, "unable to call menu position callback '%s' specified in %s on line %d", callback_name, cbd->src_filename, cbd->src_lineno); + efree(callback_name); + return; + } + + call_user_function_ex(EG(function_table), NULL, cbd->callback, &retval, 0, args, 0, NULL TSRMLS_CC); + + if (retval) { + if (Z_TYPE_P(retval) == IS_ARRAY && !php_gtk_parse_args_hash_quiet(retval, "iii", x, y, push_in)) { + php_error(E_WARNING, "unable to parse result of menu position callback"); + } + zval_ptr_dtor(&retval); + } +} + +PHP_METHOD +{ + GtkWidget *pms = NULL, *pmi = NULL; + zval *php_pms = NULL, *php_pmi = NULL; + zval *callback, *extra = NULL; + phpg_cb_data_t *data; + int button = 0, time = 0; + + NOT_STATIC_METHOD(); + + if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "|NNVii", &php_pms, gtkwidget_ce, &php_pmi, gtkwidget_ce, &callback, &button, &time)) { + return; + } + + if (php_pms && Z_TYPE_P(php_pms) != IS_NULL) + pms = GTK_WIDGET(PHPG_GOBJECT(php_pms)); + if (php_pmi && Z_TYPE_P(php_pmi) != IS_NULL) + pmi = GTK_WIDGET(PHPG_GOBJECT(php_pmi)); + if (!time) + time = gtk_get_current_event_time(); + + if (callback && Z_TYPE_P(callback) != IS_NULL) { + + zval_add_ref(&callback); + data = phpg_cb_data_new(callback, extra TSRMLS_CC); + + gtk_menu_popup(GTK_MENU(PHPG_GOBJECT(this_ptr)), pms, pmi, + (GtkMenuPositionFunc)php_gtk_menu_position, data, button, time); + + } else { + + gtk_menu_popup(GTK_MENU(PHPG_GOBJECT(this_ptr)), pms, pmi, NULL, NULL, button, time); + } +} +%% }}} + %% {{{ GtkMessageDialog %% add-arginfo GtkMessageDialog __construct