From 3b4c0c24e756cd5103c3d0f95c518e75de7692b2 Mon Sep 17 00:00:00 2001 From: Yang Dai Date: Mon, 20 Jan 2025 20:01:32 +0100 Subject: [PATCH] Update v7.3 --- README.md | 3 + README_zh.md | 5 +- app/build.gradle | 9 +- app/src/main/AndroidManifest.xml | 9 +- .../com/yangdai/calc/main/MainActivity.java | 11 +- .../calc/main/toolbox/ToolBoxFragment.java | 142 ++++++++++-------- .../functions/BaseFunctionActivity.java | 19 ++- .../functions/ruler/RulerActivity.java | 12 ++ .../toolbox/functions/ruler/RulerView.java | 92 ++++++++++++ .../functions/ruler/RulerViewInch.java | 98 ++++++++++++ app/src/main/res/drawable/ruler_icon.xml | 12 ++ app/src/main/res/drawable/ruler_left.xml | 16 ++ app/src/main/res/drawable/ruler_right.xml | 16 ++ app/src/main/res/drawable/unit_icon.xml | 14 +- .../main/res/drawable/unit_icon_shortcuts.xml | 4 +- .../drawable/unit_icon_shortcuts_colored.xml | 6 +- .../activity_chinese_number_conversion.xml | 1 + .../res/layout-land/activity_programmer.xml | 1 + .../res/layout-land/activity_relationship.xml | 1 + .../res/layout-land/activity_statistic.xml | 1 + app/src/main/res/layout-land/compass.xml | 1 + .../res/layout-sw600dp-land/activity_main.xml | 3 +- .../activity_chinese_number_conversion.xml | 1 + .../layout-sw600dp/activity_programmer.xml | 1 + .../layout-sw600dp/activity_relationship.xml | 1 + app/src/main/res/layout/activity_bmi.xml | 1 + .../activity_chinese_number_conversion.xml | 1 + .../main/res/layout/activity_date_range.xml | 1 + app/src/main/res/layout/activity_discount.xml | 1 + app/src/main/res/layout/activity_equation.xml | 1 + app/src/main/res/layout/activity_exchange.xml | 1 + app/src/main/res/layout/activity_finance.xml | 1 + app/src/main/res/layout/activity_fraction.xml | 1 + app/src/main/res/layout/activity_main.xml | 3 +- .../main/res/layout/activity_programmer.xml | 1 + .../res/layout/activity_random_number.xml | 1 + .../main/res/layout/activity_relationship.xml | 1 + app/src/main/res/layout/activity_ruler.xml | 72 +++++++++ .../main/res/layout/activity_statistic.xml | 1 + app/src/main/res/layout/compass.xml | 1 + app/src/main/res/resources.properties | 1 + app/src/main/res/values-de/strings.xml | 3 + app/src/main/res/values-night/themes.xml | 29 ---- app/src/main/res/values-zh/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/themes.xml | 14 +- app/src/main/res/xml/locales_config.xml | 6 - 47 files changed, 486 insertions(+), 140 deletions(-) create mode 100644 app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerActivity.java create mode 100644 app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerView.java create mode 100644 app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerViewInch.java create mode 100644 app/src/main/res/drawable/ruler_icon.xml create mode 100644 app/src/main/res/drawable/ruler_left.xml create mode 100644 app/src/main/res/drawable/ruler_right.xml create mode 100644 app/src/main/res/layout/activity_ruler.xml create mode 100644 app/src/main/res/resources.properties delete mode 100644 app/src/main/res/values-night/themes.xml delete mode 100644 app/src/main/res/xml/locales_config.xml diff --git a/README.md b/README.md index e619617..b89d850 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,9 @@ It integrates multiple practical functions to provide you with all calculation a 13. Mathematical statistics: - Given multiple values entered, the greatest common divisor, least common multiple, arithmetic mean, geometric mean, harmonic mean, square mean, variance, standard deviation, and sum are given. +14. Ruler: + - Measure small objects using on-screen scales, supports both inch and centimeter units. + *** Also provides a variety of widgets for simple calculations without opening the software. *** Also provides floating window function. diff --git a/README_zh.md b/README_zh.md index 3218124..1b26e4c 100644 --- a/README_zh.md +++ b/README_zh.md @@ -100,11 +100,14 @@ - 轻松求解线性方程和一元二次方程。 12. 购物助手: - - 快速计算折扣和单价。 + - 快速计算折扣和单价。 13. 数学统计: - 根据输入的多个数值,给出最大公约数、最小公倍数、算术平均数、几何平均数、调和平均数、平方平均数、方差、标准差和总和。 +14. 刻度尺: + - 通过屏幕上的刻度,测量小物件的长度,支持英寸和厘米两种单位。 + *** 还提供多种桌面小部件,无需打开软件即可进行简单运算。 *** 同时提供了悬浮窗功能,在任意位置进行计算。 diff --git a/app/build.gradle b/app/build.gradle index dbb8c3b..1c8b9f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,9 +13,12 @@ android { applicationId "com.yangdai.calc" minSdk 28 targetSdk 35 - versionCode 62 - versionName '7.2' - resourceConfigurations += ["en", "zh", "de"] + versionCode 63 + versionName '7.3' + } + + androidResources { + generateLocaleConfig true } buildTypes { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e3dca6..62d3033 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,8 +8,7 @@ - - + @@ -34,12 +33,16 @@ android:hardwareAccelerated="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" - android:localeConfig="@xml/locales_config" android:resizeableActivity="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" tools:targetApi="tiramisu"> + { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); defaultSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); defaultSharedPrefs.registerOnSharedPreferenceChangeListener(this); diff --git a/app/src/main/java/com/yangdai/calc/main/toolbox/ToolBoxFragment.java b/app/src/main/java/com/yangdai/calc/main/toolbox/ToolBoxFragment.java index e697ad3..8f6d392 100644 --- a/app/src/main/java/com/yangdai/calc/main/toolbox/ToolBoxFragment.java +++ b/app/src/main/java/com/yangdai/calc/main/toolbox/ToolBoxFragment.java @@ -22,6 +22,7 @@ import com.yangdai.calc.main.toolbox.functions.bmi.BMIActivity; import com.yangdai.calc.main.toolbox.functions.chinese.ChineseNumberConversionActivity; import com.yangdai.calc.main.toolbox.functions.programmer.ProgrammerActivity; +import com.yangdai.calc.main.toolbox.functions.ruler.RulerActivity; import com.yangdai.calc.main.toolbox.functions.shopping.ShoppingActivity; import com.yangdai.calc.main.toolbox.functions.algebra.StatisticsActivity; import com.yangdai.calc.R; @@ -48,22 +49,7 @@ public class ToolBoxFragment extends Fragment { ToolBoxAdapter adapter; private List newData; private List data; - private static final String ORDER = "0/1/2/3/4/5/6/7/8/9/10/11/12/13"; boolean isGrid; - private static final int UNIT_ACTIVITY_ID = 0; - private static final int DATE_RANGE_ACTIVITY_ID = 1; - private static final int FINANCE_ACTIVITY_ID = 2; - private static final int COMPASS_ACTIVITY_ID = 3; - private static final int BMI_ACTIVITY_ID = 4; - private static final int SHOPPING_ACTIVITY_ID = 5; - private static final int CURRENCY_ACTIVITY_ID = 6; - private static final int CHINESE_NUMBER_CONVERSION_ACTIVITY_ID = 7; - private static final int RELATIONSHIP_ACTIVITY_ID = 8; - private static final int RANDOM_ACTIVITY_ID = 9; - private static final int FUNCTION_ACTIVITY_ID = 10; - private static final int STATISTICS_ACTIVITY_ID = 11; - private static final int FRACTION_ACTIVITY_ID = 12; - private static final int PROGRAMMER_ACTIVITY_ID = 13; public ToolBoxFragment() { } @@ -77,20 +63,21 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @SuppressLint("UseCompatLoadingForDrawables") private List createToolBoxItems() { List items = new ArrayList<>(); - items.add(new ToolBoxItem(UNIT_ACTIVITY_ID, getString(R.string.UnitsActivity), getResources().getDrawable(R.drawable.unit_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(DATE_RANGE_ACTIVITY_ID, getString(R.string.dateActivity), getResources().getDrawable(R.drawable.date_range_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(FINANCE_ACTIVITY_ID, getString(R.string.financeActivity), getResources().getDrawable(R.drawable.finance_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(COMPASS_ACTIVITY_ID, getString(R.string.compassActivity), getResources().getDrawable(R.drawable.compass_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(BMI_ACTIVITY_ID, getString(R.string.bmiActivity), getResources().getDrawable(R.drawable.bmi_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(SHOPPING_ACTIVITY_ID, getString(R.string.shoppingActivity), getResources().getDrawable(R.drawable.shopping_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(CURRENCY_ACTIVITY_ID, getString(R.string.exchangeActivity), getResources().getDrawable(R.drawable.currency_exchange_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(CHINESE_NUMBER_CONVERSION_ACTIVITY_ID, getString(R.string.chineseNumberConverter), getResources().getDrawable(R.drawable.chinese_number_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(RELATIONSHIP_ACTIVITY_ID, getString(R.string.relationshipActivity), getResources().getDrawable(R.drawable.relation_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(RANDOM_ACTIVITY_ID, getString(R.string.randomActivity), getResources().getDrawable(R.drawable.random_number_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(FUNCTION_ACTIVITY_ID, getString(R.string.EquationActivity), getResources().getDrawable(R.drawable.functions_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(STATISTICS_ACTIVITY_ID, getString(R.string.statisticActivity), getResources().getDrawable(R.drawable.statistics_icon, requireContext().getTheme()))); - items.add(new ToolBoxItem(FRACTION_ACTIVITY_ID, getString(R.string.numberConvert), getResources().getDrawable(R.drawable.fraction, requireContext().getTheme()))); - items.add(new ToolBoxItem(PROGRAMMER_ACTIVITY_ID, getString(R.string.programmer), getResources().getDrawable(R.drawable.binary_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.UNIT_ACTIVITY_ID, getString(R.string.UnitsActivity), getResources().getDrawable(R.drawable.unit_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.DATE_RANGE_ACTIVITY_ID, getString(R.string.dateActivity), getResources().getDrawable(R.drawable.date_range_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.FINANCE_ACTIVITY_ID, getString(R.string.financeActivity), getResources().getDrawable(R.drawable.finance_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.COMPASS_ACTIVITY_ID, getString(R.string.compassActivity), getResources().getDrawable(R.drawable.compass_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.BMI_ACTIVITY_ID, getString(R.string.bmiActivity), getResources().getDrawable(R.drawable.bmi_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.SHOPPING_ACTIVITY_ID, getString(R.string.shoppingActivity), getResources().getDrawable(R.drawable.shopping_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.CURRENCY_ACTIVITY_ID, getString(R.string.exchangeActivity), getResources().getDrawable(R.drawable.currency_exchange_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.CHINESE_NUMBER_CONVERSION_ACTIVITY_ID, getString(R.string.chineseNumberConverter), getResources().getDrawable(R.drawable.chinese_number_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.RELATIONSHIP_ACTIVITY_ID, getString(R.string.relationshipActivity), getResources().getDrawable(R.drawable.relation_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.RANDOM_ACTIVITY_ID, getString(R.string.randomActivity), getResources().getDrawable(R.drawable.random_number_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.FUNCTION_ACTIVITY_ID, getString(R.string.EquationActivity), getResources().getDrawable(R.drawable.functions_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.STATISTICS_ACTIVITY_ID, getString(R.string.statisticActivity), getResources().getDrawable(R.drawable.statistics_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.FRACTION_ACTIVITY_ID, getString(R.string.numberConvert), getResources().getDrawable(R.drawable.fraction, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.PROGRAMMER_ACTIVITY_ID, getString(R.string.programmer), getResources().getDrawable(R.drawable.binary_icon, requireContext().getTheme()))); + items.add(new ToolBoxItem(Constants.RULER_ACTIVITY_ID, getString(R.string.ruler), getResources().getDrawable(R.drawable.ruler_icon, requireContext().getTheme()))); return items; } @@ -114,7 +101,7 @@ public void onViewCreated(@NonNull View notes, @Nullable Bundle savedInstanceSta isGrid = bundle.getBoolean("GridLayout", true); updateRecycleView(isGrid); }); - String order = sharedPreferences.getString("order", ORDER); + String order = sharedPreferences.getString("order", Constants.ORDER); List orderList = new ArrayList<>(Arrays.asList(order.split("/"))); if (orderList.size() < data.size()) { int oLength = orderList.size(); @@ -126,9 +113,9 @@ public void onViewCreated(@NonNull View notes, @Nullable Bundle savedInstanceSta editor.putString("order", orderString); editor.apply(); } else if (orderList.size() > data.size()) { - orderList = new ArrayList<>(Arrays.asList(ORDER.split("/"))); + orderList = new ArrayList<>(Arrays.asList(Constants.ORDER.split("/"))); SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString("order", ORDER); + editor.putString("order", Constants.ORDER); editor.apply(); } @@ -181,42 +168,65 @@ public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) }; } - private void updateRecycleView(boolean isGrid) { - adapter = new ToolBoxAdapter(newData, isGrid, (item) -> { - int itemId = item.id(); - switch (itemId) { - case UNIT_ACTIVITY_ID -> - startActivity(new Intent(getContext(), UnitActivity.class)); - case DATE_RANGE_ACTIVITY_ID -> - startActivity(new Intent(getContext(), DateRangeActivity.class)); - case FINANCE_ACTIVITY_ID -> - startActivity(new Intent(getContext(), FinanceActivity.class)); - case COMPASS_ACTIVITY_ID -> startActivity(new Intent(getContext(), Compass.class)); - case BMI_ACTIVITY_ID -> startActivity(new Intent(getContext(), BMIActivity.class)); - case SHOPPING_ACTIVITY_ID -> - startActivity(new Intent(getContext(), ShoppingActivity.class)); - case CURRENCY_ACTIVITY_ID -> - startActivity(new Intent(getContext(), CurrencyActivity.class)); - case CHINESE_NUMBER_CONVERSION_ACTIVITY_ID -> - startActivity(new Intent(getContext(), ChineseNumberConversionActivity.class)); - case RELATIONSHIP_ACTIVITY_ID -> - startActivity(new Intent(getContext(), RelationshipActivity.class)); - case RANDOM_ACTIVITY_ID -> - startActivity(new Intent(getContext(), RandomNumberActivity.class)); - case FUNCTION_ACTIVITY_ID -> - startActivity(new Intent(getContext(), EquationActivity.class)); - case STATISTICS_ACTIVITY_ID -> - startActivity(new Intent(getContext(), StatisticsActivity.class)); - case FRACTION_ACTIVITY_ID -> - startActivity(new Intent(getContext(), FractionActivity.class)); - case PROGRAMMER_ACTIVITY_ID -> - startActivity(new Intent(getContext(), ProgrammerActivity.class)); - default -> { - } - } - }); + adapter = new ToolBoxAdapter(newData, isGrid, this::startActivityById); recyclerView.setLayoutManager(isGrid ? new GridLayoutManager(getContext(), 3) : new LinearLayoutManager(getContext())); recyclerView.setAdapter(adapter); } + + private void startActivityById(ToolBoxItem item) { + Intent intent = null; + switch (item.id()) { + case Constants.UNIT_ACTIVITY_ID -> + intent = new Intent(getContext(), UnitActivity.class); + case Constants.DATE_RANGE_ACTIVITY_ID -> + intent = new Intent(getContext(), DateRangeActivity.class); + case Constants.FINANCE_ACTIVITY_ID -> + intent = new Intent(getContext(), FinanceActivity.class); + case Constants.COMPASS_ACTIVITY_ID -> intent = new Intent(getContext(), Compass.class); + case Constants.BMI_ACTIVITY_ID -> intent = new Intent(getContext(), BMIActivity.class); + case Constants.SHOPPING_ACTIVITY_ID -> + intent = new Intent(getContext(), ShoppingActivity.class); + case Constants.CURRENCY_ACTIVITY_ID -> + intent = new Intent(getContext(), CurrencyActivity.class); + case Constants.CHINESE_NUMBER_CONVERSION_ACTIVITY_ID -> + intent = new Intent(getContext(), ChineseNumberConversionActivity.class); + case Constants.RELATIONSHIP_ACTIVITY_ID -> + intent = new Intent(getContext(), RelationshipActivity.class); + case Constants.RANDOM_ACTIVITY_ID -> + intent = new Intent(getContext(), RandomNumberActivity.class); + case Constants.FUNCTION_ACTIVITY_ID -> + intent = new Intent(getContext(), EquationActivity.class); + case Constants.STATISTICS_ACTIVITY_ID -> + intent = new Intent(getContext(), StatisticsActivity.class); + case Constants.FRACTION_ACTIVITY_ID -> + intent = new Intent(getContext(), FractionActivity.class); + case Constants.PROGRAMMER_ACTIVITY_ID -> + intent = new Intent(getContext(), ProgrammerActivity.class); + case Constants.RULER_ACTIVITY_ID -> + intent = new Intent(getContext(), RulerActivity.class); + } + if (intent != null) { + startActivity(intent); + } + } + + private static class Constants { + public static final String ORDER = "0/1/2/3/4/5/6/7/8/9/10/11/12/13/14"; + public static final int UNIT_ACTIVITY_ID = 0; + public static final int DATE_RANGE_ACTIVITY_ID = 1; + public static final int FINANCE_ACTIVITY_ID = 2; + public static final int COMPASS_ACTIVITY_ID = 3; + public static final int BMI_ACTIVITY_ID = 4; + public static final int SHOPPING_ACTIVITY_ID = 5; + public static final int CURRENCY_ACTIVITY_ID = 6; + public static final int CHINESE_NUMBER_CONVERSION_ACTIVITY_ID = 7; + public static final int RELATIONSHIP_ACTIVITY_ID = 8; + public static final int RANDOM_ACTIVITY_ID = 9; + public static final int FUNCTION_ACTIVITY_ID = 10; + public static final int STATISTICS_ACTIVITY_ID = 11; + public static final int FRACTION_ACTIVITY_ID = 12; + public static final int PROGRAMMER_ACTIVITY_ID = 13; + public static final int RULER_ACTIVITY_ID = 14; + } } diff --git a/app/src/main/java/com/yangdai/calc/main/toolbox/functions/BaseFunctionActivity.java b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/BaseFunctionActivity.java index bbbdc28..37ba5be 100644 --- a/app/src/main/java/com/yangdai/calc/main/toolbox/functions/BaseFunctionActivity.java +++ b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/BaseFunctionActivity.java @@ -1,17 +1,23 @@ package com.yangdai.calc.main.toolbox.functions; +import androidx.activity.EdgeToEdge; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.preference.PreferenceManager; import android.content.SharedPreferences; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.view.MenuItem; +import android.view.View; import android.view.WindowManager; import com.google.android.material.elevation.SurfaceColors; +import com.yangdai.calc.R; public abstract class BaseFunctionActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -30,9 +36,12 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getWindow().setStatusBarColor(SurfaceColors.SURFACE_0.getColor(this)); + EdgeToEdge.enable(this); + setRootView(); + applyWindowInsets(findViewById(R.id.parent)); + if (getSupportActionBar() != null) { getSupportActionBar().setBackgroundDrawable(new ColorDrawable(SurfaceColors.SURFACE_0.getColor(this))); getSupportActionBar().setElevation(0f); @@ -52,6 +61,14 @@ protected void onCreate(Bundle savedInstanceState) { protected abstract void setRootView(); + protected void applyWindowInsets(View view) { + ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + } + @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) { diff --git a/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerActivity.java b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerActivity.java new file mode 100644 index 0000000..a51aa7b --- /dev/null +++ b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerActivity.java @@ -0,0 +1,12 @@ +package com.yangdai.calc.main.toolbox.functions.ruler; + +import com.yangdai.calc.R; +import com.yangdai.calc.main.toolbox.functions.BaseFunctionActivity; + +public class RulerActivity extends BaseFunctionActivity { + + @Override + protected void setRootView() { + setContentView(R.layout.activity_ruler); + } +} diff --git a/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerView.java b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerView.java new file mode 100644 index 0000000..70a9699 --- /dev/null +++ b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerView.java @@ -0,0 +1,92 @@ +package com.yangdai.calc.main.toolbox.functions.ruler; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.View; + +import androidx.annotation.NonNull; + +import com.google.android.material.R; +import com.google.android.material.color.MaterialColors; + +public class RulerView extends View { + + private Paint paintText; + private Paint paintMain; + private Paint paintSide; + private float mmToPx; + private float topPadding; + + public RulerView(Context context) { + this(context, null); + } + + public RulerView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RulerView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + paintText = new Paint(); + paintText.setColor(MaterialColors.getColor(this, R.attr.colorOutline)); + paintText.setStrokeWidth(dpToPx(context, 2f)); + paintText.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, getResources().getDisplayMetrics())); + paintText.setAntiAlias(true); + + paintMain = new Paint(); + paintMain.setColor(MaterialColors.getColor(this, R.attr.colorOutline)); + paintMain.setStrokeWidth(dpToPx(context, 2f)); + paintMain.setAntiAlias(true); + + paintSide = new Paint(); + paintSide.setColor(MaterialColors.getColor(this, R.attr.colorOutline)); + paintSide.setAlpha(127); + paintSide.setStrokeWidth(dpToPx(context, 2f)); + paintSide.setAntiAlias(true); + + mmToPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1f, getResources().getDisplayMetrics()); + topPadding = dpToPx(context, 24f); + } + + @Override + protected void onDraw(@NonNull Canvas canvas) { + super.onDraw(canvas); + + float width = getWidth(); + float height = getHeight(); + + int numDivisions = (int) ((height - topPadding) / mmToPx); + float longLineLength = width * 0.53f; + float midLineLength = width * 0.43f; + float shortLineLength = width * 0.34f; + + for (int i = 0; i <= numDivisions; i++) { + float y = topPadding + i * mmToPx; + if (i % 10 == 0) { + canvas.drawLine(width - longLineLength, y, width, y, paintMain); + String text = String.valueOf(i / 10); + float textWidth = paintText.measureText(text); + float textHeight = paintText.descent() - paintText.ascent(); + float textX = (width - longLineLength) / 2 - textWidth / 2; + float textY = y + textHeight / 3; + paintText.setColor(MaterialColors.getColor(this, (i / 10) % 5 == 0 ? R.attr.colorOnSurface : R.attr.colorOutline)); + canvas.drawText(text, textX, textY, paintText); + } else if (i % 5 == 0) { + canvas.drawLine(width - midLineLength, y, width, y, paintSide); + } else { + canvas.drawLine(width - shortLineLength, y, width, y, paintSide); + } + } + } + + private float dpToPx(Context context, float dp) { + return dp * context.getResources().getDisplayMetrics().density; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerViewInch.java b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerViewInch.java new file mode 100644 index 0000000..af1d5f8 --- /dev/null +++ b/app/src/main/java/com/yangdai/calc/main/toolbox/functions/ruler/RulerViewInch.java @@ -0,0 +1,98 @@ +package com.yangdai.calc.main.toolbox.functions.ruler; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.View; + +import androidx.annotation.NonNull; + +import com.google.android.material.R; +import com.google.android.material.color.MaterialColors; + +public class RulerViewInch extends View { + + private Paint paintText; + private Paint paintMain; + private Paint paintSide; + private float inchToPx; + private float inchInterval; + private int inchTextInterval; + private float topPadding; + + public RulerViewInch(Context context) { + this(context, null); + } + + public RulerViewInch(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RulerViewInch(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + private void init(Context context) { + paintText = new Paint(); + paintText.setColor(MaterialColors.getColor(this, R.attr.colorOutline)); + paintText.setStrokeWidth(dpToPx(context, 2f)); + paintText.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, getResources().getDisplayMetrics())); + paintText.setAntiAlias(true); + + paintMain = new Paint(); + paintMain.setColor(MaterialColors.getColor(this, R.attr.colorOutline)); + paintMain.setStrokeWidth(dpToPx(context, 2f)); + paintMain.setAntiAlias(true); + + paintSide = new Paint(); + paintSide.setColor(MaterialColors.getColor(this, R.attr.colorOutline)); + paintSide.setAlpha(127); + paintSide.setStrokeWidth(dpToPx(context, 2f)); + paintSide.setAntiAlias(true); + + inchToPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_IN, 1f, getResources().getDisplayMetrics()); + inchInterval = inchToPx / 10f; + inchTextInterval = 10; + topPadding = dpToPx(context, 24f); + } + + @Override + protected void onDraw(@NonNull Canvas canvas) { + super.onDraw(canvas); + + float width = getWidth(); + float height = getHeight(); + + float numInches = (height - topPadding) / inchToPx; + int numIntervals = (int) (numInches * 10); + + float longLineLength = width * 0.53f; + float midLineLength = width * 0.43f; + float shortLineLength = width * 0.34f; + + for (int i = 0; i <= numIntervals; i++) { + float y = topPadding + i * inchInterval; + if (i % inchTextInterval == 0) { + canvas.drawLine(0f, y, longLineLength, y, paintMain); + String text = String.valueOf(i / inchTextInterval); + float textWidth = paintText.measureText(text); + float textHeight = paintText.descent() - paintText.ascent(); + float textX = (width - longLineLength) / 2 + longLineLength - textWidth / 2; + float textY = y + textHeight / 3; + paintText.setColor(MaterialColors.getColor(this, (i / inchTextInterval) % 12 == 0 ? R.attr.colorOnSurface : R.attr.colorOutline)); + canvas.drawText(text, textX, textY, paintText); + } else if (i % 5 == 0) { + canvas.drawLine(0f, y, midLineLength, y, paintSide); + } else { + canvas.drawLine(0f, y, shortLineLength, y, paintSide); + } + } + } + + private float dpToPx(Context context, float dp) { + return dp * context.getResources().getDisplayMetrics().density; + } +} diff --git a/app/src/main/res/drawable/ruler_icon.xml b/app/src/main/res/drawable/ruler_icon.xml new file mode 100644 index 0000000..399be20 --- /dev/null +++ b/app/src/main/res/drawable/ruler_icon.xml @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ruler_left.xml b/app/src/main/res/drawable/ruler_left.xml new file mode 100644 index 0000000..a2d75ce --- /dev/null +++ b/app/src/main/res/drawable/ruler_left.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ruler_right.xml b/app/src/main/res/drawable/ruler_right.xml new file mode 100644 index 0000000..95916bd --- /dev/null +++ b/app/src/main/res/drawable/ruler_right.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/unit_icon.xml b/app/src/main/res/drawable/unit_icon.xml index 399be20..73e01dc 100644 --- a/app/src/main/res/drawable/unit_icon.xml +++ b/app/src/main/res/drawable/unit_icon.xml @@ -1,12 +1,10 @@ - - \ No newline at end of file + android:viewportHeight="960" + android:tint="?attr/colorControlNormal"> + + diff --git a/app/src/main/res/drawable/unit_icon_shortcuts.xml b/app/src/main/res/drawable/unit_icon_shortcuts.xml index 6952831..9407a8f 100644 --- a/app/src/main/res/drawable/unit_icon_shortcuts.xml +++ b/app/src/main/res/drawable/unit_icon_shortcuts.xml @@ -1,5 +1,4 @@ + android:pathData="M352,438L438,351L382,294L338,338L282,282L325,238L280,193L193,280L352,438ZM680,767L767,680L722,635L678,678L622,622L665,578L608,522L522,608L680,767ZM704,200L761,257L761,257L704,200ZM290,840L120,840L120,670L295,495L80,280L280,80L496,296L647,144Q659,132 674,126Q689,120 705,120Q721,120 736,126Q751,132 763,144L816,198Q828,210 834,225Q840,240 840,256Q840,272 834,286.5Q828,301 816,313L665,465L880,680L680,880L465,665L290,840ZM200,760L256,760L648,369L591,312L200,704L200,760ZM620,341L591,312L591,312L648,369L648,369L620,341Z" /> \ No newline at end of file diff --git a/app/src/main/res/drawable/unit_icon_shortcuts_colored.xml b/app/src/main/res/drawable/unit_icon_shortcuts_colored.xml index 8e42b9c..f97b80a 100644 --- a/app/src/main/res/drawable/unit_icon_shortcuts_colored.xml +++ b/app/src/main/res/drawable/unit_icon_shortcuts_colored.xml @@ -5,6 +5,6 @@ android:viewportWidth="24" android:viewportHeight="24"> - + android:fillColor="@android:color/white" + android:pathData="M352,438L438,351L382,294L338,338L282,282L325,238L280,193L193,280L352,438ZM680,767L767,680L722,635L678,678L622,622L665,578L608,522L522,608L680,767ZM704,200L761,257L761,257L704,200ZM290,840L120,840L120,670L295,495L80,280L280,80L496,296L647,144Q659,132 674,126Q689,120 705,120Q721,120 736,126Q751,132 763,144L816,198Q828,210 834,225Q840,240 840,256Q840,272 834,286.5Q828,301 816,313L665,465L880,680L680,880L465,665L290,840ZM200,760L256,760L648,369L591,312L200,704L200,760ZM620,341L591,312L591,312L648,369L648,369L620,341Z" /> + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_chinese_number_conversion.xml b/app/src/main/res/layout-land/activity_chinese_number_conversion.xml index a490a4d..68461d4 100644 --- a/app/src/main/res/layout-land/activity_chinese_number_conversion.xml +++ b/app/src/main/res/layout-land/activity_chinese_number_conversion.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout-land/activity_programmer.xml b/app/src/main/res/layout-land/activity_programmer.xml index 1be8df3..e1cc21c 100644 --- a/app/src/main/res/layout-land/activity_programmer.xml +++ b/app/src/main/res/layout-land/activity_programmer.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout-land/activity_statistic.xml b/app/src/main/res/layout-land/activity_statistic.xml index 2004af4..99a070b 100644 --- a/app/src/main/res/layout-land/activity_statistic.xml +++ b/app/src/main/res/layout-land/activity_statistic.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout-sw600dp-land/activity_main.xml b/app/src/main/res/layout-sw600dp-land/activity_main.xml index 564b844..c1903e1 100644 --- a/app/src/main/res/layout-sw600dp-land/activity_main.xml +++ b/app/src/main/res/layout-sw600dp-land/activity_main.xml @@ -2,16 +2,15 @@ diff --git a/app/src/main/res/layout-sw600dp/activity_chinese_number_conversion.xml b/app/src/main/res/layout-sw600dp/activity_chinese_number_conversion.xml index c410e0c..edc8ed9 100644 --- a/app/src/main/res/layout-sw600dp/activity_chinese_number_conversion.xml +++ b/app/src/main/res/layout-sw600dp/activity_chinese_number_conversion.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout-sw600dp/activity_programmer.xml b/app/src/main/res/layout-sw600dp/activity_programmer.xml index b6b332b..2b93aa6 100644 --- a/app/src/main/res/layout-sw600dp/activity_programmer.xml +++ b/app/src/main/res/layout-sw600dp/activity_programmer.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_bmi.xml b/app/src/main/res/layout/activity_bmi.xml index d80319a..f36f532 100644 --- a/app/src/main/res/layout/activity_bmi.xml +++ b/app/src/main/res/layout/activity_bmi.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_date_range.xml b/app/src/main/res/layout/activity_date_range.xml index 5e28f43..4793262 100644 --- a/app/src/main/res/layout/activity_date_range.xml +++ b/app/src/main/res/layout/activity_date_range.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_discount.xml b/app/src/main/res/layout/activity_discount.xml index cf7bb07..01fb092 100644 --- a/app/src/main/res/layout/activity_discount.xml +++ b/app/src/main/res/layout/activity_discount.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_equation.xml b/app/src/main/res/layout/activity_equation.xml index b98dbdf..677da34 100644 --- a/app/src/main/res/layout/activity_equation.xml +++ b/app/src/main/res/layout/activity_equation.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_exchange.xml b/app/src/main/res/layout/activity_exchange.xml index c7ce0cc..3255c56 100644 --- a/app/src/main/res/layout/activity_exchange.xml +++ b/app/src/main/res/layout/activity_exchange.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_fraction.xml b/app/src/main/res/layout/activity_fraction.xml index 64b38a9..400e589 100644 --- a/app/src/main/res/layout/activity_fraction.xml +++ b/app/src/main/res/layout/activity_fraction.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 3be846b..cab1a89 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -2,16 +2,15 @@ diff --git a/app/src/main/res/layout/activity_programmer.xml b/app/src/main/res/layout/activity_programmer.xml index 3dab521..9f9aadd 100644 --- a/app/src/main/res/layout/activity_programmer.xml +++ b/app/src/main/res/layout/activity_programmer.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_relationship.xml b/app/src/main/res/layout/activity_relationship.xml index d2da1fa..9b033ff 100644 --- a/app/src/main/res/layout/activity_relationship.xml +++ b/app/src/main/res/layout/activity_relationship.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/layout/activity_ruler.xml b/app/src/main/res/layout/activity_ruler.xml new file mode 100644 index 0000000..e8d8fce --- /dev/null +++ b/app/src/main/res/layout/activity_ruler.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_statistic.xml b/app/src/main/res/layout/activity_statistic.xml index ee1f132..171fff7 100644 --- a/app/src/main/res/layout/activity_statistic.xml +++ b/app/src/main/res/layout/activity_statistic.xml @@ -2,6 +2,7 @@ diff --git a/app/src/main/res/resources.properties b/app/src/main/res/resources.properties new file mode 100644 index 0000000..d5a3ddc --- /dev/null +++ b/app/src/main/res/resources.properties @@ -0,0 +1 @@ +unqualifiedResLocale=en-US \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index cdc600f..5e6bc16 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -235,6 +235,7 @@ Oktal: Binär: *inbegriffen + Lineal Helles Design @@ -242,4 +243,6 @@ Dem System-Design folgen + cm + in \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml deleted file mode 100644 index 52a86a2..0000000 --- a/app/src/main/res/values-night/themes.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 4ff03d9..99581eb 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -232,6 +232,7 @@ 八进制: 二进制: *包含 + 刻度尺 浅色主题 @@ -239,4 +240,6 @@ 跟随系统主题 + 厘米 + 英寸 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3e7fbd2..8f781e8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -253,6 +253,9 @@ Octal: Binary: *include + Ruler + cm + in Light Theme diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index e99fc8e..1c46bf9 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,17 +1,12 @@ - - diff --git a/app/src/main/res/xml/locales_config.xml b/app/src/main/res/xml/locales_config.xml deleted file mode 100644 index af544c5..0000000 --- a/app/src/main/res/xml/locales_config.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file