[Solved] How can I get the X/Y coordinates of a button?

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Insanifeeding
Newbie
Posts: 9
Joined: Wed Mar 08, 2023 10:58 am
Contact:

[Solved] How can I get the X/Y coordinates of a button?

#1 Post by Insanifeeding »

I'm trying to display a screen on top of a button when I hover over the button. I know the size of the button, but its position will vary with other factors. I've tried using renpy.focus_coordinates(), but all I get is a tuple full of None. Here's what I've got so far:

Code: Select all

define xSize = 400
define ySize = 540

label start:
    call screen button_screen
    
screen button_screen():
    default coord = ()
    grid 2 1:
        spacing 20
        align (0.5, 0.5)
        button:
            background Color("#FF0000")
            xysize(xSize, ySize)
            hovered Show("preview_screen", name = "Steve", coord = renpy.focus_coordinates())
            unhovered Hide("preview_screen")
            action [Hide("preview_screen"), Jump("steve")]
        button:
            background Color("#00FF00")
            xysize(xSize, ySize)
            hovered Show("preview_screen", name = "Tristan", coord = renpy.focus_coordinates()) 
            unhovered Hide("preview_screen")
            action [Hide("preview_screen"), Jump("tristan")]
             
screen preview_screen(name, coord = ()):
    frame:
        # renpy.focus_coordinates() should return tuple of (x, y, w, h) of focused displayable
        xpos coord[0]
        ypos coord[1]
        xysize(xSize, ySize)
        background Color("#FFFFFF7F")
        text name:
            color("#0000FF")
            align (0.5, 1.0)

label steve:
    pause

label tristan:
    pause
According to the Button documentation, the button is focused when hovered over:
hovered
An action to run when the button gains focus.
The docs for renpy.focus_coordinates() indicate that it returns coordinates of a focused object:
This attempts to find the coordinates of the currently-focused displayable. If it can, it will return them as a (x, y, w, h) tuple. If not, it will return a (None, None, None, None) tuple.
Is my button not actually focused? What am I missing here?
Last edited by Insanifeeding on Thu Mar 09, 2023 6:06 pm, edited 1 time in total.

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2411
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: How can I get the X/Y coordinates of a button?

#2 Post by Ocelot »

You are missing that focus_coordinates would be run before you hover over button. What happens:
1) Screen is evaluated. Displayables are created, theit properties are set.
2) As part of button creation, action is created, parameters for its creation are evaluated.
3) renpy.focus_coordinates is run. As nothing is shown, nothing is focused yet, so it returns Nones.
< < insert Rick Cook quote here > >

Insanifeeding
Newbie
Posts: 9
Joined: Wed Mar 08, 2023 10:58 am
Contact:

Re: How can I get the X/Y coordinates of a button?

#3 Post by Insanifeeding »

I keep forgetting that screens are evaluated before runtime. Ok, so how would I run focus_coordinates() after objects are created? I tried tying multiple actions to the hovered state:

Code: Select all

hovered [SetScreenVariable("coord", renpy.focus_coordinates()), Show("preview_screen", name = "Tristan", coord = coord)]
That of course didn't work.

Is there some way to run that function upon hover?

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2411
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: How can I get the X/Y coordinates of a button?

#4 Post by Ocelot »

I suggest to use special actions for that:
https://www.renpy.org/doc/html/screen_a ... us-actions

You can capture focus with CaptureFocus and then your screen can retrieve it with GetFocusRect
< < insert Rick Cook quote here > >

Insanifeeding
Newbie
Posts: 9
Joined: Wed Mar 08, 2023 10:58 am
Contact:

Re: How can I get the X/Y coordinates of a button?

#5 Post by Insanifeeding »

Interestingly enough, both methods work since they both return x/y/w/h tuples. My problem was trying to pass the value from the button to the screen it was calling instead of setting the value within the called screen. I'll just say that years of sequential and OOP really make adjusting to interpreted languages difficult :?

Working example:

Code: Select all

define xSize = 400
define ySize = 540

label start:
    call screen button_screen
    
screen button_screen():
    grid 2 1:
        spacing 20
        align (0.5, 0.5)
        button:
            background Color("#FF0000")
            xysize(xSize, ySize)
            hovered [Show("focus_screen", name = "Steve"), CaptureFocus("rect")]
            unhovered Hide("focus_screen")
            action [Hide("focus_screen"), Jump("steve")]
        button:
            background Color("#00FF00")
            xysize(xSize, ySize)
            hovered Show("preview_screen", name = "Tristan") 
            unhovered Hide("preview_screen")
            action [Hide("preview_screen"), Jump("tristan")]
             
screen preview_screen(name):
    default coord = renpy.focus_coordinates() # Tuple of (x, y, w, h)
    frame:
        xpos int(coord[0]) # Cast float to integer
        ypos int(coord[1])
        xysize(xSize, ySize)
        background Color("#FFFFFF7F")
        text name:
            color("#0000FF")
            align (0.5, 1.0)
            
screen focus_screen(name):
    default coord = GetFocusRect("rect") # Tuple of (x, y, w, h)
    frame:
        xpos int(coord[0]) # Cast float to integer
        ypos int(coord[1])
        xysize(xSize, ySize)
        background Color("#FFFFFF7F")
        text name:
            color("#0000FF")
            align (0.5, 1.0) 

label steve:
    pause

label tristan:
    pause
I'm guessing that using CaptureFocus() -> GetFocusRect() is slightly safer than renpy.focus_coordinates() since you are storing the position value when you focus and then retrieving it instead of requesting it immediately after. That said, the second way is more succinct.

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2411
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: [Solved] How can I get the X/Y coordinates of a button?

#6 Post by Ocelot »

You can create a function which will call renpy.focus_coordinates and then show screen, set action to call it when hovered and it will work, because renpy.focus_coordinates will be called after button will be focused. Approach with focus is recommended way of doing it (check second tooltip example on the same page, for example)
< < insert Rick Cook quote here > >

henvu50
Veteran
Posts: 337
Joined: Wed Aug 22, 2018 1:22 am
Contact:

Re: [Solved] How can I get the X/Y coordinates of a button?

#7 Post by henvu50 »

Would be great if there was an example of how to use CaptureFocus, GetFocusRect, along with transclusion.

I can't figure out how to use nearrect to get the xpos and ypos of the currently focused displayable. That's the whole point.

For example, let's say I make a button that when hovered shows text right below that button. There's no example of how to get that working.

For some reason, when using nearrect code in transclusion, it causes renpy.restart_interaction to occur 100 times in a row before erroring out, so the nearrect has to be outside of the transclusion, but at that point, the whole idea was to get the position NEAR the currently focused displayable.

Without proper documentation; EXAMPLES, putting all that effort into making this system is a waste because no one will know how to use it.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], mirceea