Imagebutton behavior when clicked

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.
Message
Author
User avatar
Marchare
Newbie
Posts: 19
Joined: Mon Apr 28, 2014 7:43 pm
Contact:

Imagebutton behavior when clicked

#1 Post by Marchare » Mon Jun 09, 2014 10:37 am

I did some research on the subject in the official Ren'py documentation and in the forum but no success. :?

Basically, the buttons on idle look like this (jpg image):
Image
When hovered, it's replaced by this red image:
Image

...and I would like it to turn blue when you press left click on it, (not necessarily "activated"):
Image

Here's the current code:

Code: Select all

 $ y=450
    imagebutton auto "menu/main/start_%s.png" xpos 80 ypos y focus_mask True action Start()
    imagebutton auto "menu/main/load_%s.png" xpos 214 ypos y focus_mask True  action ShowMenu('load')
    imagebutton auto "menu/main/config_%s.png" xpos 342 ypos y focus_mask True action ShowMenu('preferences')
    if persistent.extra_unlocked: 
        imagebutton auto "menu/main/extra_%s.png" xpos 508 ypos y focus_mask True action Start('extras')
    imagebutton auto "menu/main/exit_%s.png" xpos 646 ypos y focus_mask True action Quit(confirm=False) 
(I also added hover and action sound but it's not revelant to the subject so I removed it practical reasons)

I also wonder if I can make the buttons move a few pixels toward the bottom right, to make it look like you pressed an actual button?

If we're obliged to activate the button for it to turn blue and move down it's okay too. I tried calling the blue "START" button "start_action" but it didn't work. "selected_hover" doesn't seem to work either.


Suggestions are welcome. Thanks in advance! :D
Last edited by Marchare on Mon Jun 09, 2014 5:17 pm, edited 1 time in total.

User avatar
Asceai
Eileen-Class Veteran
Posts: 1258
Joined: Fri Sep 21, 2007 7:13 am
Projects: a battle engine
Contact:

Re: Imagebutton behavior when clicked

#2 Post by Asceai » Mon Jun 09, 2014 4:27 pm

This is one of those things that seems easy at first but it actually really miserable. The simplest solution I can think of involves a UDD- you can get 99.9% of the way easily but then you realise things like 'I need whole screen mousedown/up detection, but I also need mouseup events to get to the button... is there something I can supply to Key to not eat events? no... is there some function to rethrow events? no... hmm'
So, yeah. Anyone else got any ideas? You just need to detect if the mousebutton is held down and change the hover image of the buttons if it is, but 'detect if the mousebutton is held down' appears to be the trickiest part of the exercise.

User avatar
Marchare
Newbie
Posts: 19
Joined: Mon Apr 28, 2014 7:43 pm
Contact:

Re: Imagebutton behavior when clicked

#3 Post by Marchare » Mon Jun 09, 2014 5:16 pm

"detect if the mousebutton is held down" is a good way to put it.

By the way I have yet to see a Ren'py game where the buttons have this sort of behavior while it's actually not that rare to see an image change when the mousebutton is held down in mainstream games, I think? Not that it's a crucial part of the game.

Well, even if we're obliged to activate the button for it to turn blue and move down it's okay too. I tried calling the blue "START" button "start_action" but it didn't work. "selected_hover" doesn't seem to work either.

Thanks for trying to help me! :)

Tsapas
Regular
Posts: 69
Joined: Mon Oct 14, 2013 8:18 am
Contact:

Re: Imagebutton behavior when clicked

#4 Post by Tsapas » Wed Jun 11, 2014 9:53 am

Asceai wrote: So, yeah. Anyone else got any ideas? You just need to detect if the mousebutton is held down and change the hover image of the buttons if it is, but 'detect if the mousebutton is held down' appears to be the trickiest part of the exercise.
Apparently, as per this post, Ren'Py does not support a pressed state detection, so trying to make a custom displayable based on that may be unfeasible.

User avatar
Alex
Lemma-Class Veteran
Posts: 2981
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Imagebutton behavior when clicked

#5 Post by Alex » Wed Jun 11, 2014 5:11 pm

Kind of example that might help:

Code: Select all

define e = Character('Eileen', color="#c8ffc8")

screen my_scr_2:
    modal True
    timer 0.2 action [x, Hide("my_scr_2")]


screen my_scr:
    on "show" action [SetVariable("a", 0), SetVariable("b", 0), SetVariable("c", 0)]
    
    text "[x]" size 45 align (0.5, 0.3)

    button:
        background ConditionSwitch("a==0", Frame("fr2.png", 1, 1, 1, 1), "a==1", Frame("fr1.png", 1, 1, 1, 1), "True", Frame("fr2.png", 1, 1, 1, 1))
        text "\n Close \n"
        action [SetVariable("a", 1), Show("my_scr_2", x=(Hide("my_scr")))]
        align (0.5, 0.5)
    
    button:
        background ConditionSwitch("b==0", Frame("fr2.png", 1, 1, 1, 1), "b==1", Frame("fr1.png", 1, 1, 1, 1), "True", Frame("fr2.png", 1, 1, 1, 1))
        text "\n -1 \n"
        action [SetVariable("b", 1), SetVariable("x", x-1), Show("my_scr_2", x=(SetVariable("b", 0)))]
        align (0.3, 0.5)
        
    button:
        background ConditionSwitch("c==0", Frame("fr2.png", 1, 1, 1, 1), "c==1", Frame("fr1.png", 1, 1, 1, 1), "True", Frame("fr2.png", 1, 1, 1, 1))
        text "\n +1 \n"
        action [SetVariable("c", 1), SetVariable("x", x+1), Show("my_scr_2", x=(SetVariable("c", 0)))]
        align (0.8, 0.5)
     

       
# The game starts here.
label start:
    
    $ x = 0

    show screen my_scr
    
    e "You've created a new Ren'Py game."

    e "Once you add a story, pictures, and music, you can release it to the world!"

    return
fr1.png
fr1.png (2.76 KiB) Viewed 5005 times
fr2.png
fr2.png (2.76 KiB) Viewed 5005 times

User avatar
Asceai
Eileen-Class Veteran
Posts: 1258
Joined: Fri Sep 21, 2007 7:13 am
Projects: a battle engine
Contact:

Re: Imagebutton behavior when clicked

#6 Post by Asceai » Thu Jun 12, 2014 7:29 pm

I did it!

This was irritating only because I forgot to implement a crucial part of the UDD interface:

Code: Select all

init python:
    def run_action(action):
        try:
            for a in action:
                run_action(a)
        except TypeError, te:
            action()
    class Keymapper(renpy.Displayable):
        def __init__(self, vargs, child, **kwargs):
            super(Keymapper, self).__init__(**kwargs)
            self.child = child
            self.vargs = vargs
        def render(self, width, height, st, at):
            return renpy.render(self.child, width, height, st, at)
        def event(self, ev, x, y, st):
            for keysym, action in self.vargs:
                if renpy.map_event(ev, keysym):
                    run_action(action)
            self.child.event(ev, x, y, st)
        def visit(self):
            return [ self.child ]

    KeymapTransform = renpy.curry(Keymapper)
This class (and associated transform) will perform Actions when events occur, then pass on the event to its child.

The way we then use this is with something like:

Code: Select all

screen main_menu:
    default mouse_clicked = False
    fixed at KeymapTransform([('mousedown_1', SetScreenVariable('mouse_clicked', True)), ('mouseup_1', SetScreenVariable('mouse_clicked', False))]):
        $y = 450
        imagebutton idle "menu/main/start_idle.png" hover ("menu/main/start_clicked.png" if mouse_clicked else "menu/main/start_hover.png") xpos 80 ypos y focus_mask True action Start()
        imagebutton idle "menu/main/load_idle.png" hover ("menu/main/load_clicked.png" if mouse_clicked else "menu/main/load_hover.png") xpos 214 ypos y focus_mask True  action ShowMenu('load')
        imagebutton idle "menu/main/config_idle.png" hover ("menu/main/config_clicked.png" if mouse_clicked else "menu/main/config_hover.png") xpos 342 ypos y focus_mask True action ShowMenu('preferences')
        if persistent.extra_unlocked:
            imagebutton idle "menu/main/extra_idle.png" hover ("menu/main/extra_clicked.png" if mouse_clicked else "menu/main/extra_hover.png") xpos 508 ypos y focus_mask True action Start('extras')
        imagebutton idle "menu/main/exit_idle.png" hover ("menu/main/exit_clicked.png" if mouse_clicked else "menu/main/exit_hover.png") xpos 646 ypos y focus_mask True action Quit(confirm=False)
The above code is only an example- I haven't tested it since I don't have your images etc. but it's along the right lines. Make sure everything in that screen is within the fixed- that way the mouseup/mousedown events won't be missed regardless of where the mouse is.

User avatar
Marchare
Newbie
Posts: 19
Joined: Mon Apr 28, 2014 7:43 pm
Contact:

Re: Imagebutton behavior when clicked

#7 Post by Marchare » Wed Jun 18, 2014 1:06 pm

My bad for the late reply!

I tried using your code, Asceai, but I got a few errors, first because of the two dots at the end of the 3rd line, then because of the indentation but they got fixed quickly.

The code doesn't seem to work. I changed the filename of the Start button to make sure it matches the one written in the code (start_clicked); also put the init python below the imagebuttons.

By the way, what do you mean by making sure everything in the screen is within the fixed- ? Maybe that's why it didn't work?

User avatar
Asceai
Eileen-Class Veteran
Posts: 1258
Joined: Fri Sep 21, 2007 7:13 am
Projects: a battle engine
Contact:

Re: Imagebutton behavior when clicked

#8 Post by Asceai » Wed Jun 18, 2014 3:23 pm

What do you mean? What errors, in which piece of code, and how did you fix them?

If you were talking about the second piece of code, that was probably the problem. The colon at the end and the indentation are necessary for all of those items to go inside the fixed. Like I said, the code was untested but it should still have worked. Show me what the errors were.

User avatar
Marchare
Newbie
Posts: 19
Joined: Mon Apr 28, 2014 7:43 pm
Contact:

Re: Imagebutton behavior when clicked

#9 Post by Marchare » Tue Dec 16, 2014 8:08 pm

Digging up this old thread because I re-tested your code today and it actually works!
I guess it didn't work at first because I didn't copy/paste it well, or didn't rename all the imagebuttons.

Thank you for your patience and sorry for the very late answer! :D

User avatar
Pierrou
Regular
Posts: 53
Joined: Fri Dec 05, 2014 8:25 pm
Projects: Togainu no Chi, DMMD, Omerta, ...
Skype: pierrouney
Location: France
Contact:

Re: Imagebutton behavior when clicked

#10 Post by Pierrou » Wed Jan 21, 2015 12:11 pm

(Sorry for my bad english :oops:)
Asceai wrote:I did it!

This was irritating only because I forgot to implement a crucial part of the UDD interface:

Code: Select all

init python:
    def run_action(action):
        try:
            for a in action:
                run_action(a)
        except TypeError, te:
            action()
    class Keymapper(renpy.Displayable):
        def __init__(self, vargs, child, **kwargs):
            super(Keymapper, self).__init__(**kwargs)
            self.child = child
            self.vargs = vargs
        def render(self, width, height, st, at):
            return renpy.render(self.child, width, height, st, at)
        def event(self, ev, x, y, st):
            for keysym, action in self.vargs:
                if renpy.map_event(ev, keysym):
                    run_action(action)
            self.child.event(ev, x, y, st)
        def visit(self):
            return [ self.child ]

    KeymapTransform = renpy.curry(Keymapper)
This class (and associated transform) will perform Actions when events occur, then pass on the event to its child.

The way we then use this is with something like:

Code: Select all

screen main_menu:
    default mouse_clicked = False
    fixed at KeymapTransform([('mousedown_1', SetScreenVariable('mouse_clicked', True)), ('mouseup_1', SetScreenVariable('mouse_clicked', False))]):
        $y = 450
        imagebutton idle "menu/main/start_idle.png" hover ("menu/main/start_clicked.png" if mouse_clicked else "menu/main/start_hover.png") xpos 80 ypos y focus_mask True action Start()
        imagebutton idle "menu/main/load_idle.png" hover ("menu/main/load_clicked.png" if mouse_clicked else "menu/main/load_hover.png") xpos 214 ypos y focus_mask True  action ShowMenu('load')
        imagebutton idle "menu/main/config_idle.png" hover ("menu/main/config_clicked.png" if mouse_clicked else "menu/main/config_hover.png") xpos 342 ypos y focus_mask True action ShowMenu('preferences')
        if persistent.extra_unlocked:
            imagebutton idle "menu/main/extra_idle.png" hover ("menu/main/extra_clicked.png" if mouse_clicked else "menu/main/extra_hover.png") xpos 508 ypos y focus_mask True action Start('extras')
        imagebutton idle "menu/main/exit_idle.png" hover ("menu/main/exit_clicked.png" if mouse_clicked else "menu/main/exit_hover.png") xpos 646 ypos y focus_mask True action Quit(confirm=False)
The above code is only an example- I haven't tested it since I don't have your images etc. but it's along the right lines. Make sure everything in that screen is within the fixed- that way the mouseup/mousedown events won't be missed regardless of where the mouse is.

This works fine but not everywhere :/ I don't know why but it doesn't seem to work on Yes/No prompt for example or for One button only in the save/load Menu...

Save menu :

Code: Select all

screen save():
    tag menu
    key "s" action Return()
    default mouse_clicked = False

    if int(persistent._file_page) == 1:
        add "image/ui/saveload/s_back30.png"
        fixed at KeymapTransform([('mousedown_1', SetScreenVariable('mouse_clicked', True)), ('mouseup_1', SetScreenVariable('mouse_clicked', False))]):
            imagebutton idle "image/ui/saveload/nextbutton_idle.png" hover("image/ui/saveload/nextbutton_clicked.png" if mouse_clicked else "image/ui/saveload/nextbutton_hover.png") xpos 738 ypos 535 focus_mask None action FilePage(2) <=== WORKS
    else:
        add "image/ui/saveload/s_back60.png"
        fixed at KeymapTransform([('mousedown_1', SetScreenVariable('mouse_clicked', True)), ('mouseup_1', SetScreenVariable('mouse_clicked', False))]):
            imagebutton idle "image/ui/saveload/backbutton_idle.png" hover("image/ui/saveload/backbutton_clicked.png" if mouse_clicked else "image/ui/saveload/backbutton_hover.png") xpos 738 ypos 535 focus_mask None action FilePage(1) <=== WORKS

    fixed at KeymapTransform([('mousedown_1', SetScreenVariable('mouse_clicked', True)), ('mouseup_1', SetScreenVariable('mouse_clicked', False))]):
        imagebutton idle "image/ui/saveload/exit_idle.png" hover ("image/ui/saveload/exit_clicked.png" if mouse_clicked else "image/ui/saveload/exit_hover.png") xpos 620 ypos 520 focus_mask None action Return() <=== ACTION DOESN'T WORKS

(I didn't paste the whole but if need it, just ask me pls !)
The "design" of the button works fine. If i hit it the image changes. But the action doesn't work... Nothing appends... It disabled the action only for the "EXIT" button. It works really fine for the "Back" or "Next" button... Why ?


It's the same for the yes/no prompt :

Code: Select all

screen yesno_prompt:
    
    default mouse_clicked = False

    modal True

    if message == layout.ARE_YOU_SURE:
        add "image/ui/yesno/sure.png" xalign .5 yalign .5

    elif message == layout.DELETE_SAVE:
        add "image/ui/yesno/delete.png" xalign .5 yalign .5

    elif message == layout.OVERWRITE_SAVE:
        add "image/ui/yesno/erase.png" xalign .5 yalign .5

    elif message == layout.LOADING:
        add "image/ui/yesno/load.png" xalign .5 yalign .5

    elif message == layout.QUIT:
        add "image/ui/yesno/quit.png" xalign .5 yalign .5

    elif message == layout.MAIN_MENU:
        add "image/ui/yesno/mainmenu.png" xalign .5 yalign .5

    elif message == layout.SLOW_SKIP:
        add "image/ui/yesno/skip.png" xalign .5 yalign .5

    elif message == layout.FAST_SKIP_UNSEEN:
        add "image/ui/yesno/skipnext.png" xalign .5 yalign .5

    elif message == layout.FAST_SKIP_SEEN:
        add "image/ui/yesno/skipfast.png" xalign .5 yalign .5

    hbox:
        
        xalign .5
        yalign .55
        spacing 100
        
        fixed at KeymapTransform([('mousedown_1', SetScreenVariable('mouse_clicked', True)), ('mouseup_1', SetScreenVariable('mouse_clicked', False))]):
            imagebutton idle "image/ui/yesno/yes_idle.png" hover ("image/ui/yesno/yes_clicked.png" if mouse_clicked else "image/ui/yesno/yes_hover.png") action yes_action
            imagebutton idle "image/ui/yesno/no_idle.png" hover ("image/ui/yesno/no_clicked.png" if mouse_clicked else "image/ui/yesno/no_hover.png")  action no_action
Same problem... Images work fine, when i hit the button yes, for example, i can see yes_clicked.png but the action doesn't seem to work. Nothing appends...

Do you know why ?
Sorry for my english, it's not my native language. :s

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Imagebutton behavior when clicked

#11 Post by xela » Wed Jan 21, 2015 12:34 pm

I have an idea about what happens (mouse up is blocked for the action because transform overwrites it) but why is that happening for some buttons and not for others I can't really tell.

Proper way of doing this would be creating a new button class and overwriting the event method and not that transform overlay you're using but I don't have an example of that or know how to find one :(
Like what we're doing? Support us at:
Image

User avatar
Pierrou
Regular
Posts: 53
Joined: Fri Dec 05, 2014 8:25 pm
Projects: Togainu no Chi, DMMD, Omerta, ...
Skype: pierrouney
Location: France
Contact:

Re: Imagebutton behavior when clicked

#12 Post by Pierrou » Wed Jan 21, 2015 8:21 pm

Oh :'(

Anyway, thank you ^^
Sorry for my english, it's not my native language. :s

duck-and-wolf
Regular
Posts: 47
Joined: Thu Aug 29, 2019 6:20 pm
Completed: Head of the Class
Organization: Duck & Wolf
Contact:

Re: Imagebutton behavior when clicked

#13 Post by duck-and-wolf » Fri May 08, 2020 1:45 pm

Has this still never been updated to behave the way the original poster hoped for? It does seem a little odd when you click down on your left mouse button while over an imagebutton, and before you release your finger from the mouse button, nothing immediately seems to happen giving you any feedback that the button is indeed getting engaged.

I'm replacing my quick menu textbuttons with imagebuttons and I'd like to give the player a better idea that when they click the buttons something will indeed happen.

User avatar
gas
Miko-Class Veteran
Posts: 838
Joined: Mon Jan 26, 2009 7:21 pm
Contact:

Re: Imagebutton behavior when clicked

#14 Post by gas » Fri May 08, 2020 3:33 pm

duck-and-wolf wrote:
Fri May 08, 2020 1:45 pm
Has this still never been updated to behave the way the original poster hoped for? It does seem a little odd when you click down on your left mouse button while over an imagebutton, and before you release your finger from the mouse button, nothing immediately seems to happen giving you any feedback that the button is indeed getting engaged.

I'm replacing my quick menu textbuttons with imagebuttons and I'd like to give the player a better idea that when they click the buttons something will indeed happen.
I've asked this to PyTom thru years, always positive feedbacks, but never implemented (and it can be done, as it work for touch interfaces).
The fact Renpy is somehow standardized on old VNL of PC9800 era (textbuttons alone), and no button had feedbacks at the time. Actually, a lot of modern japanese VNL doesn't come with button feedbacks, as they strictly follow the old paradigma (japanese designers are conservative) so it's hard to promote such uncommon feature for VNL scene.
If you want to debate on a reply I gave to your posts, please QUOTE ME or i'll not be notified about. << now red so probably you'll see it.

10 ? "RENPY"
20 GOTO 10

RUN

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3636
Joined: Mon Dec 14, 2015 5:05 am
Location: Your monitor
Contact:

Re: Imagebutton behavior when clicked

#15 Post by Imperf3kt » Fri May 08, 2020 6:50 pm

selected_idle selected_hover
Do these two states not fill the requirements?
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor
Free Android GUI - Updated occasionally
Twitter
Imperf3kt Blackjack - a WIP blackjack game for Android made using Ren'Py

Post Reply

Who is online

Users browsing this forum: No registered users