import 'package:fl_lib/fl_lib.dart'; import 'package:flutter/material.dart'; final class UnixPermOp { final bool r; final bool w; final bool x; const UnixPermOp({required this.r, required this.w, required this.x}); UnixPermOp copyWith({bool? r, bool? w, bool? x}) { return UnixPermOp(r: r ?? this.r, w: w ?? this.w, x: x ?? this.x); } int get value { return (r ? 4 : 0) + (w ? 2 : 0) + (x ? 1 : 0); } } enum UnixPermScope { user, group, other; String get title { return switch (this) { user => 'User', group => 'Group', other => 'Other', }; } } final class UnixPerm { final UnixPermOp user; final UnixPermOp group; final UnixPermOp other; const UnixPerm({ required this.user, required this.group, required this.other, }); UnixPerm copyWith({UnixPermOp? user, UnixPermOp? group, UnixPermOp? other}) { return UnixPerm( user: user ?? this.user, group: group ?? this.group, other: other ?? this.other, ); } UnixPerm copyWithScope(UnixPermScope scope, UnixPermOp rwx) { switch (scope) { case UnixPermScope.user: return copyWith(user: rwx); case UnixPermScope.group: return copyWith(group: rwx); case UnixPermScope.other: return copyWith(other: rwx); } } /// eg.: 744 String get perm { return '${user.value}${group.value}${other.value}'; } static UnixPerm get empty => const UnixPerm( user: UnixPermOp(r: false, w: false, x: false), group: UnixPermOp(r: false, w: false, x: false), other: UnixPermOp(r: false, w: false, x: false), ); } final class UnixPermEditor extends StatefulWidget { final UnixPerm perm; final void Function(UnixPerm) onChanged; const UnixPermEditor({ super.key, required this.perm, required this.onChanged, }); @override State createState() => _UnixPermEditorState(); } final class _UnixPermEditorState extends State { late UnixPerm perm; @override void initState() { super.initState(); perm = widget.perm; } @override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ const Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text('Read'), Text('Writ'), // Keep it short to fit UI Text('Exec'), ], ).paddingOnly(left: 13), UIs.height7, _buildRow(UnixPermScope.user, perm.user), _buildRow(UnixPermScope.group, perm.group), _buildRow(UnixPermScope.other, perm.other), ], ); } Widget _buildRow(UnixPermScope scope, UnixPermOp rwx) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox(width: 7, child: Text(scope.title)), _buildSwitch(rwx.r, (v) { setState(() { perm = perm.copyWithScope(scope, rwx.copyWith(r: v)); widget.onChanged(perm); }); }), _buildSwitch(rwx.w, (v) { setState(() { perm = perm.copyWithScope(scope, rwx.copyWith(w: v)); widget.onChanged(perm); }); }), _buildSwitch(rwx.x, (v) { setState(() { perm = perm.copyWithScope(scope, rwx.copyWith(x: v)); widget.onChanged(perm); }); }), ], ); } Widget _buildSwitch(bool value, void Function(bool) onChanged) { return Switch(value: value, onChanged: onChanged); } }