@@ -3,6 +3,8 @@ package com.fredhappyface.ewesticker
33import android.content.SharedPreferences
44import android.inputmethodservice.InputMethodService
55import android.os.Build.VERSION.SDK_INT
6+ import android.view.GestureDetector
7+ import android.view.MotionEvent
68import android.view.View
79import android.view.ViewGroup
810import android.view.inputmethod.EditorInfo
@@ -28,8 +30,11 @@ import com.fredhappyface.ewesticker.utilities.StickerClickListener
2830import com.fredhappyface.ewesticker.utilities.StickerSender
2931import com.fredhappyface.ewesticker.utilities.Toaster
3032import java.io.File
33+ import kotlin.math.abs
3134import kotlin.math.min
3235
36+ private const val SWIPE_THRESHOLD = 1
37+ private const val SWIPE_VELOCITY_THRESHOLD = 1
3338
3439/* *
3540 * ImageKeyboard class inherits from the InputMethodService class - provides the keyboard
@@ -41,6 +46,7 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
4146 private lateinit var sharedPreferences: SharedPreferences
4247 private var restoreOnClose = false
4348 private var vertical = false
49+ private var scroll = false
4450 private var iconsPerX = 0
4551 private var iconSize = 0
4652
@@ -67,6 +73,9 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
6773 private var keyboardHeight = 0
6874 private var fullIconSize = 0
6975
76+ private lateinit var gestureDetector: GestureDetector
77+
78+
7079 /* *
7180 * When the activity is created...
7281 * - ensure coil can decode (and display) animated images
@@ -94,6 +103,7 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
94103 this .sharedPreferences = PreferenceManager .getDefaultSharedPreferences(baseContext)
95104 this .restoreOnClose = this .sharedPreferences.getBoolean(" restoreOnClose" , false )
96105 this .vertical = this .sharedPreferences.getBoolean(" vertical" , false )
106+ this .scroll = this .sharedPreferences.getBoolean(" scroll" , false )
97107 this .iconsPerX = this .sharedPreferences.getInt(" iconsPerX" , 3 )
98108 this .totalIconPadding =
99109 (resources.getDimension(R .dimen.sticker_padding) * 2 * (this .iconsPerX + 1 )).toInt()
@@ -141,6 +151,7 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
141151 */
142152 override fun onCreateInputView (): View {
143153 val keyboardLayout = View .inflate(baseContext, R .layout.keyboard_layout, null )
154+ gestureDetector = GestureDetector (baseContext, GestureListener ())
144155
145156 this .keyboardRoot = keyboardLayout.findViewById(R .id.keyboardRoot)
146157 this .packsList = keyboardLayout.findViewById(R .id.packsList)
@@ -228,7 +239,7 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
228239 stickers = loadedPacks[packName]?.stickerList ? : return
229240 }
230241 val recyclerView = RecyclerView (this )
231- val adapter = StickerPackAdapter (iconSize, stickers, this )
242+ val adapter = StickerPackAdapter (iconSize, stickers, this , gestureDetector )
232243 val layoutManager = GridLayoutManager (
233244 this ,
234245 iconsPerX,
@@ -320,6 +331,76 @@ class ImageKeyboard : InputMethodService(), StickerClickListener {
320331 fSticker.setOnClickListener { this .keyboardRoot.removeView(fullStickerLayout) }
321332 this .keyboardRoot.addView(fullStickerLayout)
322333 }
334+
335+ internal fun switchToPreviousPack () {
336+ // Get a list of sorted pack names
337+ val sortedPackNames = loadedPacks.keys.sorted()
338+
339+ // Find the index of the current active pack
340+ val currentIndex = sortedPackNames.indexOf(activePack)
341+
342+ // Calculate the index of the previous pack, considering wrap-around
343+ val previousIndex = if (currentIndex > 0 ) currentIndex - 1 else sortedPackNames.size - 1
344+
345+ // Get the name of the previous pack
346+ val previousPack = sortedPackNames[previousIndex]
347+
348+ // Switch to the previous pack layout
349+ switchPackLayout(previousPack)
350+ }
351+
352+ internal fun switchToNextPack () {
353+ // Get a list of sorted pack names
354+ val sortedPackNames = loadedPacks.keys.sorted()
355+
356+ // Find the index of the current active pack
357+ val currentIndex = sortedPackNames.indexOf(activePack)
358+
359+ // Calculate the index of the next pack, considering wrap-around
360+ val nextIndex = (currentIndex + 1 ) % sortedPackNames.size
361+
362+ // Get the name of the next pack
363+ val nextPack = sortedPackNames[nextIndex]
364+
365+ // Switch to the next pack layout
366+ switchPackLayout(nextPack)
367+ }
368+
369+
370+ private inner class GestureListener : GestureDetector .SimpleOnGestureListener () {
371+ override fun onDown (e : MotionEvent ): Boolean {
372+ return false
373+ }
374+
375+ override fun onScroll (
376+ e1 : MotionEvent ,
377+ e2 : MotionEvent ,
378+ velocityX : Float ,
379+ velocityY : Float
380+ ): Boolean {
381+ val diffX = e2.x - e1.x
382+ val diffY = e2.y - e1.y
383+
384+ if (
385+ scroll &&
386+ abs(if (vertical) diffX else diffY) > SWIPE_THRESHOLD &&
387+ abs(if (vertical) velocityX else velocityY) > SWIPE_VELOCITY_THRESHOLD
388+ ) {
389+ if (diffX > 0 ) {
390+ // Swipe right
391+ switchToPreviousPack()
392+ } else {
393+ // Swipe left
394+ switchToNextPack()
395+ }
396+ return true
397+ }
398+
399+ return false
400+ }
401+ }
402+
403+
323404}
324405
325406fun trimString (str : String ): String {
@@ -328,3 +409,4 @@ fun trimString(str: String): String {
328409 }
329410 return str
330411}
412+
0 commit comments