Tabs.qml 14.4 KB
Newer Older
1
import QtQuick
Exc404's avatar
Exc404 committed
2
import QtQuick.Controls
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
3
import QtQuick.Layouts
ADav's avatar
ADav committed
4
import QtQuick.Dialogs
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
5
import "../delegates"
6
import "../constants/tabs.js" as TabConstants
Exc404's avatar
Exc404 committed
7 8
import "../constants/style.js" as Style
import "../components" as TopMenuBut
9
import "../constants/scene.js" as S
Exc404's avatar
Exc404 committed
10

11
// TODO: code refactor
12
Rectangle {
Exc404's avatar
Exc404 committed
13
    property string currentTab: TabConstants.gamesTab
14 15
    property var activeButtonTab: buttonGames

16
    id: tabs
17
    x: 0
18
    y: 0
Exc404's avatar
Exc404 committed
19 20 21
    anchors.fill: parent

    //color: Style.backgroundColor
22 23 24
    onVisibleChanged: {
        tabButtons.changeButtonActiveTab(tabs.activeButtonTab);
        tabButtons.x = tabButtons.tempX;
25
        // console.log("tabButtons.x = " + tabButtons.x);
26
    }
27

28 29 30
    Component.onCompleted: {
        tabButtons.changeButtonActiveTab(tabs.activeButtonTab);
        tabButtons.x = tabButtons.tempX;
31
        // console.log("Tabs completed!");
32 33 34 35 36 37 38 39 40
    }
    onWidthChanged: function(){
        tabButtons.changeButtonActiveTab(tabs.activeButtonTab);
        tabButtons.x = tabButtons.tempX;
    }
    onHeightChanged: function(){
        tabButtons.changeButtonActiveTab(tabs.activeButtonTab);
        tabButtons.x = tabButtons.tempX;
    }
41 42

    // Кнопки навигации
43 44
    ColumnLayout {
        id: topNavigation
45
        width: parent.width
46 47

        Rectangle {
48 49
            width: parent.width
            height: buttonSystemManagement.height
50
            color: "#00000000"
51 52
            Layout.bottomMargin: buttonSystemManagement.height / 2
            Layout.topMargin: buttonSystemManagement.height / 3
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

            Image {
                id: iconLB
                source: "../icons/XboxController/left-bumper.svg"
                fillMode: Image.Tile
                sourceSize.width: tabButtons.width / 100 * 15
                //sourceSize.height:
                //Layout.alignment: Qt.AlignLeft;
                anchors.leftMargin: window.width / 100 * 6
                anchors.left: parent.left
                anchors.verticalCenter: tabButtons.verticalCenter
                //Layout.leftMargin: Math.floor( parent.width / 100 * 6)
            }

            RowLayout {
                id: tabButtons
                property int tempX: 100
                property bool toggle: false

                Component.onCompleted: {
                    tabButtons.changeButtonActiveTab(tabs.activeButtonTab);
                    tabButtons.x = tabButtons.tempX;
75
                    // console.log("tabButtons completed!");
76
                }
77

78
                x: 0
79 80 81 82 83 84 85 86

                // Состояния
                states: [
                    State {
                        name: "ClickTabButton";
                        when: tabButtons.toggle;
                        PropertyChanges {
                            target: tabButtons;
87
                            x: tempX
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
                        }
                    },
                    State {
                        name: "";
                        when: 1 == 1
                    }
                ]
                // Анимации при изменениях состояний
                transitions:
                    Transition {
                        from: "";
                        to: "ClickTabButton";
                        PropertyAnimation {
                            id: clickTabButtonAnimation
                            // from: tempX
                            duration: 200
                            property: "x"
                            // анимацию можно будет поменять в любое время
                            easing.type: Easing.InOutCirc
                        }
108
                    }
109

110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
                // Функция перемещения кнопок
                // TODO: OPTIMIZE (REDUCE EXTRA FOR LOOP)
                function changeButtonActiveTab(ButtonId){
                    let index = 0;
                    let left_distance = 0;
                    let i = 0;

                    for(i = 0; i < tabButtons.children.length; ++i) {
                        if (children[i] === ButtonId) {
                            index = i
                            break
                        }
                    }

                    for(i = 0; i < index; ++i) {
                        left_distance += spacing + children[i].width;
                    }

                    tempX = topNavigation.width / 2 - tabButtons.children[index].width / 2 - left_distance;
                    tabs.activeButtonTab.isActive = false;
                    tabs.activeButtonTab = ButtonId;
                    tabs.activeButtonTab.isActive = true;
132
                }
133 134 135 136 137

                TopMenuBut.TextButton {
                    id: buttonSystemManagement;
                    text: TabConstants.systemManagementTab;
                    width: 400;
ADav's avatar
ADav committed
138
                    /*
139 140 141 142 143 144
                    onClicked: function(){
                        tabButtons.x = tabButtons.tempX
                        tabButtons.changeButtonActiveTab(this)
                        tabButtons.toggle = true
                        tabs.currentTab = TabConstants.systemManagementTab;
                        // tabs.changeTab();
ADav's avatar
ADav committed
145
                        console.log(tabs.currentTab);
146
                    }
ADav's avatar
ADav committed
147
                    */
148
                    onReleased: tabButtons.toggle = false
149
                }
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
                TopMenuBut.TextButton {
                    id: buttonGames
                    text: TabConstants.gamesTab
                    onClicked: function(){
                        tabButtons.x = tabButtons.tempX
                        tabButtons.changeButtonActiveTab(this)
                        tabButtons.toggle = true
                        tabs.currentTab = TabConstants.gamesTab;
                        //if(core_app === undefined) return;
                        //console.log("core_app found");

                        //app.get_games();
                        // tabs.changeTab();
                        // ;console.log(tabs.currentTab);

                        // ;console.log("1");
                    }
                    onReleased: tabButtons.toggle = false
Exc404's avatar
Exc404 committed
168

169
                }
170

Exc404's avatar
Exc404 committed
171

172
            }
173 174 175 176 177 178 179 180 181 182 183
            Image {
                id: iconRB
                source: "../icons/XboxController/right-bumper.svg"
                fillMode: Image.Tile
                //sourceSize.width: text.font.pixelSize * 2
                //sourceSize.height: tabButtons.width / 10
                sourceSize.width: tabButtons.width / 100 * 15
                //Layout.alignment: Qt.AlignRight;
                anchors.verticalCenter: tabButtons.verticalCenter
                anchors.rightMargin: window.width / 100 * 6
                anchors.right: parent.right
Exc404's avatar
Exc404 committed
184
            }
185

Exc404's avatar
Exc404 committed
186
        }
187

Exc404's avatar
Exc404 committed
188
    }
ADav's avatar
ADav committed
189
    // Заглушка Системных настроек !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
190
    Grid {
191 192 193
        id: systemManagementGrid
        visible: tabs.currentTab == TabConstants.systemManagementTab

ADav's avatar
ADav committed
194
        columns: 1
195
        spacing: 2
ADav's avatar
ADav committed
196
        anchors.centerIn: parent
197

198 199
        anchors.left: parent.left
        anchors.right: parent.right
200
        anchors.top: parent.top
201
        anchors.bottom: parent.bottom
Exc404's avatar
Exc404 committed
202
        Layout.topMargin: 190
ADav's avatar
ADav committed
203 204 205 206
        // anchors.rightMargin: 0
        // anchors.leftMargin: 0
        // anchors.bottomMargin: 90

207 208
        anchors.rightMargin: 0
        anchors.leftMargin: 0
ADav's avatar
ADav committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
        anchors.bottomMargin : 90

        Row {
            Text {
                font.family: globalFont.font
                font.weight: 400
                font.styleName: globalFont.font.styleName
                font.pointSize: 16
                text: "Полный экран при запуске:"
                color: 'white'
                opacity: 0.8
            }
            CheckBox {
                onCheckedChanged: {
                    if (checked) {
                        window.visibility = Window.FullScreen
                    } else {
                        window.visibility = Window.Windowed
                    }
                }
            }
230
        }
ADav's avatar
ADav committed
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
        Row {
            Text {
                font.family: globalFont.font
                font.weight: 400
                font.styleName: globalFont.font.styleName
                font.pointSize: 16
                color: 'white'
                opacity: 0.8
                text: "Каталог PortProton"
            }
            TextField {
                id: pathTextField
                width: 150
                readOnly: true
                text: "Выберите каталог"
            }
            Button {
                width: 50
                text: "Выбрать"
                onClicked: fileDialog.open()
            }
252
        }
ADav's avatar
ADav committed
253 254 255 256 257 258 259 260
        FileDialog {
            id: fileDialog
            title: "Выберите каталог"
            currentFolder: "/"
            fileMode: FileDialog.Directory
            onAccepted: {
                pathTextField.text = fileDialog.currentFolder
            }
261
        }
262 263
    }

264
    // Сетка игр
Exc404's avatar
Exc404 committed
265
    ScrollView {
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
266 267 268
        visible: tabs.currentTab == TabConstants.gamesTab
        id: gamesScroller
        anchors.fill: parent
269
        anchors.topMargin: topNavigation.height
Exc404's avatar
Exc404 committed
270 271 272
        ScrollBar.vertical: ScrollBar {
            id: scrolV;
            height: parent.height
273 274
            opacity: 0
            position: 0
Exc404's avatar
Exc404 committed
275 276 277 278 279 280 281

            property double fromAnim: 0.0
            property double toAnim: 0.0
        }

        function scrollToY(y,HItem) {
            scrolV.fromAnim = scrolV.position
282 283
            scrolV.position = (1.0 - scrolV.size) * y / gamesScroller.height
            scrolV.toAnim = (1.0 - scrolV.size) * y / gamesScroller.height
284 285
            if(scrolV.toAnim != scrolV.fromAnim)
                scrollAnimation.start()
Exc404's avatar
Exc404 committed
286
        }
287
        // Анимация авто скролла
288 289 290 291 292 293 294
        PropertyAnimation {
            to: scrolV.toAnim;
            from: scrolV.fromAnim;
            target: scrolV;
            id: scrollAnimation;
            property: "position";
            duration: 200;
Exc404's avatar
Exc404 committed
295
        }
296

Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
297 298 299 300 301 302
        GridLayout {
            id: gamesGrid
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.bottom: parent.bottom
Exc404's avatar
Exc404 committed
303
            columns: 5
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
304 305
            rows: Math.max(Math.ceil(children.length / columns), 1)

306 307
            anchors.rightMargin: rowSpacing * 2
            anchors.leftMargin: rowSpacing * 2
Exc404's avatar
Exc404 committed
308
            anchors.bottomMargin : 90
Exc404's avatar
Exc404 committed
309 310
            anchors.topMargin: Math.floor( gamesScroller.width / 100 * 3)
            rowSpacing: Math.floor( gamesScroller.width / 100 * 3)
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
311 312
            columnSpacing: rowSpacing

313
            // Повторитель
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
314 315
            Repeater {
                model: core_app.games
316
                // Карточка игры
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
317
                Game {
318
                    id: game
319 320 321
                    gameTitle: model.name
                    gameExec: model.exec
                    gameIcon: model.icon
322 323 324 325 326 327 328 329 330 331
                    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.anchors.rightMargin - gamesGrid.anchors.leftMargin)
                        / gamesGrid.columns
Exc404's avatar
Exc404 committed
332
                    Layout.preferredHeight: Layout.preferredWidth / 2 * 3
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355

                    // Component.onCompleted: {a3.start()}

                    // SequentialAnimation  {
                    //     id:a3

                    //     NumberAnimation {
                    //         property:Layout.topMargin;
                    //         easing.type: Easing.InOutQuad;
                    //         duration: 300;
                    //         from: 100//Layout.preferredHeight;
                    //         to: 0;
                    //     }
                    //     NumberAnimation {
                    //         property:Layout.topMargin;
                    //         easing.type: Easing.InOutQuad;
                    //         duration: 300;
                    //         from: 0//Layout.preferredHeight;
                    //         to: 100;
                    //     }
                    //     loops: Animation.Infinite
                    // }

356
                    // Layout.topMargin: Layout.preferredHeight
357

Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
358 359
                }
            }
360
        }
361 362 363 364
    }



Exc404's avatar
Exc404 committed
365

366

Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
367
    // LOGIC
368
    property int focusedItems: 0;
369 370 371 372 373 374
    property int focusedTabs: 0;

    function getTabs(){
        return [
            buttonSystemManagement,
            buttonGames,
375
            // testbut1,
376 377 378
            testbut2
        ];
    }
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
379

380
    function applyTabsFocus(inc){
381
        if(window.scene !== S.homeScene) return;
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
382

383
        let c = tabs.getTabs();
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
384

385 386 387
        tabs.focusedTabs += inc;
        if(tabs.focusedTabs >= c.length)
            tabs.focusedTabs = 0;
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
388

389 390
        if(tabs.focusedTabs < 0)
            tabs.focusedTabs = c.length - 1;
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
391

392 393 394 395
        let item = c[tabs.focusedTabs];
        item.released();
        item.clicked();
        // tabButtons.changeButtonActiveTab(item);
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
396 397
    }

398
    function applyItemsFocus(inc){
399
        if(window.scene !== S.homeScene) return;
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414

        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();
    }

415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
    function onGamepadClickedLB(done){
        if(window.scene !== S.homeScene) return;
        tabs.applyTabsFocus(-1)
    }
    function onGamepadClickedRB(done){
        if(window.scene !== S.homeScene) return;
        tabs.applyTabsFocus(1)
    }
    function onGamepadAxisLeft(done){
        if(window.scene !== S.homeScene) return;
        tabs.applyItemsFocus(-1)
    }
    function onGamepadAxisRight(done){
        if(window.scene !== S.homeScene) return;
        tabs.applyItemsFocus(1)
    }
    function onGamepadClickedApply(done){
        if(window.scene !== S.homeScene) return;
        // console.log("onGamepadClickedApply");
        let c = gamesGrid.children;
        c[tabs.focusedItems].press();
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
436
    }
437

438
}
Georgiy Yankovskiy's avatar
Georgiy Yankovskiy committed
439

440

441 442 443 444 445 446

/*##^##
Designer {
    D{i:0}D{i:1;invisible:true}
}
##^##*/