예제 #1
0
MENUPAN*
menu_pan_create(MENU *menu, int y, int x, int id)
{
    MENUPAN *menupan;


    assert(menu);

    menupan=(MENUPAN *)malloc(sizeof(MENUPAN));
    if(!menupan) {
        set_error(ERR_NOMEM);
        lpr_error("menu_pan_create");
    }

    menupan->id=id;
    menupan->menu=menu;
    menupan->win=new_panel(newwin(item_count(menu)+2, MSIZE, y, x));
    menupan->sub=new_panel(derwin(menupan->win->win,
                                  item_count(menu), MSIZE-2, 1, 1));
    wcolor_set(menupan->win->win, 1, NULL);
    set_menu_fore(menu, COLOR_PAIR(1) | A_REVERSE);
    set_menu_back(menu, COLOR_PAIR(1));
    set_menu_grey(menu, COLOR_PAIR(1));
    set_menu_win(menu, menupan->win->win);
    set_menu_sub(menu, menupan->sub->win);


    box(menupan->win->win, 0, 0);
    menupan_hide(menupan);

    return menupan;
}
예제 #2
0
MENU*
workspace_create(void)
{
    MENU *menu;


    const char *choices[] = {
        "Lpr ",
        "Edita ",
        "Visualizza ",
        "Cerca ",
        "Help " ,
    };
    const char *desc[] = {
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
    };


    menu=menu_create(choices, desc, A_SIZE(choices));
    set_menu_format(menu, 1, A_SIZE(choices));
    set_menu_fore(menu, COLOR_PAIR(1) | A_REVERSE);
    set_menu_back(menu, COLOR_PAIR(1));

    post_menu(menu);

    return menu;

}
예제 #3
0
/*
 * Switch from field to buttons.
 * This change the foreground color of the button so the user think the cursor
 * is on the first button.
 */
static void switch_to_buttons(void)
{
	form_driver(popup_form, REQ_VALIDATION);
	menu_driver(popup_menu, REQ_FIRST_ITEM);
	is_on_button = true;
	set_menu_fore(popup_menu, A_REVERSE); // "show" the button
}
예제 #4
0
/* display current menu */
void display_menu() {
  
  int rows, cols, begin_y, begin_x;

  /* setup menu options */
  menu_opts_off(menu_ptr, O_ROWMAJOR);
  set_menu_fore(menu_ptr, COLOR_PAIR(MENU_PAIR) | A_STANDOUT);
  set_menu_back(menu_ptr, COLOR_PAIR(MENU_PAIR) | A_DIM | A_NORMAL);

  /* setup appropriate windows */
  set_menu_win(menu_ptr, stdscr);
  scale_menu(menu_ptr, &rows, &cols);

  /* locate menu in the center */
  getmaxyx(stdscr,LINES,COLS);
  begin_y = (LINES-rows) / 2;
  begin_x = (COLS-cols) / 2;

  /* create main menu window */
  sub_window = subwin(stdscr, rows, cols, begin_y, begin_x);
  set_menu_sub(menu_ptr, sub_window);

  /* display the menu */
  post_menu(menu_ptr);
  refresh();
  
}
예제 #5
0
파일: choosewin.c 프로젝트: weezel/fcd
void
show_chooser_win(MENU *dirmenu, size_t items, char *buf)
{
	int	 c = 0;
	size_t	 buflen, offset = 0;
	char	*tmp;

	buflen = strlen(buf) - 1;

	set_menu_fore(dirmenu, A_REVERSE);
	returnval = set_menu_format(dirmenu, LINES, 1);
	post_menu(dirmenu);
	refresh();

	while ((c = getch()) != 'q') {
		switch(c) {
		case 'j':
		case KEY_DOWN:
			menu_driver(dirmenu, REQ_DOWN_ITEM);
			break;
		case 'k':
		case KEY_UP:
			menu_driver(dirmenu, REQ_UP_ITEM);
			break;
		case KEY_NPAGE:
			menu_driver(dirmenu, REQ_SCR_DPAGE);
			break;
		case KEY_PPAGE:
			menu_driver(dirmenu, REQ_SCR_UPAGE);
			break;
		case KEY_END:
			menu_driver(dirmenu, REQ_LAST_ITEM);
			break;
		case KEY_HOME:
			menu_driver(dirmenu, REQ_FIRST_ITEM);
			break;
		case 10: /* Enter */
			move(20, 0);
			clrtoeol();

			tmp = (char *)item_name(current_item(dirmenu));
			offset = strlcpy(buf, tmp, MAX_CHOICESIZE);
			if (offset >= MAX_CHOICESIZE)
				goto toolong;
			if (strlcpy(buf + offset,
				    item_description(current_item(dirmenu)),
				    MAX_CHOICESIZE - offset))
				goto toolong;

			pos_menu_cursor(dirmenu);
			break;
		}
	}
toolong:
	unpost_menu(dirmenu);
	fprintf(stdout, "shit happens\n");

	fprintf(stdout, "VALUE WAS: %d\n", returnval);
}
예제 #6
0
파일: wndlist.c 프로젝트: TragicWarrior/vwm
WINDOW* vwm_fmod_wndlist(gpointer anything)
{
	const char      *title=" Window List ";
	WINDOW		    *window;
	int			    width = 0,height = 0;
	MENU			*menu;
	ITEM			**item_list;
	gchar			**titles;
	guint			item_count;

	if(viper_window_find_by_class((gpointer)vwm_fmod_wndlist) != NULL)
        return NULL;

	viper_thread_enter();

	titles = viper_deck_get_wndlist();
	item_count = g_strv_length(titles);

	if(item_count == 0)
	{
		viper_thread_leave();
		return NULL;
	}

	menu = viper_menu_create(titles);

	item_list = (ITEM**)g_malloc0(sizeof(ITEM*)*(item_count+1));

	// override the default of 1 column X 16 entries per row
	set_menu_format(menu,20,1);
	// hide character mark on left hand side
	set_menu_mark(menu," ");

	scale_menu(menu,&height,&width);
	width++;
	if((strlen(title) + 10) > width) width = (strlen(title) + 10);

	window = viper_window_create((gchar*)title,0.95,2,width,height,TRUE);
	viper_menu_bind(menu,window,0,0,width,height);

//	set_menu_sub(menu,window);
	set_menu_fore(menu,
		VIPER_COLORS(COLOR_MAGENTA,COLOR_WHITE) | A_REVERSE | A_BOLD);
	set_menu_back(menu,VIPER_COLORS(COLOR_BLACK,COLOR_WHITE));

//	post_menu(menu);

/*	viper_event_set(window,"window-activate",vwm_fmod_wndlist_ON_ACTIVATE,NULL); */
	viper_event_set(window,"window-destroy",vwm_fmod_wndlist_ON_DESTROY,
		(gpointer)menu);
	viper_window_set_key_func(window,vwm_fmod_wndlist_ON_KEYSTROKE);
	viper_window_set_userptr(window,(gpointer)menu);
	viper_window_set_state(window,STATE_EMINENT);

	viper_thread_leave();
	g_strfreev(titles);

	return window;
}
예제 #7
0
void NCPanelContainer::setActive(const NCPanel * panel)
{
	for (int i = 0; i < mPanels.size(); i++)
		if ( mPanels[i] == panel )
		{
			mPanels[i]->setActive(true);
			MENU * menu = mPanels[i]->getWidget()->getMenu();

			set_menu_grey(menu, COLOR_PAIR(3));
			set_menu_fore(menu, COLOR_PAIR(4));
			set_menu_back(menu, COLOR_PAIR(1));
			current = i;
			break;
		}
}
예제 #8
0
파일: NCRowMenu.cpp 프로젝트: lukasic/ncfm
void NCRowMenu::setup()
{
	wbkgd(getWindow(),COLOR_PAIR(2));

	ITEM **my_items;
	MENU *my_menu;
    WINDOW *my_menu_win;
	int i;

	my_items = (ITEM **) calloc(choices.size()+2, sizeof(ITEM *));
    for(i = 0; i < choices.size(); ++i)
    	my_items[i] = new_item(choices[i].c_str(), "NULL");
	
	my_menu = new_menu((ITEM **) my_items);

	set_menu_grey(my_menu, COLOR_PAIR(2));
	set_menu_fore(my_menu, COLOR_PAIR(2));
	set_menu_back(my_menu, COLOR_PAIR(2));

	menu_opts_off(my_menu, O_SHOWDESC);

    my_menu_win = getWindow();
    keypad(my_menu_win, FALSE);

	/* Set main window and sub window */
    set_menu_win(my_menu, my_menu_win);
    //set_menu_sub(my_menu, derwin(my_menu_win, 10, 150, 3, 1));
	set_menu_format(my_menu, 1, 10);
	set_menu_mark(my_menu, " ");

    //box(my_menu_win, 0, 0);

	//wbkgdset(getWindow(), COLOR_PAIR(2));
	//wrefresh(getWindow());
	wrefresh(stdscr);
	
	refresh();

	/* Post the menu */
	post_menu(my_menu);
	wrefresh(my_menu_win);

	//setBorder(0, 0);
}
예제 #9
0
void NCPanelContainer::changePanels()
{
	int curr = 0;
	for (curr = 0; curr < mPanels.size(); curr++)
	{
		MENU * menu = mPanels[curr]->getWidget()->getMenu();

		set_menu_grey(menu, COLOR_PAIR(5));
		set_menu_fore(menu, COLOR_PAIR(5));
		set_menu_back(menu, COLOR_PAIR(5));

		if ( mPanels[curr]->isActive() )
		{
			mPanels[curr]->setActive(false);
			break;
		}
	}

	curr = (curr+1) % mPanels.size();

	setActive( mPanels[curr] );
}
예제 #10
0
/*
 * This is called by main.c ncurses_action everytime a popup exists.
 * It's used to handle characters input in forms and button pressing.
 */
void popup_driver(int ch)
{
	switch (ch) {
		case KEY_DOWN:
			if (is_on_button || !popup_form)
				break;

			if (popup_form->current == popup_fields[popup_form->maxfield-1])
				switch_to_buttons();
			else
				form_driver(popup_form, REQ_NEXT_FIELD);
			break;

		case KEY_UP:
			if (is_on_button) {
				if (!popup_form)
					break;

				is_on_button = false;
				set_menu_fore(popup_menu, A_NORMAL); // "hide" the button
			} else
				form_driver(popup_form, REQ_PREV_FIELD);
			break;

		case KEY_LEFT:
			if (is_on_button)
				menu_driver(popup_menu, REQ_LEFT_ITEM);
			else
				form_driver(popup_form, REQ_PREV_CHAR);
			break;

		case KEY_RIGHT:
			if (is_on_button)
				menu_driver(popup_menu, REQ_RIGHT_ITEM);
			else
				form_driver(popup_form, REQ_NEXT_CHAR);
			break;

		case 10:
			if (is_on_button)
				driver_buttons(current_item(popup_menu));
			else
				switch_to_buttons();

			break;

		// Delete the char before cursor
		case KEY_BACKSPACE:
		case 127:
			if (!is_on_button)
				form_driver(popup_form, REQ_DEL_PREV);
			break;

		// Delete the char under the cursor
		case KEY_DC:
			if (!is_on_button)
				form_driver(popup_form, REQ_DEL_CHAR);
			break;

		default:
			if (!is_on_button)
				form_driver(popup_form, ch);

			break;

	}

	if (popup_menu) {
		if (is_on_button)
			pos_menu_cursor(popup_menu);
		else
			pos_form_cursor(popup_form);
	}

	wrefresh(win_body);
}
예제 #11
0
파일: nchgdc.c 프로젝트: Eeketh/hgd
int
hgd_update_files_win(struct ui *u)
{
	ITEM			**items = NULL;
	char			 *slash_append, *prep_item_str;
	struct dirent		**dirents_dirs = 0, **dirents_files = 0, *d, *d_copy;
	int			  n_dirs = 0, n_files = 0;
	int			  i, cur_item = 0, ret = HGD_FAIL;

	DPRINTF(HGD_D_INFO, "Update files window");

	wclear(u->content_wins[HGD_WIN_FILES]);
	hgd_unpost_and_free_content_menu(u, HGD_WIN_FILES);

	if ((n_dirs = scandir(
	    u->cwd, &dirents_dirs, hgd_filter_dirs, alphasort)) < 0) {
		 DPRINTF(HGD_D_WARN, "Failed to scan directory: '%s'", u->cwd);
		 goto clean;
	}

	if ((n_files = scandir(
	    u->cwd, &dirents_files, hgd_filter_files, alphasort)) < 0) {
		 DPRINTF(HGD_D_WARN, "Failed to scan directory: '%s'", u->cwd);
		 goto clean;
	}

	/* make our menu items */
	DPRINTF(HGD_D_INFO, "allocating %d menu items", n_files + n_dirs);
	items = xcalloc(n_files + n_dirs + 1, sizeof(ITEM *));

	/* add dirs */
	for (i = 0; i < n_dirs; i++) {
		d = dirents_dirs[i];

		xasprintf(&slash_append, "%s/", d->d_name);
		hgd_prepare_item_string(&prep_item_str, slash_append);
		free(slash_append);

		items[cur_item] = new_item(prep_item_str, NULL);

		if (items[cur_item] == NULL) {
			DPRINTF(HGD_D_WARN,
			    "Could not make new menu item: %s", SERROR);
			free(prep_item_str);
			continue;
		}

		/*
		 * jam away the dirent for later use
		 * Note! scandir does notallocate a full struct dirent
		 */
#if !defined(__linux__)
		d_copy = xcalloc(1, sizeof(struct dirent));
		d_copy->d_fileno = d->d_fileno;2
		d_copy->d_reclen = d->d_reclen;
		d_copy->d_type = d->d_type;
		d_copy->d_namlen = d->d_namlen;
		strlcpy(d_copy->d_name, d->d_name, d->d_namlen + 1);
#else
		d_copy = xcalloc(1, d->d_reclen);
		memcpy(d_copy, d, d->d_reclen);
#endif

		set_item_userptr(items[cur_item], d_copy);

		cur_item++;
	}

	/* add files */
	for (i = 0; i < n_files; i++) {
		d = dirents_files[i];

		hgd_prepare_item_string(&prep_item_str, d->d_name);

		items[cur_item] = new_item(prep_item_str, NULL);

		if (items[cur_item] == NULL) {
			DPRINTF(HGD_D_WARN,
			    "Could not make new menu item: %s", SERROR);
			free(prep_item_str);
			continue;
		}

		/*
		 * copy manually, do not use memcpy, as scandir does not
		 * allocate a full struct dirent
		 */
#if !defined(__linux__)
		d_copy = xcalloc(1, sizeof(struct dirent));
		d_copy->d_fileno = d->d_fileno;2
		d_copy->d_reclen = d->d_reclen;
		d_copy->d_type = d->d_type;
		d_copy->d_namlen = d->d_namlen;
		strlcpy(d_copy->d_name, d->d_name, d->d_namlen + 1);
#else
		d_copy = xcalloc(1, d->d_reclen);
		memcpy(d_copy, d, d->d_reclen);
#endif

		set_item_userptr(items[cur_item], d_copy);

		cur_item++;
	}

	DPRINTF(HGD_D_INFO, "Actually allocated %d menu items", cur_item);
	items[cur_item] = NULL;

	u->content_menus[HGD_WIN_FILES] = new_menu(items);

	keypad(u->content_wins[HGD_WIN_FILES], TRUE);
	set_menu_win(u->content_menus[HGD_WIN_FILES],
	    u->content_wins[HGD_WIN_FILES]);
	set_menu_mark(u->content_menus[HGD_WIN_FILES], "");
	set_menu_format(u->content_menus[HGD_WIN_FILES],
	    LINES - 2, 1);
	set_menu_fore(u->content_menus[HGD_WIN_FILES],
	    COLOR_PAIR(HGD_CPAIR_SELECTED));

	if ((post_menu(u->content_menus[HGD_WIN_FILES])) != E_OK)
		DPRINTF(HGD_D_WARN, "Could not post menu");

	ret = HGD_OK;

clean:
	if (dirents_files) {
		for (i = 0; i < n_files; i ++)
			free(dirents_files[i]);
		free(dirents_files);
	}

	if (dirents_dirs) {
		for (i = 0; i < n_dirs; i ++)
			free(dirents_dirs[i]);
		free(dirents_dirs);
	}

#if 0
	if (items)
		free(items);
#endif

	return (ret);

}
예제 #12
0
/*

    returns 1 if yes, 0 if no
*/
int confirm(const char *title, const char *text, chtype forecolor,
        chtype backcolor, int def)
{
    int retval = 0;
    ITEM **menu_items;
    MENU *confirm_menu;
    PANEL *my_panels[1];
    WINDOW *confirm_win, *dw;
    ITEM *cur;

    int height = 7, width = 25, startx = 5, starty = 5, max_x = 0, max_y = 0;
    const char *choices[] = {STR_YES, STR_NO};

    size_t n_choices = 2, i = 0;

    int ch, quit = 0;

    char *print_title;

    /* safety */
    vrmr_fatal_if_null(title);
    vrmr_fatal_if_null(text);

    if (width - 4 < (int)StrLen(text))
        width = (int)StrLen(text) + 4;
    if (width - 6 < (int)StrLen(title))
        width = (int)StrLen(title) + 6;
    getmaxyx(stdscr, max_y, max_x);
    startx = (max_x - width) / 2;
    starty = (max_y - height) / 2;

    print_title = malloc(StrMemLen(title) + 3);
    vrmr_fatal_alloc("malloc", print_title);
    snprintf(print_title, StrMemLen(title) + 3, " %s ", title);

    menu_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
    vrmr_fatal_alloc("calloc", menu_items);
    for (i = 0; i < n_choices; ++i) {
        menu_items[i] = new_item(choices[i], NULL);
    }
    menu_items[n_choices] = (ITEM *)NULL;
    confirm_menu = new_menu((ITEM **)menu_items);
    vrmr_fatal_if_null(confirm_menu);
    confirm_win = newwin(height, width, starty, startx);
    wbkgd(confirm_win, backcolor);
    keypad(confirm_win, TRUE);
    wrefresh(confirm_win);
    my_panels[0] = new_panel(confirm_win);
    set_menu_win(confirm_menu, confirm_win);
    dw = derwin(confirm_win, height - 4, 10, 4, (width) / 2 - 5);
    set_menu_sub(confirm_menu, dw);
    set_menu_format(confirm_menu, height - 4, 2);
    box(confirm_win, 0, 0);
    print_in_middle(confirm_win, 0, 0, width, print_title, backcolor);
    print_in_middle(confirm_win, 2, 0, width, text, backcolor);
    set_menu_back(confirm_menu, backcolor);
    set_menu_fore(confirm_menu, forecolor);
    post_menu(confirm_menu);

    /* set the cursor to the 'no' position */
    if (!def) {
        menu_driver(confirm_menu, REQ_RIGHT_ITEM);
    }
    update_panels();
    doupdate();

    while (quit == 0) {
        ch = wgetch(confirm_win);
        switch (ch) {
            case KEY_DOWN:
                menu_driver(confirm_menu, REQ_LEFT_ITEM);
                break;
            case KEY_UP:
                menu_driver(confirm_menu, REQ_RIGHT_ITEM);
                break;
            case KEY_LEFT:
                menu_driver(confirm_menu, REQ_LEFT_ITEM);
                break;
            case KEY_RIGHT:
                menu_driver(confirm_menu, REQ_RIGHT_ITEM);
                break;

            case 10: // enter
            {
                cur = current_item(confirm_menu);
                vrmr_fatal_if_null(cur);
                if (strcmp((char *)item_name(cur), STR_YES) == 0) {
                    retval = 1;
                }
                quit = 1;
                break;
            }

            case 'y':
            case 'Y':
                retval = 1;
                quit = 1;
                break;

            case 'n':
            case 'N':
                retval = 0;
                quit = 1;
                break;

            case 27:
            case KEY_F(10):
            case 'q':
            case 'Q':
                quit = 1;
                break;
        }
    }

    unpost_menu(confirm_menu);
    free_menu(confirm_menu);
    for (i = 0; i < n_choices; ++i)
        free_item(menu_items[i]);
    free(menu_items);
    destroy_win(dw);
    del_panel(my_panels[0]);
    destroy_win(confirm_win);
    free(print_title);
    update_panels();
    doupdate();
    return (retval);
}
예제 #13
0
파일: nchgdc.c 프로젝트: Eeketh/hgd
int
hgd_update_console_win(struct ui *u)
{
	char		  buf[HGD_LOG_BACKBUFFER + 1], *start = buf, *end, *copy;
	long		  pos, endpos, read;
	long		  toread = HGD_LOG_BACKBUFFER;
	ITEM		**items = NULL;
	int		  cur_index = 0;

	DPRINTF(HGD_D_INFO, "Update console window");

	wclear(u->content_wins[HGD_WIN_CONSOLE]);
	hgd_unpost_and_free_content_menu(u, HGD_WIN_CONSOLE);

	memset(buf, 0, HGD_LOG_BACKBUFFER + 1);

	/* find how long the log is */
	if ((fseek(logs.rd, 0, SEEK_END)) != 0)
		DPRINTF(HGD_D_WARN, "fseek: %s", SERROR);

	endpos = ftell(logs.rd);
	if (endpos < HGD_LOG_BACKBUFFER)
		toread = endpos;

	/* rewind at most HGD_LOG_BACKBUFFER and read into buffer */
	if ((fseek(logs.rd, -toread, SEEK_END)) != 0)
		DPRINTF(HGD_D_WARN, "fseek: %s", SERROR);

	pos = ftell(logs.rd);
	if ((read = fread(buf, toread, 1, logs.rd)) == 0) {
		if (ferror(logs.rd)) {
		    DPRINTF(HGD_D_WARN,
			"Failed to read console log: %s", SERROR);
		}
	}

	/* ensure we dont start printing the middle of a line */
	if (pos < 0)
		DPRINTF(HGD_D_WARN, "ftell failed: %s", SERROR);
	else if (pos != 0) {
		/* if not at the start of file, find a \n */
		while ((*start != '\n') && (*start != '\0'))
			start++;
	}

	/* this SHOULD happen, but not guaraunteed */
	if (*start == '\n')
		start++;

	items = xcalloc(sizeof(ITEM *), 1);

	/* scan for lines and add them as menu items */
	end = start;
	while (*start != 0) {
		while ((*end != 0) && (*end != '\n'))
			end++;

		if (*end == 0) {
			DPRINTF(HGD_D_WARN, "Unexpected end of log");
			break;
		}
		*end = 0;

		/* could be more efficient */
		items = xrealloc(items, sizeof(ITEM *) * (cur_index + 2));
		items[cur_index + 1] = NULL;

		hgd_prepare_item_string(&copy, start);
		items[cur_index] = new_item(copy, NULL);

		if (items[cur_index] == NULL) {
			DPRINTF(HGD_D_WARN,
			    "Could not make new menu item '%s'", start);
			free(copy);
		}

		end++;
		start = end;

		if (items[cur_index] == NULL)
			continue;

		cur_index++;
	}

	/* now we have our items, make the menu */
	if (u->content_menus[HGD_WIN_CONSOLE] != NULL) {
		/* XXX clean up old menu */
	}

	u->content_menus[HGD_WIN_CONSOLE] = new_menu(items);

	keypad(u->content_wins[HGD_WIN_CONSOLE], TRUE);
	set_menu_win(u->content_menus[HGD_WIN_CONSOLE],
	    u->content_wins[HGD_WIN_CONSOLE]);
	set_menu_mark(u->content_menus[HGD_WIN_CONSOLE], "");
	set_menu_format(u->content_menus[HGD_WIN_CONSOLE],
	    LINES - 2, 1);
	set_menu_fore(u->content_menus[HGD_WIN_CONSOLE],
	    COLOR_PAIR(HGD_CPAIR_SELECTED));

	if ((post_menu(u->content_menus[HGD_WIN_CONSOLE])) != E_OK)
		DPRINTF(HGD_D_WARN, "Could not post menu");

	menu_driver(u->content_menus[HGD_WIN_CONSOLE], REQ_LAST_ITEM);

	return (HGD_OK);
}
예제 #14
0
파일: pkgui.c 프로젝트: nbyouri/pkgui
/*
 * Return codes:
 *  0 - action performed
 * -1 - quit was pressed (only for main menu)
 * +1 - backspace or escape was pressed, back to previous menu
 */
static int
do_menu(struct menuoption *runmenu, int num, int upper, const char *title, ...)
{
	int ch, i, y, x;
//	char buf[BUFSIZ];
	char *buf;
	struct menuoption *curmenu;
	ITEM **mitems, *mitem;
	MENU *mmenu;
	WINDOW *msubwin;
	va_list ap;

	/* Clear screen and print title */
	if (upper)
		show_mainwin(0);
	else
		show_mainwin(1);
	va_start(ap, title);
	head_mainwin(title, ap);
	va_end(ap);

	x = 0;
	y = 0;
	if (upper)
		msubwin = create_uppersubwin();
	else
		msubwin = create_lowersubwin(&y, &x);

	mitems = (ITEM **)calloc(num + 1, sizeof(ITEM*));
	for (curmenu = runmenu, i = 0; i < num; i++) {
		ch = sizeof buf > x ? x - 1 : sizeof buf - 1;
//		if (snprintf(buf, ch, "%s", curmenu->m_name) <= 0) {
		if (asprintf(&buf, "%s", curmenu->m_name) <= 0) {
			ask_ok("Error creating the menu.");
			for (i--; i >= 0; i--)
				free(mitems[i]);
			return 0;
		}
		mitems[i] = new_item(buf, NULL);
		set_item_userptr(mitems[i], (void *)curmenu);
//		warnx("%ld %s", (long)curmenu, curmenu->m_name);
		curmenu++;
	}
	mitems[num] = NULL;

	mmenu = new_menu(mitems);
	set_menu_win(mmenu, mainwin);
	set_menu_sub(mmenu, msubwin);
	set_menu_format(mmenu, upper ? 1 : y, 1);
	if (colouring) {
		set_menu_fore(mmenu, COLOR_PAIR(1));
		set_menu_back(mmenu, COLOR_PAIR(1));
		set_menu_grey(mmenu, COLOR_PAIR(1));
	}
	set_menu_mark(mmenu, ">");
	if (post_menu(mmenu)) {
		ask_ok("Error posting the menu.");
		return 1;
	}
	show_mainwin(0);
	show_lowersubwin(0, msubwin);

	while ((ch = getch()) != '\n' && ch != '\b') {
		switch (ch) {
			case KEY_DOWN:
				menu_driver(mmenu, REQ_NEXT_ITEM);
				break;
			case KEY_UP:
				menu_driver(mmenu, REQ_PREV_ITEM);
				break;
			case KEY_NPAGE:
				menu_driver(mmenu, REQ_SCR_DPAGE);
				break;
			case KEY_PPAGE:
				menu_driver(mmenu, REQ_SCR_UPAGE);
				break;
			case KEY_END:
				menu_driver(mmenu, REQ_LAST_ITEM);
				break;
			case KEY_HOME:
				menu_driver(mmenu, REQ_FIRST_ITEM);
				break;
		}
		show_mainwin(0);
		show_lowersubwin(0, msubwin);
	}

	mitem = current_item(mmenu);
	curmenu = (struct menuoption *)item_userptr(mitem);

	unpost_menu(mmenu);
	delwin(msubwin);
	free_menu(mmenu);
	for (i = 0; i < num; i++)
		free_item(mitems[i]);
	free(mitems);

	if (ch != '\b' && curmenu->m_action != NULL) {
		curmenu->m_action(curmenu->m_argv);
		return 0;
	} else {
		return 1;
	}
}
예제 #15
0
/*
 * create the internal menu for the files 
 */
static void wdg_file_menu_create(struct wdg_object *wo)
{
   WDG_WO_EXT(struct wdg_file_handle, ww);
   int mrows, mcols;
   int i;
   size_t c = wdg_get_ncols(wo);
   size_t x = wdg_get_begin_x(wo);
   size_t y = wdg_get_begin_y(wo);
   struct stat buf;

   /* the menu is already posted */
   if (ww->nitems)
      return;
 
   WDG_DEBUG_MSG("wdg_file_menu_create");
   
   /* get the working directory */
   getcwd(ww->curpath, PATH_MAX);
         
   /* scan the directory */
   ww->nlist = scandir(".", &ww->namelist, 0, alphasort);

   /* on error display the message in the box */
   if (ww->nlist <= 0) {
      ww->nitems = 2;
      WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *));
      ww->items[ww->nitems - 2] = new_item("/", "root");
      ww->items[ww->nitems - 1] = new_item("Cannot open the directory", "");
      item_opts_off(ww->items[ww->nitems - 1], O_SELECTABLE);
   } else {

      /* for each directory in the directory */
      for (i = 0; i < ww->nlist; i++) {
        
         /* 
          * transform the current dir into the root.
          * useful to exit from a path whose parent is not readable 
          */
         if (!strcmp(ww->namelist[i]->d_name, ".")) {
            strncpy(ww->namelist[i]->d_name, "/", 1);
            ww->nitems++;
            WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *));
            ww->items[ww->nitems - 1] = new_item(ww->namelist[i]->d_name, "root");
            continue;
         }
         
         /* get the file properties */
         stat(ww->namelist[i]->d_name, &buf);
         
         if (S_ISDIR(buf.st_mode)) {
            ww->nitems++;
            WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *));
            ww->items[ww->nitems - 1] = new_item(ww->namelist[i]->d_name, "[...]");
         }
         // if not readable
         //item_opts_off(ww->items[ww->nitems - 1], O_SELECTABLE);
      }
      
      /* and now add the files */
      for (i = 0; i < ww->nlist; i++) {
         
         /* get the file properties */
         stat(ww->namelist[i]->d_name, &buf);
         
         if (!S_ISDIR(buf.st_mode)) {
            ww->nitems++;
            WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *));
            ww->items[ww->nitems - 1] = new_item(ww->namelist[i]->d_name, "");
         }
      }
   }

   /* null terminate the array */
   WDG_SAFE_REALLOC(ww->items, (ww->nitems + 1) * sizeof(ITEM *));
   ww->items[ww->nitems] = NULL;
     
   /* create the menu */
   ww->m = new_menu(ww->items);

   /* set the dimensions */
   set_menu_format(ww->m, ww->y - 2, 1);
   set_menu_spacing(ww->m, 2, 0, 0);

   /* get the geometry to make a window */
   scale_menu(ww->m, &mrows, &mcols);

   /* 
    * if the menu is larger than the main window
    * adapt to the new dimensions
    */
   if (mcols > (int)c - 4) {
      ww->x = mcols + 4;
      wdg_file_redraw(wo);
      return;
   }
   /* create the window for the menu */
   ww->mwin = newwin(mrows, MAX(mcols, (int)c - 4), y + 1, x + 2);
   /* set the color */
   wbkgd(ww->mwin, COLOR_PAIR(wo->window_color));
   keypad(ww->mwin, TRUE);
  
   /* associate with the menu */
   set_menu_win(ww->m, ww->mwin);
   
   /* the subwin for the menu */
   set_menu_sub(ww->m, derwin(ww->mwin, mrows + 1, mcols, 1, 1));

   /* menu attributes */
   set_menu_mark(ww->m, "");
   set_menu_grey(ww->m, COLOR_PAIR(wo->window_color));
   set_menu_back(ww->m, COLOR_PAIR(wo->window_color));
   set_menu_fore(ww->m, COLOR_PAIR(wo->window_color) | A_REVERSE | A_BOLD);
   
   /* display the menu */
   post_menu(ww->m);

   wnoutrefresh(ww->mwin);
   
}
예제 #16
0
int main()
{	ITEM **my_items;
	int c;				
	MENU *my_menu;
        int n_choices, i;
	ITEM *cur_item;
	
	/* Initialize curses */	
	initscr();
	start_color();
        cbreak();
        noecho();
	keypad(stdscr, TRUE);
	init_pair(1, COLOR_RED, COLOR_BLACK);
	init_pair(2, COLOR_GREEN, COLOR_BLACK);
	init_pair(3, COLOR_MAGENTA, COLOR_BLACK);

	/* Initialize items */
        n_choices = ARRAY_SIZE(choices);
        my_items = (ITEM **)calloc(n_choices + 1, sizeof(ITEM *));
        for(i = 0; i < n_choices; ++i)
                my_items[i] = new_item(choices[i], choices[i]);
	my_items[n_choices] = (ITEM *)NULL;
	item_opts_off(my_items[3], O_SELECTABLE);
	item_opts_off(my_items[6], O_SELECTABLE);

	/* Create menu */
	my_menu = new_menu((ITEM **)my_items);

	/* Set fore ground and back ground of the menu */
	set_menu_fore(my_menu, COLOR_PAIR(1) | A_REVERSE);
	set_menu_back(my_menu, COLOR_PAIR(2));
	set_menu_grey(my_menu, COLOR_PAIR(3));

	/* Post the menu */
	mvprintw(LINES - 3, 0, "Press <ENTER> to see the option selected");
	mvprintw(LINES - 2, 0, "Up and Down arrow keys to naviage (F1 to Exit)");
	post_menu(my_menu);
	refresh();

	while((c = getch()) != KEY_F(1))
	{       switch(c)
	        {	case KEY_DOWN:
				menu_driver(my_menu, REQ_DOWN_ITEM);
				break;
			case KEY_UP:
				menu_driver(my_menu, REQ_UP_ITEM);
				break;
			case 10: /* Enter */
				move(20, 0);
				clrtoeol();
				mvprintw(20, 0, "Item selected is : %s", 
						item_name(current_item(my_menu)));
				pos_menu_cursor(my_menu);
				break;
		}
	}	
	unpost_menu(my_menu);
	for(i = 0; i < n_choices; ++i)
		free_item(my_items[i]);
	free_menu(my_menu);
	endwin();
}
예제 #17
0
int
column_select_handle_key_form(ui_t *ui, int key)
{
    int field_idx, new_field_idx;
    char field_value[48];
    int action = -1;

    // Get panel information
    column_select_info_t *info = column_select_info(ui);

    // Get current field id
    field_idx = field_index(current_field(info->form));

    // Get current field value.
    memset(field_value, 0, sizeof(field_value));
    strcpy(field_value, field_buffer(current_field(info->form), 0));
    strtrim(field_value);

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_RIGHT:
            case ACTION_NEXT_FIELD:
                form_driver(info->form, REQ_NEXT_FIELD);
                break;
            case ACTION_LEFT:
            case ACTION_PREV_FIELD:
                form_driver(info->form, REQ_PREV_FIELD);
                break;
            case ACTION_SELECT:
            case ACTION_CONFIRM:
                switch(field_idx) {
                    case FLD_COLUMNS_ACCEPT:
                        column_select_update_columns(ui);
                        ui_destroy(ui);
                        return KEY_HANDLED;
                    case FLD_COLUMNS_CANCEL:
                        ui_destroy(ui);
                        return KEY_HANDLED;
                    case FLD_COLUMNS_SAVE:
                        column_select_update_columns(ui);
                        column_select_save_columns(ui);
                        ui_destroy(ui);
                        return KEY_HANDLED;
                }
                break;
            default:
                // Parse next action
                continue;
        }

        // This panel has handled the key successfully
        break;
    }

    // Validate all input data
    form_driver(info->form, REQ_VALIDATION);

    // Change background and cursor of "button fields"
    set_field_back(info->fields[FLD_COLUMNS_ACCEPT], A_NORMAL);
    set_field_back(info->fields[FLD_COLUMNS_SAVE],   A_NORMAL);
    set_field_back(info->fields[FLD_COLUMNS_CANCEL], A_NORMAL);

    // Get current selected field
    new_field_idx = field_index(current_field(info->form));

    // Swap between menu and form
    if (field_idx == FLD_COLUMNS_CANCEL && new_field_idx == FLD_COLUMNS_ACCEPT) {
        set_menu_fore(info->menu, COLOR_PAIR(CP_DEF_ON_BLUE));
        info->form_active = 0;
    } else {
        // Change current field background
        set_field_back(info->fields[new_field_idx], A_REVERSE);
    }

    // Return if this panel has handled or not the key
    return (action == ERR) ? KEY_NOT_HANDLED : KEY_HANDLED;
}
예제 #18
0
int
column_select_handle_key_menu(ui_t *ui, int key)
{
    MENU *menu;
    ITEM *current;
    int current_idx;
    int action = -1;

    // Get panel information
    column_select_info_t *info = column_select_info(ui);

    menu = info->menu;
    current = current_item(menu);
    current_idx = item_index(current);

    // Check actions for this key
    while ((action = key_find_action(key, action)) != ERR) {
        // Check if we handle this action
        switch (action) {
            case ACTION_DOWN:
                menu_driver(menu, REQ_DOWN_ITEM);
                break;
            case ACTION_UP:
                menu_driver(menu, REQ_UP_ITEM);
                break;
            case ACTION_NPAGE:
                menu_driver(menu, REQ_SCR_DPAGE);
                break;
            case ACTION_PPAGE:
                menu_driver(menu, REQ_SCR_UPAGE);
                break;
            case ACTION_SELECT:
                column_select_toggle_item(ui, current);
                column_select_update_menu(ui);
                break;
            case ACTION_COLUMN_MOVE_DOWN:
                column_select_move_item(ui, current, current_idx + 1);
                column_select_update_menu(ui);
                break;
            case ACTION_COLUMN_MOVE_UP:
                column_select_move_item(ui, current, current_idx - 1);
                column_select_update_menu(ui);
                break;
            case ACTION_NEXT_FIELD:
                info->form_active = 1;
                set_menu_fore(menu, COLOR_PAIR(CP_DEFAULT));
                set_field_back(info->fields[FLD_COLUMNS_ACCEPT], A_REVERSE);
                form_driver(info->form, REQ_VALIDATION);
                break;
            case ACTION_CONFIRM:
                column_select_update_columns(ui);
                ui_destroy(ui);
                return KEY_HANDLED;
            default:
                // Parse next action
                continue;
        }

        // This panel has handled the key successfully
        break;
    }

    // Draw a scrollbar to the right
    info->scroll.pos = top_row(menu);
    ui_scrollbar_draw(info->scroll);
    wnoutrefresh(info->menu_win);

    // Return if this panel has handled or not the key
    return (action == ERR) ? KEY_NOT_HANDLED : KEY_HANDLED;
}
예제 #19
0
파일: nchgdc.c 프로젝트: Eeketh/hgd
int
hgd_update_playlist_win(struct ui *u)
{
	ITEM			**items = NULL;
	int			  i, ret = HGD_FAIL;
	char			 *item_str;
	struct hgd_playlist	 *playlist = NULL;
	char			 *track_str;

	DPRINTF(HGD_D_INFO, "Update playlist window");

	hgd_set_statusbar_text(u, "Connected >>> Fetching playlist");

	if (sock_fd == -1) {
		ret = HGD_OK;
		goto clean;
	}

	wclear(u->content_wins[HGD_WIN_PLAYLIST]);
	hgd_unpost_and_free_content_menu(u, HGD_WIN_PLAYLIST);

	/* and now populate the menu */
	if (hgd_cli_get_playlist(&playlist) != HGD_OK) {
		goto clean;
	}

	if (playlist->n_items == 0) {
		ret = HGD_OK;
		mvwprintw(u->content_wins[HGD_WIN_PLAYLIST], 0, 0, "Playlist Empty - Saddest of times!");
		goto clean;
	}

	items = xcalloc(playlist->n_items + 1, sizeof(ITEM *));
	for (i = 0; i < playlist->n_items; i++) {

		DPRINTF(HGD_D_DEBUG, "Adding item \"%s\"",
		    playlist->items[i]->tags.title);

		if ((strcmp(playlist->items[i]->tags.artist, "")) ||
		    (strcmp(playlist->items[i]->tags.title, ""))) {

			xasprintf(&track_str, "#%03d from %-8s: '%s' by '%s'",
			    playlist->items[i]->id,
			    playlist->items[i]->user,
			    playlist->items[i]->tags.title,
			    playlist->items[i]->tags.artist);
		} else  {
			xasprintf(&track_str, "#%03d from %-8s: '%s'",
			    playlist->items[i]->id,
			    playlist->items[i]->user,
			    playlist->items[i]->filename);
		}

		hgd_prepare_item_string(&item_str, track_str);
		free(track_str);

		items[i] = new_item(item_str, NULL);
		if (items[i] == NULL)
			DPRINTF(HGD_D_WARN, "Could not make new item: %s", SERROR);
	}

	u->content_menus[HGD_WIN_PLAYLIST] = new_menu(items);
	if (u->content_menus[HGD_WIN_PLAYLIST] == NULL) {
			DPRINTF(HGD_D_ERROR, "Could not make menu");
			goto clean;
	}

	set_menu_win(u->content_menus[HGD_WIN_PLAYLIST],
	    u->content_wins[HGD_WIN_PLAYLIST]);
	set_menu_mark(u->content_menus[HGD_WIN_PLAYLIST], "");
	set_menu_format(u->content_menus[HGD_WIN_PLAYLIST], LINES - 2, 1);
	set_menu_fore(u->content_menus[HGD_WIN_PLAYLIST],
	    COLOR_PAIR(HGD_CPAIR_SELECTED));

	if ((post_menu(u->content_menus[HGD_WIN_PLAYLIST])) != E_OK) {
		DPRINTF(HGD_D_ERROR, "Could not post menu");
		goto clean;
	}

	hgd_set_standard_statusbar_text(u);

	ret = HGD_OK;
clean:
	if (playlist)
		hgd_free_playlist(playlist);
#if 0
	if (items)
		free(items);
#endif
	if (playlist)
		free(playlist);

	return (ret);
}
예제 #20
0
int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
{
	va_list ap;
	char *btn;
	int btns_width = 0;
	int msg_lines = 0;
	int msg_width = 0;
	int total_width;
	int win_rows = 0;
	WINDOW *win;
	WINDOW *msg_win;
	WINDOW *menu_win;
	MENU *menu;
	ITEM *btns[btn_num+1];
	int i, x, y;
	int res = -1;


	va_start(ap, btn_num);
	for (i = 0; i < btn_num; i++) {
		btn = va_arg(ap, char *);
		btns[i] = new_item(btn, "");
		btns_width += strlen(btn)+1;
	}
	va_end(ap);
	btns[btn_num] = NULL;

	/* find the widest line of msg: */
	msg_lines = get_line_no(msg);
	for (i = 0; i < msg_lines; i++) {
		const char *line = get_line(msg, i);
		int len = get_line_length(line);
		if (msg_width < len)
			msg_width = len;
	}

	total_width = max(msg_width, btns_width);
	/* place dialog in middle of screen */
	y = (LINES-(msg_lines+4))/2;
	x = (COLS-(total_width+4))/2;


	/* create the windows */
	if (btn_num > 0)
		win_rows = msg_lines+4;
	else
		win_rows = msg_lines+2;

	win = newwin(win_rows, total_width+4, y, x);
	keypad(win, TRUE);
	menu_win = derwin(win, 1, btns_width, win_rows-2,
			1+(total_width+2-btns_width)/2);
	menu = new_menu(btns);
	msg_win = derwin(win, win_rows-2, msg_width, 1,
			1+(total_width+2-msg_width)/2);

	set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
	set_menu_back(menu, attributes[DIALOG_MENU_BACK]);

	wattrset(win, attributes[DIALOG_BOX]);
	box(win, 0, 0);

	/* print message */
	wattrset(msg_win, attributes[DIALOG_TEXT]);
	fill_window(msg_win, msg);

	set_menu_win(menu, win);
	set_menu_sub(menu, menu_win);
	set_menu_format(menu, 1, btn_num);
	menu_opts_off(menu, O_SHOWDESC);
	menu_opts_off(menu, O_SHOWMATCH);
	menu_opts_on(menu, O_ONEVALUE);
	menu_opts_on(menu, O_NONCYCLIC);
	set_menu_mark(menu, "");
	post_menu(menu);


	touchwin(win);
	refresh_all_windows(main_window);
	while ((res = wgetch(win))) {
		switch (res) {
		case KEY_LEFT:
			menu_driver(menu, REQ_LEFT_ITEM);
			break;
		case KEY_RIGHT:
			menu_driver(menu, REQ_RIGHT_ITEM);
			break;
		case 10: /* ENTER */
		case 27: /* ESCAPE */
		case ' ':
		case KEY_F(F_BACK):
		case KEY_F(F_EXIT):
			break;
		}
		touchwin(win);
		refresh_all_windows(main_window);

		if (res == 10 || res == ' ') {
			res = item_index(current_item(menu));
			break;
		} else if (res == 27 || res == KEY_F(F_BACK) ||
				res == KEY_F(F_EXIT)) {
			res = KEY_EXIT;
			break;
		}
	}

	unpost_menu(menu);
	free_menu(menu);
	for (i = 0; i < btn_num; i++)
		free_item(btns[i]);

	delwin(win);
	return res;
}
예제 #21
0
/*
 * Menu attribute get/set functions - menu_attributes(3X) man page
 */
static VALUE rbncurs_c_set_menu_fore(VALUE rb_menu, VALUE attr)
{
  MENU *menu = get_menu(rb_menu);
  return INT2NUM(set_menu_fore(menu, NUM2ULONG(attr)));
}
예제 #22
0
파일: term.c 프로젝트: lchsk/xstarter
static void
prepare_for_new_results(Boolean clear)
{
    results_not_found = False;
    const config_t *conf = config();

    clear_menu(clear);

    choices_cnt = g_list_length(results);

    if (choices_cnt == 0) {
        no_results();
    }

    list_items = (ITEM**) calloc(choices_cnt + 1, sizeof(ITEM*));

    for (int i = 0; i < choices_cnt; i++) {
        if (results_not_found) {
            if (query_len == 0) {
                list_items[i] = new_item("Start typing to search", "");
            } else {
                list_items[i] = new_item("No results, sorry", "");
            }
        } else {
            GList *l = g_list_nth(results, i);
            char *path = l->data;

            char *name = g_path_get_basename(path);
            names = g_list_prepend(names, name);

            if (conf->section_main->numeric_shortcuts) {
                if (i < 10) {
                    list_items[i] = new_item(digits[i], name);
                }
                else
                    list_items[i] = new_item(" ", name);
            } else {
                list_items[i] = new_item(name, (char*) NULL);
            }
        }
    }

    list_items[choices_cnt] = new_item((char*) NULL, (char*) NULL);

    menu_list = new_menu((ITEM**) list_items);

    window = newwin(
        30, // rows
        30, // cols
        2,
        0
    );

    keypad(window, TRUE);
    /* nodelay(window, TRUE); */

    set_menu_win(menu_list, window);
    set_menu_mark(menu_list, "");
    set_menu_fore(menu_list, COLOR_PAIR(XS_COLOR_PAIR_1));
    set_menu_format(menu_list, 10, 1);

    post_menu(menu_list);

    update_info_bar();

    refresh();
}
예제 #23
0
/*
 * Create and initialize a new popup. popup_btn_action *must* be filled before
 * this call.
 * @param rows The number of rows for win_body
 * @param cols The number of lines for win_body
 * @param posy Position of the top left corner on the y axis
 * @param posx Position of the top left corner on the x axis
 * @param requests An array of strings to put in the form. This can be null:
 *	only the title and the buttons will be present.
 * @param title A string to print in the popup.
 */
void popup_new(int rows, int cols, int posy, int posx, char **requests,
		char *title)
{
	int i, cury = 0, curx = 1, tmp, nb_buttons, nb_fields;
	WINDOW *inner;

	win_body = newwin(rows, cols, posy, posx);
	assert(win_body != NULL && popup_btn_action != NULL);
	box(win_body, 0, 0);

	for (nb_buttons = 0; popup_btn_action[nb_buttons]; nb_buttons++);

	popup_items = malloc(sizeof(ITEM *) * (nb_buttons+1));
	assert(popup_items != NULL);
	assert(popup_btn_action != NULL);

	for (i = 0; popup_btn_action[i]; i++) {
		popup_items[i] = new_item(popup_btn_action[i]->key, "");
		assert(popup_items[i] != NULL);
	}

	popup_items[i] = NULL;
	popup_menu = new_menu(popup_items);
	win_menu = derwin(win_body, 3, cols-2, rows-4, 1);
	assert(popup_menu != NULL && win_menu != NULL);
	box(win_menu, 0, 0);
	set_menu_win(popup_menu, win_menu);
	set_menu_format(popup_menu, 1, nb_buttons);
	tmp = popup_menu->fcols * (popup_menu->namelen + popup_menu->spc_rows);
	tmp--;
	inner = derwin(win_menu, 1, tmp, 1, (cols-3-tmp)/2);
	assert(inner != NULL);
	set_menu_sub(popup_menu, inner);
	set_menu_mark(popup_menu, "");
	assert(post_menu(popup_menu) == E_OK);

	mvwprintw(win_body, 1, 2, "%s", title);

	for (nb_fields = 0; requests && requests[nb_fields]; nb_fields++);

	if (nb_fields == 0) {
		popup_fields = NULL;
		popup_form = NULL;
		is_on_button = true;
		return;
	}

	popup_fields = malloc(sizeof(FIELD *) * (nb_fields+1));
	assert(popup_fields != NULL);

	for (i = 0; i < nb_fields && requests[i]; i++) {

		if (i % 2 == 1) {
			popup_fields[i] = new_field(1, 41, cury, curx, 0, 0);
			assert(popup_fields[i] != NULL);
			set_field_buffer(popup_fields[i], 0, strdup(requests[i]));
			cury = cury+1;
			curx = 1;
			field_opts_on(popup_fields[i], O_ACTIVE);
			field_opts_on(popup_fields[i], O_EDIT);
			field_opts_off(popup_fields[i], O_STATIC);
			set_field_back(popup_fields[i], A_UNDERLINE); 
		} else {
			popup_fields[i] = new_field(1, 45, cury, curx, 0, 0);
			assert(popup_fields[i] != NULL);
			set_field_buffer(popup_fields[i], 0, strdup(requests[i]));
			curx = strlen(requests[i]) + 2;
			field_opts_off(popup_fields[i], O_ACTIVE);
			field_opts_off(popup_fields[i], O_EDIT);
		}
	}

	popup_fields[i] = NULL;
	popup_form = new_form(popup_fields);
	assert(popup_form != NULL);
	win_form = derwin(win_body, rows-6, cols-2, 1, 1);
	assert(popup_form != NULL && win_form != NULL);
	assert(set_form_win(popup_form, win_form) == E_OK);

	int diff_rows = popup_form->cols - win_form->_maxx-2;

	/*
	 * There isn't enough rows for the form so we resize win_body and
	 * win_form to fit the form.
	 * This resize isn't needed for the lines (as there is always fery few
	 * of them).
	 */
	if (diff_rows > 0) {
		wresize(win_body, win_body->_maxy, win_body->_maxx + diff_rows);
		wresize(win_form, win_form->_maxy, win_form->_maxx - 2 + diff_rows);
	}

	inner = derwin(win_form, win_form->_maxy-2, win_form->_maxx, 2, 0);
	assert(inner != NULL);
	set_form_sub(popup_form, inner);

	assert(post_form(popup_form) == E_OK);
	is_on_button = false;
	set_menu_fore(popup_menu, A_NORMAL); // "hide" the button
	pos_form_cursor(popup_form);
}
예제 #24
0
void
column_select_create(ui_t *ui)
{
    int attr_id, column;
    MENU *menu;
    column_select_info_t *info;

    // Cerate a new indow for the panel and form
    ui_panel_create(ui, 20, 60);

    // Initialize Filter panel specific data
    info = sng_malloc(sizeof(column_select_info_t));

    // Store it into panel userptr
    set_panel_userptr(ui->panel, (void*) info);

    // Initialize the fields
    info->fields[FLD_COLUMNS_ACCEPT] = new_field(1, 10, ui->height - 2, 13, 0, 0);
    info->fields[FLD_COLUMNS_SAVE]   = new_field(1, 10, ui->height - 2, 25, 0, 0);
    info->fields[FLD_COLUMNS_CANCEL] = new_field(1, 10, ui->height - 2, 37, 0, 0);
    info->fields[FLD_COLUMNS_COUNT] = NULL;

    // Field Labels
    set_field_buffer(info->fields[FLD_COLUMNS_ACCEPT], 0, "[ Accept ]");
    set_field_buffer(info->fields[FLD_COLUMNS_SAVE],   0, "[  Save  ]");
    set_field_buffer(info->fields[FLD_COLUMNS_CANCEL], 0, "[ Cancel ]");

    // Create the form and post it
    info->form = new_form(info->fields);
    set_form_sub(info->form, ui->win);
    post_form(info->form);

    // Create a subwin for the menu area
    info->menu_win = derwin(ui->win, 10, ui->width - 2, 7, 0);

    // Initialize one field for each attribute
    for (attr_id = 0; attr_id < SIP_ATTR_COUNT; attr_id++) {
        // Create a new field for this column
        info->items[attr_id] = new_item("[ ]", sip_attr_get_description(attr_id));
        set_item_userptr(info->items[attr_id], (void*) sip_attr_get_name(attr_id));
    }
    info->items[SIP_ATTR_COUNT] = NULL;

    // Create the columns menu and post it
    info->menu = menu = new_menu(info->items);

    // Set current enabled fields
    // FIXME Stealing Call list columns :/
    call_list_info_t *list_info = call_list_info(ui_find_by_type(PANEL_CALL_LIST));

    // Enable current enabled fields and move them to the top
    for (column = 0; column < list_info->columncnt; column++) {
        const char *attr = list_info->columns[column].attr;
        for (attr_id = 0; attr_id < item_count(menu); attr_id++) {
            if (!strcmp(item_userptr(info->items[attr_id]), attr)) {
                column_select_toggle_item(ui, info->items[attr_id]);
                column_select_move_item(ui, info->items[attr_id], column);
                break;
            }
        }
    }

    // Set main window and sub window
    set_menu_win(menu, ui->win);
    set_menu_sub(menu, derwin(ui->win, 10, ui->width - 5, 7, 2));
    set_menu_format(menu, 10, 1);
    set_menu_mark(menu, "");
    set_menu_fore(menu, COLOR_PAIR(CP_DEF_ON_BLUE));
    menu_opts_off(menu, O_ONEVALUE);
    post_menu(menu);

    // Draw a scrollbar to the right
    info->scroll = ui_set_scrollbar(info->menu_win, SB_VERTICAL, SB_RIGHT);
    info->scroll.max = item_count(menu) - 1;
    ui_scrollbar_draw(info->scroll);

    // Set the window title and boxes
    mvwprintw(ui->win, 1, ui->width / 2 - 14, "Call List columns selection");
    wattron(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF));
    title_foot_box(ui->panel);
    mvwhline(ui->win, 6, 1, ACS_HLINE, ui->width - 1);
    mvwaddch(ui->win, 6, 0, ACS_LTEE);
    mvwaddch(ui->win, 6, ui->width - 1, ACS_RTEE);
    wattroff(ui->win, COLOR_PAIR(CP_BLUE_ON_DEF));

    // Some brief explanation abotu what window shows
    wattron(ui->win, COLOR_PAIR(CP_CYAN_ON_DEF));
    mvwprintw(ui->win, 3, 2, "This windows show the list of columns displayed on Call");
    mvwprintw(ui->win, 4, 2, "List. You can enable/disable using Space Bar and reorder");
    mvwprintw(ui->win, 5, 2, "them using + and - keys.");
    wattroff(ui->win, COLOR_PAIR(CP_CYAN_ON_DEF));

    info->form_active = 0;
}
예제 #25
0
WINDOW* vwm_main_menu(void)
{
   extern WINDOW  *SCREEN_WINDOW;
	MENU           *menu=NULL;
	WINDOW 		   *window;
	gint			   width=0,height=0;
   gint           screen_height;

	VWM_MODULE	   *vwm_module;
	GSList		   *category_list=NULL;
	GSList		   *module_list=NULL;
	GSList		   *node1;
	GSList		   *node2;

	gchar			   **item_list;
   gint           idx=0;

   /* allocate storage for 128 menu items    */
   item_list=(gchar**)g_malloc0(sizeof(gchar*)*(MAX_MENU_ITEMS+1));

   item_list[idx]=g_strdup_printf(" ");
   idx++;
	category_list=vwm_modules_list_categories();
   node1=category_list;
   while(node1!=NULL && idx<MAX_MENU_ITEMS)
   {
      /* skip screensavers */
      if(strcmp((gchar*)node1->data,VWM_SCREENSAVER)==0)
      {
         node1=node1->next;
         continue;
      }

      /* add the category  */
      item_list[idx]=g_strdup_printf("%s",(gchar*)node1->data);
      idx++;
      if(idx==MAX_MENU_ITEMS) break;

      module_list=vwm_modules_list((gchar*)node1->data);
      node2=module_list;
      while(node2!=NULL)
      {
         if(idx==MAX_MENU_ITEMS) break;
         vwm_module=(VWM_MODULE*)node2->data;
         item_list[idx]=g_strdup_printf("..%s",vwm_module->title);
         idx++;
         node2=node2->next;
      }

      /* add a space before the next menu category  */
      if(idx<MAX_MENU_ITEMS)
      {
         item_list[idx]=g_strdup_printf(" ");
         idx++;
      }

      if(module_list!=NULL) g_slist_free(module_list);
      node1=node1->next;
   }
   if(category_list!=NULL) g_slist_free(category_list);

   menu=viper_menu_create(item_list);
   while(idx!=-1)
   {
      g_free(item_list[idx]);
      idx--;
   }
   g_free(item_list);

	/* hide character mark on left hand side */
	set_menu_mark(menu," ");

   window_get_size_scaled(SCREEN_WINDOW,NULL,&screen_height,0,0.80);

	scale_menu(menu,&height,&width);
	width++;
	if(width<16) width=16;
 	/* override the default of 1 column X 16 entries per row */
   if(height>(screen_height-4)) height=screen_height-4;
	set_menu_format(menu,height,1);

	viper_thread_enter();
	window=viper_window_create(" Menu ",1,2,width,height,TRUE);
   /* todo:  it would be nice if the user could resize the window (especially
      in the horizonal direction) and add more columns to the display.  right
      now, it's not a priority (but it would be easy to implement).  just need
      a few lines of code for the event window-resized.  for now, just don't
      allow it */
	set_menu_win(menu,window);
	set_menu_fore(menu,VIPER_COLORS(COLOR_WHITE,COLOR_BLUE) | A_BOLD);
	set_menu_back(menu,VIPER_COLORS(COLOR_BLACK,COLOR_WHITE));
	menu_opts_off(menu,O_NONCYCLIC);
	post_menu(menu);
   vwm_menu_marshall(menu,REQ_DOWN_ITEM);

	/* viper_event_set(window,"window-activate",vwm_main_menu_ON_ACTIVATE,NULL); */
	viper_event_set(window,"window-close",vwm_main_menu_ON_CLOSE,
		(gpointer)menu);
	viper_window_set_key_func(window,vwm_main_menu_ON_KEYSTROKE);
	viper_window_set_userptr(window,(gpointer)menu);

	viper_thread_leave();
	return window;
}
예제 #26
0
파일: gui.c 프로젝트: gmy987/zoltar
/* main gui loop function, can be called repeatedly, until returning 0 */
int loopGui() {
  int c;

  updateGui(guiProgramData, guiContext);

  c = getch();
  
  if(c=='q') {
    return 0;
  }

  switch(guiState) {
    case GUI_STATE_MAIN:
      switch(c) {
        case KEY_DOWN:
          menu_driver(mainMenu, REQ_DOWN_ITEM);
          break;
        case KEY_UP:
          menu_driver(mainMenu, REQ_UP_ITEM);
          break;
        case 10: /* enter */
          {
            switch((int)item_userptr(current_item(mainMenu))) {
              case MENU_ITEM_EXIT:
                return 0;
              case MENU_ITEM_OPMODE:
                set_menu_fore(mainMenu, A_NORMAL);
                guiState = GUI_STATE_OPMODE;
                break;
              case MENU_ITEM_SPECTRA:
                set_menu_fore(mainMenu, A_NORMAL);
                guiState = GUI_STATE_SPECTRA;
                break;
              case MENU_ITEM_INVARIANTS:
                set_menu_fore(mainMenu, A_NORMAL);
                guiState = GUI_STATE_INVARIANTTYPES;
                break;
              default:
                set_menu_fore(mainMenu, A_NORMAL);
                guiState = GUI_STATE_TMP;
                break;
            }
          }
          break;
        default:
          break;
      }
      break;
    case GUI_STATE_OPMODE:
      switch(c) {
        case KEY_DOWN:
          menu_driver(opmodeMenu, REQ_DOWN_ITEM);
          break;
        case KEY_UP:
          menu_driver(opmodeMenu, REQ_UP_ITEM);
          break;
        case 10: /* enter */
          {
            switch((int)item_userptr(current_item(opmodeMenu))) {
              case MENU_ITEM_TRAINING:
                guiProgramData->opMode = 0; /* TODO: define this */
                guiDataChanged = 1;
                break;
              case MENU_ITEM_TESTING:
                guiProgramData->opMode = 1; /* TODO: define this */
                guiDataChanged = 1;
                break;
              default:
                break;
            }
            set_menu_fore(mainMenu, A_STANDOUT);
            guiState = GUI_STATE_MAIN;
          }
          break;
        case KEY_BACKSPACE:
          set_menu_fore(mainMenu, A_STANDOUT);
          guiState = GUI_STATE_MAIN;
          break;
      }
      break;
    case GUI_STATE_SPECTRA:
      switch(c) {
        case KEY_DOWN:
          menu_driver(spectraMenu, REQ_DOWN_ITEM);
          break;
        case KEY_UP:
          menu_driver(spectraMenu, REQ_UP_ITEM);
          break;
        case 10: /* enter */
          guiSelectedSpectrum = item_index(current_item(spectraMenu));
          if(guiSelectedSpectrum >= 0) {
            guiState = GUI_STATE_SPECTRA_OP;
          }
          break;
        case KEY_BACKSPACE:
          set_menu_fore(mainMenu, A_STANDOUT);
          guiState = GUI_STATE_MAIN;
          break;
      }
      break;
    case GUI_STATE_SPECTRA_OP:
      switch(c) {
        case KEY_DOWN:
          menu_driver(spectraOpMenu, REQ_DOWN_ITEM);
          break;
        case KEY_UP:
          menu_driver(spectraOpMenu, REQ_UP_ITEM);
          break;
        case 10: /* enter */
          switch((int)item_userptr(current_item(spectraOpMenu))) {
            case MENU_ITEM_DATA:
              guiSelectedSFLResultOffset = 0;
              guiState = GUI_STATE_SPECTRUM_DATA;
              break;
            case MENU_ITEM_SFL:
              guiState = GUI_STATE_SFL_COEFF;
              break;
            default:
              guiState = GUI_STATE_SPECTRA;
              break;
          }
          break;
        case KEY_BACKSPACE:
          guiState = GUI_STATE_SPECTRA;
          break;
      }
      break;
    case GUI_STATE_SFL_COEFF:
      switch(c) {
        case KEY_DOWN:
          menu_driver(sflCoeffMenu, REQ_DOWN_ITEM);
          break;
        case KEY_UP:
          menu_driver(sflCoeffMenu, REQ_UP_ITEM);
          break;
        case 10: /* enter */
          switch((int)item_userptr(current_item(sflCoeffMenu))) {
            case S_OCHIAI:
            case S_JACCARD:
            case S_TARANTULA:
              guiSelectedSFLCoeff = (int)item_userptr(current_item(sflCoeffMenu));
              guiSFL = performSFL(guiProgramData, guiSelectedSpectrum, guiSelectedSFLCoeff);
              guiSelectedSFLResultOffset = 0;
              guiState = GUI_STATE_SFL_RESULT;
              break;
            default:
              guiState = GUI_STATE_SPECTRA_OP;
              break;
          }
          break;
        case KEY_BACKSPACE:
          guiState = GUI_STATE_SPECTRA_OP;
          break;
      }
      break;
    case GUI_STATE_SFL_RESULT:
      switch(c) {
        case KEY_DOWN:
          if(guiSelectedSFLResultOffset < (int)getSpectrum(guiProgramData, guiSelectedSpectrum)->nComponents - SFL_VISIBLE_RESULTS) {
            guiSelectedSFLResultOffset += 1;
          }
          break;
        case KEY_UP:
          if(guiSelectedSFLResultOffset > 0) {
            guiSelectedSFLResultOffset -= 1;
          }
          break;
        case KEY_NPAGE:
          guiSelectedSFLResultOffset += SFL_VISIBLE_RESULTS;
          if(guiSelectedSFLResultOffset > (int)getSpectrum(guiProgramData, guiSelectedSpectrum)->nComponents - SFL_VISIBLE_RESULTS) {
            guiSelectedSFLResultOffset = (int)getSpectrum(guiProgramData, guiSelectedSpectrum)->nComponents - SFL_VISIBLE_RESULTS;
          }
          if(guiSelectedSFLResultOffset < 0) {
            guiSelectedSFLResultOffset = 0;
          }
          break;
        case KEY_PPAGE:
          guiSelectedSFLResultOffset -= SFL_VISIBLE_RESULTS;
          if(guiSelectedSFLResultOffset < 0) {
            guiSelectedSFLResultOffset = 0;
          }
          break;
        case KEY_BACKSPACE:
          guiState = GUI_STATE_SFL_COEFF;
          break;
      }
      break;
    case GUI_STATE_SPECTRUM_DATA:
      switch(c) {
        case KEY_DOWN:
          if(guiSelectedSFLResultOffset < (int)getSpectrum(guiProgramData, guiSelectedSpectrum)->nComponents - SFL_VISIBLE_RESULTS) {
            guiSelectedSFLResultOffset += 1;
          }
          break;
        case KEY_UP:
          if(guiSelectedSFLResultOffset > 0) {
            guiSelectedSFLResultOffset -= 1;
          }
          break;
        case KEY_NPAGE:
          guiSelectedSFLResultOffset += SFL_VISIBLE_RESULTS;
          if(guiSelectedSFLResultOffset > (int)getSpectrum(guiProgramData, guiSelectedSpectrum)->nComponents - SFL_VISIBLE_RESULTS) {
            guiSelectedSFLResultOffset = (int)getSpectrum(guiProgramData, guiSelectedSpectrum)->nComponents - SFL_VISIBLE_RESULTS;
          }
          if(guiSelectedSFLResultOffset < 0) {
            guiSelectedSFLResultOffset = 0;
          }
          break;
        case KEY_PPAGE:
          guiSelectedSFLResultOffset -= SFL_VISIBLE_RESULTS;
          if(guiSelectedSFLResultOffset < 0) {
            guiSelectedSFLResultOffset = 0;
          }
          break;
        case KEY_BACKSPACE:
          guiState = GUI_STATE_SPECTRA_OP;
          break;
      }
      break;
    case GUI_STATE_INVARIANTTYPES:
      switch(c) {
        case KEY_DOWN:
          menu_driver(invariantTypesMenu, REQ_DOWN_ITEM);
          break;
        case KEY_UP:
          menu_driver(invariantTypesMenu, REQ_UP_ITEM);
          break;
        case 10: /* enter */
          guiSelectedInvariantType = item_index(current_item(invariantTypesMenu));
          if(guiSelectedInvariantType >= 0) {
            refreshInvariantsList();
            guiState = GUI_STATE_INVARIANTS;
            guiSelectedInvariantMode = INV_MODE_RANGE;
          }
          break;
        case KEY_BACKSPACE:
          set_menu_fore(mainMenu, A_STANDOUT);
          guiState = GUI_STATE_MAIN;
          break;
      }
      break;
    case GUI_STATE_INVARIANTS:
      switch(c) {
        case KEY_DOWN:
          menu_driver(invariantsMenuScr, REQ_DOWN_ITEM);
          menu_driver(invariantsMenuRng, REQ_DOWN_ITEM);
          menu_driver(invariantsMenuBmsk, REQ_DOWN_ITEM);
          break;
        case KEY_UP:
          menu_driver(invariantsMenuScr, REQ_UP_ITEM);
          menu_driver(invariantsMenuRng, REQ_UP_ITEM);
          menu_driver(invariantsMenuBmsk, REQ_UP_ITEM);
          break;
        case KEY_RIGHT:
          guiSelectedInvariantMode = (guiSelectedInvariantMode + 1 + 3)%3;
          break;
        case KEY_LEFT:
          guiSelectedInvariantMode = (guiSelectedInvariantMode - 1 + 3)%3;
          break;
        case KEY_NPAGE:
          {
            int i;
            for(i=0; i<10; i++) {
              menu_driver(invariantsMenuScr, REQ_DOWN_ITEM);
              menu_driver(invariantsMenuRng, REQ_DOWN_ITEM);
              menu_driver(invariantsMenuBmsk, REQ_DOWN_ITEM);
            }
          }
          break;
        case KEY_PPAGE:
          {
            int i;
            for(i=0; i<10; i++) {
              menu_driver(invariantsMenuScr, REQ_UP_ITEM);
              menu_driver(invariantsMenuRng, REQ_UP_ITEM);
              menu_driver(invariantsMenuBmsk, REQ_UP_ITEM);
            }
          }
          break;
        case 10: /* enter */
          guiSelectedInvariant = item_index(current_item(invariantsMenuScr));
          if(guiSelectedInvariant >= 0) {
            guiInv = getInvariantType(guiProgramData, guiSelectedInvariantType)->data[guiSelectedInvariant];
            guiState = GUI_STATE_INVARIANT_EDIT;
            guiEditState = GUI_EDIT_STATE_NONE;
            guiSelectedEditState = 0;
          }
          break;
        case KEY_BACKSPACE:
          guiState = GUI_STATE_INVARIANTTYPES;
          break;
      }
      break;
    case GUI_STATE_INVARIANT_EDIT:
      if(guiEditState == GUI_EDIT_STATE_NONE) {
        switch(c) {
          case KEY_UP:
            guiSelectedEditState = (guiSelectedEditState - 1 + 4)%4;
            break;
          case KEY_DOWN:
            guiSelectedEditState = (guiSelectedEditState + 1 + 4)%4;
            break;
          case 10: /* enter */
            guiEditState = guiSelectedEditState+1;
            guiSelectedInvariant = item_index(current_item(invariantsMenuScr));
            break;
          case KEY_BACKSPACE:
            refreshInvariantsList();
            guiState = GUI_STATE_INVARIANTS;
            break;
        }
      }
      if(guiEditState != GUI_EDIT_STATE_NONE) {
        if(guiEditState == GUI_EDIT_STATE_MIN) {
          switch(guiInv.datatype) {
            case DATA_TYPE_INT:
              editValue(textMin, &guiInv.range.i.min, DATA_TYPE_INT);
              break;
            case DATA_TYPE_UINT:
            case DATA_TYPE_UNSET:
              editValue(textMin, &guiInv.range.u.min, DATA_TYPE_UINT);
              break;
            case DATA_TYPE_DOUBLE:
              editValue(textMin, &guiInv.range.d.min, DATA_TYPE_DOUBLE);
              break;
            case DATA_TYPE_PTR:
              editValue(textMin, &guiInv.range.p.min, DATA_TYPE_PTR);
              break;
          }
        } else if(guiEditState == GUI_EDIT_STATE_MAX) {
          switch(guiInv.datatype) {
            case DATA_TYPE_INT:
              editValue(textMax, &guiInv.range.i.max, DATA_TYPE_INT);
              break;
            case DATA_TYPE_UINT:
            case DATA_TYPE_UNSET:
              editValue(textMax, &guiInv.range.u.max, DATA_TYPE_UINT);
              break;
            case DATA_TYPE_DOUBLE:
              editValue(textMax, &guiInv.range.d.max, DATA_TYPE_DOUBLE);
              break;
            case DATA_TYPE_PTR:
              editValue(textMax, &guiInv.range.p.max, DATA_TYPE_PTR);
              break;
          }
        } else if(guiEditState == GUI_EDIT_STATE_FIRST) {
          editValue(textFirst, &guiInv.bitmask.first, DATA_TYPE_PTR);
        } else if(guiEditState == GUI_EDIT_STATE_MASK) {
          editValue(textMask, &guiInv.bitmask.mask, DATA_TYPE_PTR);
        }
        guiEditState = GUI_EDIT_STATE_NONE;
        getInvariantType(guiProgramData, guiSelectedInvariantType)->data[guiSelectedInvariant] = guiInv;
        guiDataChanged = 1;
      }
      break;
    case GUI_STATE_TMP:
    default:
      switch(c) {
        case KEY_BACKSPACE:
          set_menu_fore(mainMenu, A_STANDOUT);
          guiState = GUI_STATE_MAIN;
          break;
      }
      break;
  }
  return 1;
}
예제 #27
0
WINDOW* vwm_main_menu(void)
{
    extern WINDOW   *SCREEN_WINDOW;
	MENU            *menu = NULL;
	WINDOW 		    *window;
	int			    width = 0,height = 0;
    int             screen_height;

	vwm_module_t	*vwm_module;
    char            buf[NAME_MAX];

    gchar			**item_list;
    int             idx = 0;
    int             i;

    // allocate storage for a total of MAX_MENU_ITEMS
    item_list = (gchar**)g_malloc0(sizeof(gchar*) * (MAX_MENU_ITEMS + 1));

    item_list[idx] = g_strdup_printf(" ");
    idx++;

    // iterate through the categories defined in modules.def
    for(i = 0;i < VWM_MOD_TYPE_MAX;i++)
    {
        // skip screensaver type modules.  they are a special class.
        if(i == VWM_MOD_TYPE_SCREENSAVER) continue;

        // print the menu category (type) to the window
        item_list[idx] = g_strdup_printf("%s",modtype_desc[i]);
        idx++;

        vwm_module = NULL;

        do
        {
            if(idx == MAX_MENU_ITEMS) break;

            vwm_module = vwm_module_find_by_type(vwm_module,i);
            if(vwm_module == NULL) break;

            vwm_module_get_title(vwm_module,buf,sizeof(buf) - 1);
            item_list[idx] = g_strdup_printf("..%s",buf);
            idx++;
        }
        while(vwm_module != NULL);

        // add a space before the next menu category
        if(idx < MAX_MENU_ITEMS)
        {
            item_list[idx] = g_strdup_printf(" ");
            idx++;
        }
    }

    menu = viper_menu_create(item_list);
    while(idx != -1)
    {
        g_free(item_list[idx]);
        idx--;
    }
    g_free(item_list);

	// hide character mark on left hand side
	set_menu_mark(menu," ");

    window_get_size_scaled(SCREEN_WINDOW,NULL,&screen_height,0,0.80);

	scale_menu(menu,&height,&width);
	width++;
	if(width < 16) width = 16;

 	// override the default of 1 column X 16 entries per row
    if(height>(screen_height-4)) height=screen_height-4;
	set_menu_format(menu,height,1);

	viper_thread_enter();
	window = viper_window_create(" Menu ",1,2,width,height,TRUE);
    /*
        todo:   it would be nice if the user could resize the menu
                (especially in the horizonal direction) and add more
                columns to the display.  right now, it's not a priority
                (but it would be easy to implement).  just need a few
                lines of code for the event window-resized.  for now,
                just don't allow it
    */
	set_menu_win(menu,window);
	set_menu_fore(menu,VIPER_COLORS(COLOR_WHITE,COLOR_BLUE) | A_BOLD);
	set_menu_back(menu,VIPER_COLORS(COLOR_BLACK,COLOR_WHITE));
	menu_opts_off(menu,O_NONCYCLIC);
	post_menu(menu);
    vwm_menu_marshall(menu,REQ_DOWN_ITEM);

	/* viper_event_set(window,"window-activate",vwm_main_menu_ON_ACTIVATE,NULL); */
	viper_event_set(window,"window-close",vwm_main_menu_ON_CLOSE,
		(gpointer)menu);
	viper_window_set_key_func(window,vwm_main_menu_ON_KEYSTROKE);
	viper_window_set_userptr(window,(gpointer)menu);

	viper_thread_leave();
	return window;
}