# 🎨 Кнопки Bottom Sheet - Расположение и Иконки ## 📍 Где находятся эти кнопки? **Файл:** [lib/features/profile/add/add_profile_modal.dart](../lib/features/profile/add/add_profile_modal.dart) **Класс:** `AddProfileModal` (extends `HookConsumerWidget`) --- ## 🖼️ Структура кнопок ### 1. **"Добавить из буфера обмена"** (Clipboard) ```dart _Button( key: const ValueKey("add_from_clipboard_button"), label: t.profile.add.fromClipboard, icon: FluentIcons.clipboard_paste_24_regular, // ← ИКОНКА size: buttonWidth, onTap: () async { final captureResult = await Clipboard.getData(Clipboard.kTextPlain).then((value) => value?.text ?? ''); if (addProfileState.isLoading) return; ref.read(addProfileProvider.notifier).add(captureResult); }, ) ``` **Иконка:** `FluentIcons.clipboard_paste_24_regular` **Перевод:** `t.profile.add.fromClipboard` → "Добавить из буфера обмена" **Цвет:** `theme.colorScheme.primary` (основной цвет темы) --- ### 2. **"Сканировать QR-код"** (QR Code) ```dart _Button( key: const ValueKey("add_by_qr_code_button"), label: t.profile.add.scanQr, icon: FluentIcons.qr_code_24_regular, // ← ИКОНКА size: buttonWidth, onTap: () async { final cr = await const QRCodeScannerScreen().open(context); if (cr == null) return; if (addProfileState.isLoading) return; ref.read(addProfileProvider.notifier).add(cr); }, ) ``` **Иконка:** `FluentIcons.qr_code_24_regular` **Перевод:** `t.profile.add.scanQr` → "Сканировать QR-код" **Цвет:** `theme.colorScheme.primary` **Условие:** Показывается только на мобильных (`!PlatformUtils.isDesktop`) --- ### 3. **"Добавить WARP"** ```dart Material( key: const ValueKey("add_warp_button"), elevation: 8, color: theme.colorScheme.surface, surfaceTintColor: theme.colorScheme.surfaceTint, shadowColor: Colors.transparent, borderRadius: BorderRadius.circular(8), clipBehavior: Clip.antiAlias, child: InkWell( onTap: () async { await addProfileModal(context, ref); }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( FluentIcons.add_24_regular, // ← ИКОНКА color: theme.colorScheme.primary, ), const SizedBox(width: 8), Text( t.profile.add.addWarp, // "Добавить WARP" style: theme.textTheme.labelLarge?.copyWith( color: theme.colorScheme.primary, ), ), ], ), ), ) ``` **Иконка:** `FluentIcons.add_24_regular` **Перевод:** `t.profile.add.addWarp` → "Добавить WARP" **Стиль:** Полная ширина кнопка с текстом и иконкой --- ### 4. **"Ввести вручную"** ```dart _Button( key: const ValueKey("add_manually_button"), label: t.profile.add.manually, icon: FluentIcons.add_24_regular, // ← ИКОНКА size: buttonWidth, onTap: () async { context.pop(); await const NewProfileRoute().push(context); }, ) ``` **Иконка:** `FluentIcons.add_24_regular` **Перевод:** `t.profile.add.manually` → "Ввести вручную" **Условие:** - На мобильных → показывается как отдельная кнопка внизу - На Desktop → показывается вместо кнопки "Сканировать QR-код" --- ## 🎨 Откуда берутся иконки? ### Пакет: **fluentui_system_icons** **pubspec.yaml:** ```yaml dependencies: fluentui_system_icons: ^1.1.229 ``` **Импорт:** ```dart import 'package:fluentui_system_icons/fluentui_system_icons.dart'; ``` ### Используемые иконки: | Иконка | Код | Описание | |--------|-----|----------| | 📋 | `FluentIcons.clipboard_paste_24_regular` | Буфер обмена | | 📷 | `FluentIcons.qr_code_24_regular` | QR-код | | ➕ | `FluentIcons.add_24_regular` | Добавить/Плюс | --- ## 🎨 Как иконки меняют цвет? ### Автоматическая смена цвета через Theme ```dart Icon( FluentIcons.clipboard_paste_24_regular, size: buttonWidth / 3, color: theme.colorScheme.primary, // ← ЦВЕТ ИЗ ТЕМЫ ) ``` **Откуда берётся цвет:** - `theme.colorScheme.primary` - основной цвет темы - Меняется автоматически при смене темы (светлая/тёмная) - Определяется в настройках темы приложения --- ## 🎨 Где определяется тема? **Путь к настройкам темы:** ```dart // Тема определяется в: lib/core/preferences/ lib/features/config_option/ ``` **Как работает смена цвета:** 1. **Пользователь выбирает тему** (светлую/тёмную/автоматическую) 2. **Flutter Theme система** применяет `ColorScheme` 3. **ColorScheme.primary** меняется на цвет из палитры темы 4. **Icon виджеты** автоматически перерисовываются с новым цветом **Пример:** ```dart // Светлая тема colorScheme: ColorScheme.light( primary: Color(0xFF007AFF), // Синий ) // Тёмная тема colorScheme: ColorScheme.dark( primary: Color(0xFF0A84FF), // Светло-синий ) ``` --- ## 📦 Формат иконок ### FluentUI System Icons - это векторные иконки **Технические детали:** - **Формат:** IconData (Flutter встроенный формат) - **Источник:** Microsoft Fluent Design System - **Размер:** Масштабируемые (векторные, не растровые) - **Цвет:** Одноцветные, цвет задаётся программно - **Вариации:** `_regular`, `_filled` (обычные и заполненные) **НЕ PNG, НЕ SVG файлы!** Это встроенные векторные глифы в шрифте. --- ## 🎨 Как изменить иконки? ### Вариант 1: Использовать другую иконку из того же пакета ```dart // Было: icon: FluentIcons.clipboard_paste_24_regular, // Стало: icon: FluentIcons.copy_24_regular, // Другая иконка ``` **Посмотреть все доступные иконки:** https://github.com/microsoft/fluentui-system-icons/tree/main/fonts ### Вариант 2: Использовать Material Icons ```dart // Изменить импорт import 'package:flutter/material.dart'; // Использовать Material иконку icon: Icons.content_paste, ``` ### Вариант 3: Использовать свои SVG иконки **1. Добавьте пакет flutter_svg:** ```yaml dependencies: flutter_svg: ^2.0.10 ``` **2. Сохраните SVG в assets:** ``` assets/images/icons/clipboard.svg assets/images/icons/qr_code.svg ``` **3. Используйте в коде:** ```dart // Вместо Icon виджета SvgPicture.asset( 'assets/images/icons/clipboard.svg', width: size / 3, height: size / 3, colorFilter: ColorFilter.mode( theme.colorScheme.primary, BlendMode.srcIn, ), ) ``` --- ## 🔧 Как изменить размер иконок? ```dart Icon( FluentIcons.clipboard_paste_24_regular, size: buttonWidth / 3, // ← РАЗМЕР color: theme.colorScheme.primary, ) ``` **Текущий размер:** `buttonWidth / 3` - buttonWidth рассчитывается из ширины экрана - Примерно 48-56 пикселей для иконки **Чтобы изменить:** ```dart // Фиксированный размер size: 64, // Относительный размер size: buttonWidth / 2, // Больше size: buttonWidth / 4, // Меньше ``` --- ## 🎨 Как изменить цвет иконок? ### Вариант 1: Использовать другой цвет из темы ```dart Icon( FluentIcons.clipboard_paste_24_regular, color: theme.colorScheme.secondary, // Вторичный цвет // или: // color: theme.colorScheme.tertiary, // color: theme.colorScheme.error, // color: theme.colorScheme.onSurface, ) ``` ### Вариант 2: Использовать кастомный цвет ```dart Icon( FluentIcons.clipboard_paste_24_regular, color: Color(0xFF00FF00), // Зелёный // или: // color: Colors.red, // color: Colors.amber, ) ``` ### Вариант 3: Градиент (сложнее) Для градиента нужно использовать `ShaderMask`: ```dart ShaderMask( shaderCallback: (Rect bounds) { return LinearGradient( colors: [Colors.blue, Colors.purple], ).createShader(bounds); }, child: Icon( FluentIcons.clipboard_paste_24_regular, size: buttonWidth / 3, color: Colors.white, // Базовый цвет (будет заменён градиентом) ), ) ``` --- ## 📱 Адаптивность кнопок ### Мобильные (Android/iOS): ```dart if (!PlatformUtils.isDesktop) _Button( label: t.profile.add.scanQr, icon: FluentIcons.qr_code_24_regular, ) ``` **Показывается:** - ✅ Добавить из буфера обмена - ✅ Сканировать QR-код - ✅ Добавить WARP - ✅ Ввести вручную ### Desktop (Windows/macOS/Linux): ```dart else _Button( label: t.profile.add.manually, icon: FluentIcons.add_24_regular, ) ``` **Показывается:** - ✅ Добавить из буфера обмена - ✅ Ввести вручную (вместо QR) - ✅ Добавить WARP --- ## 🎯 Класс _Button **Виджет для квадратных кнопок:** ```dart class _Button extends StatelessWidget { final String label; // Текст кнопки final IconData icon; // Иконка (FluentIcons.*) final double size; // Размер кнопки (квадрат) final VoidCallback onTap; // Действие при нажатии @override Widget build(BuildContext context) { return SizedBox( width: size, height: size, child: Material( elevation: 8, // Тень color: theme.colorScheme.surface, borderRadius: BorderRadius.circular(8), child: InkWell( onTap: onTap, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, size: size / 3, color: color), const Gap(16), Text(label, style: labelStyle), ], ), ), ), ); } } ``` **Свойства:** - Квадратная форма (`width = height = size`) - Иконка вверху (1/3 размера кнопки) - Текст внизу - Скругленные углы (8px) - Тень (elevation: 8) - Ripple эффект при нажатии (InkWell) --- ## 🎨 Цветовая схема по умолчанию **Где определяется primary цвет:** ```dart // Вероятно в: lib/core/preferences/general_preferences_provider.dart lib/core/theme/ ``` **Umbrix использует:** - **Primary color:** Бирюзовый/голубой (#00BCD4 или похожий) - **Surface:** Фон карточек - **OnSurface:** Текст на фоне --- ## 💡 Быстрые изменения ### Изменить цвет всех иконок на красный: ```dart Icon( icon, size: size / 3, color: Colors.red, // ← ВСЕ ИКОНКИ СТАНУТ КРАСНЫМИ ) ``` ### Изменить размер иконок на больший: ```dart Icon( icon, size: size / 2, // ← БЫЛО /3, СТАЛО /2 (больше) color: color, ) ``` ### Использовать заполненные (filled) иконки: ```dart // Было: icon: FluentIcons.clipboard_paste_24_regular, // Стало: icon: FluentIcons.clipboard_paste_24_filled, // Заполненная версия ``` --- ## 🔍 Где ещё используются FluentIcons? **Поиск по проекту:** ```bash grep -r "FluentIcons\." lib/ | wc -l # Результат: Много! Используются по всему приложению ``` **Примеры файлов:** - `lib/features/home/widget/home_page.dart` - `lib/features/proxy/overview/proxies_overview_page.dart` - `lib/features/common/adaptive_root_scaffold.dart` --- ## 📚 Полезные ссылки 1. **Fluent UI Icons Gallery:** https://aka.ms/fluentui-system-icons 2. **Flutter Icon класс:** https://api.flutter.dev/flutter/widgets/Icon-class.html 3. **ColorScheme документация:** https://api.flutter.dev/flutter/material/ColorScheme-class.html 4. **Пакет fluentui_system_icons:** https://pub.dev/packages/fluentui_system_icons --- ## 🎯 Резюме **Кнопки находятся:** `lib/features/profile/add/add_profile_modal.dart` **Иконки:** - Формат: IconData из пакета `fluentui_system_icons` - НЕ файлы PNG/SVG, а векторные глифы в шрифте - Цвет: `theme.colorScheme.primary` (меняется с темой) - Размер: Масштабируемые, задаются программно **Смена цвета:** - Автоматическая через Theme системы Flutter - `colorScheme.primary` берётся из настроек темы - Светлая/тёмная тема → разные оттенки **Чтобы изменить:** 1. Цвет → поменять `color: theme.colorScheme.primary` на другой 2. Размер → изменить `size: buttonWidth / 3` 3. Иконку → заменить `FluentIcons.clipboard_paste_24_regular` на другую 4. Свою иконку → использовать SVG через flutter_svg пакет