Mobile App Dev 2021W: Tutorial 8

From Soma-notes
Revision as of 15:18, 29 March 2021 by Soma (talk | contribs) (Created page with "'''This tutorial is still being developed.''' ==Code== [https://homeostasis.scs.carleton.ca/~soma/mad-2021w/code/PicViewer2A.zip PicViewer2A.zip] ===MainActivity.kt=== <sy...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This tutorial is still being developed.

Code

PicViewer2A.zip

MainActivity.kt

package carleton.comp1601.picviewer2a

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.ImageView

val appName = "PicViewer2A"

class MainActivity : AppCompatActivity() {
    private lateinit var p: ImageView
    private var pic = R.drawable.kittens
    private var r = 0F
    private var scale = 1F
    private var pX = 0F
    private lateinit var rotationInput: EditText
    private lateinit var scaleInput: EditText
    private lateinit var pXInput: EditText
    private lateinit var pYInput: EditText

    val Y = PicWatcher("Y", 0F, ::updateImage)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        if (savedInstanceState != null) {
            // do something
        }

        p = findViewById(R.id.mypic)

        rotationInput = findViewById(R.id.rotation)
        rotationInput.setText(String.format("%.0f", r))
        rotationInput.addTextChangedListener(rotationWatcher)

        scaleInput = findViewById(R.id.scale)
        scaleInput.addTextChangedListener(scaleWatcher)

        pXInput = findViewById(R.id.x)
        pXInput.addTextChangedListener(pXWatcher)

        pYInput = findViewById(R.id.y)
        pYInput.addTextChangedListener(Y)

        updateImage()
        Log.d(appName, "Activity Created")
    }

    fun updateImage() {
        p.setImageResource(pic)
        p.setX(pX)
        p.setY(Y.value)
        p.setRotation(r)
        p.setScaleX(scale)
        p.setScaleY(scale)
    }

    fun toggleImage(v: View) {
        if (pic == R.drawable.roshi) {
            pic = R.drawable.kittens
        } else {
            pic = R.drawable.roshi
        }
        updateImage()
    }

    private val rotationWatcher = object : TextWatcher {
        override fun afterTextChanged(s: Editable) {
            val new_rS = rotationInput.getText().toString()
            val new_r = new_rS.toFloatOrNull()

            if (new_r != null) {
                r = new_r
                Log.d(appName, "New rotation is ${new_r}")
            } else {
                r = 0F
                Log.d(appName, "Rotation is ${r}")
            }
            updateImage()
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        }
    }

    private val scaleWatcher = object : TextWatcher {
        override fun afterTextChanged(s: Editable) {
            val new_scaleS = scaleInput.getText().toString()
            val new_scale = new_scaleS.toFloatOrNull()

            if (new_scale != null) {
                if (new_scale > 10F) {
                    scale = 10F
                } else if (new_scale < 0F) {
                    scale = 0F
                } else {
                    scale = new_scale
                }
                Log.d(appName, "Set scale to ${new_scale}")
                updateImage()
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        }
    }

    private val pXWatcher = object : TextWatcher {
        override fun afterTextChanged(s: Editable) {
            val new_xS = pXInput.getText().toString()
            val new_x = new_xS.toFloatOrNull()

            if (new_x != null) {
                pX = new_x
                Log.d(appName, "Set X to ${new_x}")
                updateImage()
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        }
    }
}

class PicWatcher: TextWatcher {
    var value: Float
    var name: String
    var update: () -> Unit

    override fun afterTextChanged(s: Editable) {
        val new_value = s.toString().toFloatOrNull()

        if (new_value != null) {
            value = new_value
            Log.d(appName, "Set ${name} to ${value} (wow).")
            update()
        }
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    constructor(n: String, v: Float, u: () -> Unit) {
        value = v
        name = n
        update = u
    }
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/mypic"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="0dp"
        android:layout_marginTop="0dp"
        android:layout_marginEnd="0dp"
        android:layout_marginBottom="20dp"
        android:onClick="toggleImage"
        app:layout_constraintBottom_toTopOf="@+id/rotation"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/kittens" />

    <EditText
        android:id="@+id/rotation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="5"
        android:inputType="number"
        app:layout_constraintBottom_toTopOf="@+id/scale"
        app:layout_constraintStart_toStartOf="@+id/scale" />

    <EditText
        android:id="@+id/scale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="5"
        android:inputType="numberDecimal"
        app:layout_constraintBottom_toTopOf="@+id/x"
        app:layout_constraintStart_toStartOf="@+id/x" />

    <EditText
        android:id="@+id/x"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="5"
        android:inputType="number"
        app:layout_constraintBottom_toTopOf="@+id/y"
        app:layout_constraintStart_toStartOf="@+id/y" />

    <EditText
        android:id="@+id/y"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        android:ems="5"
        android:inputType="number"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/ylabel" />

    <TextView
        android:id="@+id/rotationlabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="12dp"
        android:text="rotation"
        android:textStyle="bold"
        app:layout_constraintBaseline_toBaselineOf="@+id/rotation"
        app:layout_constraintEnd_toStartOf="@+id/rotation"
        />

    <TextView
        android:id="@+id/scalelabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="12dp"
        android:layout_marginBottom="11dp"
        android:text="scale"
        android:textStyle="bold"
        app:layout_constraintBaseline_toBaselineOf="@+id/scale"
        app:layout_constraintEnd_toStartOf="@+id/scale" />

    <TextView
        android:id="@+id/xlabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="12dp"
        android:text="X"
        android:textStyle="bold"
        app:layout_constraintBaseline_toBaselineOf="@+id/x"
        app:layout_constraintEnd_toStartOf="@+id/x" />

    <TextView
        android:id="@+id/ylabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="12dp"
        android:text="Y"
        android:textStyle="bold"
        app:layout_constraintBaseline_toBaselineOf="@+id/y"
        app:layout_constraintEnd_toStartOf="@+id/y" />

</androidx.constraintlayout.widget.ConstraintLayout>