|
62 | 62 | import com.zebra.datawedgeprofileintents.DWScannerPluginEnable; |
63 | 63 | import com.zebra.datawedgeprofileintentshelpers.CreateProfileHelper; |
64 | 64 |
|
| 65 | +import androidx.appcompat.app.AlertDialog; |
65 | 66 | import androidx.appcompat.app.AppCompatActivity; |
66 | 67 | import androidx.appcompat.widget.Toolbar; |
67 | 68 | import androidx.core.view.ViewCompat; |
@@ -416,6 +417,9 @@ public void onClick(View v) { |
416 | 417 | // Setup debounce listeners |
417 | 418 | setupDebounceListeners(); |
418 | 419 |
|
| 420 | + // Setup high-res stabilization listener |
| 421 | + setupHighResStabilizationListener(); |
| 422 | + |
419 | 423 | findViewById(R.id.btCancel).setOnClickListener(new View.OnClickListener() { |
420 | 424 | @Override |
421 | 425 | public void onClick(View view) { |
@@ -1722,13 +1726,241 @@ private void loadHighResStabilization(SharedPreferences sharedPreferences) { |
1722 | 1726 | boolean highResStabilizationEnabled = sharedPreferences.getBoolean( |
1723 | 1727 | SHARED_PREFERENCES_HIGH_RES_STABILIZATION_ENABLED, |
1724 | 1728 | SHARED_PREFERENCES_HIGH_RES_STABILIZATION_ENABLED_DEFAULT); |
| 1729 | + |
| 1730 | + // Temporarily remove listener to prevent dialog from showing during load |
| 1731 | + cbHighResStabilization.setOnCheckedChangeListener(null); |
1725 | 1732 | cbHighResStabilization.setChecked(highResStabilizationEnabled); |
| 1733 | + // Restore listener |
| 1734 | + setupHighResStabilizationListener(); |
| 1735 | + |
| 1736 | + // Update high resolution options state based on loaded setting |
| 1737 | + updateHighResolutionOptionsState(highResStabilizationEnabled); |
1726 | 1738 | } |
1727 | 1739 |
|
1728 | 1740 | private void saveHighResStabilization(SharedPreferences.Editor editor) { |
1729 | 1741 | editor.putBoolean(SHARED_PREFERENCES_HIGH_RES_STABILIZATION_ENABLED, cbHighResStabilization.isChecked()); |
1730 | 1742 | } |
1731 | 1743 |
|
| 1744 | + private void setupHighResStabilizationListener() { |
| 1745 | + cbHighResStabilization.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { |
| 1746 | + @Override |
| 1747 | + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
| 1748 | + if (isChecked) { |
| 1749 | + // Check if debounce is disabled |
| 1750 | + checkDebounceForHighResStabilization(); |
| 1751 | + // Disable high resolutions (>8MP) when high-res stabilization is enabled |
| 1752 | + updateHighResolutionOptionsState(true); |
| 1753 | + } else { |
| 1754 | + // Re-enable high resolutions when high-res stabilization is disabled |
| 1755 | + updateHighResolutionOptionsState(false); |
| 1756 | + } |
| 1757 | + } |
| 1758 | + }); |
| 1759 | + } |
| 1760 | + |
| 1761 | + /** |
| 1762 | + * Updates the state of high resolution options (>8MP) based on high-res stabilization state. |
| 1763 | + * When high-res stabilization is enabled, resolutions above 8MP are disabled to ensure |
| 1764 | + * consistent coordinate mapping between preview and high-res capture. |
| 1765 | + * |
| 1766 | + * @param disableHighRes true to disable resolutions >8MP, false to re-enable them |
| 1767 | + */ |
| 1768 | + private void updateHighResolutionOptionsState(boolean disableHighRes) { |
| 1769 | + // Disable/enable dynamic resolution mode |
| 1770 | + // When high-res stabilization is enabled, only static resolution mode is available |
| 1771 | + if (spinnerResolutionMode != null) { |
| 1772 | + spinnerResolutionMode.setEnabled(!disableHighRes); |
| 1773 | + spinnerResolutionMode.setAlpha(disableHighRes ? 0.5f : 1.0f); |
| 1774 | + |
| 1775 | + // If disabling dynamic mode and it's currently selected, switch to static |
| 1776 | + if (disableHighRes && spinnerResolutionMode.getSelectedItemPosition() == 1) { |
| 1777 | + spinnerResolutionMode.setSelection(0); |
| 1778 | + updateResolutionModeVisibility(0); |
| 1779 | + } |
| 1780 | + } |
| 1781 | + |
| 1782 | + // Disable/enable 12MP and higher resolutions (only applicable in static mode) |
| 1783 | + if (rb12MPResolution != null) { |
| 1784 | + rb12MPResolution.setEnabled(!disableHighRes); |
| 1785 | + rb12MPResolution.setAlpha(disableHighRes ? 0.5f : 1.0f); |
| 1786 | + } |
| 1787 | + if (rb12_5MPResolution != null) { |
| 1788 | + rb12_5MPResolution.setEnabled(!disableHighRes); |
| 1789 | + rb12_5MPResolution.setAlpha(disableHighRes ? 0.5f : 1.0f); |
| 1790 | + } |
| 1791 | + if (rb12_6MPResolution != null) { |
| 1792 | + rb12_6MPResolution.setEnabled(!disableHighRes); |
| 1793 | + rb12_6MPResolution.setAlpha(disableHighRes ? 0.5f : 1.0f); |
| 1794 | + } |
| 1795 | + |
| 1796 | + // If disabling and one of the high resolutions is currently selected, fall back to 8MP or lower |
| 1797 | + if (disableHighRes) { |
| 1798 | + boolean needsFallback = (rb12MPResolution != null && rb12MPResolution.isChecked()) || |
| 1799 | + (rb12_5MPResolution != null && rb12_5MPResolution.isChecked()) || |
| 1800 | + (rb12_6MPResolution != null && rb12_6MPResolution.isChecked()); |
| 1801 | + |
| 1802 | + if (needsFallback) { |
| 1803 | + // Select the highest available resolution <= 8MP |
| 1804 | + if (rb8MPResolution != null && rb8MPResolution.getVisibility() == View.VISIBLE) { |
| 1805 | + rb8MPResolution.setChecked(true); |
| 1806 | + } else if (rb4MPResolution != null && rb4MPResolution.getVisibility() == View.VISIBLE) { |
| 1807 | + rb4MPResolution.setChecked(true); |
| 1808 | + } else if (rb2MPResolution != null && rb2MPResolution.getVisibility() == View.VISIBLE) { |
| 1809 | + rb2MPResolution.setChecked(true); |
| 1810 | + } else if (rb1MPResolution != null && rb1MPResolution.getVisibility() == View.VISIBLE) { |
| 1811 | + rb1MPResolution.setChecked(true); |
| 1812 | + } |
| 1813 | + } |
| 1814 | + } |
| 1815 | + } |
| 1816 | + |
| 1817 | + private void checkDebounceForHighResStabilization() { |
| 1818 | + if (!cbDebounceEnabled.isChecked()) { |
| 1819 | + // Show warning dialog for debounce |
| 1820 | + new AlertDialog.Builder(this) |
| 1821 | + .setTitle(getString(R.string.high_res_debounce_warning_title)) |
| 1822 | + .setMessage(getString(R.string.high_res_debounce_warning_message)) |
| 1823 | + .setNegativeButton(getString(R.string.cancel), (dialog, which) -> { |
| 1824 | + // Cancel - uncheck high-res stabilization |
| 1825 | + cbHighResStabilization.setOnCheckedChangeListener(null); |
| 1826 | + cbHighResStabilization.setChecked(false); |
| 1827 | + setupHighResStabilizationListener(); |
| 1828 | + dialog.dismiss(); |
| 1829 | + }) |
| 1830 | + .setNeutralButton(getString(R.string.enable_debounce), (dialog, which) -> { |
| 1831 | + // Enable debounce with current settings |
| 1832 | + cbDebounceEnabled.setChecked(true); |
| 1833 | + updateDebounceUIState(true); |
| 1834 | + dialog.dismiss(); |
| 1835 | + // Continue to check resolution mode |
| 1836 | + checkResolutionModeForHighResStabilization(); |
| 1837 | + }) |
| 1838 | + .setPositiveButton(getString(R.string.enable_debounce_recommended), (dialog, which) -> { |
| 1839 | + // Enable debounce with recommended settings |
| 1840 | + applyRecommendedDebounceSettings(); |
| 1841 | + dialog.dismiss(); |
| 1842 | + // Continue to check resolution mode |
| 1843 | + checkResolutionModeForHighResStabilization(); |
| 1844 | + }) |
| 1845 | + .setCancelable(false) |
| 1846 | + .show(); |
| 1847 | + } else { |
| 1848 | + // Debounce is already enabled, check resolution mode |
| 1849 | + checkResolutionModeForHighResStabilization(); |
| 1850 | + } |
| 1851 | + } |
| 1852 | + |
| 1853 | + private void applyRecommendedDebounceSettings() { |
| 1854 | + // Enable debounce |
| 1855 | + cbDebounceEnabled.setChecked(true); |
| 1856 | + updateDebounceUIState(true); |
| 1857 | + |
| 1858 | + // Set algorithm to IOU (index 1) |
| 1859 | + spinnerDebounceAlgorithm.setSelection(1); |
| 1860 | + updateDebounceAlgorithmVisibility(1); |
| 1861 | + |
| 1862 | + // Set max frames to 30 |
| 1863 | + sbDebounceMaxFrames.setProgress(30); |
| 1864 | + tvDebounceMaxFramesValue.setText(getString(R.string.debounce_max_frames_value, 30)); |
| 1865 | + |
| 1866 | + // Set IOU threshold to 20 (0.2) |
| 1867 | + sbDebounceIouThreshold.setProgress(20); |
| 1868 | + float iouValue = 20 / 100.0f; |
| 1869 | + tvDebounceIouThresholdValue.setText(String.format(getString(R.string.debounce_iou_threshold_value), iouValue)); |
| 1870 | + } |
| 1871 | + |
| 1872 | + private void checkResolutionModeForHighResStabilization() { |
| 1873 | + // Check if resolution mode is dynamic (position 1) |
| 1874 | + int modePosition = spinnerResolutionMode.getSelectedItemPosition(); |
| 1875 | + if (modePosition == 1) { |
| 1876 | + // Show warning dialog for dynamic resolution |
| 1877 | + new AlertDialog.Builder(this) |
| 1878 | + .setTitle(getString(R.string.high_res_dynamic_warning_title)) |
| 1879 | + .setMessage(getString(R.string.high_res_dynamic_warning_message)) |
| 1880 | + .setNegativeButton(getString(R.string.cancel), (dialog, which) -> { |
| 1881 | + // Cancel - uncheck high-res stabilization |
| 1882 | + cbHighResStabilization.setOnCheckedChangeListener(null); |
| 1883 | + cbHighResStabilization.setChecked(false); |
| 1884 | + setupHighResStabilizationListener(); |
| 1885 | + dialog.dismiss(); |
| 1886 | + }) |
| 1887 | + .setNeutralButton(getString(R.string.set_static_mode), (dialog, which) -> { |
| 1888 | + // Set to static mode with current resolution |
| 1889 | + spinnerResolutionMode.setSelection(0); |
| 1890 | + updateResolutionModeVisibility(0); |
| 1891 | + dialog.dismiss(); |
| 1892 | + // Continue to check if static resolution is too high |
| 1893 | + checkStaticResolutionForHighResStabilization(); |
| 1894 | + }) |
| 1895 | + .setPositiveButton(getString(R.string.set_static_recommended), (dialog, which) -> { |
| 1896 | + // Set to static mode with recommended settings (4MP) |
| 1897 | + applyRecommendedResolutionSettings(); |
| 1898 | + dialog.dismiss(); |
| 1899 | + // No need to check resolution - already set to 4MP |
| 1900 | + }) |
| 1901 | + .setCancelable(false) |
| 1902 | + .show(); |
| 1903 | + } else { |
| 1904 | + // Static mode - check if resolution is too high |
| 1905 | + checkStaticResolutionForHighResStabilization(); |
| 1906 | + } |
| 1907 | + } |
| 1908 | + |
| 1909 | + private void checkStaticResolutionForHighResStabilization() { |
| 1910 | + // Check if a resolution higher than 8MP is selected |
| 1911 | + boolean isHighResSelected = (rb12MPResolution != null && rb12MPResolution.isChecked()) || |
| 1912 | + (rb12_5MPResolution != null && rb12_5MPResolution.isChecked()) || |
| 1913 | + (rb12_6MPResolution != null && rb12_6MPResolution.isChecked()); |
| 1914 | + |
| 1915 | + if (isHighResSelected) { |
| 1916 | + // Show warning dialog for high resolution |
| 1917 | + new AlertDialog.Builder(this) |
| 1918 | + .setTitle(getString(R.string.high_res_resolution_warning_title)) |
| 1919 | + .setMessage(getString(R.string.high_res_resolution_warning_message)) |
| 1920 | + .setNegativeButton(getString(R.string.cancel), (dialog, which) -> { |
| 1921 | + // Cancel - uncheck high-res stabilization |
| 1922 | + cbHighResStabilization.setOnCheckedChangeListener(null); |
| 1923 | + cbHighResStabilization.setChecked(false); |
| 1924 | + setupHighResStabilizationListener(); |
| 1925 | + dialog.dismiss(); |
| 1926 | + }) |
| 1927 | + .setPositiveButton(getString(R.string.set_lower_resolution), (dialog, which) -> { |
| 1928 | + // Set to the highest available resolution <= 8MP |
| 1929 | + selectHighestAvailableResolutionUnder8MP(); |
| 1930 | + dialog.dismiss(); |
| 1931 | + }) |
| 1932 | + .setCancelable(false) |
| 1933 | + .show(); |
| 1934 | + } |
| 1935 | + } |
| 1936 | + |
| 1937 | + private void selectHighestAvailableResolutionUnder8MP() { |
| 1938 | + // Select the highest available resolution <= 8MP |
| 1939 | + if (rb8MPResolution != null && rb8MPResolution.getVisibility() == View.VISIBLE) { |
| 1940 | + rb8MPResolution.setChecked(true); |
| 1941 | + } else if (rb4MPResolution != null && rb4MPResolution.getVisibility() == View.VISIBLE) { |
| 1942 | + rb4MPResolution.setChecked(true); |
| 1943 | + } else if (rb2MPResolution != null && rb2MPResolution.getVisibility() == View.VISIBLE) { |
| 1944 | + rb2MPResolution.setChecked(true); |
| 1945 | + } else if (rb1MPResolution != null && rb1MPResolution.getVisibility() == View.VISIBLE) { |
| 1946 | + rb1MPResolution.setChecked(true); |
| 1947 | + } |
| 1948 | + } |
| 1949 | + |
| 1950 | + private void applyRecommendedResolutionSettings() { |
| 1951 | + // Set to static mode |
| 1952 | + spinnerResolutionMode.setSelection(0); |
| 1953 | + updateResolutionModeVisibility(0); |
| 1954 | + |
| 1955 | + // Set to 4MP resolution |
| 1956 | + if (rb4MPResolution != null && rb4MPResolution.getVisibility() == View.VISIBLE) { |
| 1957 | + rb4MPResolution.setChecked(true); |
| 1958 | + } else if (rb2MPResolution != null && rb2MPResolution.getVisibility() == View.VISIBLE) { |
| 1959 | + // Fallback to 2MP if 4MP not available |
| 1960 | + rb2MPResolution.setChecked(true); |
| 1961 | + } |
| 1962 | + } |
| 1963 | + |
1732 | 1964 | private void setupDebounceListeners() { |
1733 | 1965 | // Setup algorithm spinner |
1734 | 1966 | setupDebounceAlgorithmSpinner(); |
|
0 commit comments