//Hi there ! // This is the documentation for Nightly Clock Sailfish custom clock faces // Clock faces are subject to a validation check inside the app, this is to protect users in case anyone decides to be horrible and distribute malicious code to users // It's nothing strict, just a few forbidden imports & function calls (at the moment), if you have any problems or would like information on API's Nightly Clock uses please email me contact@allstarsoftware.co.uk // If you do fail validation the App will tell you exactly what caused the fail // You can find the validation document here: https://allstarsoftware.co.uk/NightlyClockSailfish/Docs/Validation.pdf // Your Clockface needs to be in its own folder, and the file which will be loaded by NightlyClock // needs to be called 'face.qml' (all lowercase) otherwise the App will not load the clock face // Place all additional files in the same directory (no subdirectories please) // Here are some global properties you can use if you wish: // Updated for v1.11(20) /* alarmEnabled : Simple enough, returns if the Alarm is currently enabled, please don't set this property just return alarmTime : Returns the full formatted alarm time, formatted to the users choice from settings timeFormat : Returns the formatted time set by the user dateFormat : Returns the formatted date set by the user networkOnline : Returns true if device has internet connectivity mceBatteryLevel.text : Returns current battery % mceChargerState.charging : Returns true if battery is currently charging standbyMode : Returns true if app is in standy mode, this is turned on after 5 mins of inactivity on the main screen compactMode : Returns true if device is in the portrait orientation lightTheme : Returns true if App is in Bright Theme mode largeScreen : Returns true if Screen.sizeCategory = Screen.Large, more for convenience appsettings.getSystemSetting("settingName", "keepmeblank"); */ //If you would like to show the weather on your clock face you can by using the inbuilt WeatherAPI and calling customClockFaceWantsWeather=false from component creation /* ** Properties: weatherAPI.weatherIconId weatherAPI.weatherTemp // This is automatically formatted to the user selected unit weatherAPI.weatherDescription weatherAPI.weatherCityName weatherAPI.weatherHumidity ** To update the weather call the following, we recommend a small delay after Component created: weatherAPI.requestWeather(appsettings.getSystemSetting("weatherlocation", ""));} ** Listen for the update signal from a Connections: Connections{target: weatherAPI; onUpdateWeather:{yourUpdateFunctionHere();}} ** If you want to show a weather icon, we do it like this: img.decideSource(weatherAPI.weatherIconId); ** Documentation for iconIDs: https://openweathermap.org/weather-conditions ** Choose image from iconID like this: function decideSource(type){ console.log(type) switch (type) { case "01d": { return "images/weather/sunny.svg" ; break; } case "01n": { return "images/weather/moon.svg"; break; } case "02d": { return "images/weather/cloud.svg"; break; } case "02n": { return "images/weather/cloud1.svg"; break; } case "03d": { return "images/weather/cloudy.svg"; break; } case "03n": { return "images/weather/cloudy.svg"; break; } case "04d": { return "images/weather/cloudy.svg"; break; } case "04n": { return "images/weather/cloudy.svg"; break; } case "09d": { return "images/weather/rainlight.svg"; break; } case "09n": { return "images/weather/rainlight.svg"; break; } case "10d": { return "images/weather/rain.svg"; break; } case "10n": { return "images/weather/rain.svg"; break; } case "11d": { return "images/weather/storm.svg"; break; } case "11n": { return "images/weather/storm.svg"; break; } case "13d": { return "images/weather/snow.svg"; break; } case "13n": { return "images/weather/snow.svg"; break; } case "50d": { return "images/weather/mist.svg"; break; } case "50n": { return "images/weather/mist.svg"; break; } default: { break; } } } */ // Below is an example of Analog Basic face: import QtQuick 2.6 import QtGraphicalEffects 1.0 import Sailfish.Silica 1.0 import "../" Item { id: analogclock // Here you can choose to hide and date/weather on the main screen, NOTE: This will respect the Show Weather setting set by the user, if Show Weather is set to false weather will not show on your clockface. property bool showDateOnMain:true property bool showWeatherOnMain:true Component.onCompleted: {customClockFaceWantsDate=showDateOnMain;customClockFaceWantsWeather=showWeatherOnMain;} // Please use this value, this dims the component for the Apps inbuilt power saving mode opacity:powerSaving?0.6:1.0 // This is the code for the anti burn in protection, please leave interval set to globalScreenSaverInterval // as the app changes this on the fly in certain conditions Timer{running:true;repeat: true; id: upMovement; interval: globalScreenSaverInterval onTriggered: {if(analogclock.anchors.horizontalCenterOffset>=0) {analogclock.anchors.horizontalCenterOffset+=1;} if(analogclock.anchors.horizontalCenterOffset>20){downMovement.start(); upMovement.stop(); } } } Timer{id: downMovement; repeat: true;interval: globalScreenSaverInterval; onTriggered: {if(analogclock.anchors.horizontalCenterOffset===0){downMovement.stop(); upMovement.start();} else{analogclock.anchors.horizontalCenterOffset-=1;} } } //Sizing code, Screen.Large is used by Tablet size devices width: Screen.sizeCategory== Screen.Large? Screen.width/1.3:Screen.width/1.2 height: width anchors{top:parent.top; topMargin: Theme.paddingLarge horizontalCenter: parent.horizontalCenter} // Timing Code, this is synced with the Apps main timer via Connections and be toggled with the bool 'running' below function getHours() { var date = new Date return date.getHours() } function getMinutes(){ var date = new Date return date.getMinutes() } function getSeconds(){ var date = new Date return date.getSeconds() } property int hours: getHours() property int minutes: getMinutes() property int seconds: getSeconds() property int milliseconds function timeChanged() { var date = new Date; hours = getHours(); minutes = getMinutes(); seconds = getSeconds(); } property bool running: true Connections{target:running? main:null; onTimeUpdated:{analogclock.timeChanged();} } // Clock Face, you can create whatever style you would like here, some clockfaces use Canvas for some neat effects Image { id: face source: "../images/analog_basic.svg" sourceSize.height:sourceSize.width width: sourceSize.width height: sourceSize.height sourceSize.width: analogclock.width anchors.centerIn: parent } // Simple colour overlay if you want your face to match the user UI colour ColorOverlay { anchors.fill:face source: face color:colour } // This is the little center circle which covers the tips of the handles Rectangle{ height:Theme.itemSizeExtraSmall/2.3 width:height; radius: 30; anchors.centerIn: parent; color:colour } // Handles, see bottom for the code for these HourHand{ parent: face id: hourHand anchors.centerIn: parent transform: Rotation { id: hourRotation origin.x: hourHand.width/2; origin.y: hourHand.height/2; angle: (analogclock.hours * 30) + (analogclock.minutes * 0.5) Behavior on angle { SpringAnimation { spring: powerSaving?1:2; damping: 0.2; modulus: 360 } //RotationAnimation{ direction: RotationAnimation.Clockwise } } } } MinuteHand{ id: minuteHand anchors.centerIn: parent parent: face smooth: true transform: Rotation { id: minuteRotation origin.x: minuteHand.width/2; origin.y: minuteHand.height/2; angle: analogclock.minutes * 6 Behavior on angle { SpringAnimation { spring: powerSaving?1:2; damping: 0.2; modulus: 360 } } } } SecondHand{ id: secondHand anchors.centerIn: parent parent: face smooth: true transform: Rotation { id: secondRotation origin.x: secondHand.width/2; origin.y: secondHand.height/2; angle: analogclock.seconds * 6 Behavior on angle { SpringAnimation { spring: powerSaving?1:2; damping: 0.2; modulus: 360 } } } } } // HourHand.qml /* import QtQuick 2.0 import Sailfish.Silica 1.0 Item { width: 11; height: face.height/2.4 Rectangle{ radius: 45 height: parent.height/2 width: parent.width id: vsible color:colour anchors{top:parent.top} } Rectangle{ height: parent.height/2 width: parent.width id: hidden color:"Transparent" anchors{top:vsible.bottom} } } */ //MinuteHand.qml /* import QtQuick 2.0 import Sailfish.Silica 1.0 Item { width: 10; height: face.height/1.5 Rectangle{ radius: 40 height: parent.height/2 width: parent.width id: vsible color:colour anchors{top:parent.top} } Rectangle{ height: parent.height/2 width: parent.width id: hidden color:"Transparent" anchors{top:vsible.bottom} } } */ //secondHand.qml /* import QtQuick 2.0 import Sailfish.Silica 1.0 Item { width: 8; height: face.height/1.5 Rectangle{ radius: 40 height: parent.height/2 width: parent.width id: vsible smooth: true color:Qt.lighter(colour) anchors{top:parent.top} } Rectangle{ height: parent.height/2 width: parent.width id: hidden color:"Transparent" anchors{top:vsible.bottom} } } */