0
0
mirror of https://github.com/markusfisch/BinaryEye.git synced 2024-09-19 19:42:18 +02:00

Only ask for barcode size when exporting/sharing

Because this parameter is just relevant when exporting/sharing
a raster image format.
This commit is contained in:
Markus Fisch 2024-09-17 22:27:01 +02:00
parent 8a6073291b
commit 3fee49301e
4 changed files with 113 additions and 70 deletions

View File

@ -14,6 +14,8 @@ import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.SeekBar
import android.widget.TextView
import de.markusfisch.android.binaryeye.R
import de.markusfisch.android.binaryeye.app.db
import de.markusfisch.android.binaryeye.app.hasWritePermission
@ -45,6 +47,7 @@ import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream
import java.util.Locale
import kotlin.math.max
import kotlin.math.min
class BarcodeFragment : Fragment() {
@ -107,7 +110,7 @@ class BarcodeFragment : Fragment() {
// Make sure to invoke this after ScalingImageView.onLayout().
imageView.minWidth = min(
imageView.minWidth / 2f,
barcode.size.toFloat()
max(bitmap.width, bitmap.height).toFloat()
)
}
@ -136,7 +139,6 @@ class BarcodeFragment : Fragment() {
"format cannot be null"
)
),
getInt(SIZE),
getInt(MARGIN),
getInt(EC_LEVEL),
Colors.entries[getInt(COLORS)]
@ -173,7 +175,10 @@ class BarcodeFragment : Fragment() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.add_to_history -> {
readAndAddToHistory(barcode.bitmap(), barcode.format)
readAndAddToHistory(
barcode.bitmap(),
barcode.format
)
addToHistoryItem.isVisible = false
context.toast(R.string.added_to_history)
true
@ -224,11 +229,23 @@ class BarcodeFragment : Fragment() {
// Dialogs do not have a parent view.
@SuppressLint("InflateParams")
private fun askForFileNameAndSave(fileType: FileType) {
private fun askForFileNameAndSave(fileType: FileType, size: Int = -1) {
if (size == -1) {
when (fileType) {
FileType.PNG, FileType.JPG -> {
askForSize {
askForFileNameAndSave(fileType, it)
}
return
}
else -> {}
}
}
val ac = activity ?: return
// Write permission is only required before Android Q.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q &&
!ac.hasWritePermission { askForFileNameAndSave(fileType) }
!ac.hasWritePermission { askForFileNameAndSave(fileType, size) }
) {
return
}
@ -246,14 +263,14 @@ class BarcodeFragment : Fragment() {
addSuffixIfNotGiven(fileName, ".png"),
MIME_PNG
) {
barcode.bitmap().saveAsPng(it)
barcode.bitmap(size).saveAsPng(it)
}
FileType.JPG -> saveAs(
addSuffixIfNotGiven(fileName, ".jpg"),
MIME_JPG
) {
barcode.bitmap().saveAsJpg(it)
barcode.bitmap(size).saveAsJpg(it)
}
FileType.SVG -> saveAs(
@ -276,6 +293,52 @@ class BarcodeFragment : Fragment() {
.show()
}
// Dialogs do not have a parent view.
@SuppressLint("InflateParams")
private fun askForSize(write: (size: Int) -> Unit) {
val ac = activity ?: return
val view = ac.layoutInflater.inflate(R.layout.dialog_size, null)
val sizeView = view.findViewById<TextView>(R.id.size_display)
val sizeBarView = view.findViewById<SeekBar>(R.id.size_bar)
sizeBarView.initSizeBar(sizeView)
AlertDialog.Builder(ac)
.setView(view)
.setPositiveButton(android.R.string.ok) { _, _ ->
write(getSize(sizeBarView.progress))
}
.setNegativeButton(android.R.string.cancel) { _, _ ->
}
.show()
}
private fun SeekBar.initSizeBar(sizeView: TextView) {
sizeView.updateSize(progress)
setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar,
progressValue: Int,
fromUser: Boolean
) {
sizeView.updateSize(progressValue)
}
override fun onStartTrackingTouch(seekBar: SeekBar) {}
override fun onStopTrackingTouch(seekBar: SeekBar) {}
}
)
}
private fun TextView.updateSize(power: Int) {
val size = getSize(power)
text = if (size > 0) {
getString(R.string.size_width_by_height, size, size)
} else {
getString(R.string.size_no_magnification)
}
}
private fun saveAs(
fileName: String,
mimeType: String,
@ -292,8 +355,14 @@ class BarcodeFragment : Fragment() {
private fun Context.shareAs(fileType: FileType) {
when (fileType) {
FileType.PNG -> share(barcode.bitmap(), MIME_PNG, "png")
FileType.JPG -> share(barcode.bitmap(), MIME_JPG, "jpg")
FileType.PNG -> askForSize {
share(barcode.bitmap(it), MIME_PNG, "png")
}
FileType.JPG -> askForSize {
share(barcode.bitmap(it), MIME_JPG, "jpg")
}
FileType.SVG -> shareText(barcode.svg(), MIME_SVG)
FileType.TXT -> shareText(barcode.text())
}
@ -349,7 +418,6 @@ class BarcodeFragment : Fragment() {
private const val CONTENT_TEXT = "content_text"
private const val CONTENT_RAW = "content_raw"
private const val FORMAT = "format"
private const val SIZE = "size"
private const val MARGIN = "margin"
private const val EC_LEVEL = "ec_level"
private const val COLORS = "colors"
@ -361,7 +429,6 @@ class BarcodeFragment : Fragment() {
fun <T> newInstance(
content: T,
format: BarcodeFormat,
size: Int,
margin: Int,
ecLevel: Int = -1,
colors: Int = 0
@ -383,7 +450,6 @@ class BarcodeFragment : Fragment() {
}
}
args.putString(FORMAT, format.name)
args.putInt(SIZE, size)
args.putInt(MARGIN, margin)
args.putInt(EC_LEVEL, ecLevel)
args.putInt(COLORS, colors)
@ -397,20 +463,23 @@ class BarcodeFragment : Fragment() {
private data class Barcode<T>(
val content: T,
val format: BarcodeFormat,
val size: Int,
val margin: Int,
val ecLevel: Int,
val colors: Colors
) {
private var _bitmap: Bitmap? = null
fun bitmap(): Bitmap {
val b = _bitmap ?: ZxingCpp.encodeAsBitmap(
val b = _bitmap ?: bitmap(512)
_bitmap = b
return b
}
fun bitmap(size: Int): Bitmap {
return ZxingCpp.encodeAsBitmap(
content, format, size, size, margin, ecLevel,
setColor = colors.foregroundColor(),
unsetColor = colors.backgroundColor()
)
_bitmap = b
return b
}
private var _svg: String? = null
@ -468,6 +537,11 @@ private fun encodeFileName(name: String): String = fileNameCharacters
.trim('_')
.lowercase(Locale.getDefault())
private fun getSize(step: Int) = when (step) {
0 -> 0
else -> 128 shl (step - 1)
}
private fun readAndAddToHistory(
bitmap: Bitmap,
format: BarcodeFormat

View File

@ -38,8 +38,6 @@ class EncodeFragment : Fragment() {
private lateinit var ecSpinner: Spinner
private lateinit var colorsLabel: TextView
private lateinit var colorsSpinner: Spinner
private lateinit var sizeView: TextView
private lateinit var sizeBarView: SeekBar
private lateinit var marginLayout: View
private lateinit var marginView: TextView
private lateinit var marginBarView: SeekBar
@ -178,10 +176,6 @@ class EncodeFragment : Fragment() {
colorsLabel = view.findViewById(R.id.colors_label)
colorsSpinner = view.findViewById(R.id.colors)
sizeView = view.findViewById(R.id.size_display)
sizeBarView = view.findViewById(R.id.size_bar)
initSizeBar()
marginLayout = view.findViewById(R.id.margin)
marginView = view.findViewById(R.id.margin_display)
marginBarView = view.findViewById(R.id.margin_bar)
@ -259,7 +253,6 @@ class EncodeFragment : Fragment() {
BarcodeFragment.newInstance(
content,
format,
getSize(sizeBarView.progress),
when (format) {
BarcodeFormat.AZTEC,
BarcodeFormat.DATA_MATRIX,
@ -303,33 +296,6 @@ class EncodeFragment : Fragment() {
return text
}
private fun initSizeBar() {
updateSize(sizeBarView.progress)
sizeBarView.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(
seekBar: SeekBar,
progressValue: Int,
fromUser: Boolean
) {
updateSize(progressValue)
}
override fun onStartTrackingTouch(seekBar: SeekBar) {}
override fun onStopTrackingTouch(seekBar: SeekBar) {}
})
}
private fun updateSize(power: Int) {
val size = getSize(power)
sizeView.text = if (size > 0) {
getString(R.string.size_width_by_height, size, size)
} else {
getString(R.string.size_no_magnification)
}
}
private fun initMarginBar() {
updateMargin(marginBarView.progress)
marginBarView.setOnSeekBarChangeListener(
@ -460,11 +426,6 @@ private fun Spinner.setEntries(resId: Int) = ArrayAdapter.createFromResource(
adapter = aa
}
private fun getSize(step: Int) = when (step) {
0 -> 0
else -> 128 shl (step - 1)
}
private fun InputStream.readBytesMax(max: Int): ByteArray {
var offset = 0
var remaining = min(available(), max)

View File

@ -0,0 +1,23 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/size_display"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="8dp"/>
<SeekBar
style="@style/Widget.AppCompat.SeekBar.Discrete"
android:id="@+id/size_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:progress="2"
android:max="4"/>
</LinearLayout>

View File

@ -65,21 +65,6 @@
android:id="@+id/colors"
android:layout_marginBottom="16dp"
android:entries="@array/colors"/>
<TextView
android:id="@+id/size_display"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"/>
<SeekBar
style="@style/Widget.AppCompat.SeekBar.Discrete"
android:id="@+id/size_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:progress="2"
android:max="4"/>
<LinearLayout
android:id="@+id/margin"
android:layout_width="match_parent"