diff --git a/harbour-batterybuddy.pro b/harbour-batterybuddy.pro index 46e5299..165f400 100644 --- a/harbour-batterybuddy.pro +++ b/harbour-batterybuddy.pro @@ -26,6 +26,7 @@ SOURCES += src/harbour-batterybuddy.cpp \ DISTFILES += qml/harbour-batterybuddy.qml \ qml/components/AboutLabel.qml \ + qml/components/MyLabel.qml \ qml/components/MySlider.qml \ qml/pages\LicensePage.qml \ qml/cover/CoverPage.qml \ diff --git a/qml/components/MyLabel.qml b/qml/components/MyLabel.qml new file mode 100644 index 0000000..3d61f89 --- /dev/null +++ b/qml/components/MyLabel.qml @@ -0,0 +1,26 @@ +/** + * Battery Buddy, a Sailfish application to prolong battery lifetime + * + * Copyright (C) 2019-2020 Matti Viljanen + * + * Battery Buddy 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. + * + * Battery Buddy 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 CarBudget. If not, see . + * + * Author: Matti Viljanen + */ +import QtQuick 2.0 +import Sailfish.Silica 1.0 + +Label { + width: parent.width + wrapMode: Text.Wrap + color: Theme.primaryColor + font.pixelSize: Theme.fontSizeSmall +} diff --git a/qml/harbour-batterybuddy.qml b/qml/harbour-batterybuddy.qml index 80c24db..559f9f3 100644 --- a/qml/harbour-batterybuddy.qml +++ b/qml/harbour-batterybuddy.qml @@ -81,5 +81,5 @@ ApplicationWindow initialPage: Component { MainPage { } } cover: Qt.resolvedUrl("cover/CoverPage.qml") - allowedOrientations: defaultAllowedOrientations + allowedOrientations: Orientation.LandscapeMask | Orientation.Portrait } diff --git a/qml/pages/InfoPage.qml b/qml/pages/InfoPage.qml index 17ab2d9..02131cb 100644 --- a/qml/pages/InfoPage.qml +++ b/qml/pages/InfoPage.qml @@ -17,15 +17,15 @@ */ import QtQuick 2.0 import Sailfish.Silica 1.0 +import "../components" Page { id: infoPage - anchors.fill: parent - + allowedOrientations: Orientation.Portrait | Orientation.Landscape | Orientation.LandscapeInverted SilicaFlickable { id: infoFlickable anchors.fill: parent - contentHeight: header.height + infoColumn.height + contentHeight: header.height + infoColumn.height + Theme.horizontalPageMargin VerticalScrollDecorator { flickable: infoFlickable @@ -35,28 +35,22 @@ Page { id: header title: qsTr("More info") } - Column { id: infoColumn anchors.top: header.bottom - width: parent.width + width: isPortrait ? (parent.width - 2*Theme.paddingLarge) : (parent.width - 4*Theme.paddingLarge) + anchors.horizontalCenter: parent.horizontalCenter spacing: Theme.paddingMedium - Label { x: Theme.paddingLarge text: qsTr("What is Battery Buddy?") color: Theme.highlightColor font.pixelSize: Theme.fontSizeMedium } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap + MyLabel { text: qsTr("Battery Buddy is a small and simple utility designed to improve the lifetime of the battery.") +" "+ qsTr("It simply monitors the battery level and if it has been charged above the limit, it plays a sound and displays a notification.") +" "+ qsTr("A different sound is played and notification send when the battery has been discharged under the limit.") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall } Label { x: Theme.paddingLarge @@ -64,15 +58,10 @@ Page { color: Theme.highlightColor font.pixelSize: Theme.fontSizeMedium } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap + MyLabel { text: qsTr("Lithium-based batteries do not last forever. Every charge and discharge wear out the battery a small amount. This is normal and currently unavoidable.") +" "+ qsTr("A full charge from 0% to 100% stresses the battery more than, say, charging from 25% to 75%.") +" "+ qsTr("Charging and discharging the battery lowers the capacity over time. Small discharge wears out the capacity slower than a deep discharge and a full recharge.") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall } Label { x: Theme.paddingLarge @@ -80,16 +69,11 @@ Page { color: Theme.highlightColor font.pixelSize: Theme.fontSizeMedium } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap + MyLabel { text: qsTr("Yes, it is. If you always let the battery drain down to 0% and then charge it to 100%, your battery may not see 500 charge cycles.") +" "+ qsTr("A full charge from 0% to 100% stresses the battery more than, say, charging from 25% to 75%.") +" "+ qsTr("If you only let the battery charge go down to 50% and then charge it to 70%, it could last several thousands of cycles!") +"\n\n"+ qsTr("Please keep in mind that the numbers are very coarse estimates. There are also other variables that affect the life cycle, such as charge current and battery temperature.") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall } Label { x: Theme.paddingLarge @@ -97,15 +81,10 @@ Page { color: Theme.highlightColor font.pixelSize: Theme.fontSizeMedium } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap + MyLabel { text: qsTr("Every battery produced uses a lot of energy and at least some non-renewable resources.") +" "+ qsTr("By taking care of your devices battery, you don't have to buy a new battery so soon.") +" "+ qsTr("Even better; in some devices the battery is very difficult to replace without braking the device, which means you don't have to pay for the service, either.") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall } Label { x: Theme.paddingLarge @@ -113,15 +92,10 @@ Page { color: Theme.highlightColor font.pixelSize: Theme.fontSizeMedium } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap + MyLabel { text: qsTr("Uninstall battery-hungry applications you don't use. Reboot your device every now and then in order to keep it running flawlessly.") +"\n\n"+ qsTr("Use flight mode overnight whenever possible in order to cut power usage down. Powering the device off and on again may use a lot more battery than you think!") +"\n\n"+ qsTr("Don't use your phone in hot or cold environments. In the winter keep the phone in your pocket near your body (but take note of the moisture) and use a handsfree device. Extreme temperatures are bad for the battery.") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall } Label { x: Theme.paddingLarge @@ -129,29 +103,14 @@ Page { color: Theme.highlightColor font.pixelSize: Theme.fontSizeMedium } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap + MyLabel { text: qsTr("Great! There are a lot of articles to read and papers to study, so click the link to begin!") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall } - Item { - width: parent.width - height: lowButton.height - anchors.left: parent.left - Button { - id: lowButton - text: "Google Search" - onClicked: Qt.openUrlExternally("https://www.google.com/search?q=How+to+prolong+lithium-based+battery+life%3F") - anchors.centerIn: parent - } - - } - Item { - width: parent.width - height: Theme.paddingMedium + Button { + id: lowButton + anchors.horizontalCenter: parent.horizontalCenter + text: "Google Search" + onClicked: Qt.openUrlExternally("https://www.google.com/search?q=How+to+prolong+lithium-based+battery+life%3F") } } } diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index 0dbf01a..5032fa7 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -21,6 +21,7 @@ import "../components" Page { id: page + allowedOrientations: Orientation.Portrait | Orientation.Landscape | Orientation.LandscapeInverted property variant statusText: { "idle": qsTr("idle", "Charger plugged in, not using nor charging battery"), "discharging": qsTr("discharging", "Charger not plugged in, battery discharging"), @@ -42,7 +43,7 @@ Page { SilicaFlickable { id: mainFlickable anchors.fill: parent - contentHeight: column.height + Theme.horizontalPageMargin + contentHeight: flow.height + Theme.horizontalPageMargin VerticalScrollDecorator { flickable: mainFlickable } @@ -55,102 +56,118 @@ Page { // Place our content in a Column. The PageHeader is always placed at the top // of the page, followed by our content. - Column { - id: column + Flow { + id: flow + anchors { + top: parent.top + left: parent.left + right: parent.right + } + height: header.height + Math.max(columnOne.heigh, columnTwo.height) - width: page.width - spacing: Theme.paddingLarge PageHeader { + id: header title: qsTr("Battery Buddy") } - Label { - x: Theme.paddingLarge - text: qsTr("Battery status") - color: Theme.highlightColor - } - Item { - width: parent.width - // Rotation: width <==> height - height: batteryGraph.width - BatteryGraph { - id: batteryGraph - transformOrigin: Item.Center - rotation: 90 - width: parent.width * 0.2 - anchors.centerIn: parent - } - } - // Detail column Column { - width: parent.width - spacing: 0 + id: columnOne + width: isPortrait ? parent.width : parent.width / 2 + spacing: Theme.paddingLarge - MyDetailItem { - label: qsTr("Charge:") - value: battery.charge + "%" + Label { + x: Theme.paddingLarge + text: qsTr("Battery status") + color: Theme.highlightColor } - MyDetailItem { - label: qsTr("Charger connected:") - value: battery.chargerConnected ? qsTr("yes") : qsTr("no") - } - MyDetailItem { - label: qsTr("State:") - value: statusText[battery.state] - } - } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap - text: qsTr("Please leave Battery Buddy running in the background for proper operation.") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall - } - Label { - x: Theme.paddingLarge - text: qsTr("Charger control") - color: Theme.highlightColor - } - Label { - x: Theme.paddingLarge*2 - width: parent.width - x*2; - wrapMode: Text.Wrap - text: qsTr("Using these controls overrides the automated settings.") - color: Theme.primaryColor - font.pixelSize: Theme.fontSizeSmall - } - Row { - anchors { - left: parent.left - right: parent.right - } - height: resumeButton.height - - Column { - width: parent.width / 2 - Button { - id: resumeButton - anchors.horizontalCenter: parent.horizontalCenter - text: qsTr("Resume") - onClicked: { - battery.chargingEnabled = true - settings.limitEnabled = false - } - enabled: !battery.chargingEnabled + Item { + width: parent.width + // Rotation: width <==> height + height: batteryGraph.width + BatteryGraph { + id: batteryGraph + transformOrigin: Item.Center + rotation: 90 + width: parent.width * 0.2 + anchors.centerIn: parent } } + // Detail column Column { - width: parent.width / 2 - Button { - id: pauseButton - anchors.horizontalCenter: parent.horizontalCenter - text: qsTr("Pause") - onClicked: { - battery.chargingEnabled = false - settings.limitEnabled = false - } - enabled: battery.chargingEnabled + width: parent.width + spacing: 0 + + MyDetailItem { + label: qsTr("Charge:") + value: battery.charge + "%" } + MyDetailItem { + label: qsTr("Charger connected:") + value: battery.chargerConnected ? qsTr("yes") : qsTr("no") + } + MyDetailItem { + label: qsTr("State:") + value: statusText[battery.state] + } + } + } + Column { + id: columnTwo + width: isPortrait ? parent.width : parent.width / 2 + spacing: Theme.paddingMedium + Label { + x: Theme.paddingLarge + text: qsTr("Charger control") + color: Theme.highlightColor + } + Label { + x: Theme.paddingLarge*2 + width: parent.width - x*2; + wrapMode: Text.Wrap + text: qsTr("Using these controls overrides the automated settings.") + color: Theme.primaryColor + font.pixelSize: Theme.fontSizeSmall + } + Row { + anchors { + left: parent.left + right: parent.right + } + height: resumeButton.height + + Column { + width: parent.width / 2 + Button { + id: resumeButton + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Resume") + onClicked: { + battery.chargingEnabled = true + settings.limitEnabled = false + } + enabled: !battery.chargingEnabled + } + } + Column { + width: parent.width / 2 + Button { + id: pauseButton + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Pause") + onClicked: { + battery.chargingEnabled = false + settings.limitEnabled = false + } + enabled: battery.chargingEnabled + } + } + } + Label { + x: Theme.paddingLarge*2 + width: parent.width - x*2; + wrapMode: Text.Wrap + text: qsTr("Please leave Battery Buddy running in the background for proper operation.") + color: Theme.primaryColor + font.pixelSize: Theme.fontSizeSmall } } } diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml index 7560374..e7e52ee 100644 --- a/qml/pages/SettingsPage.qml +++ b/qml/pages/SettingsPage.qml @@ -21,6 +21,7 @@ import "../components" Page { id: settingsPage + allowedOrientations: Orientation.Portrait | Orientation.Landscape | Orientation.LandscapeInverted onStatusChanged: { if(status === PageStatus.Activating) { @@ -52,7 +53,7 @@ Page { SilicaFlickable { anchors.fill: parent - contentHeight: header.height + settingsColumn.height + Theme.horizontalPageMargin + contentHeight: flow.height + Theme.horizontalPageMargin PullDownMenu { MenuItem { @@ -61,113 +62,123 @@ Page { } } - PageHeader { - id: header - title: qsTr("Settings") - } - - Column { - id: settingsColumn + Flow { + id: flow anchors { - top: header.bottom + top: parent.top left: parent.left right: parent.right } + height: header.height + Math.max(columnOne.heigh, columnTwo.height) - spacing: Theme.paddingMedium - - Label { - x: Theme.paddingLarge - text: qsTr("Charging settings") - color: Theme.highlightColor - } - TextSwitch { - id: autoStopCharging - text: qsTr("Automatic charging control") - description: qsTr("This option disables charging automatically when the battery has charged above the pausing percentage and enables it again when the battery has depleted below the resuming percentage.") - onCheckedChanged: settings.limitEnabled = checked + PageHeader { + id: header + title: qsTr("Settings") } - MySlider { - id: highLimitSlider - handleVisible: enabled - width: parent.width - label: qsTr("Pause charging limit") - minimumValue: 21 - maximumValue: 95 - stepSize: 1 - valueText: value + "%" - highlightDirection: Qt.RightToLeft - onValueChanged: { - settings.highLimit = value - if(lowLimitSlider.value >= value) - lowLimitSlider.value = value - 1 + Column { + id: columnOne + width: isPortrait ? parent.width : parent.width / 2 + spacing: Theme.paddingMedium + + Label { + x: Theme.paddingLarge + text: qsTr("Charging settings") + color: Theme.highlightColor + } + TextSwitch { + id: autoStopCharging + text: qsTr("Automatic charging control") + description: qsTr("This option disables charging automatically when the battery has charged above the pausing percentage and enables it again when the battery has depleted below the resuming percentage.") + onCheckedChanged: settings.limitEnabled = checked + } + + MySlider { + id: highLimitSlider + handleVisible: enabled + width: parent.width + label: qsTr("Pause charging limit") + minimumValue: 21 + maximumValue: 95 + stepSize: 1 + valueText: value + "%" + highlightDirection: Qt.RightToLeft + onValueChanged: { + settings.highLimit = value + if(lowLimitSlider.value >= value) + lowLimitSlider.value = value - 1 + } + } + MySlider { + id: lowLimitSlider + handleVisible: enabled + width: parent.width + label: qsTr("Resume charging limit") + minimumValue: 20 + maximumValue: 94 + stepSize: 1 + valueText: value + "%" + onValueChanged: { + settings.lowLimit = value + if(highLimitSlider.value <= value) + highLimitSlider.value = value + 1 + } } } - MySlider { - id: lowLimitSlider - handleVisible: enabled - width: parent.width - label: qsTr("Resume charging limit") - minimumValue: 20 - maximumValue: 94 - stepSize: 1 - valueText: value + "%" - onValueChanged: { - settings.lowLimit = value - if(highLimitSlider.value <= value) - highLimitSlider.value = value + 1 + Column { + id: columnTwo + width: isPortrait ? parent.width : parent.width / 2 + spacing: Theme.paddingMedium + Label { + x: Theme.paddingLarge + text: qsTr("Notification settings") + color: Theme.highlightColor } - } - Label { - x: Theme.paddingLarge - text: qsTr("Notification settings") - color: Theme.highlightColor - } - TextSwitch { - id: notificationsSwitch - text: qsTr("Use notifications") - description: qsTr("Display visual and audible notifications about reached battery charge levels, when the battery charge is below or above desired percentage.") - onCheckedChanged: settings.notificationsEnabled = checked - } - MySlider { - id: highAlertSlider - width: parent.width - label: qsTr("Battery full notification") - minimumValue: 11 - maximumValue: 100 - stepSize: 1 - valueText: value + "%" - highlightDirection: Qt.RightToLeft - onValueChanged: { - settings.highAlert = value - if(lowAlertSlider.value >= value) - lowAlertSlider.value = value - 1 + TextSwitch { + id: notificationsSwitch + text: qsTr("Use notifications") + description: qsTr("Display visual and audible notifications about reached battery charge levels, when the battery charge is below or above desired percentage.") + onCheckedChanged: settings.notificationsEnabled = checked } - } - MySlider { - id: lowAlertSlider - width: parent.width - label: qsTr("Battery low notification") - minimumValue: 10 - maximumValue: 99 - stepSize: 1 - valueText: value + "%" - onValueChanged: { - settings.lowAlert = value - if(highAlertSlider.value <= value) - highAlertSlider.value = value + 1 + MySlider { + id: highAlertSlider + width: parent.width + label: qsTr("Battery full notification") + minimumValue: 11 + maximumValue: 100 + stepSize: 1 + valueText: value + "%" + highlightDirection: Qt.RightToLeft + onValueChanged: { + settings.highAlert = value + if(lowAlertSlider.value >= value) + lowAlertSlider.value = value - 1 + } + } + MySlider { + id: lowAlertSlider + width: parent.width + label: qsTr("Battery low notification") + minimumValue: 10 + maximumValue: 99 + stepSize: 1 + valueText: value + "%" + onValueChanged: { + settings.lowAlert = value + if(highAlertSlider.value <= value) + highAlertSlider.value = value + 1 + } + } + MySlider { + id: intervalSlider + width: parent.width + label: qsTr("Notification interval") + minimumValue: 60 + maximumValue: 600 + stepSize: 10 + valueText: Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60) + onValueChanged: settings.interval = value } - } - MySlider { - id: intervalSlider - width: parent.width - label: qsTr("Notification interval") - minimumValue: 60 - maximumValue: 600 - stepSize: 10 - valueText: Math.floor(value / 60) + (value % 60 < 10 ? ":0" + value % 60 : ":" + value % 60) - onValueChanged: settings.interval = value } } }