Skip to content
Snippets Groups Projects
LunaIcon.qml 6.25 KiB
Newer Older
  • Learn to ignore specific revisions
  •     Copyright 2016,2017 Bill Binder <dxtwjb@gmail.com>
    
        Copyright (C) 2011, 2012, 2013 Glad Deschrijver <glad.deschrijver@gmail.com>
    
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 3 of the License, or
        (at your option) any later version.
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
    
        You should have received a copy of the GNU General Public License
        along with this program; if not, see <http://www.gnu.org/licenses/>.
    
    */
    
    
    wwjjbb's avatar
    wwjjbb committed
    import QtQuick 2.1
    
    import QtGraphicalEffects 1.12
    
    wwjjbb's avatar
    wwjjbb committed
    import org.kde.plasma.core 2.0 as PlasmaCore
    import org.kde.plasma.plasmoid 2.0
    
    import "../code/shadowcalcs.js" as ShadowCalcs
    
    
    wwjjbb's avatar
    wwjjbb committed
        id: lunaIcon
    
        property int phaseNumber: 0
        property int hemisphere: 0
    
        property bool showShadow: true
    
        property bool transparentShadow: true
    
    
        property string lunarImage: ''
    
    dxtwjb's avatar
    dxtwjb committed
        property color diskColour: '#ffffff'
    
        property int lunarImageTweak: 0
    
    wwjjbb's avatar
    wwjjbb committed
    
    
    dxtwjb's avatar
    dxtwjb committed
        property bool showGrid: false
        property bool showTycho: false
        property bool showCopernicus: false
    
    
        // Degrees. 0= new moon, 90= first quarter, 180= full moon, 270= third quarter
        property int theta: 45
    
    
    wwjjbb's avatar
    wwjjbb committed
        PlasmaCore.Svg {
            id: lunaSvg
    
    dxtwjb's avatar
    dxtwjb committed
            imagePath: lunarImage === '' ? '' : plasmoid.file("data", lunarImage)
    
    wwjjbb's avatar
    wwjjbb committed
        }
    
        PlasmaCore.SvgItem {
            id: lunaSvgItem
    
    
            anchors.centerIn: parent
            width: Math.min(parent.width,parent.height)
            height: Math.min(parent.width,parent.height)
    
    
    wwjjbb's avatar
    wwjjbb committed
            svg: lunaSvg
    
            // deal with northern <-> southern hemisphere
            transformOrigin: Item.Center
    
            rotation: (hemisphere == 0 ? 0 : 180) - lunarImageTweak
    
            visible: !transparentShadow
    
    wwjjbb's avatar
    wwjjbb committed
        }
    
    
        Canvas {
            id: shadow
            width: lunaSvgItem.width
            height: lunaSvgItem.height
    
            visible: !transparentShadow
    
    
            property int hemisphere: lunaIcon.hemisphere
            property int theta: lunaIcon.theta
    
            property bool showShadow: lunaIcon.showShadow
    
    dxtwjb's avatar
    dxtwjb committed
            property string lunarImage: lunaIcon.lunarImage
            property string diskColour: lunaIcon.diskColour
            property bool showGrid: lunaIcon.showGrid
            property bool showTycho: lunaIcon.showTycho
            property bool showCopernicus: lunaIcon.showCopernicus
    
            anchors.centerIn: parent
            contextType: "2d"
    
    
            onHemisphereChanged: requestPaint()
    
            onThetaChanged: requestPaint()
    
    
    dxtwjb's avatar
    dxtwjb committed
            onLunarImageChanged: requestPaint()
    
            onDiskColourChanged: requestPaint()
    
            onShowGridChanged: requestPaint()
            onShowTychoChanged: requestPaint()
            onShowCopernicusChanged: requestPaint()
    
    
            onPaint:
            {
                context.reset()
                context.globalAlpha = 0.9
                context.fillStyle = '#000000'
    
    
                function radians(deg) {
                    return deg / 180.0 * Math.PI;
                }
    
                function marker(latitude,longitude) {
                  var dy = radius * Math.sin(radians(latitude))
                  var dx = radius * Math.cos(radians(latitude)) * Math.sin(radians(longitude))
                  //console.log("dx: " + dx.toString())
                  //console.log("dy: " + dy.toString())
                  context.beginPath()
                  context.strokeStyle = "#FF0000"
                  context.arc(dx,-dy,5,0,2*Math.PI)
                  context.moveTo(dx-5, -dy-5)
                  context.lineTo(dx+5, -dy+5)
                  context.moveTo(dx-5, -dy+5)
                  context.lineTo(dx+5, -dy-5)
                  context.stroke()
                }
    
                function grid() {
    
                  context.beginPath()
                  context.strokeStyle = "#FF4040"
                  context.moveTo(0,-radius)
                  context.lineTo(0,radius)
                  context.moveTo(-radius,0)
                  context.lineTo(radius,0)
                  context.stroke()
    
                  context.beginPath()
                  context.strokeStyle = "#40FF40"
                  for (var ll=10;ll<65;ll+=10) {
                    var dy = radius * Math.sin(radians(ll))
                    context.moveTo(-radius,dy)
                    context.lineTo(radius,dy)
                    context.moveTo(-radius,-dy)
                    context.lineTo(radius,-dy)
                  }
                  context.stroke()
                }
    
    dxtwjb's avatar
    dxtwjb committed
                //console.log("Angle: " + theta.toString())
    
    
                var ct = Math.cos(theta/180*Math.PI)
    
                var radius = ShadowCalcs.setup(Math.floor(shadow.height/2))
    
    
                //console.log("radius: " + radius.toString())
    
                context.translate(radius,radius)
                if (hemisphere>0)
                  context.rotate(Math.PI)
    
    
                // These two determine which side of the centre meridan to draw
                // the two arcs enclosing the shadow area.
    
                var terminator = (theta <= 180) ? 1 : -1
                var edge = (theta <= 180) ? -1 : 1
    
    
    dxtwjb's avatar
    dxtwjb committed
                var z
    
                if (lunarImage === '') {
                    context.beginPath()
                    context.fillStyle = diskColour
                    context.arc(0,0,radius,0,2*Math.PI)
                    context.closePath()
                    context.fill()
                }
    
    
                if (showShadow) {
                  context.beginPath()
    
    dxtwjb's avatar
    dxtwjb committed
                  context.fillStyle = '#000000'
    
                  context.moveTo(ShadowCalcs.get(-radius), -radius)
    
    dxtwjb's avatar
    dxtwjb committed
                  for (z = -radius+1; z <= radius; z++ ) {
    
                      context.lineTo(terminator*ShadowCalcs.get(z)*ct, z)
                  }
    
                  for (z = radius-1; z >= -radius+1; --z) {
                    context.lineTo(edge*ShadowCalcs.get(z), z)
                  }
    
                  context.closePath()
                  context.fill()
    
                else {
                  // Callibration markers
    
    dxtwjb's avatar
    dxtwjb committed
                  if (showGrid)
                      grid()
    
                  if (showTycho)
                      marker(-43,-11.5)  // Tycho
    
                  if (showCopernicus)
                      marker(9.6,-20)    // Copernicus
    
    
        OpacityMask {
            anchors.fill: lunaSvgItem
            source: lunaSvgItem
            maskSource: shadow
            invert: true
            visible: transparentShadow
        }