|
|
|
@ -2,52 +2,26 @@ package main
@@ -2,52 +2,26 @@ package main
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"flag" |
|
|
|
|
"fmt" |
|
|
|
|
"os" |
|
|
|
|
"strconv" |
|
|
|
|
"strings" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/bogosj/tesla" |
|
|
|
|
"github.com/therecipe/qt/widgets" |
|
|
|
|
|
|
|
|
|
"git.nightmare.haus/rudi/TeslaGo/ui" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
// Info/Statuses
|
|
|
|
|
batteryLevel *widgets.QLabel |
|
|
|
|
batteryRange *widgets.QLabel |
|
|
|
|
chargingState *widgets.QLabel |
|
|
|
|
minutesToFull *widgets.QLabel |
|
|
|
|
fastChargerInd *widgets.QLabel |
|
|
|
|
batteryHeaterInd *widgets.QLabel |
|
|
|
|
chargeDoorOpenInd *widgets.QLabel |
|
|
|
|
insideTemp *widgets.QLabel |
|
|
|
|
outsideTemp *widgets.QLabel |
|
|
|
|
climateUnitLabel *widgets.QLabel |
|
|
|
|
|
|
|
|
|
// Controls
|
|
|
|
|
tempSetting *widgets.QLineEdit |
|
|
|
|
climateOn *widgets.QCheckBox |
|
|
|
|
lockedDoors *widgets.QCheckBox |
|
|
|
|
sentryMode *widgets.QCheckBox |
|
|
|
|
startStopCharge *widgets.QCheckBox |
|
|
|
|
|
|
|
|
|
honk *widgets.QPushButton |
|
|
|
|
flashLights *widgets.QPushButton |
|
|
|
|
trunk *widgets.QPushButton |
|
|
|
|
frunk *widgets.QPushButton |
|
|
|
|
|
|
|
|
|
vehicle *tesla.Vehicle |
|
|
|
|
vehicleState *tesla.VehicleState |
|
|
|
|
chargeStats *tesla.ChargeState |
|
|
|
|
climateState *tesla.ClimateState |
|
|
|
|
guiSettings *tesla.GuiSettings |
|
|
|
|
|
|
|
|
|
window *widgets.QMainWindow |
|
|
|
|
window *ui.MainWindow |
|
|
|
|
mainApp *widgets.QApplication |
|
|
|
|
vehicleSearch string |
|
|
|
|
refresh int |
|
|
|
|
popup = false |
|
|
|
|
popup bool |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
func init() { |
|
|
|
@ -55,9 +29,9 @@ func init() {
@@ -55,9 +29,9 @@ func init() {
|
|
|
|
|
flag.IntVar(&refresh, "r", -1, "Auto-refresh (every \"r\" minutes) WARNING: Vehicle can not sleep while refreshing.") |
|
|
|
|
flag.Parse() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func main() { |
|
|
|
|
mainApp = widgets.NewQApplication(len(os.Args), os.Args) |
|
|
|
|
window = widgets.NewQMainWindow(nil, 0) |
|
|
|
|
|
|
|
|
|
c := getTeslaClient() |
|
|
|
|
vehicles, err := c.Vehicles() |
|
|
|
@ -72,353 +46,31 @@ func main() {
@@ -72,353 +46,31 @@ func main() {
|
|
|
|
|
showDialogue(false, "Unable to determine vehicle.") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Setup all UI Elements
|
|
|
|
|
window.SetWindowTitle("Loading, please wait!") |
|
|
|
|
|
|
|
|
|
batteryLevel = widgets.NewQLabel(nil, 0) |
|
|
|
|
batteryRange = widgets.NewQLabel(nil, 0) |
|
|
|
|
chargingState = widgets.NewQLabel(nil, 0) |
|
|
|
|
minutesToFull = widgets.NewQLabel(nil, 0) |
|
|
|
|
fastChargerInd = widgets.NewQLabel(nil, 0) |
|
|
|
|
batteryHeaterInd = widgets.NewQLabel(nil, 0) |
|
|
|
|
chargeDoorOpenInd = widgets.NewQLabel(nil, 0) |
|
|
|
|
insideTemp = widgets.NewQLabel(nil, 0) |
|
|
|
|
outsideTemp = widgets.NewQLabel(nil, 0) |
|
|
|
|
currentChargeLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
currentRangeLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
insideTempLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
outsideTempLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
climateEnabledLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
climateSettingLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
doorLockLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
sentryModeLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
chargingStateLabel := widgets.NewQLabel(nil, 0) |
|
|
|
|
climateUnitLabel = widgets.NewQLabel(nil, 0) |
|
|
|
|
|
|
|
|
|
tempSetting = widgets.NewQLineEdit(nil) |
|
|
|
|
|
|
|
|
|
climateOn = widgets.NewQCheckBox(nil) |
|
|
|
|
lockedDoors = widgets.NewQCheckBox(nil) |
|
|
|
|
sentryMode = widgets.NewQCheckBox(nil) |
|
|
|
|
startStopCharge = widgets.NewQCheckBox(nil) |
|
|
|
|
|
|
|
|
|
honk = widgets.NewQPushButton(nil) |
|
|
|
|
flashLights = widgets.NewQPushButton(nil) |
|
|
|
|
trunk = widgets.NewQPushButton(nil) |
|
|
|
|
frunk = widgets.NewQPushButton(nil) |
|
|
|
|
|
|
|
|
|
statusLayout := widgets.NewQFormLayout(nil) |
|
|
|
|
chargeHbox := widgets.NewQHBoxLayout() |
|
|
|
|
tempHbox := widgets.NewQHBoxLayout() |
|
|
|
|
climateHbox := widgets.NewQHBoxLayout() |
|
|
|
|
securityHbox := widgets.NewQHBoxLayout() |
|
|
|
|
actionHbox := widgets.NewQHBoxLayout() |
|
|
|
|
|
|
|
|
|
centralWidget := widgets.NewQWidget(window, 0) |
|
|
|
|
|
|
|
|
|
// Set Values for everything
|
|
|
|
|
setValues() |
|
|
|
|
if refresh >= 1 { |
|
|
|
|
go func() { |
|
|
|
|
for { |
|
|
|
|
time.Sleep(time.Duration(refresh) * time.Minute) |
|
|
|
|
setValues() |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Some adjustments
|
|
|
|
|
|
|
|
|
|
lockedDoors.SetCheckable(false) |
|
|
|
|
climateOn.SetCheckable(false) |
|
|
|
|
tempSetting.SetReadOnly(true) |
|
|
|
|
|
|
|
|
|
batteryLevel.SetFixedWidth(30) |
|
|
|
|
insideTemp.SetFixedWidth(25) |
|
|
|
|
outsideTemp.SetFixedWidth(25) |
|
|
|
|
tempSetting.SetFixedWidth(25) |
|
|
|
|
|
|
|
|
|
currentChargeLabel.SetText("Current Charge:") |
|
|
|
|
currentRangeLabel.SetText("Current Range:") |
|
|
|
|
insideTempLabel.SetText("Inside Temp:") |
|
|
|
|
outsideTempLabel.SetText("Outside Temp:") |
|
|
|
|
climateEnabledLabel.SetText("Climate On:") |
|
|
|
|
climateSettingLabel.SetText("Climate Setting:") |
|
|
|
|
doorLockLabel.SetText("Lock Doors:") |
|
|
|
|
sentryModeLabel.SetText("Sentry Mode:") |
|
|
|
|
chargingStateLabel.SetText("Charging:") |
|
|
|
|
honk.SetText("Honk") |
|
|
|
|
flashLights.SetText("Flash") |
|
|
|
|
trunk.SetText("Trunk") |
|
|
|
|
frunk.SetText("Frunk") |
|
|
|
|
|
|
|
|
|
// Connect Controls
|
|
|
|
|
honk.ConnectClicked(honkHorn) |
|
|
|
|
flashLights.ConnectClicked(flash) |
|
|
|
|
trunk.ConnectClicked(openTrunk) |
|
|
|
|
frunk.ConnectClicked(openFrunk) |
|
|
|
|
lockedDoors.ConnectStateChanged(lockDoors) |
|
|
|
|
sentryMode.ConnectStateChanged(sentryModeEnable) |
|
|
|
|
startStopCharge.ConnectStateChanged(enableCharging) |
|
|
|
|
climateOn.ConnectStateChanged(enableClimate) |
|
|
|
|
|
|
|
|
|
// Setup Layout for first row, Current Charge
|
|
|
|
|
chargeHbox.AddWidget(batteryLevel, 0, 0) |
|
|
|
|
chargeHbox.AddItem(widgets.NewQSpacerItem(5, 2, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding)) |
|
|
|
|
chargeHbox.AddWidget(currentRangeLabel, 0, 0) |
|
|
|
|
chargeHbox.AddWidget(batteryRange, 0, 0) |
|
|
|
|
|
|
|
|
|
// Charging State has its own section and is handled differently based on if it is present or not
|
|
|
|
|
if chargeStats.ChargingState != "Disconnected" { |
|
|
|
|
statusLayout.AddRow3("Time to Full:", minutesToFull) |
|
|
|
|
if chargeStats.FastChargerPresent { |
|
|
|
|
statusLayout.AddRow3("Fast Charger:", fastChargerInd) |
|
|
|
|
} |
|
|
|
|
if chargeStats.BatteryHeaterOn { |
|
|
|
|
statusLayout.AddRow3("Battey Heater:", batteryHeaterInd) |
|
|
|
|
} |
|
|
|
|
statusLayout.AddRow3(" ", nil) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Temperature section (NOT CLIMATE CONTROL)
|
|
|
|
|
tempHbox.AddWidget(insideTemp, 0, 0) |
|
|
|
|
tempHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
tempHbox.AddWidget(outsideTempLabel, 0, 0) |
|
|
|
|
tempHbox.AddWidget(outsideTemp, 0, 0) |
|
|
|
|
|
|
|
|
|
// Climate Control Section
|
|
|
|
|
climateHbox.AddWidget(climateOn, 0, 0) |
|
|
|
|
climateHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
climateHbox.AddWidget(climateSettingLabel, 0, 0) |
|
|
|
|
climateHbox.AddWidget(tempSetting, 0, 0) |
|
|
|
|
climateHbox.AddWidget(climateUnitLabel, 0, 0) |
|
|
|
|
|
|
|
|
|
// Security Section (Lock/Unlock doors & start/stop charge. Also enable Sentry Mode)
|
|
|
|
|
securityHbox.AddWidget(lockedDoors, 0, 0) |
|
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
securityHbox.AddWidget(sentryModeLabel, 0, 0) |
|
|
|
|
securityHbox.AddWidget(sentryMode, 0, 0) |
|
|
|
|
if chargeStats.ChargingState != "Disconnected" { |
|
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
securityHbox.AddWidget(chargingStateLabel, 0, 0) |
|
|
|
|
securityHbox.AddWidget(startStopCharge, 0, 0) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Action Buttons
|
|
|
|
|
actionHbox.AddWidget(honk, 0, 0) |
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
actionHbox.AddWidget(flashLights, 0, 0) |
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
actionHbox.AddWidget(trunk, 0, 0) |
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
actionHbox.AddWidget(frunk, 0, 0) |
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
|
|
|
|
|
|
// Put all Sections Together, note ChargingState (top) is already handled
|
|
|
|
|
statusLayout.AddRow2(currentChargeLabel, chargeHbox) |
|
|
|
|
statusLayout.AddRow3("Charging State:", chargingState) |
|
|
|
|
statusLayout.AddRow3("Charge Port:", chargeDoorOpenInd) |
|
|
|
|
statusLayout.AddRow3(" ", nil) |
|
|
|
|
statusLayout.AddRow2(insideTempLabel, tempHbox) |
|
|
|
|
statusLayout.AddRow2(climateEnabledLabel, climateHbox) |
|
|
|
|
statusLayout.AddRow3(" ", nil) |
|
|
|
|
statusLayout.AddRow2(doorLockLabel, securityHbox) |
|
|
|
|
statusLayout.AddRow6(actionHbox) |
|
|
|
|
|
|
|
|
|
// Finish setting up the window, and let her go
|
|
|
|
|
centralWidget.SetLayout(statusLayout) |
|
|
|
|
window.SetCentralWidget(centralWidget) |
|
|
|
|
if !popup { |
|
|
|
|
window.Show() |
|
|
|
|
NewMainWindow().Show() |
|
|
|
|
} |
|
|
|
|
widgets.QApplication_Exec() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func setValues() { |
|
|
|
|
vehicle = getVehicle(vehicleSearch) |
|
|
|
|
if vehicle == nil { |
|
|
|
|
showDialogue(false, "Unable to get vehicle") |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
test, err := vehicle.Data(vehicle.ID) |
|
|
|
|
if err != nil { |
|
|
|
|
showDialogue(false, "Unable to get Vehicle State") |
|
|
|
|
} |
|
|
|
|
vehicleState = test.Response.VehicleState |
|
|
|
|
chargeStats = test.Response.ChargeState |
|
|
|
|
climateState = test.Response.ClimateState |
|
|
|
|
guiSettings = test.Response.GuiSettings |
|
|
|
|
|
|
|
|
|
window.SetWindowTitle(fmt.Sprintf("%+v: %+v", vehicle.DisplayName, vehicle.Vin)) |
|
|
|
|
tempSettingVal := climateState.DriverTempSetting |
|
|
|
|
insideTempVal := climateState.InsideTemp |
|
|
|
|
outsideTempVal := climateState.OutsideTemp |
|
|
|
|
if guiSettings.GuiTemperatureUnits == "F" { |
|
|
|
|
tempSettingVal = (climateState.DriverTempSetting * 1.8) + 32 |
|
|
|
|
insideTempVal = (climateState.InsideTemp * 1.8) + 32 |
|
|
|
|
outsideTempVal = (climateState.OutsideTemp * 1.8) + 32 |
|
|
|
|
} |
|
|
|
|
batteryLevel.SetText(fmt.Sprintf("%+v%%", chargeStats.BatteryLevel)) |
|
|
|
|
batteryRange.SetText(fmt.Sprintf("%.2f%+v", chargeStats.BatteryRange, |
|
|
|
|
strings.Replace(guiSettings.GuiDistanceUnits, "/hr", "", -1))) |
|
|
|
|
batteryRange.SetFixedWidth(10 * len(batteryRange.Text())) |
|
|
|
|
chargingState.SetText(chargeStats.ChargingState) |
|
|
|
|
chargeTimer := time.Duration(chargeStats.MinutesToFullCharge) * time.Minute |
|
|
|
|
minutesToFull.SetText(fmt.Sprintf("%+v (%+v)", formatDuration(chargeTimer), time.Now().Add(chargeTimer).Format("15:04"))) |
|
|
|
|
|
|
|
|
|
fastChargerInd.SetText(chargeStats.FastChargerBrand) |
|
|
|
|
if chargeStats.BatteryHeaterOn { |
|
|
|
|
batteryHeaterInd.SetText("On") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if chargeStats.ChargePortDoorOpen { |
|
|
|
|
chargeDoorOpenInd.SetText("Open") |
|
|
|
|
} else { |
|
|
|
|
chargeDoorOpenInd.SetText("Closed") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
insideTemp.SetText(fmt.Sprintf("%.0f %+v", insideTempVal, guiSettings.GuiTemperatureUnits)) |
|
|
|
|
outsideTemp.SetText(fmt.Sprintf("%.0f %+v", outsideTempVal, guiSettings.GuiTemperatureUnits)) |
|
|
|
|
climateOn.SetChecked(climateState.IsClimateOn) |
|
|
|
|
tempSetting.SetText(fmt.Sprintf("%.0f", tempSettingVal)) |
|
|
|
|
climateUnitLabel.SetText(guiSettings.GuiTemperatureUnits) |
|
|
|
|
|
|
|
|
|
lockedDoors.SetChecked(vehicleState.Locked) |
|
|
|
|
sentryMode.SetChecked(vehicleState.SentryMode) |
|
|
|
|
sentryMode.SetCheckable(!vehicleState.SentryMode) |
|
|
|
|
lockedDoors.SetCheckable(true) |
|
|
|
|
climateOn.SetCheckable(true) |
|
|
|
|
tempSetting.SetReadOnly(false) |
|
|
|
|
|
|
|
|
|
startStopCharge.SetChecked(chargeStats.ChargingState == "Charging") |
|
|
|
|
|
|
|
|
|
startStopCharge.SetCheckable(chargeStats.ChargingState != "Disconnected") |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func enableClimate(i int) { |
|
|
|
|
temp, err := strconv.ParseFloat(tempSetting.Text(), 64) |
|
|
|
|
if err != nil { |
|
|
|
|
showDialogue(true, "Unable to parse temp setting\n%+v", err) |
|
|
|
|
} |
|
|
|
|
if guiSettings.GuiTemperatureUnits == "F" { |
|
|
|
|
temp = (temp - 32) * 5 / 9 |
|
|
|
|
} |
|
|
|
|
if i == 0 { |
|
|
|
|
vehicle.StopAirConditioning() |
|
|
|
|
} else { |
|
|
|
|
vehicle.SetTemperature(temp, temp) |
|
|
|
|
vehicle.StartAirConditioning() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
go setValues() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func lockDoors(i int) { |
|
|
|
|
if i == 0 { |
|
|
|
|
vehicle.UnlockDoors() |
|
|
|
|
} else { |
|
|
|
|
vehicle.LockDoors() |
|
|
|
|
} |
|
|
|
|
go setValues() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func sentryModeEnable(i int) { |
|
|
|
|
vehicle.EnableSentry() |
|
|
|
|
go setValues() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func enableCharging(i int) { |
|
|
|
|
if i == 0 { |
|
|
|
|
vehicle.StopCharging() |
|
|
|
|
} else { |
|
|
|
|
vehicle.StartCharging() |
|
|
|
|
} |
|
|
|
|
func NewMainWindow() *ui.MainWindow { |
|
|
|
|
window = ui.NewMainWindow(nil) |
|
|
|
|
|
|
|
|
|
window.SetWindowTitle("Tesla Go!") |
|
|
|
|
window.HonkPushButton.ConnectClicked(honkHorn) |
|
|
|
|
window.TimeToChargeLabel.SetText("") |
|
|
|
|
window.TimeToChargeVal.SetText("") |
|
|
|
|
window.FlashPushButton.ConnectClicked(flash) |
|
|
|
|
window.FrunkPushButton.ConnectClicked(openFrunk) |
|
|
|
|
window.TrunkPushButton.ConnectClicked(openTrunk) |
|
|
|
|
window.LockPushButton.ConnectClicked(lockDoors) |
|
|
|
|
window.ChargePushButton.ConnectClicked(enableCharging) |
|
|
|
|
window.VehiclePreviewView.SetFixedWidth(50) |
|
|
|
|
window.ClimateOnCheckbox.ConnectStateChanged(enableClimate) |
|
|
|
|
window.ActionRefresh.ConnectTriggered(setVal2) |
|
|
|
|
go setValues() |
|
|
|
|
return window |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func honkHorn(c bool) { |
|
|
|
|
err := vehicle.HonkHorn() |
|
|
|
|
if err != nil { |
|
|
|
|
showDialogue(true, "There was an error honking the horn\n%+v", err) |
|
|
|
|
fmt.Printf("%+v\n", err) |
|
|
|
|
} |
|
|
|
|
go setValues() |
|
|
|
|
} |
|
|
|
|
func flash(c bool) { |
|
|
|
|
err := vehicle.FlashLights() |
|
|
|
|
if err != nil { |
|
|
|
|
showDialogue(true, "There was an error flashing the lights\n%+v", err) |
|
|
|
|
fmt.Printf("%+v\n", err) |
|
|
|
|
} |
|
|
|
|
go setValues() |
|
|
|
|
} |
|
|
|
|
func openTrunk(c bool) { |
|
|
|
|
err := vehicle.OpenTrunk("rear") |
|
|
|
|
if err != nil { |
|
|
|
|
showDialogue(true, "There was an error opening your trunk\n%+v", err) |
|
|
|
|
fmt.Printf("%+v\n", err) |
|
|
|
|
} |
|
|
|
|
func setVal2(check bool) { |
|
|
|
|
go setValues() |
|
|
|
|
} |
|
|
|
|
func openFrunk(c bool) { |
|
|
|
|
err := vehicle.OpenTrunk("front") |
|
|
|
|
if err != nil { |
|
|
|
|
showDialogue(true, "There was an error opening your frunk\n%+v", err) |
|
|
|
|
fmt.Printf("%+v\n", err) |
|
|
|
|
} |
|
|
|
|
go setValues() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func showDialogue(recover bool, msg string, a ...interface{}) { |
|
|
|
|
popup = true |
|
|
|
|
if !recover { |
|
|
|
|
window.Close() |
|
|
|
|
} |
|
|
|
|
dialogue := widgets.NewQDialog(nil, 0) |
|
|
|
|
centralWidget := widgets.NewQWidget(dialogue, 0) |
|
|
|
|
actionHBox := widgets.NewQHBoxLayout() |
|
|
|
|
formLayout := widgets.NewQFormLayout(nil) |
|
|
|
|
contBtn := widgets.NewQPushButton(nil) |
|
|
|
|
quitBtn := widgets.NewQPushButton(nil) |
|
|
|
|
message := widgets.NewQLabel(nil, 0) |
|
|
|
|
|
|
|
|
|
dialogue.SetWindowTitle("TeslaGo Alert") |
|
|
|
|
dialogue.SetMinimumWidth(255) |
|
|
|
|
dialogue.SetMinimumHeight(50 + (20 * (1 + strings.Count(msg, "\n")))) |
|
|
|
|
|
|
|
|
|
contBtn.SetText("Continue") |
|
|
|
|
quitBtn.SetText("Quit") |
|
|
|
|
message.SetText(fmt.Sprintf(msg, a...)) |
|
|
|
|
message.SetWordWrap(true) |
|
|
|
|
|
|
|
|
|
contBtn.ConnectClicked(func(checked bool) { |
|
|
|
|
window.Show() |
|
|
|
|
popup = false |
|
|
|
|
dialogue.Close() |
|
|
|
|
|
|
|
|
|
go setValues() |
|
|
|
|
}) |
|
|
|
|
quitBtn.ConnectClicked(func(checked bool) { |
|
|
|
|
mainApp.Quit() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if recover { |
|
|
|
|
actionHBox.AddWidget(contBtn, 0, 0) |
|
|
|
|
} |
|
|
|
|
actionHBox.AddWidget(quitBtn, 0, 0) |
|
|
|
|
|
|
|
|
|
formLayout.AddRow5(message) |
|
|
|
|
formLayout.AddRow6(actionHBox) |
|
|
|
|
centralWidget.SetLayout(formLayout) |
|
|
|
|
|
|
|
|
|
dialogue.Show() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func formatDuration(d time.Duration) string { |
|
|
|
|
d = d.Round(time.Minute) |
|
|
|
|
h := d / time.Hour |
|
|
|
|
d -= h * time.Hour |
|
|
|
|
m := d / time.Minute |
|
|
|
|
return fmt.Sprintf("%02dh%02dm", h, m) |
|
|
|
|
} |
|
|
|
|