opt: color (#1782)

* fixes

* opt: color

* fix
This commit is contained in:
My-Responsitories
2025-12-18 11:08:03 +08:00
committed by GitHub
parent 11cdb67050
commit d7f7611af4
7 changed files with 102 additions and 58 deletions

View File

@@ -1,39 +1,32 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:flutter/material.dart';
import 'package:material_color_utilities/material_color_utilities.dart';
class ColorPalette extends StatelessWidget {
final Color color;
final ColorScheme colorScheme;
final bool selected;
final bool showBgColor;
const ColorPalette({
super.key,
required this.color,
required this.colorScheme,
required this.selected,
this.showBgColor = true,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final Hct hct = Hct.fromInt(color.toARGB32());
final primary = Color(Hct.from(hct.hue, 20.0, 90.0).toInt());
final tertiary = Color(Hct.from(hct.hue + 50, 20.0, 85.0).toInt());
final primaryContainer = Color(Hct.from(hct.hue, 30.0, 50.0).toInt());
Widget coloredBox(Color color) => Expanded(
child: ColoredBox(
color: color,
child: const SizedBox.expand(),
),
);
final primary = colorScheme.primary;
final tertiary = colorScheme.tertiary;
final primaryContainer = colorScheme.primaryContainer;
Widget child = ClipOval(
child: Column(
children: [
coloredBox(primary),
_coloredBox(primary),
Expanded(
child: Row(
children: [
coloredBox(tertiary),
coloredBox(primaryContainer),
_coloredBox(tertiary),
_coloredBox(primaryContainer),
],
),
),
@@ -50,7 +43,7 @@ class ColorPalette extends StatelessWidget {
width: 23,
height: 23,
decoration: BoxDecoration(
color: Color(Hct.from(hct.hue, 30.0, 40.0).toInt()),
color: colorScheme.surfaceContainer,
shape: BoxShape.circle,
),
child: Icon(
@@ -66,11 +59,20 @@ class ColorPalette extends StatelessWidget {
width: 50,
height: 50,
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: theme.colorScheme.onInverseSurface,
borderRadius: StyleString.mdRadius,
),
decoration: showBgColor
? BoxDecoration(
color: colorScheme.onInverseSurface,
borderRadius: StyleString.mdRadius,
)
: null,
child: child,
);
}
static Widget _coloredBox(Color color) => Expanded(
child: ColoredBox(
color: color,
child: const SizedBox.expand(),
),
);
}

View File

@@ -3402,6 +3402,17 @@ class EditableTextState extends State<EditableText>
if (!_isMultiline) {
_finalizeEditing(action, shouldUnfocus: true);
} else if (HardwareKeyboard.instance.isControlPressed) {
final ctr = widget.controller;
final offset = ctr.selection.end;
// delete newline
ctr.syncRichText(
TextEditingDeltaDeletion(
composing: TextRange.empty,
selection: TextSelection.collapsed(offset: offset - 1),
deletedRange: TextRange(start: offset - 1, end: offset),
oldText: ctr.text,
),
);
_finalizeEditing(action, shouldUnfocus: true);
}
case TextInputAction.done:

View File

@@ -15,6 +15,7 @@ import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/cache_manager.dart';
import 'package:PiliPlus/utils/calc_window_position.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/json_file_handler.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/path_utils.dart';
@@ -267,24 +268,14 @@ class MyApp extends StatelessWidget {
theme: ThemeUtils.getThemeData(
colorScheme: dynamicColor
? _light!
: SeedColorScheme.fromSeeds(
variant: variant,
primaryKey: brandColor,
brightness: Brightness.light,
useExpressiveOnContainerColors: false,
),
: brandColor.asColorSchemeSeed(variant, .light),
isDynamic: dynamicColor,
),
darkTheme: ThemeUtils.getThemeData(
isDark: true,
colorScheme: dynamicColor
? _dark!
: SeedColorScheme.fromSeeds(
variant: variant,
primaryKey: brandColor,
brightness: Brightness.dark,
useExpressiveOnContainerColors: false,
),
: brandColor.asColorSchemeSeed(variant, .dark),
isDynamic: dynamicColor,
),
themeMode: Pref.themeMode,
@@ -348,8 +339,8 @@ class MyApp extends StatelessWidget {
}
/// from [DynamicColorBuilderState.initPlatformState]
static Future<void> initPlatformState() async {
if (_light != null || _dark != null) return;
static Future<bool> initPlatformState() async {
if (_light != null || _dark != null) return true;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
final corePalette = await DynamicColorPlugin.getCorePalette();
@@ -360,7 +351,7 @@ class MyApp extends StatelessWidget {
}
_light = corePalette.toColorScheme();
_dark = corePalette.toColorScheme(brightness: Brightness.dark);
return;
return true;
}
} on PlatformException {
if (kDebugMode) {
@@ -375,15 +366,10 @@ class MyApp extends StatelessWidget {
if (kDebugMode) {
debugPrint('dynamic_color: Accent color detected.');
}
_light = ColorScheme.fromSeed(
seedColor: accentColor,
brightness: Brightness.light,
);
_dark = ColorScheme.fromSeed(
seedColor: accentColor,
brightness: Brightness.dark,
);
return;
final variant = FlexSchemeVariant.values[Pref.schemeVariant];
_light = accentColor.asColorSchemeSeed(variant, .light);
_dark = accentColor.asColorSchemeSeed(variant, .dark);
return true;
}
} on PlatformException {
if (kDebugMode) {
@@ -393,6 +379,8 @@ class MyApp extends StatelessWidget {
if (kDebugMode) {
debugPrint('dynamic_color: Dynamic color not detected on this device.');
}
GStorage.setting.put(SettingBoxKey.dynamicColor, false);
return false;
}
}

View File

@@ -1,6 +1,7 @@
import 'dart:io';
import 'dart:math';
import 'package:PiliPlus/common/widgets/color_palette.dart';
import 'package:PiliPlus/common/widgets/custom_toast.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
@@ -11,6 +12,7 @@ import 'package:PiliPlus/models/common/dynamic/up_panel_position.dart';
import 'package:PiliPlus/models/common/home_tab_type.dart';
import 'package:PiliPlus/models/common/msg/msg_unread_type.dart';
import 'package:PiliPlus/models/common/nav_bar_config.dart';
import 'package:PiliPlus/models/common/theme/theme_color_type.dart';
import 'package:PiliPlus/models/common/theme/theme_type.dart';
import 'package:PiliPlus/pages/main/controller.dart';
import 'package:PiliPlus/pages/mine/controller.dart';
@@ -22,12 +24,15 @@ import 'package:PiliPlus/pages/setting/widgets/multi_select_dialog.dart';
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
import 'package:PiliPlus/pages/setting/widgets/slide_dialog.dart';
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
import 'package:PiliPlus/utils/extension/get_ext.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/global_data.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:auto_orientation/auto_orientation.dart';
import 'package:flex_seed_scheme/flex_seed_scheme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -548,7 +553,7 @@ List<SettingsModel> get styleSettings => [
Get.find<MineController>().themeType.value = result;
} catch (_) {}
GStorage.setting.put(SettingBoxKey.themeMode, result.index);
Get.put(ColorSelectController()).themeType.value = result;
Get.putOrFind(ColorSelectController.new).themeType.value = result;
Get.changeThemeMode(result.toThemeMode);
setState();
}
@@ -572,8 +577,21 @@ List<SettingsModel> get styleSettings => [
onTap: (context, setState) => Get.toNamed('/colorSetting'),
leading: const Icon(Icons.color_lens_outlined),
title: '应用主题',
getSubtitle: () =>
'当前主题:${Get.put(ColorSelectController()).dynamicColor.value ? '动态取色' : '指定颜色'}',
getSubtitle: () => '当前主题:${Pref.dynamicColor ? '动态取色' : '指定颜色'}',
getTrailing: () => Pref.dynamicColor
? Icon(Icons.color_lens_rounded, color: Get.theme.colorScheme.primary)
: SizedBox.square(
dimension: 32,
child: ColorPalette(
colorScheme: colorThemeTypes[Pref.customColor].color
.asColorSchemeSeed(
FlexSchemeVariant.values[Pref.schemeVariant],
Get.theme.brightness,
),
selected: false,
showBgColor: false,
),
),
),
NormalModel(
onTap: (context, setState) async {
@@ -671,15 +689,18 @@ List<SettingsModel> get styleSettings => [
onTap: (context, setState) async {
final result = await Get.toNamed('/fontSizeSetting');
if (result != null) {
Get.put(ColorSelectController()).currentTextScale.value = result;
Get.putOrFind(ColorSelectController.new).currentTextScale.value =
result;
}
},
title: '字体大小',
leading: const Icon(Icons.format_size_outlined),
getSubtitle: () =>
Get.put(ColorSelectController()).currentTextScale.value == 1.0
Get.putOrFind(ColorSelectController.new).currentTextScale.value == 1.0
? '默认'
: Get.put(ColorSelectController()).currentTextScale.value.toString(),
: Get.putOrFind(
ColorSelectController.new,
).currentTextScale.value.toString(),
),
NormalModel(
onTap: (context, setState) => Get.toNamed(

View File

@@ -8,11 +8,13 @@ import 'package:PiliPlus/models/common/theme/theme_type.dart';
import 'package:PiliPlus/pages/home/view.dart';
import 'package:PiliPlus/pages/mine/controller.dart';
import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:flex_seed_scheme/flex_seed_scheme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
@@ -45,7 +47,7 @@ List<Item> generateItems(int count) {
}
class _ColorSelectPageState extends State<ColorSelectPage> {
final ColorSelectController ctr = Get.put(ColorSelectController());
final ctr = Get.put(ColorSelectController());
FlexSchemeVariant _dynamicSchemeVariant =
FlexSchemeVariant.values[Pref.schemeVariant];
@@ -177,9 +179,15 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
..dynamicColor.value = val!
..setting.put(SettingBoxKey.dynamicColor, val);
if (val) {
await MyApp.initPlatformState();
if (await MyApp.initPlatformState()) {
Get.forceAppUpdate();
} else {
SmartDialog.showToast('该设备可能不支持动态取色');
ctr.dynamicColor.value = false;
}
} else {
Get.forceAppUpdate();
}
Get.forceAppUpdate();
},
),
),
@@ -218,7 +226,10 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
spacing: 3,
children: [
ColorPalette(
color: item.color,
colorScheme: item.color.asColorSchemeSeed(
_dynamicSchemeVariant,
theme.brightness,
),
selected: ctr.currentColor.value == index,
),
Text(
@@ -275,5 +286,5 @@ class ColorSelectController extends GetxController {
final RxDouble currentTextScale = Pref.defaultTextScale.obs;
final Rx<ThemeType> themeType = Pref.themeType.obs;
Box setting = GStorage.setting;
Box get setting => GStorage.setting;
}

View File

@@ -7,7 +7,7 @@ class NormalItem extends StatefulWidget {
final String? subtitle;
final ValueGetter<String>? getSubtitle;
final Widget? leading;
final Widget Function()? getTrailing;
final ValueGetter<Widget?>? getTrailing;
final void Function(BuildContext context, void Function() setState)? onTap;
final EdgeInsetsGeometry? contentPadding;
final TextStyle? titleStyle;

View File

@@ -1,3 +1,4 @@
import 'package:flex_seed_scheme/flex_seed_scheme.dart';
import 'package:flutter/material.dart';
extension ColorSchemeExt on ColorScheme {
@@ -17,6 +18,16 @@ extension ColorExtension on Color {
assert(amount >= 0 && amount <= 1, 'Amount must be between 0 and 1');
return Color.lerp(this, Colors.black, amount)!;
}
ColorScheme asColorSchemeSeed([
FlexSchemeVariant variant = .material,
Brightness brightness = .light,
]) => SeedColorScheme.fromSeeds(
primaryKey: this,
variant: variant,
brightness: brightness,
useExpressiveOnContainerColors: false,
);
}
extension BrightnessExt on Brightness {