core/MenuManager.cpp
changeset 1653 ad81268fb2f2
parent 1476 24da5fadf93f
child 1766 d30c252089be
     1.1 --- a/core/MenuManager.cpp	Mon Oct 29 00:33:20 2007 +0000
     1.2 +++ b/core/MenuManager.cpp	Tue Oct 30 01:22:47 2007 +0000
     1.3 @@ -211,10 +211,22 @@
     1.4  	IMenuStyle *style = menu->GetDrawStyle();
     1.5  	unsigned int pgn = menu->GetPagination();
     1.6  	unsigned int maxItems = style->GetMaxPageItems();
     1.7 +	bool exitButton = (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXIT) == MENUFLAG_BUTTON_EXIT;
     1.8 +
     1.9  	if (pgn != MENU_NO_PAGINATION)
    1.10  	{
    1.11  		maxItems = pgn;
    1.12  	}
    1.13 +	else if (exitButton)
    1.14 +	{
    1.15 +		maxItems--;
    1.16 +	}
    1.17 +
    1.18 +	/* This is very not allowed! */
    1.19 +	if (maxItems < 2)
    1.20 +	{
    1.21 +		return NULL;
    1.22 +	}
    1.23  
    1.24  	unsigned int totalItems = menu->GetItemCount();
    1.25  	unsigned int startItem = 0;
    1.26 @@ -234,7 +246,9 @@
    1.27  				startItem = totalItems - 1;
    1.28  				order = ItemOrder_Descending;
    1.29  			}
    1.30 -		} else if (order == ItemOrder_Descending) {
    1.31 +		}
    1.32 +		else if (order == ItemOrder_Descending)
    1.33 +		{
    1.34  			startItem = md.firstItem;
    1.35  			/* This shouldn't happen with well-coded menus.
    1.36  			 * If searching backwards doesn't give us enough room,
    1.37 @@ -249,11 +263,16 @@
    1.38  	}
    1.39  
    1.40  	/* Get our Display pointer and initialize some crap */
    1.41 -	IMenuPanel *display = menu->CreatePanel();
    1.42 +	IMenuPanel *panel = menu->CreatePanel();
    1.43  	IMenuHandler *mh = md.mh;
    1.44  	bool foundExtra = false;
    1.45  	unsigned int extraItem = 0;
    1.46  
    1.47 +	if (panel == NULL)
    1.48 +	{
    1.49 +		return NULL;
    1.50 +	}
    1.51 +
    1.52  	/**
    1.53  	 * We keep searching until:
    1.54  	 * 1) There are no more items
    1.55 @@ -271,7 +290,7 @@
    1.56  			/* Ask the user to change the style, if necessary */
    1.57  			mh->OnMenuDrawItem(menu, client, i, dr.style);
    1.58  			/* Check if it's renderable */
    1.59 -			if (IsSlotItem(display, dr.style))
    1.60 +			if (IsSlotItem(panel, dr.style))
    1.61  			{
    1.62  				/* If we've already found the max number of items,
    1.63  				 * This means we should just cancel out and log our
    1.64 @@ -318,31 +337,32 @@
    1.65  	/* There were no items to draw! */
    1.66  	if (!foundItems)
    1.67  	{
    1.68 -		display->DeleteThis();
    1.69 +		panel->DeleteThis();
    1.70  		return NULL;
    1.71  	}
    1.72  
    1.73 -	/* Check initial buttons */
    1.74  	bool displayPrev = false;
    1.75  	bool displayNext = false;
    1.76 -	if (foundExtra)
    1.77 -	{
    1.78 -		if (order == ItemOrder_Descending)
    1.79 -		{
    1.80 -			displayPrev = true;
    1.81 -			md.firstItem = extraItem;
    1.82 -		} else if (order == ItemOrder_Ascending) {
    1.83 -			displayNext = true;
    1.84 -			md.lastItem = extraItem;
    1.85 -		}
    1.86 -	}
    1.87  
    1.88 -	/**
    1.89 -	 * If we're paginated, we have to find if there is another page.
    1.90 -	 * Sadly, the only way to do this is to try drawing more items!
    1.91 +	/* This is an annoying process.
    1.92 +	 * Skip it for non-paginated menus, which get special treatment.
    1.93  	 */
    1.94  	if (pgn != MENU_NO_PAGINATION)
    1.95  	{
    1.96 +		if (foundExtra)
    1.97 +		{
    1.98 +			if (order == ItemOrder_Descending)
    1.99 +			{
   1.100 +				displayPrev = true;
   1.101 +				md.firstItem = extraItem;
   1.102 +			}
   1.103 +			else if (order == ItemOrder_Ascending)
   1.104 +			{
   1.105 +				displayNext = true;
   1.106 +				md.lastItem = extraItem;
   1.107 +			}
   1.108 +		}
   1.109 +
   1.110  		unsigned int lastItem = 0;
   1.111  		ItemDrawInfo dr;
   1.112  		/* Find the last feasible item to search from. */
   1.113 @@ -358,7 +378,7 @@
   1.114  				if (menu->GetItemInfo(lastItem, &dr) != NULL)
   1.115  				{
   1.116  					mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
   1.117 -					if (IsSlotItem(display, dr.style))
   1.118 +					if (IsSlotItem(panel, dr.style))
   1.119  					{
   1.120  						displayNext = true;
   1.121  						md.lastItem = lastItem;
   1.122 @@ -366,7 +386,9 @@
   1.123  					}
   1.124  				}
   1.125  			}
   1.126 -		} else if (order == ItemOrder_Ascending) {
   1.127 +		}
   1.128 +		else if (order == ItemOrder_Ascending)
   1.129 +		{
   1.130  			lastItem = drawItems[0].position;
   1.131  			if (lastItem == 0)
   1.132  			{
   1.133 @@ -378,7 +400,7 @@
   1.134  				if (menu->GetItemInfo(lastItem, &dr) != NULL)
   1.135  				{
   1.136  					mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
   1.137 -					if (IsSlotItem(display, dr.style))
   1.138 +					if (IsSlotItem(panel, dr.style))
   1.139  					{
   1.140  						displayPrev = true;
   1.141  						md.firstItem = lastItem;
   1.142 @@ -389,6 +411,7 @@
   1.143  			}
   1.144  		}
   1.145  	}
   1.146 +
   1.147  skip_search:
   1.148  
   1.149  	/* Draw the item according to the order */
   1.150 @@ -400,9 +423,9 @@
   1.151  		for (unsigned int i = 0; i < foundItems; i++)
   1.152  		{
   1.153  			ItemDrawInfo &dr = drawItems[i].draw;
   1.154 -			if ((position = mh->OnMenuDisplayItem(menu, client, display, drawItems[i].position, dr)) == 0)
   1.155 +			if ((position = mh->OnMenuDisplayItem(menu, client, panel, drawItems[i].position, dr)) == 0)
   1.156  			{
   1.157 -				position = display->DrawItem(dr);
   1.158 +				position = panel->DrawItem(dr);
   1.159  			}
   1.160  			if (position != 0)
   1.161  			{
   1.162 @@ -421,9 +444,9 @@
   1.163  		while (i--)
   1.164  		{
   1.165  			ItemDrawInfo &dr = drawItems[i].draw;
   1.166 -			if ((position = mh->OnMenuDisplayItem(menu, client, display, drawItems[i].position, dr)) == 0)
   1.167 +			if ((position = mh->OnMenuDisplayItem(menu, client, panel, drawItems[i].position, dr)) == 0)
   1.168  			{
   1.169 -				position = display->DrawItem(dr);
   1.170 +				position = panel->DrawItem(dr);
   1.171  			}
   1.172  			if (position != 0)
   1.173  			{
   1.174 @@ -434,13 +457,18 @@
   1.175  	}
   1.176  
   1.177  	/* Now, we need to check if we need to add anything extra */
   1.178 -	if (pgn != MENU_NO_PAGINATION)
   1.179 +	if (pgn != MENU_NO_PAGINATION || exitButton)
   1.180  	{
   1.181 -		bool canDrawDisabled = display->CanDrawItem(ITEMDRAW_DISABLED|ITEMDRAW_CONTROL);
   1.182 -		bool exitButton = (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXIT) == MENUFLAG_BUTTON_EXIT;
   1.183 -		bool exitBackButton = (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXITBACK) == MENUFLAG_BUTTON_EXITBACK;
   1.184 +		bool canDrawDisabled = panel->CanDrawItem(ITEMDRAW_DISABLED|ITEMDRAW_CONTROL);
   1.185 +		bool exitBackButton = false;
   1.186  		char text[50];
   1.187  
   1.188 +		if (pgn != MENU_NO_PAGINATION
   1.189 +			&& (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXITBACK) == MENUFLAG_BUTTON_EXITBACK)
   1.190 +		{
   1.191 +			exitBackButton = true;
   1.192 +		}
   1.193 +
   1.194  		/* Calculate how many items we are allowed for control stuff */
   1.195  		unsigned int padding = style->GetMaxPageItems() - maxItems;
   1.196  		
   1.197 @@ -461,8 +489,11 @@
   1.198  		}
   1.199  #endif
   1.200  
   1.201 -		/* Subtract two slots for the displayNext/displayPrev padding */
   1.202 -		padding -= 2;
   1.203 +		if (pgn != MENU_NO_PAGINATION)
   1.204 +		{
   1.205 +			/* Subtract two slots for the displayNext/displayPrev padding */
   1.206 +			padding -= 2;
   1.207 +		}
   1.208  
   1.209  		/* If we have an "Exit Back" button and the space to draw it, do so. */
   1.210  		if (exitBackButton)
   1.211 @@ -470,7 +501,9 @@
   1.212  			if (!displayPrev)
   1.213  			{
   1.214  				displayPrev = true;
   1.215 -			} else {
   1.216 +			}
   1.217 +			else
   1.218 +			{
   1.219  				exitBackButton = false;
   1.220  			}
   1.221  		}
   1.222 @@ -493,7 +526,7 @@
   1.223  			/* Add spacers so we can pad to the end */
   1.224  			for (unsigned int i=0; i<padding; i++)
   1.225  			{
   1.226 -				position = display->DrawItem(padItem);
   1.227 +				position = panel->DrawItem(padItem);
   1.228  				slots[position].type = ItemSel_None;
   1.229  			}
   1.230  		}
   1.231 @@ -502,60 +535,72 @@
   1.232  		if ((displayPrev || displayNext) || exitButton)
   1.233  		{
   1.234  			ItemDrawInfo draw("", ITEMDRAW_RAWLINE|ITEMDRAW_SPACER);
   1.235 -			display->DrawItem(draw);
   1.236 +			panel->DrawItem(draw);
   1.237  		}
   1.238  
   1.239  		ItemDrawInfo dr(text, 0);
   1.240 +
   1.241  		/**
   1.242  		 * If we have one or the other, we need to have spacers for both.
   1.243  		 */
   1.244 -		if (displayPrev || displayNext)
   1.245 +		if (pgn != MENU_NO_PAGINATION)
   1.246  		{
   1.247 -			/* PREVIOUS */
   1.248 -			ItemDrawInfo padCtrlItem(NULL, ITEMDRAW_SPACER|ITEMDRAW_CONTROL);
   1.249 -			if (displayPrev || canDrawDisabled)
   1.250 +			if (displayPrev || displayNext)
   1.251  			{
   1.252 -				if (exitBackButton)
   1.253 +				/* PREVIOUS */
   1.254 +				ItemDrawInfo padCtrlItem(NULL, ITEMDRAW_SPACER|ITEMDRAW_CONTROL);
   1.255 +				if (displayPrev || canDrawDisabled)
   1.256 +				{
   1.257 +					if (exitBackButton)
   1.258 +					{
   1.259 +						CorePlayerTranslate(client, text, sizeof(text), "Back", NULL);
   1.260 +						dr.style = ITEMDRAW_CONTROL;
   1.261 +						position = panel->DrawItem(dr);
   1.262 +						slots[position].type = ItemSel_ExitBack;
   1.263 +					}
   1.264 +					else
   1.265 +					{
   1.266 +						CorePlayerTranslate(client, text, sizeof(text), "Previous", NULL);
   1.267 +						dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
   1.268 +						position = panel->DrawItem(dr);
   1.269 +						slots[position].type = ItemSel_Back;
   1.270 +					}
   1.271 +				}
   1.272 +				else if (displayNext || exitButton)
   1.273  				{
   1.274 -					CorePlayerTranslate(client, text, sizeof(text), "Back", NULL);
   1.275 -					dr.style = ITEMDRAW_CONTROL;
   1.276 -					position = display->DrawItem(dr);
   1.277 -					slots[position].type = ItemSel_ExitBack;
   1.278 -				} else {
   1.279 -					CorePlayerTranslate(client, text, sizeof(text), "Previous", NULL);
   1.280 -					dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
   1.281 -					position = display->DrawItem(dr);
   1.282 -					slots[position].type = ItemSel_Back;
   1.283 +					/* If we can't display this, and there is an exit button,
   1.284 +					 * we need to pad!
   1.285 +					 */
   1.286 +					position = panel->DrawItem(padCtrlItem);
   1.287 +					slots[position].type = ItemSel_None;
   1.288 +				}
   1.289 +
   1.290 +				/* NEXT */
   1.291 +				if (displayNext || canDrawDisabled)
   1.292 +				{
   1.293 +					CorePlayerTranslate(client, text, sizeof(text), "Next", NULL);
   1.294 +					dr.style = (displayNext ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
   1.295 +					position = panel->DrawItem(dr);
   1.296 +					slots[position].type = ItemSel_Next;
   1.297  				}
   1.298 -			} else if (displayNext || exitButton) {
   1.299 -				/* If we can't display this, and there is an exit button,
   1.300 -				 * we need to pad!
   1.301 -				 */
   1.302 -				position = display->DrawItem(padCtrlItem);
   1.303 +				else if (exitButton)
   1.304 +				{
   1.305 +					/* If we can't display this,
   1.306 +					 * but there is an "exit" button, we need to pad!
   1.307 +					 */
   1.308 +					position = panel->DrawItem(padCtrlItem);
   1.309 +					slots[position].type = ItemSel_None;
   1.310 +				}
   1.311 +			}
   1.312 +			else
   1.313 +			{
   1.314 +				/* Otherwise, bump to two slots! */
   1.315 +				ItemDrawInfo numBump(NULL, ITEMDRAW_NOTEXT);
   1.316 +				position = panel->DrawItem(numBump);
   1.317 +				slots[position].type = ItemSel_None;
   1.318 +				position = panel->DrawItem(numBump);
   1.319  				slots[position].type = ItemSel_None;
   1.320  			}
   1.321 -
   1.322 -			/* NEXT */
   1.323 -			if (displayNext || canDrawDisabled)
   1.324 -			{
   1.325 -				CorePlayerTranslate(client, text, sizeof(text), "Next", NULL);
   1.326 -				dr.style = (displayNext ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
   1.327 -				position = display->DrawItem(dr);
   1.328 -				slots[position].type = ItemSel_Next;
   1.329 -			} else if (exitButton) {
   1.330 -				/* If we can't display this,
   1.331 -				 * but there is an "exit" button, we need to pad!
   1.332 -				 */
   1.333 -				position = display->DrawItem(padCtrlItem);
   1.334 -				slots[position].type = ItemSel_None;
   1.335 -			}
   1.336 -		} else {
   1.337 -			/* Otherwise, bump to two slots! */
   1.338 -			ItemDrawInfo numBump(NULL, ITEMDRAW_NOTEXT);
   1.339 -			position = display->DrawItem(numBump);
   1.340 -			slots[position].type = ItemSel_None;
   1.341 -			position = display->DrawItem(numBump);
   1.342 -			slots[position].type = ItemSel_None;
   1.343  		}
   1.344  
   1.345  		/* EXIT */
   1.346 @@ -563,7 +608,7 @@
   1.347  		{
   1.348  			CorePlayerTranslate(client, text, sizeof(text), "Exit", NULL);
   1.349  			dr.style = ITEMDRAW_CONTROL;
   1.350 -			position = display->DrawItem(dr);
   1.351 +			position = panel->DrawItem(dr);
   1.352  			slots[position].type = ItemSel_Exit;
   1.353  		}
   1.354  	}
   1.355 @@ -575,10 +620,10 @@
   1.356  	}
   1.357  
   1.358  	/* Do title stuff */
   1.359 -	mh->OnMenuDisplay(menu, client, display);
   1.360 -	display->DrawTitle(menu->GetDefaultTitle(), true);
   1.361 +	mh->OnMenuDisplay(menu, client, panel);
   1.362 +	panel->DrawTitle(menu->GetDefaultTitle(), true);
   1.363  
   1.364 -	return display;
   1.365 +	return panel;
   1.366  }
   1.367  
   1.368  IMenuStyle *MenuManager::GetDefaultStyle()