diff --git a/.gitignore b/.gitignore index daf913b..bf2bb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ _testmain.go *.exe *.test *.prof + +.DS_Store diff --git a/glfw.go b/glfw.go index 72a9170..65d02a5 100644 --- a/glfw.go +++ b/glfw.go @@ -5,12 +5,10 @@ import ( "fmt" "image" "log" - "os" "github.com/go-gl/gl/v2.1/gl" "github.com/go-gl/glfw/v3.1/glfw" "github.com/lordwelch/qml" - "github.com/go-gl/gltext" ) var ( @@ -21,18 +19,8 @@ var ( projMonitor *glfw.Monitor tex1 *uint32 //identifier for opengl texture texDel Bool //if texture should be deleted - flt *os.File - f *gltext.Font ) -func loadfont(){ - - flt,err = os.Open("Comfortaa-Regular.ttf") - if err != nil { - f, err = gltext.LoadTruetype(flt, 30, 32, 255, gltext.LeftToRight) - } -} - func setupScene() { gl.ClearColor(0, 0, 0, 0) @@ -75,7 +63,6 @@ func drawSlide() { gl.Vertex3f(-1, -1, 0) gl.End() - f.Printf(5,10,"test") } @@ -155,7 +142,6 @@ func glInit() { if err := gl.Init(); err != nil { panic(err) } - loadfont() win.SetPos(projMonitor.GetPos()) setupScene() diff --git a/imagick.go b/imagick.go index 2bce974..e0d18d0 100644 --- a/imagick.go +++ b/imagick.go @@ -2,12 +2,19 @@ package main import ( + "bytes" "image" - . "math" + "log" + "math" + "os/exec" "gopkg.in/gographics/imagick.v2/imagick" ) +var ( + fontlst []string +) + /*resizeImage() mw fullsize image newwidth, newheight = size to be resized to keepSpecSize = return image with exactly the size specified or just the size of the resized image @@ -81,9 +88,79 @@ func (cl cell) getImage(width, height int) (img *image.RGBA) { return } +// Text effect 1 - shadow effect using MagickShadowImage +func textEffect1() { + imagick.Initialize() + defer imagick.Terminate() + mw := imagick.NewMagickWand() + defer mw.Destroy() + dw := imagick.NewDrawingWand() + defer dw.Destroy() + pw := imagick.NewPixelWand() + defer pw.Destroy() + pw.SetColor("none") + + // Create a new transparent image + mw.NewImage(0, 0, pw) + + // Set up a 72 point white font + pw.SetColor("white") + dw.SetFillColor(pw) + dw.SetFont("Verdana-Bold-Italic") + dw.SetFontSize(72) + + // Add a black outline to the text + pw.SetColor("black") + dw.SetStrokeColor(pw) + + // Turn antialias on - not sure this makes a difference + dw.SetTextAntialias(true) + + // Now draw the text + dw.Annotation(25, 65, "Magick") + + // Draw the image on to the mw + mw.DrawImage(dw) + + // Trim the image down to include only the text + mw.TrimImage(0) + + // equivalent to the command line +repage + mw.ResetImagePage("") + + // Make a copy of the text image + cw := mw.Clone() + + // Set the background colour to blue for the shadow + pw.SetColor("blue") + mw.SetImageBackgroundColor(pw) + + // Opacity is a real number indicating (apparently) percentage + mw.ShadowImage(70, 4, 5, 5) + + // Composite the text on top of the shadow + mw.CompositeImage(cw, imagick.COMPOSITE_OP_OVER, 5, 5) + cw.Destroy() + + // and write the result + mw.WriteImage("text_shadow.png") +} + +func findfonts() { + cmd := exec.Command("grep", "-ivE", `\-Oblique$|-Bold$|-Italic$|-Light$`) + cmd.Stdin = strings.NewReader(strings.Join(imagick.QueryFonts("*"), "\n")) + var out bytes.Buffer + cmd.Stdout = &out + err := cmd.Run() + if err != nil { + log.Print(err) + } + fontlst = strings.Seperate(out.String(), "\n") +} + func round(a float64) int { if a < 0 { - return int(Ceil(a - 0.5)) + return int(math.Ceil(a - 0.5)) } - return int(Floor(a + 0.5)) + return int(math.Floor(a + 0.5)) } diff --git a/main.go b/main.go index 906e16b..ad82e63 100644 --- a/main.go +++ b/main.go @@ -45,7 +45,7 @@ func main() { func run() error { imagick.Initialize() - engine := qml.NewEngine() + engine = qml.NewEngine() engine.AddImageProvider("images", imgProvider) //path for qml files TODO: change to somewhere else path, err = osext.ExecutableFolder() @@ -56,6 +56,11 @@ func run() error { return err } + edtQml, err = engine.LoadFile(path + "/qml/tst.qml") + if err != nil { + return err + } + cellQml, err = engine.LoadFile(path + "/qml/cell.qml") if err != nil { return err @@ -66,7 +71,8 @@ func run() error { return err } - window = mainQml.CreateWindow(nil) + window = mainQml.CreateWindow(engine.Context()) + window2 := edtQml.CreateWindow(engine.Context()) textEdit = window.ObjectByName("textEdit") //signals for whole qml @@ -77,6 +83,7 @@ func run() error { imgready = true window.Show() + window2.Show() slides[0].clearcache() qml.RunMain(glInit) @@ -94,7 +101,7 @@ func (sl *slide) add( /*cl *cell*/ ) { //increase count on parent QML element window.ObjectByName("gridRect").Set("count", window.ObjectByName("gridRect").Int("count")+1) - cl.qmlcell = cellQml.Create(nil) + cl.qmlcell = cellQml.Create(engine.Context()) cl.qmlcell.Set("objectName", fmt.Sprintf("cellRect%d", len(*sl))) cl.qmlcell.Set("parent", window.ObjectByName("data1")) cl.qmlcell.Set("index", cl.index) @@ -111,7 +118,7 @@ func (sl *slide) add( /*cl *cell*/ ) { *sl = append(*sl, &cl) //seperate image object in QML - cl.qmlimg = qimg.Create(nil) + cl.qmlimg = qimg.Create(engine.Context()) cl.qmlimg.Set("objectName", fmt.Sprintf("cellImg%d", cl.index)) cl.qmlimg.Set("source", fmt.Sprintf("image://images/%d"+`;`+"0", cl.index)) cl.qmlimg.Set("parent", window.ObjectByName("data2")) diff --git a/main.qml b/main.qml index e6b5076..ee01522 100644 --- a/main.qml +++ b/main.qml @@ -26,7 +26,9 @@ ApplicationWindow { FileDialog { id: imgpicker + // @disable-check M16 title: "Choose an image for this slide" + // @disable-check M16 objectName: "imgpicker" } diff --git a/qml.go b/qml.go index aa0982d..a87e9e1 100644 --- a/qml.go +++ b/qml.go @@ -17,8 +17,10 @@ var ( qimg qml.Object //file for the image object cellQml qml.Object //file for the cell object mainQml qml.Object //main QML file + edtQml qml.Object textEdit qml.Object window *qml.Window + engine *qml.Engine quickEdit Bool = false imgready Bool = false ) diff --git a/qml/songEdit.qml b/qml/songEdit.qml index 3bc8d6f..02f8a9d 100755 --- a/qml/songEdit.qml +++ b/qml/songEdit.qml @@ -1,12 +1,11 @@ import QtQuick 2.4 import QtQuick.Controls 1.3 -import QtQuick.Window 2.0 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.2 ApplicationWindow { - id: songEdit - title: "Song Editor" - visible: true - objectName: "SongEdit" + minimumHeight: 480 + minimumWidth: 640 menuBar: MenuBar { Menu { @@ -39,91 +38,213 @@ ApplicationWindow { } } } - GroupBox { - anchors.top: parent - anchors.bottom: textArea - ComboBox { - id: verseSelector - model: ["V1", "V2"] - anchors.left: parent - anchors.right: imageSelector - anchors.top: parent - anchors.bottom: parent + + RowLayout { + id: rowLayout1 + enabled: true + smooth: true + antialiasing: true + anchors.fill: parent + + RowLayout { + id: rowlayout3 + Layout.fillHeight: true + Layout.alignment: Qt.AlignTop + Layout.maximumWidth: 225 + + ColumnLayout { + id: columnlayout2 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillHeight: true + + Label { + id: label1 + text: qsTr("Label") + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + } + ListView { + id: listView1 + clip: true + highlight: Rectangle { + color: "lightsteelblue" + radius: 5 + } + width: 110 + Layout.fillHeight: true + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + focus: true + keyNavigationWraps: true + boundsBehavior: Flickable.StopAtBounds + model: ListModel { + ListElement { + name: "v1" + } + ListElement { + name: "v2" + } + ListElement { + name: "v3" + } + ListElement { + name: "v4" + } + ListElement { + name: "v5" + } + } + delegate: Item { + x: 5 + width: 80 + height: 40 + + Text { + text: name + anchors.verticalCenter: parent.verticalCenter + font.bold: true + } + } + } + } + + ColumnLayout { + id: columnlayout3 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillHeight: true + + Label { + id: label2 + text: qsTr("Label") + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + } + ListView { + id: listView2 + clip: true + highlight: Rectangle { + color: "lightsteelblue" + radius: 5 + } + width: 110 + Layout.fillHeight: true + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + boundsBehavior: Flickable.StopAtBounds + model: ListModel { + ListElement { + name: "v1" + } + ListElement { + name: "v2" + } + ListElement { + name: "v3" + } + ListElement { + name: "v4" + } + ListElement { + name: "v5" + } + } + delegate: Item { + x: 5 + width: 80 + height: 40 + + Text { + text: name + anchors.verticalCenter: parent.verticalCenter + font.bold: true + } + } + } + } } - ComboBox { - id: imageSelector - anchors.left: verseSelector - anchors.right: parent - anchors.top: parent - anchors.bottom: parent + + ColumnLayout { + id: columnlayout4 + Layout.fillWidth: true + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillHeight: true + + RowLayout { + id: rowLayout3 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.maximumHeight: 30 + Layout.minimumHeight: 30 + Layout.preferredHeight: 30 + Layout.fillWidth: true + + ToolButton { + id: textColorPicker + objectName: "textColorPicker" + text: "Text Color" + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + tooltip: "Pick the color of the text" + } + + ToolButton { + id: outlineColorPicker + objectName: "outlineColorPicker" + text: "Outline Color" + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + tooltip: "Pick the color of the text outline" + } + + ComboBox { + id: fontPicker + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + objectName: "fontPicker" + } + + SpinBox { + id: fontSize + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + objectName: "fontSize" + maximumValue: 1000 + value: 1 + suffix: "Pt" + } + + SpinBox { + id: outlineSize + stepSize: 0.1 + decimals: 1 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + objectName: "outlineSize" + maximumValue: 10 + value: 1 + } + } + RowLayout { + id: rowLayout2 + Layout.preferredHeight: 30 + Layout.maximumHeight: 30 + Layout.minimumHeight: 30 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillHeight: true + Layout.fillWidth: true + + ComboBox { + id: versePicker + objectName: "versePicker" + } + + ComboBox { + id: imgPicker + objectName: "imgPicker" + } + } + TextEdit { + id: textEdit1 + width: 80 + height: 20 + text: qsTr("Text Edit") + textFormat: Text.AutoText + cursorVisible: true + Layout.fillHeight: true + Layout.fillWidth: true + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + font.pixelSize: 12 + } } } - SplitView { - - ListView { - width: 180 - height: 200 - boundsBehavior: Flickable.StopAtBounds - - model: ListModel { - ListElement { - name: "v1" - } - ListElement { - name: "v2" - } - ListElement { - name: "v3" - } - ListElement { - name: "v4" - } - ListElement { - name: "v5" - } - } - delegate: Component { - id: contactsDelegate - Text { - id: contactInfo - text: name - } - } - focus: true - } - ListView { - width: 180 - height: 200 - boundsBehavior: Flickable.StopAtBounds - - model: ListModel { - ListElement { - name: "v1" - } - ListElement { - name: "v2" - } - ListElement { - name: "v3" - } - ListElement { - name: "v4" - } - ListElement { - name: "v5" - } - } - delegate: Component { - id: contactsDelegate1 - Text { - id: contactInfo - text: name - } - } - focus: true - } - } - TextArea { - id: textArea - } }