PDA

View Full Version : About menus *sigh* again


SamuraiBarbi
10-01-2007, 19:44
A large portion of a script I'm working on is dependent on menus and I have a couple questions after reading and researching.

First, I read the following on the wiki about menu api.
"The purpose of Menus is to simplify the procedure of storing, drawing, and calculating the selection of items. Thus, menus do not allow for adding raw text, as that would considerably complicate the drawing algorithm. Note: The C++ API supports hooking IBaseMenu drawing procedures and adding raw text; this will be added to the scripting API soon."

Is this still true? I really need the ability to draw raw text. I mean raw text that doesn't appear as a selection so I can have for instance, a header in a menu or even just so I can display various information in a menu. I thought that maybe using ITEMDRAW_RAWLINE would accomplish this but it wasn't quite what I was trying to accomplish.

Second question is, how can I get around what appears to be a size limitation for menus in Sourcemod? I have an immediate need for the ability to draw a menu larger than what, to my current knowledge the menu system in Sourcemod will allow. I do not want pagination in the menu I'm trying to build, but I do need for it to be larger than what I think is an enforced line limit. I am able to do this using Eventscripts but I'm not sure in what way their method for building menu's differs nor how they managed to allow for scripters to build large menu's.

Thanks!

BAILOPAN
10-01-2007, 20:21
First question: The easiest route is to use panels. If you're really trying to customize your menus, and you have no need for pagination, panels will give you the most flexibility at the price of being very low-level. That means, all of the "nice" features that menus have, such as pagination, item info/text abstraction, and cross-style consistency, won't exist. You just add text to the panel and you're done.

If you decide that managed menus are the way to go, read on. The rest of this post deals with the rendering algorithm and I will answer your second question in a follow-up post.

You can hook the per-item rendering algorithm with MenuAction_DisplayItem and the title-rendering portion with MenuAction_Display. That said, you need to understand how the rendering algorithm works to go further:


First, it decides how many items can be displayed on the current page. That number will be less than or equal to 10 (let's say it's equal to N).
Then it will go through every item on the menu until it meets a certain set of credentials. The credential process:
GetMenuItem() is called to retrieve information about the item.
The MenuHandler is called with MenuAction_DrawItem -- this is so the plugin can override the style normally retrieved by GetMenuItem().
If the item cannot be drawn by the style, it will be ignored. For radio menus, that's having ITEMDRAW_IGNORE, or ITEMDRAW_DISABLED|ITEMDRAW_CONTROL. For VGUI menus, that's having ITEMDRAW_RAWLINE, ITEMDRAW_NOTEXT, ITEMDRAW_SPACER, or ITEMDRAW_DISABLED.
If the item has ITEMDRAW_IGNORE, it is ignored.
If the item has ITEMDRAW_RAWLINE, it is ignored.
Otherwise, the item is stored in an array of "valid" items.

Once the menu has N items, going from item X to X+N, it will then try to match items X-1 and X+N+1 to determine whether there are other pages. That uses the same "credential" process.
The menu is finally ready to draw. It creates a new Panel object, then for each of the N items:
The MenuHandler is called with MenuAction_DisplayItem. This allows the text to be redrawn.
The text is added to the Panel.

Once all items are added to the panel, the MenuHandler is called with MenuAction_Display. If no title is set on the Panel after the handler concludes, then a default title is applied.
The panel is returned from the rendering algorithm, and the menu subsystem displays it to the client.


As you can see, it's an involved, complicated process, completely dedicated to having uniform-looking menus. Letting users attach raw lines of text to a given menu greatly complicates the design -- the rendering algorithm would basically need a complete rewrite. The only viable solution would be to have "sub-items" of text that get drawn along with an item. If we do add that, it won't be for 1.0.0. It's further complicated by the fact that the Valve menu style doesn't really support raw lines of text (other than cramming the button full with one blurb).

That said, we can add a MenuAction_DisplayItemEx callback. This would be a "serious users only" callback that would let you inject raw text during the drawing process. You have to be clever about it, but basically the idea is that the renderer would say, "draw item #2 for me." You could then draw whatever you wanted via the Panel it gives you. (MenuAction_DisplayItem is a simplified handler which just lets you change the selectable text, rather than have full underlying Panel control.)

BAILOPAN
10-01-2007, 20:24
Second question: SourceMod has no real limit to the menu size. The CS:S client has a restriction of 512 bytes (if that's the mod you're using). If that limit has since been increased, it's possible SourceMod is inappropriately truncating it, but I don't think it has been.

SamuraiBarbi
10-02-2007, 01:14
Thx Bailopan, I'm gonna try and work with that and see if I can get somewhere with it.