10 changed files with 206 additions and 49 deletions
@ -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