Beispiel #1
0
void ui_menu_create(GtkWidget *w, GtkAccelGroup *accel, const char *menu_name, ui_menu_entry_t *list)
{
    static int level = 0;
    unsigned int i, j;
    ui_menu_cb_obj *obj = NULL;

    level++;

#ifdef DEBUG_MENUS
    printf("allocate new: %s\t(%p)\t%s\n",
	   gtk_type_name(GTK_WIDGET_TYPE(w)), w,
	   menu_name);
#endif

        for (i = j = 0; list[i].string; i++) {
            GtkWidget *new_item = NULL;
            int do_right_justify = 0;

            char name[256];

            sprintf(name, "MenuItem%d", j);	/* ugly... */
            switch (*list[i].string) 
	    {
	    case '-':		/* line */
		new_item  = gtk_menu_item_new();
                break;
	    case '*':		/* toggle */
	    {
		/* Add this item to the list of calls to perform to update the
		   menu status. */
                char *label = make_menu_label(&list[i]);
		if (list[i].callback) 
		{
		    checkmark_t *cmt;
		    new_item = gtk_check_menu_item_new_with_label(label + 1);
		    
		    cmt = (checkmark_t *)lib_malloc(sizeof(checkmark_t));
		    cmt->name = lib_stralloc(list[i].string+1);
		    cmt->w = new_item;
		    cmt->cb = list[i].callback;
		    cmt->obj.value = (void*) list[i].callback_data;
		    cmt->obj.status = CB_NORMAL;
		    cmt->handlerid = 
			g_signal_connect(G_OBJECT(new_item),"activate",
					 G_CALLBACK(list[i].callback),
					 (gpointer) &(cmt->obj)); 
		    g_signal_connect(G_OBJECT(new_item), "destroy",
				     G_CALLBACK(delete_checkmark_cb),
				     (gpointer) cmt);
		    checkmark_list = g_list_prepend(checkmark_list, cmt);
		    obj = &cmt->obj;
		} 
		else 
		    new_item = gtk_menu_item_new_with_label(label + 1);

		j++;
		lib_free(label);
		break;
	    }
            case 0:
                break;
	    default:
	    {
		char *item, *itemp;
		item = itemp = make_menu_label(&list[i]);
                if (strncmp(item, "RJ", 2) == 0)
                {
                    do_right_justify = 1;
                    item += 2;
                }

		new_item = gtk_menu_item_new_with_label(item);
		if (list[i].callback) {
		    obj = (ui_menu_cb_obj*)lib_malloc(sizeof(ui_menu_cb_obj));
		    obj->value = (void*) list[i].callback_data;
		    
		    g_signal_connect(G_OBJECT(new_item),"activate",
				     G_CALLBACK(list[i].callback),
				     (gpointer) obj); 
		}
		lib_free(itemp);
		j++;
	    }
            }

            if (new_item)
            {
	        gtk_menu_shell_append(GTK_MENU_SHELL(w), new_item);
	        gtk_widget_show(new_item);
                if (do_right_justify)
                    gtk_menu_item_set_right_justified(GTK_MENU_ITEM(new_item), TRUE);
#ifdef DEBUG_MENUS
	    printf("allocate new: %s\t(%p)\t%s\n",
		   gtk_type_name(GTK_WIDGET_TYPE(new_item)), new_item,
		   list[i].string);
#endif
            }

            if (list[i].sub_menu) 
	    {
                GtkWidget *sub;
                if (new_item && *list[i].string != '-')
                {
                    sub = gtk_menu_new();
		    gtk_menu_item_set_submenu(GTK_MENU_ITEM(new_item),sub);
                }
                else
                {
                    sub = w;
                }
		ui_menu_create(sub, accel, list[i].string, 
				     list[i].sub_menu);
            } 
	    else 
	    {            /* no submenu */
	        if (accel && list[i].hotkey_keysym != KEYSYM_NONE
		    && list[i].callback != NULL && new_item != NULL)
                    add_accelerator(new_item,
                               accel, list[i].hotkey_keysym,
                               list[i].hotkey_modifier);
            }
        }
    
    level--;
}
Beispiel #2
0
static void ui_add_items_to_shell(Widget w, int menulevel, ui_menu_entry_t *list)
{
    unsigned int i, j;

    for (i = j = 0; list[i].string; i++) {
        Widget new_item = NULL;
        char *name;

        name = lib_msprintf("MenuItem%d", j);
        switch (list[i].type) {
            case UI_MENU_TYPE_SEPARATOR:    /* line */
                new_item = XtVaCreateManagedWidget("separator",
                                                   smeLineObjectClass, w,
                                                   XtNsensitive, 0,
                                                   NULL);
                break;
            case UI_MENU_TYPE_TICK:         /* toggle */
            case UI_MENU_TYPE_TICKDOTS:     /* toggle */
                {
                    char *label = make_menu_label(&list[i]);

                    new_item = XtVaCreateManagedWidget(name,
                                                       smeBSBObjectClass, w,
                                                       XtNrightMargin, 20,
                                                       XtNleftMargin, 20,
                                                       XtNlabel, label,
                                                       NULL);
                    /* Add this item to the list of calls to perform to update
                       the menu status. */
                    if (list[i].callback) {
                        if (num_checkmark_menu_items >= num_checkmark_menu_items_max) {
                            num_checkmark_menu_items_max += 100;
                            checkmark_menu_items = lib_realloc(checkmark_menu_items, num_checkmark_menu_items_max * sizeof(Widget));
                        }
                        XtAddCallback(new_item, XtNdestroyCallback, tick_destroy, (XtPointer)num_checkmark_menu_items);
                        checkmark_menu_items[num_checkmark_menu_items++] = new_item;
                    }
                    j++;

                    lib_free(label);
                }
                break;
            case UI_MENU_TYPE_NONE:
                break;
            default:
                {
                    char *label = make_menu_label(&list[i]);

                    new_item = XtVaCreateManagedWidget(name,
                                                       smeBSBObjectClass, w,
                                                       XtNleftMargin, 20,
                                                       XtNrightMargin, 20,
                                                       XtNlabel, label,
                                                       NULL);
                    lib_free(label);
                    j++;
                }
        }
        lib_free(name);

        if (list[i].callback) {
            XtAddCallback(new_item, XtNcallback, (XtCallbackProc)list[i].callback, list[i].callback_data);
        }
        if (list[i].sub_menu) {
            /*
             * Apparently, the submenu support of Xaw is not used
             * (it isn't documented in the specs document but exists since
             * patch "#2716 24 Apr 1999"; see its old-doc/ChangeLog;
             * see also the man page Xaw(3) which mentions it.)
             * If the "menuName" resource (XtNmenuName) of a SmeBSB (item)
             * contains a menu name, that is the submenu and it will
             * pop up automatically.
            */
            if (num_submenus > MAX_SUBMENUS) {
                fprintf(stderr, "Maximum number of sub menus reached! Please fix the code.\n");
                exit(-1);
            }
            if (new_item != NULL && (list[i].type != UI_MENU_TYPE_SEPARATOR)) {
                Widget subw;

                XtVaSetValues(new_item, XtNrightBitmap, right_arrow_bitmap, NULL);
                subw = ui_create_shell(_ui_top_level, "SUB", simpleMenuWidgetClass);
                XtAddCallback(subw, XtNpopupCallback, submenu_popup_callback, submenus + num_submenus);
                XtAddCallback(subw, XtNpopdownCallback, submenu_popdown_callback, (XtPointer)w);
                XtOverrideTranslations(subw, menu_translations);

                ui_add_items_to_shell(subw, menulevel + 1, list[i].sub_menu);
                submenus[num_submenus].widget = subw;
                submenus[num_submenus].parent = new_item;
                submenus[num_submenus].level = menulevel;
                num_submenus++;
            } else {
                ui_add_items_to_shell(w, menulevel, list[i].sub_menu);
            }
        } else {            /* no submenu */
            if (list[i].hotkey_keysym != (KeySym)0 && list[i].callback != NULL) {
                ui_hotkey_register(list[i].hotkey_modifier, (signed long)list[i].hotkey_keysym, (ui_callback_t)list[i].callback, (ui_callback_data_t)list[i].callback_data);
            }
        }
    }

#ifdef UI_MENU_DEBUG
    fprintf(stderr, "num_checkmark_menu_items: %d\tnum_submenus = %d.\n", num_checkmark_menu_items, num_submenus);
#endif
}