Skip to content

Commit

Permalink
Merge pull request #21365 from osmandapp/speedlimit_frame/aa_fix
Browse files Browse the repository at this point in the history
Fix frame positions for speedlimit/ align for AA
  • Loading branch information
Chumva authored Nov 20, 2024
2 parents 8c08e65 + 8d9ca47 commit b13b6c9
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 51 deletions.
31 changes: 16 additions & 15 deletions OsmAnd/res/layout/speedometer_widget.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/content_padding_medium"
android:clipToPadding="false"
android:clipChildren="false"
>
android:clipToPadding="false"
android:orientation="horizontal"
android:padding="@dimen/content_padding_medium">

<LinearLayout
android:id="@+id/speedometer_container"
Expand All @@ -18,24 +17,23 @@
android:elevation="2dp"
android:orientation="vertical"
android:paddingHorizontal="9dp"
android:paddingVertical="9dp"
>
android:paddingVertical="9dp">

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/speedometer_value"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="start|top"
android:gravity="start|center_vertical"
android:layout_weight="1"
android:autoSizeMinTextSize="16sp"
android:autoSizeMaxTextSize="80sp"
android:autoSizeMinTextSize="16sp"
android:autoSizeStepGranularity="1sp"
android:autoSizeTextType="uniform"
android:ellipsize="none"
android:gravity="start|center_vertical"
android:includeFontPadding="false"
android:textColor="@color/widgettext_day"
android:textSize="36sp"
android:includeFontPadding="false"
tools:text="85" />

<net.osmand.plus.widgets.TextViewEx
Expand All @@ -49,8 +47,8 @@
android:textAllCaps="true"
android:textColor="?android:textColorSecondary"
android:textSize="11dp"
tools:text="KM/H"
tools:ignore="SpUsage" />
tools:ignore="SpUsage"
tools:text="KM/H" />

</LinearLayout>

Expand All @@ -59,20 +57,22 @@
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="center"
android:gravity="center"
android:layout_marginVertical="9dp"
android:layout_marginStart="-6dp"
android:layout_marginEnd="6dp"
android:background="@drawable/speed_limit_shape"
android:elevation="2dp"
android:gravity="center"
android:orientation="vertical"
android:paddingHorizontal="9dp"
android:paddingVertical="9dp"
android:translationX="-6dp"
android:translationZ="2dp">

<TextView
android:id="@+id/limit_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top|center_horizontal"
android:layout_weight="1"
android:gravity="center"
android:includeFontPadding="false"
android:text="@string/shared_string_limit"
android:textAllCaps="true"
Expand All @@ -83,6 +83,7 @@
android:id="@+id/speed_limit_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:ellipsize="none"
android:gravity="center"
android:includeFontPadding="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ public boolean setPreference(String key, Object value, ApplicationMode mode) {
} else if (preference instanceof ListStringPreference listStringPreference) {
if (value instanceof List<?> || (value == null && listStringPreference.isNullSupported(mode))) {
if (value == null) {
listStringPreference.setStringsListForProfile(mode,null);
listStringPreference.setStringsListForProfile(mode, null);
} else {
List<?> list = (List<?>) value;
boolean isListOfString = list.stream().allMatch(element -> element instanceof String);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
import net.osmand.plus.views.mapwidgets.WidgetsVisibilityHelper;
import net.osmand.util.Algorithms;

import java.util.List;

public class SpeedometerWidget {

private final static int PREVIEW_VALUE = 85;
Expand Down Expand Up @@ -84,6 +86,11 @@ public class SpeedometerWidget {
private final static int SPEED_LIMIT_SIZE_L = 96;
private final static int SPEED_LIMIT_DESCRIPTION_SIZE_USUAL = 11;
private final static int SPEED_LIMIT_DESCRIPTION_SIZE_CANADA_S = 9;
private final static int SPEED_LIMIT_CONTAINER_US_PADDING_S = 7;
private final static int SPEED_LIMIT_CONTAINER_US_PADDING_M = 9;
private final static int SPEED_LIMIT_CONTAINER_US_PADDING_L = 12;
private final static int SPEED_LIMIT_VALUE_WEIGHT = 2;
private final static int SPEED_LIMIT_DESCRIPTION_WEIGHT = 1;

private final static int SPEEDOMETER_PADDING_SIDE_S = 9;
private final static int SPEEDOMETER_PADDING_SIDE_ML = 12;
Expand All @@ -93,11 +100,6 @@ public class SpeedometerWidget {
private final static int SPEEDOMETER_PADDING_BOTTOM_L = 12;
private final static int SPEEDOMETER_PADDING_SIDE_AA = 12;
private final static int SPEEDOMETER_PADDING_TOP_BOTTOM_AA = 9;
private final static int US_SPEED_LIMIT_BOTTOM = 18;
private final static int US_SPEED_LIMIT_BOTTOM_S = 14;
private final static int US_SPEED_LIMIT_DESCRIPTION_TOP_S = 18;
private final static int US_SPEED_LIMIT_DESCRIPTION_TOP_M = 24;
private final static int US_SPEED_LIMIT_DESCRIPTION_TOP_L = 28;
private final static int SPEEDOMETER_UNIT_DESCR_CANADA_SIZE_S = 8;

private final static int SHADOW_SIZE = 4;
Expand Down Expand Up @@ -127,6 +129,8 @@ public class SpeedometerWidget {
private float cachedSpeed = UNDEFINED_SPEED;
private String cachedSpeedLimitText;
private boolean lastNightMode;
private Integer cachedMetricSystem;
private DrivingRegion cachedRegion;

@Nullable
private Bitmap widgetBitmap;
Expand Down Expand Up @@ -157,24 +161,29 @@ private void setupWidget() {
return;
}

boolean isUsaOrCanada = isUsaOrCanadaRegion();
LinearLayout.LayoutParams speedLimitValueParams = (LinearLayout.LayoutParams) speedLimitValueView.getLayoutParams();
speedLimitValueParams.setMargins(0, 0, 0, 0);
speedLimitValueView.setLayoutParams(speedLimitValueParams);
AndroidUiHelper.updateVisibility(speedLimitDescription, false);
AndroidUiHelper.updateVisibility(speedLimitDescription, isUsaOrCanada);
WidgetSize newWidgetSize = settings.SPEEDOMETER_SIZE.getModeValue(mode);
if (previousWidgetSize == newWidgetSize) {
DrivingRegion newDrivingRegion = settings.DRIVING_REGION.getModeValue(mode);
if (previousWidgetSize == newWidgetSize && cachedRegion == newDrivingRegion) {
return;
}
previousWidgetSize = newWidgetSize;
cachedRegion = newDrivingRegion;

LinearLayout.LayoutParams speedLimitLayoutParams = (LinearLayout.LayoutParams) speedLimitContainer.getLayoutParams();
speedLimitLayoutParams.gravity = Gravity.CENTER;
LinearLayout.LayoutParams speedometerLayoutParams = (LinearLayout.LayoutParams) speedometerContainer.getLayoutParams();
if (isUsaOrCanadaRegion()) {
if (isUsaOrCanada) {
speedLimitValueParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
} else{
} else {
speedLimitValueParams.height = LinearLayout.LayoutParams.MATCH_PARENT;
}

int speedLimitPadding;
speedLimitContainer.setLayoutParams(speedLimitLayoutParams);
switch (previousWidgetSize) {
case MEDIUM:
Expand All @@ -187,6 +196,8 @@ private void setupWidget() {
speedLimitLayoutParams.height = dpToPx(SPEED_LIMIT_SIZE_M);
speedLimitLayoutParams.width = dpToPx(SPEED_LIMIT_SIZE_M);
speedLimitValueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, SPEED_LIMIT_TEXT_SIZE_M);
speedLimitPadding = isUsaOrCanada ? dpToPx(SPEED_LIMIT_CONTAINER_US_PADDING_M) : 0;
speedLimitContainer.setPadding(speedLimitPadding, speedLimitPadding, speedLimitPadding, speedLimitPadding);
speedLimitContainer.setLayoutParams(speedLimitLayoutParams);
speedLimitDescription.setTextSize(TypedValue.COMPLEX_UNIT_SP, SPEED_LIMIT_DESCRIPTION_SIZE_USUAL);
break;
Expand All @@ -199,6 +210,8 @@ private void setupWidget() {

speedLimitLayoutParams.height = dpToPx(SPEED_LIMIT_SIZE_L);
speedLimitLayoutParams.width = dpToPx(SPEED_LIMIT_SIZE_L);
speedLimitPadding = isUsaOrCanada ? dpToPx(SPEED_LIMIT_CONTAINER_US_PADDING_L) : 0;
speedLimitContainer.setPadding(speedLimitPadding, speedLimitPadding, speedLimitPadding, speedLimitPadding);
speedLimitContainer.setLayoutParams(speedLimitLayoutParams);
speedLimitValueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, SPEED_LIMIT_TEXT_SIZE_L);
speedLimitDescription.setTextSize(TypedValue.COMPLEX_UNIT_SP, SPEED_LIMIT_DESCRIPTION_SIZE_USUAL);
Expand All @@ -212,6 +225,8 @@ private void setupWidget() {

speedLimitLayoutParams.height = dpToPx(SPEED_LIMIT_SIZE_S);
speedLimitLayoutParams.width = dpToPx(SPEED_LIMIT_SIZE_S);
speedLimitPadding = isUsaOrCanada ? dpToPx(SPEED_LIMIT_CONTAINER_US_PADDING_S) : 0;
speedLimitContainer.setPadding(speedLimitPadding, speedLimitPadding, speedLimitPadding, speedLimitPadding);
speedLimitContainer.setLayoutParams(speedLimitLayoutParams);
speedLimitValueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, SPEED_LIMIT_TEXT_SIZE_S);
speedLimitDescription.setTextSize(TypedValue.COMPLEX_UNIT_SP, isCanadaRegion() ? SPEED_LIMIT_DESCRIPTION_SIZE_CANADA_S : SPEED_LIMIT_DESCRIPTION_SIZE_USUAL);
Expand Down Expand Up @@ -255,6 +270,9 @@ public void updateInfo(@Nullable DrawSettings drawSettings, boolean drawBitmap,
lastNightMode = nightMode;
isChanged = true;
}
if (isMetricUpdateNeeded()) {
isChanged = true;
}
Location location = provider.getLastKnownLocation();
if (location != null && location.hasSpeed()) {
float updateThreshold = cachedSpeed < LOW_SPEED_THRESHOLD_MPS
Expand Down Expand Up @@ -344,6 +362,15 @@ public void updateInfo(@Nullable DrawSettings drawSettings, boolean drawBitmap,
}
}

public boolean isMetricUpdateNeeded() {
int metricSystem = app.getSettings().METRIC_SYSTEM.get().ordinal();
if (cachedMetricSystem == null || cachedMetricSystem != metricSystem) {
cachedMetricSystem = metricSystem;
return true;
}
return false;
}

private boolean shouldShowWidget() {
boolean showSpeedometerSetting = settings.SHOW_SPEEDOMETER.getModeValue(mode);
if (visibilityHelper != null) {
Expand Down Expand Up @@ -428,20 +455,19 @@ private void drawSpeedLimit(Canvas canvas, int textSize, float density, Rect ale
float x = alertRect.left + (float) alertRect.width() / 2 - textPaint.measureText(cachedSpeedLimitText) / 2;
float y;
if (isUsaOrCanadaRegion()) {
int padding;
if (newWidgetSize == WidgetSize.SMALL) {
padding = US_SPEED_LIMIT_BOTTOM_S;
} else {
padding = US_SPEED_LIMIT_BOTTOM;
}
y = alertRect.bottom - padding * density;
Rect contentRect = getSpeedlimitContentRect(alertRect, newWidgetSize, density);
y = calculateYWeightPose(contentRect, SPEED_LIMIT_VALUE_WEIGHT, List.of(SPEED_LIMIT_DESCRIPTION_WEIGHT, SPEED_LIMIT_VALUE_WEIGHT), List.of(SPEED_LIMIT_DESCRIPTION_WEIGHT), textBounds);
} else {
y = alertRect.top + (float) alertRect.height() / 2 + (float) textBounds.height() / 2;
}
canvas.drawText(cachedSpeedLimitText, x, y, textPaint);
}

private void drawSpeedLimitDescription(Canvas canvas, TextPaint textPaint, Rect alertRect, float density, WidgetSize newWidgetSize){
private float calculateFrameTextHeight(float weight, float totalWeight, float rectHeight) {
return ((weight * rectHeight / totalWeight));
}

private void drawSpeedLimitDescription(Canvas canvas, TextPaint textPaint, Rect alertRect, float density, WidgetSize newWidgetSize) {
float unitTextSize;
String textLimitDescription;
if (isUsaRegion()) {
Expand All @@ -455,18 +481,51 @@ private void drawSpeedLimitDescription(Canvas canvas, TextPaint textPaint, Rect
unitTextSize = SPEEDOMETER_UNIT_TEXT_SIZE;
}
}
Rect contentRect = getSpeedlimitContentRect(alertRect, newWidgetSize, density);
textPaint.setTextSize(unitTextSize * density);
float xDescr = alertRect.left + (float) alertRect.width() / 2 - textPaint.measureText(textLimitDescription) / 2;
int padding;
if (newWidgetSize == WidgetSize.SMALL) {
padding = US_SPEED_LIMIT_DESCRIPTION_TOP_S;
} else if (newWidgetSize == WidgetSize.MEDIUM) {
padding = US_SPEED_LIMIT_DESCRIPTION_TOP_M;
Rect textBounds = new Rect();
textPaint.getTextBounds(textLimitDescription, 0, textLimitDescription.length(), textBounds);
float xDescr = contentRect.left + (float) contentRect.width() / 2 - textPaint.measureText(textLimitDescription) / 2;
float yDescr = calculateYWeightPose(contentRect, SPEED_LIMIT_DESCRIPTION_WEIGHT, List.of(SPEED_LIMIT_VALUE_WEIGHT, SPEED_LIMIT_DESCRIPTION_WEIGHT), null, textBounds);

canvas.drawText(textLimitDescription, xDescr, yDescr, textPaint);
}

private float calculateYWeightPose(@NonNull Rect contentRect, int frameWeight, @NonNull List<Integer> allWeights,
@Nullable List<Integer> weightsAbove, @NonNull Rect textBounds) {
float halfTextHeight = textBounds.height() / 2.0f;
float totalWeight = allWeights.stream().reduce(0, Integer::sum);

float totalHeightAbove = 0;
if (weightsAbove != null) {
for (Integer weight : weightsAbove) {
totalHeightAbove += calculateFrameTextHeight(weight, totalWeight, contentRect.height());
}
}

float calculatedFrameTextHeight = calculateFrameTextHeight(frameWeight, totalWeight, contentRect.height());
float frameCenterPosition = calculatedFrameTextHeight / 2 + totalHeightAbove + halfTextHeight;
return frameCenterPosition + contentRect.top;
}

private Rect getSpeedlimitContentRect(@NonNull Rect speedlimitRect, @NonNull WidgetSize newWidgetSize, float density) {
if (isUsaOrCanadaRegion()) {
int padding;
if (newWidgetSize == WidgetSize.SMALL) {
padding = SPEED_LIMIT_CONTAINER_US_PADDING_S;
} else if (newWidgetSize == WidgetSize.MEDIUM) {
padding = SPEED_LIMIT_CONTAINER_US_PADDING_M;
} else {
padding = SPEED_LIMIT_CONTAINER_US_PADDING_L;
}
float scaledPadding = padding * density;
return new Rect((int) (speedlimitRect.left + scaledPadding),
(int) (speedlimitRect.top + scaledPadding),
(int) (speedlimitRect.right - scaledPadding),
(int) (speedlimitRect.bottom - scaledPadding));
} else {
padding = US_SPEED_LIMIT_DESCRIPTION_TOP_L;
return speedlimitRect;
}
float yDescr = alertRect.top + padding * density;
canvas.drawText(textLimitDescription, xDescr, yDescr, textPaint);
}

private void drawCurrentSpeed(Canvas canvas, int textSize, Rect speedArea, float density, boolean speedExceed) {
Expand Down Expand Up @@ -508,7 +567,7 @@ private void drawCurrentSpeed(Canvas canvas, int textSize, Rect speedArea, float
canvas.drawText(formattedSpeed.value, x, y, textPaint);
}

private int getSpeedLimitColor(boolean nightMode){
private int getSpeedLimitColor(boolean nightMode) {
if (isUsaOrCanadaRegion() || isEuropeRegion()) {
return app.getColor(nightMode ? R.color.widgettext_night : R.color.widgettext_day);
} else {
Expand Down Expand Up @@ -609,15 +668,10 @@ private void setSpeedLimitText(String value) {
}

private void setSpeedLimitDescription() {
boolean visible = false;
if (isUsaOrCanadaRegion()) {
if (speedLimitDescription != null) {
String textLimitDescription = app.getString(isCanadaRegion() ? R.string.speedometer_maximum : R.string.shared_string_limit).toUpperCase();
speedLimitDescription.setText(textLimitDescription);
visible = true;
}
if (isUsaOrCanadaRegion() && speedLimitDescription != null) {
String textLimitDescription = app.getString(isCanadaRegion() ? R.string.speedometer_maximum : R.string.shared_string_limit).toUpperCase();
speedLimitDescription.setText(textLimitDescription);
}
AndroidUiHelper.updateVisibility(speedLimitDescription, visible);
}

private boolean isUsaOrCanadaRegion() {
Expand Down

0 comments on commit b13b6c9

Please sign in to comment.