马良AI写作初始化仓库

This commit is contained in:
邓滨杰
2025-09-10 00:07:52 +08:00
parent 3c06bb1a03
commit 39c0f8840f
1309 changed files with 318528 additions and 0 deletions

View File

@@ -0,0 +1,162 @@
import 'package:flutter/material.dart';
import 'package:ainoval/utils/web_theme.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:ainoval/utils/logger.dart';
import 'package:ainoval/utils/setting_reference_processor.dart';
/// 🎯 简化版设定引用悬停状态管理器
/// 使用TextStyle.backgroundColor实现悬停效果比复杂的位置计算更简单高效
class SettingReferenceHoverManager extends ChangeNotifier {
static final SettingReferenceHoverManager _instance = SettingReferenceHoverManager._internal();
factory SettingReferenceHoverManager() => _instance;
SettingReferenceHoverManager._internal();
String? _hoveredSettingId;
String? get hoveredSettingId => _hoveredSettingId;
/// 设置悬停的设定引用ID
void setHoveredSetting(String? settingId) {
if (_hoveredSettingId != settingId) {
_hoveredSettingId = settingId;
notifyListeners();
AppLogger.d('SettingReferenceHoverManager',
_hoveredSettingId != null
? '🖱️ 设定引用悬停开始: $_hoveredSettingId'
: '🖱️ 设定引用悬停结束');
}
}
/// 清除悬停状态
void clearHover() {
setHoveredSetting(null);
}
}
/// 设定引用交互混入 - 为 SceneEditor 提供设定引用交互功能
mixin SettingReferenceInteractionMixin {
/// 🎯 获取支持悬停效果的设定引用样式构建器
/// 这是最核心的方法直接在customStyleBuilder中处理悬停效果
static TextStyle Function(Attribute) getCustomStyleBuilderWithHover({
required String? hoveredSettingId,
}) {
return (Attribute attribute) {
// 处理设定引用的样式标记
if (attribute.key == SettingReferenceProcessor.settingStyleAttr &&
attribute.value == 'reference') {
// 🎯 关键使用TextStyle.backgroundColor实现悬停效果
return const TextStyle(
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.dotted,
decorationColor: WebTheme.grey400,
decorationThickness: 1.5,
// 🎯 核心直接使用TextStyle的backgroundColor属性
backgroundColor: Color(0x00FFF3CD),
).copyWith(
backgroundColor: hoveredSettingId != null ? const Color(0xFFFFF3CD) : null,
);
}
return const TextStyle();
};
}
/// 获取设定引用的自定义手势识别器构建器
static GestureRecognizer? Function(Attribute, Node) getCustomRecognizerBuilder({
required Function(String settingId)? onSettingReferenceClicked,
required Function(String settingId)? onSettingReferenceHovered,
required VoidCallback? onSettingReferenceHoverEnd,
}) {
return (Attribute attribute, Node node) {
// 检查是否是设定引用属性
if (attribute.key == SettingReferenceProcessor.settingReferenceAttr ) {
final settingId = attribute.value as String?;
if (settingId != null && settingId.isNotEmpty) {
//AppLogger.d('SettingReferenceInteraction', '🎯 创建设定引用手势识别器: $settingId');
// 创建支持点击和悬停的手势识别器
final tapRecognizer = TapGestureRecognizer()
..onTap = () {
AppLogger.i('SettingReferenceInteraction', '🖱️ 设定引用被点击: $settingId');
onSettingReferenceClicked?.call(settingId);
};
return tapRecognizer;
}
}
return null;
};
}
/// 获取设定引用的自定义样式构建器(基础版本)
static TextStyle Function(Attribute) getCustomStyleBuilder() {
return (Attribute attribute) {
// 处理设定引用的样式标记
if (attribute.key == SettingReferenceProcessor.settingStyleAttr &&
attribute.value == 'reference') {
return const TextStyle(
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.dotted,
decorationColor: WebTheme.grey400,
decorationThickness: 1.5,
);
}
return const TextStyle();
};
}
}
/// 🎯 设定引用鼠标悬停检测器Widget
/// 使用MouseRegion包装编辑器检测鼠标悬停并更新状态
class SettingReferenceMouseDetector extends StatefulWidget {
final Widget child;
final QuillController controller;
final String? novelId;
const SettingReferenceMouseDetector({
Key? key,
required this.child,
required this.controller,
this.novelId,
}) : super(key: key);
@override
State<SettingReferenceMouseDetector> createState() => _SettingReferenceMouseDetectorState();
}
class _SettingReferenceMouseDetectorState extends State<SettingReferenceMouseDetector> {
final _hoverManager = SettingReferenceHoverManager();
@override
Widget build(BuildContext context) {
return MouseRegion(
onHover: _handleMouseMove,
onExit: (_) => _hoverManager.clearHover(),
child: widget.child,
);
}
void _handleMouseMove(PointerHoverEvent event) {
// 🎯 这里可以实现基于鼠标位置的设定引用检测
// 为了简化,暂时先处理基本的悬停状态
try {
// TODO: 实现更精确的位置检测逻辑
// 目前先简化处理,后续可以根据需要优化
// 暂时用一个简单的方式来模拟检测
// 实际项目中可能需要更复杂的位置计算
AppLogger.v('SettingReferenceMouseDetector', '🖱️ 鼠标移动: ${event.localPosition}');
} catch (e) {
AppLogger.w('SettingReferenceMouseDetector', '检测设定引用悬停失败', e);
}
}
}