OSDN Git Service

ロータリー入力に対応。
authorMRSa <mrsa@myad.jp>
Sat, 15 Apr 2023 12:26:11 +0000 (21:26 +0900)
committerMRSa <mrsa@myad.jp>
Sat, 15 Apr 2023 12:26:11 +0000 (21:26 +0900)
.idea/deploymentTargetDropDown.xml
wear/src/main/java/net/osdn/gokigen/joggingtimer/recorddetail/DetailActivity.java [deleted file]
wear/src/main/java/net/osdn/gokigen/joggingtimer/recorddetail/DetailActivity.kt [new file with mode: 0644]
wear/src/main/java/net/osdn/gokigen/joggingtimer/recordlist/ListActivity.java [deleted file]
wear/src/main/java/net/osdn/gokigen/joggingtimer/recordlist/ListActivity.kt [new file with mode: 0644]

index 7a6e652..509e98b 100644 (file)
@@ -6,12 +6,12 @@
         <type value="RUNNING_DEVICE_TARGET" />
         <deviceKey>
           <Key>
         <type value="RUNNING_DEVICE_TARGET" />
         <deviceKey>
           <Key>
-            <type value="SERIAL_NUMBER" />
-            <value value="192.168.19.23:5555" />
+            <type value="VIRTUAL_DEVICE_PATH" />
+            <value value="C:\Users\MRSa\.android\avd\Wear_OS_Small_Round_API_30.avd" />
           </Key>
         </deviceKey>
       </Target>
     </runningDeviceTargetSelectedWithDropDown>
           </Key>
         </deviceKey>
       </Target>
     </runningDeviceTargetSelectedWithDropDown>
-    <timeTargetWasSelectedWithDropDown value="2023-04-15T12:06:39.781714400Z" />
+    <timeTargetWasSelectedWithDropDown value="2023-04-15T12:22:12.467173700Z" />
   </component>
 </project>
\ No newline at end of file
   </component>
 </project>
\ No newline at end of file
diff --git a/wear/src/main/java/net/osdn/gokigen/joggingtimer/recorddetail/DetailActivity.java b/wear/src/main/java/net/osdn/gokigen/joggingtimer/recorddetail/DetailActivity.java
deleted file mode 100644 (file)
index 7d0b9ba..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-package net.osdn.gokigen.joggingtimer.recorddetail;
-
-import android.os.Bundle;
-import android.util.Log;
-import android.view.MenuItem;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.fragment.app.FragmentManager;
-import androidx.recyclerview.widget.DividerItemDecoration;
-import androidx.wear.ambient.AmbientModeSupport;
-import androidx.wear.widget.WearableLinearLayoutManager;
-import androidx.wear.widget.WearableRecyclerView;
-import androidx.wear.widget.drawer.WearableActionDrawerView;
-import androidx.wear.widget.drawer.WearableNavigationDrawerView;
-
-import net.osdn.gokigen.joggingtimer.R;
-import net.osdn.gokigen.joggingtimer.utilities.CreateModelData;
-import net.osdn.gokigen.joggingtimer.utilities.DataEditDialog;
-import net.osdn.gokigen.joggingtimer.utilities.SetReferenceDialog;
-
-
-/**
- *
- *
- */
-public class DetailActivity extends AppCompatActivity implements RecordDetailSetup.IDatabaseReadyNotify, MenuItem.OnMenuItemClickListener, DataEditDialog.Callback, CreateModelData.IEditedModelDataCallback, DetailSelectionMenuAdapter.ISelectedMenu, AmbientModeSupport.AmbientCallbackProvider, SetReferenceDialog.SetReferenceCallback
-{
-    private final String TAG = toString();
-    public static final String INTENT_EXTRA_DATA_ID = "Detail.dataId";
-
-    private RecordDetailAdapter detailAdapter = null;
-    private RecordDetailSetup setupper = null;
-
-    private WearableActionDrawerView actionDrawerView = null;
-
-    /**
-     *
-     */
-    @Override
-    protected void onCreate(Bundle savedInstanceState)
-    {
-        super.onCreate(savedInstanceState);
-        Log.v(TAG, "onCreate()");
-
-        setContentView(R.layout.activity_detail);
-
-        // Enables Always-on
-        //setAmbientEnabled();
-        try
-        {
-            AmbientModeSupport.AmbientController ambientController = AmbientModeSupport.attach(this);
-            ambientController.setAutoResumeEnabled(true);
-            //boolean isAmbient = ambientController.isAmbient();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-
-        try
-        {
-            WearableNavigationDrawerView naviView = findViewById(R.id.top_navigation_drawer);
-            DetailSelectionMenuAdapter menuAdapter = new DetailSelectionMenuAdapter(this, this);
-            naviView.setAdapter(menuAdapter);
-            naviView.addOnItemSelectedListener(menuAdapter);
-
-            WearableRecyclerView view = findViewById(R.id.recycler_detail_view);
-            detailAdapter = new RecordDetailAdapter();
-            WearableLinearLayoutManager layoutManager = new WearableLinearLayoutManager(this);
-
-            //view.setCircularScrollingGestureEnabled(getResources().getConfiguration().isScreenRound());
-            view.setCircularScrollingGestureEnabled(false);
-
-            DividerItemDecoration dividerDecoration = new DividerItemDecoration(view.getContext(), layoutManager.getOrientation());
-
-            view.addItemDecoration(dividerDecoration);
-            view.setLayoutManager(layoutManager);
-            view.setAdapter(detailAdapter);
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-            detailAdapter = null;
-        }
-
-        // Bottom Action Drawer
-        actionDrawerView = findViewById(R.id.bottom_action_drawer);
-        actionDrawerView.getController().peekDrawer();
-        actionDrawerView.setOnMenuItemClickListener(this);
-
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onSaveInstanceState(@NonNull Bundle outState)
-    {
-        super.onSaveInstanceState(outState);
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState)
-    {
-        super.onRestoreInstanceState(savedInstanceState);
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onResume()
-    {
-        super.onResume();
-        Log.v(TAG, "onResume() ");
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onPause()
-    {
-        super.onPause();
-        Log.v(TAG, "onPause()");
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void onStart()
-    {
-        super.onStart();
-        try
-        {
-            long indexId = getIntent().getLongExtra(INTENT_EXTRA_DATA_ID, -1);
-            Log.v(TAG, "onResume() " + indexId);
-
-            setupper = new RecordDetailSetup(this, indexId, this, detailAdapter, this);
-            setupper.setup();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void onStop()
-    {
-        super.onStop();
-        Log.v(TAG, "onStop()");
-
-        try
-        {
-            if (setupper != null)
-            {
-                setupper.closeDatabase();
-                setupper = null;
-            }
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-        System.gc();
-    }
-
-/*
-    @Override
-    public void onEnterAmbient(Bundle ambientDetails)
-    {
-        super.onEnterAmbient(ambientDetails);
-        Log.v(TAG, "onEnterAmbient()");
-    }
-
-    @Override
-    public void onExitAmbient()
-    {
-        super.onExitAmbient();
-        Log.v(TAG, "onExitAmbient()");
-    }
-
-    @Override
-    public void onUpdateAmbient()
-    {
-        super.onUpdateAmbient();
-        Log.v(TAG, "onUpdateAmbient()");
-    }
-*/
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void databaseSetupFinished(boolean result)
-    {
-        Log.v(TAG, "databaseSetupFinished() : " + result);
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void updatedIndexData(final boolean isIconOnly)
-    {
-        Log.v(TAG, "selectedReferenceData() : " + isIconOnly);
-        runOnUiThread(() -> {
-            try
-            {
-                String title;
-                if (isIconOnly)
-                {
-                    title = getString(R.string.action_set_reference);
-                }
-                else
-                {
-                    title = getString(R.string.action_edited_data);
-                }
-                Toast toast = Toast.makeText(getApplicationContext(), title, Toast.LENGTH_SHORT);
-                toast.show();
-            }
-            catch (Exception e)
-            {
-                e.printStackTrace();
-            }
-        });
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public boolean onMenuItemClick(MenuItem item)
-    {
-        Log.v(TAG, "onMenuItemClick(): " + item);
-
-        final int itemId = item.getItemId();
-        try
-        {
-            actionDrawerView.getController().closeDrawer();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-        return (itemSelected(itemId));
-    }
-
-    private boolean itemSelected(int itemId)
-    {
-        boolean ret = false;
-        //String toastMessage = "";
-        if (itemId == R.id.menu_edit_title)
-        {
-            // タイトルの編集
-            String title = "";
-            int iconId = R.drawable.ic_android_black_24dp;
-            RecordDetailSetup.EditIndexData data = setupper.getEditIndexData();
-            if (data != null) {
-                iconId = data.getIcon();
-                title = data.getTitle();
-            }
-            DataEditDialog dialog = DataEditDialog.newInstance(iconId, title, this);
-            FragmentManager manager = getSupportFragmentManager();
-            dialog.show(manager, "dialog");
-            ret = true;
-        }
-        else if (itemId == R.id.menu_set_reference)
-        {
-            // 基準値の設定ダイアログを表示する
-            final SetReferenceDialog.SetReferenceCallback callback = this;
-            this.runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    try
-                    {
-                        // 基準値設定ダイアログを表示する
-                        SetReferenceDialog dialog = SetReferenceDialog.newInstance(callback);
-                        FragmentManager manager = getSupportFragmentManager();
-                        dialog.show(manager, "dialog");
-                    }
-                    catch (Exception e)
-                    {
-                        e.printStackTrace();
-                    }
-                }
-            });
-            ret = true;
-        }
-        else if (itemId == R.id.menu_share_data)
-        {
-            // 現在のデータを共有する
-            setupper.shareTheData(detailAdapter);
-            ret = true;
-        }
-/*
-        try
-        {
-            if (toastMessage.length() > 0)
-            {
-                Toast toast = Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_SHORT);
-                toast.show();
-            }
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-*/
-        return (ret);
-    }
-
-    /**
-     *
-     */
-    @Override
-    public void dataEdited(int iconId, String title)
-    {
-        Log.v(TAG, "iconId : " + iconId + " title : '"+ title +"'");
-        try {
-            setupper.setEditIndexData(title, iconId);
-            WearableRecyclerView view = findViewById(R.id.recycler_detail_view);
-            view.postInvalidate();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     *
-     */
-    private void updateScreen()
-    {
-        try
-        {
-            WearableRecyclerView view = findViewById(R.id.recycler_detail_view);
-            view.postInvalidate();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     *
-     */
-    @Override
-    public void cancelled()
-    {
-        updateScreen();
-    }
-
-    /**
-     *
-     */
-    @Override
-    public void editedModelData(long indexId, long detailId, int lapCount, long prevTime, long newTime)
-    {
-        Log.v(TAG, "editedModelData() " + indexId + " " + detailId + " " + lapCount + " (" + prevTime + " -> " + newTime + ")");
-        if (detailAdapter == null)
-        {
-            return;
-        }
-
-        long diffTime = newTime - prevTime;
-        int count = detailAdapter.getItemCount();
-        if (count > 1)
-        {
-            long totalTime = 0;
-            long modTime = diffTime * (-1) / (count - 1);
-            for (int index = 1; index <= count; index++)
-            {
-                DetailRecord record = detailAdapter.getRecord(index - 1);
-                if (lapCount == index)
-                {
-                    totalTime = record.addModifiedTime(diffTime, totalTime);
-                }
-                else
-                {
-                    totalTime = record.addModifiedTime(modTime, totalTime);
-                }
-                detailAdapter.notifyItemChanged(index - 1);
-            }
-            try
-            {
-                Thread thread = new Thread(() -> {
-                    if (setupper != null)
-                    {
-                        setupper.updateDatabaseRecord(detailAdapter);
-                    }
-                });
-                thread.start();
-            }
-            catch (Exception e)
-            {
-                e.printStackTrace();
-            }
-        }
-        try
-        {
-            detailAdapter.notifyDataSetChanged();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public void selectedMenu(int itemId)
-    {
-        itemSelected(itemId);
-    }
-
-    @Override
-    public AmbientModeSupport.AmbientCallback getAmbientCallback()
-    {
-        return (new AmbientModeSupport.AmbientCallback() {
-            public void onEnterAmbient(Bundle ambientDetails)
-            {
-                Log.v(TAG, "onEnterAmbient()");
-            }
-            public void onExitAmbient(Bundle ambientDetails)
-            {
-                Log.v(TAG, "onExitAmbient()");
-            }
-        });
-    }
-
-    @Override
-    public void onPointerCaptureChanged(boolean hasCapture)
-    {
-        super.onPointerCaptureChanged(hasCapture);
-    }
-
-    @Override
-    public void confirmed(int id)
-    {
-        // 現在のデータを基準値として設定する
-        Log.v(TAG, " SET REFERENCE DATA ID: " + id);
-        setupper.setReferenceData(id);
-    }
-}
diff --git a/wear/src/main/java/net/osdn/gokigen/joggingtimer/recorddetail/DetailActivity.kt b/wear/src/main/java/net/osdn/gokigen/joggingtimer/recorddetail/DetailActivity.kt
new file mode 100644 (file)
index 0000000..0b80a94
--- /dev/null
@@ -0,0 +1,399 @@
+package net.osdn.gokigen.joggingtimer.recorddetail
+
+import android.os.Bundle
+import android.util.Log
+import android.view.MenuItem
+import android.view.MotionEvent
+import android.view.ViewConfiguration
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.InputDeviceCompat
+import androidx.core.view.MotionEventCompat
+import androidx.core.view.ViewConfigurationCompat
+import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.wear.ambient.AmbientModeSupport
+import androidx.wear.widget.WearableLinearLayoutManager
+import androidx.wear.widget.WearableRecyclerView
+import androidx.wear.widget.drawer.WearableActionDrawerView
+import androidx.wear.widget.drawer.WearableNavigationDrawerView
+import net.osdn.gokigen.joggingtimer.R
+import net.osdn.gokigen.joggingtimer.utilities.CreateModelData.IEditedModelDataCallback
+import net.osdn.gokigen.joggingtimer.utilities.DataEditDialog
+import net.osdn.gokigen.joggingtimer.utilities.SetReferenceDialog
+import net.osdn.gokigen.joggingtimer.utilities.SetReferenceDialog.SetReferenceCallback
+import kotlin.math.roundToInt
+
+/**
+ *
+ *
+ */
+class DetailActivity : AppCompatActivity(),
+    RecordDetailSetup.IDatabaseReadyNotify, MenuItem.OnMenuItemClickListener,
+    DataEditDialog.Callback, IEditedModelDataCallback, DetailSelectionMenuAdapter.ISelectedMenu,
+    AmbientModeSupport.AmbientCallbackProvider, SetReferenceCallback {
+    private val TAG = toString()
+    private var detailAdapter: RecordDetailAdapter? = null
+    private var setupper: RecordDetailSetup? = null
+    private var actionDrawerView: WearableActionDrawerView? = null
+
+    /**
+     *
+     */
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        Log.v(TAG, "onCreate()")
+        setContentView(R.layout.activity_detail)
+
+        // Enables Always-on
+        //setAmbientEnabled();
+        try {
+            val ambientController = AmbientModeSupport.attach(this)
+            ambientController.setAutoResumeEnabled(true)
+            //boolean isAmbient = ambientController.isAmbient();
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        try {
+            val naviView = findViewById<WearableNavigationDrawerView>(R.id.top_navigation_drawer)
+            val menuAdapter = DetailSelectionMenuAdapter(this, this)
+            naviView.setAdapter(menuAdapter)
+            naviView.addOnItemSelectedListener(menuAdapter)
+            val view = findViewById<WearableRecyclerView>(R.id.recycler_detail_view)
+            detailAdapter = RecordDetailAdapter()
+            val layoutManager = WearableLinearLayoutManager(this)
+
+            //view.setCircularScrollingGestureEnabled(getResources().getConfiguration().isScreenRound());
+            view.isCircularScrollingGestureEnabled = false
+            val dividerDecoration = DividerItemDecoration(view.context, layoutManager.orientation)
+            view.addItemDecoration(dividerDecoration)
+            view.layoutManager = layoutManager
+            view.adapter = detailAdapter
+        } catch (e: Exception) {
+            e.printStackTrace()
+            detailAdapter = null
+        }
+
+        // Bottom Action Drawer
+        actionDrawerView = findViewById(R.id.bottom_action_drawer)
+        actionDrawerView?.controller?.peekDrawer()
+        actionDrawerView?.setOnMenuItemClickListener(this)
+    }
+
+    /**
+     *
+     */
+    override fun onSaveInstanceState(outState: Bundle) {
+        super.onSaveInstanceState(outState)
+    }
+
+    /**
+     *
+     */
+    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
+        super.onRestoreInstanceState(savedInstanceState)
+    }
+
+    /**
+     *
+     */
+    override fun onResume() {
+        super.onResume()
+        Log.v(TAG, "onResume() ")
+    }
+
+    /**
+     *
+     */
+    override fun onPause() {
+        super.onPause()
+        Log.v(TAG, "onPause()")
+    }
+
+    /**
+     *
+     *
+     */
+    public override fun onStart() {
+        super.onStart()
+        try {
+            val indexId = intent.getLongExtra(INTENT_EXTRA_DATA_ID, -1)
+            Log.v(TAG, "onResume() $indexId")
+            setupper = RecordDetailSetup(this, indexId, this, detailAdapter, this)
+            setupper!!.setup()
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     *
+     *
+     */
+    public override fun onStop() {
+        super.onStop()
+        Log.v(TAG, "onStop()")
+        try {
+            if (setupper != null) {
+                setupper!!.closeDatabase()
+                setupper = null
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        System.gc()
+    }
+    /*
+    @Override
+    public void onEnterAmbient(Bundle ambientDetails)
+    {
+        super.onEnterAmbient(ambientDetails);
+        Log.v(TAG, "onEnterAmbient()");
+    }
+
+    @Override
+    public void onExitAmbient()
+    {
+        super.onExitAmbient();
+        Log.v(TAG, "onExitAmbient()");
+    }
+
+    @Override
+    public void onUpdateAmbient()
+    {
+        super.onUpdateAmbient();
+        Log.v(TAG, "onUpdateAmbient()");
+    }
+*/
+
+    override fun onGenericMotionEvent(ev: MotionEvent?): Boolean
+    {
+        try
+        {
+            if ((ev?.action == MotionEvent.ACTION_SCROLL)&& (ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)))
+            {
+                // ロータリー入力でスクロールする
+                // Log.v(TAG, "Rotary Encoder Input")
+                val view = findViewById<WearableRecyclerView>(R.id.recycler_detail_view)
+                val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *
+                        ViewConfigurationCompat.getScaledVerticalScrollFactor(ViewConfiguration.get(this), this)
+                view.scrollBy(0, delta.roundToInt())
+                return (true)
+            }
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        return (super.onGenericMotionEvent(ev))
+    }
+
+
+    /**
+     *
+     *
+     */
+    override fun databaseSetupFinished(result: Boolean) {
+        Log.v(TAG, "databaseSetupFinished() : $result")
+    }
+
+    /**
+     *
+     *
+     */
+    override fun updatedIndexData(isIconOnly: Boolean) {
+        Log.v(TAG, "selectedReferenceData() : $isIconOnly")
+        runOnUiThread {
+            try {
+                val title: String
+                title = if (isIconOnly) {
+                    getString(R.string.action_set_reference)
+                } else {
+                    getString(R.string.action_edited_data)
+                }
+                val toast =
+                    Toast.makeText(applicationContext, title, Toast.LENGTH_SHORT)
+                toast.show()
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+    }
+
+    /**
+     *
+     *
+     */
+    override fun onMenuItemClick(item: MenuItem): Boolean {
+        Log.v(TAG, "onMenuItemClick(): $item")
+        val itemId = item.itemId
+        try {
+            actionDrawerView!!.controller.closeDrawer()
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return itemSelected(itemId)
+    }
+
+    private fun itemSelected(itemId: Int): Boolean {
+        var ret = false
+        //String toastMessage = "";
+        if (itemId == R.id.menu_edit_title) {
+            // タイトルの編集
+            var title = ""
+            var iconId = R.drawable.ic_android_black_24dp
+            val data = setupper!!.editIndexData
+            if (data != null) {
+                iconId = data.getIcon()
+                title = data.getTitle()
+            }
+            val dialog = DataEditDialog.newInstance(iconId, title, this)
+            val manager = supportFragmentManager
+            dialog.show(manager, "dialog")
+            ret = true
+        } else if (itemId == R.id.menu_set_reference) {
+            // 基準値の設定ダイアログを表示する
+            val callback: SetReferenceCallback = this
+            runOnUiThread {
+                try {
+                    // 基準値設定ダイアログを表示する
+                    val dialog = SetReferenceDialog.newInstance(callback)
+                    val manager = supportFragmentManager
+                    dialog.show(manager, "dialog")
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                }
+            }
+            ret = true
+        } else if (itemId == R.id.menu_share_data) {
+            // 現在のデータを共有する
+            setupper!!.shareTheData(detailAdapter)
+            ret = true
+        }
+        /*
+        try
+        {
+            if (toastMessage.length() > 0)
+            {
+                Toast toast = Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_SHORT);
+                toast.show();
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+*/return ret
+    }
+
+    /**
+     *
+     */
+    override fun dataEdited(iconId: Int, title: String) {
+        Log.v(TAG, "iconId : $iconId title : '$title'")
+        try {
+            setupper!!.setEditIndexData(title, iconId)
+            val view = findViewById<WearableRecyclerView>(R.id.recycler_detail_view)
+            view.postInvalidate()
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     *
+     */
+    private fun updateScreen() {
+        try {
+            val view = findViewById<WearableRecyclerView>(R.id.recycler_detail_view)
+            view.postInvalidate()
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     *
+     */
+    override fun cancelled() {
+        updateScreen()
+    }
+
+    /**
+     *
+     */
+    override fun editedModelData(
+        indexId: Long,
+        detailId: Long,
+        lapCount: Int,
+        prevTime: Long,
+        newTime: Long
+    ) {
+        Log.v(
+            TAG,
+            "editedModelData() $indexId $detailId $lapCount ($prevTime -> $newTime)"
+        )
+        if (detailAdapter == null) {
+            return
+        }
+        val diffTime = newTime - prevTime
+        val count = detailAdapter!!.itemCount
+        if (count > 1) {
+            var totalTime: Long = 0
+            val modTime = diffTime * -1 / (count - 1)
+            for (index in 1..count) {
+                val record = detailAdapter!!.getRecord(index - 1)
+                totalTime = if (lapCount == index) {
+                    record.addModifiedTime(diffTime, totalTime)
+                } else {
+                    record.addModifiedTime(modTime, totalTime)
+                }
+                detailAdapter!!.notifyItemChanged(index - 1)
+            }
+            try {
+                val thread = Thread {
+                    if (setupper != null) {
+                        setupper!!.updateDatabaseRecord(detailAdapter!!)
+                    }
+                }
+                thread.start()
+            } catch (e: Exception) {
+                e.printStackTrace()
+            }
+        }
+        try {
+            detailAdapter?.notifyDataSetChanged()
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    override fun selectedMenu(itemId: Int) {
+        itemSelected(itemId)
+    }
+
+    override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback {
+        return object : AmbientModeSupport.AmbientCallback() {
+            override fun onEnterAmbient(ambientDetails: Bundle) {
+                Log.v(TAG, "onEnterAmbient()")
+            }
+
+            fun onExitAmbient(ambientDetails: Bundle?) {
+                Log.v(TAG, "onExitAmbient()")
+            }
+        }
+    }
+
+    override fun onPointerCaptureChanged(hasCapture: Boolean) {
+        super.onPointerCaptureChanged(hasCapture)
+    }
+
+    override fun confirmed(id: Int) {
+        // 現在のデータを基準値として設定する
+        Log.v(TAG, " SET REFERENCE DATA ID: $id")
+        setupper!!.setReferenceData(id)
+    }
+
+    companion object {
+        const val INTENT_EXTRA_DATA_ID = "Detail.dataId"
+    }
+}
\ No newline at end of file
diff --git a/wear/src/main/java/net/osdn/gokigen/joggingtimer/recordlist/ListActivity.java b/wear/src/main/java/net/osdn/gokigen/joggingtimer/recordlist/ListActivity.java
deleted file mode 100644 (file)
index c37a7b2..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-package net.osdn.gokigen.joggingtimer.recordlist;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.recyclerview.widget.DividerItemDecoration;
-import androidx.wear.ambient.AmbientModeSupport;
-import androidx.wear.widget.WearableLinearLayoutManager;
-import androidx.wear.widget.WearableRecyclerView;
-import androidx.wear.widget.drawer.WearableNavigationDrawerView;
-
-import net.osdn.gokigen.joggingtimer.R;
-import net.osdn.gokigen.joggingtimer.recorddetail.DetailActivity;
-import net.osdn.gokigen.joggingtimer.storage.ITimeEntryDatabase;
-import net.osdn.gokigen.joggingtimer.utilities.ConfirmationDialog;
-import net.osdn.gokigen.joggingtimer.utilities.CreateModelData;
-import net.osdn.gokigen.joggingtimer.utilities.CreateModelDataDialog;
-
-/**
- *
- *
- */
-public class ListActivity extends AppCompatActivity implements IDetailLauncher, RecordSummarySetup.IDatabaseReadyNotify, CreateModelData.ICreatedModelDataCallback, ListSelectionMenuAdapter.ISelectedMenu, AmbientModeSupport.AmbientCallbackProvider
-{
-    private final String TAG = toString();
-    private RecordSummaryAdapter summaryAdapter = null;
-    private RecordSummarySetup setupper = null;
-
-    /**
-     *
-     */
-    @Override
-    protected void onCreate(Bundle savedInstanceState)
-    {
-        super.onCreate(savedInstanceState);
-        Log.v(TAG, "onCreate()");
-
-        setContentView(R.layout.activity_list);
-
-        // Enables Always-on
-        //setAmbientEnabled();
-        try
-        {
-            AmbientModeSupport.AmbientController ambientController = AmbientModeSupport.attach(this);
-            ambientController.setAutoResumeEnabled(true);
-            //boolean isAmbient = ambientController.isAmbient();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-
-        try
-        {
-            WearableNavigationDrawerView naviView = findViewById(R.id.list_top_navigation_drawer);
-            ListSelectionMenuAdapter menuAdapter = new ListSelectionMenuAdapter(this, this);
-            naviView.setAdapter(menuAdapter);
-            naviView.addOnItemSelectedListener(menuAdapter);
-
-
-            WearableRecyclerView view = findViewById(R.id.recycler_list_view);
-            summaryAdapter = new RecordSummaryAdapter();
-            WearableLinearLayoutManager layoutManager = new WearableLinearLayoutManager(this);
-
-            view.setCircularScrollingGestureEnabled(getResources().getConfiguration().isScreenRound());
-            //view.setCircularScrollingGestureEnabled(false);
-
-            DividerItemDecoration dividerDecoration = new DividerItemDecoration(view.getContext(), layoutManager.getOrientation());
-
-            view.addItemDecoration(dividerDecoration);
-            view.setLayoutManager(layoutManager);
-            view.setAdapter(summaryAdapter);
-
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-            summaryAdapter = null;
-        }
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onSaveInstanceState(@NonNull Bundle outState)
-    {
-        super.onSaveInstanceState(outState);
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState)
-    {
-        super.onRestoreInstanceState(savedInstanceState);
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onResume()
-    {
-        super.onResume();
-        Log.v(TAG, "onResume()");
-        try
-        {
-            setupper = new RecordSummarySetup(this, this, this, summaryAdapter, this);
-            setupper.setup();
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-
-    }
-
-    /**
-     *
-     */
-    @Override
-    protected void onPause()
-    {
-        super.onPause();
-        Log.v(TAG, "onPause()");
-        try
-        {
-            if (setupper != null)
-            {
-                setupper.closeDatabase();
-                setupper = null;
-            }
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-        System.gc();
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void onStart()
-    {
-        super.onStart();
-        Log.v(TAG, "onStart()");
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void onStop()
-    {
-        super.onStop();
-        Log.v(TAG, "onStop()");
-    }
-
-/*
-    @Override
-    public void onEnterAmbient(Bundle ambientDetails)
-    {
-        super.onEnterAmbient(ambientDetails);
-        Log.v(TAG, "onEnterAmbient()");
-    }
-
-    @Override
-    public void onExitAmbient()
-    {
-        super.onExitAmbient();
-        Log.v(TAG, "onExitAmbient()");
-    }
-
-    @Override
-    public void onUpdateAmbient()
-    {
-        super.onUpdateAmbient();
-        Log.v(TAG, "onUpdateAmbient()");
-    }
-*/
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void launchDetail(long recordId)
-    {
-        Log.v(TAG, "launchDetail() id:" + recordId);
-        try
-        {
-            Intent intent = new Intent(this, DetailActivity.class);
-            intent.putExtra(DetailActivity.INTENT_EXTRA_DATA_ID, recordId);
-            startActivity(intent);
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     *
-     *
-     */
-    private void itemSelected(int itemId)
-    {
-        //String toastMessage = "";
-        if (itemId == R.id.menu_create_model)
-        {
-                // モデルデータの作成
-                CreateModelDataDialog dialog2 = CreateModelDataDialog.newInstance(true, getString(R.string.information_time_picker), 0, setupper.getCreateModelDataCallback(ITimeEntryDatabase.DONT_USE_ID, ITimeEntryDatabase.DONT_USE_ID), 0);
-                dialog2.show(getSupportFragmentManager(), "dialog2");
-        }
-/*
-        try
-        {
-            if (toastMessage.length() > 0)
-            {
-                Toast toast = Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_SHORT);
-                toast.show();
-            }
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
- */
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void deleteRecord(@NonNull DataRecord targetRecord)
-    {
-        try
-        {
-            final int positionId = targetRecord.getPositionId();
-            final String title = targetRecord.getTitle();
-
-            Log.v(TAG, "deleteRecord() : " + title);
-
-            String message = getString(R.string.dialog_message_delete) + " (" + title + ")";
-            ConfirmationDialog dialog = ConfirmationDialog.newInstance(getString(R.string.dialog_title_delete), message, () -> {
-                Log.v(TAG, "Delete Record Execute [" + title + "]" + " pos:" + positionId);
-                if (summaryAdapter != null)
-                {
-                    final long indexId = summaryAdapter.removeItem(positionId);
-                    try
-                    {
-                        Thread thread = new Thread(() -> {
-                            if (indexId >= 0)
-                            {
-                                setupper.deleteTimeEntryData(indexId);
-                            }
-                        });
-                        thread.start();
-                    }
-                    catch (Exception e)
-                    {
-                        e.printStackTrace();
-                    }
-                }
-            });
-            dialog.show(getSupportFragmentManager(), "dialog");
-        }
-        catch (Exception e)
-        {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void databaseSetupFinished(boolean result)
-    {
-        Log.v(TAG, "databaseSetupFinished() : " + result);
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void selectedMenu(int itemId)
-    {
-        itemSelected(itemId);
-    }
-
-    /**
-     *
-     *
-     */
-    @Override
-    public void createdModelData(long indexId)
-    {
-        // データの登録
-        setupper.setIndexData(indexId);
-
-        // 一覧の更新
-        runOnUiThread(() -> {
-            if (summaryAdapter != null)
-            {
-                int count = summaryAdapter.getItemCount();
-                summaryAdapter.notifyItemChanged(count - 1);
-                summaryAdapter.notifyDataSetChanged();
-            }
-
-            // Toastで作成を通知する
-            Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.created_model_data), Toast.LENGTH_SHORT);
-            toast.show();
-        });
-    }
-
-    @Override
-    public AmbientModeSupport.AmbientCallback getAmbientCallback()
-    {
-        return (new AmbientModeSupport.AmbientCallback() {
-            public void onEnterAmbient(Bundle ambientDetails)
-            {
-                Log.v(TAG, "onEnterAmbient()");
-            }
-            public void onExitAmbient(Bundle ambientDetails)
-            {
-                Log.v(TAG, "onExitAmbient()");
-                //updateTimerLabel();
-            }
-        });
-    }
-
-    @Override
-    public void onPointerCaptureChanged(boolean hasCapture) {
-        super.onPointerCaptureChanged(hasCapture);
-    }
-}
diff --git a/wear/src/main/java/net/osdn/gokigen/joggingtimer/recordlist/ListActivity.kt b/wear/src/main/java/net/osdn/gokigen/joggingtimer/recordlist/ListActivity.kt
new file mode 100644 (file)
index 0000000..25da2ee
--- /dev/null
@@ -0,0 +1,328 @@
+package net.osdn.gokigen.joggingtimer.recordlist
+
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.view.MotionEvent
+import android.view.ViewConfiguration
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.InputDeviceCompat
+import androidx.core.view.MotionEventCompat
+import androidx.core.view.ViewConfigurationCompat
+import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.wear.ambient.AmbientModeSupport
+import androidx.wear.widget.WearableLinearLayoutManager
+import androidx.wear.widget.WearableRecyclerView
+import androidx.wear.widget.drawer.WearableNavigationDrawerView
+import net.osdn.gokigen.joggingtimer.R
+import net.osdn.gokigen.joggingtimer.recorddetail.DetailActivity
+import net.osdn.gokigen.joggingtimer.storage.ITimeEntryDatabase
+import net.osdn.gokigen.joggingtimer.utilities.ConfirmationDialog
+import net.osdn.gokigen.joggingtimer.utilities.CreateModelData.ICreatedModelDataCallback
+import net.osdn.gokigen.joggingtimer.utilities.CreateModelDataDialog
+import kotlin.math.roundToInt
+
+/**
+ *
+ *
+ */
+class ListActivity : AppCompatActivity(),
+    IDetailLauncher, RecordSummarySetup.IDatabaseReadyNotify, ICreatedModelDataCallback,
+    ListSelectionMenuAdapter.ISelectedMenu, AmbientModeSupport.AmbientCallbackProvider {
+    private val TAG = toString()
+    private var summaryAdapter: RecordSummaryAdapter? = null
+    private var setupper: RecordSummarySetup? = null
+
+    /**
+     *
+     */
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        Log.v(TAG, "onCreate()")
+        setContentView(R.layout.activity_list)
+
+        // Enables Always-on
+        //setAmbientEnabled();
+        try {
+            val ambientController = AmbientModeSupport.attach(this)
+            ambientController.setAutoResumeEnabled(true)
+            //boolean isAmbient = ambientController.isAmbient();
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        try {
+            val naviView =
+                findViewById<WearableNavigationDrawerView>(R.id.list_top_navigation_drawer)
+            val menuAdapter = ListSelectionMenuAdapter(this, this)
+            naviView.setAdapter(menuAdapter)
+            naviView.addOnItemSelectedListener(menuAdapter)
+            val view = findViewById<WearableRecyclerView>(R.id.recycler_list_view)
+            summaryAdapter = RecordSummaryAdapter()
+            val layoutManager = WearableLinearLayoutManager(this)
+            view.isCircularScrollingGestureEnabled = resources.configuration.isScreenRound
+            //view.setCircularScrollingGestureEnabled(false);
+            val dividerDecoration = DividerItemDecoration(view.context, layoutManager.orientation)
+            view.addItemDecoration(dividerDecoration)
+            view.layoutManager = layoutManager
+            view.adapter = summaryAdapter
+        } catch (e: Exception) {
+            e.printStackTrace()
+            summaryAdapter = null
+        }
+    }
+
+    /**
+     *
+     */
+    override fun onSaveInstanceState(outState: Bundle) {
+        super.onSaveInstanceState(outState)
+    }
+
+    /**
+     *
+     */
+    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
+        super.onRestoreInstanceState(savedInstanceState)
+    }
+
+    /**
+     *
+     */
+    override fun onResume() {
+        super.onResume()
+        Log.v(TAG, "onResume()")
+        try {
+            setupper = RecordSummarySetup(this, this, this, summaryAdapter, this)
+            setupper!!.setup()
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     *
+     */
+    override fun onPause() {
+        super.onPause()
+        Log.v(TAG, "onPause()")
+        try {
+            if (setupper != null) {
+                setupper!!.closeDatabase()
+                setupper = null
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        System.gc()
+    }
+
+    /**
+     *
+     *
+     */
+    public override fun onStart() {
+        super.onStart()
+        Log.v(TAG, "onStart()")
+    }
+
+    /**
+     *
+     *
+     */
+    public override fun onStop() {
+        super.onStop()
+        Log.v(TAG, "onStop()")
+    }
+    /*
+    @Override
+    public void onEnterAmbient(Bundle ambientDetails)
+    {
+        super.onEnterAmbient(ambientDetails);
+        Log.v(TAG, "onEnterAmbient()");
+    }
+
+    @Override
+    public void onExitAmbient()
+    {
+        super.onExitAmbient();
+        Log.v(TAG, "onExitAmbient()");
+    }
+
+    @Override
+    public void onUpdateAmbient()
+    {
+        super.onUpdateAmbient();
+        Log.v(TAG, "onUpdateAmbient()");
+    }
+*/
+
+    override fun onGenericMotionEvent(ev: MotionEvent?): Boolean
+    {
+        try
+        {
+            if ((ev?.action == MotionEvent.ACTION_SCROLL)&& (ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)))
+            {
+                // ロータリー入力でスクロールする
+                // Log.v(TAG, "Rotary Encoder Input")
+                val view = findViewById<WearableRecyclerView>(R.id.recycler_list_view)
+                val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *
+                        ViewConfigurationCompat.getScaledVerticalScrollFactor(ViewConfiguration.get(this), this)
+                view.scrollBy(0, delta.roundToInt())
+                return (true)
+            }
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        return (super.onGenericMotionEvent(ev))
+    }
+
+    /**
+     *
+     *
+     */
+    override fun launchDetail(recordId: Long) {
+        Log.v(TAG, "launchDetail() id:$recordId")
+        try {
+            val intent = Intent(this, DetailActivity::class.java)
+            intent.putExtra(DetailActivity.INTENT_EXTRA_DATA_ID, recordId)
+            startActivity(intent)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     *
+     *
+     */
+    private fun itemSelected(itemId: Int) {
+        //String toastMessage = "";
+        if (itemId == R.id.menu_create_model) {
+            // モデルデータの作成
+            val dialog2 = CreateModelDataDialog.newInstance(
+                true,
+                getString(R.string.information_time_picker),
+                0,
+                setupper!!.getCreateModelDataCallback(
+                    ITimeEntryDatabase.DONT_USE_ID,
+                    ITimeEntryDatabase.DONT_USE_ID
+                ),
+                0
+            )
+            dialog2.show(supportFragmentManager, "dialog2")
+        }
+        /*
+        try
+        {
+            if (toastMessage.length() > 0)
+            {
+                Toast toast = Toast.makeText(getApplicationContext(), toastMessage, Toast.LENGTH_SHORT);
+                toast.show();
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+ */
+    }
+
+    /**
+     *
+     *
+     */
+    override fun deleteRecord(targetRecord: DataRecord) {
+        try {
+            val positionId = targetRecord.positionId
+            val title = targetRecord.title
+            Log.v(TAG, "deleteRecord() : $title")
+            val message = getString(R.string.dialog_message_delete) + " (" + title + ")"
+            val dialog = ConfirmationDialog.newInstance(
+                getString(R.string.dialog_title_delete), message
+            ) {
+                Log.v(
+                    TAG,
+                    "Delete Record Execute [$title] pos:$positionId"
+                )
+                if (summaryAdapter != null) {
+                    val indexId = summaryAdapter!!.removeItem(positionId)
+                    try {
+                        val thread = Thread {
+                            if (indexId >= 0) {
+                                setupper!!.deleteTimeEntryData(indexId)
+                            }
+                        }
+                        thread.start()
+                    } catch (e: Exception) {
+                        e.printStackTrace()
+                    }
+                }
+            }
+            dialog.show(supportFragmentManager, "dialog")
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     *
+     *
+     */
+    override fun databaseSetupFinished(result: Boolean) {
+        Log.v(TAG, "databaseSetupFinished() : $result")
+    }
+
+    /**
+     *
+     *
+     */
+    override fun selectedMenu(itemId: Int) {
+        itemSelected(itemId)
+    }
+
+    /**
+     *
+     *
+     */
+    override fun createdModelData(indexId: Long) {
+        // データの登録
+        setupper!!.setIndexData(indexId)
+
+        // 一覧の更新
+        runOnUiThread {
+            if (summaryAdapter != null) {
+                val count = summaryAdapter!!.itemCount
+                summaryAdapter!!.notifyItemChanged(count - 1)
+                summaryAdapter!!.notifyDataSetChanged()
+            }
+
+            // Toastで作成を通知する
+            val toast = Toast.makeText(
+                applicationContext,
+                getString(R.string.created_model_data),
+                Toast.LENGTH_SHORT
+            )
+            toast.show()
+        }
+    }
+
+    override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback {
+        return object : AmbientModeSupport.AmbientCallback() {
+            override fun onEnterAmbient(ambientDetails: Bundle) {
+                Log.v(TAG, "onEnterAmbient()")
+            }
+
+            fun onExitAmbient(ambientDetails: Bundle?) {
+                Log.v(TAG, "onExitAmbient()")
+                //updateTimerLabel();
+            }
+        }
+    }
+
+    override fun onPointerCaptureChanged(hasCapture: Boolean) {
+        super.onPointerCaptureChanged(hasCapture)
+    }
+}
\ No newline at end of file