Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions app/src/main/java/com/knowre/android/kal/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import com.google.android.material.snackbar.Snackbar
import com.knowre.android.kal.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
Expand All @@ -27,10 +26,6 @@ class MainActivity : AppCompatActivity() {
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)

binding.fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG).setAction("Action", null).show()
}
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.knowre.android.kal.myscript


internal sealed class Candidate {

class Data(val itemId: String, val label: String) : Candidate()

class Exit() : Candidate()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.knowre.android.kal.myscript

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.knowre.android.kal.databinding.ViewCandidateItemBinding


internal class CandidateAdapter(
private val onCandidateClicked: (Candidate.Data) -> Unit,
private val onExitClicked: () -> Unit
) : RecyclerView.Adapter<CandidateViewHolder>() {

private var candidates = listOf<Candidate>()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CandidateViewHolder {
return CandidateViewHolder.newInstance(parent,
onCandidateClicked = {
clear()
onCandidateClicked(it)
},
onExitClicked = {
clear()
onExitClicked()
}
)
}

override fun onBindViewHolder(holder: CandidateViewHolder, position: Int) {
holder.bind(candidates[position])
}

override fun getItemCount() = candidates.size

fun setCandidates(candidates: List<Candidate>) {
this.candidates = candidates
.toMutableList()
.apply { if (isNotEmpty()) add(Candidate.Exit()) }
.also { notifyDataSetChanged() }
}

fun clear() {
this.candidates = listOf()
notifyDataSetChanged()
}
}

internal class CandidateViewHolder(
private val binding: ViewCandidateItemBinding
) : RecyclerView.ViewHolder(binding.root) {

private lateinit var candidate: Candidate

fun bind(candidate: Candidate) {
this.candidate = candidate
when (candidate) {
is Candidate.Data -> binding.candidateText.text = candidate.label
is Candidate.Exit -> {
binding.candidateText.text = "X"
}
}
}

companion object {
fun newInstance(
parent: ViewGroup,
onCandidateClicked: (Candidate.Data) -> Unit,
onExitClicked: () -> Unit
): CandidateViewHolder {
return CandidateViewHolder(ViewCandidateItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)).apply {
binding.root.setOnClickListener {
if (candidate is Candidate.Data) {
onCandidateClicked(candidate as Candidate.Data)
} else {
onExitClicked()
}
}
}
}
}
}
142 changes: 97 additions & 45 deletions app/src/main/java/com/knowre/android/kal/myscript/MyScriptPadView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@ package com.knowre.android.kal.myscript

import android.content.Context
import android.content.res.AssetManager
import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.Color
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.widget.FrameLayout
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel
import com.knowre.android.kal.databinding.ViewMyscriptPadBinding
import com.knowre.android.myscript.iink.FolderProvider
import com.knowre.android.myscript.iink.MyScriptApi
import com.knowre.android.myscript.iink.MyScriptAssetResource
import com.knowre.android.myscript.iink.MyScriptInitializer
import com.knowre.android.myscript.iink.MyScriptInterpretListener
import com.knowre.android.myscript.iink.ToolFunction
import com.knowre.android.myscript.iink.ToolType
import com.knowre.android.myscript.iink.certificate.MyCertificate
import com.myscript.iink.Editor
import com.myscript.iink.EditorError
import kotlinx.coroutines.MainScope
Expand All @@ -32,65 +37,84 @@ internal class MyScriptPadView constructor(

private val mainScope = MainScope()

private lateinit var myscript: MyScriptApi
private lateinit var myScript: MyScriptApi

private val candidateAdapter = CandidateAdapter(
onCandidateClicked = { candidate -> },
onExitClicked = {}
)

init {
MyScriptInitializer(
certificate = MyCertificate.getBytes(),
editorView = binding.myScript.editorView,
context = context,
folders = FolderProvider(context),
assetResource = MyScriptAssetResource(context),
scope = mainScope
)
.setGeneralConfiguration()
.setMathConfiguration()
.initialize {
myscript = it.apply {
listener = object : MyScriptInterpretListener {
override fun onInterpreted(interpreted: String) {
binding.latex.text = interpreted
mainScope.launch {
binding.redo.isEnabled = myscript.canRedo
binding.undo.isEnabled = myscript.canUndo
}
}

override fun onError(editor: Editor, blockId: String, error: EditorError, message: String) {
Log.d("MY_SCRIPT_ERROR", "$error with message $message")
}
}
}
initializeMyScript()
initializeRecyclerView()
initializeToolsListener()
}

override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
mainScope.cancel()
}

private fun initializeMyScript() {
mainScope.launch {
myScript = MyScriptInitializer(
myScriptView = binding.myScriptView,
context = context,
scope = mainScope
)
.initialize()
.apply { addListener(interpretListener) }
.apply { isAutoConvertEnabled = false }
}
}

private fun initializeRecyclerView() {
with(binding.candidate) {
adapter = candidateAdapter
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
background = MaterialShapeDrawable(
ShapeAppearanceModel.Builder()
.setAllCornerSizes(8F.dp)
.build()
).apply {
tintList = ColorStateList.valueOf(Color.parseColor("#FFFFFF"))
strokeWidth = 1F.dp
strokeColor = ColorStateList.valueOf(Color.parseColor("#CFD8DC"))
elevation = 4F.dp
}
}
}

private fun initializeToolsListener() {
binding.redo.isEnabled = false
binding.undo.isEnabled = false

binding.convert.setOnClickListener { myscript.convert() }
binding.deleteAll.setOnClickListener { myscript.eraseAll() }
binding.deleteAll.setOnClickListener { myScript.eraseAll() }
binding.digitOnlyGrammar.setOnClickListener {
myscript.loadMathGrammar("n_digit_exp", context.assets.toByteArray("n_digit_exp.res"))
myScript.loadMathGrammar("n_digit_exp", context.assets.toByteArray("n_digit_exp.res"))
}

binding.defaultGrammar.setOnClickListener {
//TODO
}

binding.red.setOnClickListener {
myscript.penColor = 0xFF0000
myScript.penColor = 0xFF0000
}

binding.blue.setOnClickListener {
myscript.penColor = 0x0000FF
myScript.penColor = 0x0000FF
}

binding.black.setOnClickListener {
myscript.penColor = 0x000000
myScript.penColor = 0x000000
}

binding.convert.setOnClickListener { myScript.convert() }

binding.penSwitch.setOnCheckedChangeListener { _, isChecked ->
binding.eraserSwitch.isChecked = false
myscript.tool = if (isChecked) {
myScript.tool = if (isChecked) {
MyScriptApi.Tool(
toolType = ToolType.PEN,
toolFunction = ToolFunction.DRAWING
Expand All @@ -104,32 +128,60 @@ internal class MyScriptPadView constructor(
}

binding.convertSwitch.setOnCheckedChangeListener { _, isChecked ->
myscript.isAutoConvertEnabled = isChecked
myScript.isAutoConvertEnabled = isChecked
}

binding.eraserSwitch.setOnCheckedChangeListener { _, isChecked ->
val toolType = if (binding.penSwitch.isChecked) ToolType.PEN else ToolType.HAND
if (isChecked) {
myscript.tool = MyScriptApi.Tool(toolType, ToolFunction.ERASING)
myScript.tool = MyScriptApi.Tool(toolType, ToolFunction.ERASING)
} else {
myscript.tool = MyScriptApi.Tool(toolType, ToolFunction.DRAWING)
myScript.tool = MyScriptApi.Tool(toolType, ToolFunction.DRAWING)
}
}

binding.redo.setOnClickListener {
myscript.redo()
myScript.redo()
}

binding.undo.setOnClickListener {
myscript.undo()
myScript.undo()
}

binding.candidateSwitch.setOnCheckedChangeListener { _, isChecked -> }
}

override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
mainScope.cancel()
private val interpretListener: MyScriptInterpretListener
get() = object : MyScriptInterpretListener {
override fun onInterpreted(interpreted: String) {
binding.latex.text = interpreted
binding.redo.isEnabled = myScript.canRedo
binding.undo.isEnabled = myScript.canUndo
}

override fun onInterpretError(editor: Editor, blockId: String, error: EditorError, message: String) {
Log.d("MY_SCRIPT_ERROR", "$error with message $message")
}

override fun onImportError() {
Toast
.makeText(context, "해당 문자로는 변경이 불가능합니다.", Toast.LENGTH_SHORT)
.show()
}
}

private fun showNoCandidateAvailable() {
Toast
.makeText(context, "No candidates available.", Toast.LENGTH_SHORT)
.show()
}

private fun AssetManager.toByteArray(fileName: String) = open(fileName).use { it.readBytes() }

private val Number.dp: Float
get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
toFloat(),
Resources.getSystem().displayMetrics
)
}
9 changes: 0 additions & 9 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,6 @@

</com.google.android.material.appbar.AppBarLayout>

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_gravity="bottom|end"
app:srcCompat="@android:drawable/ic_dialog_email" />

<include layout="@layout/content_main" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
20 changes: 3 additions & 17 deletions app/src/main/res/layout/fragment_first.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,17 @@
android:id="@+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:layout_marginTop="50dp"
android:text="@string/next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />


<TextView
android:id="@+id/textview_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:background="#ffff00"
android:text="@string/hello_first_fragment"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.knowre.android.kal.myscript.MyScriptPadView
android:id="@+id/my_script_pad"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_marginTop="100dp"
android:background="#44333345"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Loading