From 6f2c9e46b7ad5c50999b9b0fbe05eecd1068be98 Mon Sep 17 00:00:00 2001
From: Georgiy Yankovskiy <admin@yageorgiy.ru>
Date: Thu, 25 Apr 2024 02:05:39 +0300
Subject: [PATCH] Game items gamepad switch (beta) + GameInfoScene.qml buttons
 gamepad switch (beta)

---
 ingame/models/App.py         |  6 ++++
 ingame/models/Gamepad.py     | 45 ++++++++++++++++++++++++++++-
 qml/components/Tabs.qml      | 56 +++++++++++++++++++++++++++++-------
 qml/qml.qml                  |  9 ++++++
 qml/scenes/GameInfoScene.qml | 34 ++++++++++++++++++++++
 5 files changed, 138 insertions(+), 12 deletions(-)

diff --git a/ingame/models/App.py b/ingame/models/App.py
index 12ad0bb..11cf5ac 100644
--- a/ingame/models/App.py
+++ b/ingame/models/App.py
@@ -28,6 +28,9 @@ class App(QtCore.QObject):
 
     gamepad_clicked_LB = Signal(bool, name="gamepadClickedLB")
     gamepad_clicked_RB = Signal(bool, name="gamepadClickedRB")
+    gamepad_clicked_apply = Signal(bool, name="gamepadClickedApply")
+    gamepad_axis_left = Signal(bool, name="gamepadAxisLeft")
+    gamepad_axis_right = Signal(bool, name="gamepadAxisRight")
 
     def __init__(self):
         super().__init__()
@@ -40,6 +43,9 @@ class App(QtCore.QObject):
         self.gamepad: Gamepad = Gamepad()
         self.gamepad.lb_clicked = lambda: self.gamepad_clicked_LB.emit(True)
         self.gamepad.rb_clicked = lambda: self.gamepad_clicked_RB.emit(True)
+        self.gamepad.apply_clicked = lambda: self.gamepad_clicked_apply.emit(True)
+        self.gamepad.l_clicked = lambda: self.gamepad_axis_left.emit(True)
+        self.gamepad.r_clicked = lambda: self.gamepad_axis_right.emit(True)
 
         self.setup()
 
diff --git a/ingame/models/Gamepad.py b/ingame/models/Gamepad.py
index 445f968..294097f 100644
--- a/ingame/models/Gamepad.py
+++ b/ingame/models/Gamepad.py
@@ -9,14 +9,23 @@ from pygame.joystick import Joystick
 class Gamepad:
     LB_BUTTON = 4
     RB_BUTTON = 5
+    LEFT_RIGHT_AXIS = 0
+    LEFT_RIGHT_AXIS_SENSITIVITY = 0.7
+    APPLY_BUTTON = 0
 
     def __init__(self):
         self.joystick: Union[Joystick, None] = None
         self.terminated: bool = False
         self.last_rb_clicked: bool = False
         self.last_lb_clicked: bool = False
+        self.last_apply_clicked: bool = False
+        self.last_left_clicked: bool = False
+        self.last_right_clicked: bool = False
         self.lb_clicked: () = lambda: None
         self.rb_clicked: () = lambda: None
+        self.l_clicked: () = lambda: None
+        self.r_clicked: () = lambda: None
+        self.apply_clicked: () = lambda: None
         self.thread: Union[threading.Thread, None] = None
 
         pygame.init()
@@ -35,12 +44,20 @@ class Gamepad:
 
     def cycle(self):
         try:
+
+            # TODO: use this instead:
+            # events = pygame.event.get()
+            # for event in events:
+            #     if event.type == pygame.JOYBUTTONDOWN:
+
             while not self.terminated:
                 # pygame.event.pump()
                 pygame.event.wait()
 
                 lb_button = self.joystick.get_button(self.LB_BUTTON)
                 rb_button = self.joystick.get_button(self.RB_BUTTON)
+                apply_button = self.joystick.get_button(self.APPLY_BUTTON)
+                left_right_axis = self.joystick.get_axis(self.LEFT_RIGHT_AXIS)
 
                 # LB
 
@@ -60,13 +77,39 @@ class Gamepad:
                 if not rb_button and self.last_rb_clicked:
                     self.last_rb_clicked = not self.last_rb_clicked
 
+                # APPLY
+
+                if apply_button and not self.last_apply_clicked:
+                    self.last_apply_clicked = not self.last_apply_clicked
+                    self.apply_clicked()
+
+                if not apply_button and self.last_apply_clicked:
+                    self.last_apply_clicked = not self.last_apply_clicked
+
+                # LEFT
+                if (left_right_axis <= -self.LEFT_RIGHT_AXIS_SENSITIVITY) and not self.last_left_clicked:
+                    self.last_left_clicked = not self.last_left_clicked
+                    self.l_clicked()
+
+                if not (left_right_axis <= -self.LEFT_RIGHT_AXIS_SENSITIVITY) and self.last_left_clicked:
+                    self.last_left_clicked = not self.last_left_clicked
+
+                # RIGHT
+
+                if (left_right_axis >= self.LEFT_RIGHT_AXIS_SENSITIVITY) and not self.last_right_clicked:
+                    self.last_right_clicked = not self.last_right_clicked
+                    self.r_clicked()
+
+                if (not left_right_axis >= self.LEFT_RIGHT_AXIS_SENSITIVITY) and self.last_right_clicked:
+                    self.last_right_clicked = not self.last_right_clicked
+
                 # print(f"Button {self.LB_BUTTON}: {lb_button}")
                 # print(f"Button {self.RB_BUTTON}: {rb_button}")
 
                 # for i in range(self.joystick.get_numaxes()):
                 #     axis = self.joystick.get_axis(i)
                 #     print(f"Axis {i}: {axis}")
-                #
+
                 # for i in range(self.joystick.get_numbuttons()):
                 #     button = self.joystick.get_button(i)
                 #     print(f"Button {i}: {button}")
diff --git a/qml/components/Tabs.qml b/qml/components/Tabs.qml
index 404ccbf..034ad6f 100644
--- a/qml/components/Tabs.qml
+++ b/qml/components/Tabs.qml
@@ -148,23 +148,24 @@ Rectangle {
     }
 
     // LOGIC
-    property int focused: 0;
+    property int focusedTabs: 0;
+    property int focusedItems: 0;
 
-    function applyFocus(inc){
+    function applyTabsFocus(inc){
         if(!visible)
             return;
 
         let c = row.children;
 
-        tabs.focused += inc;
-        if(tabs.focused >= c.length)
-            tabs.focused = 0;
+        tabs.focusedTabs += inc;
+        if(tabs.focusedTabs >= c.length)
+            tabs.focusedTabs = 0;
 
-        if(tabs.focused < 0)
-            tabs.focused = c.length - 1;
+        if(tabs.focusedTabs < 0)
+            tabs.focusedTabs = c.length - 1;
 
-        c[tabs.focused].forceActiveFocus();
-        c[tabs.focused].clicked();
+        c[tabs.focusedTabs].forceActiveFocus();
+        c[tabs.focusedTabs].clicked();
 
         /* if (c[i].focus) {
             console.log("focus found");
@@ -173,13 +174,46 @@ Rectangle {
         } */
     }
 
+    function applyItemsFocus(inc){
+        if(!gamesScroller.visible)
+            return;
+
+        let c = gamesGrid.children;
+
+        tabs.focusedItems += inc;
+        if(tabs.focusedItems >= c.length)
+            tabs.focusedItems = 0;
+
+        if(tabs.focusedItems < 0)
+            tabs.focusedItems = c.length - 1;
+
+        c[tabs.focusedItems].forceActiveFocus();
+        // gamesScroller.contentY = c[tabs.focusedItems].y; // not working
+        // c[tabs.focusedItems].clicked();
+    }
+
     Connections {
         target: core_app
         function onGamepadClickedLB(done){
-            tabs.applyFocus(1)
+            if(!visible) return;
+            tabs.applyTabsFocus(-1)
         }
         function onGamepadClickedRB(done){
-            tabs.applyFocus(-1)
+            if(!visible) return;
+            tabs.applyTabsFocus(1)
+        }
+        function onGamepadAxisLeft(done){
+            if(!visible) return;
+            tabs.applyItemsFocus(-1)
+        }
+        function onGamepadAxisRight(done){
+            if(!visible) return;
+            tabs.applyItemsFocus(1)
+        }
+        function onGamepadClickedApply(done){
+            if(!visible) return;
+            let c = gamesGrid.children;
+            c[tabs.focusedItems].clicked();
         }
     }
 
diff --git a/qml/qml.qml b/qml/qml.qml
index afb4ee3..7e9e582 100644
--- a/qml/qml.qml
+++ b/qml/qml.qml
@@ -24,6 +24,15 @@ Window {
         function onGamepadClickedRB(done){
             // console.log("core_app: onGamepadClickedRB");
         }
+        function onGamepadAxisLeft(done){
+            // console.log("core_app: onGamepadAxisLeft");
+        }
+        function onGamepadAxisRight(done){
+            // console.log("core_app: onGamepadAxisRight");
+        }
+        function onGamepadClickedApply(done){
+            // console.log("core_app: onGamepadClickedApply");
+        }
     }
 
     Component.onDestruction: {
diff --git a/qml/scenes/GameInfoScene.qml b/qml/scenes/GameInfoScene.qml
index c4d7b97..056686c 100644
--- a/qml/scenes/GameInfoScene.qml
+++ b/qml/scenes/GameInfoScene.qml
@@ -79,4 +79,38 @@ Rectangle {
         }
     }
 
+    // LOGIC
+
+    property int focusedItems: 0;
+    function applyItemsFocus(inc){
+        let c = children;
+
+        focusedItems += inc;
+        if(focusedItems >= c.length)
+            focusedItems = 0;
+
+        if(focusedItems < 0)
+            focusedItems = c.length - 1;
+
+        c[focusedItems].forceActiveFocus();
+        // c[focusedItems].clicked();
+    }
+
+    Connections {
+        target: core_app
+        function onGamepadAxisLeft(done){
+            if(!visible) return;
+            container.applyItemsFocus(-1)
+        }
+        function onGamepadAxisRight(done){
+            if(!visible) return;
+            container.applyItemsFocus(1)
+        }
+        function onGamepadClickedApply(done){
+            if(!visible) return;
+            let c = container.children;
+            c[container.focusedItems].clicked();
+        }
+    }
+
 }
-- 
2.24.1