diff options
Diffstat (limited to 'apps/fxlab/app/src/main/kotlin/com/mobileer/androidfxlab/EffectsAdapter.kt')
-rw-r--r-- | apps/fxlab/app/src/main/kotlin/com/mobileer/androidfxlab/EffectsAdapter.kt | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/apps/fxlab/app/src/main/kotlin/com/mobileer/androidfxlab/EffectsAdapter.kt b/apps/fxlab/app/src/main/kotlin/com/mobileer/androidfxlab/EffectsAdapter.kt new file mode 100644 index 00000000..bccefa01 --- /dev/null +++ b/apps/fxlab/app/src/main/kotlin/com/mobileer/androidfxlab/EffectsAdapter.kt @@ -0,0 +1,210 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mobileer.androidfxlab + +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.SeekBar +import android.widget.TextView +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.switchmaterial.SwitchMaterial +import com.mobileer.androidfxlab.datatype.Effect +import java.util.* +import kotlin.concurrent.timerTask +import kotlin.math.max +import kotlin.math.min + +object EffectsAdapter : + RecyclerView.Adapter<EffectsAdapter.EffectsHolder>() { + val effectList = arrayListOf<Effect>() + lateinit var mRecyclerView: RecyclerView + + // This class adapts view in effect_view.xml for Effect class + class EffectsHolder(val parentView: ViewGroup) : RecyclerView.ViewHolder(parentView) { + private val layoutContainer: LinearLayout = parentView.findViewById(R.id.effectContainer) + lateinit var effect: Effect + private val floatFormat = "%4.2f" + private var index: Int = -1 + fun bindEffect(bindedEffect: Effect, position: Int) { + effect = bindedEffect + index = position + // Clear all views + layoutContainer.removeAllViews() + View.inflate(layoutContainer.context, + R.layout.effect_header, layoutContainer) + val header: LinearLayout = layoutContainer.findViewById(R.id.effectHeader) + val dragHandleView: View = header.findViewById(R.id.cat_card_list_item_drag_handle) + val checkBoxView: SwitchMaterial = header.findViewById(R.id.effectEnabled) + val label: TextView = header.findViewById(R.id.effectLabel) + // Bind header views + label.text = effect.name + checkBoxView.isChecked = effectList[index].enable + checkBoxView.setOnCheckedChangeListener { _, checked -> + effectList[index].enable = checked + NativeInterface.enableEffectAt(checked, index) + } + dragHandleView.setOnTouchListener { _, event -> + if (event.action == MotionEvent.ACTION_DOWN) { + itemTouchHelper.startDrag(this@EffectsHolder) + return@setOnTouchListener true + } + false + } + header.setOnTouchListener { _, event -> + if (event.action == MotionEvent.ACTION_DOWN) { + itemTouchHelper.startSwipe(this@EffectsHolder) + return@setOnTouchListener true + } + false + } + // Add correct number of SeekBars based on effect + for (ind in effect.effectDescription.paramValues.withIndex()) { + val param = ind.value + val counter = ind.index + val view = View.inflate(layoutContainer.context, + R.layout.param_seek, null) + layoutContainer.addView(view) + val paramWrapper: LinearLayout = view.findViewById(R.id.paramWrapper) + val paramLabelView: TextView = paramWrapper.findViewById(R.id.paramLabel) + val minLabelView: TextView = paramWrapper.findViewById(R.id.minLabel) + val maxLabelView: TextView = paramWrapper.findViewById(R.id.maxLabel) + val curLabelView: TextView = paramWrapper.findViewById(R.id.curLabel) + val seekBar: SeekBar = paramWrapper.findViewById(R.id.seekBar) + paramLabelView.text = param.paramName + minLabelView.text = floatFormat.format(param.minValue) + maxLabelView.text = floatFormat.format(param.maxValue) + seekBar.progress = + ((effectList[index].paramValues[counter] - param.minValue) * 100 / (param.maxValue + - param.minValue)).toInt() + curLabelView.text = floatFormat.format(effectList[index].paramValues[counter]) + // Bind param listeners to effects + seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { + val paramInd = counter + var timer : Timer? = null + + override fun onStartTrackingTouch(p0: SeekBar?) {} + + override fun onStopTrackingTouch(seekbar: SeekBar?) {} + + override fun onProgressChanged( + seekBar: SeekBar?, progress: Int, fromUser: Boolean + ) { + val fracprogress = + ((seekBar!!.progress / 100f) * (param.maxValue - param.minValue) + param.minValue) + curLabelView.text = floatFormat.format(fracprogress) + + timer?.cancel() + timer = Timer() + timer?.schedule(timerTask { updateEffectParam(fracprogress) }, 100) + } + + fun updateEffectParam(fracprogress : Float){ + effectList[index].paramValues[paramInd] = fracprogress + NativeInterface.updateParamsAt(effect, index) + } + }) + } + } + + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): EffectsHolder { + val myView = LayoutInflater.from(parent.context) + .inflate(R.layout.effect_view, parent, false) + return EffectsHolder(myView as ViewGroup) + } + + override fun onBindViewHolder(holder: EffectsHolder, position: Int) { + holder.bindEffect(effectList[position], position) + } + + override fun getItemCount() = effectList.size + + override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { + super.onAttachedToRecyclerView(recyclerView) + mRecyclerView = recyclerView + itemTouchHelper.attachToRecyclerView(mRecyclerView) + } + + private val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback( + ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT + ) { + + var dragFrom = -1 + var dragTo = -1 + override fun onMove( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + target: RecyclerView.ViewHolder + ): Boolean { + + val fromPos = viewHolder.adapterPosition + val toPos = target.adapterPosition + if (dragFrom == -1) { + dragFrom = fromPos + } + dragTo = toPos + effectList.add(toPos, effectList.removeAt(fromPos)) + recyclerView.adapter?.notifyItemMoved(fromPos, toPos) + return true + } + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + val position = viewHolder.adapterPosition + effectList.removeAt(position) + mRecyclerView.adapter?.notifyItemRemoved(position) + NativeInterface.removeEffectAt(position) + for (i in position until effectList.size) { + var holder = mRecyclerView.findViewHolderForAdapterPosition(i) as EffectsHolder + holder.bindEffect(holder.effect, i) + } + } + + override fun clearView( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder + ) { + super.clearView(recyclerView, viewHolder) + if (dragFrom != -1 && dragTo != -1 && dragFrom != dragTo) { + rotateItems(dragFrom, dragTo) + } + dragFrom = -1 + dragTo = -1 + } + + override fun isLongPressDragEnabled(): Boolean = false + override fun isItemViewSwipeEnabled(): Boolean = false + + fun rotateItems(fromPos: Int, toPos: Int) { + val a = min(fromPos, toPos) + val b = max(fromPos, toPos) + for (i in a..b) { + var holder = mRecyclerView.findViewHolderForAdapterPosition(i) as EffectsHolder + holder.bindEffect(holder.effect, i) + } + NativeInterface.rotateEffectAt(fromPos, toPos) + } + }) + +} |