Thursday 29 December 2022

binding the movement/rotation of two kivy scatter widgets

Below I have a code that displays 2 scatter widgets in a kivy screen. If one widget is dragged, the other also drags and vice versa.

What I want is in addition to movement, if one is rotated, the other rotates in the same way. In other words, they are exactly mimicking each other with both rotation and position.

The problem I am facing is that kivy's default position is the bottom left of the widget. So, if the user rotates one widget from some random axis point, the other widget rotates at the bottom left. When introducing rotation while the positions are locked, it becomes all messed up, and I cannot find a way to overcome this bug in order to match both rotation and movement.

Here is code with positions locked.

from kivy.uix.scatter import Scatter
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder

class ScatterWidget(Scatter):
    pass

class SquareWidget(Widget):
    pass

class WindowManager(ScreenManager):
    pass

class GeneralWindow(Screen,RelativeLayout):

    start_position_1=(200,200)
    start_position_2=(300,400)
    def on_touch_move(self, touch):
        app=self.manager.get_screen('General')
        pos1=app.ids['widget10'].parent.to_parent(*self.pos)
        pos2=app.ids['widget20'].parent.to_parent(*self.pos)
        mov1=(pos1[0]-self.start_position_1[0],pos1[1]-self.start_position_1[1])
        mov2=(pos2[0]-self.start_position_2[0],pos2[1]-self.start_position_2[1])

        if self.ids.one.collide_point(*touch.pos):
            app.ids['two'].pos=(mov1[0]+self.start_position_2[0],mov1[1]+self.start_position_2[1])
        if self.ids.two.collide_point(*touch.pos):
            app.ids['one'].pos =(mov2[0]+self.start_position_1[0],mov2[1]+self.start_position_1[1])

KV = Builder.load_string("""

WindowManager:
    GeneralWindow:

<GeneralWindow>:
    name: 'General'
    RelativeLayout:
        canvas: 
            Color: 
                rgba: 0,0,0,0.3
            Rectangle: 
                size: self.size
                pos: self.pos
        
        ScatterWidget:
            do_scale: False
            id: one
            size_hint: None,None
            size: widget10.size
            rotation: 0
            pos: root.start_position_1

            SquareWidget:
                id: widget10
                size: (200,20)
                canvas: 
                    Color:
                        rgba: 1,1,0,0.7
                    Rectangle:
                        size: self.size
                        pos:  self.pos  

        ScatterWidget:
            do_scale: False
            id: two
            size_hint: None,None
            size: widget20.size
            rotation: 0
            pos: root.start_position_2

            SquareWidget:
                id: widget20
                size: (200,20)
                canvas: 
                    Color:
                        rgba: 0,1,0,0.7
                    Rectangle:
                        size: self.size
                        pos:  self.pos 

""")

class TApp(App):

    def build(self):
        return KV

if __name__ == '__main__':
    TApp().run()


from binding the movement/rotation of two kivy scatter widgets

No comments:

Post a Comment