Commit d85cd652 authored by Georgiy Yankovskiy's avatar Georgiy Yankovskiy

Merge remote-tracking branch 'origin/main'

parents 0849c7a3 9a49b9d1
......@@ -7,12 +7,13 @@ Use the following commands in UNIX shell:
```shell
# Prepare and activate virtual environment
python -m venv .venv
source .venv/bin/activate
python -m pip install --user pipx
python -m pipx ensurepath
pipx install poetry
# Install requirements
pip install -r requirements.txt
poetry install
# Run
python src/main.py
poetry run main
```
\ No newline at end of file
import sys
from pathlib import Path
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from ingame.models.App import App
from ingame.models.GamesModel import GamesModel
from models.App import App
from models.GamesModel import GamesModel
# TODO: add VirtualKeyboard
if __name__ == "__main__":
def main():
app = QGuiApplication(sys.argv)
app_model = App()
app.aboutToQuit.connect(app_model.close_event)
qml_file = Path(__file__).resolve().parent / "../qml/qml.qml"
engine = QQmlApplicationEngine()
app_model = App()
context = engine.rootContext()
context.setContextProperty("core_app", app_model)
......@@ -23,3 +25,7 @@ if __name__ == "__main__":
sys.exit(-1)
sys.exit(app.exec())
if __name__ == "__main__":
main()
import threading
import glob
import os.path
import subprocess
from time import sleep
from pathlib import Path
from typing import AnyStr, Union
from PySide6 import QtCore
from os.path import expanduser
import glob
from desktop_parser import DesktopFile
import os.path
from pathlib import Path
from ingame.models.Gamepad import Gamepad
from ingame.models.GamesModel import Game, GamesModel
from PySide6.QtCore import Property, Signal, Slot, QObject, Qt
from models.GamesModel import Game, GamesModel
import subprocess
class GameShortcut:
......@@ -23,13 +26,27 @@ class App(QtCore.QObject):
game_started = Signal(bool, name="gameStarted")
game_ended = Signal(bool, name="gameEnded")
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__()
self.games_model = GamesModel()
self.home = expanduser('~')
self.config_location = '/.config/PortProton.conf'
self.portproton_location = ''
self.running_game_process = None
self.games_model: GamesModel = GamesModel()
self.home: AnyStr = expanduser('~')
self.config_location: str = '/.config/PortProton.conf'
self.portproton_location: str = ''
self.running_game_process: Union[subprocess.Popen, None] = None
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()
def setup(self):
......@@ -51,10 +68,10 @@ class App(QtCore.QObject):
_icon = entry['Icon']
assert (isinstance(_name, str)
and isinstance(exec, str)
and isinstance(_exec, str)
and isinstance(_icon, str))
exec_split = exec.split(' ')
exec_split = _exec.split(' ')
# Ignore extra non-related desktop entries
if (len(exec_split) <= 1 or
......@@ -64,7 +81,7 @@ class App(QtCore.QObject):
# TODO parse product name
_icon = (os.path.isfile(_icon) and _icon
or os.path.realpath(f"{Path(__file__).resolve().parent}../../../qml/images/game_icon.png"))
or os.path.realpath(f"{Path(__file__).resolve().parent}../../../qml/images/PUBG.png"))
# Автозапуск игры:
# PW_GUI_DISABLED_CS=1
......@@ -73,12 +90,24 @@ class App(QtCore.QObject):
self.games_model.add_game(Game(name=_name, icon=_icon, exec=_exec))
self.gamepad.run()
except FileNotFoundError:
print('File not found')
except Exception as e:
print('An error occurred', e)
pass
### CALLBACKS ###
def close_event(self):
# do stuff
# if can_exit:
self.gamepad.terminate()
# event.accept() # let the window close
# else:
# event.ignore()
### SLOTS ###
@Slot(str)
......
import subprocess
import threading
from typing import Union
import pygame
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()
pygame.joystick.init()
def run(self):
joystick_count = pygame.joystick.get_count()
if joystick_count == 0:
print("No joysticks found.")
else:
self.joystick = pygame.joystick.Joystick(0)
self.joystick.init()
self.thread = threading.Thread(target=lambda t, _exec: t.cycle(), args=(self, exec))
self.thread.start()
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
if lb_button and not self.last_lb_clicked:
self.last_lb_clicked = not self.last_lb_clicked
self.lb_clicked()
if not lb_button and self.last_lb_clicked:
self.last_lb_clicked = not self.last_lb_clicked
# RB
if rb_button and not self.last_rb_clicked:
self.last_rb_clicked = not self.last_rb_clicked
self.rb_clicked()
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}")
except pygame.error:
pass
def terminate(self):
self.terminated = True
pygame.quit()
pass
pass
import typing
from dataclasses import dataclass, fields
from PySide6.QtCore import QAbstractListModel, QModelIndex, Qt, QByteArray
......
This diff is collapsed. Click to expand it.
[tool.poetry]
name = "ingame"
version = "0.1.0"
description = ""
authors = ["Mikhail Tergoev <57610802+castro-fidel@users.noreply.github.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.11,<3.13"
PySide6 = "^6.7.0"
PySide6-Essentials = "^6.7.0"
PySide6-Addons = "^6.7.0"
shiboken6 = "^6.7.0"
pyqtgraph = "^0.13.6"
requests = "^2.31.0"
desktop-parser = "^0.1.1"
pygame = "^2.5.2"
[tool.poetry.group.dev.dependencies]
mypy = "^1.9.0"
[tool.poetry.scripts]
main = 'ingame.main:main'
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
......@@ -2,28 +2,37 @@ import QtQuick
import QtQuick.Controls as C
C.Button {
// control.down
// control.activeFocus
id: control
text: qsTr("Button")
font.bold: true
//font.letterSpacing: font.pixelSize / 100 * 30
// font.pointSize: Math.max(parent.width / 100,10)
// contentItem: Text {
// text: control.text
// font: control.font
// //fontSizeMode: Text.Fit; minimumPixelSize: 10;
// opacity: enabled ? 1.0 : 0.3
// color: control.down ? "Black" : (control.activeFocus ? "#333333" : "#ffffff")
// horizontalAlignment: Text.AlignHCenter
// verticalAlignment: Text.AlignVCenter
// elide: Text.ElideRight
// leftPadding: font.pointSize / 100 * 20
// rightPadding: font.pointSize / 100 * 20
// topPadding: font.pointSize / 100 * 0
// bottomPadding: font.pointSize / 100 * 0
// }
// background: Rectangle {
// //implicitWidth: 100
// //implicitHeight: 40
// opacity: enabled ? 1 : 0.3
// color: control.down ? "#000000" : (control.activeFocus ? "#ffffff" : "#00000000")
// border.width: 0
// radius: 16
// }
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#000000" : (control.activeFocus ? "#ff0000" : "#555555")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
border.color: control.down ? "#000000" : (control.activeFocus ? "#ff0000" : "#555555")
border.width: 1
radius: 8
}
}
import QtQuick
import QtQuick.Controls as C
import QtQuick.Controls
import QtQuick.Layouts
import "../delegates"
import "../constants/tabs.js" as TabConstants
import "../constants/style.js" as Style
import "../components" as TopMenuBut
Rectangle {
// PROPERTIES
property string currentTab: TabConstants.systemManagementTab
property string currentTab: TabConstants.gamesTab
// FIELDS
id: tabs
......@@ -15,12 +18,57 @@ Rectangle {
y: 0
width: 640
height: 480
color: "#ffffff"
color: Style.backgroundColor
// onWidthChanged: { console.log("Window Width changed: " + width) }
// onHeightChanged: { console.log("Window Height changed: " + height)}
// COMPONENTS
RowLayout {
id: row
spacing: 5
//width: parent.width
anchors.leftMargin: parent.width / 10
anchors.rightMargin: parent.width / 10
anchors.bottomMargin: buttonSystemManagement.height / 6
anchors.topMargin: buttonSystemManagement.height / 6
Layout.alignment: Qt.AlignHCenter
height: buttonSystemManagement.height + anchors.bottomMargin + anchors.topMargin
//padding: 0
TopMenuBut.Button {
id: buttonSystemManagement
text: TabConstants.systemManagementTab
//Layout.preferredHeight: 30
onClicked: function(){
tabs.currentTab = TabConstants.systemManagementTab;
// tabs.changeTab();
// console.log(tabs.currentTab);
}
}
TopMenuBut.Button {
//anchors.horizontalCenter: parent.horizontalCenter
id: buttonGames
text: TabConstants.gamesTab
//Layout.preferredHeight: 30
onClicked: function(){
tabs.currentTab = TabConstants.gamesTab;
//if(core_app === undefined) return;
//console.log("core_app found");
//app.get_games();
// tabs.changeTab();
// console.log(tabs.currentTab);
}
}
}
Grid {
id: systemManagementGrid
......@@ -33,10 +81,10 @@ Rectangle {
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: 60
Layout.topMargin: 190
anchors.rightMargin: 0
anchors.leftMargin: 0
anchors.bottomMargin: 0
anchors.bottomMargin: 90
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
......@@ -46,107 +94,134 @@ Rectangle {
}
C.ScrollView {
ScrollView {
visible: tabs.currentTab == TabConstants.gamesTab
id: gamesScroller
anchors.fill: parent
anchors.topMargin: 60
clip : true
anchors.topMargin: row.height
ScrollBar.vertical: ScrollBar {
id: scrolV;
height: parent.height
opacity:0
property double fromAnim: 0.0
property double toAnim: 0.0
}
function scrollToY(y,HItem) {
scrolV.fromAnim = scrolV.position
scrolV.position = (1.0 - scrolV.size) * y/gamesScroller.height
scrolV.toAnim = (1.0 - scrolV.size) * y/gamesScroller.height
if(scrolV.toAnim != scrolV.fromAnim)scrollAnimation.start()
}
PropertyAnimation {to:scrolV.toAnim;from:scrolV.fromAnim;target:scrolV;id:scrollAnimation; property: "position" ;duration: 200 }
GridLayout {
id: gamesGrid
readonly property int elementWidth: 256 + gamesGrid.rowSpacing*2
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
// columns: Math.max(Math.floor(parent.width / elementWidth), 1)
// rows: Math.max(Math.ceil(children.length / columns), 1)
columns: Math.max(Math.floor(gamesScroller.width / elementWidth), 1)
columns: 6
rows: Math.max(Math.ceil(children.length / columns), 1)
anchors.rightMargin: 8
anchors.leftMargin: 8
anchors.bottomMargin: 8
anchors.topMargin: 8
rowSpacing: 8
anchors.rightMargin: rowSpacing
anchors.leftMargin: rowSpacing
anchors.bottomMargin : 90
anchors.topMargin: Math.floor( gamesScroller.width / 100 * 1.5)
rowSpacing:Math.floor( gamesScroller.width / 100 * 1.5)
columnSpacing: rowSpacing
Repeater {
// Layout.fillHeight: true
// Layout.fillWidth: true
model: core_app.games
Game {
gameTitle: model.name
gameExec: model.exec
gameIcon: model.icon
width: 256
height: 256
// icon: core_app.games.icon
// exec: core_app.games.exec
Layout.bottomMargin : (index - index % gamesGrid.columns)/ gamesGrid.columns === gamesGrid.rows-1 ? gamesGrid.rowSpacing*2 : 0
onFocusChanged: if(focus) { gamesScroller.scrollToY(y); }
Layout.preferredWidth: (gamesScroller.width - (gamesGrid.columns +1)* gamesGrid.rowSpacing) / gamesGrid.columns
Layout.preferredHeight: Layout.preferredWidth / 2 * 3
}
}
}
}
Rectangle {
id: tabsBar
height: 60
color: "#4a4a4a"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 0
anchors.leftMargin: 0
anchors.rightMargin: 0
Row {
id: row
height: 60
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: 5
padding: 0
rightPadding: 5
leftPadding: 5
bottomPadding: 5
topPadding: 5
Button {
id: buttonSystemManagement
text: "System management"
width: 150
height: 50
onClicked: function(){
tabs.currentTab = TabConstants.systemManagementTab;
// tabs.changeTab();
// console.log(tabs.currentTab);
}
}
Button {
id: buttonGames
text: "Games"
width: 150
height: 50
onClicked: function(){
tabs.currentTab = TabConstants.gamesTab;
//if(core_app === undefined) return;
//console.log("core_app found");
//app.get_games();
// tabs.changeTab();
// console.log(tabs.currentTab);
}
}
}
// LOGIC
property int focusedTabs: 0;
property int focusedItems: 0;
function applyTabsFocus(inc){
if(!visible)
return;
let c = row.children;
tabs.focusedTabs += inc;
if(tabs.focusedTabs >= c.length)
tabs.focusedTabs = 0;
if(tabs.focusedTabs < 0)
tabs.focusedTabs = c.length - 1;
c[tabs.focusedTabs].forceActiveFocus();
c[tabs.focusedTabs].clicked();
/* if (c[i].focus) {
console.log("focus found");
c[i].nextItemInFocusChain().forceActiveFocus()
break
} */
}
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){
if(!visible) return;
tabs.applyTabsFocus(-1)
}
function onGamepadClickedRB(done){
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();
}
}
}
......
var backColor = "red";
\ No newline at end of file
var backColor = "red";
var backgroundColor = "#1b262c";
var systemManagementTab = "systemManagement";
var gamesTab = "games";
\ No newline at end of file
var systemManagementTab = "System";
var gamesTab = "Games";
import QtQuick
import "../constants/scene.js" as SceneConstants
import "../components/" as C
//import "../components/" as C
import QtQuick.Controls as C
// Подключить для работы с типом объекта LinearGradient
C.Button {
property string gameTitle: "Generic title"
......@@ -8,24 +12,99 @@ C.Button {
property string gameExec: ""
id: game
width: 256
height: 256
implicitWidth: 256
implicitHeight: 256
text: ""
// color: "#efefef"
//radius: 5
// border.width: 1
MouseArea {
id: hoverArea
anchors.fill: parent
hoverEnabled: true
onClicked: function(){
// console.log(game.title);
gameInfoScene.title = game.gameTitle;
gameInfoScene.icon = game.gameIcon;
gameInfoScene.exec = game.gameExec;
window.scene = SceneConstants.gameInfoScene;
}
}
onClicked: function(){
// console.log(game.title);
gameInfoScene.title = game.gameTitle;
gameInfoScene.icon = game.gameIcon;
gameInfoScene.exec = game.gameExec;
window.scene = SceneConstants.gameInfoScene;
background: Rectangle {
id: rect
width:game.width + border.width *2
height:game.height + border.width*2
opacity: 1.0
color: "#000000"
anchors.centerIn: parent
border.width: 0
border.color: "#ffffff"
radius: 1
}
states: [
State {
name: "focus"; when: game.activeFocus
PropertyChanges { target: rect; border.width: Math.max(game.width / 100 * 2 ,2);}
PropertyChanges { target: game; scale:1.05 }
PropertyChanges { target: bgNameGrad; opacity:1 }
},
State {
name: "hover"; when: hoverArea.containsMouse
PropertyChanges { target: game; scale:1.05 }
PropertyChanges { target: bgNameGrad; opacity:1 }
}
]
transitions: [
Transition {
from: ""; to: "focus"
reversible: false
SequentialAnimation {
NumberAnimation{
target: rect; property: "border.width"
duration: 100
to: Math.max(game.width / 100 * 4,4) // пока x не будет равно 250
easing.type: Easing.InOutQuad
}
NumberAnimation {target: rect; property: "border.width"; duration: 100 }
}
},
Transition {
from: ""; to: "hover"
reversible: true
NumberAnimation {target: game ; property: "scale"; duration: 100 }
}
]
// вообще должно быть в Transition focus но оно там не рнаботает :(
SequentialAnimation{
id:anim
running: game.activeFocus ? true: false
loops: Animation.Infinite
OpacityAnimator {
target:rect ;
from: 1;
to: 0.4;
duration: 1000
}
OpacityAnimator {
target: rect;
from: 0.4;
to: 1;
duration: 1000
}
}
Image {
id: image
anchors.left: parent.left
......@@ -33,27 +112,44 @@ C.Button {
anchors.top: parent.top
anchors.bottom: parent.bottom
source: game.gameIcon
anchors.rightMargin: 8
anchors.bottomMargin: 47
anchors.leftMargin: 8
anchors.topMargin: 8
fillMode: Image.PreserveAspectFit
}
Text {
id: title
y: 439
height: 33
text: game.gameTitle
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
font.pixelSize: 22
horizontalAlignment: Text.AlignHCenter
anchors.rightMargin: 8
anchors.leftMargin: 8
anchors.bottomMargin: 8
Rectangle {
id:bgNameGrad
opacity: 0
anchors.fill: parent
gradient:Gradient {
GradientStop { position: 0.6; color: "#00000000" }
//GradientStop { position: 0.33; color: "yellow" }
GradientStop { position: 1.0; color: "#a0000000" }
}
Behavior on opacity{
NumberAnimation {target: bgNameGrad; property: "opacity"; duration: 200 }
}
Text {
id: title
y: 439
height: 33
color: "#ffffff"
text: game.gameTitle
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
font.pixelSize: Math.max(game.width / 100 * 8,10)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
// anchors.rightMargin: 8
// anchors.leftMargin: 8
anchors.bottomMargin: Math.max(game.width / 100 * 8,10)
}
}
}
}
......@@ -11,13 +11,32 @@ Window {
Connections {
target: core_app
function onGameStarted(done) {
console.log("gameStarted!!");
console.log("core_app: gameStarted");
window.scene = SceneConstants.runningScene;
}
function onGameEnded(done) {
console.log("gameEnded!!");
console.log("core_app: gameEnded");
window.scene = SceneConstants.gameInfoScene;
}
function onGamepadClickedLB(done){
// console.log("core_app: onGamepadClickedLB");
}
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: {
console.log("Desctructing window");
}
id: window
......
......@@ -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();
}
}
}
......@@ -12,8 +12,8 @@ Rectangle {
Rectangle {
id: rectangle
height: 64
color: "#2b2b2b"
height: parent.height/100 * 5
color: "black"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
......@@ -28,7 +28,7 @@ Rectangle {
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: 64
anchors.topMargin: rectangle.height
anchors.bottomMargin: 0
anchors.leftMargin: 0
anchors.rightMargin: 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment