diff --git a/lib/modules/eq_settings/controllers/eq_settings_controller.dart b/lib/modules/eq_settings/controllers/eq_settings_controller.dart index 3f08120f4..842fa5be0 100644 --- a/lib/modules/eq_settings/controllers/eq_settings_controller.dart +++ b/lib/modules/eq_settings/controllers/eq_settings_controller.dart @@ -1,10 +1,11 @@ -import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../core/utils/logger.dart'; import '../../../routes/app_routes.dart'; import '../views/widgets/row_confirm_widget.dart'; import '../views/widgets/row_input_widget.dart'; +import '../views/widgets/row_keypress_widget.dart'; import '../views/widgets/row_radio_widget.dart'; import '../views/widgets/row_switch_widget.dart'; @@ -16,7 +17,33 @@ class EqSettingsController extends GetxController { }, { 'title': '按键功能', - 'templates': [], + 'templates': [ + { + 'type': 'keypress', + 'data': [ + {'key': 'key1', 'label': '单击', 'left': 1, 'right': 1}, + {'key': 'key2', 'label': '双击', 'left': 1, 'right': 1}, + {'key': 'key3', 'label': '三击', 'left': 1, 'right': 1}, + {'key': 'key4', 'label': '长按', 'left': 1, 'right': 1}, + ], + 'options': [ + {'label': '无作用', 'value': 0}, + {'label': '回拨电话', 'value': 1}, + {'label': '语音助手', 'value': 2}, + {'label': '上一曲', 'value': 3}, + {'label': '下一曲', 'value': 4}, + {'label': '音量加', 'value': 5}, + {'label': '音量减', 'value': 6}, + {'label': '播放暂停', 'value': 7}, + {'label': '游戏模式', 'value': 8}, + {'label': '降噪设置', 'value': 9}, + {'label': 'EQ切换', 'value': 10}, + ], + 'onCallback': (Map value) { + Logger.d('keypress', '按键功能:$value'); + }, + }, + ], }, { 'title': '耳机功能', @@ -32,13 +59,13 @@ class EqSettingsController extends GetxController { { 'type': 'radio', 'name': '工作模式', - 'value': '1', + 'value': 1, 'options': [ - {'label': '游戏模式', 'value': '1'}, - {'label': '娱乐模式', 'value': '2'}, - {'label': '睡眠模式', 'value': '3'}, + {'label': '游戏模式', 'value': 1}, + {'label': '娱乐模式', 'value': 2}, + {'label': '睡眠模式', 'value': 3}, ], - 'onCallback': (String value) { + 'onCallback': (int value) { Logger.d('radio', '工作模式:$value'); }, }, @@ -90,6 +117,7 @@ class EqSettingsController extends GetxController { Widget getTemplate(Map data) { return switch (data['type']) { + 'keypress' => RowKeypressWidget(data), 'input' => RowInputWidget(data), 'radio' => RowRadioWidget(data), 'switch' => RowSwitchWidget(data), diff --git a/lib/modules/eq_settings/views/widgets/row_keypress_widget.dart b/lib/modules/eq_settings/views/widgets/row_keypress_widget.dart new file mode 100644 index 000000000..0e5f5229a --- /dev/null +++ b/lib/modules/eq_settings/views/widgets/row_keypress_widget.dart @@ -0,0 +1,236 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +class RowKeypressWidget extends StatefulWidget { + final Map templateData; + + const RowKeypressWidget(this.templateData, {super.key}); + + @override + State createState() => _RowKeypressWidgetState(); +} + +class _RowKeypressWidgetState extends State { + Map get _templateData => widget.templateData; + + String _getLabel(int value) { + return _templateData['options'].firstWhere((item) => item['value'] == value, + orElse: () => {'label': ''})['label']; + } + + @override + Widget build(BuildContext context) { + final isDarkMode = Theme.of(context).brightness == Brightness.dark; + + return Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 10.w), + child: Row( + children: [ + const Spacer(), + Expanded( + child: Text( + '左', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + ), + Expanded( + child: Text( + '右', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + ), + ], + ), + ), + ..._templateData['data'] + .map((item) => _rowItem(isDarkMode, item)) + .toList(), + ], + ); + } + + Widget _rowItem(bool isDarkMode, Map item) { + return Padding( + padding: EdgeInsets.symmetric(vertical: 10.w), + child: Row( + children: [ + Expanded( + child: Text( + item['label'], + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + ), + Expanded( + child: GestureDetector( + onTap: () => _radioDialog(isDarkMode, item, 'left'), + behavior: HitTestBehavior.translucent, + child: Text( + _getLabel(item['left']), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12.sp, + color: isDarkMode ? Colors.white : Colors.grey, + ), + ), + ), + ), + Expanded( + child: GestureDetector( + onTap: () => _radioDialog(isDarkMode, item, 'right'), + behavior: HitTestBehavior.translucent, + child: Text( + _getLabel(item['right']), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12.sp, + color: isDarkMode ? Colors.white : Colors.grey, + ), + ), + ), + ), + ], + ), + ); + } + + void _radioDialog(bool isDarkMode, Map item, String key) { + Get.dialog( + Dialog( + backgroundColor: isDarkMode ? Colors.grey[900] : Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16.r), + ), + child: Padding( + padding: EdgeInsets.all(12.w), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${item['label']}-${key == 'left' ? '左' : '右'}', + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black87, + ), + ), + SizedBox(height: 16.h), + Container( + constraints: BoxConstraints(maxHeight: 0.5.sh), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: _templateData['options'] + .map((option) => + _radioItem(isDarkMode, option, item, key)) + .toList(), + ), + ), + ), + SizedBox(height: 16.h), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () => Get.back(), + child: Text( + 'cancel'.tr, // 取消 + style: TextStyle( + color: isDarkMode ? Colors.white70 : Colors.black54, + ), + ), + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget _radioItem(bool isDarkMode, Map option, Map item, String key) { + return GestureDetector( + onTap: () { + setState(() { + item[key] = option['value']; + }); + Map data = { + 'key': item['key'], + key: option['value'], + }; + _templateData['onCallback'](data); + Get.back(); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10.h), + padding: EdgeInsets.all(10.w), + decoration: BoxDecoration( + color: item[key] == option['value'] + ? (isDarkMode + ? Colors.teal[900]!.withValues(alpha: 0.3) + : Colors.teal[50]!) + : (isDarkMode + ? Colors.white.withValues(alpha: 0.05) + : Colors.grey[100]!), + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: item[key] == option['value'] + ? (isDarkMode ? Colors.teal[300]! : Colors.teal[600]!) + : Colors.transparent, + width: 1, + ), + ), + child: Row( + children: [ + Expanded( + child: Text( + option['label'], + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w500, + color: isDarkMode ? Colors.white : Colors.black87, + ), + overflow: TextOverflow.ellipsis, + ), + ), + Container( + width: 24.w, + height: 24.w, + decoration: BoxDecoration( + color: item[key] == option['value'] + ? (isDarkMode ? Colors.teal[300] : Colors.teal[600]) + : (isDarkMode + ? Colors.white.withValues(alpha: 0.1) + : Colors.grey[300]), + shape: BoxShape.circle, + ), + child: item[key] == option['value'] + ? Icon( + Icons.check, + size: 16.w, + color: Colors.white, + ) + : null, + ), + ], + ), + ), + ); + } +}