Skip to content

Commit

Permalink
Support disabling actions (#21)
Browse files Browse the repository at this point in the history
## Changelog:

Bump android library to 1.8.0
Bump iOS library to 1.6.1
Support disabling Actions
Add GesturedeckFlutterActivity

---------

Co-authored-by: Foti Dim <[email protected]>
  • Loading branch information
rohitsangwan01 and fotiDim authored Nov 13, 2023
1 parent 1b0abae commit 12184c9
Show file tree
Hide file tree
Showing 20 changed files with 857 additions and 164 deletions.
18 changes: 12 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## 1.2.0
* Bump Android library to 1.8.0
* Bump iOS library to 1.6.1
* Support disabling actions
* Add GesturedeckFlutterActivity

## 1.1.5
* Bump android native library to 1.5.0
* Bump Android library to 1.5.0

## 1.1.4
* Bump native libraries to 1.4.0
Expand All @@ -8,14 +14,14 @@
* Update docs location

## 1.1.2
* Bump native android library to 1.3.1
* Bump Android library to 1.3.1

## 1.1.1
* update docs
* Update docs

## 1.1.0
* minor API improvements.
* use latest native SDKs.
* Minor API improvements.
* Use latest native SDKs.

## 1.0.0
* initial release.
* Initial release
33 changes: 26 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,35 @@ Integrate Gesturedeck into your Flutter app with just a few steps:

1. Initialize Gesturedeck:
```dart
var gesturedeck = Gesturedeck.initialize(
await Gesturedeck.initialize(
tapAction: () {},
swipeLeftAction: () {},
swipeRightAction: () {},
panAction: () {},
);
// Or set actions after initialization
Gesturedeck.tapAction = (){}
```

2. Start and stop Gesturedeck detection:
```dart
gesturedeck.start();
gesturedeck.stop();
Gesturedeck.start();
Gesturedeck.stop();
```

To disable a gesture action, set its corresponding parameter to null when initializing Gesturedeck, like this:

```dart
await Gesturedeck.initialize(
tapAction: null,
);
```

Alternatively, you can disable a gesture action by setting its corresponding property to null after Gesturedeck has been initialized, like this:

```dart
Gesturedeck.tapAction = null
```

### Setup GesturedeckMedia
Expand All @@ -55,7 +72,7 @@ Enhance media app controls using GesturedeckMedia:

1. Initialize GesturedeckMedia with overlay UI customization:
```dart
var gesturedeckMedia = GesturedeckMedia.initialize(
await GesturedeckMedia.initialize(
tapAction: () {},
swipeLeftAction: () {},
swipeRightAction: () {},
Expand All @@ -72,15 +89,17 @@ var gesturedeckMedia = GesturedeckMedia.initialize(

2. Start and stop GesturedeckMedia detection:
```dart
gesturedeckMedia.start();
gesturedeckMedia.stop();
GesturedeckMedia.start();
GesturedeckMedia.stop();
```

3. Customize reverse horizontal swipes:
```dart
gesturedeckMedia.reverseHorizontalSwipes = true;
GesturedeckMedia.reverseHorizontalSwipes = true;
```

To display GesturedeckMedia UI when pressing volume buttons in Android, replace `class MainActivity : FlutterActivity()` with `class MainActivity : GesturedeckFlutterActivity()` in native Android.

#### iOS only
When using the default gesture actions you need to add the `NSAppleMusicUsageDescription` key in your project's `Info` tab with a value explaining why you need this permission (e.g. `"Control music playback"`).

Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ android {
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.github.Navideck:Gesturedeck-Android:1.5.0"
implementation "com.github.Navideck:Gesturedeck-Android:1.8.0"
implementation 'com.github.Navideck:Universal-Volume:1.1.2'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.navideck.gesturedeck_flutter

import android.os.Bundle
import android.view.KeyEvent
import io.flutter.embedding.android.FlutterActivity

open class GesturedeckFlutterActivity : FlutterActivity() {
private var gesturedeckFlutterPlugin: GesturedeckFlutterPlugin? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gesturedeckFlutterPlugin = GesturedeckFlutterPlugin.instance
gesturedeckFlutterPlugin?.extendAroundNotch(this)
}

// To Take Control over VolumeKeys , and show our custom UI instead of Device VolumeDialog
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
return gesturedeckFlutterPlugin?.dispatchKeyEvent(event) ?: false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package com.navideck.gesturedeck_flutter

import android.app.Activity
import android.os.Build
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.WindowManager
import androidx.core.view.allViews
import com.navideck.gesturedeck_flutter.handlers.GesturedeckHandler
Expand All @@ -24,7 +26,6 @@ class GesturedeckFlutterPlugin : FlutterPlugin, ActivityAware {

private lateinit var flutterPluginBinding: FlutterPluginBinding
private var activityBinding: ActivityPluginBinding? = null

private var universalVolume: UniversalVolume? = null
private var gesturedeckHandler: GesturedeckHandler? = null
private var gesturedeckMediaHandler: GesturedeckMediaHandler? = null
Expand Down Expand Up @@ -67,6 +68,7 @@ class GesturedeckFlutterPlugin : FlutterPlugin, ActivityAware {
)
}


private val flutterUiListener = object : FlutterUiDisplayListener {
override fun onFlutterUiDisplayed() {
val activity = activityBinding?.activity ?: return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,75 @@ data class OverlayConfig (
)
}
}

/** Generated class from Pigeon that represents data sent in messages. */
data class GestureActionConfig (
val enableTapAction: Boolean? = null,
val enableSwipeLeftAction: Boolean? = null,
val enableSwipeRightAction: Boolean? = null,
val enablePanAction: Boolean? = null,
val enableLongPressAction: Boolean? = null

) {
companion object {
@Suppress("UNCHECKED_CAST")
fun fromList(list: List<Any?>): GestureActionConfig {
val enableTapAction = list[0] as Boolean?
val enableSwipeLeftAction = list[1] as Boolean?
val enableSwipeRightAction = list[2] as Boolean?
val enablePanAction = list[3] as Boolean?
val enableLongPressAction = list[4] as Boolean?
return GestureActionConfig(enableTapAction, enableSwipeLeftAction, enableSwipeRightAction, enablePanAction, enableLongPressAction)
}
}
fun toList(): List<Any?> {
return listOf<Any?>(
enableTapAction,
enableSwipeLeftAction,
enableSwipeRightAction,
enablePanAction,
enableLongPressAction,
)
}
}
@Suppress("UNCHECKED_CAST")
private object GesturedeckChannelCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
128.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
GestureActionConfig.fromList(it)
}
}
else -> super.readValueOfType(type, buffer)
}
}
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
when (value) {
is GestureActionConfig -> {
stream.write(128)
writeValue(stream, value.toList())
}
else -> super.writeValue(stream, value)
}
}
}

/**
* Gesturedeck
*
* Generated interface from Pigeon that represents a handler of messages from Flutter.
*/
interface GesturedeckChannel {
fun initialize(androidActivationKey: String?, iOSActivationKey: String?, autoStart: Boolean)
fun initialize(androidActivationKey: String?, iOSActivationKey: String?, autoStart: Boolean, gestureActionConfig: GestureActionConfig)
fun start()
fun stop()
fun updateActionConfig(gestureActionConfig: GestureActionConfig)

companion object {
/** The codec used by GesturedeckChannel. */
val codec: MessageCodec<Any?> by lazy {
StandardMessageCodec()
GesturedeckChannelCodec
}
/** Sets up an instance of `GesturedeckChannel` to handle messages through the `binaryMessenger`. */
@Suppress("UNCHECKED_CAST")
Expand All @@ -105,9 +160,10 @@ interface GesturedeckChannel {
val androidActivationKeyArg = args[0] as String?
val iOSActivationKeyArg = args[1] as String?
val autoStartArg = args[2] as Boolean
val gestureActionConfigArg = args[3] as GestureActionConfig
var wrapped: List<Any?>
try {
api.initialize(androidActivationKeyArg, iOSActivationKeyArg, autoStartArg)
api.initialize(androidActivationKeyArg, iOSActivationKeyArg, autoStartArg, gestureActionConfigArg)
wrapped = listOf<Any?>(null)
} catch (exception: Throwable) {
wrapped = wrapError(exception)
Expand Down Expand Up @@ -152,6 +208,25 @@ interface GesturedeckChannel {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.gesturedeck_flutter.GesturedeckChannel.updateActionConfig", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val gestureActionConfigArg = args[0] as GestureActionConfig
var wrapped: List<Any?>
try {
api.updateActionConfig(gestureActionConfigArg)
wrapped = listOf<Any?>(null)
} catch (exception: Throwable) {
wrapped = wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}
Expand All @@ -160,6 +235,11 @@ private object GesturedeckMediaChannelCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
128.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
GestureActionConfig.fromList(it)
}
}
129.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
OverlayConfig.fromList(it)
}
Expand All @@ -169,10 +249,14 @@ private object GesturedeckMediaChannelCodec : StandardMessageCodec() {
}
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
when (value) {
is OverlayConfig -> {
is GestureActionConfig -> {
stream.write(128)
writeValue(stream, value.toList())
}
is OverlayConfig -> {
stream.write(129)
writeValue(stream, value.toList())
}
else -> super.writeValue(stream, value)
}
}
Expand All @@ -184,12 +268,13 @@ private object GesturedeckMediaChannelCodec : StandardMessageCodec() {
* Generated interface from Pigeon that represents a handler of messages from Flutter.
*/
interface GesturedeckMediaChannel {
fun initialize(androidActivationKey: String?, iOSActivationKey: String?, autoStart: Boolean, reverseHorizontalSwipes: Boolean, panSensitivity: Long?, overlayConfig: OverlayConfig?)
fun initialize(androidActivationKey: String?, iOSActivationKey: String?, autoStart: Boolean, reverseHorizontalSwipes: Boolean, panSensitivity: Long?, gestureActionConfig: GestureActionConfig, overlayConfig: OverlayConfig?)
fun start()
fun stop()
fun dispose()
fun reverseHorizontalSwipes(value: Boolean)
fun setGesturedeckMediaOverlay(overlayConfig: OverlayConfig?)
fun updateActionConfig(gestureActionConfig: GestureActionConfig)

companion object {
/** The codec used by GesturedeckMediaChannel. */
Expand All @@ -209,10 +294,11 @@ interface GesturedeckMediaChannel {
val autoStartArg = args[2] as Boolean
val reverseHorizontalSwipesArg = args[3] as Boolean
val panSensitivityArg = args[4].let { if (it is Int) it.toLong() else it as Long? }
val overlayConfigArg = args[5] as OverlayConfig?
val gestureActionConfigArg = args[5] as GestureActionConfig
val overlayConfigArg = args[6] as OverlayConfig?
var wrapped: List<Any?>
try {
api.initialize(androidActivationKeyArg, iOSActivationKeyArg, autoStartArg, reverseHorizontalSwipesArg, panSensitivityArg, overlayConfigArg)
api.initialize(androidActivationKeyArg, iOSActivationKeyArg, autoStartArg, reverseHorizontalSwipesArg, panSensitivityArg, gestureActionConfigArg, overlayConfigArg)
wrapped = listOf<Any?>(null)
} catch (exception: Throwable) {
wrapped = wrapError(exception)
Expand Down Expand Up @@ -312,6 +398,25 @@ interface GesturedeckMediaChannel {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.gesturedeck_flutter.GesturedeckMediaChannel.updateActionConfig", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val gestureActionConfigArg = args[0] as GestureActionConfig
var wrapped: List<Any?>
try {
api.updateActionConfig(gestureActionConfigArg)
wrapped = listOf<Any?>(null)
} catch (exception: Throwable) {
wrapped = wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}
Expand Down
Loading

0 comments on commit 12184c9

Please sign in to comment.