Mercurial > cgi-bin > hgweb.cgi > SimpleResizer
comparison app/src/main/java/com/bartsent/simpleresizer/EditImage.kt @ 16:3ed74dc0e34a
Fix error messages, make scaling menu more user-friendly, fix return from settings.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 21 Feb 2021 21:43:54 -0800 |
parents | 20da616dcda0 |
children | eedf995462d9 |
comparison
equal
deleted
inserted
replaced
15:20da616dcda0 | 16:3ed74dc0e34a |
---|---|
16 import android.view.Menu | 16 import android.view.Menu |
17 import android.view.MenuItem | 17 import android.view.MenuItem |
18 import android.view.View | 18 import android.view.View |
19 import android.widget.EditText | 19 import android.widget.EditText |
20 import android.widget.ProgressBar | 20 import android.widget.ProgressBar |
21 import android.widget.Toast | |
21 import androidx.appcompat.app.AlertDialog | 22 import androidx.appcompat.app.AlertDialog |
22 import androidx.appcompat.app.AppCompatActivity | 23 import androidx.appcompat.app.AppCompatActivity |
23 import androidx.appcompat.widget.PopupMenu | 24 import androidx.appcompat.widget.PopupMenu |
24 import com.bartsent.simpleresizer.databinding.ActivityEditImageBinding | 25 import com.bartsent.simpleresizer.databinding.ActivityEditImageBinding |
25 import com.bartsent.simpleresizer.lib.getScaledInstance | 26 import com.bartsent.simpleresizer.lib.getScaledInstance |
76 result = uriPath?.substring(uriPath.lastIndexOf('/') + 1) | 77 result = uriPath?.substring(uriPath.lastIndexOf('/') + 1) |
77 } | 78 } |
78 return result | 79 return result |
79 } | 80 } |
80 | 81 |
81 private fun showError(message: String): Unit { | 82 private fun showFatalError(message: String): Unit { |
82 AlertDialog.Builder(this).also { | 83 AlertDialog.Builder(this).also { |
83 it.setMessage(message) | 84 it.setMessage(message) |
84 it.setNeutralButton(R.string.ok_text) { dialog, _ -> | 85 it.setNeutralButton(R.string.ok_text) { dialog, _ -> |
85 dialog.dismiss() | 86 dialog.dismiss() |
86 } | 87 } |
95 super.onResume() | 96 super.onResume() |
96 | 97 |
97 // Read the URI, die if we can't. | 98 // Read the URI, die if we can't. |
98 val imageUri = intent?.data | 99 val imageUri = intent?.data |
99 if (imageUri == null) { | 100 if (imageUri == null) { |
100 showError(getString(R.string.error_no_uri)) | 101 if (State.bitmap == null) |
102 showFatalError(getString(R.string.error_no_uri)) | |
103 else | |
104 setImage(State.bitmap!!) | |
101 return | 105 return |
102 } | 106 } |
103 | 107 |
104 // Being stateful stops data loss when the phone gets rotated. | 108 // Being stateful stops data loss when the phone gets rotated. |
105 if (imageUri != State.uri) { | 109 if (imageUri != State.uri) { |
107 State.bitmap = contentResolver.openInputStream(imageUri).use { | 111 State.bitmap = contentResolver.openInputStream(imageUri).use { |
108 BitmapFactory.decodeStream(it) | 112 BitmapFactory.decodeStream(it) |
109 } | 113 } |
110 } | 114 } |
111 if (State.bitmap == null) { | 115 if (State.bitmap == null) { |
112 showError(getString(R.string.error_bad_image)) | 116 showFatalError(getString(R.string.error_bad_image)) |
113 return | 117 return |
114 } | 118 } |
115 setImage(State.bitmap!!) | 119 setImage(State.bitmap!!) |
116 } | 120 } |
117 | 121 |
119 binding.imageSize.text = getString(R.string.image_size_text, image.width, image.height) | 123 binding.imageSize.text = getString(R.string.image_size_text, image.width, image.height) |
120 binding.image.setImageBitmap(image) | 124 binding.image.setImageBitmap(image) |
121 State.bitmap = image | 125 State.bitmap = image |
122 } | 126 } |
123 | 127 |
128 private val CUSTOM = 999998 | |
129 private val CANCEL = 999999 | |
130 | |
124 fun scaleClicked(view: View): Unit { | 131 fun scaleClicked(view: View): Unit { |
125 val maxSize = State.bitmap!!.run { maxOf(width, height) } | 132 val (maxSize, horizontal) = State.bitmap!!.run { |
133 if (width > height) Pair(width, true) else Pair(height, false) | |
134 } | |
126 PopupMenu(this, view).apply { | 135 PopupMenu(this, view).apply { |
127 menu.run { | 136 menu.run { |
128 STDDIMS.filter { it < maxSize }.forEach { add(it.toString()) } | 137 STDDIMS.filter { it < maxSize }.forEach { major -> |
129 add(getString(R.string.custom_text)) | 138 val minor = major * 3 / 4 |
130 add(getString(R.string.cancel_text)) | 139 add(Menu.NONE, major, Menu.NONE, |
140 if (horizontal) "$major ✕ $minor" else "$minor ✕ $major") | |
141 } | |
142 add(Menu.NONE, CUSTOM, Menu.NONE, R.string.custom_text) | |
143 add(Menu.NONE, CANCEL, Menu.NONE, R.string.cancel_text) | |
131 } | 144 } |
132 setOnMenuItemClickListener(::scaleMenuItemClicked) | 145 setOnMenuItemClickListener(::scaleMenuItemClicked) |
133 show() | 146 show() |
134 } | 147 } |
135 } | 148 } |
136 | 149 |
137 fun scaleMenuItemClicked(item: MenuItem) : Boolean { | 150 fun scaleMenuItemClicked(item: MenuItem) : Boolean = |
138 val itString = item.title.toString() | 151 when (item.itemId) { |
139 var itVal = itString.toIntOrNull() | 152 CUSTOM -> { showCustomScaleDialog(); true } |
140 if (itVal == null) { | 153 CANCEL -> true |
141 return when (itString) { | 154 in STDDIMS -> { doScale(item.itemId); true } |
142 getString(R.string.cancel_text) -> true | 155 else -> false |
143 getString(R.string.custom_text) -> { showCustomScaleDialog(); true } | 156 } |
144 else -> false | |
145 } | |
146 } | |
147 doScale(itVal) | |
148 return true | |
149 } | |
150 | 157 |
151 private fun copyColorSpace(old: Bitmap, new: Bitmap): Unit { | 158 private fun copyColorSpace(old: Bitmap, new: Bitmap): Unit { |
152 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { | 159 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { |
153 val oldColorSpace = old.colorSpace | 160 val oldColorSpace = old.colorSpace |
154 if (oldColorSpace != null) | 161 if (oldColorSpace != null) |
178 setImage(newBitmap) | 185 setImage(newBitmap) |
179 } | 186 } |
180 } | 187 } |
181 } | 188 } |
182 | 189 |
183 // is there any way to remember the last scale value? | |
184 // if so: should we? | |
185 | |
186 fun showCustomScaleDialog(): Unit { | 190 fun showCustomScaleDialog(): Unit { |
187 val image = State.bitmap!! | 191 val image = State.bitmap!! |
188 val curMaxDim = maxOf(image.width, image.height) | 192 val curMaxDim = maxOf(image.width, image.height) |
189 val dialogView = layoutInflater.inflate(R.layout.dialog_custom_scale, null) | 193 val dialogView = layoutInflater.inflate(R.layout.dialog_custom_scale, null) |
190 AlertDialog.Builder(this).also { | 194 AlertDialog.Builder(this).also { |
191 it.setPositiveButton(R.string.ok_text) { dialog, _ -> | 195 it.setPositiveButton(R.string.ok_text) { dialog, _ -> |
192 val maxDim = dialogView.findViewById<EditText>(R.id.custom_scale)?.text.toString().toIntOrNull() | 196 val maxDim = dialogView.findViewById<EditText>(R.id.custom_scale)?.text.toString().toIntOrNull() |
193 dialog.dismiss() | 197 dialog.dismiss() |
194 if (maxDim == null || maxDim < 8 || maxDim >= curMaxDim) { | 198 if (maxDim == null || maxDim < 8 || maxDim >= curMaxDim) { |
195 AlertDialog.Builder(this).also { | 199 Toast.makeText(applicationContext, R.string.bad_scale, Toast.LENGTH_LONG).show() |
196 it.setMessage(R.string.bad_scale) | |
197 it.setNeutralButton(R.string.ok_text) { dialog, _ -> | |
198 dialog.dismiss() | |
199 } | |
200 it.create() | |
201 }.show() | |
202 } else { | 200 } else { |
203 doScale(maxDim) | 201 doScale(maxDim) |
204 } | 202 } |
205 } | 203 } |
206 it.setNegativeButton(R.string.cancel_text) { dialog, _ -> | 204 it.setNegativeButton(R.string.cancel_text) { dialog, _ -> |
306 if (!State.bitmap!!.compress(Bitmap.CompressFormat.JPEG, quality, it)) { | 304 if (!State.bitmap!!.compress(Bitmap.CompressFormat.JPEG, quality, it)) { |
307 throw IOException(getString(R.string.error_save_bitmap)) | 305 throw IOException(getString(R.string.error_save_bitmap)) |
308 } | 306 } |
309 } | 307 } |
310 } catch (ioe: IOException) { | 308 } catch (ioe: IOException) { |
311 showError(ioe.message ?: getString(R.string.error_io)) | 309 Toast.makeText(applicationContext, ioe.message ?: getString(R.string.error_io), Toast.LENGTH_LONG).show() |
312 } | 310 } |
313 finish() | 311 finish() |
314 } | 312 } |
315 } | 313 } |