Page 1 of 1

Drag & Drop + Tooltip = bug :(

Posted: Tue Dec 27, 2011 6:08 am
by jack_norton
Anima made a cool drag&drop party setup for Loren RPG. I wanted to add some tooltips to help the player, but it breaks everything. When you hover the mouse on the button to show the tooltip, the draggable item positions are broken like if they're "reset" in a previous position. See the video to understand better what I mean:
http://www.flickr.com/photos/pcmacgames/6580579419/

the code, though is just standard drag&drop and tooltip, I don't think there's anything strange:

Code: Select all

init python:
    # Definitions for the party drag and drop functions.
    
    def dragChar(pDrag, pDrop):
        # This is called whenever a Character is dragged somewhere.
        
        # self.listPosition => Tuple, the position in the list for this character.
        # self.currentPosition => None or a partyslot.
        # self.character => The character object.
        if pDrag[0].currentPosition:
            # If the character is already occupying a slot remove him from that slot.
            pDrag[0].currentPosition.occupied = None
            pDrag[0].currentPosition.party.partyPosition[pDrag[0].currentPosition.positionKey] = None
            pDrag[0].currentPosition = None
        if pDrop and (pDrop.party.partysize() < pDrop.party.partylimit or pDrop.occupied) :
            # This is the case if the character is dropped on a partyslot.
            if pDrop.occupied:
                pDrop.party.partyPosition[pDrop.positionKey] = None
                pDrop.occupied.snap(pDrop.occupied.listPosition[0],pDrop.occupied.listPosition[1],0.0)
                pDrop.occupied.currentPosition = None
                pDrop.occupied = None
            pDrag[0].snap(pDrop.x,pDrop.y,0.1)
            pDrag[0].currentPosition = pDrop
            pDrop.occupied = pDrag[0]
            pDrop.party.partyPosition[pDrop.positionKey] =  pDrag[0].character
        else:
            # This is the case when the character is not dropped on a partyslot.
            pDrag[0].snap(pDrag[0].listPosition[0],pDrag[0].listPosition[1],0.2)
        return
        
    def getCharacters(pParty):
        rv = []
        runningTotal = 0
        listPositions = [(50,80),(50,195),(50,310),(50,425),(175,80),(175,195),(175,310),(175,425),(300,80),(300,195),(300,310),(300,425),(425,80),(425,195),(425,310),(425,425)]
        for entry in pParty.available:
            tmp = Drag(Image(("gfx/party/p_" + entry.name + ".png")), entry.name, True, False, True, dragChar, xpos=listPositions[runningTotal][0], ypos=listPositions[runningTotal][1])
            if entry in pParty.partyPosition.values():
                for search in pParty.partyPosition.items():
                    if search[1] == entry:
                        tmp.currentPosition = pParty.partySlots[search[0]]
            else:
                tmp.currentPosition = None
            tmp.character = entry
            tmp.listPosition = listPositions[runningTotal]
            runningTotal += 1
            rv.append(tmp)
        return rv
        
init:
    screen chooseParty:
        default tt = Tooltip(("The current partylimit is: %s\n\nDrag and drop the character portraits to setup your battle formation." % party.partylimit))
        zorder 0
        frame:
            xfill True yfill True
            textbutton "Front Row" pos (720, 20) action Return() xcenter .5 style "file_picker_button" hovered tt.Action("Front Row characters are in direct contact with enemies and can be engaged in melee combat. Don't put Mages here!")
            textbutton "Back Row" pos (720, 170) action Return() xcenter .5 style "file_picker_button" hovered tt.Action("Back Row characters are protected by First Row characters, and can attack only through magic or missile weapons.")
            text tt.value pos (720, 350) outlines [(2,"#1e1a16")] xcenter .5 xmaximum 400 justify True
            textbutton "{size=32}Finish{/size}" action Return() pos (630, 460) xminimum 200 yminimum 64
            draggroup:
                for entry in party.partySlots.values():
                    add entry
                    
                for entry in getCharacters(party):
                    add entry
                    if entry.currentPosition:
                        $ entry.snap(entry.currentPosition.x,entry.currentPosition.y,0)

Re: Drag & Drop + Tooltip = bug :(

Posted: Mon Jan 09, 2012 5:09 am
by jack_norton
Another video, this time NO tooltip is used, but still the Drag&Drop seems to "forget" the right positions of the sprites:
http://www.flickr.com/photos/pcmacgames/6665733711/

Code: Select all

init python:
    # Definitions for the party drag and drop functions.
    
    def dragChar(pDrag, pDrop):
        # This is called whenever a Character is dragged somewhere.
        
        # self.listPosition => Tuple, the position in the list for this character.
        # self.currentPosition => None or a partyslot.
        # self.character => The character object.
        if pDrag[0].currentPosition:
            # If the character is already occupying a slot remove him from that slot.
            pDrag[0].currentPosition.occupied = None
            pDrag[0].currentPosition.party.partyPosition[pDrag[0].currentPosition.positionKey] = None
            pDrag[0].currentPosition = None
            party.removeParty(pDrag[0].character)
        if pDrop and (pDrop.party.partysize() < pDrop.party.partylimit or pDrop.occupied) :
            # This is the case if the character is dropped on a partyslot.
            if pDrop.occupied:
                pDrop.party.partyPosition[pDrop.positionKey] = None
                pDrop.occupied.snap(pDrop.occupied.listPosition[0],pDrop.occupied.listPosition[1],0.0)
                pDrop.occupied.currentPosition = None
                party.removeParty(pDrop.occupied)
                pDrop.occupied = None
            pDrag[0].snap(pDrop.x,pDrop.y,0.1)
            pDrag[0].currentPosition = pDrop
            pDrop.occupied = pDrag[0]
            pDrop.party.partyPosition[pDrop.positionKey] =  pDrag[0].character
            party.addParty(pDrag[0].character)
        else:
            # This is the case when the character is not dropped on a partyslot.
            pDrag[0].snap(pDrag[0].listPosition[0],pDrag[0].listPosition[1],0.2)
        return
        
    def getCharacters(pParty):
        rv = []
        runningTotal = 0
        listPositions = [(40,80),(40,195),(40,310),(40,425),(160,80),(160,195),(160,310),(160,425),(280,80),(280,195),(280,310),(280,425),(400,80),(400,195),(400,310),(400,425)]
        for entry in pParty.available:
            tmp = Drag(Image(("gfx/party/p_" + entry.name + ".png")), entry.name, True, False, True, dragChar, xpos=listPositions[runningTotal][0], ypos=listPositions[runningTotal][1])
            if entry in pParty.partyPosition.values():
                for search in pParty.partyPosition.items():
                    if search[1] == entry:
                        tmp.currentPosition = pParty.partySlots[search[0]]
            else:
                tmp.currentPosition = None
            tmp.character = entry
            tmp.listPosition = listPositions[runningTotal]
            runningTotal += 1
            rv.append(tmp)
        return rv
        
init:
    screen chooseParty:
        #default tt = Tooltip(("The current partylimit is: %s\n\nDrag and drop the character portraits to setup your battle formation." % party.partylimit))
        zorder 0
        frame:
            xfill True yfill True
            textbutton "Front Row" pos (720, 20) action Return() xcenter .5 style "file_picker_button" #hovered tt.Action("Front Row characters are in direct contact with enemies and can be engaged in melee combat. Don't put Mages here!")
            textbutton "Back Row" pos (720, 170) action Return() xcenter .5 style "file_picker_button" #hovered tt.Action("Back Row characters are protected by First Row characters, and can attack only through magic or missile weapons.")
            #text tt.value pos (720, 350) outlines [(2,"#1e1a16")] xcenter .5 xmaximum 400 justify True
            textbutton "{size=32}Finish{/size}" action Show("confirmParty") pos (630, 460) xminimum 200 yminimum 64
            draggroup:
                for entry in party.partySlots.values():
                    add entry
                    
                for entry in getCharacters(party):
                    add entry
                    if entry.currentPosition:
                        $ entry.snap(entry.currentPosition.x,entry.currentPosition.y,0)
                        
    screen confirmParty:
        modal True
        frame:
            area (100,200,400,200)
            xpadding 20 ypadding 20
            has vbox
            if party.checkParty():
                text "Is this party okay ?"
                hbox:
                    spacing 20
                    textbutton "Yes" action (Hide("confirmParty"),Return())
                    textbutton "No" action (Hide("confirmParty"))
            else:
                text "This party is invalid."
                text ("You must have between %s and %s party members." % (party.partyMinSize,party.partylimit))
                for entry in party.requiredParty:
                    text ("%s must be in the party." % entry.name)
                textbutton "Close" action (Hide("confirmParty"))

Re: Drag & Drop + Tooltip = bug :(

Posted: Thu Jan 12, 2012 12:01 pm
by PyTom
I'll be working on this shortly. Would it be possible for me to get a working demo of this problem, so I can confirm I fixed it. Just having the code isn't as useful as if I could run it.

Re: Drag & Drop + Tooltip = bug :(

Posted: Thu Jan 12, 2012 12:52 pm
by PyTom
Oh, the bug is in your code. When the tooltip changes, the screen refreshes, and the code:

Code: Select all

                for entry in getCharacters(party):
                    add entry
                    if entry.currentPosition:
                        $ entry.snap(entry.currentPosition.x,entry.currentPosition.y,0)
is run again, causing the snapping to occur. Screens are meant to be declarative - they can be called at any time, even when they are not being shown. So code with side effects - like snap - can't be called on a screen. Consider using

Code: Select all

    on "show" action ...
to run code only when the screen is first shown.

Re: Drag & Drop + Tooltip = bug :(

Posted: Thu Jan 12, 2012 1:47 pm
by Anima
Yeah, right on the mark. Next time, I'll keep in mind that the screen can refresh during an interaction.
It looks like it works now without problem, thanks for your help. :D

Re: Drag & Drop + Tooltip = bug :(

Posted: Thu Jan 12, 2012 1:55 pm
by jack_norton
Cool thanks. I had no clue how D&D worked at all (even looking at the code I still have some doubts lol) so thought was a Ren'Py bug :oops: :oops: