Laying out main page and adding songlistmodel

This commit is contained in:
Chris Cochrun 2022-02-10 08:44:51 -06:00
parent f2a10ebfcc
commit 3bd74d1ca6
24 changed files with 816 additions and 454 deletions

View file

@ -10,11 +10,18 @@ import "./presenter" as Presenter
Kirigami.ApplicationWindow {
id: root
property bool libraryOpen: true
pageStack.initialPage: mainPage
header: Presenter.Header {}
width: 1280
Presenter.MainWindow {
id: mainPage
}
function toggleLibrary() {
libraryOpen = !libraryOpen
}
}

View file

@ -0,0 +1,12 @@
import QtQuick 2.13
import QtQuick.Dialogs 1.0
import QtQuick.Controls 2.15 as Controls
import QtQuick.Window 2.13
import QtQuick.Layouts 1.2
import QtMultimedia 5.15
import QtAudioEngine 1.15
import org.kde.kirigami 2.13 as Kirigami
import "./" as Presenter
QtObject {
}

View file

@ -0,0 +1,54 @@
import QtQuick 2.13
import QtQuick.Dialogs 1.0
import QtQuick.Controls 2.15 as Controls
import QtQuick.Window 2.13
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.13 as Kirigami
Kirigami.ActionToolBar {
id: root
alignment: Qt.AlignRight
Kirigami.Heading {
text: "Presenter"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 20
}
actions: [
Kirigami.Action {
displayComponent: Component {
Kirigami.SearchField {
id: searchField
onAccepted: showPassiveNotification(searchField.text, 3000)
}
}
},
Kirigami.Action {
icon.name: "fileopen"
text: "VideoBG"
onTriggered: {
print("Action button in buttons page clicked");
fileDialog.open()
}
},
Kirigami.Action {
icon.name: "view-presentation"
text: "Go Live"
onTriggered: {
print("Window is loading")
presentLoader.active = true
}
},
Kirigami.Action {
icon.name: "sidebar-collapse-right"
text: "Close Library"
onTriggered: toggleLibrary()
}
]
}

View file

@ -7,11 +7,49 @@ import QtMultimedia 5.15
import QtAudioEngine 1.15
import org.kde.kirigami 2.13 as Kirigami
ListView {
id: serviceItemList
model: listModel
delegate: itemDelegate
/* flickDeceleration: 2000 */
ColumnLayout {
id: root
Layout.fillHeight: true
Kirigami.Heading {
id: serviceTitle
text: "Service List"
level: 1
Layout.alignment: Qt.AlignHCenter
}
ListView {
id: serviceItemList
model: listModel
delegate: itemDelegate
/* flickDeceleration: 2000 */
Component {
id: itemDelegate
Kirigami.BasicListItem {
width: serviceItemList.width
height:50
label: itemName
subtitle: type
hoverEnabled: true
onClicked: serviceItemList.currentIndex = index
}
}
Kirigami.WheelHandler {
id: wheelHandler
target: serviceItemList
filterMouseEvents: true
keyNavigationEnabled: true
}
Controls.ScrollBar.vertical: Controls.ScrollBar {
anchors.right: serviceItemList.right
anchors.leftMargin: 10
active: hovered || pressed
}
}
ListModel {
id: listModel
@ -88,30 +126,4 @@ ListView {
type: "video"
}
}
Component {
id: itemDelegate
Kirigami.BasicListItem {
width: serviceItemList.width
height:50
label: itemName
subtitle: type
hoverEnabled: true
onClicked: serviceItemList.currentIndex = index
}
}
Kirigami.WheelHandler {
id: wheelHandler
target: serviceItemList
filterMouseEvents: true
keyNavigationEnabled: true
}
Controls.ScrollBar.vertical: Controls.ScrollBar {
anchors.right: serviceItemList.right
anchors.leftMargin: 10
active: hovered || pressed
}
}

View file

@ -0,0 +1,47 @@
import QtQuick 2.13
import QtQuick.Dialogs 1.0
import QtQuick.Controls 2.0 as Controls
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.13 as Kirigami
import "./" as Presenter
Item {
id: root
Presenter.PanelItem {
anchors.fill: parent
title: "Songs"
ListView {
anchors.fill: parent
id: libraryListView
model: _songListModel
delegate: itemDelegate
Component {
id: itemDelegate
Kirigami.BasicListItem {
width: ListView.view.width
height:40
label: title
subtitle: author
hoverEnabled: true
onClicked: ListView.view.currentIndex = index
}
}
Kirigami.WheelHandler {
id: wheelHandler
target: libraryListView
filterMouseEvents: true
keyNavigationEnabled: true
}
Controls.ScrollBar.vertical: Controls.ScrollBar {
anchors.right: libraryListView.right
anchors.leftMargin: 10
active: hovered || pressed
}
}
}
}

View file

@ -0,0 +1,11 @@
import QtQuick 2.13
import org.kde.kirigami 2.13 as Kirigami
Kirigami.BasicListItem {
width: ListView.view.width
height:20
label: model.itemName
subtitle: model.type
hoverEnabled: true
onClicked: ListView.view.currentIndex = index
}

View file

@ -0,0 +1,76 @@
import QtQuick 2.13
ListModel {
ListElement {
itemName: "10,000 Reason"
type: "song"
}
ListElement {
itemName: "Marvelous Light"
type: "song"
}
ListElement {
itemName: "10 reason to use church presenter"
type: "video"
}
ListElement {
itemName: "killer.jpg"
type: "image"
}
ListElement {
itemName: "Marvelous Light"
type: "song"
}
ListElement {
itemName: "Cool runnings"
type: "video"
}
ListElement {
itemName: "10,000 Reason"
type: "song"
}
ListElement {
itemName: "Slides1.odp"
type: "presentation"
}
ListElement {
itemName: "IntroSlide"
type: "custom-slide"
}
ListElement {
itemName: "10,000 Reason"
type: "song"
}
ListElement {
itemName: "Marvelous Light"
type: "song"
}
ListElement {
itemName: "other slide"
type: "custom-slide"
}
ListElement {
itemName: "10,000 Reason"
type: "song"
}
ListElement {
itemName: "Marvelous Light"
type: "song"
}
ListElement {
itemName: "10 reason to use church presenter"
type: "video"
}
ListElement {
itemName: "10,000 Reason"
type: "song"
}
ListElement {
itemName: "Marvelous Light"
type: "song"
}
ListElement {
itemName: "10 reason to use church presenter"
type: "video"
}
}

View file

@ -1,6 +1,6 @@
import QtQuick 2.13
import QtQuick.Dialogs 1.0
import QtQuick.Controls 2.0 as Controls
import QtQuick.Controls 2.15 as Controls
import QtQuick.Window 2.13
import QtQuick.Layouts 1.2
import QtMultimedia 5.15
@ -8,61 +8,54 @@ import QtAudioEngine 1.15
import org.kde.kirigami 2.13 as Kirigami
import "./" as Presenter
Kirigami.Page {
Controls.Page {
id: mainPage
title: "Presenter"
padding: 0
property var video: null
actions {
main: Kirigami.Action {
icon.name: "fileopen"
text: "VideoBG"
onTriggered: {
print("Action button in buttons page clicked");
fileDialog.open()
}
}
right: Kirigami.Action {
icon.name: "view-presentation"
text: "Go Live"
onTriggered: {
print("Window is loading")
presentLoader.active = true
}
}
}
Item {
id: mainItem
anchors.fill: parent
height: parent.height
GridLayout {
id: gridLayout
Controls.SplitView {
id: splitMainView
anchors.fill: parent
height: parent.height
columns: 3
rows: 2
Presenter.LeftDock {
id: leftDock
Layout.fillHeight: true
implicitWidth: 200
handle: Item{
implicitWidth: 6
Rectangle {
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
implicitWidth: 2
color: Controls.SplitHandle.hovered ? Kirigami.Theme.hoverColor : Kirigami.Theme.backgroundColor
//Controls.SplitHandle.pressed ? Kirigami.Theme.focusColor
//: (Controls.Splithandle.hovered ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor)
}
}
Rectangle {
id: leftDockBorder
color: "lightblue"
Layout.fillHeight: true
width: 2
Presenter.LeftDock {
id: leftDock
Controls.SplitView.fillHeight: true
Controls.SplitView.preferredWidth: 200
}
Rectangle {
id: rightMainArea
color: "red"
Layout.fillHeight: true
Layout.fillWidth: true
Controls.SplitView.fillHeight: true
Controls.SplitView.fillWidth: true
Controls.SplitView.preferredWidth: 700
Controls.SplitView.minimumWidth: 500
}
Presenter.Library {
id: library
Controls.SplitView.fillHeight: true
Controls.SplitView.preferredWidth: libraryOpen ? 200 : 0
Controls.SplitView.maximumWidth: 350
}
}
}

View file

@ -0,0 +1,70 @@
import QtQuick 2.7
import QtQuick.Controls 2.0 as Controls
import QtQuick.Layouts 1.2
import org.kde.kirigami 2.13 as Kirigami
Item {
default property var contentItem: null
property string title: "panel"
id: root
Layout.fillWidth: true
height: 30
Layout.fillHeight: current
property bool current: false
ColumnLayout {
anchors.fill: parent
spacing: 0
Rectangle {
id: bar
Layout.fillWidth: true
height: 30
color: root.current ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
Controls.Label {
anchors.fill: parent
anchors.margins: 10
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: root.title
}
Controls.Label {
anchors{
right: parent.right
top: parent.top
bottom: parent.bottom
margins: 10
}
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
text: "^"
rotation: root.current ? "180" : 0
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
root.current = !root.current;
if(root.parent.currentItem !== null)
root.parent.currentItem.current = false;
root.parent.currentItem = root;
}
}
}
Rectangle {
id: container
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
Layout.topMargin: bar.height / 4
implicitHeight: root.height - bar.height
color: Kirigami.Theme.backgroundColor
clip: true
Behavior on implicitHeight {
PropertyAnimation { duration: 100 }
}
}
Component.onCompleted: {
if(root.contentItem !== null)
root.contentItem.parent = container;
}
}
}

164
src/qml/presenter/Slide.qml Normal file
View file

@ -0,0 +1,164 @@
import QtQuick 2.13
import QtQuick.Controls 2.15 as Controls
import QtQuick.Layouts 1.2
import QtMultimedia 5.15
import QtAudioEngine 1.15
import org.kde.kirigami 2.13 as Kirigami
import "./" as Presenter
Item {
/*
Slides can only be instantiated as a direct child of a Presentation {} as they rely on
several properties there.
*/
id: slide
property bool isSlide: true;
property bool delayPoints: false;
property int _pointCounter: 0;
function _advance() {
if (!parent.allowDelay)
return false;
_pointCounter = _pointCounter + 1;
if (_pointCounter < content.length)
return true;
_pointCounter = 0;
return false;
}
property string title;
property variant content: []
property string centeredText
property string writeInText;
property string notes;
property real fontSize: parent.height * 0.05
property real fontScale: 1
property real baseFontSize: fontSize * fontScale
property real titleFontSize: fontSize * 1.2 * fontScale
property real bulletSpacing: 1
property real contentWidth: width
// Define the slide to be the "content area"
x: parent.width * 0.05
y: parent.height * 0.2
width: parent.width * 0.9
height: parent.height * 0.7
property real masterWidth: parent.width
property real masterHeight: parent.height
property color titleColor: parent.titleColor;
property color textColor: parent.textColor;
property string fontFamily: parent.fontFamily;
property int textFormat: Text.PlainText
visible: false
Controls.Label {
id: titleText
font.pixelSize: titleFontSize
text: title;
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.top
anchors.bottomMargin: parent.fontSize * 1.5
font.bold: true;
font.family: slide.fontFamily
color: slide.titleColor
horizontalAlignment: Text.Center
z: 1
}
Controls.Label {
id: centeredId
width: parent.width
anchors.centerIn: parent
anchors.verticalCenterOffset: - parent.y / 3
text: centeredText
horizontalAlignment: Text.Center
font.pixelSize: baseFontSize
font.family: slide.fontFamily
color: slide.textColor
wrapMode: Text.Wrap
}
Controls.Label {
id: writeInTextId
property int length;
font.family: slide.fontFamily
font.pixelSize: baseFontSize
color: slide.textColor
anchors.fill: parent;
wrapMode: Text.Wrap
text: slide.writeInText.substring(0, length);
NumberAnimation on length {
from: 0;
to: slide.writeInText.length;
duration: slide.writeInText.length * 30;
running: slide.visible && parent.visible && slide.writeInText.length > 0
}
visible: slide.writeInText != undefined;
}
Column {
id: contentId
anchors.fill: parent
Repeater {
model: content.length
Row {
id: row
function decideIndentLevel(s) { return s.charAt(0) == " " ? 1 + decideIndentLevel(s.substring(1)) : 0 }
property int indentLevel: decideIndentLevel(content[index])
property int nextIndentLevel: index < content.length - 1 ? decideIndentLevel(content[index+1]) : 0
property real indentFactor: (10 - row.indentLevel * 2) / 10;
height: text.height + (nextIndentLevel == 0 ? 1 : 0.3) * slide.baseFontSize * slide.bulletSpacing
x: slide.baseFontSize * indentLevel
visible: (!slide.parent.allowDelay || !delayPoints) || index <= _pointCounter
Rectangle {
id: dot
anchors.baseline: text.baseline
anchors.baselineOffset: -text.font.pixelSize / 2
width: text.font.pixelSize / 3
height: text.font.pixelSize / 3
color: slide.textColor
radius: width / 2
opacity: text.text.length == 0 ? 0 : 1
}
Item {
id: space
width: dot.width * 1.5
height: 1
}
Controls.Label {
id: text
width: slide.contentWidth - parent.x - dot.width - space.width
font.pixelSize: baseFontSize * row.indentFactor
text: content[index]
textFormat: slide.textFormat
wrapMode: Text.WordWrap
color: slide.textColor
horizontalAlignment: Text.AlignLeft
font.family: slide.fontFamily
}
}
}
}
}