From bb644807f3c3f48b640dc496c3509568aa1d8412 Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 27 Jul 2017 13:14:07 +0800 Subject: [PATCH] + extras: DSL for navigating between activities #62 --- .../macroid/extras/UIActionsExtras.scala | 262 +++++++++++++++++- 1 file changed, 259 insertions(+), 3 deletions(-) diff --git a/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala b/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala index 352ab1f..802d7c1 100644 --- a/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala +++ b/macroid-extras/src/main/scala/macroid/extras/UIActionsExtras.scala @@ -1,9 +1,10 @@ package macroid.extras -import android.content.Context -import android.os.{ Handler, Vibrator } +import android.app.Activity +import android.content.{Context, Intent} +import android.os._ import android.widget.Toast -import macroid.{ ContextWrapper, Ui } +import macroid.{ContextWrapper, Ui} object UIActionsExtras { @@ -40,6 +41,261 @@ object UIActionsExtras { } } + private def readArray[A](source: Parcel, build: Int => Array[A], read: Parcel => A) = { + val N = source.readInt() + val array = build(N) + for { + i <- 0 until N + } array(i) = read(source) + array + } + + class Ints(val get: Array[Int]) extends Parcelable { + + + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(dest.writeInt) + } + } + + object Ints { + def apply(array: Int*) { + new Ints(array.toArray) + } + val CREATOR: Parcelable.Creator[Ints] = new Parcelable.Creator[Ints] { + + override def createFromParcel(source: Parcel): Ints = new Ints({ + source.createIntArray() + }) + + override def newArray(size: Int): Array[Ints] = new Array[Ints](size) + } + } + + + class Bytes(val get: Array[Byte]) extends Parcelable { + + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(dest.writeByte) + } + } + + object Bytes { + def apply(array: Byte*) { + new Bytes(array.toArray) + } + val CREATOR: Parcelable.Creator[Bytes] = new Parcelable.Creator[Bytes] { + + override def createFromParcel(source: Parcel): Bytes = new Bytes({ + readArray(source, N => new Array[Byte](N), _.readByte()) + }) + + override def newArray(size: Int): Array[Bytes] = new Array[Bytes](size) + } + } + + class Doubles(val get: Array[Double]) extends Parcelable { + + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(dest.writeDouble) + } + } + + object Doubles { + def apply(array: Double*) { + new Doubles(array.toArray) + } + val CREATOR: Parcelable.Creator[Doubles] = new Parcelable.Creator[Doubles] { + + override def createFromParcel(source: Parcel): Doubles = new Doubles({ + readArray(source, N => new Array[Double](N), _.readDouble()) + }) + + override def newArray(size: Int): Array[Doubles] = new Array[Doubles](size) + } + } + + class Floats(val get: Array[Float]) extends Parcelable { + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(dest.writeFloat) + } + } + + object Floats { + def apply(array: Float*) { + new Floats(array.toArray) + } + + val CREATOR: Parcelable.Creator[Floats] = new Parcelable.Creator[Floats] { + + override def createFromParcel(source: Parcel): Floats = new Floats({ + readArray(source, N => new Array[Float](N), _.readFloat()) + }) + + override def newArray(size: Int): Array[Floats] = new Array[Floats](size) + } + } + + class Longs(val get: Array[Long]) extends Parcelable { + + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(dest.writeLong) + } + } + + object Longs { + def apply(array: Long*) { + new Longs(array.toArray) + } + + val CREATOR: Parcelable.Creator[Longs] = new Parcelable.Creator[Longs] { + + override def createFromParcel(source: Parcel): Longs = new Longs({ + readArray(source, N => new Array[Long](N), _.readLong()) + }) + + override def newArray(size: Int): Array[Longs] = new Array[Longs](size) + } + } + + class Booleans(val get: Array[Boolean]) extends Parcelable { + + + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(c => dest.writeInt(if (c) 1 else 0)) + } + } + + object Booleans { + def apply(array: Boolean*) { + new Booleans(array.toArray) + } + val CREATOR: Parcelable.Creator[Booleans] = new Parcelable.Creator[Booleans] { + + override def createFromParcel(source: Parcel): Booleans = new Booleans({ + readArray(source, N => new Array[Boolean](N), _.readInt() != 0) + }) + + override def newArray(size: Int): Array[Booleans] = new Array[Booleans](size) + } + } + + class Chars(val get: Array[Char]) extends Parcelable { + // def this(array: Char*) { + // this(array.toArray) + // } + + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(c => dest.writeInt(c)) + } + } + + object Chars { + val CREATOR: Parcelable.Creator[Chars] = new Parcelable.Creator[Chars] { + + override def createFromParcel(source: Parcel): Chars = new Chars( + readArray(source, N => new Array[Char](N), _.readInt.toChar) + ) + + override def newArray(size: Int): Array[Chars] = new Array[Chars](size) + } + } + + class Strings(val get: Array[String]) extends Parcelable { + override def describeContents() = 0 + + override def writeToParcel(dest: Parcel, flags: Int) { + dest.writeInt(get.length) + get.foreach(dest.writeString) + } + } + + object Strings { + + def apply(array:String*) ={ + new Strings(array.toArray) + } + + val CREATOR: Parcelable.Creator[Strings] = new Parcelable.Creator[Strings] { + override def createFromParcel(source: Parcel): Strings = + new Strings(readArray(source, n => new Array[String](n), _.readString)) + + + override def newArray(size: Int): Array[Strings] = new Array[Strings](size) + } + } + + implicit class IntentVisitor(value: Any) { + def putExtra(intent: Intent, key: String): Unit = { + value match { + case v: Short => intent.putExtra(key, v) + case v: Int => intent.putExtra(key, v) + case v: Byte => intent.putExtra(key, v) + case v: Double => intent.putExtra(key, v) + case v: Float => intent.putExtra(key, v) + case v: Long => intent.putExtra(key, v) + case v: String => intent.putExtra(key, v) + case v: Boolean => intent.putExtra(key, v) + case v: Char => intent.putExtra(key, v) + case v: CharSequence => intent.putExtra(key, v) + case v: Serializable => intent.putExtra(key, v) + case v: Bundle => intent.putExtra(key, v) + case v: Parcelable => intent.putExtra(key, v) + case v => throw new IllegalArgumentException(s"Please don't put ${v.getClass} into the extra") + } + } + } + + /** + * example: goto(classOf[TuningActivity], i => i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), "ID" -> 1) + * + * @param cls class of the activity + * @param configFn extra config steps(add flags) + * @param extra the extra key value pair + * @param context context + * @return Ui action that can navigate to the class of the Activity + */ + def goto(cls: Class[_ <: Activity], configFn: Intent => Unit, extra: (String, Any)*)(implicit context: ContextWrapper): Ui[Unit] = { + val intent = new Intent(context.getOriginal, cls) + extra.foreach(elem => elem._2.putExtra(intent, elem._1)) + configFn(intent) + Ui(context.getOriginal.startActivity(intent)) + } + + /** + * example: goto(classOf[TuningActivity], i => i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), "ID" -> 1) + * + * @param cls class of the activity + * @param extra the extra key value pair + * @param context context + * @return Ui action that can navigate to the class of the Activity + */ + def goto(cls: Class[_ <: Activity], extra: (String, Any)*)(implicit context: ContextWrapper): Ui[Unit] = { + val intent = new Intent(context.getOriginal, cls) + extra.foreach(elem => elem._2.putExtra(intent, elem._1)) + Ui(context.getOriginal.startActivity(intent)) + } } object ActionsExtras {