diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 9cd7039..cc0ee13 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -38,10 +38,7 @@
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
-
-
-
-
+
@@ -59,6 +56,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
result.success(openFolder(call.argument("path") ?: ""))
+ "setAppIcon" -> result.success(setAppIcon(call.argument("id") ?: ""))
"keepAlive" -> {
keepAlive(call.argument("text") ?: "", call.argument("progress") ?: -1)
result.success(null)
@@ -238,6 +239,23 @@ class MainActivity : FlutterActivity() {
}
/// 폴더를 파일 앱으로 연다 (내장 저장소 안의 폴더만). 열 앱이 없으면 false.
+ /// 앱 아이콘 바꾸기: 고른 아이콘의 activity-alias 만 켜고 나머지는 끈다 (앱은 계속 켜 둔 채로)
+ private fun setAppIcon(id: String): Boolean {
+ val ids = listOf("yellow", "black", "film_jj", "film", "blue")
+ if (id !in ids) return false
+ val pm = packageManager
+ for (i in ids) {
+ val name = "$packageName.Icon" + i.split('_').joinToString("") { it.replaceFirstChar(Char::uppercaseChar) }
+ val state = if (i == id) PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ else PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ val cn = android.content.ComponentName(this, name)
+ if (pm.getComponentEnabledSetting(cn) != state) {
+ pm.setComponentEnabledSetting(cn, state, PackageManager.DONT_KILL_APP)
+ }
+ }
+ return true
+ }
+
private fun openFolder(path: String): Boolean {
// 내장 저장소 (primary) 또는 SD 카드 · USB (/storage/XXXX-XXXX → 문서 ID "XXXX-XXXX:...")
val root = Environment.getExternalStorageDirectory().path
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index 80bcc6f..1b29709 100644
--- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,6 +1,6 @@
-
-
-
+
+
+
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_black.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_black.xml
new file mode 100644
index 0000000..c248192
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_black.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_blue.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_blue.xml
new file mode 100644
index 0000000..4923826
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_blue.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_film.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_film.xml
new file mode 100644
index 0000000..2459be6
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_film.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_film_jj.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_film_jj.xml
new file mode 100644
index 0000000..a44cc66
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_film_jj.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_yellow.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_yellow.xml
new file mode 100644
index 0000000..641ca40
--- /dev/null
+++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_yellow.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
index ea4a8ea..6dba372 100644
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_bg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_bg.png
new file mode 100644
index 0000000..7163774
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_bg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_black.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_black.png
new file mode 100644
index 0000000..ea4a8ea
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_black.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_black_bg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
rename to android/app/src/main/res/mipmap-hdpi/ic_launcher_black_bg.png
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_black_fg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
rename to android/app/src/main/res/mipmap-hdpi/ic_launcher_black_fg.png
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue.png
new file mode 100644
index 0000000..e729bfd
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue_bg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue_bg.png
new file mode 100644
index 0000000..fa8c0b6
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue_bg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue_fg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue_fg.png
new file mode 100644
index 0000000..5a08bc1
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_blue_fg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_fg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_fg.png
new file mode 100644
index 0000000..223f891
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_fg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_film.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film.png
new file mode 100644
index 0000000..6d58d70
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_bg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_bg.png
new file mode 100644
index 0000000..73c4bae
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_bg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_fg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_fg.png
new file mode 100644
index 0000000..29486f4
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_fg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj.png
new file mode 100644
index 0000000..f9aab88
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj_bg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj_bg.png
new file mode 100644
index 0000000..73c4bae
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj_bg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj_fg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj_fg.png
new file mode 100644
index 0000000..b372574
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_film_jj_fg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow.png
new file mode 100644
index 0000000..6dba372
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow_bg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow_bg.png
new file mode 100644
index 0000000..7163774
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow_bg.png differ
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow_fg.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow_fg.png
new file mode 100644
index 0000000..223f891
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_yellow_fg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
index 2b51c3c..4f46e65 100644
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_bg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_bg.png
new file mode 100644
index 0000000..65d0435
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_bg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_black.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_black.png
new file mode 100644
index 0000000..2b51c3c
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_black.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_black_bg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
rename to android/app/src/main/res/mipmap-mdpi/ic_launcher_black_bg.png
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_black_fg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
rename to android/app/src/main/res/mipmap-mdpi/ic_launcher_black_fg.png
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue.png
new file mode 100644
index 0000000..d762181
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue_bg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue_bg.png
new file mode 100644
index 0000000..ec41826
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue_bg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue_fg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue_fg.png
new file mode 100644
index 0000000..59fa089
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_blue_fg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_fg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_fg.png
new file mode 100644
index 0000000..2cbad15
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_fg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_film.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film.png
new file mode 100644
index 0000000..787c32d
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_bg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_bg.png
new file mode 100644
index 0000000..6f5572e
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_bg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_fg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_fg.png
new file mode 100644
index 0000000..6986123
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_fg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj.png
new file mode 100644
index 0000000..9acf839
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj_bg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj_bg.png
new file mode 100644
index 0000000..6f5572e
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj_bg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj_fg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj_fg.png
new file mode 100644
index 0000000..45fa2e8
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_film_jj_fg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow.png
new file mode 100644
index 0000000..4f46e65
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow_bg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow_bg.png
new file mode 100644
index 0000000..65d0435
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow_bg.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow_fg.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow_fg.png
new file mode 100644
index 0000000..2cbad15
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_yellow_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
index efcd467..c5f76ea 100644
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_bg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_bg.png
new file mode 100644
index 0000000..d496804
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_black.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_black.png
new file mode 100644
index 0000000..efcd467
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_black.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_black_bg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
rename to android/app/src/main/res/mipmap-xhdpi/ic_launcher_black_bg.png
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_black_fg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
rename to android/app/src/main/res/mipmap-xhdpi/ic_launcher_black_fg.png
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue.png
new file mode 100644
index 0000000..d63904c
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue_bg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue_bg.png
new file mode 100644
index 0000000..eb5b9cd
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue_fg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue_fg.png
new file mode 100644
index 0000000..9bd0ce6
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_blue_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_fg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_fg.png
new file mode 100644
index 0000000..7664f5c
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film.png
new file mode 100644
index 0000000..feb6ab2
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_bg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_bg.png
new file mode 100644
index 0000000..1c511f4
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_fg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_fg.png
new file mode 100644
index 0000000..798d930
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj.png
new file mode 100644
index 0000000..2580f9b
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj_bg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj_bg.png
new file mode 100644
index 0000000..1c511f4
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj_fg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj_fg.png
new file mode 100644
index 0000000..ec0eaea
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_film_jj_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow.png
new file mode 100644
index 0000000..c5f76ea
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow_bg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow_bg.png
new file mode 100644
index 0000000..d496804
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow_fg.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow_fg.png
new file mode 100644
index 0000000..7664f5c
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_yellow_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
index 97fe7b8..42612d7 100644
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_bg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_bg.png
new file mode 100644
index 0000000..2be7342
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_black.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_black.png
new file mode 100644
index 0000000..97fe7b8
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_black.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_black_bg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
rename to android/app/src/main/res/mipmap-xxhdpi/ic_launcher_black_bg.png
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_black_fg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
rename to android/app/src/main/res/mipmap-xxhdpi/ic_launcher_black_fg.png
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue.png
new file mode 100644
index 0000000..001cddc
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue_bg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue_bg.png
new file mode 100644
index 0000000..5739926
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue_fg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue_fg.png
new file mode 100644
index 0000000..7de2d7c
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_blue_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_fg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_fg.png
new file mode 100644
index 0000000..6c7ea89
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film.png
new file mode 100644
index 0000000..cccf608
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_bg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_bg.png
new file mode 100644
index 0000000..23fb1aa
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_fg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_fg.png
new file mode 100644
index 0000000..e7dfd5f
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj.png
new file mode 100644
index 0000000..dd359e2
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj_bg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj_bg.png
new file mode 100644
index 0000000..23fb1aa
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj_fg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj_fg.png
new file mode 100644
index 0000000..637732a
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_film_jj_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow.png
new file mode 100644
index 0000000..42612d7
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow_bg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow_bg.png
new file mode 100644
index 0000000..2be7342
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow_fg.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow_fg.png
new file mode 100644
index 0000000..6c7ea89
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_yellow_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index d5cca78..2237f0e 100644
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_bg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_bg.png
new file mode 100644
index 0000000..4078cf2
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_black.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_black.png
new file mode 100644
index 0000000..d5cca78
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_black.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_black_bg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
rename to android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_black_bg.png
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_black_fg.png
similarity index 100%
rename from android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
rename to android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_black_fg.png
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue.png
new file mode 100644
index 0000000..e20fcdb
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue_bg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue_bg.png
new file mode 100644
index 0000000..a469791
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue_fg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue_fg.png
new file mode 100644
index 0000000..84e0f2a
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_blue_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_fg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_fg.png
new file mode 100644
index 0000000..bf27060
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film.png
new file mode 100644
index 0000000..9cd3c42
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_bg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_bg.png
new file mode 100644
index 0000000..3e84ed9
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_fg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_fg.png
new file mode 100644
index 0000000..38c1132
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj.png
new file mode 100644
index 0000000..d1e7081
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj_bg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj_bg.png
new file mode 100644
index 0000000..3e84ed9
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj_fg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj_fg.png
new file mode 100644
index 0000000..58beb90
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_film_jj_fg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow.png
new file mode 100644
index 0000000..2237f0e
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow_bg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow_bg.png
new file mode 100644
index 0000000..4078cf2
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow_bg.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow_fg.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow_fg.png
new file mode 100644
index 0000000..bf27060
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_yellow_fg.png differ
diff --git a/assets/icon/app_button_256.png b/assets/icon/app_button_256.png
deleted file mode 100644
index 02337e6..0000000
Binary files a/assets/icon/app_button_256.png and /dev/null differ
diff --git a/assets/icon/app_icon_1024.png b/assets/icon/app_icon_1024.png
index 9606816..8f5f4ef 100644
Binary files a/assets/icon/app_icon_1024.png and b/assets/icon/app_icon_1024.png differ
diff --git a/assets/icon/app_icon_small_256.png b/assets/icon/app_icon_small_256.png
deleted file mode 100644
index 855eb37..0000000
Binary files a/assets/icon/app_icon_small_256.png and /dev/null differ
diff --git a/assets/icon/variants/black.ico b/assets/icon/variants/black.ico
new file mode 100644
index 0000000..9ea798c
Binary files /dev/null and b/assets/icon/variants/black.ico differ
diff --git a/assets/icon/app_icon_256.png b/assets/icon/variants/black_256.png
similarity index 100%
rename from assets/icon/app_icon_256.png
rename to assets/icon/variants/black_256.png
diff --git a/assets/icon/variants/black_button.png b/assets/icon/variants/black_button.png
new file mode 100644
index 0000000..61f09cb
Binary files /dev/null and b/assets/icon/variants/black_button.png differ
diff --git a/assets/icon/variants/blue.ico b/assets/icon/variants/blue.ico
new file mode 100644
index 0000000..31138fa
Binary files /dev/null and b/assets/icon/variants/blue.ico differ
diff --git a/assets/icon/variants/blue_256.png b/assets/icon/variants/blue_256.png
new file mode 100644
index 0000000..22d51db
Binary files /dev/null and b/assets/icon/variants/blue_256.png differ
diff --git a/assets/icon/variants/blue_button.png b/assets/icon/variants/blue_button.png
new file mode 100644
index 0000000..bf9db7c
Binary files /dev/null and b/assets/icon/variants/blue_button.png differ
diff --git a/assets/icon/variants/film.ico b/assets/icon/variants/film.ico
new file mode 100644
index 0000000..0a8ae94
Binary files /dev/null and b/assets/icon/variants/film.ico differ
diff --git a/assets/icon/variants/film_256.png b/assets/icon/variants/film_256.png
new file mode 100644
index 0000000..eda60ab
Binary files /dev/null and b/assets/icon/variants/film_256.png differ
diff --git a/assets/icon/variants/film_button.png b/assets/icon/variants/film_button.png
new file mode 100644
index 0000000..4069e11
Binary files /dev/null and b/assets/icon/variants/film_button.png differ
diff --git a/assets/icon/variants/film_jj.ico b/assets/icon/variants/film_jj.ico
new file mode 100644
index 0000000..b195933
Binary files /dev/null and b/assets/icon/variants/film_jj.ico differ
diff --git a/assets/icon/variants/film_jj_256.png b/assets/icon/variants/film_jj_256.png
new file mode 100644
index 0000000..7d97c95
Binary files /dev/null and b/assets/icon/variants/film_jj_256.png differ
diff --git a/assets/icon/variants/film_jj_button.png b/assets/icon/variants/film_jj_button.png
new file mode 100644
index 0000000..4069e11
Binary files /dev/null and b/assets/icon/variants/film_jj_button.png differ
diff --git a/assets/icon/variants/yellow.ico b/assets/icon/variants/yellow.ico
new file mode 100644
index 0000000..51f68b7
Binary files /dev/null and b/assets/icon/variants/yellow.ico differ
diff --git a/assets/icon/variants/yellow_256.png b/assets/icon/variants/yellow_256.png
new file mode 100644
index 0000000..43fe91a
Binary files /dev/null and b/assets/icon/variants/yellow_256.png differ
diff --git a/assets/icon/variants/yellow_button.png b/assets/icon/variants/yellow_button.png
new file mode 100644
index 0000000..6583381
Binary files /dev/null and b/assets/icon/variants/yellow_button.png differ
diff --git a/assets/l10n/en.json b/assets/l10n/en.json
index 31d5955..79475bc 100644
--- a/assets/l10n/en.json
+++ b/assets/l10n/en.json
@@ -201,6 +201,7 @@
"건너뜀 (출력 폴더의 파일): {0}": "Skipped (file in the output folder): {0}",
"검색": "Search",
"검색 지우기": "Clear search",
+ "검정": "Black",
"결과 폴더": "Output folder",
"결과 폴더 열기 (동영상을 고르세요)": "Open output folder (choose a video)",
"결과 폴더 열기: {0}": "Open output folder: {0}",
@@ -217,6 +218,7 @@
"글자 · 버튼 크기입니다. 위쪽 막대의 − · + 로 그때그때 바꿀 수 있고, 가운데 숫자를 누르면 이 크기로 돌아갑니다 (지금 {0}%)": "Text · button size. Change it any time with − · + on the top bar; press the number in the middle to return to this size (now {0}%)",
"기계 번역": "Machine translation",
"기기": "device",
+ "기본": "Default",
"기본 연결 프로그램": "Default app",
"기본 크기 ({0}%) 로 · 기본 크기는 환경 설정 > 화면 에서": "Back to the default size ({0}%) · set the default size in Settings > Display",
"기본 프로그램": "Default program",
@@ -259,6 +261,7 @@
"내장 플레이어": "Built-in player",
"네덜란드어": "Dutch",
"네팔어": "Nepali",
+ "노랑": "Yellow",
"노르웨이어": "Norwegian",
"누르고 있으면 조정 전": "Hold to see before",
"다 받는 대로 MKV 만들기의 동영상 목록에 넣고, 다운로드 목록에서는 뺍니다 (다운로드 화면의 체크 상자와 같음)": "As soon as they finish, put them in the Make MKV video list and remove them from the download list (same as the checkbox on the download screen)",
@@ -485,6 +488,8 @@
"압축 파일 안에 없습니다": "Not in the archive",
"압축 파일 안에 프로그램이 없습니다.": "The program is not in the archive.",
"압축을 풀 수 없습니다: {0}": "Cannot extract the archive: {0}",
+ "앱 목록 · 홈 화면과 앱 안 왼쪽 위 버튼의 아이콘입니다. 바꾸면 홈 화면에 둔 아이콘이 없어질 수 있어 앱 목록에서 다시 끌어다 놓아야 할 수 있습니다": "Icon in the app list, home screen and the top-left button in the app. After changing it, the icon on your home screen may disappear and you may need to drag it from the app list again",
+ "앱 아이콘": "App icon",
"앱 안 브라우저 (권장)": "In-app browser (recommended)",
"앱 안 브라우저의 로그인 사용 (브라우저 화면에서 YouTube 에 로그인하세요)": "Use the in-app browser's sign-in (sign in to YouTube on the browser screen)",
"앱 안 웹 브라우저: [건너뛰기] 를 대신 누르고, 건너뛸 수 없는 광고는 소리를 끄고 빨리 넘깁니다 (넘기는 동안 화면 위쪽에 \"광고 건너뛰는 중…\")": "In-app web browser: presses [Skip] for you, and mutes and fast-forwards ads that can't be skipped (\"Skipping ad…\" shows at the top while skipping)",
@@ -744,6 +749,7 @@
"직접 입력…": "Custom…",
"진행 중인 작업 없음": "No jobs in progress",
"진행 중인 작업이 있습니다: {0}\n중지하고 끝낼까요?": "A job is in progress: {0}\nStop it and quit?",
+ "창 · 작업 표시줄 · 트레이와 앱 안 왼쪽 위 버튼의 아이콘입니다 (실행 파일 · 바탕 화면 바로 가기 아이콘은 그대로)": "Icon of the window, taskbar, tray and the top-left button in the app (the program file and desktop shortcut icons stay the same)",
"창 보이기 / 숨기기 단축키": "Hotkey to show / hide the window",
"창 숨김 → 프로세스 종료": "Window hidden → process exit",
"창 종료": "Close window",
@@ -752,6 +758,7 @@
"채도": "Saturation",
"채우기 (가운데 잘라냄)": "Fill (crop the center)",
"처음 사용 시 내려받기 {0}": "Downloads {0} on first use",
+ "처음 아이콘 (파랑)": "Original icon (blue)",
"첫 줄 추가": "Add first line",
"청각장애인용": "Hearing impaired",
"체코어": "Czech",
@@ -829,6 +836,8 @@
"프로그램의 모든 글자를 고른 언어로 보여 줍니다. 목록에 없는 언어는 [언어 추가] 로 이 기기의 AI 번역 모델이 자동 번역해 넣습니다.": "Shows all of the program's text in the chosen language. Languages not in the list can be added with [Add language]; this device's AI translation model translates them automatically.",
"프로그램이 이미 켜져 있을 때. 새 창은 재생만 하는 창이며 닫으면 그 창만 끝납니다": "When the program is already running. The new window only plays, and closing it ends only that window",
"핀란드어": "Finnish",
+ "필름": "Film",
+ "필름 + JJ": "Film + JJ",
"필수 프로그램 설치": "Install required programs",
"필수 프로그램 점검": "Check required programs",
"필수 프로그램이 모두 설치되어 있습니다.": "All required programs are installed.",
diff --git a/assets/l10n/ja.json b/assets/l10n/ja.json
index 70e0cad..daac76f 100644
--- a/assets/l10n/ja.json
+++ b/assets/l10n/ja.json
@@ -201,6 +201,7 @@
"건너뜀 (출력 폴더의 파일): {0}": "スキップ(出力フォルダーのファイル): {0}",
"검색": "検索",
"검색 지우기": "検索をクリア",
+ "검정": "黒",
"결과 폴더": "出力フォルダー",
"결과 폴더 열기 (동영상을 고르세요)": "出力フォルダーを開く(動画を選んでください)",
"결과 폴더 열기: {0}": "出力フォルダーを開く: {0}",
@@ -217,6 +218,7 @@
"글자 · 버튼 크기입니다. 위쪽 막대의 − · + 로 그때그때 바꿀 수 있고, 가운데 숫자를 누르면 이 크기로 돌아갑니다 (지금 {0}%)": "文字・ボタンの大きさです。上部バーの − ・ + でその都度変更でき、中央の数字を押すとこの大きさに戻ります(現在 {0}%)",
"기계 번역": "機械翻訳",
"기기": "端末",
+ "기본": "既定",
"기본 연결 프로그램": "既定のアプリ",
"기본 크기 ({0}%) 로 · 기본 크기는 환경 설정 > 화면 에서": "既定の大きさ({0}%)に戻す・既定の大きさは 環境設定 > 画面 で",
"기본 프로그램": "既定のプログラム",
@@ -259,6 +261,7 @@
"내장 플레이어": "内蔵プレーヤー",
"네덜란드어": "オランダ語",
"네팔어": "ネパール語",
+ "노랑": "黄色",
"노르웨이어": "ノルウェー語",
"누르고 있으면 조정 전": "押している間は調整前",
"다 받는 대로 MKV 만들기의 동영상 목록에 넣고, 다운로드 목록에서는 뺍니다 (다운로드 화면의 체크 상자와 같음)": "ダウンロードが終わり次第 MKV 作成の動画リストに入れ、ダウンロードリストからは外します(ダウンロード画面のチェックボックスと同じ)",
@@ -485,6 +488,8 @@
"압축 파일 안에 없습니다": "圧縮ファイル内にありません",
"압축 파일 안에 프로그램이 없습니다.": "圧縮ファイル内にプログラムがありません。",
"압축을 풀 수 없습니다: {0}": "圧縮ファイルを展開できません: {0}",
+ "앱 목록 · 홈 화면과 앱 안 왼쪽 위 버튼의 아이콘입니다. 바꾸면 홈 화면에 둔 아이콘이 없어질 수 있어 앱 목록에서 다시 끌어다 놓아야 할 수 있습니다": "アプリ一覧・ホーム画面とアプリ内左上のボタンのアイコンです。変更するとホーム画面のアイコンが消えることがあり、アプリ一覧から再度ドラッグする必要がある場合があります",
+ "앱 아이콘": "アプリアイコン",
"앱 안 브라우저 (권장)": "アプリ内ブラウザー(推奨)",
"앱 안 브라우저의 로그인 사용 (브라우저 화면에서 YouTube 에 로그인하세요)": "アプリ内ブラウザーのログインを使う(ブラウザー画面で YouTube にログインしてください)",
"앱 안 웹 브라우저: [건너뛰기] 를 대신 누르고, 건너뛸 수 없는 광고는 소리를 끄고 빨리 넘깁니다 (넘기는 동안 화면 위쪽에 \"광고 건너뛰는 중…\")": "アプリ内ウェブブラウザー:[スキップ]を代わりに押し、スキップできない広告は音を消して早送りします(スキップ中は画面上部に「広告をスキップ中…」)",
@@ -744,6 +749,7 @@
"직접 입력…": "直接入力…",
"진행 중인 작업 없음": "進行中の作業なし",
"진행 중인 작업이 있습니다: {0}\n중지하고 끝낼까요?": "進行中の作業があります: {0}\n中止して終了しますか?",
+ "창 · 작업 표시줄 · 트레이와 앱 안 왼쪽 위 버튼의 아이콘입니다 (실행 파일 · 바탕 화면 바로 가기 아이콘은 그대로)": "ウィンドウ・タスクバー・トレイとアプリ内左上のボタンのアイコンです(実行ファイル・デスクトップのショートカットのアイコンはそのまま)",
"창 보이기 / 숨기기 단축키": "ウィンドウ表示 / 非表示のショートカット",
"창 숨김 → 프로세스 종료": "ウィンドウ非表示 → プロセス終了",
"창 종료": "ウィンドウを閉じる",
@@ -752,6 +758,7 @@
"채도": "彩度",
"채우기 (가운데 잘라냄)": "フィル(中央を切り抜き)",
"처음 사용 시 내려받기 {0}": "初回使用時にダウンロード {0}",
+ "처음 아이콘 (파랑)": "最初のアイコン(青)",
"첫 줄 추가": "最初の行を追加",
"청각장애인용": "聴覚障害者用",
"체코어": "チェコ語",
@@ -829,6 +836,8 @@
"프로그램의 모든 글자를 고른 언어로 보여 줍니다. 목록에 없는 언어는 [언어 추가] 로 이 기기의 AI 번역 모델이 자동 번역해 넣습니다.": "プログラムのすべての文字を選んだ言語で表示します。リストにない言語は[言語を追加]で、この端末の AI 翻訳モデルが自動翻訳して追加します。",
"프로그램이 이미 켜져 있을 때. 새 창은 재생만 하는 창이며 닫으면 그 창만 끝납니다": "プログラムが既に起動しているとき。新しいウィンドウは再生専用で、閉じるとそのウィンドウだけ終了します",
"핀란드어": "フィンランド語",
+ "필름": "フィルム",
+ "필름 + JJ": "フィルム + JJ",
"필수 프로그램 설치": "必須プログラムをインストール",
"필수 프로그램 점검": "必須プログラムの点検",
"필수 프로그램이 모두 설치되어 있습니다.": "必須プログラムはすべてインストールされています。",
diff --git a/assets/l10n/zh-Hans.json b/assets/l10n/zh-Hans.json
index c398f80..030f5b1 100644
--- a/assets/l10n/zh-Hans.json
+++ b/assets/l10n/zh-Hans.json
@@ -201,6 +201,7 @@
"건너뜀 (출력 폴더의 파일): {0}": "已跳过(输出文件夹中的文件): {0}",
"검색": "搜索",
"검색 지우기": "清除搜索",
+ "검정": "黑色",
"결과 폴더": "输出文件夹",
"결과 폴더 열기 (동영상을 고르세요)": "打开输出文件夹(请选择视频)",
"결과 폴더 열기: {0}": "打开输出文件夹: {0}",
@@ -217,6 +218,7 @@
"글자 · 버튼 크기입니다. 위쪽 막대의 − · + 로 그때그때 바꿀 수 있고, 가운데 숫자를 누르면 이 크기로 돌아갑니다 (지금 {0}%)": "文字 · 按钮大小。可随时用顶部栏的 − · + 调整,点击中间的数字恢复为此大小(当前 {0}%)",
"기계 번역": "机器翻译",
"기기": "设备",
+ "기본": "默认",
"기본 연결 프로그램": "默认打开方式",
"기본 크기 ({0}%) 로 · 기본 크기는 환경 설정 > 화면 에서": "恢复默认大小({0}%)· 默认大小在 设置 > 显示 中设置",
"기본 프로그램": "默认程序",
@@ -259,6 +261,7 @@
"내장 플레이어": "内置播放器",
"네덜란드어": "荷兰语",
"네팔어": "尼泊尔语",
+ "노랑": "黄色",
"노르웨이어": "挪威语",
"누르고 있으면 조정 전": "按住查看调整前",
"다 받는 대로 MKV 만들기의 동영상 목록에 넣고, 다운로드 목록에서는 뺍니다 (다운로드 화면의 체크 상자와 같음)": "下载完成后立即放入制作 MKV 的视频列表,并从下载列表移除(与下载界面的复选框相同)",
@@ -485,6 +488,8 @@
"압축 파일 안에 없습니다": "压缩文件中没有",
"압축 파일 안에 프로그램이 없습니다.": "压缩文件中没有程序。",
"압축을 풀 수 없습니다: {0}": "无法解压: {0}",
+ "앱 목록 · 홈 화면과 앱 안 왼쪽 위 버튼의 아이콘입니다. 바꾸면 홈 화면에 둔 아이콘이 없어질 수 있어 앱 목록에서 다시 끌어다 놓아야 할 수 있습니다": "应用列表、主屏幕以及应用内左上角按钮的图标。更改后主屏幕上的图标可能会消失,可能需要从应用列表重新拖放",
+ "앱 아이콘": "应用图标",
"앱 안 브라우저 (권장)": "应用内浏览器(推荐)",
"앱 안 브라우저의 로그인 사용 (브라우저 화면에서 YouTube 에 로그인하세요)": "使用应用内浏览器的登录(请在浏览器界面登录 YouTube)",
"앱 안 웹 브라우저: [건너뛰기] 를 대신 누르고, 건너뛸 수 없는 광고는 소리를 끄고 빨리 넘깁니다 (넘기는 동안 화면 위쪽에 \"광고 건너뛰는 중…\")": "应用内网页浏览器: 代为点击[跳过],无法跳过的广告会静音并快进(跳过时屏幕顶部显示“正在跳过广告…”)",
@@ -744,6 +749,7 @@
"직접 입력…": "手动输入…",
"진행 중인 작업 없음": "没有进行中的任务",
"진행 중인 작업이 있습니다: {0}\n중지하고 끝낼까요?": "有正在进行的任务: {0}\n要停止并退出吗?",
+ "창 · 작업 표시줄 · 트레이와 앱 안 왼쪽 위 버튼의 아이콘입니다 (실행 파일 · 바탕 화면 바로 가기 아이콘은 그대로)": "窗口、任务栏、托盘以及应用内左上角按钮的图标(程序文件和桌面快捷方式的图标不变)",
"창 보이기 / 숨기기 단축키": "显示 / 隐藏窗口的快捷键",
"창 숨김 → 프로세스 종료": "窗口隐藏 → 进程退出",
"창 종료": "关闭窗口",
@@ -752,6 +758,7 @@
"채도": "饱和度",
"채우기 (가운데 잘라냄)": "填充(裁切中间)",
"처음 사용 시 내려받기 {0}": "首次使用时下载 {0}",
+ "처음 아이콘 (파랑)": "最初的图标(蓝色)",
"첫 줄 추가": "添加第一行",
"청각장애인용": "听障字幕",
"체코어": "捷克语",
@@ -829,6 +836,8 @@
"프로그램의 모든 글자를 고른 언어로 보여 줍니다. 목록에 없는 언어는 [언어 추가] 로 이 기기의 AI 번역 모델이 자동 번역해 넣습니다.": "以所选语言显示程序的所有文字。列表中没有的语言可通过[添加语言],由此设备的 AI 翻译模型自动翻译添加。",
"프로그램이 이미 켜져 있을 때. 새 창은 재생만 하는 창이며 닫으면 그 창만 끝납니다": "程序已在运行时。新窗口仅用于播放,关闭后只结束该窗口",
"핀란드어": "芬兰语",
+ "필름": "胶片",
+ "필름 + JJ": "胶片 + JJ",
"필수 프로그램 설치": "安装必需程序",
"필수 프로그램 점검": "检查必需程序",
"필수 프로그램이 모두 설치되어 있습니다.": "所有必需程序均已安装。",
diff --git a/assets/tray_icon.ico b/assets/tray_icon.ico
index 448868c..0a48377 100644
Binary files a/assets/tray_icon.ico and b/assets/tray_icon.ico differ
diff --git a/lib/app/settings.dart b/lib/app/settings.dart
index 92fb7e8..5c4e530 100644
--- a/lib/app/settings.dart
+++ b/lib/app/settings.dart
@@ -7,6 +7,7 @@ import 'package:path_provider/path_provider.dart';
import '../core/download_detect.dart';
import '../core/encode_options.dart';
import '../core/playlist.dart';
+import '../services/app_shell.dart' show appIconOf;
/// MKV 세부 정보의 이동 버튼 하나: 표시 이름 · 옮길 폴더
class MoveTarget {
@@ -110,6 +111,9 @@ class AppSettings {
/// 화면 언어 (ko · en · ja · zh-Hans, 또는 더한 언어)
String uiLanguage = 'ko';
+ /// 앱 아이콘 (appIconIds 중 하나: 'yellow' 기본 · 'black' · 'film_jj' · 'film' · 'blue')
+ String appIcon = 'yellow';
+
/// 더한 화면 언어 (AI 로 자동 번역한 사전이 설정 폴더 l10n 에 있음)
List uiLanguagesAdded = [];
@@ -178,6 +182,7 @@ class AppSettings {
'openFileAction': openFileAction,
'screenOrientation': screenOrientation,
'uiLanguage': uiLanguage,
+ 'appIcon': appIcon,
'uiLanguagesAdded': uiLanguagesAdded,
'openFileWindow': openFileWindow,
'homeUrl': homeUrl,
@@ -245,6 +250,7 @@ class AppSettings {
..uiScaleDefault = clampUiScale(j['uiScaleDefault'] as num?)
..openFileAction = j['openFileAction'] == 'add' ? 'add' : 'play'
..uiLanguage = j['uiLanguage'] as String? ?? 'ko'
+ ..appIcon = appIconOf(j['appIcon'] as String?)
..uiLanguagesAdded = [for (final x in (j['uiLanguagesAdded'] as List?) ?? const []) '$x']
..screenOrientation = const ['portrait', 'auto'].contains(j['screenOrientation'])
? j['screenOrientation'] as String
diff --git a/lib/main.dart b/lib/main.dart
index c044eb0..e0b83b8 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -188,6 +188,7 @@ Future main(List args) async {
if (nav != null) unawaited(DownloadsPage.open(nav, downloads));
},
);
+ await services.shell.setAppIcon(controller.settings.appIcon);
// 제목 표시줄에 버전 · 지난번 창 위치에서 열기 · 동영상 목록 불러오기 (창끼리 공유)
await windowManager.setTitle(appTitle);
final shell = services.shell;
@@ -370,6 +371,7 @@ Future runAndroid(String dataDir) async {
i18n.init(controller, dataDir);
await i18n.apply(controller.settings.uiLanguage, save: false);
await applyScreenOrientation(controller.settings.screenOrientation);
+ unawaited(services.shell.setAppIcon(controller.settings.appIcon));
final bookmarks = BookmarksController();
await bookmarks.load();
final navigatorKey = GlobalKey();
diff --git a/lib/platform/android/android_shell.dart b/lib/platform/android/android_shell.dart
index 37bc0e2..8eca0b7 100644
--- a/lib/platform/android/android_shell.dart
+++ b/lib/platform/android/android_shell.dart
@@ -29,6 +29,14 @@ class AndroidShell extends NoopShell {
@override
Future isFullScreen() async => _full;
+ /// 앱 목록 · 홈 화면 아이콘: 고른 아이콘의 activity-alias 만 켠다 (런처가 다시 그리는 데 몇 초 걸릴 수 있음)
+ @override
+ Future setAppIcon(String id) async {
+ try {
+ await _ch.invokeMethod('setAppIcon', {'id': appIconOf(id)});
+ } catch (_) {}
+ }
+
/// 기기의 기본 브라우저로 (고른 브라우저는 PC 에서만)
@override
Future openUrl(String url, {String browser = 'system'}) async {
diff --git a/lib/platform/windows/desktop_shell.dart b/lib/platform/windows/desktop_shell.dart
index c6ebfb3..26a6faa 100644
--- a/lib/platform/windows/desktop_shell.dart
+++ b/lib/platform/windows/desktop_shell.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/services.dart';
+import 'package:path/path.dart' as p;
import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:tray_manager/tray_manager.dart' as tray;
import 'package:screen_retriever/screen_retriever.dart';
@@ -41,11 +42,31 @@ class DesktopShell with WindowListener implements AppShell {
await setHotkey(hotkey);
}
+ /// 고른 앱 아이콘 (init 전에 [setAppIcon] 으로 정해 둘 수 있음)
+ String _icon = appIconIds.first;
+
+ tray.Image? _trayImage() =>
+ tray.ImageAsset.fromAsset('assets/icon/variants/$_icon.ico') ??
+ tray.ImageAsset.fromAsset('assets/tray_icon.ico') ??
+ tray.Image.fromFile(Platform.resolvedExecutable);
+
+ /// 창 · 작업 표시줄 · 트레이 아이콘 (exe 파일 아이콘 · 바탕 화면 바로 가기는 그대로)
+ @override
+ Future setAppIcon(String id) async {
+ _icon = appIconOf(id);
+ final ico = p.join(p.dirname(Platform.resolvedExecutable), 'data', 'flutter_assets', 'assets', 'icon', 'variants',
+ '$_icon.ico');
+ try {
+ if (File(ico).existsSync()) await windowManager.setIcon(ico);
+ } catch (_) {}
+ final t = _tray;
+ if (t != null) t.icon = _trayImage();
+ }
+
void _initTray() {
final t = tray.TrayIcon.create();
if (t == null) return;
- t.icon = tray.ImageAsset.fromAsset('assets/tray_icon.ico') ??
- tray.Image.fromFile(Platform.resolvedExecutable);
+ t.icon = _trayImage();
t.setTooltip('JJ_MKVMaker');
final menu = tray.Menu.create()!;
diff --git a/lib/services/app_shell.dart b/lib/services/app_shell.dart
index 9093a63..3e5ee20 100644
--- a/lib/services/app_shell.dart
+++ b/lib/services/app_shell.dart
@@ -25,6 +25,9 @@ abstract class AppShell {
/// 프로그램 종료
Future quit();
+ /// 앱 아이콘 바꾸기 ([appIconIds] 중 하나). Windows: 창 · 작업 표시줄 · 트레이, Android: 앱 목록 · 홈 화면
+ Future setAppIcon(String id);
+
// ───────── 플레이어 창 ─────────
Future setFullScreen(bool on);
@@ -88,6 +91,8 @@ class NoopShell implements AppShell {
@override
Future quit() async {}
@override
+ Future setAppIcon(String id) async {}
+ @override
Future setFullScreen(bool on) async {}
@override
Future isFullScreen() async => false;
@@ -119,6 +124,19 @@ class NoopShell implements AppShell {
Future restart() async {}
}
+/// 고를 수 있는 앱 아이콘 (환경 설정 > 일반 > 앱 아이콘). 첫 번째가 기본.
+/// 그림은 tool/make_icon.py 가 만든다: `assets/icon/variants/_256.png` · `_button.png` · `.ico`
+const appIconIds = ['yellow', 'black', 'film_jj', 'film', 'blue'];
+
+/// 저장된 값이 모르는 것이면 기본 아이콘
+String appIconOf(String? id) => appIconIds.contains(id) ? id! : appIconIds.first;
+
+/// 앱 안 왼쪽 위 홈 버튼 그림
+String appIconButtonAsset(String? id) => 'assets/icon/variants/${appIconOf(id)}_button.png';
+
+/// 설정에서 고를 때 보여 주는 큰 그림
+String appIconPreviewAsset(String id) => 'assets/icon/variants/${appIconOf(id)}_256.png';
+
/// "Ctrl+Shift+X" → (수식키 목록, 키 이름). 형식이 틀리면 null.
(List, String)? parseHotkey(String text) {
final parts = text.split('+').map((s) => s.trim()).where((s) => s.isNotEmpty).toList();
diff --git a/lib/ui/app_actions.dart b/lib/ui/app_actions.dart
index 98f6448..a814ce9 100644
--- a/lib/ui/app_actions.dart
+++ b/lib/ui/app_actions.dart
@@ -4,6 +4,7 @@ import '../app/app_controller.dart';
import '../app/bookmarks_controller.dart';
import '../app/download_manager.dart';
import '../app/settings.dart';
+import '../services/app_shell.dart' show appIconButtonAsset;
import '../services/system_usage.dart';
import 'browser_page.dart';
import 'downloads_page.dart';
@@ -84,7 +85,8 @@ class AppNavButtons extends StatelessWidget {
width: width,
child: Row(children: [
btn(
- Image.asset('assets/icon/app_button_256.png', width: 26, height: 26, filterQuality: FilterQuality.medium),
+ Image.asset(appIconButtonAsset(scope?.controller.settings.appIcon),
+ width: 26, height: 26, filterQuality: FilterQuality.medium),
trf('홈 화면 ({0}) · 환경 설정에서 바꿈', [homeIsBrowser ? tr('웹 브라우저') : tr('MKV 화면')]),
scope == null ? null : () => toHome(context),
),
diff --git a/lib/ui/settings_page.dart b/lib/ui/settings_page.dart
index c1687f4..4ae5364 100644
--- a/lib/ui/settings_page.dart
+++ b/lib/ui/settings_page.dart
@@ -278,6 +278,7 @@ class _SettingsPageState extends State {
_group('general', Icons.tune, tr('일반'), [
// 화면 언어 (읽을 수 없는 언어를 골라도 바로 찾아 되돌릴 수 있게 맨 위)
const LanguageSettings(),
+ _appIconTile(c, desk),
if (c.services.updater != null) ...[
ListTile(
leading: const Icon(Icons.system_update_alt, color: JjColors.accent),
@@ -829,6 +830,54 @@ class _SettingsPageState extends State {
);
/// 묶음 안의 작은 제목
+ /// 앱 아이콘 고르기: 그림을 누르면 바로 바뀐다
+ Widget _appIconTile(AppController c, bool desk) {
+ final now = appIconOf(c.settings.appIcon);
+ return ListTile(
+ title: Text(tr('앱 아이콘')),
+ subtitle: Padding(
+ padding: const EdgeInsets.only(top: 4),
+ child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
+ Text(desk
+ ? tr('창 · 작업 표시줄 · 트레이와 앱 안 왼쪽 위 버튼의 아이콘입니다 (실행 파일 · 바탕 화면 바로 가기 아이콘은 그대로)')
+ : tr('앱 목록 · 홈 화면과 앱 안 왼쪽 위 버튼의 아이콘입니다. 바꾸면 홈 화면에 둔 아이콘이 없어질 수 있어 앱 목록에서 다시 끌어다 놓아야 할 수 있습니다')),
+ const SizedBox(height: 8),
+ Wrap(spacing: 10, runSpacing: 10, children: [
+ for (final id in appIconIds)
+ Tooltip(
+ message: id == appIconIds.first ? '${_appIconName(id)} (${tr('기본')})' : _appIconName(id),
+ child: InkWell(
+ borderRadius: BorderRadius.circular(14),
+ onTap: id == now
+ ? null
+ : () {
+ c.updateSettings((x) => x.appIcon = id);
+ c.services.shell.setAppIcon(id);
+ },
+ child: Container(
+ padding: const EdgeInsets.all(4),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(14),
+ border: Border.all(color: id == now ? JjColors.accent : Colors.transparent, width: 3),
+ ),
+ child: Image.asset(appIconPreviewAsset(id), width: 56, height: 56, filterQuality: FilterQuality.medium),
+ ),
+ ),
+ ),
+ ]),
+ ]),
+ ),
+ );
+ }
+
+ static String _appIconName(String id) => switch (id) {
+ 'yellow' => tr('노랑'),
+ 'black' => tr('검정'),
+ 'film_jj' => tr('필름 + JJ'),
+ 'film' => tr('필름'),
+ _ => tr('처음 아이콘 (파랑)'),
+ };
+
Widget _subTitle(String t) => Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
child: Text(t, style: const TextStyle(fontSize: 13, color: JjColors.accent, fontWeight: FontWeight.w600)),
diff --git a/pubspec.yaml b/pubspec.yaml
index 24f3bfd..b907e3b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -93,8 +93,7 @@ flutter:
assets:
- assets/tray_icon.ico
- assets/l10n/
- - assets/icon/app_icon_256.png
- - assets/icon/app_button_256.png
+ - assets/icon/variants/
# To add assets to your application, add an assets section, like this:
# assets:
diff --git a/test/app_icon_test.dart b/test/app_icon_test.dart
new file mode 100644
index 0000000..802662c
--- /dev/null
+++ b/test/app_icon_test.dart
@@ -0,0 +1,31 @@
+import 'dart:io';
+
+import 'package:flutter_test/flutter_test.dart';
+import 'package:jj_mkvmaker/app/settings.dart';
+import 'package:jj_mkvmaker/services/app_shell.dart';
+
+void main() {
+ test('앱 아이콘 설정: 기본은 노랑, 저장 · 불러오기, 모르는 값은 기본으로', () {
+ expect(AppSettings().appIcon, 'yellow');
+ final s = AppSettings()..appIcon = 'black';
+ expect(AppSettings.fromJson(s.toJson()).appIcon, 'black');
+ expect(AppSettings.fromJson({'appIcon': 'nope'}).appIcon, 'yellow');
+ expect(AppSettings.fromJson({}).appIcon, 'yellow');
+ });
+
+ test('아이콘마다 그림 파일 (설정 미리보기 · 앱 안 버튼 · Windows ico · Android 런처) 이 있다', () {
+ for (final id in appIconIds) {
+ expect(File(appIconPreviewAsset(id)).existsSync(), isTrue, reason: id);
+ expect(File(appIconButtonAsset(id)).existsSync(), isTrue, reason: id);
+ expect(File('assets/icon/variants/$id.ico').existsSync(), isTrue, reason: id);
+ expect(File('android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_$id.xml').existsSync(), isTrue, reason: id);
+ expect(File('android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_$id.png').existsSync(), isTrue, reason: id);
+ }
+ // Android: 아이콘마다 activity-alias 하나 (처음에는 기본만 켜짐)
+ final manifest = File('android/app/src/main/AndroidManifest.xml').readAsStringSync();
+ for (final id in appIconIds) {
+ expect(manifest, contains('@mipmap/ic_launcher_$id"'), reason: id);
+ }
+ expect('android:enabled="true"'.allMatches(manifest).length, 1);
+ });
+}
diff --git a/tool/make_icon.py b/tool/make_icon.py
index 0f8f527..6abb0f4 100644
--- a/tool/make_icon.py
+++ b/tool/make_icon.py
@@ -1,13 +1,18 @@
-"""JJ_MKVMaker 아이콘 만들기 (1024px 원본 → .ico / .png)
+"""JJ_MKVMaker 아이콘 만들기 (환경 설정 > 일반 > 앱 아이콘 에서 고르는 여러 가지)
-검은 바탕 (짙은 회색 → 검정) 에 노란 J · J 와 큰 흰 재생(▶) 버튼, 위아래 필름 구멍 띠.
-(JJ 로 시작하는 다른 프로그램과 헷갈리지 않게 글자 대신 재생 버튼이 주인공)
+아이콘 종류 (id):
+ yellow 노란 바탕 + 검은 J · J + 검은 재생 버튼 (두 가지 색만, 기본)
+ black 검은 바탕 + 노란 J · J + 흰 재생 버튼 + 필름 띠
+ film_jj 빨강 → 주황 바탕 + 노란 J · J + 흰 재생 버튼 + 필름 띠
+ film 빨강 → 주황 바탕 + 큰 흰 재생 버튼 + 필름 띠
+ blue 청록 → 보라 바탕 + 흰 JJ + 재생 표시 (처음 아이콘)
사용법: python tool/make_icon.py
-결과: assets/icon/app_icon_1024.png · app_icon_256.png · app_icon_small_256.png,
- windows/runner/resources/app_icon.ico, assets/tray_icon.ico,
- android/app/src/main/res/mipmap-*/ic_launcher.png (예전 Android),
- mipmap-*/ic_launcher_foreground.png · ic_launcher_background.png + mipmap-anydpi-v26/ic_launcher.xml (Android 8 이상)
+결과: assets/icon/variants/_256.png (설정 미리보기) · _button.png (앱 안 왼쪽 위 버튼) · .ico (Windows 창 · 트레이)
+ assets/icon/app_icon_1024.png · windows/runner/resources/app_icon.ico · assets/tray_icon.ico (기본 아이콘)
+ android/app/src/main/res/mipmap-*/ic_launcher[_].png · ic_launcher[_]_bg.png · _fg.png
+ + mipmap-anydpi-v26/ic_launcher[_].xml (Android 8 이상 adaptive icon)
+ build/icon_preview.png (한눈에 보기)
"""
from pathlib import Path
@@ -15,48 +20,50 @@ from PIL import Image, ImageDraw, ImageFilter, ImageFont
ROOT = Path(__file__).resolve().parent.parent
S = 1024 # 원본 크기
-
-TOP = (58, 58, 66) # 바탕 왼쪽 위 (짙은 회색)
-BOTTOM = (6, 6, 8) # 바탕 오른쪽 아래 (검정)
-FILM = (0, 0, 0) # 필름 띠 (바탕보다 더 검게)
-YELLOW = (255, 214, 0) # JJ 글자 (검은 바탕에서 눈에 띄게)
-OUTLINE = (0, 0, 0) # JJ 테두리
FONT = 'C:/Windows/Fonts/seguibl.ttf' # Segoe UI Black
+DEFAULT = 'yellow'
+IDS = ['yellow', 'black', 'film_jj', 'film', 'blue']
+
+WHITE = (255, 255, 255)
+BLACK = (0, 0, 0)
+YELLOW = (255, 210, 0) # 노란 아이콘 바탕
+JJ_YELLOW = (255, 214, 0) # 검은 · 빨간 아이콘의 JJ 글자
def lerp(a, b, t):
return tuple(round(a[i] + (b[i] - a[i]) * t) for i in range(3))
-def rounded_mask(size, radius):
- m = Image.new('L', (size, size), 0)
- ImageDraw.Draw(m).rounded_rectangle((0, 0, size - 1, size - 1), radius=radius, fill=255)
+def rounded_mask(radius):
+ m = Image.new('L', (S, S), 0)
+ ImageDraw.Draw(m).rounded_rectangle((0, 0, S - 1, S - 1), radius=int(S * radius), fill=255)
return m
-def gradient(size):
- """대각선 그라데이션 (왼쪽 위 짙은 회색 → 오른쪽 아래 검정) + 왼쪽 위의 은은한 빛"""
- g = Image.new('RGB', (size, size))
+def gradient(c1, c2, glow=0):
+ """대각선 그라데이션 (왼쪽 위 c1 → 오른쪽 아래 c2) + 왼쪽 위의 은은한 빛"""
+ g = Image.new('RGB', (S, S))
px = g.load()
- for y in range(size):
- for x in range(size):
- px[x, y] = lerp(TOP, BOTTOM, (x + y) / (2 * (size - 1)))
- glow = Image.new('L', (size, size), 0)
- ImageDraw.Draw(glow).ellipse((-size * 0.4, -size * 0.5, size * 0.8, size * 0.45), fill=22)
- glow = glow.filter(ImageFilter.GaussianBlur(size * 0.15))
- return Image.composite(Image.new('RGB', (size, size), (255, 255, 255)), g, glow)
+ for y in range(S):
+ for x in range(S):
+ px[x, y] = lerp(c1, c2, (x + y) / (2 * (S - 1)))
+ if glow:
+ m = Image.new('L', (S, S), 0)
+ ImageDraw.Draw(m).ellipse((-S * 0.4, -S * 0.5, S * 0.8, S * 0.45), fill=glow)
+ m = m.filter(ImageFilter.GaussianBlur(S * 0.15))
+ g = Image.composite(Image.new('RGB', (S, S), WHITE), g, m)
+ return g
-def play(size, scale=1.0, cx=0.5, cy=0.5):
- """흰 재생 버튼 (모서리가 둥근 굵은 삼각형 + 그림자) 만 있는 투명 그림"""
- layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
- h = size * 0.46 * scale # 삼각형 높이 (세로)
- w = h * 0.92 # 너비
- # 무게 중심이 가운데 오도록 약간 오른쪽으로
- x0 = size * cx - w * 0.40
- y0 = size * cy - h / 2
+def play(scale=1.0, cx=0.5, cy=0.5, color=WHITE, shadow=(0, 0, 0, 200)):
+ """재생 버튼 (모서리가 둥근 굵은 삼각형). shadow=None: 그림자 없음 (단색 아이콘)"""
+ layer = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ h = S * 0.46 * scale
+ w = h * 0.92
+ x0 = S * cx - w * 0.40 # 무게 중심이 가운데 오도록 약간 오른쪽으로
+ y0 = S * cy - h / 2
pts = [(x0, y0), (x0, y0 + h), (x0 + w, y0 + h / 2)]
- r = size * 0.05 * scale # 모서리 둥글기 (선 두께로)
+ r = S * 0.05 * scale
def draw(img, fill, off=(0, 0)):
d = ImageDraw.Draw(img)
@@ -66,132 +73,201 @@ def play(size, scale=1.0, cx=0.5, cy=0.5):
for x, y in p:
d.ellipse((x - r, y - r, x + r, y + r), fill=fill)
- shadow = Image.new('RGBA', (size, size), (0, 0, 0, 0))
- draw(shadow, (0, 0, 0, 200), off=(size * 0.012 * scale, size * 0.028 * scale))
- shadow = shadow.filter(ImageFilter.GaussianBlur(size * 0.025 * scale))
- layer = Image.alpha_composite(layer, shadow)
- draw(layer, (255, 255, 255, 255))
+ if shadow:
+ sh = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ draw(sh, shadow, off=(S * 0.012 * scale, S * 0.028 * scale))
+ layer = Image.alpha_composite(layer, sh.filter(ImageFilter.GaussianBlur(S * 0.025 * scale)))
+ draw(layer, color + (255,))
return layer
-def jj(size, cx, top, bottom):
- """왼쪽에 J 를 위 · 아래로 하나씩 (노란 굵은 글자 + 진한 테두리 + 그림자)"""
- layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
+def jj(cx, top, bottom, color, outline=None, shadow=True):
+ """J 를 위 · 아래로 하나씩. outline: 테두리 색 (글자와 같은 색이면 더 굵게), shadow: 그림자"""
+ layer = Image.new('RGBA', (S, S), (0, 0, 0, 0))
h = (bottom - top) / 2
font = ImageFont.truetype(FONT, int(h * 1.18))
- stroke = max(2, int(h * 0.09))
- shadow = Image.new('RGBA', (size, size), (0, 0, 0, 0))
+ # 글자와 같은 색 테두리는 살짝만 (위아래 J 가 붙지 않게)
+ stroke = 0 if not outline else int(h * (0.03 if outline == color else 0.09))
+ sh = Image.new('RGBA', (S, S), (0, 0, 0, 0))
for i in range(2):
d = ImageDraw.Draw(layer)
l, t, r, b = d.textbbox((0, 0), 'J', font=font, stroke_width=stroke)
x = cx - (l + r) / 2
y = top + h * i + (h - (b - t)) / 2 - t
- ImageDraw.Draw(shadow).text((x + h * 0.04, y + h * 0.07), 'J', font=font, fill=(0, 0, 0, 200),
+ if outline and shadow:
+ ImageDraw.Draw(sh).text((x + h * 0.04, y + h * 0.07), 'J', font=font, fill=(0, 0, 0, 200),
stroke_width=stroke, stroke_fill=(0, 0, 0, 200))
- d.text((x, y), 'J', font=font, fill=YELLOW + (255,), stroke_width=stroke, stroke_fill=OUTLINE + (255,))
- shadow = shadow.filter(ImageFilter.GaussianBlur(h * 0.05))
- return Image.alpha_composite(shadow, layer)
-
-
-def film_bands(size, top, band, holes=6):
- """위아래 필름 띠 (어두운 띠 + 흰 구멍)"""
- layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
- d = ImageDraw.Draw(layer)
- for y0 in (top, size - top - band):
- d.rectangle((0, y0, size, y0 + band), fill=FILM + (255,))
- hw, hh = size / (holes * 2.2), band * 0.46
- gap = size / holes
- for i in range(holes):
- cx = gap * (i + 0.5)
- cy = y0 + band / 2
- d.rounded_rectangle((cx - hw / 2, cy - hh / 2, cx + hw / 2, cy + hh / 2), radius=hh * 0.3,
- fill=(235, 235, 240, 255))
+ d.text((x, y), 'J', font=font, fill=color + (255,), stroke_width=stroke,
+ stroke_fill=(outline or color) + (255,))
+ if outline and shadow:
+ layer = Image.alpha_composite(sh.filter(ImageFilter.GaussianBlur(h * 0.05)), layer)
return layer
-def make_master(small=False):
- """앱 아이콘 (둥근 사각형). small=True: 16~32px 용 (필름 띠 없이 재생 버튼을 크게)"""
- icon = Image.new('RGBA', (S, S), (0, 0, 0, 0))
- icon.paste(gradient(S), (0, 0), rounded_mask(S, int(S * 0.22)))
- if small:
- return Image.alpha_composite(icon, play(S, scale=1.25))
- bands = film_bands(S, top=int(S * 0.055), band=int(S * 0.13))
- icon = Image.alpha_composite(icon, Image.composite(bands, Image.new('RGBA', (S, S)), rounded_mask(S, int(S * 0.22))))
- # 왼쪽: J · J (위 · 아래), 재생 버튼은 오른쪽으로
- icon = Image.alpha_composite(icon, jj(S, cx=S * 0.19, top=S * 0.23, bottom=S * 0.77))
- return Image.alpha_composite(icon, play(S, scale=0.92, cx=0.6))
+def film_bands(top, band, film, hole, holes=6):
+ """위아래 필름 띠 (어두운 띠 + 밝은 구멍)"""
+ layer = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ d = ImageDraw.Draw(layer)
+ for y0 in (top, S - top - band):
+ d.rectangle((0, y0, S, y0 + band), fill=film + (255,))
+ hw, hh = S / (holes * 2.2), band * 0.46
+ gap = S / holes
+ for i in range(holes):
+ cx, cy = gap * (i + 0.5), y0 + band / 2
+ d.rounded_rectangle((cx - hw / 2, cy - hh / 2, cx + hw / 2, cy + hh / 2), radius=hh * 0.3,
+ fill=hole + (255,))
+ return layer
-def make_adaptive():
- """Android 8 이상 (adaptive icon): 108dp 바탕 (그라데이션 + 필름 띠) · 앞 (재생 버튼, 안전 영역 66dp 안)"""
- bg = gradient(S).convert('RGBA')
- bg = Image.alpha_composite(bg, film_bands(S, top=int(S * 0.17), band=int(S * 0.1), holes=7))
- # 안전 영역 (가운데 66/108) 안에: 왼쪽 J · J, 오른쪽 재생 버튼
- fg = Image.alpha_composite(jj(S, cx=S * 0.335, top=S * 0.31, bottom=S * 0.69), play(S, scale=0.55, cx=0.57))
- return bg, fg
+def on(bg, *layers, radius=0.22):
+ """둥근 사각형 바탕 위에 그림들을 겹친다 (바깥으로 나간 부분은 자름)"""
+ mask = rounded_mask(radius)
+ img = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ img.paste(bg, (0, 0), mask)
+ for l in layers:
+ img = Image.alpha_composite(img, Image.composite(l, Image.new('RGBA', (S, S)), mask))
+ return img
+
+
+def big_jj(color, outline=None, size=0.62):
+ """가운데 큰 JJ (앱 안 26px 버튼처럼 작아도 또렷하게)"""
+ layer = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ font = ImageFont.truetype(FONT, int(S * size))
+ d = ImageDraw.Draw(layer)
+ stroke = int(S * 0.035) if outline else 0
+ l, t, r, b = d.textbbox((0, 0), 'JJ', font=font, stroke_width=stroke)
+ d.text(((S - (r - l)) / 2 - l, (S - (b - t)) / 2 - t), 'JJ', font=font, fill=color + (255,),
+ stroke_width=stroke, stroke_fill=(outline or color) + (255,))
+ return layer
+
+
+def variant(vid):
+ """아이콘 하나: (큰 아이콘, 16~32px 용, 앱 안 버튼, Android 바탕, Android 앞)"""
+ if vid == 'yellow':
+ # 노랑 + 검정 두 가지 색만: 그림자 · 테두리 없이 단순하게
+ bg = Image.new('RGB', (S, S), YELLOW)
+ master = on(bg, jj(S * 0.215, S * 0.2, S * 0.8, BLACK, BLACK, shadow=False), play(0.95, cx=0.6, color=BLACK, shadow=None))
+ small = on(bg, play(1.3, color=BLACK, shadow=None))
+ button = on(bg, big_jj(BLACK))
+ fg = Image.alpha_composite(jj(S * 0.345, S * 0.3, S * 0.7, BLACK, BLACK, shadow=False),
+ play(0.55, cx=0.575, color=BLACK, shadow=None))
+ return master, small, button, bg.convert('RGBA'), fg
+
+ if vid in ('black', 'film_jj', 'film'):
+ if vid == 'black':
+ bg, film, hole, outline = gradient((58, 58, 66), (6, 6, 8), glow=22), BLACK, (235, 235, 240), BLACK
+ else:
+ bg, film, hole, outline = gradient((255, 45, 85), (255, 149, 0), glow=45), (25, 10, 30), WHITE, (60, 0, 30)
+ bands = film_bands(int(S * 0.055), int(S * 0.13), film, hole)
+ if vid == 'film':
+ master = on(bg, bands, play(1.0))
+ fg = play(0.62)
+ else:
+ master = on(bg, bands, jj(S * 0.19, S * 0.23, S * 0.77, JJ_YELLOW, outline), play(0.92, cx=0.6))
+ fg = Image.alpha_composite(jj(S * 0.335, S * 0.31, S * 0.69, JJ_YELLOW, outline), play(0.55, cx=0.57))
+ small = on(bg, play(1.25))
+ button = on(bg, big_jj(JJ_YELLOW, outline))
+ a_bg = Image.alpha_composite(bg.convert('RGBA'), film_bands(int(S * 0.17), int(S * 0.1), film, hole, holes=7))
+ return master, small, button, a_bg, fg
+
+ # blue: 처음 아이콘 (청록 → 보라 + 흰 JJ + 오른쪽 아래 흰 동그라미 재생 표시)
+ violet = (108, 92, 255)
+ bg = gradient((0, 196, 204), violet, glow=38)
+
+ def white_jj(size, dx, dy):
+ layer = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ font = ImageFont.truetype(FONT, int(S * size))
+ l, t, r, b = ImageDraw.Draw(layer).textbbox((0, 0), 'JJ', font=font)
+ x, y = (S - (r - l)) / 2 - l + dx, (S - (b - t)) / 2 - t + dy
+ sh = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ ImageDraw.Draw(sh).text((x + S * 0.012, y + S * 0.022), 'JJ', font=font, fill=(20, 10, 60, 120))
+ layer = Image.alpha_composite(layer, sh.filter(ImageFilter.GaussianBlur(S * 0.018)))
+ ImageDraw.Draw(layer).text((x, y), 'JJ', font=font, fill=WHITE + (255,))
+ return layer
+
+ def badge(cx, cy, rad):
+ b = Image.new('RGBA', (S, S), (0, 0, 0, 0))
+ ImageDraw.Draw(b).ellipse((cx - rad * 1.12, cy - rad * 1.12, cx + rad * 1.12, cy + rad * 1.12),
+ fill=(40, 20, 110, 90))
+ b = b.filter(ImageFilter.GaussianBlur(S * 0.012))
+ d = ImageDraw.Draw(b)
+ d.ellipse((cx - rad, cy - rad, cx + rad, cy + rad), fill=WHITE + (255,))
+ tri = rad * 0.52
+ d.polygon([(cx - tri * 0.62, cy - tri), (cx - tri * 0.62, cy + tri), (cx + tri * 0.95, cy)],
+ fill=violet + (255,))
+ return b
+
+ master = on(bg, white_jj(0.56, -S * 0.035, -S * 0.02), badge(S * 0.765, S * 0.765, S * 0.135), radius=0.23)
+ small = on(bg, white_jj(0.66, 0, 0), radius=0.23)
+ fg = Image.alpha_composite(white_jj(0.36, -S * 0.02, -S * 0.01), badge(S * 0.64, S * 0.64, S * 0.085))
+ return master, small, small, bg.convert('RGBA'), fg
+
+
+def save_ico(path, master, small, sizes):
+ imgs = [(small if s <= 32 else master).resize((s, s), Image.LANCZOS) for s in sizes]
+ imgs[-1].save(path, format='ICO', sizes=[(s, s) for s in sizes], append_images=imgs[:-1])
def main():
- master = make_master()
- out = ROOT / 'assets' / 'icon'
+ icon_dir = ROOT / 'assets' / 'icon'
+ out = icon_dir / 'variants'
out.mkdir(parents=True, exist_ok=True)
- master.save(out / 'app_icon_1024.png')
- master.resize((256, 256), Image.LANCZOS).save(out / 'app_icon_256.png')
-
- # 앱 안 왼쪽 위 홈 버튼 (26px 정도): 바탕 + 큰 노란 JJ 만 (작아도 또렷하게)
- button = Image.new('RGBA', (S, S), (0, 0, 0, 0))
- button.paste(gradient(S), (0, 0), rounded_mask(S, int(S * 0.22)))
- font = ImageFont.truetype(FONT, int(S * 0.62))
- d = ImageDraw.Draw(button)
- stroke = int(S * 0.035)
- l, t, r, b = d.textbbox((0, 0), 'JJ', font=font, stroke_width=stroke)
- d.text(((S - (r - l)) / 2 - l, (S - (b - t)) / 2 - t), 'JJ', font=font, fill=YELLOW + (255,),
- stroke_width=stroke, stroke_fill=OUTLINE + (255,))
- button.resize((256, 256), Image.LANCZOS).save(out / 'app_button_256.png')
-
- # 작은 크기 (16~32px) 는 단순 버전, 큰 크기는 필름 띠 포함 버전
- simple = make_master(small=True)
- simple.resize((256, 256), Image.LANCZOS).save(out / 'app_icon_small_256.png')
-
- def ico(path, sizes):
- imgs = [(simple if s <= 32 else master).resize((s, s), Image.LANCZOS) for s in sizes]
- imgs[-1].save(path, format='ICO', sizes=[(s, s) for s in sizes], append_images=imgs[:-1])
-
- ico(ROOT / 'windows' / 'runner' / 'resources' / 'app_icon.ico', [16, 20, 24, 32, 40, 48, 64, 128, 256])
- ico(ROOT / 'assets' / 'tray_icon.ico', [16, 20, 24, 32, 48])
-
- # Android: 예전 기기용 아이콘 + Android 8 이상 adaptive icon (기기마다 다른 모양 틀에 꽉 차게)
res = ROOT / 'android' / 'app' / 'src' / 'main' / 'res'
- bg, fg = make_adaptive()
- for name, px in {'mdpi': 48, 'hdpi': 72, 'xhdpi': 96, 'xxhdpi': 144, 'xxxhdpi': 192}.items():
- d = res / f'mipmap-{name}'
- d.mkdir(parents=True, exist_ok=True)
- master.resize((px, px), Image.LANCZOS).save(d / 'ic_launcher.png')
- a = px * 108 // 48 # adaptive 는 108dp
- bg.resize((a, a), Image.LANCZOS).save(d / 'ic_launcher_background.png')
- fg.resize((a, a), Image.LANCZOS).save(d / 'ic_launcher_foreground.png')
any_dpi = res / 'mipmap-anydpi-v26'
any_dpi.mkdir(parents=True, exist_ok=True)
- (any_dpi / 'ic_launcher.xml').write_text(
- '\n'
- '\n'
- ' \n'
- ' \n'
- ' \n'
- '\n', encoding='utf-8')
+ dpis = {'mdpi': 48, 'hdpi': 72, 'xhdpi': 96, 'xxhdpi': 144, 'xxxhdpi': 192}
+ # 예전 판에서 만든 파일 정리
+ for name in ('app_icon_256.png', 'app_icon_small_256.png', 'app_button_256.png', 'preview.png'):
+ (icon_dir / name).unlink(missing_ok=True)
+ for d in res.glob('mipmap-*'):
+ for f in d.glob('ic_launcher*'):
+ f.unlink()
- # 미리보기 (원형 마스크 · 둥근 사각형 마스크)
- prev = Image.new('RGBA', (S * 3 + 80, S + 40), (40, 40, 48, 255))
- prev.alpha_composite(master, (20, 20))
- full = Image.alpha_composite(bg, fg)
- crop = int(S * 18 / 108)
- view = full.crop((crop, crop, S - crop, S - crop)).resize((S, S), Image.LANCZOS)
- circle = Image.new('L', (S, S), 0)
- ImageDraw.Draw(circle).ellipse((0, 0, S, S), fill=255)
- prev.paste(view, (S + 40, 20), circle)
- prev.paste(view, (S * 2 + 60, 20), rounded_mask(S, int(S * 0.3)))
- prev.resize((prev.width // 4, prev.height // 4), Image.LANCZOS).save(out / 'preview.png')
- print('아이콘 생성 완료:', out / 'app_icon_1024.png')
+ all_icons = {}
+ for vid in IDS:
+ master, small, button, a_bg, a_fg = all_icons[vid] = variant(vid)
+ master.resize((256, 256), Image.LANCZOS).save(out / f'{vid}_256.png')
+ button.resize((128, 128), Image.LANCZOS).save(out / f'{vid}_button.png')
+ save_ico(out / f'{vid}.ico', master, small, [16, 20, 24, 32, 40, 48, 64, 128, 256])
+ # Android: 고를 수 있는 아이콘마다 ic_launcher_, 기본 아이콘은 ic_launcher 로도
+ for name in [f'_{vid}'] + ([''] if vid == DEFAULT else []):
+ for dpi, px in dpis.items():
+ d = res / f'mipmap-{dpi}'
+ d.mkdir(parents=True, exist_ok=True)
+ master.resize((px, px), Image.LANCZOS).save(d / f'ic_launcher{name}.png')
+ a = px * 108 // 48 # adaptive 는 108dp
+ a_bg.resize((a, a), Image.LANCZOS).save(d / f'ic_launcher{name}_bg.png')
+ a_fg.resize((a, a), Image.LANCZOS).save(d / f'ic_launcher{name}_fg.png')
+ (any_dpi / f'ic_launcher{name}.xml').write_text(
+ '\n'
+ '\n'
+ f' \n'
+ f' \n'
+ f' \n'
+ '\n', encoding='utf-8')
+ if vid == DEFAULT:
+ master.save(icon_dir / 'app_icon_1024.png')
+ save_ico(ROOT / 'windows' / 'runner' / 'resources' / 'app_icon.ico', master, small,
+ [16, 20, 24, 32, 40, 48, 64, 128, 256])
+ save_ico(ROOT / 'assets' / 'tray_icon.ico', master, small, [16, 20, 24, 32, 48])
+
+ # 한눈에 보기: 줄마다 큰 아이콘 · Android 동그라미 · 앱 안 버튼 / 16px
+ prev = Image.new('RGBA', (len(IDS) * 280 + 20, 660), (128, 128, 136, 255))
+ circle = Image.new('L', (256, 256), 0)
+ ImageDraw.Draw(circle).ellipse((0, 0, 255, 255), fill=255)
+ c = int(S * 18 / 108)
+ for i, vid in enumerate(IDS):
+ master, small, button, a_bg, a_fg = all_icons[vid]
+ x = 20 + i * 280
+ prev.alpha_composite(master.resize((256, 256), Image.LANCZOS), (x, 20))
+ full = Image.alpha_composite(a_bg, a_fg).crop((c, c, S - c, S - c)).resize((256, 256), Image.LANCZOS)
+ prev.paste(full, (x, 296), circle)
+ prev.alpha_composite(button.resize((52, 52), Image.LANCZOS), (x, 580))
+ prev.alpha_composite(small.resize((32, 32), Image.LANCZOS), (x + 80, 590))
+ prev.alpha_composite(small.resize((16, 16), Image.LANCZOS), (x + 130, 598))
+ (ROOT / 'build').mkdir(exist_ok=True)
+ prev.save(ROOT / 'build' / 'icon_preview.png')
+ print('icons ok')
if __name__ == '__main__':
diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico
index 9ea798c..51f68b7 100644
Binary files a/windows/runner/resources/app_icon.ico and b/windows/runner/resources/app_icon.ico differ