From d7a1f2fabdfdcbeb6dbd05091e954c58a4a76dff Mon Sep 17 00:00:00 2001 From: Mikkeli Matlock Date: Sun, 25 Jan 2026 22:49:13 +0900 Subject: [PATCH] extra material and simulink creation script --- .gitignore | 9 +- pi/ui/assets/images/.gitignore | 2 + pi/ui/fonts/.gitignore | 3 + pi/ui/lib/main.dart | 2 + pi/ui/lib/screens/dashboard_screen.dart | 129 ++++++++++++++---------- pi/ui/pubspec.yaml | 15 +++ scripts/build.py | 8 ++ scripts/build.sh | 9 ++ scripts/prepare_assets.sh | 109 ++++++++++++++++++++ 9 files changed, 227 insertions(+), 59 deletions(-) create mode 100644 pi/ui/assets/images/.gitignore create mode 100644 pi/ui/fonts/.gitignore create mode 100644 scripts/prepare_assets.sh diff --git a/.gitignore b/.gitignore index 17fa13b..31d6fac 100644 --- a/.gitignore +++ b/.gitignore @@ -60,10 +60,5 @@ scripts/*.pyc scripts/*.pyo # extra resources -extra/fonts/*.ttf -extra/fonts/*.otf -extra/images/*.png -extra/images/*.jpg -extra/images/*.jpeg -extra/images/*.gif -extra/images/*.svg \ No newline at end of file +extra/fonts/ +extra/images/ \ No newline at end of file diff --git a/pi/ui/assets/images/.gitignore b/pi/ui/assets/images/.gitignore new file mode 100644 index 0000000..eb6e97c --- /dev/null +++ b/pi/ui/assets/images/.gitignore @@ -0,0 +1,2 @@ +# Generated/symlinked images - created by prepare_assets.sh +rei_default.png diff --git a/pi/ui/fonts/.gitignore b/pi/ui/fonts/.gitignore new file mode 100644 index 0000000..245c75a --- /dev/null +++ b/pi/ui/fonts/.gitignore @@ -0,0 +1,3 @@ +# Generated/symlinked font files - created by prepare_assets.sh +din1451alt.ttf +NotoSans-*.ttf diff --git a/pi/ui/lib/main.dart b/pi/ui/lib/main.dart index d89e8aa..5bd2738 100644 --- a/pi/ui/lib/main.dart +++ b/pi/ui/lib/main.dart @@ -20,6 +20,8 @@ class SmartSerowApp extends StatelessWidget { brightness: Brightness.dark, ), useMaterial3: true, + fontFamily: 'DIN1451', + fontFamilyFallback: const ['NotoSans', 'Roboto'], ), home: const AppRoot(), ); diff --git a/pi/ui/lib/screens/dashboard_screen.dart b/pi/ui/lib/screens/dashboard_screen.dart index 7ad6ffd..1a732df 100644 --- a/pi/ui/lib/screens/dashboard_screen.dart +++ b/pi/ui/lib/screens/dashboard_screen.dart @@ -52,65 +52,90 @@ class _DashboardScreenState extends State { backgroundColor: Colors.black, body: Padding( padding: const EdgeInsets.all(32), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + child: Row( children: [ - // Header - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'SMART SEROW', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: Colors.teal, - letterSpacing: 2, - ), - ), - Text( - '${_voltage.toStringAsFixed(1)}V', - style: Theme.of(context).textTheme.titleMedium?.copyWith( - color: _voltage < 12.0 ? Colors.red : Colors.green, - ), - ), - ], - ), - - const SizedBox(height: 48), - - // Main Pi temperature display + // Left side: All dashboard widgets (flex: 2) Expanded( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - _piTemp != null ? _piTemp!.toStringAsFixed(1) : '—', - style: const TextStyle( - fontSize: 180, - fontWeight: FontWeight.w200, - color: Colors.white, - height: 1, + flex: 2, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // Header + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'SMART SEROW', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: Colors.teal, + letterSpacing: 2, + ), + ), + Text( + '${_voltage.toStringAsFixed(1)}V', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: _voltage < 12.0 ? Colors.red : Colors.green, + ), + ), + ], + ), + + const SizedBox(height: 48), + + // Main Pi temperature display + Expanded( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + _piTemp != null ? _piTemp!.toStringAsFixed(1) : '—', + style: const TextStyle( + fontSize: 180, + fontWeight: FontWeight.w200, + color: Colors.white, + height: 1, + ), + ), + Text( + 'Pi Temp', + style: Theme.of(context).textTheme.headlineSmall?.copyWith( + color: Colors.grey, + ), + ), + ], ), ), - Text( - 'Pi Temp', - style: Theme.of(context).textTheme.headlineSmall?.copyWith( - color: Colors.grey, - ), - ), - ], - ), + ), + + // Bottom stats row + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + StatBox(label: 'RPM', value: _rpm.toString()), + StatBox(label: 'ENG', value: '$_temp°C'), + StatBox(label: 'GEAR', value: '—'), + ], + ), + ], ), ), - // Bottom stats row - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - StatBox(label: 'RPM', value: _rpm.toString()), - StatBox(label: 'ENG', value: '$_temp°C'), - StatBox(label: 'GEAR', value: '—'), - ], + const SizedBox(width: 32), + + // Right side: Image display (flex: 1) + Expanded( + flex: 1, + child: Center( + child: Image.asset( + 'assets/images/rei_default.png', + fit: BoxFit.contain, + errorBuilder: (context, error, stackTrace) { + // Graceful fallback - empty box if image missing + return const SizedBox.shrink(); + }, + ), + ), ), ], ), diff --git a/pi/ui/pubspec.yaml b/pi/ui/pubspec.yaml index 415dc39..c1e5787 100644 --- a/pi/ui/pubspec.yaml +++ b/pi/ui/pubspec.yaml @@ -17,3 +17,18 @@ dev_dependencies: flutter: uses-material-design: true + + assets: + - assets/images/ + + fonts: + - family: DIN1451 + fonts: + - asset: fonts/din1451alt.ttf + - family: NotoSans + fonts: + - asset: fonts/NotoSans-Regular.ttf + - asset: fonts/NotoSans-Bold.ttf + weight: 700 + - asset: fonts/NotoSans-Light.ttf + weight: 300 diff --git a/scripts/build.py b/scripts/build.py index dcacfe6..64a3f0d 100644 --- a/scripts/build.py +++ b/scripts/build.py @@ -71,6 +71,14 @@ def build(clean: bool = False) -> bool: os.chdir(UI_DIR) + # Prepare assets (fonts, images) + prepare_script = SCRIPT_DIR / "prepare_assets.sh" + if prepare_script.exists(): + print("Preparing assets...") + run(["bash", str(prepare_script)]) + else: + print(f"WARNING: {prepare_script} not found") + # Initialize elinux project if needed elinux_dir = UI_DIR / "elinux" if not elinux_dir.exists(): diff --git a/scripts/build.sh b/scripts/build.sh index 4de7eb1..b1b6318 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -36,6 +36,15 @@ echo "Cross-compiler: $CXX" cd "$UI_DIR" +# Prepare assets (fonts, images) +PREPARE_SCRIPT="$SCRIPT_DIR/prepare_assets.sh" +if [ -x "$PREPARE_SCRIPT" ]; then + echo "Preparing assets..." + "$PREPARE_SCRIPT" +else + echo "WARNING: $PREPARE_SCRIPT not found or not executable" +fi + # Initialize elinux project if not already configured if [ ! -d "elinux" ]; then echo "Initializing elinux project structure..." diff --git a/scripts/prepare_assets.sh b/scripts/prepare_assets.sh new file mode 100644 index 0000000..7b99f72 --- /dev/null +++ b/scripts/prepare_assets.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# prepare_assets.sh - Prepares fonts and images for Flutter build +# Run this before 'flutter build' to ensure assets are in place +# +# This script handles: +# - DIN1451 font: symlinks from extra/ if present, otherwise downloads Noto Sans as fallback +# - Dashboard image: symlinks from extra/ if present, otherwise skipped (handled at runtime) + +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +UI_DIR="$PROJECT_ROOT/pi/ui" +FONTS_DIR="$UI_DIR/fonts" +IMAGES_DIR="$UI_DIR/assets/images" +EXTRA_FONTS="$PROJECT_ROOT/extra/fonts" +EXTRA_IMAGES="$PROJECT_ROOT/extra/images" + +# Noto Sans download URLs (Google Fonts) +NOTO_SANS_BASE="https://github.com/googlefonts/noto-fonts/raw/main/hinted/ttf/NotoSans" +NOTO_REGULAR="$NOTO_SANS_BASE/NotoSans-Regular.ttf" +NOTO_BOLD="$NOTO_SANS_BASE/NotoSans-Bold.ttf" +NOTO_LIGHT="$NOTO_SANS_BASE/NotoSans-Light.ttf" + +echo "=== Smart Serow Asset Preparation ===" + +# --- FONTS --- +echo "" +echo "--- Fonts ---" + +# Ensure Noto Sans fallbacks exist +download_noto() { + local weight=$1 + local url=$2 + local dest="$FONTS_DIR/NotoSans-${weight}.ttf" + + if [ ! -f "$dest" ]; then + echo "Downloading Noto Sans $weight..." + curl -sL "$url" -o "$dest" || { + echo "Warning: Failed to download Noto Sans $weight" + return 1 + } + echo " -> Downloaded $dest" + else + echo " Noto Sans $weight already present" + fi +} + +download_noto "Regular" "$NOTO_REGULAR" +download_noto "Bold" "$NOTO_BOLD" +download_noto "Light" "$NOTO_LIGHT" + +# DIN1451 - symlink if available, otherwise use Noto Sans +DIN_TARGET="$FONTS_DIR/din1451alt.ttf" +DIN_SOURCE="$EXTRA_FONTS/din1451alt.ttf" + +# Remove old symlink/file to ensure fresh state +rm -f "$DIN_TARGET" + +if [ -f "$DIN_SOURCE" ]; then + echo "DIN1451 found - linking/copying" + # Try symlink first, fall back to copy (Windows compatibility) + if ln -s "$DIN_SOURCE" "$DIN_TARGET" 2>/dev/null; then + echo " -> Linked $DIN_TARGET -> $DIN_SOURCE" + else + cp "$DIN_SOURCE" "$DIN_TARGET" + echo " -> Copied $DIN_TARGET (symlinks not supported)" + fi +else + echo "DIN1451 not found - using Noto Sans as fallback" + if [ -f "$FONTS_DIR/NotoSans-Regular.ttf" ]; then + cp "$FONTS_DIR/NotoSans-Regular.ttf" "$DIN_TARGET" + echo " -> Copied Noto Sans Regular as $DIN_TARGET" + else + echo " ERROR: No fallback font available!" + exit 1 + fi +fi + +# --- IMAGES --- +echo "" +echo "--- Images ---" + +REI_TARGET="$IMAGES_DIR/rei_default.png" +REI_SOURCE="$EXTRA_IMAGES/rei_default.png" + +# Remove old symlink/file +rm -f "$REI_TARGET" + +if [ -f "$REI_SOURCE" ]; then + echo "Dashboard image found - linking/copying" + # Try symlink first, fall back to copy (Windows compatibility) + if ln -s "$REI_SOURCE" "$REI_TARGET" 2>/dev/null; then + echo " -> Linked $REI_TARGET -> $REI_SOURCE" + else + cp "$REI_SOURCE" "$REI_TARGET" + echo " -> Copied $REI_TARGET (symlinks not supported)" + fi +else + echo "Dashboard image not found - will use empty fallback at runtime" + # Create a tiny transparent PNG placeholder (1x1 pixel) + # This avoids asset not found errors while keeping the build clean + printf '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx\x9cc\x00\x01\x00\x00\x05\x00\x01\r\n-\xb4\x00\x00\x00\x00IEND\xaeB`\x82' > "$REI_TARGET" + echo " -> Created 1x1 transparent placeholder" +fi + +echo "" +echo "=== Asset preparation complete ===" +echo "You can now run: flutter build linux"