mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-04-27 18:46:10 -04:00
190 lines
7.4 KiB
Dart
190 lines
7.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'scale_input_decorator_theme.dart';
|
|
import 'scale_scheme.dart';
|
|
|
|
export 'scale_app_bar_theme.dart';
|
|
export 'scale_color.dart';
|
|
export 'scale_input_decorator_theme.dart';
|
|
export 'scale_scheme.dart';
|
|
export 'scale_tile_theme.dart';
|
|
export 'scale_toast_theme.dart';
|
|
|
|
class ScaleTheme extends ThemeExtension<ScaleTheme> {
|
|
ScaleTheme({
|
|
required this.textTheme,
|
|
required this.scheme,
|
|
required this.config,
|
|
});
|
|
|
|
final TextTheme textTheme;
|
|
final ScaleScheme scheme;
|
|
final ScaleConfig config;
|
|
|
|
@override
|
|
ScaleTheme copyWith({
|
|
TextTheme? textTheme,
|
|
ScaleScheme? scheme,
|
|
ScaleConfig? config,
|
|
}) =>
|
|
ScaleTheme(
|
|
textTheme: textTheme ?? this.textTheme,
|
|
scheme: scheme ?? this.scheme,
|
|
config: config ?? this.config,
|
|
);
|
|
|
|
@override
|
|
ScaleTheme lerp(ScaleTheme? other, double t) {
|
|
if (other is! ScaleTheme) {
|
|
return this;
|
|
}
|
|
return ScaleTheme(
|
|
textTheme: TextTheme.lerp(textTheme, other.textTheme, t),
|
|
scheme: scheme.lerp(other.scheme, t),
|
|
config: config.lerp(other.config, t));
|
|
}
|
|
|
|
WidgetStateProperty<BorderSide?> elementBorderWidgetStateProperty() =>
|
|
WidgetStateProperty.resolveWith((states) {
|
|
if (states.contains(WidgetState.disabled)) {
|
|
return BorderSide(
|
|
color: scheme.grayScale.border.withAlpha(0x7F),
|
|
strokeAlign: BorderSide.strokeAlignOutside);
|
|
} else if (states.contains(WidgetState.pressed)) {
|
|
return BorderSide(
|
|
color: scheme.primaryScale.border,
|
|
);
|
|
} else if (states.contains(WidgetState.hovered)) {
|
|
return BorderSide(
|
|
color: scheme.primaryScale.hoverBorder,
|
|
strokeAlign: BorderSide.strokeAlignOutside);
|
|
} else if (states.contains(WidgetState.focused)) {
|
|
return BorderSide(
|
|
color: scheme.primaryScale.hoverBorder,
|
|
width: 2,
|
|
strokeAlign: BorderSide.strokeAlignOutside);
|
|
}
|
|
return BorderSide(
|
|
color: scheme.primaryScale.border,
|
|
strokeAlign: BorderSide.strokeAlignOutside);
|
|
});
|
|
|
|
WidgetStateProperty<Color?> elementColorWidgetStateProperty() =>
|
|
WidgetStateProperty.resolveWith((states) {
|
|
if (states.contains(WidgetState.disabled)) {
|
|
return scheme.grayScale.primary.withAlpha(0x7F);
|
|
} else if (states.contains(WidgetState.pressed)) {
|
|
return scheme.primaryScale.borderText;
|
|
} else if (states.contains(WidgetState.hovered)) {
|
|
return scheme.primaryScale.borderText;
|
|
} else if (states.contains(WidgetState.focused)) {
|
|
return scheme.primaryScale.borderText;
|
|
}
|
|
return Color.lerp(
|
|
scheme.primaryScale.borderText, scheme.primaryScale.primary, 0.25);
|
|
});
|
|
|
|
WidgetStateProperty<Color?> checkboxFillColorWidgetStateProperty() =>
|
|
WidgetStateProperty.resolveWith((states) {
|
|
if (states.contains(WidgetState.selected)) {
|
|
if (states.contains(WidgetState.disabled)) {
|
|
return scheme.grayScale.primary.withAlpha(0x7F);
|
|
} else if (states.contains(WidgetState.pressed)) {
|
|
return scheme.primaryScale.hoverBorder;
|
|
} else if (states.contains(WidgetState.hovered)) {
|
|
return scheme.primaryScale.hoverBorder;
|
|
} else if (states.contains(WidgetState.focused)) {
|
|
return scheme.primaryScale.border;
|
|
}
|
|
return scheme.primaryScale.border;
|
|
} else {
|
|
return Colors.transparent;
|
|
}
|
|
});
|
|
|
|
// WidgetStateProperty<Color?> elementBackgroundWidgetStateProperty() {
|
|
// return null;
|
|
// }
|
|
|
|
ThemeData toThemeData(Brightness brightness) {
|
|
final colorScheme = scheme.toColorScheme(brightness);
|
|
|
|
final baseThemeData = ThemeData.from(
|
|
colorScheme: colorScheme, textTheme: textTheme, useMaterial3: true);
|
|
|
|
final elevatedButtonTheme = ElevatedButtonThemeData(
|
|
style: ElevatedButton.styleFrom(
|
|
elevation: 0,
|
|
textStyle: textTheme.labelSmall,
|
|
backgroundColor: scheme.primaryScale.elementBackground,
|
|
disabledBackgroundColor:
|
|
scheme.grayScale.elementBackground.withAlpha(0x7F),
|
|
disabledForegroundColor:
|
|
scheme.grayScale.primary.withAlpha(0x7F),
|
|
shape: RoundedRectangleBorder(
|
|
side: BorderSide(color: scheme.primaryScale.border),
|
|
borderRadius:
|
|
BorderRadius.circular(8 * config.borderRadiusScale)))
|
|
.copyWith(
|
|
foregroundColor: elementColorWidgetStateProperty(),
|
|
side: elementBorderWidgetStateProperty(),
|
|
iconColor: elementColorWidgetStateProperty(),
|
|
));
|
|
|
|
final themeData = baseThemeData.copyWith(
|
|
scrollbarTheme: baseThemeData.scrollbarTheme.copyWith(
|
|
thumbColor: WidgetStateProperty.resolveWith((states) {
|
|
if (states.contains(WidgetState.pressed)) {
|
|
return scheme.primaryScale.border;
|
|
} else if (states.contains(WidgetState.hovered)) {
|
|
return scheme.primaryScale.hoverBorder;
|
|
}
|
|
return scheme.primaryScale.subtleBorder;
|
|
}), trackColor: WidgetStateProperty.resolveWith((states) {
|
|
if (states.contains(WidgetState.pressed)) {
|
|
return scheme.primaryScale.activeElementBackground;
|
|
} else if (states.contains(WidgetState.hovered)) {
|
|
return scheme.primaryScale.hoverElementBackground;
|
|
}
|
|
return scheme.primaryScale.elementBackground;
|
|
}), trackBorderColor: WidgetStateProperty.resolveWith((states) {
|
|
if (states.contains(WidgetState.pressed)) {
|
|
return scheme.primaryScale.subtleBorder;
|
|
} else if (states.contains(WidgetState.hovered)) {
|
|
return scheme.primaryScale.subtleBorder;
|
|
}
|
|
return scheme.primaryScale.subtleBorder;
|
|
})),
|
|
appBarTheme: baseThemeData.appBarTheme.copyWith(
|
|
backgroundColor: scheme.primaryScale.border,
|
|
foregroundColor: scheme.primaryScale.borderText,
|
|
toolbarHeight: 48,
|
|
),
|
|
bottomSheetTheme: baseThemeData.bottomSheetTheme.copyWith(
|
|
elevation: 0,
|
|
modalElevation: 0,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(16 * config.borderRadiusScale),
|
|
topRight: Radius.circular(16 * config.borderRadiusScale)))),
|
|
canvasColor: scheme.primaryScale.subtleBackground,
|
|
checkboxTheme: baseThemeData.checkboxTheme.copyWith(
|
|
side: BorderSide(color: scheme.primaryScale.border, width: 2),
|
|
checkColor: elementColorWidgetStateProperty(),
|
|
fillColor: checkboxFillColorWidgetStateProperty(),
|
|
),
|
|
chipTheme: baseThemeData.chipTheme.copyWith(
|
|
backgroundColor: scheme.primaryScale.elementBackground,
|
|
selectedColor: scheme.primaryScale.activeElementBackground,
|
|
surfaceTintColor: scheme.primaryScale.hoverElementBackground,
|
|
checkmarkColor: scheme.primaryScale.primary,
|
|
side: BorderSide(color: scheme.primaryScale.border)),
|
|
elevatedButtonTheme: elevatedButtonTheme,
|
|
inputDecorationTheme:
|
|
ScaleInputDecoratorTheme(scheme, config, textTheme),
|
|
extensions: <ThemeExtension<dynamic>>[scheme, config, this]);
|
|
|
|
return themeData;
|
|
}
|
|
}
|