dyn4j の実力を JetpackCompose wrapper Physics Layout で思い知る

やはり Java のライブラリ群を使えることは素晴らしいことです。

以下、サンプルコードを参考に Activity を書き換えます。


👉 KlassenKonstantin/ComposePhysicsLayout: A custom Compose layout backed by a physics engine hatena-bookmark





class MainActivity : ComponentActivity() {

  @SuppressLint("SourceLockedOrientationActivity")
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    WindowCompat.setDecorFitsSystemWindows(window, false)
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    setContent {
      PhysicsLayoutTheme {
        Surface(
          modifier = Modifier.fillMaxSize(),
          color = MaterialTheme.colorScheme.background
        ) {

          val simulation = rememberSimulation()
          val balls = remember { mutableStateListOf<BallMeta>() }

          GravitySensor {
            simulation.setGravity(it.copy(x = -it.x).times(3f))
          }

          LaunchedEffect(Unit) {
            var i = 0
            val count = colors.count()
            while (true) {
              balls.add(BallMeta(color = colors[i % count]))
              delay(100)
              i++
            }
          }

          LaunchedEffect(Unit) {
            delay(5000)
            while (true) {
              balls.removeFirst()
              delay(100)
            }
          }

          Box {
            PhysicsLayout(
              modifier = Modifier.systemBarsPadding(),
              simulation = simulation
            ) {

              Block(   0, -200)
              Block(-125, -100)
              Block( 125, -100)
              Block(   0,    0)
              Block(-100,  100)
              Block( 100,  100)
              Block(   0,  200)

              balls.forEach { meta ->
                Ball(0, -350, meta = meta)
              }

            }
          }

        }
      }
    }
  }
}

@Composable
fun PhysicsLayoutScope.Block(x: Int, y: Int) {
  val offset = offsetDp(x, y)
  Card(
    modifier = Modifier
      .body(
        isStatic = true,
        initialTranslation =  offset
      )
  ) {
    Spacer(
      modifier = Modifier
        .size(62.dp)
        .background(color = Color.Gray)
    )
  }
}

@Composable
fun PhysicsLayoutScope.Ball(x: Int, y: Int, meta: BallMeta) {

  val initialOffset = offsetDp(x, y)

  Card(
    modifier = Modifier.body(
      id = meta.id,
      shape = RoundedCornerShape(meta.corner),
      initialTranslation = Offset(initialOffset.x, initialOffset.y),
      initialImpulse = Offset((Random.nextFloat() - 0.5f) * 2, (Random.nextFloat()) * 2),
    ),
    shape = RoundedCornerShape(meta.corner),
    colors = CardDefaults.cardColors(containerColor = meta.color)
  ) {
    Icon(
      modifier = Modifier
        .size(32.dp)
        .padding(4.dp),
      imageVector = Icons.Rounded.Rocket,
      contentDescription = null,
      tint = Color.White
    )
  }
}

@Composable
fun offsetDp(x: Int, y: Int) = with(LocalDensity.current) { Offset(x.dp.toPx(), y.dp.toPx()) }


@Immutable
data class BallMeta(
  val id: String = System.currentTimeMillis().toString(),
  val color: Color,
  val corner: Int = listOf(0, 50).shuffled()[0]
)

private val colors = listOf(
  Color(0xFFEF5350), Color(0xFFEC407A), Color(0xFFAB47BC), Color(0xFF7E57C2),
  Color(0xFF29B6FC), Color(0xFF26C6DA), Color(0xFF26A69A), Color(0xFF66BB6A),
  Color(0xFF9CCC65), Color(0xFFD4E157), Color(0xFFFFEE58), Color(0xFFFFCA28),
  Color(0xFFFFA726), Color(0xFFFF7043), Color(0xFF8D6E63), Color(0xFFBDBDBD),
  Color(0xFF78909C)
)

強力です。

👉 dyn4j hatena-bookmark
👉 【Jetpack Compose】dp / px / sp の相互変換 hatena-bookmark




【macOS】「⌫ (delete)」 と「⌦ (forward delete)」の キーボードショートカット設定

カーソルの左右の文字を消す

「⌫(delete)」「⌦(forward delete)」

の操作。

両手がキーボードのホームポジションから離したくないので、各エディタアプリごとの設定でキーボードショートカットやキーマップを設定しようとして困惑。

まあ、だるい。

設定できても衝突の話もある。

 

■ どうしたいのか

それぞれを 「⌃(control)」 を使ったショートカットに振り分けたい。


カーソルの左を消す delete-backward-char (Windows Backspace)
delete

→ ⌃(control) + H


カーソルの右を消す delete-char (Windows Delete)
fn (function) + delete

→ ⌃(control) + D

 

■ キーマップアプリで設定する

macOS 上で動くキーマップアプリでショートカットとして登録しちゃいます。

👉 ⌘英かな hatena-bookmark
👉 Karabiner-Elements hatena-bookmark

これだけです。

 

■ まとめ

macOS 上で動くテキストのエディタ系の操作はこれですべて統一できます。

もし、すでに 「⌃(control) + H/D」をショートカットすでに使用している場合は使えなくなりますが、最も頻繁に直感的に使うエディタ操作を優先します。

👉 【macOS】キーマップとキーボードショートカットの変更設定 hatena-bookmark
👉 Deletion (GNU Emacs Manual) hatena-bookmark


0120-578-225 からのSMS (ショートメッセージ )

こんな SMS (ショートメッセージ) きました。

ネットで検索してみると以下。

現在この電話番号(0120-578-225)を調べている方が急増しています。

👉 フリーダイヤル0120578225の詳細情報 | みんなの電話帳 hatena-bookmark

詐欺なのか、誤送信なのか、

厚生労働省からなのか、詐欺業者からなのか、

分かりません。

送信元番号に電話してみました。


使われていないです。

書かれているリンク https://goo.gl/LHCS9W のリダイレクト後のリンク先は、Android ヘルプページ。

Android スマートフォンの電話番号の確認手続きを行う - Android ヘルプ
👉 https://support.google.com/android/answer/7521240?visit_id=699072665013167797-3299884897&p=verify_number&rd=1

となっています。なんですかね、このパラメータ。

電話番号 0120-578-225 を厚生労働省が実際に利用している(た)として、

メッセージ自体心当たりが無いので、パターンとしては


1. 詐欺業者からの詐欺メッセージ

2. 詐欺業者からの誤送信

3. 詐欺業者からの電話番号確認

4. 厚生労働省からの詐欺メッセージ

5. 厚生労働省からの電話番号確認

6. 厚生労働省からの誤送信

が考えられます。

どうしてます?

どうしたらいいの?

👉 SMSで送信元の電話番号を偽装したメッセージを送る - Akaki I/O hatena-bookmark