2024-04-15 18:06:18 +00:00
|
|
|
init python in wheelmenu:
|
|
|
|
import math
|
|
|
|
|
|
|
|
def pos(num_buttons):
|
2024-04-22 17:11:01 +00:00
|
|
|
num_buttons = max(num_buttons, 2)
|
2024-04-15 18:06:18 +00:00
|
|
|
reference_num_buttons = 32
|
|
|
|
reference_radius = 0.5
|
|
|
|
radius = reference_radius * (num_buttons / reference_num_buttons) ** 0.5
|
|
|
|
angle_step = 2 * math.pi / num_buttons
|
|
|
|
start_angle = angle_step / 2 if num_buttons % 2 else 0
|
|
|
|
positions = [(min(max(0.5 + math.cos(start_angle + i * angle_step) * radius, 0.0), 1.0),
|
|
|
|
min(max(0.5 + math.sin(start_angle + i * angle_step) * radius, 0.0), 1.0))
|
|
|
|
for i in range(num_buttons)]
|
|
|
|
return positions
|
|
|
|
|
|
|
|
def button(displayable, action, condition, state=None, **kwargs):
|
|
|
|
"""
|
|
|
|
displayable - Ren'Py displayable
|
|
|
|
action - Ren'Py screen action
|
|
|
|
condition - Boolean
|
|
|
|
state -
|
|
|
|
None - No change
|
|
|
|
"hidden" - Hidden if condition==False
|
|
|
|
"disabled" - Disabled if condition==False
|
|
|
|
"""
|
|
|
|
|
|
|
|
if state == "hidden":
|
|
|
|
return None
|
|
|
|
elif state == "disabled":
|
2024-04-15 18:56:14 +00:00
|
|
|
return renpy.store.Button(displayable, action=action, style="wheelmenu_disabled_button", **kwargs)
|
2024-04-15 18:06:18 +00:00
|
|
|
|
|
|
|
if condition:
|
2024-04-15 18:56:14 +00:00
|
|
|
return renpy.store.Button(displayable, action=action, style="wheelmenu_button", **kwargs)
|
2024-04-22 17:11:01 +00:00
|
|
|
elif action is None:
|
|
|
|
return renpy.store.Button(displayable, action=action, style="wheelmenu_disabled_button", **kwargs)
|
2024-04-15 18:06:18 +00:00
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
init python:
|
|
|
|
def create_wheelmenu(elements):
|
|
|
|
# Proxy function; We cannot evaluate in a named store without side effects.
|
|
|
|
|
|
|
|
buttons = []
|
|
|
|
for name, (displayable, action, condition) in elements.items():
|
|
|
|
condition = eval(condition)
|
|
|
|
|
2024-04-18 15:57:31 +00:00
|
|
|
if not condition:
|
|
|
|
continue
|
|
|
|
|
2024-04-15 18:06:18 +00:00
|
|
|
buttons.append(wheelmenu.button(displayable, action, condition, tooltip=name))
|
|
|
|
|
2024-04-22 17:11:01 +00:00
|
|
|
if not buttons:
|
|
|
|
return None
|
2024-04-15 18:06:18 +00:00
|
|
|
|
2024-04-22 17:11:01 +00:00
|
|
|
positions = wheelmenu.pos(len(buttons))
|
2024-04-15 18:06:18 +00:00
|
|
|
return tuple(zip(buttons, positions)) # Nonhashable types cannot be used in a screen, so we use a tuple instead.
|
|
|
|
|
2024-04-17 20:50:53 +00:00
|
|
|
config.per_frame_screens.append("wheelmenu")
|
|
|
|
|
2024-04-15 18:06:18 +00:00
|
|
|
label wheelmenu(btns, ret, pos=None):
|
2024-04-18 15:57:31 +00:00
|
|
|
play sound "sounds/qubodup-click1.ogg"
|
2024-04-15 18:06:18 +00:00
|
|
|
call screen wheelmenu(btns, pos)
|
|
|
|
|
|
|
|
jump expression ret
|
|
|
|
|
|
|
|
screen wheelmenu(btns, pos):
|
|
|
|
layer "interface"
|
|
|
|
tag wheelmenu
|
2024-05-19 20:12:51 +00:00
|
|
|
zorder 1
|
2024-04-15 18:06:18 +00:00
|
|
|
style_prefix "wheelmenu"
|
|
|
|
|
2024-04-17 20:50:53 +00:00
|
|
|
$ mpos = renpy.get_mouse_pos()
|
|
|
|
default start_pos = pos or mpos
|
2024-04-15 18:06:18 +00:00
|
|
|
|
2024-04-17 20:50:53 +00:00
|
|
|
use close_button_background(keysym="game_menu")
|
2024-04-15 18:06:18 +00:00
|
|
|
|
2024-04-15 18:56:14 +00:00
|
|
|
window at wheelmenu_anim:
|
2024-04-15 18:06:18 +00:00
|
|
|
id "wheelmenu"
|
|
|
|
pos start_pos
|
|
|
|
|
|
|
|
for btn, pos in btns:
|
|
|
|
add btn pos pos
|
|
|
|
|
2024-04-17 20:50:53 +00:00
|
|
|
add "wheelmenu_genie" align (0.5, 0.5) at transform:
|
|
|
|
subpixel True
|
|
|
|
xysize (48, 48)
|
2024-04-18 15:57:31 +00:00
|
|
|
yzoom (1 if mpos[0] < start_pos[0] else -1)
|
2024-04-17 20:50:53 +00:00
|
|
|
rotate (math.degrees(math.atan2(mpos[1] - start_pos[1], mpos[0] - start_pos[0])) + 360) % 360 - 180
|
2024-04-15 18:06:18 +00:00
|
|
|
|
|
|
|
style wheelmenu_window is empty:
|
2024-04-17 20:50:53 +00:00
|
|
|
background Transform("wheelmenu_gradient", align=(0.5, 0.5), xysize=(200, 200))
|
2024-04-15 18:06:18 +00:00
|
|
|
maximum (400, 400)
|
|
|
|
anchor (0.5, 0.5)
|
|
|
|
|
2024-04-15 18:56:14 +00:00
|
|
|
style wheelmenu_button is empty:
|
2024-04-17 18:23:53 +00:00
|
|
|
background Transform("wheelmenu_button", xysize=(48,48))
|
2024-04-17 20:50:53 +00:00
|
|
|
hover_background At(Transform("wheelmenu_button_opaque", xysize=(48,48)), wheelmenu_hover_anim)
|
2024-04-18 15:57:31 +00:00
|
|
|
hover_sound "sounds/qubodup-hover1.ogg"
|
|
|
|
activate_sound "sounds/qubodup-click2.ogg"
|
2024-04-15 18:06:18 +00:00
|
|
|
xysize (48, 48)
|
|
|
|
anchor (0.5, 0.5)
|
|
|
|
|
2024-04-15 18:56:14 +00:00
|
|
|
style wheelmenu_disabled_button is wheelmenu_button:
|
2024-04-15 18:06:18 +00:00
|
|
|
background "#ffffff80"
|
2024-04-22 17:11:01 +00:00
|
|
|
foreground "#ff00ff"
|
2024-04-15 18:56:14 +00:00
|
|
|
xysize (48, 48)
|
|
|
|
anchor (0.5, 0.5)
|
2024-04-15 18:06:18 +00:00
|
|
|
|
|
|
|
style wheelmenu_window_text is default:
|
|
|
|
anchor (0.5, 0.5)
|
|
|
|
color "#fff"
|
|
|
|
size 10
|
|
|
|
outlines [(1, "#00000080", 1, 0)]
|
|
|
|
|
|
|
|
style wheelmenu_button_text is wheelmenu_text
|
|
|
|
|
2024-04-15 18:56:14 +00:00
|
|
|
transform wheelmenu_anim:
|
|
|
|
on show:
|
2024-05-24 11:14:46 +00:00
|
|
|
zoom 0.0
|
|
|
|
alpha 0.0
|
|
|
|
easein_back 0.2 zoom 1.0 alpha 1.0
|
2024-04-15 18:56:14 +00:00
|
|
|
on hide:
|
2024-05-24 11:14:46 +00:00
|
|
|
easeout 0.15 zoom 0.0 alpha 0.0
|
2024-04-15 18:56:14 +00:00
|
|
|
|
2024-04-17 20:50:53 +00:00
|
|
|
transform wheelmenu_hover_anim(t=2.0, strength=0.2, pause=0.0):
|
|
|
|
matrixcolor BrightnessMatrix(value=0.0)
|
|
|
|
linear t/2 matrixcolor BrightnessMatrix(value=strength)
|
|
|
|
linear t/2 matrixcolor BrightnessMatrix(value=0.0)
|
|
|
|
pause pause
|
|
|
|
repeat
|
|
|
|
|
2024-04-15 18:06:18 +00:00
|
|
|
# transform tooltip_follow:
|
|
|
|
# events False
|
|
|
|
# function tooltip_func
|
|
|
|
|
|
|
|
# init python:
|
|
|
|
|
|
|
|
# def tooltip_func(trans, st, at):
|
|
|
|
# x, y = renpy.get_mouse_pos()
|
|
|
|
|
|
|
|
# if trans.pos is not (x, y):
|
|
|
|
# cw, ch = trans.child.window_size
|
|
|
|
|
|
|
|
# xanchor = 1.0 if (x + int(cw)) > (config.screen_width) else 0.0
|
|
|
|
# yanchor = 1.0 if (y + int(ch)) > (config.screen_height) else 0.0
|
|
|
|
|
|
|
|
# xoffset = 18 if xanchor else 0
|
|
|
|
# yoffset = 24 if yanchor else 0
|
|
|
|
# trans.pos = (x, y)
|
|
|
|
# trans.anchor = (xanchor, yanchor)
|
|
|
|
# trans.offset = (xoffset, yoffset)
|
|
|
|
|
|
|
|
# return 0
|
|
|
|
|
|
|
|
# if not renpy.android:
|
|
|
|
|
|
|
|
# config.always_shown_screens.append("tooltip")
|
|
|
|
# config.per_frame_screens.append("tooltip")
|