Move widgets added to a ScatterLayout in kivy

Viewed 57

I'm working on a card game where I'm using ScatterLayout as Board because I am interested on the zoom in/out functionality, then I have some cards I want to move around. I know how to move the cards, but when using the ScatterLayout I end up moving the Scatterlayout rather than the cards. I can block the move of the ScatterLayout, because when zoomed in it's good I can move the layout around

I understand the issue, I need to make a distinction on when move the layout and when to move the card. Similar as what ScrollView does.

I've been reviewing the code the ScrollView and it makes this difference based on time and distance moved during the first touch. Which makes sense, But I haven't figurate out how to implement it on the ScatterLayout and the cards, as it seems I have to modify the on_touch_down and on_touch_move.

Is there any suggestion on how to implement this? i hope I'm not the first one facing this situation ;).

This is a sample code of what I'm working on:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.scatterlayout import ScatterLayout
from kivy.uix.widget import Widget

Builder.load_string("""
<Board>:
Card:
    pos: 100, 100
    size: 100, 100
Card:
    pos: 300, 100
    size: 50, 100

<Card>:
    size_hint: None, None
    canvas:
    Color:
        rgba: 0, 1, 0, 1
    Rectangle:
        pos: self.pos
        size: self.size
""")

class Card(Widget):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            touch.grab(self)
        return super().on_touch_down(touch)

    def on_touch_move(self, touch):
        if touch.grab_current is self:
            self.center_x = touch.x
            self.center_y = touch.y
            return True
        return super().on_touch_move(touch)

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
        return super().on_touch_up(touch)


class Board(ScatterLayout):
    do_collide_after_children=False


class MoveApp(App):
    def build(self):
        return Board()


MoveApp().run()
1 Answers

So, I found the solution which was kind of simple:

I need to add 'return True' on_touch_down and on_touch_up, which give info the the ScatterLayout that the children is doing something.

Now, I'm trying to make difference between moving the Widgets and Scale the Scatterlayout. But that's a different question.

Related