mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-06-01 12:34:19 -04:00
ui cleanup, new themes
This commit is contained in:
parent
94988718e8
commit
44fe198e5d
31 changed files with 1051 additions and 407 deletions
|
@ -5,47 +5,82 @@ import 'package:flutter_chat_ui/flutter_chat_ui.dart';
|
|||
|
||||
import 'scale_scheme.dart';
|
||||
|
||||
ChatTheme makeChatTheme(ScaleScheme scale, TextTheme textTheme) =>
|
||||
ChatTheme makeChatTheme(
|
||||
ScaleScheme scale, ScaleConfig scaleConfig, TextTheme textTheme) =>
|
||||
DefaultChatTheme(
|
||||
primaryColor: scale.primaryScale.calloutBackground,
|
||||
secondaryColor: scale.secondaryScale.calloutBackground,
|
||||
primaryColor: scaleConfig.preferBorders
|
||||
? scale.primaryScale.calloutText
|
||||
: scale.primaryScale.calloutBackground,
|
||||
secondaryColor: scaleConfig.preferBorders
|
||||
? scale.secondaryScale.calloutText
|
||||
: scale.secondaryScale.calloutBackground,
|
||||
backgroundColor: scale.grayScale.appBackground,
|
||||
messageBorderRadius: scaleConfig.borderRadiusScale * 16,
|
||||
bubbleBorderSide: scaleConfig.preferBorders
|
||||
? BorderSide(
|
||||
color: scale.primaryScale.calloutBackground,
|
||||
width: 2,
|
||||
)
|
||||
: null,
|
||||
sendButtonIcon: Image.asset(
|
||||
'assets/icon-send.png',
|
||||
color: scale.primaryScale.borderText,
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.border
|
||||
: scale.primaryScale.borderText,
|
||||
package: 'flutter_chat_ui',
|
||||
),
|
||||
inputBackgroundColor: Colors.blue,
|
||||
inputBorderRadius: BorderRadius.zero,
|
||||
inputTextDecoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: scale.primaryScale.elementBackground,
|
||||
filled: !scaleConfig.preferBorders,
|
||||
fillColor: scale.primaryScale.subtleBackground,
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.fromLTRB(8, 12, 8, 12),
|
||||
border: const OutlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.all(Radius.circular(8))),
|
||||
focusedBorder: const OutlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.all(Radius.circular(8))),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderSide: scaleConfig.preferBorders
|
||||
? BorderSide(color: scale.grayScale.border, width: 2)
|
||||
: BorderSide.none,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: scaleConfig.preferBorders
|
||||
? BorderSide(color: scale.primaryScale.border, width: 2)
|
||||
: BorderSide.none,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: scaleConfig.preferBorders
|
||||
? BorderSide(color: scale.primaryScale.border, width: 2)
|
||||
: BorderSide.none,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||
),
|
||||
inputContainerDecoration:
|
||||
BoxDecoration(color: scale.primaryScale.border),
|
||||
inputPadding: const EdgeInsets.all(9),
|
||||
inputTextColor: scale.primaryScale.appText,
|
||||
inputContainerDecoration: BoxDecoration(
|
||||
border: scaleConfig.preferBorders
|
||||
? Border(
|
||||
top: BorderSide(color: scale.primaryScale.border, width: 2))
|
||||
: null,
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.elementBackground
|
||||
: scale.primaryScale.border),
|
||||
inputPadding: const EdgeInsets.all(12),
|
||||
inputTextColor: !scaleConfig.preferBorders
|
||||
? scale.primaryScale.appText
|
||||
: scale.primaryScale.border,
|
||||
attachmentButtonIcon: const Icon(Icons.attach_file),
|
||||
sentMessageBodyTextStyle: TextStyle(
|
||||
color: scale.primaryScale.calloutText,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1.5,
|
||||
sentMessageBodyTextStyle: textTheme.bodyLarge!.copyWith(
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.primaryScale.calloutBackground
|
||||
: scale.primaryScale.calloutText,
|
||||
),
|
||||
sentEmojiMessageTextStyle: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 64,
|
||||
),
|
||||
receivedMessageBodyTextStyle: TextStyle(
|
||||
color: scale.secondaryScale.calloutText,
|
||||
color: scaleConfig.preferBorders
|
||||
? scale.secondaryScale.calloutBackground
|
||||
: scale.secondaryScale.calloutText,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1.5,
|
||||
|
|
|
@ -5,11 +5,14 @@ import 'scale_color.dart';
|
|||
import 'scale_input_decorator_theme.dart';
|
||||
import 'scale_scheme.dart';
|
||||
|
||||
ScaleScheme _contrastScale(Brightness brightness) {
|
||||
final back = brightness == Brightness.light ? Colors.white : Colors.black;
|
||||
final front = brightness == Brightness.light ? Colors.black : Colors.white;
|
||||
ScaleColor _contrastScaleColor(
|
||||
{required Brightness brightness,
|
||||
required Color frontColor,
|
||||
required Color backColor}) {
|
||||
final back = brightness == Brightness.light ? backColor : frontColor;
|
||||
final front = brightness == Brightness.light ? frontColor : backColor;
|
||||
|
||||
final primaryScale = ScaleColor(
|
||||
return ScaleColor(
|
||||
appBackground: back,
|
||||
subtleBackground: back,
|
||||
elementBackground: back,
|
||||
|
@ -28,21 +31,236 @@ ScaleScheme _contrastScale(Brightness brightness) {
|
|||
calloutBackground: front,
|
||||
calloutText: back,
|
||||
);
|
||||
|
||||
return ScaleScheme(
|
||||
primaryScale: primaryScale,
|
||||
primaryAlphaScale: primaryScale,
|
||||
secondaryScale: primaryScale,
|
||||
tertiaryScale: primaryScale,
|
||||
grayScale: primaryScale,
|
||||
errorScale: primaryScale);
|
||||
}
|
||||
|
||||
ThemeData contrastGenerator(Brightness brightness) {
|
||||
final textTheme = makeRadixTextTheme(brightness);
|
||||
final scaleScheme = _contrastScale(brightness);
|
||||
final colorScheme = scaleScheme.toColorScheme(brightness);
|
||||
final scaleConfig = ScaleConfig(useVisualIndicators: true);
|
||||
const kMonoSpaceFontDisplay = 'Source Code Pro';
|
||||
const kMonoSpaceFontText = 'Source Code Pro';
|
||||
|
||||
TextTheme makeMonoSpaceTextTheme(Brightness brightness) =>
|
||||
(brightness == Brightness.light)
|
||||
? const TextTheme(
|
||||
displayLarge: TextStyle(
|
||||
debugLabel: 'blackMonoSpace displayLarge',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.black54,
|
||||
decoration: TextDecoration.none),
|
||||
displayMedium: TextStyle(
|
||||
debugLabel: 'blackMonoSpace displayMedium',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.black54,
|
||||
decoration: TextDecoration.none),
|
||||
displaySmall: TextStyle(
|
||||
debugLabel: 'blackMonoSpace displaySmall',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.black54,
|
||||
decoration: TextDecoration.none),
|
||||
headlineLarge: TextStyle(
|
||||
debugLabel: 'blackMonoSpace headlineLarge',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.black54,
|
||||
decoration: TextDecoration.none),
|
||||
headlineMedium: TextStyle(
|
||||
debugLabel: 'blackMonoSpace headlineMedium',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.black54,
|
||||
decoration: TextDecoration.none),
|
||||
headlineSmall: TextStyle(
|
||||
debugLabel: 'blackMonoSpace headlineSmall',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.black87,
|
||||
decoration: TextDecoration.none),
|
||||
titleLarge: TextStyle(
|
||||
debugLabel: 'blackMonoSpace titleLarge',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.black87,
|
||||
decoration: TextDecoration.none),
|
||||
titleMedium: TextStyle(
|
||||
debugLabel: 'blackMonoSpace titleMedium',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black87,
|
||||
decoration: TextDecoration.none),
|
||||
titleSmall: TextStyle(
|
||||
debugLabel: 'blackMonoSpace titleSmall',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black,
|
||||
decoration: TextDecoration.none),
|
||||
bodyLarge: TextStyle(
|
||||
debugLabel: 'blackMonoSpace bodyLarge',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black87,
|
||||
decoration: TextDecoration.none),
|
||||
bodyMedium: TextStyle(
|
||||
debugLabel: 'blackMonoSpace bodyMedium',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black87,
|
||||
decoration: TextDecoration.none),
|
||||
bodySmall: TextStyle(
|
||||
debugLabel: 'blackMonoSpace bodySmall',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black54,
|
||||
decoration: TextDecoration.none),
|
||||
labelLarge: TextStyle(
|
||||
debugLabel: 'blackMonoSpace labelLarge',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black87,
|
||||
decoration: TextDecoration.none),
|
||||
labelMedium: TextStyle(
|
||||
debugLabel: 'blackMonoSpace labelMedium',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black,
|
||||
decoration: TextDecoration.none),
|
||||
labelSmall: TextStyle(
|
||||
debugLabel: 'blackMonoSpace labelSmall',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.black,
|
||||
decoration: TextDecoration.none),
|
||||
)
|
||||
: const TextTheme(
|
||||
displayLarge: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace displayLarge',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.white70,
|
||||
decoration: TextDecoration.none),
|
||||
displayMedium: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace displayMedium',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.white70,
|
||||
decoration: TextDecoration.none),
|
||||
displaySmall: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace displaySmall',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.white70,
|
||||
decoration: TextDecoration.none),
|
||||
headlineLarge: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace headlineLarge',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.white70,
|
||||
decoration: TextDecoration.none),
|
||||
headlineMedium: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace headlineMedium',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.white70,
|
||||
decoration: TextDecoration.none),
|
||||
headlineSmall: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace headlineSmall',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
titleLarge: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace titleLarge',
|
||||
fontFamily: kMonoSpaceFontDisplay,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
titleMedium: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace titleMedium',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
titleSmall: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace titleSmall',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
bodyLarge: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace bodyLarge',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
bodyMedium: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace bodyMedium',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
bodySmall: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace bodySmall',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white70,
|
||||
decoration: TextDecoration.none),
|
||||
labelLarge: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace labelLarge',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
labelMedium: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace labelMedium',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
labelSmall: TextStyle(
|
||||
debugLabel: 'whiteMonoSpace labelSmall',
|
||||
fontFamily: kMonoSpaceFontText,
|
||||
color: Colors.white,
|
||||
decoration: TextDecoration.none),
|
||||
);
|
||||
|
||||
ScaleScheme _contrastScaleScheme(
|
||||
{required Brightness brightness,
|
||||
required Color primaryFront,
|
||||
required Color primaryBack,
|
||||
required Color secondaryFront,
|
||||
required Color secondaryBack,
|
||||
required Color tertiaryFront,
|
||||
required Color tertiaryBack,
|
||||
required Color grayFront,
|
||||
required Color grayBack,
|
||||
required Color errorFront,
|
||||
required Color errorBack}) =>
|
||||
ScaleScheme(
|
||||
primaryScale: _contrastScaleColor(
|
||||
brightness: brightness,
|
||||
frontColor: primaryFront,
|
||||
backColor: primaryBack),
|
||||
primaryAlphaScale: _contrastScaleColor(
|
||||
brightness: brightness,
|
||||
frontColor: primaryFront,
|
||||
backColor: primaryBack),
|
||||
secondaryScale: _contrastScaleColor(
|
||||
brightness: brightness,
|
||||
frontColor: secondaryFront,
|
||||
backColor: secondaryBack),
|
||||
tertiaryScale: _contrastScaleColor(
|
||||
brightness: brightness,
|
||||
frontColor: tertiaryFront,
|
||||
backColor: tertiaryBack),
|
||||
grayScale: _contrastScaleColor(
|
||||
brightness: brightness, frontColor: grayFront, backColor: grayBack),
|
||||
errorScale: _contrastScaleColor(
|
||||
brightness: brightness,
|
||||
frontColor: errorFront,
|
||||
backColor: errorBack));
|
||||
|
||||
ThemeData contrastGenerator({
|
||||
required Brightness brightness,
|
||||
required ScaleConfig scaleConfig,
|
||||
required Color primaryFront,
|
||||
required Color primaryBack,
|
||||
required Color secondaryFront,
|
||||
required Color secondaryBack,
|
||||
required Color tertiaryFront,
|
||||
required Color tertiaryBack,
|
||||
required Color grayFront,
|
||||
required Color grayBack,
|
||||
required Color errorFront,
|
||||
required Color errorBack,
|
||||
TextTheme? customTextTheme,
|
||||
}) {
|
||||
final textTheme = customTextTheme ?? makeRadixTextTheme(brightness);
|
||||
final scaleScheme = _contrastScaleScheme(
|
||||
brightness: brightness,
|
||||
primaryFront: primaryFront,
|
||||
primaryBack: primaryBack,
|
||||
secondaryFront: secondaryFront,
|
||||
secondaryBack: secondaryBack,
|
||||
tertiaryFront: tertiaryFront,
|
||||
tertiaryBack: tertiaryBack,
|
||||
grayFront: grayFront,
|
||||
grayBack: grayBack,
|
||||
errorFront: errorFront,
|
||||
errorBack: errorBack,
|
||||
);
|
||||
final colorScheme = scaleScheme.toColorScheme(
|
||||
brightness,
|
||||
);
|
||||
|
||||
final themeData = ThemeData.from(
|
||||
colorScheme: colorScheme, textTheme: textTheme, useMaterial3: true);
|
||||
|
@ -50,10 +268,11 @@ ThemeData contrastGenerator(Brightness brightness) {
|
|||
bottomSheetTheme: themeData.bottomSheetTheme.copyWith(
|
||||
elevation: 0,
|
||||
modalElevation: 0,
|
||||
shape: const RoundedRectangleBorder(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16)))),
|
||||
topLeft: Radius.circular(16 * scaleConfig.borderRadiusScale),
|
||||
topRight:
|
||||
Radius.circular(16 * scaleConfig.borderRadiusScale)))),
|
||||
canvasColor: scaleScheme.primaryScale.subtleBackground,
|
||||
chipTheme: themeData.chipTheme.copyWith(
|
||||
backgroundColor: scaleScheme.primaryScale.elementBackground,
|
||||
|
@ -69,13 +288,15 @@ ThemeData contrastGenerator(Brightness brightness) {
|
|||
disabledForegroundColor: scaleScheme.grayScale.appText,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: scaleScheme.primaryScale.border),
|
||||
borderRadius: BorderRadius.circular(8))),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||
),
|
||||
textSelectionTheme: TextSelectionThemeData(
|
||||
cursorColor: scaleScheme.primaryScale.appText,
|
||||
selectionColor: scaleScheme.primaryScale.appText.withAlpha(0x7F),
|
||||
selectionHandleColor: scaleScheme.primaryScale.appText),
|
||||
inputDecorationTheme: ScaleInputDecoratorTheme(scaleScheme, textTheme),
|
||||
inputDecorationTheme:
|
||||
ScaleInputDecoratorTheme(scaleScheme, scaleConfig, textTheme),
|
||||
extensions: <ThemeExtension<dynamic>>[
|
||||
scaleScheme,
|
||||
scaleConfig,
|
||||
|
|
|
@ -604,7 +604,11 @@ ThemeData radixGenerator(Brightness brightness, RadixThemeColor themeColor) {
|
|||
final radix = _radixScheme(brightness, themeColor);
|
||||
final scaleScheme = radix.toScale();
|
||||
final colorScheme = scaleScheme.toColorScheme(brightness);
|
||||
final scaleConfig = ScaleConfig(useVisualIndicators: false);
|
||||
final scaleConfig = ScaleConfig(
|
||||
useVisualIndicators: false,
|
||||
preferBorders: false,
|
||||
borderRadiusScale: 1,
|
||||
);
|
||||
|
||||
final themeData = ThemeData.from(
|
||||
colorScheme: colorScheme, textTheme: textTheme, useMaterial3: true);
|
||||
|
@ -654,8 +658,10 @@ ThemeData radixGenerator(Brightness brightness, RadixThemeColor themeColor) {
|
|||
disabledForegroundColor: scaleScheme.grayScale.primary,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: scaleScheme.primaryScale.border),
|
||||
borderRadius: BorderRadius.circular(8))),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||
),
|
||||
inputDecorationTheme: ScaleInputDecoratorTheme(scaleScheme, textTheme),
|
||||
inputDecorationTheme:
|
||||
ScaleInputDecoratorTheme(scaleScheme, scaleConfig, textTheme),
|
||||
extensions: <ThemeExtension<dynamic>>[scaleScheme, scaleConfig]);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,13 @@ import 'package:flutter/material.dart';
|
|||
import 'scale_scheme.dart';
|
||||
|
||||
class ScaleInputDecoratorTheme extends InputDecorationTheme {
|
||||
ScaleInputDecoratorTheme(this._scaleScheme, this._textTheme)
|
||||
ScaleInputDecoratorTheme(
|
||||
this._scaleScheme, ScaleConfig scaleConfig, this._textTheme)
|
||||
: super(
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: _scaleScheme.primaryScale.border),
|
||||
borderRadius: BorderRadius.circular(8)),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8 * scaleConfig.borderRadiusScale)),
|
||||
contentPadding: const EdgeInsets.all(8),
|
||||
labelStyle: TextStyle(
|
||||
color: _scaleScheme.primaryScale.subtleText.withAlpha(127)),
|
||||
|
@ -16,7 +18,8 @@ class ScaleInputDecoratorTheme extends InputDecorationTheme {
|
|||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: _scaleScheme.primaryScale.hoverBorder, width: 2),
|
||||
borderRadius: BorderRadius.circular(8)));
|
||||
borderRadius:
|
||||
BorderRadius.circular(8 * scaleConfig.borderRadiusScale)));
|
||||
|
||||
final ScaleScheme _scaleScheme;
|
||||
final TextTheme _textTheme;
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:awesome_extensions/awesome_extensions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'scale_color.dart';
|
||||
|
@ -97,7 +100,7 @@ class ScaleScheme extends ThemeExtension<ScaleScheme> {
|
|||
onSurfaceVariant: secondaryScale.primaryText, // ?? reviewed a little
|
||||
outline: primaryScale.border,
|
||||
outlineVariant: secondaryScale.border,
|
||||
shadow: const Color(0xFF000000),
|
||||
shadow: primaryScale.primary.darken(80),
|
||||
//scrim: primaryScale.background,
|
||||
// inverseSurface: primaryScale.subtleText,
|
||||
// onInverseSurface: primaryScale.subtleBackground,
|
||||
|
@ -109,16 +112,24 @@ class ScaleScheme extends ThemeExtension<ScaleScheme> {
|
|||
class ScaleConfig extends ThemeExtension<ScaleConfig> {
|
||||
ScaleConfig({
|
||||
required this.useVisualIndicators,
|
||||
required this.preferBorders,
|
||||
required this.borderRadiusScale,
|
||||
});
|
||||
|
||||
final bool useVisualIndicators;
|
||||
final bool preferBorders;
|
||||
final double borderRadiusScale;
|
||||
|
||||
@override
|
||||
ScaleConfig copyWith({
|
||||
bool? useVisualIndicators,
|
||||
bool? preferBorders,
|
||||
double? borderRadiusScale,
|
||||
}) =>
|
||||
ScaleConfig(
|
||||
useVisualIndicators: useVisualIndicators ?? this.useVisualIndicators,
|
||||
preferBorders: preferBorders ?? this.preferBorders,
|
||||
borderRadiusScale: borderRadiusScale ?? this.borderRadiusScale,
|
||||
);
|
||||
|
||||
@override
|
||||
|
@ -127,8 +138,10 @@ class ScaleConfig extends ThemeExtension<ScaleConfig> {
|
|||
return this;
|
||||
}
|
||||
return ScaleConfig(
|
||||
useVisualIndicators:
|
||||
t < .5 ? useVisualIndicators : other.useVisualIndicators,
|
||||
);
|
||||
useVisualIndicators:
|
||||
t < .5 ? useVisualIndicators : other.useVisualIndicators,
|
||||
preferBorders: t < .5 ? preferBorders : other.preferBorders,
|
||||
borderRadiusScale:
|
||||
lerpDouble(borderRadiusScale, other.borderRadiusScale, t) ?? 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,13 +64,13 @@ class SliderTile extends StatelessWidget {
|
|||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final tileColor = scale.scale(!disabled ? tileScale : ScaleKind.gray);
|
||||
final scalecfg = theme.extension<ScaleConfig>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
|
||||
final borderColor = selected ? tileColor.hoverBorder : tileColor.border;
|
||||
final backgroundColor = scalecfg.useVisualIndicators && !selected
|
||||
final backgroundColor = scaleConfig.useVisualIndicators && !selected
|
||||
? tileColor.borderText
|
||||
: borderColor;
|
||||
final textColor = scalecfg.useVisualIndicators && !selected
|
||||
final textColor = scaleConfig.useVisualIndicators && !selected
|
||||
? borderColor
|
||||
: tileColor.borderText;
|
||||
|
||||
|
@ -79,10 +79,11 @@ class SliderTile extends StatelessWidget {
|
|||
decoration: ShapeDecoration(
|
||||
color: backgroundColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: scalecfg.useVisualIndicators
|
||||
side: scaleConfig.useVisualIndicators
|
||||
? BorderSide(width: 2, color: borderColor, strokeAlign: 0)
|
||||
: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8 * scaleConfig.borderRadiusScale),
|
||||
)),
|
||||
child: Slidable(
|
||||
// Specify a key if the Slidable is dismissible.
|
||||
|
@ -95,12 +96,12 @@ class SliderTile extends StatelessWidget {
|
|||
.map(
|
||||
(a) => SlidableAction(
|
||||
onPressed: disabled ? null : a.onPressed,
|
||||
backgroundColor: scalecfg.useVisualIndicators
|
||||
backgroundColor: scaleConfig.useVisualIndicators
|
||||
? (selected
|
||||
? tileColor.borderText
|
||||
: tileColor.border)
|
||||
: scale.scale(a.actionScale).primary,
|
||||
foregroundColor: scalecfg.useVisualIndicators
|
||||
foregroundColor: scaleConfig.useVisualIndicators
|
||||
? (selected
|
||||
? tileColor.border
|
||||
: tileColor.borderText)
|
||||
|
@ -118,12 +119,12 @@ class SliderTile extends StatelessWidget {
|
|||
.map(
|
||||
(a) => SlidableAction(
|
||||
onPressed: disabled ? null : a.onPressed,
|
||||
backgroundColor: scalecfg.useVisualIndicators
|
||||
backgroundColor: scaleConfig.useVisualIndicators
|
||||
? (selected
|
||||
? tileColor.borderText
|
||||
: tileColor.border)
|
||||
: scale.scale(a.actionScale).primary,
|
||||
foregroundColor: scalecfg.useVisualIndicators
|
||||
foregroundColor: scaleConfig.useVisualIndicators
|
||||
? (selected
|
||||
? tileColor.border
|
||||
: tileColor.borderText)
|
||||
|
@ -134,7 +135,7 @@ class SliderTile extends StatelessWidget {
|
|||
)
|
||||
.toList()),
|
||||
child: Padding(
|
||||
padding: scalecfg.useVisualIndicators
|
||||
padding: scaleConfig.useVisualIndicators
|
||||
? EdgeInsets.zero
|
||||
: const EdgeInsets.fromLTRB(0, 2, 0, 2),
|
||||
child: ListTile(
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||
import '../views/widget_helpers.dart';
|
||||
import 'contrast_generator.dart';
|
||||
import 'radix_generator.dart';
|
||||
import 'scale_scheme.dart';
|
||||
|
||||
part 'theme_preference.freezed.dart';
|
||||
part 'theme_preference.g.dart';
|
||||
|
@ -37,6 +38,7 @@ enum ColorPreference {
|
|||
lime,
|
||||
grim,
|
||||
// Accessible Colors
|
||||
elite,
|
||||
contrast;
|
||||
|
||||
factory ColorPreference.fromJson(dynamic j) =>
|
||||
|
@ -63,7 +65,7 @@ class ThemePreferences with _$ThemePreferences {
|
|||
}
|
||||
|
||||
extension ThemePreferencesExt on ThemePreferences {
|
||||
/// Get material 'ThemeData' for existinb
|
||||
/// Get material 'ThemeData' for existing theme
|
||||
ThemeData themeData() {
|
||||
late final Brightness brightness;
|
||||
switch (brightnessPreference) {
|
||||
|
@ -83,8 +85,60 @@ extension ThemePreferencesExt on ThemePreferences {
|
|||
switch (colorPreference) {
|
||||
// Special cases
|
||||
case ColorPreference.contrast:
|
||||
// xxx do contrastGenerator
|
||||
themeData = contrastGenerator(brightness);
|
||||
themeData = contrastGenerator(
|
||||
brightness: brightness,
|
||||
scaleConfig: ScaleConfig(
|
||||
useVisualIndicators: true,
|
||||
preferBorders: false,
|
||||
borderRadiusScale: 1),
|
||||
primaryFront: Colors.black,
|
||||
primaryBack: Colors.white,
|
||||
secondaryFront: Colors.black,
|
||||
secondaryBack: Colors.white,
|
||||
tertiaryFront: Colors.black,
|
||||
tertiaryBack: Colors.white,
|
||||
grayFront: Colors.black,
|
||||
grayBack: Colors.white,
|
||||
errorFront: Colors.black,
|
||||
errorBack: Colors.white,
|
||||
);
|
||||
case ColorPreference.elite:
|
||||
themeData = brightness == Brightness.light
|
||||
? contrastGenerator(
|
||||
brightness: Brightness.light,
|
||||
scaleConfig: ScaleConfig(
|
||||
useVisualIndicators: true,
|
||||
preferBorders: true,
|
||||
borderRadiusScale: 0.2),
|
||||
primaryFront: const Color(0xFF000000),
|
||||
primaryBack: const Color(0xFF00FF00),
|
||||
secondaryFront: const Color(0xFF000000),
|
||||
secondaryBack: const Color(0xFF00FFFF),
|
||||
tertiaryFront: const Color(0xFF000000),
|
||||
tertiaryBack: const Color(0xFFFF00FF),
|
||||
grayFront: const Color(0xFF000000),
|
||||
grayBack: const Color(0xFFFFFFFF),
|
||||
errorFront: const Color(0xFFC0C0C0),
|
||||
errorBack: const Color(0xFF0000FF),
|
||||
customTextTheme: makeMonoSpaceTextTheme(Brightness.light))
|
||||
: contrastGenerator(
|
||||
brightness: Brightness.dark,
|
||||
scaleConfig: ScaleConfig(
|
||||
useVisualIndicators: true,
|
||||
preferBorders: true,
|
||||
borderRadiusScale: 0.5),
|
||||
primaryFront: const Color(0xFF000000),
|
||||
primaryBack: const Color(0xFF00FF00),
|
||||
secondaryFront: const Color(0xFF000000),
|
||||
secondaryBack: const Color(0xFF00FFFF),
|
||||
tertiaryFront: const Color(0xFF000000),
|
||||
tertiaryBack: const Color(0xFFFF00FF),
|
||||
grayFront: const Color(0xFF000000),
|
||||
grayBack: const Color(0xFFFFFFFF),
|
||||
errorFront: const Color(0xFF0000FF),
|
||||
errorBack: const Color(0xFFC0C0C0),
|
||||
customTextTheme: makeMonoSpaceTextTheme(Brightness.dark),
|
||||
);
|
||||
// Generate from Radix
|
||||
case ColorPreference.scarlet:
|
||||
themeData = radixGenerator(brightness, RadixThemeColor.scarlet);
|
||||
|
|
|
@ -22,6 +22,7 @@ List<DropdownMenuItem<dynamic>> _getThemeDropdownItems() {
|
|||
ColorPreference.eggplant: translate('themes.eggplant'),
|
||||
ColorPreference.lime: translate('themes.lime'),
|
||||
ColorPreference.grim: translate('themes.grim'),
|
||||
ColorPreference.elite: translate('themes.elite'),
|
||||
ColorPreference.contrast: translate('themes.contrast')
|
||||
};
|
||||
|
||||
|
|
|
@ -11,12 +11,14 @@ class StyledDialog extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
final textTheme = theme.textTheme;
|
||||
|
||||
return AlertDialog(
|
||||
elevation: 0,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(16 * scaleConfig.borderRadiusScale)),
|
||||
),
|
||||
contentPadding: const EdgeInsets.all(4),
|
||||
backgroundColor: scale.primaryScale.dialogBorder,
|
||||
|
@ -31,12 +33,14 @@ class StyledDialog extends StatelessWidget {
|
|||
decoration: ShapeDecoration(
|
||||
color: scale.primaryScale.border,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16))),
|
||||
borderRadius: BorderRadius.circular(
|
||||
16 * scaleConfig.borderRadiusScale))),
|
||||
child: DecoratedBox(
|
||||
decoration: ShapeDecoration(
|
||||
color: scale.primaryScale.appBackground,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12))),
|
||||
borderRadius: BorderRadius.circular(
|
||||
12 * scaleConfig.borderRadiusScale))),
|
||||
child: child.paddingAll(0))));
|
||||
}
|
||||
|
||||
|
|
27
lib/theme/views/styled_scaffold.dart
Normal file
27
lib/theme/views/styled_scaffold.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
import 'package:awesome_extensions/awesome_extensions.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../theme.dart';
|
||||
|
||||
class StyledScaffold extends StatelessWidget {
|
||||
const StyledScaffold({required this.appBar, required this.body, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
|
||||
return clipBorder(
|
||||
clipEnabled: true,
|
||||
borderEnabled: scaleConfig.useVisualIndicators,
|
||||
borderRadius: 16 * scaleConfig.borderRadiusScale,
|
||||
borderColor: scale.primaryScale.border,
|
||||
child: Scaffold(appBar: appBar, body: body, key: key))
|
||||
.paddingAll(32);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
final PreferredSizeWidget? appBar;
|
||||
final Widget? body;
|
||||
}
|
|
@ -2,4 +2,5 @@ export 'brightness_preferences.dart';
|
|||
export 'color_preferences.dart';
|
||||
export 'scanner_error_widget.dart';
|
||||
export 'styled_dialog.dart';
|
||||
export 'styled_scaffold.dart';
|
||||
export 'widget_helpers.dart';
|
||||
|
|
|
@ -132,7 +132,7 @@ void showErrorToast(BuildContext context, String message) {
|
|||
contentPadding: const EdgeInsets.all(16),
|
||||
primaryColor: scale.errorScale.elementBackground,
|
||||
secondaryColor: scale.errorScale.calloutBackground,
|
||||
borderRadius: 16,
|
||||
borderRadius: 16 * scaleConfig.borderRadiusScale,
|
||||
toastDuration: const Duration(seconds: 4),
|
||||
animationDuration: const Duration(milliseconds: 1000),
|
||||
displayBorder: scaleConfig.useVisualIndicators,
|
||||
|
@ -152,7 +152,7 @@ void showInfoToast(BuildContext context, String message) {
|
|||
contentPadding: const EdgeInsets.all(16),
|
||||
primaryColor: scale.tertiaryScale.elementBackground,
|
||||
secondaryColor: scale.tertiaryScale.calloutBackground,
|
||||
borderRadius: 16,
|
||||
borderRadius: 16 * scaleConfig.borderRadiusScale,
|
||||
toastDuration: const Duration(seconds: 2),
|
||||
animationDuration: const Duration(milliseconds: 500),
|
||||
displayBorder: scaleConfig.useVisualIndicators,
|
||||
|
@ -170,13 +170,15 @@ Widget styledTitleContainer({
|
|||
}) {
|
||||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
final textTheme = theme.textTheme;
|
||||
|
||||
return DecoratedBox(
|
||||
decoration: ShapeDecoration(
|
||||
color: borderColor ?? scale.primaryScale.border,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius:
|
||||
BorderRadius.circular(16 * scaleConfig.borderRadiusScale),
|
||||
)),
|
||||
child: Column(children: [
|
||||
Text(
|
||||
|
@ -189,7 +191,8 @@ Widget styledTitleContainer({
|
|||
color:
|
||||
backgroundColor ?? scale.primaryScale.subtleBackground,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(
|
||||
16 * scaleConfig.borderRadiusScale),
|
||||
)),
|
||||
child: child)
|
||||
.paddingAll(4)
|
||||
|
@ -207,15 +210,17 @@ Widget styledBottomSheet({
|
|||
}) {
|
||||
final theme = Theme.of(context);
|
||||
final scale = theme.extension<ScaleScheme>()!;
|
||||
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||
final textTheme = theme.textTheme;
|
||||
|
||||
return DecoratedBox(
|
||||
decoration: ShapeDecoration(
|
||||
color: borderColor ?? scale.primaryScale.dialogBorder,
|
||||
shape: const RoundedRectangleBorder(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16)))),
|
||||
topLeft: Radius.circular(16 * scaleConfig.borderRadiusScale),
|
||||
topRight:
|
||||
Radius.circular(16 * scaleConfig.borderRadiusScale)))),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Text(
|
||||
title,
|
||||
|
@ -226,10 +231,12 @@ Widget styledBottomSheet({
|
|||
decoration: ShapeDecoration(
|
||||
color:
|
||||
backgroundColor ?? scale.primaryScale.subtleBackground,
|
||||
shape: const RoundedRectangleBorder(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16),
|
||||
topRight: Radius.circular(16)))),
|
||||
topLeft: Radius.circular(
|
||||
16 * scaleConfig.borderRadiusScale),
|
||||
topRight: Radius.circular(
|
||||
16 * scaleConfig.borderRadiusScale)))),
|
||||
child: child)
|
||||
.paddingLTRB(4, 4, 4, 0)
|
||||
]));
|
||||
|
@ -261,3 +268,25 @@ const grayColorFilter = ColorFilter.matrix(<double>[
|
|||
1,
|
||||
0,
|
||||
]);
|
||||
|
||||
Widget clipBorder({
|
||||
required bool clipEnabled,
|
||||
required bool borderEnabled,
|
||||
required double borderRadius,
|
||||
required Color borderColor,
|
||||
required Widget child,
|
||||
}) =>
|
||||
ClipRRect(
|
||||
borderRadius: clipEnabled
|
||||
? BorderRadius.circular(borderRadius)
|
||||
: BorderRadius.zero,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(boxShadow: [
|
||||
if (borderEnabled) BoxShadow(color: borderColor, spreadRadius: 2)
|
||||
]),
|
||||
child: ClipRRect(
|
||||
borderRadius: clipEnabled
|
||||
? BorderRadius.circular(borderRadius)
|
||||
: BorderRadius.zero,
|
||||
child: child,
|
||||
)).paddingAll(clipEnabled && borderEnabled ? 2 : 0));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue