Пример #1
0
menu_st *menu_handle_item(menu_st *menulist, int num)
{
	item_st *item;
	/* out of bounds */
	if(num < 0 || num >= menulist->num_items) {
		Dprintf("menu_handle_item::Invalid item");
		return menulist;
	}
	item = &menulist->items[num];
	menulist->lastsel = -1;

	if(SUB_MENU_HEADER & item->op) {
		/* Destroy timer */
		menu_handle_timer(menulist, 1);
		/* create another sub-menu  */
		menulist = menu_right_transition(menulist, item);
	}
	else if(ACTION_MENU & item->op) {
		/* execute the function */
		void (* fp)(void);
		fp = item->action;
		(* fp)();
		menulist->lastsel = 0;
	}
	else if(BOOLEAN_MENU & item->op) {
		/* toggle boolean; draw */
		item->sel_option = !(item->sel_option);
		if(item->setting != 0)
			ipod_set_setting(item->setting, item->sel_option);
		menu_retext_pixmap(menulist, num - menulist->top_item, item);
	}
	else if(OPTION_MENU & item->op) {
		/* rotate option; draw */
		item->sel_option = ((item->sel_option + 1) >
				(item->item_count - 1) ? 0 :
				item->sel_option + 1);
		if(item->setting != 0)
			ipod_set_setting(item->setting, item->sel_option);
		menu_retext_pixmap(menulist, num - menulist->top_item, item);
	}
	
	else if(SETTING_ITEM & item->op) {
		if(item->setting != 0)
			ipod_set_setting(item->setting, item->item_count);
		menulist = menu_destroy(menulist);
	}


	/* this isnt an else, so you can do (ACTION_MENU|SUB_MENU_PREV) */
	if(SUB_MENU_PREV & item->op) {
		menulist = menu_destroy(menulist);
	}
	return menulist;
}
Пример #2
0
/* selects specified item */
void menu_select_item(menu_st *menulist, int sel)
{
	int diff, i, j, tmp;
	
	/* if it goes off the end either way, do nothing */
	if(sel > menulist->num_items - 1 || sel < 0)
		return;

	/* the difference in select */
	diff = sel - menulist->top_item;

	/* set selected */
	menulist->sel = sel;
	
	/* if sel is below the visible screen */
	if(diff > (menulist->screen_items - 1)) {
		/* set top item */
		menulist->top_item = sel - (menulist->screen_items - 1);
		/* for each time the screen shifts down, rotate the pixmaps */
		for(j = diff - (menulist->screen_items - 1); j > 0; j--) {
			tmp = menulist->pixmap_pos[0];
			for(i = 0; i < menulist->screen_items - 1; i++)
				menulist->pixmap_pos[i] =
					menulist->pixmap_pos[i + 1];
			menulist->pixmap_pos[menulist->screen_items - 1] = tmp;
			/* draw appropriate text to the bottom pixmap */
			menu_retext_pixmap(menulist, menulist->screen_items -
					1, &menulist->items[sel - (j-1)]);
		}
	}
	/* if sel is above the visible screen */
	else if(diff < 0) {
		/* set top item */
		menulist->top_item = sel;
		/* for each time the screen shifts up, rotate the pixmaps */
		for(j = diff; j < 0; j++) {
			tmp = menulist->pixmap_pos[menulist->screen_items - 1];
			for(i = menulist->screen_items - 1; i > 0; i--)
				menulist->pixmap_pos[i] =
					menulist->pixmap_pos[i - 1];
			menulist->pixmap_pos[0] = tmp;
			/* draw appropriate text to the top pixmap */
			menu_retext_pixmap(menulist, 0,
					&menulist->items[sel - (j+1)]);
		}
	}
}
Пример #3
0
/* does the drawing, safe(and recommended) to use {in, as} an exposure event */
void menu_draw(menu_st *menulist)
{
	int i;

	/* appearance changed, force a redraw */
	if(menulist->scheme_no != appearance_get_color_scheme() ||
			get_current_font() != menulist->font) {
		menu_update_menu(menulist);
	}

	/* first draw; init onscreen text items */
	if(menulist->init == 0) {
		for(i = (menulist->num_items > menulist->screen_items) ?
				menulist->screen_items : menulist->num_items;
				i; i--)
			menu_retext_pixmap(menulist, i - 1,
				&menulist->items[menulist->top_item + (i - 1)]);
		menulist->init = 1;
	}
#if 0
	else if(menulist->lastsel == menulist->sel) {
		Dprintf("Aborted draw because %d == %d\n", menulist->sel,
				menulist->lastsel);
		return;
	}
	Dprintf("Continuing, %d != %d\n", menulist->sel, menulist->lastsel);
#endif
	/* draw each pixmap */
	for(i = 0; i < menulist->screen_items; i++)
		menu_draw_item(menulist, i);

	/* erase the bottom unused part of the allocated screen */
	GrSetGCForeground(menulist->menu_gc, appearance_get_color( CS_BG ));
	GrFillRect(menulist->menu_wid, menulist->menu_gc, menulist->x,
			menulist->height * menulist->screen_items, menulist->w,
			menulist->h - (menulist->height *
			menulist->screen_items));

	GrSetGCForeground(menulist->menu_gc, BLACK);

	/* draw scrollbar if needed */
	if(menulist->num_items > menulist->screen_items) {
		menulist->scrollbar = 1;
		menu_draw_scrollbar(menulist);
	}
	else
		menulist->scrollbar = 0;

	/* deal with the timer */
	menu_handle_timer(menulist, 0);

	menulist->lastsel = menulist->sel;
}
Пример #4
0
/* removes the referenced item from the menu */
void menu_delete_item(menu_st *menulist, int num)
{
	int i, tmp;
	/* if num is off the end either way, do nothing */
	if(num > menulist->num_items - 1 || num < 0) {
		Dprintf("menu_delete_item::Invalid item\n");
		return;
	}
	if(menulist->alloc_items == 0) {
		Dprintf("menu_delete_item::Deleting from a static menu causes "
				"undefined behavior\n");
		return;
	}

	/* assume removed item is onscreen */
	tmp = menulist->pixmap_pos[num-menulist->top_item];
	for(i = 0; i < (menulist->screen_items-(num-menulist->top_item))-1;
			i++) {
		menulist->pixmap_pos[(num-menulist->top_item) + i] =
			menulist->pixmap_pos[(num-menulist->top_item) + (i+1)];
		menu_draw_item(menulist, num-menulist->top_item + i);
	}
	menulist->pixmap_pos[menulist->screen_items - 1] = tmp;
	
	/* actually remove the item */
	for(i = num; i < menulist->num_items - 1; i++)
		menulist->items[i] = menulist->items[i + 1];
	menulist->num_items--;
	/* if last item was selected, shift selected */
	if(menulist->sel == menulist->num_items)
		menu_shift_selected(menulist, -1);

	/* erase pixmaps that are off the bottom of the list */
	if(menulist->top_item + (menulist->screen_items - 1) >
			menulist->num_items - 1)
		menu_clear_pixmap(menulist, menulist->screen_items - 1);

	/* draw appropriate text to the bottom pixmap */
	else
		menu_retext_pixmap(menulist, menulist->screen_items -
				1, &menulist->items[menulist->top_item +
				(menulist->screen_items - 1)]);

	/* specify if scrollbar should draw */
	if(menulist->num_items <= menulist->screen_items)
		menulist->scrollbar = 0;

}
Пример #5
0
void menu_draw_timer(menu_st *menulist)
{
	char *c = strdup(">");
	int colors[] = {CS_ARROW0, CS_ARROW1, CS_ARROW2, CS_ARROW3,
			CS_ARROW3, CS_ARROW2, CS_ARROW1, CS_ARROW0};

	if(menulist->items[menulist->sel].op & CFLASH) {
		menulist->items[menulist->sel].op ^= CFLASH;
		menu_clear_pixmap(menulist, menulist->sel - menulist->top_item);
		menu_retext_pixmap(menulist, menulist->sel - menulist->top_item,
				&menulist->items[menulist->sel]);
		menu_handle_timer(menulist, 0);
		free(c);
		return;
	}

	if(menulist->items[menulist->sel].text_width >
			menulist->w - (8 + (menulist->scrollbar ? 8 : 0))) {
		int item, diff, move;
		item = menulist->sel - menulist->top_item;
		diff = (menulist->items[menulist->sel].text_width + 8) -
			(menulist->w - (8 + (menulist->scrollbar ? 8 : 0)));
		menulist->timer_step++;
		move = (!((menulist->timer_step / diff) % 2) ?
			(menulist->timer_step % diff) :
			(diff - (menulist->timer_step % diff)));
		if (menulist->timer == INT_MAX - 1)
			menulist->timer = 0;
		/* xor the pixmap */
		GrSetGCMode(menulist->menu_gc, GR_MODE_XOR);
		if (hw_version == 0 || hw_version == 0x6 || hw_version == 0xc || hw_version == 0xb) {
			/* make sure that the xor works properly for devices with
			 * fbrev turned off (host, photo) */
			GrSetGCForeground(menulist->menu_gc, WHITE);
		}
		GrFillRect(menulist->pixmaps[menulist->pixmap_pos[item]],
				menulist->menu_gc, move, 0,
				menulist->w, menulist->height);
		GrCopyArea(menulist->menu_wid, menulist->menu_gc, menulist->x,
				(item * menulist->height) + menulist->y,
				menulist->w - (menulist->scrollbar ? 8 : 0),
				menulist->height,
				menulist->pixmaps[menulist->pixmap_pos[item]],
				move, 0, 0);
		/* un umm xor the pixmap */
		GrFillRect(menulist->pixmaps[menulist->pixmap_pos[item]],
				menulist->menu_gc, move, 0,
				menulist->w, menulist->height);
		GrSetGCMode(menulist->menu_gc, GR_MODE_SET);
		if (hw_version == 0 || hw_version == 0x6 || hw_version == 0xc || hw_version == 0xb) {
			/* reset fix for xor on certain devices (host, photo) */
			GrSetGCForeground(menulist->menu_gc, BLACK);
		}
		free(c);
		return;
	}
	GrSetGCUseBackground(menulist->menu_gc, GR_FALSE);

	/* cycle through colors */
	if (menulist->timer_step < 0 || menulist->timer_step >= 12)
		menulist->timer_step = 0;
	GrSetGCForeground(menulist->menu_gc,
		appearance_get_color(colors[menulist->timer_step < 8 ?
			menulist->timer_step : 7]));
	menulist->timer_step++;

	/* executable instead */
	if(EXECUTE_MENU & menulist->items[menulist->sel].op)
		*c = 'x';
	/* double; with a 1px offset for bold */
	GrText(menulist->menu_wid, menulist->menu_gc, menulist->x +
			(menulist->w - 8) - 6, menulist->height *
			(menulist->sel - menulist->top_item) + menulist->y + 2,
			c, -1, GR_TFASCII | GR_TFTOP);
	GrText(menulist->menu_wid, menulist->menu_gc, menulist->x +
			(menulist->w - 8) - 7, menulist->height *
			(menulist->sel - menulist->top_item) + menulist->y + 2,
			c, -1, GR_TFASCII | GR_TFTOP);
	GrSetGCForeground(menulist->menu_gc, BLACK);
	GrSetGCUseBackground(menulist->menu_gc, GR_TRUE);

	free(c);
}