10 changed files with 206 additions and 49 deletions
@ -0,0 +1,143 @@
@@ -0,0 +1,143 @@
|
||||
// shared/components/code_generation_components.dart |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter/services.dart'; |
||||
|
||||
class CodeGenerationRadioItem extends StatelessWidget { |
||||
final String label; |
||||
final String? groupValue; |
||||
final ValueChanged<String?> onChanged; |
||||
|
||||
const CodeGenerationRadioItem({ |
||||
super.key, |
||||
required this.label, |
||||
required this.groupValue, |
||||
required this.onChanged, |
||||
}); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Row( |
||||
mainAxisSize: MainAxisSize.min, |
||||
children: [ |
||||
Transform.scale( |
||||
scale: 0.75, |
||||
child: Radio<String>(value: label, groupValue: groupValue, onChanged: onChanged), |
||||
), |
||||
const SizedBox(width: 4), |
||||
Text(label, style: const TextStyle(fontSize: 14)), |
||||
], |
||||
); |
||||
} |
||||
} |
||||
|
||||
class CodeGenerationSection extends StatelessWidget { |
||||
final String title; |
||||
final Widget child; |
||||
final TextEditingController codeController; |
||||
|
||||
const CodeGenerationSection({ |
||||
super.key, |
||||
required this.title, |
||||
required this.child, |
||||
required this.codeController, |
||||
}); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return Column( |
||||
children: [ |
||||
child, |
||||
Padding( |
||||
padding: const EdgeInsets.only(left: 8.0, right: 8.0), |
||||
child: Row( |
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
children: [ |
||||
Text('$title:', style: const TextStyle(fontWeight: FontWeight.bold)), |
||||
IconButton( |
||||
icon: const Icon(Icons.content_copy, size: 20), |
||||
tooltip: '复制代码', |
||||
onPressed: () { |
||||
if (codeController.text.isNotEmpty) { |
||||
Clipboard.setData(ClipboardData(text: codeController.text)); |
||||
ScaffoldMessenger.of( |
||||
context, |
||||
).showSnackBar(const SnackBar(content: Text('已复制到剪贴板'))); |
||||
} |
||||
}, |
||||
), |
||||
], |
||||
), |
||||
), |
||||
Flexible(child: _buildCodeEditor(codeController)), |
||||
], |
||||
); |
||||
} |
||||
|
||||
Widget _buildCodeEditor(TextEditingController controller) { |
||||
return Card( |
||||
child: Padding( |
||||
padding: const EdgeInsets.all(8), |
||||
child: Container( |
||||
decoration: BoxDecoration( |
||||
border: Border.all(color: Colors.grey), |
||||
borderRadius: BorderRadius.circular(4), |
||||
), |
||||
child: TextField( |
||||
controller: controller, |
||||
maxLines: null, |
||||
expands: true, |
||||
decoration: const InputDecoration( |
||||
border: InputBorder.none, |
||||
contentPadding: EdgeInsets.all(8), |
||||
), |
||||
style: const TextStyle(fontFamily: 'monospace', color: Colors.blueAccent), |
||||
), |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
||||
class OperationRadioSection extends StatelessWidget { |
||||
final List<String> operations; |
||||
final String? selectedOperation; |
||||
final ValueChanged<String?> onOperationSelected; |
||||
|
||||
const OperationRadioSection({ |
||||
super.key, |
||||
required this.operations, |
||||
required this.selectedOperation, |
||||
required this.onOperationSelected, |
||||
}); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
return SizedBox( |
||||
width: double.infinity, |
||||
child: Card( |
||||
child: Padding( |
||||
padding: const EdgeInsets.all(12), |
||||
child: Column( |
||||
crossAxisAlignment: CrossAxisAlignment.start, |
||||
children: [ |
||||
Wrap( |
||||
spacing: 16, |
||||
runSpacing: 8, |
||||
children: |
||||
operations |
||||
.map( |
||||
(op) => CodeGenerationRadioItem( |
||||
label: op, |
||||
groupValue: selectedOperation, |
||||
onChanged: onOperationSelected, |
||||
), |
||||
) |
||||
.toList(), |
||||
), |
||||
], |
||||
), |
||||
), |
||||
), |
||||
); |
||||
} |
||||
} |
Loading…
Reference in new issue