[PATCH] GtkMenu::popup() - final version
| From: | Steph | Date: | Sat, 10 Sep 2005 18:34:27 +0000 |
| Subject: | [PATCH] GtkMenu::popup() - final version | ||
| Groups: | php.gtk.dev | ||
| Request: | Send a blank email to php-gtk-dev+get-1618@lists.php.net to get a copy of this message | ||
Andrei -
OK, ignore my last list email, I think I'd been eating too many jungle-beans
or something. Got my head around it now, everything's working as
advertised, patch attached.
The only vaguely controversial part's the error message. I output an extra
line of info because, although there's already an E_WARNING thrown from
php_gtk_parse_varargs() at that point, it's not particularly helpful given
the context. That aside, I'd happily commit this version - just thought I'd
better ask first.
You can _not_ call php_gtk_hash_as_array_offset() with an offset of 0, and
it's probably better not to try :) Mini-patch to throw an internal error
there is also attached, 'cos it had me confused for hours.
If GtkTreeView::insert_column_with_data_func() causes any problems, it might
be worth looking again at that hash_as_array_offset function - I don't
really want to unfocus right now.
- Steph
Index: main/php_gtk_util.c =================================================================== RCS file: /repository/php-gtk/main/php_gtk_util.c,v retrieving revision 1.47 diff -u -r1.47 php_gtk_util.c --- main/php_gtk_util.c 2 Sep 2005 09:16:54 -0000 1.47 +++ main/php_gtk_util.c 10 Sep 2005 18:10:10 -0000 @@ -763,6 +763,8 @@ int argc = 0; zval ***values; + g_assert(offset > 0); + if (hash) argc = zend_hash_num_elements(Z_ARRVAL_P(hash)); values = (zval ***)emalloc(argc + offset * sizeof(zval **)); Index: ext/gtk+/gtk.overrides =================================================================== RCS file: /repository/php-gtk/ext/gtk+/gtk.overrides,v retrieving revision 1.119 diff -u -r1.119 gtk.overrides --- ext/gtk+/gtk.overrides 9 Sep 2005 11:02:47 -0000 1.119 +++ ext/gtk+/gtk.overrides 10 Sep 2005 16:00:48 -0000 @@ -925,6 +925,88 @@ } %% }}} +%% {{{ 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 = NULL; + zval ***args = NULL; + int n_args = 0; + 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; + } + + if (cbd->user_args) { + args = php_gtk_hash_as_array(cbd->user_args); + n_args = zend_hash_num_elements(Z_ARRVAL_P(cbd->user_args)); + } + + call_user_function_ex(EG(function_table), NULL, cbd->callback, &retval, n_args, args, 0, NULL TSRMLS_CC); + + if (retval) { + if (Z_TYPE_P(retval) == IS_ARRAY && !php_gtk_parse_args_hash_quiet(retval, "ii|b", x, y, push_in)) { + php_error(E_WARNING, "unable to parse result of menu position callback"); + } + zval_ptr_dtor(&retval); + } + + if (args) { + efree(args); + } + + efree(callback_name); +} + +PHP_METHOD +{ + GtkWidget *pms = NULL, *pmi = NULL; + zval *php_pms = NULL, *php_pmi = NULL; + zval *callback = NULL, *user_args = NULL; + int button = 0, time = 0; + phpg_cb_data_t *data; + + NOT_STATIC_METHOD(); + + if (ZEND_NUM_ARGS() > 2) { + if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), 5, &user_args, "NNVii", &php_pms, gtkwidget_ce, &php_pmi, gtkwidget_ce, &callback, &button, &time)) { + fprintf(stderr, "- At least 5 arguments are required when a menu position callback is used.\n"); + return; + } + } else { + if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "|NN", &php_pms, gtkwidget_ce, &php_pmi, gtkwidget_ce)) { + 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, user_args 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: main/php_gtk_util.c =================================================================== RCS file: /repository/php-gtk/main/php_gtk_util.c,v retrieving revision 1.47 diff -u -r1.47 php_gtk_util.c --- main/php_gtk_util.c 2 Sep 2005 09:16:54 -0000 1.47 +++ main/php_gtk_util.c 10 Sep 2005 18:10:10 -0000 @@ -763,6 +763,8 @@ int argc = 0; zval ***values; + g_assert(offset > 0); + if (hash) argc = zend_hash_num_elements(Z_ARRVAL_P(hash)); values = (zval ***)emalloc(argc + offset * sizeof(zval **)); Index: ext/gtk+/gtk.overrides =================================================================== RCS file: /repository/php-gtk/ext/gtk+/gtk.overrides,v retrieving revision 1.119 diff -u -r1.119 gtk.overrides --- ext/gtk+/gtk.overrides 9 Sep 2005 11:02:47 -0000 1.119 +++ ext/gtk+/gtk.overrides 10 Sep 2005 16:00:48 -0000 @@ -925,6 +925,88 @@ } %% }}} +%% {{{ 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 = NULL; + zval ***args = NULL; + int n_args = 0; + 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; + } + + if (cbd->user_args) { + args = php_gtk_hash_as_array(cbd->user_args); + n_args = zend_hash_num_elements(Z_ARRVAL_P(cbd->user_args)); + } + + call_user_function_ex(EG(function_table), NULL, cbd->callback, &retval, n_args, args, 0, NULL TSRMLS_CC); + + if (retval) { + if (Z_TYPE_P(retval) == IS_ARRAY && !php_gtk_parse_args_hash_quiet(retval, "ii|b", x, y, push_in)) { + php_error(E_WARNING, "unable to parse result of menu position callback"); + } + zval_ptr_dtor(&retval); + } + + if (args) { + efree(args); + } + + efree(callback_name); +} + +PHP_METHOD +{ + GtkWidget *pms = NULL, *pmi = NULL; + zval *php_pms = NULL, *php_pmi = NULL; + zval *callback = NULL, *user_args = NULL; + int button = 0, time = 0; + phpg_cb_data_t *data; + + NOT_STATIC_METHOD(); + + if (ZEND_NUM_ARGS() > 2) { + if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), 5, &user_args, "NNVii", &php_pms, gtkwidget_ce, &php_pmi, gtkwidget_ce, &callback, &button, &time)) { + fprintf(stderr, "- At least 5 arguments are required when a menu position callback is used.\n"); + return; + } + } else { + if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "|NN", &php_pms, gtkwidget_ce, &php_pmi, gtkwidget_ce)) { + 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, user_args 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