Packages
mob_dev
0.6.21
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.37
0.3.35
0.3.34
0.3.33
0.3.28
0.3.26
0.3.23
0.3.21
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.18
0.2.17
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Development tooling for the Mob mobile framework
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/mob.icon.ex
defmodule Mix.Tasks.Mob.Icon do
use Mix.Task
@shortdoc "Generate or regenerate app icons"
@moduledoc """
Generates platform icons for the current Mob project.
Must be run from the project root (the directory containing `mix.exs`).
mix mob.icon # random robot avatar
mix mob.icon --source PATH # resize an existing image
mix mob.icon --source PATH --adaptive # also emit adaptive Android icons
mix mob.icon --source PATH --adaptive --adaptive-bg "#E8B53C"
## Output
Writes icons into the current project directory:
- `android/app/src/main/res/mipmap-*/ic_launcher.png` (legacy)
- `ios/Assets.xcassets/AppIcon.appiconset/icon_*.png`
- `ios/Assets.xcassets/AppIcon.appiconset/Contents.json`
- `icon_source.png` (1024×1024 master, only when generating)
With `--adaptive`, also writes:
- `android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml`
- `android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml`
- `android/app/src/main/res/mipmap-*/ic_launcher_foreground.png`
- `android/app/src/main/res/values/ic_launcher_background.xml`
Adaptive icons are what modern Android launchers (Pixel, Samsung, Moto…)
expect: a foreground layer + a background colour, masked by the launcher
to whatever shape it prefers (circle, squircle, teardrop). Without them,
legacy icons get shrunk inside a launcher-supplied white circle.
## Under the hood
`mix mob.icon` uses the `image` Elixir library (backed by `libvips`) to
resize a 1024×1024 source PNG into every required platform size.
No external tools (ImageMagick, Xcode, etc.) are required — `libvips` is
bundled as a precompiled NIF via the `image` dependency.
"""
@switches [source: :string, adaptive: :boolean, adaptive_bg: :string]
@impl Mix.Task
def run(argv) do
{opts, _args, _} = OptionParser.parse(argv, strict: @switches)
project_dir = File.cwd!()
unless File.exists?(Path.join(project_dir, "mix.exs")) do
Mix.raise("No mix.exs found. Run mix mob.icon from your project root.")
end
# `--adaptive-bg` (if given) sets the flatten background for the opaque iOS
# icons too, so both platforms share one background colour; otherwise it's
# sampled from the source per platform.
icon_opts = if opts[:adaptive_bg], do: [background_color: opts[:adaptive_bg]], else: []
source =
case opts[:source] do
nil ->
Mix.shell().info("Generating random robot icon...")
MobDev.IconGenerator.generate_random(project_dir, icon_opts)
Path.join(project_dir, "icon_source.png")
source ->
unless File.exists?(source) do
Mix.raise("Source file not found: #{source}")
end
Mix.shell().info("Resizing icon from #{source}...")
MobDev.IconGenerator.generate_from_source(source, project_dir, icon_opts)
source
end
if opts[:adaptive] do
Mix.shell().info("Generating adaptive Android icons...")
MobDev.IconGenerator.generate_adaptive(source, project_dir, icon_opts)
end
Mix.shell().info("Icons written to #{project_dir}")
Mix.shell().info(" Android: android/app/src/main/res/mipmap-*/ic_launcher.png")
if opts[:adaptive] do
Mix.shell().info(
" Android (adaptive): mipmap-anydpi-v26/, ic_launcher_foreground.png, values/ic_launcher_background.xml"
)
end
Mix.shell().info(" iOS: ios/Assets.xcassets/AppIcon.appiconset/")
end
end