mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-06-11 04:33:08 +08:00
add tag color
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
ae640dda56
commit
a5bba37cae
@ -1074,6 +1074,30 @@ Color str2color(String str, [alpha = 0xFF]) {
|
|||||||
return Color((hash & 0xFF7FFF) | (alpha << 24));
|
return Color((hash & 0xFF7FFF) | (alpha << 24));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color str2color2(String str, [alpha = 0xFF]) {
|
||||||
|
List<Color> colorList = [
|
||||||
|
Colors.red,
|
||||||
|
Colors.green,
|
||||||
|
Colors.blue,
|
||||||
|
Colors.orange,
|
||||||
|
Colors.yellow,
|
||||||
|
Colors.purple,
|
||||||
|
Colors.grey,
|
||||||
|
Colors.cyan,
|
||||||
|
Colors.lime,
|
||||||
|
Colors.teal,
|
||||||
|
Colors.pink,
|
||||||
|
Colors.indigo,
|
||||||
|
Colors.brown,
|
||||||
|
];
|
||||||
|
var hash = 0;
|
||||||
|
for (var i = 0; i < str.length; i++) {
|
||||||
|
hash += str.codeUnitAt(i);
|
||||||
|
}
|
||||||
|
hash = hash % colorList.length;
|
||||||
|
return colorList[hash].withAlpha(alpha);
|
||||||
|
}
|
||||||
|
|
||||||
const K = 1024;
|
const K = 1024;
|
||||||
const M = K * K;
|
const M = K * K;
|
||||||
const G = M * K;
|
const G = M * K;
|
||||||
|
@ -449,26 +449,43 @@ class AddressBookTag extends StatelessWidget {
|
|||||||
pos = RelativeRect.fromLTRB(x, y, x, y);
|
pos = RelativeRect.fromLTRB(x, y, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const double radius = 8;
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
onTapDown: showActionMenu ? setPosition : null,
|
onTapDown: showActionMenu ? setPosition : null,
|
||||||
onSecondaryTapDown: showActionMenu ? setPosition : null,
|
onSecondaryTapDown: showActionMenu ? setPosition : null,
|
||||||
onSecondaryTap: showActionMenu ? () => _showMenu(context, pos) : null,
|
onSecondaryTap: showActionMenu ? () => _showMenu(context, pos) : null,
|
||||||
onLongPress: showActionMenu ? () => _showMenu(context, pos) : null,
|
onLongPress: showActionMenu ? () => _showMenu(context, pos) : null,
|
||||||
child: Obx(
|
child: Obx(() => Container(
|
||||||
() => Container(
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: tags.contains(name)
|
color: tags.contains(name)
|
||||||
? Colors.blue
|
? str2color2(name, 0xFF)
|
||||||
: Theme.of(context).colorScheme.background,
|
: Theme.of(context).colorScheme.background,
|
||||||
borderRadius: BorderRadius.circular(6)),
|
borderRadius: BorderRadius.circular(4)),
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 8.0),
|
margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 6.0),
|
||||||
|
child: IntrinsicWidth(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: radius,
|
||||||
|
height: radius,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: tags.contains(name)
|
||||||
|
? Colors.white
|
||||||
|
: str2color2(name)),
|
||||||
|
).marginOnly(right: radius / 2),
|
||||||
|
Expanded(
|
||||||
child: Text(name,
|
child: Text(name,
|
||||||
style:
|
style: TextStyle(
|
||||||
TextStyle(color: tags.contains(name) ? Colors.white : null)),
|
overflow: TextOverflow.ellipsis,
|
||||||
|
color: tags.contains(name) ? Colors.white : null)),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import '../../models/peer_model.dart';
|
|||||||
import '../../models/platform_model.dart';
|
import '../../models/platform_model.dart';
|
||||||
import '../../desktop/widgets/material_mod_popup_menu.dart' as mod_menu;
|
import '../../desktop/widgets/material_mod_popup_menu.dart' as mod_menu;
|
||||||
import '../../desktop/widgets/popup_menu.dart';
|
import '../../desktop/widgets/popup_menu.dart';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
typedef PopupMenuEntryBuilder = Future<List<mod_menu.PopupMenuEntry<String>>>
|
typedef PopupMenuEntryBuilder = Future<List<mod_menu.PopupMenuEntry<String>>>
|
||||||
Function(BuildContext);
|
Function(BuildContext);
|
||||||
@ -159,7 +160,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6));
|
color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6));
|
||||||
final alias = bind.mainGetPeerOptionSync(id: peer.id, key: 'alias');
|
final alias = bind.mainGetPeerOptionSync(id: peer.id, key: 'alias');
|
||||||
return Obx(
|
final child = Obx(
|
||||||
() => Container(
|
() => Container(
|
||||||
foregroundDecoration: deco.value,
|
foregroundDecoration: deco.value,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -199,7 +200,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: Theme.of(context).textTheme.titleSmall,
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
)),
|
)),
|
||||||
]).marginOnly(bottom: 2),
|
]).marginOnly(bottom: 0, top: 2),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
@ -221,13 +222,29 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList();
|
||||||
|
return Tooltip(
|
||||||
|
message: peer.tags.isNotEmpty
|
||||||
|
? '${translate('Tags')}: ${peer.tags.join(', ')}'
|
||||||
|
: '',
|
||||||
|
child: Stack(children: [
|
||||||
|
child,
|
||||||
|
Positioned(
|
||||||
|
top: 2,
|
||||||
|
right: 10,
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: TagPainter(radius: 3, colors: colors),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildPeerCard(
|
Widget _buildPeerCard(
|
||||||
BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
|
BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
|
||||||
final name =
|
final name =
|
||||||
'${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}';
|
'${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}';
|
||||||
return Card(
|
final child = Card(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
@ -253,7 +270,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
padding: const EdgeInsets.all(6),
|
padding: const EdgeInsets.all(6),
|
||||||
child:
|
child:
|
||||||
getPlatformImage(peer.platform, size: 60),
|
getPlatformImage(peer.platform, size: 60),
|
||||||
),
|
).marginOnly(top: 4),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -304,6 +321,31 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList();
|
||||||
|
return Tooltip(
|
||||||
|
message: peer.tags.isNotEmpty
|
||||||
|
? '${translate('Tags')}: ${peer.tags.join(', ')}'
|
||||||
|
: '',
|
||||||
|
child: Stack(children: [
|
||||||
|
child,
|
||||||
|
Positioned(
|
||||||
|
top: 4,
|
||||||
|
right: 12,
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: TagPainter(radius: 4, colors: colors),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List _frontN<T>(List list, int n) {
|
||||||
|
if (list.length <= n) {
|
||||||
|
return list;
|
||||||
|
} else {
|
||||||
|
return list.sublist(0, n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget checkBoxOrActionMoreMobile(Peer peer) {
|
Widget checkBoxOrActionMoreMobile(Peer peer) {
|
||||||
@ -1193,3 +1235,41 @@ Widget build_more(BuildContext context, {bool invert = false}) {
|
|||||||
?.color
|
?.color
|
||||||
?.withOpacity(0.5)))));
|
?.withOpacity(0.5)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TagPainter extends CustomPainter {
|
||||||
|
final double radius;
|
||||||
|
late final List<Color> colors;
|
||||||
|
|
||||||
|
TagPainter({required this.radius, required List<Color> colors}) {
|
||||||
|
this.colors = colors.reversed.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
double x = 0;
|
||||||
|
double y = radius;
|
||||||
|
for (int i = 0; i < colors.length; i++) {
|
||||||
|
Paint paint = Paint();
|
||||||
|
paint.color = colors[i];
|
||||||
|
x -= radius + 1;
|
||||||
|
if (i == colors.length - 1) {
|
||||||
|
canvas.drawCircle(Offset(x, y), radius, paint);
|
||||||
|
} else {
|
||||||
|
Path path = Path();
|
||||||
|
path.addArc(Rect.fromCircle(center: Offset(x, y), radius: radius),
|
||||||
|
math.pi * 4 / 3, math.pi * 4 / 3);
|
||||||
|
path.addArc(
|
||||||
|
Rect.fromCircle(center: Offset(x - radius, y), radius: radius),
|
||||||
|
math.pi * 5 / 3,
|
||||||
|
math.pi * 2 / 3);
|
||||||
|
path.fillType = PathFillType.evenOdd;
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user