diff --git a/main.go b/main.go index 2995511..c84b931 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,14 @@ // PresentationApp project main.go +//go:generate genqrc qml + package main import ( "fmt" "image/color" "os" - "path/filepath" "github.com/go-gl/glfw/v3.1/glfw" - "github.com/kardianos/osext" "github.com/lordwelch/qml" "gopkg.in/gographics/imagick.v2/imagick" ) @@ -41,6 +41,7 @@ type cell struct { outline Bool } } + type slide []*cell var ( @@ -69,9 +70,7 @@ func run() error { engine.Context().SetVar("go", QML) findfonts() engine.AddImageProvider("images", imgProvider) - //path for qml files TODO: change to somewhere else - path, err = osext.ExecutableFolder() - path = filepath.Clean(path + "/../src/github.com/lordwelch/PresentationApp/") + path = "qrc:///qml" mainQml, err = engine.LoadFile(path + "/main.qml") if err != nil { diff --git a/main.qml b/main.qml deleted file mode 100644 index ee01522..0000000 --- a/main.qml +++ /dev/null @@ -1,253 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Dialogs 1.2 -import QtQuick.Controls 1.3 -import QtQuick.Window 2.0 -import "qml" -import QtQuick.Layouts 1.0 - -ApplicationWindow { - id: applicationWindow1 - title: "Presentation App" - visible: true - objectName: "applicationWindow1" - minimumWidth: 500 - minimumHeight: 500 - width: 1000 - height: 600 - property bool cls: false - - - /*function getFileDialogUrl() { - return - }*/ - onClosing: if (!cls) { - close.accepted = false - } - - FileDialog { - id: imgpicker - // @disable-check M16 - title: "Choose an image for this slide" - // @disable-check M16 - objectName: "imgpicker" - } - - AboutDialog { - id: aboutDialog - } - - Action { - id: aboutAction - text: "About" - onTriggered: aboutDialog.open() - } - - menuBar: MenuBar { - Menu { - title: "&File" - MenuItem { - text: "Close" - shortcut: StandardKey.Quit - } - } - Menu { - title: "&Edit" - MenuItem { - text: "quick edit" - objectName: "mnuEdit" - } - } - - Menu { - title: "Window" - - MenuItem { - text: "Display" - objectName: "mnuDisplay" - } - } - - Menu { - title: "&Help" - MenuItem { - action: aboutAction - } - } - } - - Menu { - objectName: "mnuCtx" - title: "new image..." - MenuItem { - objectName: "mnuImgPick" - text: "new Image..." - onTriggered: imgpicker.open() - } - } - - SplitView { - id: mainSlider - objectName: "mainSlider" - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.top: parent.top - anchors.left: parent.left - anchors.rightMargin: 0 - anchors.bottomMargin: 0 - anchors.leftMargin: 0 - anchors.topMargin: 0 - orientation: Qt.Horizontal - onResizingChanged: col1.width = gridData.width / 2 - - Rectangle { - id: gridRect - objectName: "gridRect" - width: 300 - color: "#00000000" - border.width: 4 - anchors.left: parent.left - anchors.leftMargin: 0 - anchors.bottom: parent.bottom - anchors.bottomMargin: 0 - anchors.top: parent.top - anchors.topMargin: 0 - property int count: 0 - - ScrollView { - id: scview - anchors.fill: parent - anchors.margins: 4 - horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff - verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn - - SplitView { - id: gridData - objectName: "gridData" - width: scview.width - 1 - height: gridRect.count * 101 - - Rectangle { - id: col1 - objectName: "col1" - width: gridData.width / 2 - color: "#00000000" - transformOrigin: Item.TopLeft - border.width: 0 - Rectangle { - id: textEdit - property int cell - x: 232 - y: 622 - objectName: "textEdit" - width: 200 - height: 200 - color: "#ffffff" - visible: false - property bool txt: true - Keys.onPressed: { - if ((event.key == Qt.Key_Return) - && (event.modifiers & Qt.ControlModifier)) { - txt = true - - x = -100 - y = -100 - visible = false - focus = true - enabled = false - opacity = 0 - textEdit1.focus = false - - event.accepted = true - } - - if (event.key == Qt.Key_Escape) { - txt = false - x = -100 - y = -100 - visible = false - focus = true - enabled = false - opacity = 0 - textEdit1.focus = false - - event.accepted = true - } - } - - TextArea { - id: textEdit1 - objectName: "textEdit1" - anchors.fill: parent - clip: true - textFormat: Text.AutoText - visible: true - font.pixelSize: 12 - z: 99 - } - } - - Column { - id: data1 - objectName: "data1" - spacing: 1 - anchors.fill: parent - } - } - - Rectangle { - id: col2 - objectName: "col2" - color: "#00000000" - border.width: 0 - - Column { - id: data2 - spacing: 1 - objectName: "data2" - anchors.fill: parent - } - } - } - } - } - - Rectangle { - id: mainView - border.width: 0 - objectName: "mainView" - anchors.right: parent.right - anchors.rightMargin: 0 - anchors.leftMargin: 0 - anchors.left: gridRect.right - anchors.bottom: parent.bottom - anchors.top: parent.top - z: 1 - clip: false - visible: true - - Button { - id: button1 - objectName: "btnAdd" - x: 8 - y: 8 - text: qsTr("Button") - } - - Button { - id: button2 - x: 8 - y: 39 - text: qsTr("Button") - objectName: "btnRem" - } - - Button { - id: button3 - x: 8 - y: 70 - text: qsTr("Button") - objectName: "btnMem" - } - } - } -} diff --git a/qml.go b/qml.go index 10bda7f..c3f699e 100644 --- a/qml.go +++ b/qml.go @@ -13,7 +13,7 @@ import ( ) var ( - selCell int //the focused and + selCell int //the focused cell rhtClkCell int //the cell that was last right clicked qimg qml.Object //file for the image object cellQml qml.Object //file for the cell object @@ -193,10 +193,8 @@ func imgProvider(id string, width, height int) image.Image { //just gives a new source so that the cache isn't used func (cl *cell) clearcache() { str := cl.qmlimg.String("source") - //fmt.Println("source (click): ", str) i := strings.Index(str, `;`) str1 := str[:i] - //fmt.Println("ext (click): ", str1) i1, _ := strconv.Atoi(str[i+1:]) str = str1 + `;` + strconv.Itoa(i1+1) //fmt.Println("new source (click): ", str) diff --git a/qml/main.qml b/qml/main.qml new file mode 100644 index 0000000..31fe814 --- /dev/null +++ b/qml/main.qml @@ -0,0 +1,601 @@ +import QtQuick 2.4 +import QtQuick.Dialogs 1.2 +import QtQuick.Controls 1.3 +import QtQuick.Window 2.0 +import "qml" +import QtQuick.Layouts 1.0 + +ApplicationWindow { + id: applicationWindow1 + title: "Presentation App" + visible: true + objectName: "applicationWindow1" + minimumWidth: 500 + minimumHeight: 500 + width: 1000 + height: 600 + property bool cls: false + + + /*function getFileDialogUrl() { + return + }*/ + /*onClosing: if (!cls) { + close.accepted = false + }*/ + + FileDialog { + id: imgpicker + // @disable-check M16 + title: "Choose an image for this slide" + // @disable-check M16 + objectName: "imgpicker" + } + + AboutDialog { + id: aboutDialog + } + + Action { + id: aboutAction + text: "About" + onTriggered: aboutDialog.open() + } + + menuBar: MenuBar { + Menu { + title: "&File" + MenuItem { + text: "Close" + shortcut: StandardKey.Quit + } + } + Menu { + title: "&Edit" + MenuItem { + text: "quick edit" + objectName: "mnuEdit" + } + } + + Menu { + title: "Window" + + MenuItem { + text: "Display" + objectName: "mnuDisplay" + } + } + + Menu { + title: "&Help" + MenuItem { + action: aboutAction + } + } + } + + Menu { + objectName: "mnuCtx" + title: "new image..." + MenuItem { + objectName: "mnuImgPick" + text: "new Image..." + onTriggered: imgpicker.open() + } + } + + SplitView { + id: mainSlider + objectName: "mainSlider" + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.top: parent.top + anchors.left: parent.left + anchors.rightMargin: 0 + anchors.bottomMargin: 0 + anchors.leftMargin: 0 + anchors.topMargin: 0 + orientation: Qt.Horizontal + onResizingChanged: col1.width = gridData.width / 2 + + Rectangle { + id: gridRect + objectName: "gridRect" + width: 300 + color: "#00000000" + border.width: 4 + anchors.left: parent.left + anchors.leftMargin: 0 + anchors.bottom: parent.bottom + anchors.bottomMargin: 0 + anchors.top: parent.top + anchors.topMargin: 0 + property int count: 1 + property int expcount: 1 + + ScrollView { + id: scview + anchors.fill: parent + anchors.margins: 4 + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn + + SplitView { + id: gridData + objectName: "gridData" + width: scview.width - 1 + height: data1.childrenRect.height//gridRect.count * 101 + + Rectangle { + id: col1 + objectName: "col1" + width: gridData.width / 2 + color: "#00000000" + transformOrigin: Item.TopLeft + border.width: 0 + height: data1.childrenRect.height + Rectangle { + id: textEdit + property int cell + x: 232 + y: 622 + objectName: "textEdit" + width: 200 + height: 200 + color: "#ffffff" + visible: false + property bool txt: true + Keys.onPressed: { + if ((event.key == Qt.Key_Return) && (event.modifiers & Qt.ControlModifier)) { + txt = true + + x = -100 + y = -100 + visible = false + focus = true + enabled = false + opacity = 0 + textEdit1.focus = false + + event.accepted = true + } + + if (event.key == Qt.Key_Escape) { + txt = false + x = -100 + y = -100 + visible = false + focus = true + enabled = false + opacity = 0 + textEdit1.focus = false + + event.accepted = true + } + } + + TextArea { + id: textEdit1 + objectName: "textEdit1" + anchors.fill: parent + clip: true + textFormat: Text.AutoText + visible: true + font.pixelSize: 12 + z: 99 + } + } + + Column { + id: data1 + objectName: "data1" + spacing: 1 + anchors.fill: parent + clip: true + height: data1.childrenRect.height + + Item { + id:tst6 + height: 50+(tst5.subCount*40) + anchors.right: parent.right + anchors.left: parent.left + clip: true + + ListView { + id:tst5 + anchors.fill: parent + property int subCount: 0 + model: ListModel { + id: nestedModel1 + ListElement { + categoryName: "Cars" + collapsed: true + subItems: [ + ListElement { itemName: "Nissan" }, + ListElement { itemName: "Toyota" }, + ListElement { itemName: "Chevy" }, + ListElement { itemName: "Audi" } + ] + } + } + delegate: Component { + id: categoryDelegate1 + Column { + anchors.right: parent.right + anchors.left: parent.left + //width: 200 + + Rectangle { + id: categoryItem + anchors.right: parent.right + anchors.left: parent.left + border.color: "black" + border.width: 5 + color: "white" + height: 50 + //width: 200 + + Text { + anchors.verticalCenter: parent.verticalCenter + x: 15 + font.pixelSize: 24 + text: categoryName + } + + Rectangle { + color: "red" + width: 30 + height: 30 + anchors.right: parent.right + anchors.rightMargin: 15 + anchors.verticalCenter: parent.verticalCenter + + MouseArea { + anchors.fill: parent + + // Toggle the 'collapsed' property + onClicked: { + nestedModel1.setProperty(index, "collapsed", !collapsed) + if (!nestedModel1.get(index).collapsed) { + tst5.subCount = subItemLoader.subItemModel.count + } else { + tst5.subCount = 0 + } + } + } + } + } + + Loader { + id: subItemLoader + + // This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null + // the Loader element retains the same height it had when sourceComponent was set. Setting visible + // to false makes the parent Column treat it as if it's height was 0. + visible: !collapsed + property variant subItemModel: subItems + sourceComponent: collapsed ? null : subItemColumnDelegate1 + onStatusChanged: if (status == Loader.Ready) + item.model = subItemModel + } + } + } + } + + Component { + id: subItemColumnDelegate1 + Column { + property alias model: subItemRepeater.model + + width: col1.width + Repeater { + id: subItemRepeater + delegate: Rectangle { + color: "#cccccc" + height: 40 + anchors.right: parent.right + anchors.left: parent.left + //width: 200 + border.color: "black" + border.width: 2 + + Text { + anchors.verticalCenter: parent.verticalCenter + x: 30 + font.pixelSize: 18 + text: itemName + } + } + } + } + } + }Item { + id:tst4 + height: 50+(tst3.subCount*40) + anchors.right: parent.right + anchors.left: parent.left + + ListView { + id:tst3 + anchors.fill: parent + property int subCount: 0 + model: ListModel { + id: nestedModel + ListElement { + categoryName: "Cars" + collapsed: true + subItems: [ + ListElement { itemName: "Nissan" }, + ListElement { itemName: "Toyota" }, + ListElement { itemName: "Chevy" }, + ListElement { itemName: "Audi" } + ] + } + } + delegate: Component { + id: categoryDelegate + Column { + anchors.right: parent.right + anchors.left: parent.left + //width: 200 + + Rectangle { + id: categoryItem + anchors.right: parent.right + anchors.left: parent.left + border.color: "black" + border.width: 5 + color: "white" + height: 50 + //width: 200 + + Text { + anchors.verticalCenter: parent.verticalCenter + x: 15 + font.pixelSize: 24 + text: categoryName + } + + Rectangle { + color: "red" + width: 30 + height: 30 + anchors.right: parent.right + anchors.rightMargin: 15 + anchors.verticalCenter: parent.verticalCenter + + MouseArea { + anchors.fill: parent + + // Toggle the 'collapsed' property + onClicked: { + nestedModel.setProperty(index, "collapsed", !collapsed) + if (!nestedModel.get(index).collapsed) { + tst3.subCount = subItemLoader.subItemModel.count + } else { + tst3.subCount = 0 + } + } + } + } + } + + Loader { + id: subItemLoader + + // This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null + // the Loader element retains the same height it had when sourceComponent was set. Setting visible + // to false makes the parent Column treat it as if it's height was 0. + visible: !collapsed + property variant subItemModel: subItems + sourceComponent: collapsed ? null : subItemColumnDelegate + onStatusChanged: if (status == Loader.Ready) + item.model = subItemModel + } + } + } + } + + Component { + id: subItemColumnDelegate + Column { + property alias model: subItemRepeater.model + + width: col1.width + Repeater { + id: subItemRepeater + delegate: Rectangle { + color: "#cccccc" + height: 40 + anchors.right: parent.right + anchors.left: parent.left + //width: 200 + border.color: "black" + border.width: 2 + + Text { + anchors.verticalCenter: parent.verticalCenter + x: 30 + font.pixelSize: 18 + text: itemName + } + } + } + } + } + }Item { + id: tst2 + height: 50+(tst1.subCount*40) + anchors.right: parent.right + anchors.left: parent.left + + ListView { + id: tst1 + anchors.fill: parent + property int subCount: 0 + model: ListModel { + id: nestedMdel + ListElement { + categoryName: "Cars " + collapsed: true + subIte: [ + ListElement { itemName: "Nissan" }, + ListElement { itemName: "Toyota" }, + ListElement { itemName: "Chevy" }, + ListElement { itemName: "Audi" } + ] + } + } + delegate: Component { + id: categoryDlegate + Column { + anchors.right: parent.right + anchors.left: parent.left + //width: 200 + + Rectangle { + id: categoryItem + anchors.right: parent.right + anchors.left: parent.left + border.color: "black" + border.width: 5 + color: "white" + height: 50 + //width: 200 + + Text { + anchors.verticalCenter: parent.verticalCenter + x: 15 + font.pixelSize: 24 + text: categoryName + } + + Rectangle { + color: "red" + width: 30 + height: 30 + anchors.right: parent.right + anchors.rightMargin: 15 + anchors.verticalCenter: parent.verticalCenter + + MouseArea { + anchors.fill: parent + + // Toggle the 'collapsed' property + onClicked: { + nestedMdel.setProperty(index, "collapsed", !collapsed) + if (!nestedMdel.get(index).collapsed) { + tst1.subCount = subItemLoader.subItemModel.count + } else { + tst1.subCount = 0 + } + } + } + } + } + + Loader { + id: subItemLoader + + // This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null + // the Loader element retains the same height it had when sourceComponent was set. Setting visible + // to false makes the parent Column treat it as if it's height was 0. + visible: !collapsed + property variant subItemModel: subIte + sourceComponent: collapsed ? null : subItemColumnDlegate + onStatusChanged: if (status == Loader.Ready) + item.model = subItemModel + } + } + } + } + + Component { + id: subItemColumnDlegate + Column { + property alias model: subItemRepeater.model + + width: col1.width + Repeater { + id: subItemRepeater + delegate: Rectangle { + color: "#cccccc" + height: 40 + anchors.right: parent.right + anchors.left: parent.left + //width: 200 + border.color: "black" + border.width: 2 + + Text { + anchors.verticalCenter: parent.verticalCenter + x: 30 + font.pixelSize: 18 + text: itemName + } + } + } + } + } + } + } + } + + Rectangle { + id: col2 + objectName: "col2" + color: "#00000000" + border.width: 0 + + Column { + id: data2 + spacing: 1 + objectName: "data2" + anchors.fill: parent + } + } + } + } + } + + Rectangle { + id: mainView + border.width: 0 + objectName: "mainView" + anchors.right: parent.right + anchors.rightMargin: 0 + anchors.leftMargin: 0 + anchors.left: gridRect.right + anchors.bottom: parent.bottom + anchors.top: parent.top + z: 1 + clip: false + visible: true + + Button { + id: button1 + objectName: "btnAdd" + x: 8 + y: 8 + text: qsTr("Button") +data1.childrenRect.height + } + + Button { + id: button2 + x: 8 + y: 39 + text: qsTr("Button ") + tst4.height + objectName: "btnRem" + } + + Button { + id: button3 + x: 8 + y: 70 + text: qsTr("Button ") + tst2.height + objectName: "btnMem" + } + } + } +} diff --git a/qml/AboutDialog.qml b/qml/qml/AboutDialog.qml similarity index 100% rename from qml/AboutDialog.qml rename to qml/qml/AboutDialog.qml diff --git a/qml/cell.qml b/qml/qml/cell.qml similarity index 100% rename from qml/cell.qml rename to qml/qml/cell.qml diff --git a/qml/fileDialogs.qml b/qml/qml/fileDialogs.qml similarity index 100% rename from qml/fileDialogs.qml rename to qml/qml/fileDialogs.qml diff --git a/qml/img.qml b/qml/qml/img.qml similarity index 100% rename from qml/img.qml rename to qml/qml/img.qml diff --git a/qml/songEdit.qml b/qml/qml/songEdit.qml similarity index 100% rename from qml/songEdit.qml rename to qml/qml/songEdit.qml diff --git a/qrc.go b/qrc.go new file mode 100644 index 0000000..8272b55 --- /dev/null +++ b/qrc.go @@ -0,0 +1,58 @@ +package main + +// This file is automatically generated by github.com/lordwelch/qml/cmd/genqrc + +import ( + "io/ioutil" + "os" + "path/filepath" + + "github.com/lordwelch/qml" +) + +func init() { + var r *qml.Resources + var err error + if true/*os.Getenv("QRC_REPACK") == "1"*/ { + err = qrcRepackResources() + if err != nil { + panic("cannot repack qrc resources: " + err.Error()) + } + r, err = qml.ParseResources(qrcResourcesRepacked) + } else { + r, err = qml.ParseResourcesString(qrcResourcesData) + } + if err != nil { + panic("cannot parse bundled resources data: " + err.Error()) + } + qml.LoadResources(r) +} + +func qrcRepackResources() error { + subdirs := []string{"qml"} + var rp qml.ResourcesPacker + for _, subdir := range subdirs { + err := filepath.Walk(subdir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + data, err := ioutil.ReadFile(path) + if err != nil { + return err + } + rp.Add(filepath.ToSlash(path), data) + return nil + }) + if err != nil { + return err + } + } + qrcResourcesRepacked = rp.Pack().Bytes() + return nil +} + +var qrcResourcesRepacked []byte +var qrcResourcesData = "qres\x00\x00\x00\x01\x00\x00F\x9d\x00\x00\x00\x14\x00\x00E\xeb\x00\x00\x1cjimport QtQuick 2.4\nimport QtQuick.Dialogs 1.2\nimport QtQuick.Controls 1.3\nimport QtQuick.Window 2.0\nimport \"qml\"\nimport QtQuick.Layouts 1.0\n\nApplicationWindow {\n id: applicationWindow1\n title: \"Presentation App\"\n visible: true\n objectName: \"applicationWindow1\"\n minimumWidth: 500\n minimumHeight: 500\n width: 1000\n height: 600\n property bool cls: false\n\n\n /*function getFileDialogUrl() {\n return\n }*/\n onClosing: if (!cls) {\n close.accepted = false\n }\n\n FileDialog {\n id: imgpicker\n // @disable-check M16\n title: \"Choose an image for this slide\"\n // @disable-check M16\n objectName: \"imgpicker\"\n }\n\n AboutDialog {\n id: aboutDialog\n }\n\n Action {\n id: aboutAction\n text: \"About\"\n onTriggered: aboutDialog.open()\n }\n\n menuBar: MenuBar {\n Menu {\n title: \"&File\"\n MenuItem {\n text: \"Close\"\n shortcut: StandardKey.Quit\n }\n }\n Menu {\n title: \"&Edit\"\n MenuItem {\n text: \"quick edit\"\n objectName: \"mnuEdit\"\n }\n }\n\n Menu {\n title: \"Window\"\n\n MenuItem {\n text: \"Display\"\n objectName: \"mnuDisplay\"\n }\n }\n\n Menu {\n title: \"&Help\"\n MenuItem {\n action: aboutAction\n }\n }\n }\n\n Menu {\n objectName: \"mnuCtx\"\n title: \"new image...\"\n MenuItem {\n objectName: \"mnuImgPick\"\n text: \"new Image...\"\n onTriggered: imgpicker.open()\n }\n }\n\n SplitView {\n id: mainSlider\n objectName: \"mainSlider\"\n anchors.right: parent.right\n anchors.bottom: parent.bottom\n anchors.top: parent.top\n anchors.left: parent.left\n anchors.rightMargin: 0\n anchors.bottomMargin: 0\n anchors.leftMargin: 0\n anchors.topMargin: 0\n orientation: Qt.Horizontal\n onResizingChanged: col1.width = gridData.width / 2\n\n Rectangle {\n id: gridRect\n objectName: \"gridRect\"\n width: 300\n color: \"#00000000\"\n border.width: 4\n anchors.left: parent.left\n anchors.leftMargin: 0\n anchors.bottom: parent.bottom\n anchors.bottomMargin: 0\n anchors.top: parent.top\n anchors.topMargin: 0\n property int count: 0\n\n ScrollView {\n id: scview\n anchors.fill: parent\n anchors.margins: 4\n horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff\n verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn\n\n SplitView {\n id: gridData\n objectName: \"gridData\"\n width: scview.width - 1\n height: gridRect.count * 101\n\n Rectangle {\n id: col1\n objectName: \"col1\"\n width: gridData.width / 2\n color: \"#00000000\"\n transformOrigin: Item.TopLeft\n border.width: 0\n Rectangle {\n id: textEdit\n property int cell\n x: 232\n y: 622\n objectName: \"textEdit\"\n width: 200\n height: 200\n color: \"#ffffff\"\n visible: false\n property bool txt: true\n Keys.onPressed: {\n if ((event.key == Qt.Key_Return)\n && (event.modifiers & Qt.ControlModifier)) {\n txt = true\n\n x = -100\n y = -100\n visible = false\n focus = true\n enabled = false\n opacity = 0\n textEdit1.focus = false\n\n event.accepted = true\n }\n\n if (event.key == Qt.Key_Escape) {\n txt = false\n x = -100\n y = -100\n visible = false\n focus = true\n enabled = false\n opacity = 0\n textEdit1.focus = false\n\n event.accepted = true\n }\n }\n\n TextArea {\n id: textEdit1\n objectName: \"textEdit1\"\n anchors.fill: parent\n clip: true\n textFormat: Text.AutoText\n visible: true\n font.pixelSize: 12\n z: 99\n }\n }\n\n Column {\n id: data1\n objectName: \"data1\"\n spacing: 1\n anchors.fill: parent\n }\n }\n\n Rectangle {\n id: col2\n objectName: \"col2\"\n color: \"#00000000\"\n border.width: 0\n\n Column {\n id: data2\n spacing: 1\n objectName: \"data2\"\n anchors.fill: parent\n }\n }\n }\n }\n }\n\n Rectangle {\n id: mainView\n border.width: 0\n objectName: \"mainView\"\n anchors.right: parent.right\n anchors.rightMargin: 0\n anchors.leftMargin: 0\n anchors.left: gridRect.right\n anchors.bottom: parent.bottom\n anchors.top: parent.top\n z: 1\n clip: false\n visible: true\n\n Button {\n id: button1\n objectName: \"btnAdd\"\n x: 8\n y: 8\n text: qsTr(\"Button\")\n }\n\n Button {\n id: button2\n x: 8\n y: 39\n text: qsTr(\"Button\")\n objectName: \"btnRem\"\n }\n\n Button {\n id: button3\n x: 8\n y: 70\n text: qsTr(\"Button\")\n objectName: \"btnMem\"\n }\n }\n }\n}\n\x00\x00\x02\x1dimport QtQuick 2.4\n\nImage {\n id: img\n antialiasing: true\n source: \"image://images/\"\n objectName: \"cellImg\"\n property int index: 0\n height: 100\n transformOrigin: Item.TopLeft\n fillMode: Image.PreserveAspectFit\n anchors.right: parent.right\n anchors.left: parent.left\n //cache: false\n MouseArea {\n id: cellMouse\n hoverEnabled: true\n enabled: true\n objectName: \"cellMouse\"\n anchors.fill: parent\n acceptedButtons: Qt.AllButtons\n }\n}\n\x00\x00\x00\xe9import QtQuick 2.2\nimport QtQuick.Dialogs 1.0\n\nFileDialog {\n id: imgDialog\n title: \"Please choose an image\"\n folder: shortcuts.home\n onAccepted: {\n }\n onRejected: {\n }\n Component.onCompleted: visible = true\n}\n\x00\x00\x1eyimport QtQuick 2.4\nimport QtQuick.Controls 1.4\nimport QtQuick.Layouts 1.1\nimport QtQuick.Dialogs 1.2\n//import Qt.labs.controls 1.0\n\nApplicationWindow {\n minimumHeight: 480\n minimumWidth: 640\n\n ColorDialog {\n id: textClrDialog\n //objectname: \"textClrDialog\"\n // @disable-check M16\n title: \"Please choose a color for the text\"\n // @disable-check M16\n showAlphaChannel: true\n }\n\n ColorDialog {\n id: outlineClrDialog\n //objectname: \"outlineClrDialog\"\n // @disable-check M16\n title: \"Please choose a color for the text\"\n // @disable-check M16\n showAlphaChannel: true\n }\n\n menuBar: MenuBar {\n Menu {\n title: \"&File\"\n MenuItem {\n text: \"Close\"\n }\n }\n Menu {\n title: \"&Edit\"\n MenuItem {\n text: \"quick edit\"\n objectName: \"mnuEdit\"\n }\n }\n\n Menu {\n title: \"Window\"\n\n MenuItem {\n text: \"Display\"\n objectName: \"mnuDisplay\"\n }\n }\n\n Menu {\n title: \"&Help\"\n MenuItem {\n //action: aboutAction\n }\n }\n }\n\n RowLayout {\n id: rowLayout1\n enabled: true\n smooth: true\n antialiasing: true\n anchors.fill: parent\n\n RowLayout {\n id: rowlayout3\n Layout.fillHeight: true\n Layout.alignment: Qt.AlignTop\n Layout.maximumWidth: 225\n\n ColumnLayout {\n id: columnlayout2\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n Layout.fillHeight: true\n\n Label {\n id: label1\n text: qsTr(\"Verses\")\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n }\n ListView {\n id: lstVerses\n\t\t objectName: \"lstVerses\"\n clip: true\n highlight: Rectangle {\n color: \"lightsteelblue\"\n radius: 5\n }\n width: 110\n Layout.fillHeight: true\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n focus: true\n keyNavigationWraps: true\n boundsBehavior: Flickable.StopAtBounds\n model: go.verseLen\n\n delegate: Item {\n x: 5\n width: 80\n height: 40\n\n Text {\n text: go.verses(index)\n anchors.verticalCenter: parent.verticalCenter\n font.bold: true\n }\n }\n }\n }\n\n ColumnLayout {\n id: columnlayout3\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n Layout.fillHeight: true\n\n Label {\n id: label2\n text: qsTr(\"Verse Order\")\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n }\n ListView {\n id: lstOrder\n\t\t objectName: \"lstOrder\"\n clip: true\n highlight: Rectangle {\n color: \"lightsteelblue\"\n radius: 5\n }\n width: 110\n Layout.fillHeight: true\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n boundsBehavior: Flickable.StopAtBounds\n model: go.orderLen\n delegate: Item {\n x: 5\n width: 80\n height: 40\n\n Text {\n text: go.verseOrder(index)\n anchors.verticalCenter: parent.verticalCenter\n font.bold: true\n }\n }\n }\n }\n }\n\n ColumnLayout {\n id: columnlayout4\n Layout.fillWidth: true\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n Layout.fillHeight: true\n\n RowLayout {\n id: rowLayout3\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n Layout.maximumHeight: 30\n Layout.minimumHeight: 30\n Layout.preferredHeight: 30\n Layout.fillWidth: true\n\n ToolButton {\n id: textColorPicker\n objectName: \"textColorPicker\"\n text: \"Text Color\"\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n tooltip: \"Pick the color of the text\"\n }\n\n ToolButton {\n id: outlineColorPicker\n objectName: \"outlineColorPicker\"\n text: \"Outline Color\"\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n tooltip: \"Pick the color of the text outline\"\n }\n\n ComboBox {\n id: fontPicker\n objectName: \"fontPicker\"\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n model: go.fontLen\n // @disable-check M16\n /*delegate:Text {\n text: go.fontList(index)\n }*/\n\n }\n\n SpinBox {\n id: fontSize\n objectName: \"fontSize\"\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n maximumValue: 1000\n value: 1\n suffix: \"Pt\"\n }\n\n SpinBox {\n id: outlineSize\n stepSize: 0.1\n decimals: 1\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n objectName: \"outlineSize\"\n maximumValue: 10\n value: 1\n }\n }\n RowLayout {\n id: rowLayout2\n Layout.preferredHeight: 30\n Layout.maximumHeight: 30\n Layout.minimumHeight: 30\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n Layout.fillHeight: true\n Layout.fillWidth: true\n\n ComboBox {\n id: versePicker\n objectName: \"versePicker\"\n model: go.verseLen\n // @disable-check M16\n /* delegate: Text {\n text: go.verses(index)\n }*/\n }\n\n ComboBox {\n id: imgPicker\n objectName: \"imgPicker\"\n model: go.imgLen\n // @disable-check M16\n /*delegate: Text {\n text: go.img(index)\n }*/\n }\n TextArea {\n id: txtVerse\n\t\t objectName: \"txtVerse\"\n width: 80\n height: 20\n text: qsTr(\"Text Edit\")\n textFormat: Text.AutoText\n Layout.fillHeight: true\n Layout.fillWidth: true\n Layout.alignment: Qt.AlignLeft | Qt.AlignTop\n font.pixelSize: 12\n selectByKeyboard: true\n selectByMouse: true\n }\n }\n }\n }\n}\n\x00\x00\x06eimport QtQuick 2.4\n\nRectangle {\n objectName: \"cellRect\"\n property int index: 0\n height: 100\n border.width: 2\n border.color: \"black\"\n anchors.right: parent.right\n anchors.left: parent.left\n\n Text {\n id: cellText\n enabled: true\n objectName: \"cellText\"\n text: \"\"\n clip: true\n wrapMode: Text.WrapAtWordBoundaryOrAnywhere\n anchors.fill: parent\n anchors.right: parent.right\n anchors.rightMargin: 0\n anchors.left: parent.left\n anchors.leftMargin: 2\n\n MouseArea {\n id: cellMouse\n hoverEnabled: true\n enabled: true\n objectName: \"cellMouse\"\n anchors.fill: parent\n acceptedButtons: Qt.AllButtons\n\n onMouseXChanged: cellHover()\n onExited: focusChanged(focus)\n\n function cellHover() {\n if (containsMouse) {\n parent.parent.border.color = \"skyblue\"\n parent.parent.color = \"darkblue\"\n parent.color = \"white\"\n } else if (focus) {\n parent.color = \"black\"\n }\n }\n\n function notSelected() {\n\n parent.parent.border.color = \"black\"\n parent.parent.color = \"white\"\n parent.color = \"black\"\n cellHover()\n }\n\n function selected() {\n parent.parent.border.color = \"blue\"\n parent.color = \"black\"\n parent.parent.color = \"gainsboro\"\n cellHover()\n }\n }\n }\n}\n\x00\x00\x01qimport QtQuick 2.4\nimport QtQuick.Dialogs 1.1\n\nMessageDialog {\n icon: StandardIcon.Information\n text: \"Presentation App \\nVersion: Alpha\"\n detailedText: \"Presentation App for use in a church service\\nMade in 2016 by Timmy Welch.\"\n title: \"About\"\n height: 100\n width: 200\n standardButtons: StandardButton.Close\n}\n\x00\x03\x00\x00x<\x00q\x00m\x00l\x00\b\b\x01Z\\\x00m\x00a\x00i\x00n\x00.\x00q\x00m\x00l\x00\a\x00:X\xdc\x00i\x00m\x00g\x00.\x00q\x00m\x00l\x00\x0f\x00\xd2\f\\\x00f\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00s\x00.\x00q\x00m\x00l\x00\f\x04K\xc3\\\x00s\x00o\x00n\x00g\x00E\x00d\x00i\x00t\x00.\x00q\x00m\x00l\x00\b\f/]\x1c\x00c\x00e\x00l\x00l\x00.\x00q\x00m\x00l\x00\x0f\x0e\xca\x18\xfc\x00A\x00b\x00o\x00u\x00t\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00q\x00m\x00l\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\f\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x00\x00\x01\x00\x00\x1cn\x00\x00\x006\x00\x00\x00\x00\x00\x01\x00\x00\x1e\x8f\x00\x00\x00Z\x00\x00\x00\x00\x00\x01\x00\x00\x1f|\x00\x00\x00x\x00\x00\x00\x00\x00\x01\x00\x00=\xf9\x00\x00\x00\x8e\x00\x00\x00\x00\x00\x01\x00\x00Db" diff --git a/tst.qml b/tst.qml new file mode 100644 index 0000000..bf6ce09 --- /dev/null +++ b/tst.qml @@ -0,0 +1,137 @@ +//https://gist.github.com/elpuri/3753756 +import QtQuick 2.4 +import QtQuick.Controls 1.3 + +ApplicationWindow { + id: app1 + minimumWidth: 200 + minimumHeight: 50 + + Item { + id: tst4 + height: 50 + (tst3.subCount * 40) + anchors.right: parent.right + anchors.rightMargin: 0 + anchors.left: parent.left + anchors.leftMargin: 0 + + + ListView { + id: tst3 + anchors.fill: parent + property int subCount: 0 + model: ListModel { + id: nestedModel + ListElement { + categoryName: "Cars" + collapsed: true + subItems: [ + ListElement { + itemName: "Nissan" + }, + ListElement { + itemName: "Toyota" + }, + ListElement { + itemName: "Chevy" + }, + ListElement { + itemName: "Audi" + } + ] + } + } + delegate: Component { + id: categoryDelegate + Column { + anchors.right: parent.right + anchors.left: parent.left + + //width: 200 + Rectangle { + id: categoryItem + anchors.right: parent.right + anchors.left: parent.left + border.color: "black" + border.width: 5 + color: "white" + height: 50 + + //width: 200 + Text { + anchors.verticalCenter: parent.verticalCenter + x: 15 + font.pixelSize: 24 + text: categoryName + } + + Rectangle { + color: "red" + width: 30 + height: 30 + anchors.right: parent.right + anchors.rightMargin: 15 + anchors.verticalCenter: parent.verticalCenter + + MouseArea { + anchors.fill: parent + + // Toggle the 'collapsed' property + onClicked: { + nestedModel.setProperty(index, "collapsed", + !collapsed) + if (!nestedModel.get(index).collapsed) { + tst3.subCount = subItemLoader.subItemModel.count + } else { + tst3.subCount = 0 + } + } + } + } + } + + Loader { + id: subItemLoader + + // This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null + // the Loader element retains the same height it had when sourceComponent was set. Setting visible + // to false makes the parent Column treat it as if it's height was 0. + visible: !collapsed + property variant subItemModel: subItems + sourceComponent: collapsed ? null : subItemColumnDelegate + onStatusChanged: if (status == Loader.Ready) + item.model = subItemModel + } + } + } + } + + Component { + id: subItemColumnDelegate + Column { + property alias model: subItemRepeater.model + + width: tst4.width + Repeater { + id: subItemRepeater + delegate: Rectangle { + color: "#cccccc" + height: 40 + anchors.right: parent.right + anchors.left: parent.left + //width: 200 + border.color: "black" + border.width: 2 + + Text { + anchors.verticalCenter: parent.verticalCenter + x: 30 + font.pixelSize: 18 + text: itemName + } + } + } + } + } + } +}