Page 1 of 2

A menus package is now available!

Posted: Thu Jul 17, 2014 6:34 pm
by Ayuto
We have finally added a menu package! Below you can find some examples:

#1

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Source.Python
from menus import SimpleMenu
from menus import Option
from menus import Text

from players.entity import PlayerEntity
from players.helpers import index_from_userid

from messages import SayText2
from events import Event


# =============================================================================
# >> GAME EVENTS
# =============================================================================
@Event
def player_say(event):
'''
Called whenever a player says something.
'''

# Did the player say "apples"?
if event.get_string('text') == 'apples':
# Send him the apple menu
my_menu.send(index_from_userid(event.get_int('userid')))

# =============================================================================
# >> CALLBACKS
# =============================================================================
def my_select_callback(menu, ply_index, option):
'''
Called whenever a selection was made.
'''

# Get a PlayerEntity instance
player = PlayerEntity(ply_index)

# Does the player like apples?
if option.value:
SayText2(message='{0} likes apples!'.format(player.name)).send()
else:
SayText2(
message='Everyone likes apples! Go and select "Yes!".').send(
ply_index)

# Return the menu. It will be instantly displayed again.
return menu


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Create a new menu
my_menu = SimpleMenu()

# Add a simple line
my_menu.append(Text('Do you like apples?'))

# Add two answer options. The first argument is the text that is displayed
# in the menu. The second argument is a value that you can access later in
# your select callback
my_menu.append(Option('Yes!', True))
my_menu.append(Option('No!', False))

# Define the select callback
my_menu.select_callback = my_select_callback

#2

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Python
import time

# Source.Python
from menus import SimpleMenu
from menus import Option
from menus import Text

from players.entity import PlayerEntity
from players.helpers import index_from_userid

from events import Event


# =============================================================================
# >> GAME EVENTS
# =============================================================================
@Event
def player_say(event):
'''
Called whenever a player says something.
'''

# Did the player say "menu"?
if event.get_string('text') == 'menu':
# Send the menu
my_menu.send(index_from_userid(event.get_int('userid')))


# =============================================================================
# >> CALLBACKS
# =============================================================================
def my_select_callback(menu, ply_index, option):
'''
Called whenever a selection was made.
'''

# Since only one option was added to the menu, we don't need to make any
# if/elif/else conditions. We just return the other menu
return another_menu

def my_build_callback(menu, ply_index):
'''
Called before the menu is send to a player.
'''

# Clear the menu, so we have an empty menu
menu.clear()

# Get a PlayerEntity instance
player = PlayerEntity(ply_index)

# Welcome the player
menu.append('Hello, {0}!'.format(player.name))

# Add a submenu link
menu.append(Option('Click here to get another menu.'))

# Add an empty line
menu.append(' ')

# Add a simple line
menu.append('Current time:')

# Also, tell the current time
menu.append(time.strftime('%H:%M:%S'))


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Create a menu with a build callback
my_menu = SimpleMenu(
select_callback=my_select_callback,
build_callback=my_build_callback
)

# Create another menu with a single line
another_menu = SimpleMenu(['This is the other menu.'])

#3

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Python
import random

# Source.Python
from menus import PagedMenu
from menus import Option

from events import Event
from players.helpers import index_from_userid


# =============================================================================
# >> CALLBACKS
# =============================================================================
def my_select_callback(menu, ply_index, option):
'''
Called whenever a selection was made.
'''

# Shuffle the menu : D
random.shuffle(menu)

# Make it sticky
return menu


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
my_menu = PagedMenu(
title='Welcome menu',
description='Choose an option:',
select_callback=my_select_callback
)

# Add some options
for x in range(40):
my_menu.append(Option('Test {0}'.format(x), x))


# =============================================================================
# >> GAME EVENTS
# =============================================================================
@Event
def player_say(event):
'''
Called whenever a player says something.
'''

# Did the player say "menu"?
if event.get_string('text') == 'menu':
# Send the menu
my_menu.send(index_from_userid(event.get_int('userid')))

If you have any suggestions or found a bug, please let us know about it! :)

Posted: Thu Jul 17, 2014 7:04 pm
by TPDerp
Woot! This is awesome! (yes, I came on only to write this)

Posted: Fri Jul 18, 2014 1:05 am
by satoon101
Awesome!! Good job, Ayuto :) We've been needing this for a long time.

*Edit: since this is a big feature we know many people have been waiting for, we decided to post a new release.
https://github.com/Source-Python-Dev-Team/Source.Python/releases

Posted: Fri Jul 18, 2014 3:47 am
by Woody
Great job Ayuto! I've been waiting for this!

Posted: Fri Jul 18, 2014 10:07 am
by Predz
Thanks Ayuto. Waiting for this for ages aswell :D

Posted: Sat Jul 26, 2014 12:37 pm
by Ayuto
Thank you all! How is it working so far?

Posted: Sat Jul 26, 2014 2:21 pm
by Predz
Heya. Seems to be working perfectly, thank you.

Only one problem I have found with usability so far. When you use a PagedMenu and the length is only of 1 page. Then the close button is not active. So therefore there is no way to close the page, apart from menuselect a invalid key.

Posted: Sat Jul 26, 2014 2:31 pm
by Ayuto
Actually, menuselect 0 is always enabled. Are you testing on CS:GO?

Posted: Mon Aug 11, 2014 6:06 am
by DJiSer
Ayuto wrote:Actually, menuselect 0 is always enabled. Are you testing on CS:GO?


I can't close both menus(Paged and Simple) by pressing '0'.This button always inactive.

CS:GO Windows

Posted: Mon Aug 11, 2014 9:24 am
by Hedgehog
While working with menus package I faced a problem:
DLL_MessageEnd: Refusing to send user message ShowMenu of 256 bytes to client, user message size limit is 255 bytes

As I know 1 unicode symbol is equal to 2 bytes symbols in size, so if we use unicode in the menu it become twice smaller. Can somebody fix it?

CS:S, Windows, July 17 build

UPD: The menu isn't being send with this error.

UPD: Solved http://www.sourcepython.com/showthread.php?567-A-menus-package-is-now-available!&p=2897&viewfull=1#post2897

Posted: Mon Aug 11, 2014 9:37 am
by Predz
DJ. To use the current Menu Library in CSGO you need to do a small bit of value changing inside the radio.py. Just ensure that the maximum number used is 9.

I did it for my current add-on I am writing, if you would like the python file I am using PM me.

Posted: Mon Aug 11, 2014 6:58 pm
by Hedgehog
Hedgehog wrote:While working with menus package I faced a problem:

As I know 1 unicode symbol is equal to 2 bytes symbols in size, so if we use unicode in the menu it become twice smaller. Can somebody fix it?

CS:S, Windows, July 17 build

UPD: The menu isn't being send with this error.

Doesn't matter.

Setting MAXIMUM_LENGTH to 127 in messages.types.cstrike.showmenu fixed the problem for me.

Posted: Tue Aug 12, 2014 12:53 am
by satoon101
Could you please not delete relevant information from future posts and put an arbitrary "Solved" statement? If someone else encounters the same issue in the future, they won't be able to find reference to it from your original post. I will not restrict forum users to be unable to edit their posts, as there are plenty of times when doing so makes sense, but this is something that always bothers me when I see it.

I went ahead and added back in all of the previous text this time, please try to keep this in mind in the future.

Sorry for the derail, back to the topic at hand. We know about the CS:GO limitation and are working on a fix for that. Once that has been made available, we will post about it.

I would like to add that a suggestion has been put forth by L'In20Cible to allow a user setting on CS:GO (or any future games that have this issue) where a player can use something like the following in their client's autoexec.cfg (or another cfg file that gets executed for their client):

Code: Select all

bind "0" "menuselect 10"
setinfo sp_bound_menuselect10 1

If you bind "menuselect 10" to a key, you will be able to close the menus with that key. This is just a workaround, so by default, menus will still be sent with 9 being "Close". The second line lets SP know that your client has bound "menuselect 10", so that it will utilize 0 as "Close" instead. Of course, you can bind it to any key, but 0 will be the symbol used to represent that choice. We can't get the value you have bound, but we could allow the setting to be the value and show that value in the menu:

Code: Select all

setinfo sp_bound_menuselect10 0
I'm not sure how necessary that is, as 99.9999% of the people would use 0.

This is just an idea, but one I thought worth asking the entire community if they liked or not.

Posted: Thu Oct 09, 2014 7:13 am
by Predz
Is there anyway to specifically define which number value an Option is bound to? Because if you create an SimpleMenu which only contains text and you want a Back/Next/Close Button, it always starts from 1.

Would prefer it if I could make it constant, like in Popuplib. So people don't get different Back/Next/Close values every time they use a Menu.

Posted: Thu Oct 09, 2014 7:46 am
by Ayuto
No, it's currently not possible, but we will consider your suggestion!

Posted: Tue Oct 14, 2014 8:21 am
by 8guawong
sooooooooo how do you close the paged menu????

Predz wrote:DJ. To use the current Menu Library in CSGO you need to do a small bit of value changing inside the radio.py. Just ensure that the maximum number used is 9.

I did it for my current add-on I am writing, if you would like the python file I am using PM me.


how to do this??? what to change in radio.py could you how me?

satoon101 wrote:Could you please not delete relevant information from future posts and put an arbitrary "Solved" statement? If someone else encounters the same issue in the future, they won't be able to find reference to it from your original post. I will not restrict forum users to be unable to edit their posts, as there are plenty of times when doing so makes sense, but this is something that always bothers me when I see it.

I went ahead and added back in all of the previous text this time, please try to keep this in mind in the future.

Sorry for the derail, back to the topic at hand. We know about the CS:GO limitation and are working on a fix for that. Once that has been made available, we will post about it.

I would like to add that a suggestion has been put forth by L'In20Cible to allow a user setting on CS:GO (or any future games that have this issue) where a player can use something like the following in their client's autoexec.cfg (or another cfg file that gets executed for their client):

Code: Select all

bind "0" "menuselect 10"
setinfo sp_bound_menuselect10 1

If you bind "menuselect 10" to a key, you will be able to close the menus with that key. This is just a workaround, so by default, menus will still be sent with 9 being "Close". The second line lets SP know that your client has bound "menuselect 10", so that it will utilize 0 as "Close" instead. Of course, you can bind it to any key, but 0 will be the symbol used to represent that choice. We can't get the value you have bound, but we could allow the setting to be the value and show that value in the menu:

Code: Select all

setinfo sp_bound_menuselect10 0
I'm not sure how necessary that is, as 99.9999% of the people would use 0.

This is just an idea, but one I thought worth asking the entire community if they liked or not.


doing the bind doesn't close the menu really... the menu still show on screen... it just allow you to press the options and doesn't do the action that is associated with the option

Posted: Tue Oct 14, 2014 12:41 pm
by Ayuto
There is no need to edit anything. Just type bind "0" "menuselect 10" in your client console. If you then hit 0 the menu will close. We will change that in the future, so there is no need to do that.

Posted: Wed Oct 15, 2014 1:12 am
by 8guawong
Ayuto wrote:There is no need to edit anything. Just type bind "0" "menuselect 10" in your client console. If you then hit 0 the menu will close. We will change that in the future, so there is no need to do that.


guess i'll wait for the future then since it would be much easier than having to tell every user that asks that they have to do bind "0" in the console :cool:

Posted: Mon Nov 10, 2014 8:03 am
by 8guawong
is there a timeout option for the current package??

like http://python.eventscripts.com/pages/Popuplib.Popup_base.timeout

Posted: Tue Nov 11, 2014 9:33 pm
by Ayuto
No, currently there isn't, but you can create your own timeout by delay-calling <your menu>.close() after sending it.