Mobile App Dev 2021W: Tutorial 8

From Soma-notes
Revision as of 11: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)
Jump to navigation Jump to search

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>