LibraryView.qml 23.6 KB
Newer Older
1 2 3 4
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import QtQuick.Layouts 1.3
5
import Athenaeum 1.0
librebob's avatar
librebob committed
6 7

Page {
librebob's avatar
librebob committed
8 9
    header: NavigationBar {
        activeView: 'library'
librebob's avatar
librebob committed
10
    }
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    /* Search Bar */
    TextField {
        id: searchField
        leftPadding: 10
        rightPadding: 10
        anchors.top: parent.top
        anchors.bottom: filterCombo.top
        width: listView.width
        // background: Rectangle {
        //     anchors.fill: parent
        //     color: Material.background
        // }
        color: Material.foreground
        placeholderText: qsTr('Search %L1 Games...').arg(library.filter.length)
        onTextChanged: {
            library.searchValue = text
        }
        Keys.onEscapePressed: {
            text = ''
        }
    }
librebob's avatar
librebob committed
32
    /* Game List */
librebob's avatar
librebob committed
33 34
    ComboBox {
        id: filterCombo
35 36
        width: listView.width
        anchors.top: searchField.bottom
37 38 39 40 41 42
        currentIndex: getFilterIndex(library.filterValue)
        
        property string filterIndex: library.filterValue
        onFilterIndexChanged: {
            currentIndex = getFilterIndex(library.filterValue)
        }
43 44 45
        onModelChanged: {
            currentIndex = getFilterIndex(library.filterValue)
        }
46 47 48 49
        onActivated: {
            library.filterValue = getFilterKey(index)
            searchField.text = ''
        }
librebob's avatar
librebob committed
50
        function getFilterIndex(key) {
51 52
            switch(key) {
                case 'installed':
librebob's avatar
librebob committed
53
                    return 0;
54
                case 'recent':
librebob's avatar
librebob committed
55
                    return 1;
56
                case 'has_updates':
librebob's avatar
librebob committed
57
                    return 2;
58
                case 'processing':
librebob's avatar
librebob committed
59
                    return 3;
librebob's avatar
librebob committed
60
            }
61
        }
62 63 64 65 66 67 68 69 70 71 72 73 74
        function getFilterKey(index) {
            switch(index) {
                case 0:
                    return 'installed';
                case 1:
                    return 'recent';
                case 2:
                    return 'has_updates';
                case 3:
                    return 'processing';
            }
        }
       
librebob's avatar
librebob committed
75 76 77 78 79 80
        model: [
            qsTr('Installed (%L1)').arg(library.installedCount),
            qsTr('Recent (%L1)').arg(library.recentCount),
            qsTr('Has Updates (%L1)').arg(library.hasUpdatesCount),
            qsTr('Processing (%L1)').arg(library.processingCount)
        ]
81
        validator: IntValidator {
82
            top: 4
83 84
            bottom: 0
        }
85

librebob's avatar
librebob committed
86
    }
librebob's avatar
librebob committed
87 88
    ListView {
        id: listView
librebob's avatar
librebob committed
89
        anchors.top: filterCombo.bottom
librebob's avatar
librebob committed
90
        anchors.bottom: parent.bottom
91
        model: library.filter
librebob's avatar
librebob committed
92 93 94
        width: 200
        ScrollBar.vertical: ScrollBar { }
        boundsBehavior: Flickable.StopAtBounds
librebob's avatar
librebob committed
95
        keyNavigationEnabled: true
96
        // focus: true
librebob's avatar
librebob committed
97
        clip:true
98 99 100

        onModelChanged: {
            currentIndex = library.getIndexForCurrentGame()
librebob's avatar
librebob committed
101
        }
102

librebob's avatar
librebob committed
103 104
        delegate: Component {
            id: delegateComponent
105
            Rectangle {
librebob's avatar
librebob committed
106 107
                anchors.left: parent.left
                anchors.right: parent.right
librebob's avatar
librebob committed
108
                height: 35
librebob's avatar
librebob committed
109
                id: rect
librebob's avatar
librebob committed
110
                border.color: ListView.isCurrentItem || itemMouseArea.containsMouse ? Material.accent : tr
librebob's avatar
librebob committed
111 112 113 114
                border.width: 1
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
115 116
                        listView.currentIndex = index
                        window.indexUpdated(index)
117
                        listView.forceActiveFocus()
librebob's avatar
librebob committed
118 119 120 121
                    }
                    id: itemMouseArea
                    hoverEnabled: true
                }
122
                // color: ListView.isCurrentItem ? Material.accent : itemMouseArea.containsMouse ? Material.accent : Material.background
librebob's avatar
librebob committed
123
                color: tr
librebob's avatar
librebob committed
124
                Rectangle {
librebob's avatar
librebob committed
125 126 127
                    id: gameIcon
                    anchors.top: parent.top
                    anchors.bottom: parent.bottom
librebob's avatar
librebob committed
128 129 130
                    anchors.margins: 1
                    width: parent.height
                    height: parent.height
131
                    color: tr
librebob's avatar
librebob committed
132 133 134 135 136 137
                    Image {
                        anchors.fill: parent
                        anchors.margins: 5
                        fillMode: Image.PreserveAspectFit
                        source: iconSmall
                    }
librebob's avatar
librebob committed
138 139
                }
                Text {
140 141
                    // color: parent.ListView.isCurrentItem ? Material.background : itemMouseArea.containsMouse ? Material.background : Material.foreground
                    color: Material.foreground
librebob's avatar
librebob committed
142 143
                    clip: true
                    width: parent.width
librebob's avatar
librebob committed
144 145
                    anchors.left: gameIcon.right
                    anchors.top: parent.top
librebob's avatar
librebob committed
146
                    anchors.bottom: parent.bottom
147
                    anchors.right: parent.right
librebob's avatar
librebob committed
148
                    text: name
librebob's avatar
librebob committed
149 150 151 152
                    anchors.topMargin: 5
                    anchors.rightMargin: 5
                    anchors.bottomMargin: 5
                    verticalAlignment: Text.AlignVCenter
librebob's avatar
librebob committed
153
                }
154
                BusyIndicator {
155
                    visible: true
156 157 158 159 160 161
                    height: parent.height
                    width: parent.height
                    id: gameProcessing
                    anchors.right: parent.right
                    running: processing
                }
162 163 164 165 166 167 168 169 170 171
                Rectangle {
                    visible: false
                    height: parent.height
                    width: parent.height
                    anchors.right: parent.right
                    color: tr
                    Rectangle {
                        width: childrenRect.width
                        height: childrenRect.height
                        anchors.centerIn: parent
172
                        //color: sel
173 174 175 176 177
                        radius: 3
                        Text {
                            text: qsTr('New')
                            font.pixelSize: 12
                            padding: 3
178
                            //color: tc
179 180 181
                        }
                    }
                }
librebob's avatar
librebob committed
182 183 184
            }
        }
    }
librebob's avatar
librebob committed
185
    /* Game Detail Pane */
186
    Rectangle {
librebob's avatar
librebob committed
187 188 189
        anchors.left: listView.right
        anchors.right: parent.right
        anchors.top: parent.top
190
        anchors.bottom: parent.bottom
191
        color: Material.background
192 193 194 195 196 197 198 199
        Text {
            visible: !library.currentGame.id.length
            text: qsTr('Nothing seems to be here.')
            anchors.centerIn: parent
            color: Material.primary
            font.italic: true
            font.pixelSize: 14
        }
200
        Flickable {
201
            visible: library.currentGame.id.length
202 203 204
            anchors.fill: parent
            contentHeight: col.height
            contentWidth: parent.width
205 206
            ScrollBar.vertical: ScrollBar { }
            boundsBehavior: Flickable.StopAtBounds
207 208 209
            Column {
                id: col
                width: parent.width
librebob's avatar
librebob committed
210
                spacing: 40
librebob's avatar
librebob committed
211
                /* Header */
librebob's avatar
librebob committed
212 213 214 215 216
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.rightMargin: 40
                    anchors.leftMargin: 40
librebob's avatar
librebob committed
217

218
                    color: Material.background
librebob's avatar
librebob committed
219
                    height: childrenRect.height
librebob's avatar
librebob committed
220

librebob's avatar
librebob committed
221 222
                    Rectangle {
                        anchors.top: parent.top
librebob's avatar
librebob committed
223
                        anchors.left: parent.left
librebob's avatar
librebob committed
224 225 226
                        anchors.right: gameTitle.left
                        // anchors.bottom: parent.bottom
                        anchors.topMargin: 40
librebob's avatar
librebob committed
227

librebob's avatar
librebob committed
228 229 230
                        width: 128
                        height: 128
                        id: gameLogo
librebob's avatar
librebob committed
231

232
                        color: Material.primary
librebob's avatar
librebob committed
233 234 235 236 237 238
                        radius: 10
                        Image {
                            id: img
                            anchors.fill: parent
                            fillMode: Image.PreserveAspectFit
                            source: library.currentGame.iconLarge
librebob's avatar
librebob committed
239
                        }
librebob's avatar
librebob committed
240 241 242 243 244 245 246
                    }
                    Text {
                        id: gameTitle
                        anchors.top: parent.top
                        anchors.left: gameLogo.right
                        anchors.right: parent.right
                        anchors.topMargin: 40
librebob's avatar
librebob committed
247

librebob's avatar
librebob committed
248
                        leftPadding: 20
librebob's avatar
librebob committed
249

250
                        color: Material.foreground
librebob's avatar
librebob committed
251
                        text: library.currentGame.name
librebob's avatar
librebob committed
252 253


librebob's avatar
librebob committed
254 255 256
                        fontSizeMode: Text.VerticalFit
                        font.pixelSize: 48
                        minimumPixelSize: 30;
librebob's avatar
librebob committed
257

librebob's avatar
librebob committed
258
                        elide: Label.ElideRight
librebob's avatar
librebob committed
259

librebob's avatar
librebob committed
260 261 262 263 264 265 266 267 268
                        horizontalAlignment: Text.AlignLeft
                        wrapMode: Text.WordWrap
                    }
                    Text {
                        id: gameSummary
                        anchors.top: gameTitle.bottom
                        anchors.left: gameLogo.right
                        anchors.right: parent.right
                        leftPadding: 20
librebob's avatar
librebob committed
269

270
                        color: Material.foreground
librebob's avatar
librebob committed
271
                        text: library.currentGame.summary
librebob's avatar
librebob committed
272

librebob's avatar
librebob committed
273 274 275 276
                        fontSizeMode: Text.VerticalFit
                        font.pixelSize: 16
                        minimumPixelSize: 10;
                        elide: Label.ElideRight
librebob's avatar
librebob committed
277

librebob's avatar
librebob committed
278 279 280 281 282 283 284
                        horizontalAlignment: Text.AlignLeft
                        wrapMode: Text.WordWrap
                    }
                    Row {
                        anchors.top: gameSummary.bottom
                        anchors.left: gameLogo.right
                        anchors.right: parent.right
librebob's avatar
librebob committed
285
                        spacing: 10
librebob's avatar
librebob committed
286 287 288 289 290 291 292 293
                        leftPadding: 20
                        topPadding: 10
                        Button {
                            visible: !library.currentGame.installed
                            enabled: !library.currentGame.processing
                            onClicked: {
                                window.installGame(library.currentGame.id)
                            }
librebob's avatar
librebob committed
294 295
                            icon.source: 'icons/download.svg'
                            text: qsTr('Install')
librebob's avatar
librebob committed
296
                        }
librebob's avatar
librebob committed
297
                        Button {
librebob's avatar
librebob committed
298
                            id: playButton
librebob's avatar
librebob committed
299 300 301 302 303
                            visible:  library.currentGame.installed
                            enabled: !library.currentGame.playing
                            onClicked: {
                                window.playGame(library.currentGame.id)
                            }
librebob's avatar
librebob committed
304 305 306 307 308
                            highlighted: true
//                             background.color= 'lightgreen'
                            icon.source: 'icons/play.svg'
                            text: qsTr('Play')

librebob's avatar
librebob committed
309
                        }
310 311 312 313 314 315
                        Button {
                            visible: library.currentGame.hasUpdate && library.currentGame.installed
                            enabled: !library.currentGame.playing && !library.currentGame.processing
                            onClicked: {
                                window.updateGame(library.currentGame.id)
                            }
librebob's avatar
librebob committed
316
                            text: qsTr('Update')
317
                        }
librebob's avatar
librebob committed
318
                        Button {
librebob's avatar
librebob committed
319 320
                            text: qsTr('Uninstall')
                            icon.source: 'icons/trash.svg'
librebob's avatar
librebob committed
321 322 323 324 325 326
                            visible: library.currentGame.installed
                            enabled: !library.currentGame.processing
                            MouseArea {
                                id: uninstallMouseArea
                                anchors.fill: parent
                                hoverEnabled: true
327
                                onClicked: {
328 329 330 331 332
                                    uninstallPopup.open()
                                }
                            }
                            Popup {
                                id: uninstallPopup
333
                                parent: stackView
334 335 336 337 338 339
                                x: Math.round((parent.width - width) / 2)
                                y: Math.round((parent.height - height) / 2)
                                modal: true
                                dim: true
                                focus: true
                                contentItem: Column {
librebob's avatar
librebob committed
340
                                    spacing: 20
341 342
                                    Text {
                                        anchors.horizontalCenter: parent.horizontalCenter
343
                                        color: Material.foreground
344
                                        font.pixelSize: 20
345
                                        text: qsTr('Are you sure?')
346 347 348 349 350
                                    }
                                    Row {
                                        spacing: 20
                                        anchors.horizontalCenter: parent.horizontalCenter
                                        Button {
librebob's avatar
librebob committed
351 352 353
                                            onClicked: {
                                                window.uninstallGame(library.currentGame.id)
                                                uninstallPopup.close()
354
                                            }
librebob's avatar
librebob committed
355
                                            text: qsTr('Yes')
356 357
                                        }
                                        Button {
librebob's avatar
librebob committed
358 359 360
                                            text: qsTr('Cancel')
                                            onClicked: {
                                                uninstallPopup.close()
361 362 363
                                            }
                                        }
                                    }
364
                                }
librebob's avatar
librebob committed
365
                            }
librebob's avatar
librebob committed
366 367 368 369
                        }
                        Button {
                            onClicked: {
                                enter(gameView, library.currentGame.id)
librebob's avatar
librebob committed
370
                            }
librebob's avatar
librebob committed
371 372
                            icon.source: 'icons/browse.svg'
                            text: qsTr('View In Store')
librebob's avatar
librebob committed
373
                        }
374
                    }
librebob's avatar
librebob committed
375
                }
librebob's avatar
librebob committed
376 377


librebob's avatar
librebob committed
378
                /* Logs */
379 380 381 382 383
                Rectangle {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.rightMargin: 40
                    anchors.leftMargin: 40
384
                    color: "black"
385
                    height: 160
librebob's avatar
librebob committed
386
                    visible: library.currentGame.error || library.currentGame.processing || (settings.alwaysShowLogs && library.currentGame.installed)
387 388 389

                    Flickable {
                        id: testFlick
390
                        anchors.fill: parent
391 392 393 394 395 396 397 398 399 400 401

                        // ScrollBar.vertical: ScrollBar {
                        //     policy: ScrollBar.AlwaysOn }
                        clip: true
                        boundsBehavior: Flickable.StopAtBounds

                        TextArea {
                            id: ta
                            onContentHeightChanged: {
                                testFlick.contentY = (contentHeight <= 150 ? 0 : contentHeight - 150)
                            }
402
                            color: "white"
403 404
                            readOnly: true
                            text: library.currentGame.log
405 406 407 408
                            background: Rectangle {
                                anchors.fill: parent
                                color: "black"
                            }
409 410 411
                        }
                    }
                }
librebob's avatar
librebob committed
412
                /* Body */
librebob's avatar
librebob committed
413
                Grid {
librebob's avatar
librebob committed
414 415
                    anchors.left: parent.left
                    anchors.right: parent.right
librebob's avatar
librebob committed
416
                    columns: 2
librebob's avatar
librebob committed
417 418 419 420 421
                    spacing: 20
                    /* Releases */
                    leftPadding: 40
                    rightPadding: 40
                    topPadding: 10
librebob's avatar
librebob committed
422
                    Column {
librebob's avatar
librebob committed
423 424
                        width: parent.width - 250
                        spacing: 10
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
                        Text {
                            id: releaseHeading
                            color: Material.foreground
                            font.pixelSize: 24
                            text: qsTr('Releases')
                            wrapMode: Text.WrapAnywhere
                        }
                        Text {
                            visible: !library.currentGame.releases.length
                            text: qsTr('No release information available.')
                            font.italic: true
                            color: Material.foreground
                        }
                        ListView {
                            visible: library.currentGame.releases.length
                            model: library.currentGame.releases
librebob's avatar
librebob committed
441
                            width: parent.width
442 443 444
                            height: contentHeight
                            spacing: 10
                            delegate: Column {
librebob's avatar
librebob committed
445
                                width: parent.width
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
                                function formatTimestamp(ts) {
                                    var t = new Date( 0 );
                                    t.setSeconds(ts);
                                    return t.toLocaleDateString();
                                }
                                Flow {
                                    width: parent.width
                                    spacing: 10
                                    Text {
                                        color: Material.foreground
                                        font.pixelSize: 20
                                        text: qsTr('Version %1').arg(version)
                                        wrapMode: Text.WrapAnywhere
                                    }
                                    Text {
                                        color: Material.foreground
                                        font.pixelSize: 20
                                        text: formatTimestamp(timestamp)
                                        wrapMode: Text.WrapAnywhere
                                    }
librebob's avatar
librebob committed
466
                                }
librebob's avatar
librebob committed
467
                                Text {
468 469 470
                                    topPadding: 10
                                    bottomPadding: 10
                                    width: parent.width
librebob's avatar
librebob committed
471
                                    color: Material.foreground
472 473 474
                                    font.pixelSize: 16
                                    font.italic: description ? false : true
                                    text: description || qsTr('No release description available.')
librebob's avatar
librebob committed
475
                                    wrapMode: Text.WrapAnywhere
476
                                }
librebob's avatar
librebob committed
477
                            }
librebob's avatar
librebob committed
478 479 480 481 482 483
                        }
                    }
                    
                    Column {
                        width: 250
                        spacing: 10
librebob's avatar
librebob committed
484 485 486 487 488 489 490 491 492 493 494 495
//                         Text {
//                             color: Material.foreground
//                             font.pixelSize: 20
//                             text: qsTr('Hours Played')
//                             wrapMode: Text.WrapAnywhere
//                         }
//                         Text {
//                             color: Material.foreground
//                             font.pixelSize: 16
//                             text: qsTr('14 Hours')
//                             wrapMode: Text.WrapAnywhere
//                         }
librebob's avatar
librebob committed
496
                        
497 498 499
                        Text {
                            visible: library.currentGame.developerName
                            color: Material.foreground
librebob's avatar
librebob committed
500
                            font.pixelSize: 20
501 502 503 504 505 506 507 508 509 510 511 512 513 514
                            text: qsTr('Developer')
                            wrapMode: Text.WrapAnywhere
                        }
                        Text {
                            visible: library.currentGame.developerName
                            color: Material.foreground
                            font.pixelSize: 16
                            text: library.currentGame.developerName
                            wrapMode: Text.WordWrap
                        }
                        
                        Text {
                            visible: library.currentGame.license
                            color: Material.foreground
librebob's avatar
librebob committed
515
                            font.pixelSize: 20
516 517 518 519 520 521 522 523 524 525 526 527 528 529
                            text: qsTr('License')
                            wrapMode: Text.WrapAnywhere
                        }
                        Text {
                            visible: library.currentGame.license
                            color: Material.foreground
                            font.pixelSize: 16
                            text: library.currentGame.license
                            wrapMode: Text.WrapAnywhere
                        }
                            
                        Text {
                            visible: library.currentGame.urls.length
                            color: Material.foreground
librebob's avatar
librebob committed
530
                            font.pixelSize: 20
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
                            text: qsTr('Links')
                            wrapMode: Text.WrapAnywhere
                        }
                        ListView {
                            visible: library.currentGame.urls.length
                            model: library.currentGame.urls
                            id: linksList
                            height: contentHeight
                            width: contentWidth
                            delegate: Button {
                                MouseArea {
                                    anchors.fill: parent
                                    hoverEnabled: true
                                    cursorShape: Qt.PointingHandCursor
                                    onClicked: {
                                        Qt.openUrlExternally(url)
                                    }
                                }
                                icon.source: 'icons/' + urlIcon
                                topPadding: 0
                                leftPadding: 0
                                background: Rectangle {
                                    anchors.fill: parent
                                    color: tr
555
                                }
librebob's avatar
librebob committed
556

557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
                                icon.color: type === 'donation' ? '#00000000' : icon.color
                                font.capitalization: Font.MixedCase
                                function getTitle(type) {
                                    switch(type) {
                                        case 'homepage':
                                            return qsTr('Homepage');
                                        case 'bugtracker':
                                            return qsTr('Bug Tracker');
                                        case 'help':
                                            return qsTr('Help');
                                        case 'faq':
                                            return qsTr('FAQ');
                                        case 'donation':
                                            return qsTr('Donate');
                                        case 'translate':
                                            return qsTr('Translation');
                                        case 'unknown':
                                            return qsTr('Unknown');
                                        case 'manifest':
                                            return qsTr('Manifest');
                                    }
librebob's avatar
librebob committed
578
                                }
579
                                text: getTitle(type)
580 581 582 583
                            }
                        }
                    }
                }
584
            }
librebob's avatar
librebob committed
585 586 587
        }
    }
}