diff --git a/app/src/main/assets/fossil_hr/openSourceWatchface.bin b/app/src/main/assets/fossil_hr/openSourceWatchface.bin index eeaa332bc..32b54f2e2 100644 Binary files a/app/src/main/assets/fossil_hr/openSourceWatchface.bin and b/app/src/main/assets/fossil_hr/openSourceWatchface.bin differ diff --git a/app/src/main/assets/fossil_hr/widget2ndTZ.bin b/app/src/main/assets/fossil_hr/widget2ndTZ.bin index bed2417d2..1aa07387e 100644 Binary files a/app/src/main/assets/fossil_hr/widget2ndTZ.bin and b/app/src/main/assets/fossil_hr/widget2ndTZ.bin differ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceDesignerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceDesignerActivity.java index f482c1fd9..6e3f9b035 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceDesignerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceDesignerActivity.java @@ -41,6 +41,7 @@ import android.view.DragEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; @@ -67,8 +68,10 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.TimeZone; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -328,6 +331,7 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem JSONObject layoutItem = layout.getJSONObject(i); if (layoutItem.getString("type").equals("comp")) { String widgetName = layoutItem.getString("name"); + String widgetTimezone = null; switch (widgetName) { case "dateSSE": widgetName = "widgetDate"; @@ -357,11 +361,20 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem widgetName = "widget2ndTZ"; break; } + if (widgetName.equals("widget2ndTZ")) { + try { + JSONObject widgetData = layoutItem.getJSONObject("data"); + widgetTimezone = widgetData.getString("tzName"); + } catch (JSONException e) { + LOG.error("Couldn't determine tzName!", e); + } + } int widgetColor = layoutItem.getString("color").equals("white") ? HybridHRWatchfaceWidget.COLOR_WHITE : HybridHRWatchfaceWidget.COLOR_BLACK; widgets.add(new HybridHRWatchfaceWidget(widgetName, layoutItem.getJSONObject("pos").getInt("x"), layoutItem.getJSONObject("pos").getInt("y"), - widgetColor)); + widgetColor, + widgetTimezone)); } } } catch (JSONException e) { @@ -541,6 +554,33 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem posY.setText("120"); } }); + // Populate timezone spinner + String[] timezonesList = TimeZone.getAvailableIDs(); + final Spinner tzSpinner = layout.findViewById(R.id.watchface_widget_timezone_spinner); + final LinearLayout timezoneLayout = layout.findViewById(R.id.watchface_widget_timezone_layout); + timezoneLayout.setVisibility(View.GONE); + ArrayAdapter widgetTZAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, timezonesList); + tzSpinner.setAdapter(widgetTZAdapter); + if ((widget != null) && (Arrays.asList(timezonesList).contains(widget.getTimezone()))) { + tzSpinner.setSelection(Arrays.asList(timezonesList).indexOf(widget.getTimezone())); + } else { + tzSpinner.setSelection(Arrays.asList(timezonesList).indexOf("Etc/UTC")); + } + // Show timezone spinner only when 2nd TZ widget is selected + typeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + String selectedType = widgetTypesArray.get(typeSpinner.getSelectedItemPosition()); + if (selectedType.equals("widget2ndTZ")) { + timezoneLayout.setVisibility(View.VISIBLE); + } else { + timezoneLayout.setVisibility(View.GONE); + } + } + @Override + public void onNothingSelected(AdapterView parent) { } + }); + // Show dialog new AlertDialog.Builder(this) .setView(layout) .setNegativeButton(R.string.fossil_hr_edit_action_delete, new DialogInterface.OnClickListener() { @@ -570,10 +610,17 @@ public class HybridHRWatchfaceDesignerActivity extends AbstractGBActivity implem if (selectedPosY < 1) selectedPosY = 1; if (selectedPosY > 240) selectedPosY = 240; String selectedType = widgetTypesArray.get(typeSpinner.getSelectedItemPosition()); - if (index >= 0) { - widgets.set(index, new HybridHRWatchfaceWidget(selectedType, selectedPosX, selectedPosY, colorSpinner.getSelectedItemPosition())); + String selectedTZ = tzSpinner.getSelectedItem().toString(); + HybridHRWatchfaceWidget widgetConfig; + if (selectedType.equals("widget2ndTZ")) { + widgetConfig = new HybridHRWatchfaceWidget(selectedType, selectedPosX, selectedPosY, colorSpinner.getSelectedItemPosition(), selectedTZ); } else { - widgets.add(new HybridHRWatchfaceWidget(selectedType, selectedPosX, selectedPosY, colorSpinner.getSelectedItemPosition())); + widgetConfig = new HybridHRWatchfaceWidget(selectedType, selectedPosX, selectedPosY, colorSpinner.getSelectedItemPosition()); + } + if (index >= 0) { + widgets.set(index, widgetConfig); + } else { + widgets.add(widgetConfig); } renderWatchfacePreview(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java index f88526a3f..6754009d4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.TimeZone; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.ImageConverter; @@ -70,11 +71,26 @@ public class HybridHRWatchfaceFactory { case "widgetCalories": case "widgetActiveMins": case "widgetChanceOfRain": + widget.put("type", "comp"); + widget.put("name", widgetDesc.getWidgetType()); + widget.put("goal_ring", false); + widget.put("color", widgetDesc.getColor() == HybridHRWatchfaceWidget.COLOR_WHITE ? "white" : "black"); + break; case "widget2ndTZ": widget.put("type", "comp"); widget.put("name", widgetDesc.getWidgetType()); widget.put("goal_ring", false); widget.put("color", widgetDesc.getColor() == HybridHRWatchfaceWidget.COLOR_WHITE ? "white" : "black"); + if (widgetDesc.getTimezone() != null) { + JSONObject data = new JSONObject(); + TimeZone tz = TimeZone.getTimeZone(widgetDesc.getTimezone()); + String tzShortName = widgetDesc.getTimezone().replaceAll(".*/", ""); + int tzOffsetMins = tz.getRawOffset() / 1000 / 60; + data.put("tzName", widgetDesc.getTimezone()); + data.put("loc", tzShortName); + data.put("utc", tzOffsetMins); + widget.put("data", data); + } break; default: LOG.warn("Invalid widget name: " + widgetDesc.getWidgetType()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceWidget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceWidget.java index 656150378..246157730 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceWidget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceWidget.java @@ -32,6 +32,7 @@ public class HybridHRWatchfaceWidget { private int posX; private int posY; private int color = 0; + private String timezone; public static int COLOR_WHITE = 0; public static int COLOR_BLACK = 1; @@ -42,6 +43,11 @@ public class HybridHRWatchfaceWidget { this.posY = posY; this.color = color; } + public HybridHRWatchfaceWidget(String widgetType, int posX, int posY, int color, String timezone) { + this(widgetType, posX, posY, color); + this.timezone = timezone; + } + public static LinkedHashMap getAvailableWidgetTypes(Context context) { LinkedHashMap widgetTypes = new LinkedHashMap<>(); @@ -73,7 +79,6 @@ public class HybridHRWatchfaceWidget { public int getPosX() { return posX; } - public int getPosY() { return posY; } @@ -81,7 +86,6 @@ public class HybridHRWatchfaceWidget { public void setPosX(int posX) { this.posX = posX; } - public void setPosY(int posY) { this.posY = posY; } @@ -89,4 +93,8 @@ public class HybridHRWatchfaceWidget { public int getColor() { return color; } + + public String getTimezone() { + return timezone; + } } diff --git a/app/src/main/res/layout/dialog_hybridhr_watchface_widget.xml b/app/src/main/res/layout/dialog_hybridhr_watchface_widget.xml index 272fd82c6..7ed49186f 100644 --- a/app/src/main/res/layout/dialog_hybridhr_watchface_widget.xml +++ b/app/src/main/res/layout/dialog_hybridhr_watchface_widget.xml @@ -76,4 +76,19 @@ android:text="@string/watchface_dialog_widget_preset_right"/> - \ No newline at end of file + + + + + + diff --git a/external/fossil-hr-watchface b/external/fossil-hr-watchface index 01bd1424d..15aeb1e72 160000 --- a/external/fossil-hr-watchface +++ b/external/fossil-hr-watchface @@ -1 +1 @@ -Subproject commit 01bd1424dc4c492ab25f3e2824be2aa8bf5b5256 +Subproject commit 15aeb1e72595fb285702878632d8a9e42b0eb181