new: picker & opt. rm -r

This commit is contained in:
lollipopkit
2023-10-05 19:51:24 +08:00
parent ef144e27cb
commit a23a284d1a
28 changed files with 192 additions and 316 deletions

View File

@@ -0,0 +1,29 @@
import 'package:choice/selection.dart';
import 'package:flutter/material.dart';
class ChoiceChipX<T> extends StatelessWidget {
const ChoiceChipX({
Key? key,
required this.label,
required this.state,
required this.value,
}) : super(key: key);
final String label;
final ChoiceController<T> state;
final T value;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(3),
child: ChoiceChip(
label: Text(label),
side: BorderSide.none,
selected: state.selected(value),
selectedColor: Theme.of(context).colorScheme.primary,
onSelected: state.onSelected(value),
),
);
}
}

View File

@@ -1,52 +0,0 @@
import 'package:flutter/material.dart';
class Picker extends StatelessWidget {
final List<Widget> items;
final void Function(int idx) onSelected;
final double height;
const Picker({
super.key,
required this.items,
required this.onSelected,
this.height = 157,
});
@override
Widget build(BuildContext context) {
final pad = (height - 37) / 2;
return SizedBox(
height: height,
child: Stack(
children: [
Positioned(
top: pad,
bottom: pad,
left: 0,
right: 0,
child: Container(
height: 37,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(7)),
color: Colors.black12,
),
),
),
ListWheelScrollView.useDelegate(
itemExtent: 37,
diameterRatio: 2.7,
controller: FixedExtentScrollController(initialItem: 0),
onSelectedItemChanged: (idx) => onSelected(idx),
physics: const FixedExtentScrollPhysics(),
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) => Center(
child: items[index],
),
childCount: items.length,
),
)
],
),
);
}
}

View File

@@ -21,7 +21,6 @@ import '../../data/model/pkg/upgrade_info.dart';
import '../../data/model/server/server_private_info.dart';
import '../../data/model/server/snippet.dart';
import 'popup_menu.dart';
import 'tag.dart';
class ServerFuncBtnsTopRight extends StatelessWidget {
final ServerPrivateInfo spi;
@@ -96,13 +95,10 @@ void _onTapMoreBtns(
);
break;
case ServerTabMenuType.snippet:
final snippets = await showDialog<List<Snippet>>(
context: context,
builder: (_) => TagPicker<Snippet>(
final snippets = await context.showPickDialog<Snippet>(
items: Pros.snippet.snippets,
tags: Pros.server.tags.toSet(),
),
);
name: (e) => e.name,
);
if (snippets == null) {
return;
}

View File

@@ -6,7 +6,6 @@ import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/input_field.dart';
import 'package:toolbox/view/widget/round_rect_card.dart';
import '../../data/model/app/tag_pickable.dart';
import '../../data/res/color.dart';
const _kTagBtnHeight = 31.0;
@@ -179,119 +178,6 @@ class _TagEditorState extends State<TagEditor> {
}
}
class TagPicker<T extends TagPickable> extends StatefulWidget {
final List<T> items;
final Set<String> tags;
const TagPicker({
Key? key,
required this.items,
required this.tags,
}) : super(key: key);
@override
_TagPickerState<T> createState() => _TagPickerState<T>();
}
class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
late MediaQueryData _media;
final List<T> _selected = [];
@override
void didChangeDependencies() {
super.didChangeDependencies();
_media = MediaQuery.of(context);
}
@override
Widget build(BuildContext context) {
final children = <Widget>[];
if (widget.tags.isNotEmpty) {
children.add(Text(l10n.tag));
children.add(UIs.height13);
children.add(SizedBox(
height: _kTagBtnHeight,
width: _media.size.width * 0.7,
child: _buildTags(),
));
}
if (widget.items.isNotEmpty) {
children.add(Text(l10n.all));
children.add(UIs.height13);
children.add(SizedBox(
height: _kTagBtnHeight,
width: _media.size.width * 0.7,
child: _buildItems(),
));
}
final child = widget.tags.isEmpty && widget.items.isEmpty
? Text(l10n.noOptions)
: Column(mainAxisSize: MainAxisSize.min, children: children);
return AlertDialog(
title: Text(l10n.choose),
content: child,
actions: [
TextButton(
onPressed: () => context.pop(_selected),
child: Text(l10n.ok),
),
],
);
}
Widget _buildTags() {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: widget.tags.length,
itemBuilder: (_, idx) {
final item = widget.tags.elementAt(idx);
final isEnable =
widget.items.where((ele) => ele.containsTag(item)).every(
(ele) => _selected.contains(ele),
);
return TagBtn(
isEnable: isEnable,
onTap: () {
if (isEnable) {
_selected.removeWhere(
(ele) => ele.containsTag(item),
);
} else {
_selected.addAll(widget.items.where(
(ele) => ele.containsTag(item),
));
}
setState(() {});
},
content: item,
);
},
);
}
Widget _buildItems() {
return ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: widget.items.length,
itemBuilder: (context, index) {
final e = widget.items[index];
return TagBtn(
isEnable: _selected.contains(e),
onTap: () {
if (_selected.contains(e)) {
_selected.remove(e);
} else {
_selected.add(e);
}
setState(() {});
},
content: e.tagName,
);
},
);
}
}
class TagSwitcher extends StatelessWidget {
final List<String> tags;
final double width;