diff --git a/app/android/app/src/main/res/drawable-nodpi/splash_logo.png b/app/android/app/src/main/res/drawable-nodpi/splash_logo.png new file mode 100644 index 0000000..318cecf Binary files /dev/null and b/app/android/app/src/main/res/drawable-nodpi/splash_logo.png differ diff --git a/app/android/app/src/main/res/drawable-v21/launch_background.xml b/app/android/app/src/main/res/drawable-v21/launch_background.xml index f74085f..908e264 100644 --- a/app/android/app/src/main/res/drawable-v21/launch_background.xml +++ b/app/android/app/src/main/res/drawable-v21/launch_background.xml @@ -1,12 +1,11 @@ - + - - - + android:src="@drawable/splash_logo" /> + diff --git a/app/android/app/src/main/res/drawable/launch_background.xml b/app/android/app/src/main/res/drawable/launch_background.xml index 304732f..d1821e8 100644 --- a/app/android/app/src/main/res/drawable/launch_background.xml +++ b/app/android/app/src/main/res/drawable/launch_background.xml @@ -1,12 +1,10 @@ - + - - - + android:src="@drawable/splash_logo" /> + diff --git a/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index db77bb4..213eb70 100644 Binary files a/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 17987b7..f490fb5 100644 Binary files a/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 09d4391..84bac95 100644 Binary files a/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index d5f1c8d..9e47aac 100644 Binary files a/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 4d6372e..4579a2b 100644 Binary files a/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/assets/logo.png b/app/assets/logo.png new file mode 100644 index 0000000..dcddcd8 Binary files /dev/null and b/app/assets/logo.png differ diff --git a/app/assets/logo.svg b/app/assets/logo.svg index 53f3b80..0b777c9 100644 --- a/app/assets/logo.svg +++ b/app/assets/logo.svg @@ -24,9 +24,9 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="0.54252946" - inkscape:cx="292.15003" + inkscape:cx="291.22842" inkscape:cy="292.15003" - inkscape:window-width="1563" + inkscape:window-width="1536" inkscape:window-height="891" inkscape:window-x="0" inkscape:window-y="0" @@ -40,18 +40,27 @@ id="layer1" transform="translate(-27.689651,-71.189651)"> - + + + + diff --git a/app/linux/runner/my_application.cc b/app/linux/runner/my_application.cc index 7074cf4..5f9df19 100644 --- a/app/linux/runner/my_application.cc +++ b/app/linux/runner/my_application.cc @@ -54,6 +54,16 @@ static void my_application_activate(GApplication* application) { gtk_window_set_default_size(window, 1280, 720); + // The window wears the bundled logo, which lives beside the binary with + // the Flutter assets, where the engine also finds it. + g_autofree gchar* exe_path = g_file_read_link("/proc/self/exe", NULL); + if (exe_path != NULL) { + g_autofree gchar* exe_dir = g_path_get_dirname(exe_path); + g_autofree gchar* icon_path = g_build_filename( + exe_dir, "data", "flutter_assets", "assets", "logo.png", NULL); + gtk_window_set_icon_from_file(window, icon_path, NULL); + } + g_autoptr(FlDartProject) project = fl_dart_project_new(); fl_dart_project_set_dart_entrypoint_arguments( project, self->dart_entrypoint_arguments); diff --git a/app/pubspec.lock b/app/pubspec.lock index 2b1d7b7..6c6a73e 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -331,6 +331,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_svg: + dependency: "direct dev" + description: + name: flutter_svg + sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f" + url: "https://pub.dev" + source: hosted + version: "2.3.0" flutter_test: dependency: "direct dev" description: flutter @@ -541,6 +549,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" + url: "https://pub.dev" + source: hosted + version: "1.1.0" path_provider: dependency: "direct main" description: @@ -874,6 +890,30 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.6" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: "9d0e3b9cb16542ad660daee871e726a10d13a93b7b5391677c3160e8f5e83935" + url: "https://pub.dev" + source: hosted + version: "1.2.3" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" + url: "https://pub.dev" + source: hosted + version: "1.1.13" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "4dca4feb77dc3ec7f6e27e49c53241eb8217f55e4f9b12599a27f8903bca5682" + url: "https://pub.dev" + source: hosted + version: "1.3.0" vector_math: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 6d47b10..3542a39 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -33,11 +33,13 @@ dev_dependencies: flutter_lints: ^6.0.0 drift_dev: ^2.34.0 build_runner: ^2.14.1 + flutter_svg: ^2.3.0 flutter: uses-material-design: true assets: + - assets/logo.png - locales/en-US/main.ftl - locales/de/main.ftl - locales/es/main.ftl diff --git a/app/tool/generate_icons.dart b/app/tool/generate_icons.dart new file mode 100644 index 0000000..d6f6323 --- /dev/null +++ b/app/tool/generate_icons.dart @@ -0,0 +1,50 @@ +import 'dart:io'; +import 'dart:ui' as ui show ImageByteFormat, PictureRecorder; + + +import 'package:flutter/widgets.dart' show Canvas; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Rasterizes `assets/logo.svg` into the PNGs the platforms want: the +/// Android launcher icons at every density, the splash logo, and the +/// bundled logo the Linux window icon loads. Run with: +/// +/// flutter test tool/generate_icons.dart +/// +/// The committed PNGs are the product; this exists so a new logo can be +/// dropped in as the SVG and every platform follows in one run. +const sizes = { + 'android/app/src/main/res/mipmap-mdpi/ic_launcher.png': 48, + 'android/app/src/main/res/mipmap-hdpi/ic_launcher.png': 72, + 'android/app/src/main/res/mipmap-xhdpi/ic_launcher.png': 96, + 'android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png': 144, + 'android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png': 192, + 'android/app/src/main/res/drawable-nodpi/splash_logo.png': 432, + 'assets/logo.png': 256, +}; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + test('rasterizes the logo for every platform', () async { + final svg = File('assets/logo.svg').readAsStringSync(); + final info = await vg.loadPicture(SvgStringLoader(svg), null); + + for (final entry in sizes.entries) { + final size = entry.value; + final recorder = ui.PictureRecorder(); + final canvas = Canvas(recorder); + // The logo is square, so one scale fits both axes. + canvas.scale(size / info.size.width, size / info.size.height); + canvas.drawPicture(info.picture); + final image = await recorder.endRecording().toImage(size, size); + final bytes = await image.toByteData(format: ui.ImageByteFormat.png); + final file = File(entry.key); + await file.parent.create(recursive: true); + await file.writeAsBytes(bytes!.buffer.asUint8List()); + // ignore: avoid_print + print('wrote ${file.path} (${size}x$size)'); + } + }); +}