Files
umbrix/docs/BOTTOM_SHEET_BUTTONS.md

524 lines
14 KiB
Markdown
Raw Normal View History

# 🎨 Кнопки 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 пакет