Refactor a large part of main into theme
This commit is contained in:
417
lib/main.dart
417
lib/main.dart
@@ -5,6 +5,175 @@ import 'package:rimworld_modman/logger.dart';
|
|||||||
import 'package:rimworld_modman/mod.dart';
|
import 'package:rimworld_modman/mod.dart';
|
||||||
import 'package:rimworld_modman/mod_list.dart';
|
import 'package:rimworld_modman/mod_list.dart';
|
||||||
|
|
||||||
|
// Theme extension to store app-specific constants
|
||||||
|
class AppThemeExtension extends ThemeExtension<AppThemeExtension> {
|
||||||
|
final double iconSizeSmall;
|
||||||
|
final double iconSizeRegular;
|
||||||
|
final double iconSizeLarge;
|
||||||
|
final double textSizeSmall;
|
||||||
|
final double textSizeRegular;
|
||||||
|
final double textSizeLarge;
|
||||||
|
final EdgeInsets paddingSmall;
|
||||||
|
final EdgeInsets paddingRegular;
|
||||||
|
final EdgeInsets paddingLarge;
|
||||||
|
final Color enabledModColor;
|
||||||
|
final Color enabledModBackgroundColor;
|
||||||
|
final Color errorBackgroundColor;
|
||||||
|
final Color warningColor;
|
||||||
|
final Color errorColor;
|
||||||
|
final Color baseGameColor;
|
||||||
|
final Color expansionColor;
|
||||||
|
final Color linkColor;
|
||||||
|
final Color loadAfterColor;
|
||||||
|
final Color loadBeforeColor;
|
||||||
|
|
||||||
|
AppThemeExtension({
|
||||||
|
required this.iconSizeSmall,
|
||||||
|
required this.iconSizeRegular,
|
||||||
|
required this.iconSizeLarge,
|
||||||
|
required this.textSizeSmall,
|
||||||
|
required this.textSizeRegular,
|
||||||
|
required this.textSizeLarge,
|
||||||
|
required this.paddingSmall,
|
||||||
|
required this.paddingRegular,
|
||||||
|
required this.paddingLarge,
|
||||||
|
required this.enabledModColor,
|
||||||
|
required this.enabledModBackgroundColor,
|
||||||
|
required this.errorBackgroundColor,
|
||||||
|
required this.warningColor,
|
||||||
|
required this.errorColor,
|
||||||
|
required this.baseGameColor,
|
||||||
|
required this.expansionColor,
|
||||||
|
required this.linkColor,
|
||||||
|
required this.loadAfterColor,
|
||||||
|
required this.loadBeforeColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
static AppThemeExtension of(BuildContext context) {
|
||||||
|
return Theme.of(context).extension<AppThemeExtension>()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ThemeExtension<AppThemeExtension> copyWith({
|
||||||
|
double? iconSizeSmall,
|
||||||
|
double? iconSizeRegular,
|
||||||
|
double? iconSizeLarge,
|
||||||
|
double? textSizeSmall,
|
||||||
|
double? textSizeRegular,
|
||||||
|
double? textSizeLarge,
|
||||||
|
EdgeInsets? paddingSmall,
|
||||||
|
EdgeInsets? paddingRegular,
|
||||||
|
EdgeInsets? paddingLarge,
|
||||||
|
Color? enabledModColor,
|
||||||
|
Color? enabledModBackgroundColor,
|
||||||
|
Color? errorBackgroundColor,
|
||||||
|
Color? warningColor,
|
||||||
|
Color? errorColor,
|
||||||
|
Color? baseGameColor,
|
||||||
|
Color? expansionColor,
|
||||||
|
Color? linkColor,
|
||||||
|
Color? loadAfterColor,
|
||||||
|
Color? loadBeforeColor,
|
||||||
|
}) {
|
||||||
|
return AppThemeExtension(
|
||||||
|
iconSizeSmall: iconSizeSmall ?? this.iconSizeSmall,
|
||||||
|
iconSizeRegular: iconSizeRegular ?? this.iconSizeRegular,
|
||||||
|
iconSizeLarge: iconSizeLarge ?? this.iconSizeLarge,
|
||||||
|
textSizeSmall: textSizeSmall ?? this.textSizeSmall,
|
||||||
|
textSizeRegular: textSizeRegular ?? this.textSizeRegular,
|
||||||
|
textSizeLarge: textSizeLarge ?? this.textSizeLarge,
|
||||||
|
paddingSmall: paddingSmall ?? this.paddingSmall,
|
||||||
|
paddingRegular: paddingRegular ?? this.paddingRegular,
|
||||||
|
paddingLarge: paddingLarge ?? this.paddingLarge,
|
||||||
|
enabledModColor: enabledModColor ?? this.enabledModColor,
|
||||||
|
enabledModBackgroundColor:
|
||||||
|
enabledModBackgroundColor ?? this.enabledModBackgroundColor,
|
||||||
|
errorBackgroundColor: errorBackgroundColor ?? this.errorBackgroundColor,
|
||||||
|
warningColor: warningColor ?? this.warningColor,
|
||||||
|
errorColor: errorColor ?? this.errorColor,
|
||||||
|
baseGameColor: baseGameColor ?? this.baseGameColor,
|
||||||
|
expansionColor: expansionColor ?? this.expansionColor,
|
||||||
|
linkColor: linkColor ?? this.linkColor,
|
||||||
|
loadAfterColor: loadAfterColor ?? this.loadAfterColor,
|
||||||
|
loadBeforeColor: loadBeforeColor ?? this.loadBeforeColor,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ThemeExtension<AppThemeExtension> lerp(
|
||||||
|
covariant ThemeExtension<AppThemeExtension>? other,
|
||||||
|
double t,
|
||||||
|
) {
|
||||||
|
if (other is! AppThemeExtension) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return AppThemeExtension(
|
||||||
|
iconSizeSmall: lerpDouble(iconSizeSmall, other.iconSizeSmall, t),
|
||||||
|
iconSizeRegular: lerpDouble(iconSizeRegular, other.iconSizeRegular, t),
|
||||||
|
iconSizeLarge: lerpDouble(iconSizeLarge, other.iconSizeLarge, t),
|
||||||
|
textSizeSmall: lerpDouble(textSizeSmall, other.textSizeSmall, t),
|
||||||
|
textSizeRegular: lerpDouble(textSizeRegular, other.textSizeRegular, t),
|
||||||
|
textSizeLarge: lerpDouble(textSizeLarge, other.textSizeLarge, t),
|
||||||
|
paddingSmall: EdgeInsets.lerp(paddingSmall, other.paddingSmall, t)!,
|
||||||
|
paddingRegular: EdgeInsets.lerp(paddingRegular, other.paddingRegular, t)!,
|
||||||
|
paddingLarge: EdgeInsets.lerp(paddingLarge, other.paddingLarge, t)!,
|
||||||
|
enabledModColor: Color.lerp(enabledModColor, other.enabledModColor, t)!,
|
||||||
|
enabledModBackgroundColor:
|
||||||
|
Color.lerp(
|
||||||
|
enabledModBackgroundColor,
|
||||||
|
other.enabledModBackgroundColor,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
|
errorBackgroundColor:
|
||||||
|
Color.lerp(errorBackgroundColor, other.errorBackgroundColor, t)!,
|
||||||
|
warningColor: Color.lerp(warningColor, other.warningColor, t)!,
|
||||||
|
errorColor: Color.lerp(errorColor, other.errorColor, t)!,
|
||||||
|
baseGameColor: Color.lerp(baseGameColor, other.baseGameColor, t)!,
|
||||||
|
expansionColor: Color.lerp(expansionColor, other.expansionColor, t)!,
|
||||||
|
linkColor: Color.lerp(linkColor, other.linkColor, t)!,
|
||||||
|
loadAfterColor: Color.lerp(loadAfterColor, other.loadAfterColor, t)!,
|
||||||
|
loadBeforeColor: Color.lerp(loadBeforeColor, other.loadBeforeColor, t)!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AppThemeExtension light() {
|
||||||
|
return AppThemeExtension(
|
||||||
|
iconSizeSmall: 16,
|
||||||
|
iconSizeRegular: 24,
|
||||||
|
iconSizeLarge: 32,
|
||||||
|
textSizeSmall: 10,
|
||||||
|
textSizeRegular: 14,
|
||||||
|
textSizeLarge: 18,
|
||||||
|
paddingSmall: const EdgeInsets.all(4.0),
|
||||||
|
paddingRegular: const EdgeInsets.all(8.0),
|
||||||
|
paddingLarge: const EdgeInsets.all(16.0),
|
||||||
|
enabledModColor: Colors.green,
|
||||||
|
enabledModBackgroundColor: const Color.fromRGBO(0, 128, 0, 0.1),
|
||||||
|
errorBackgroundColor: Color.fromRGBO(
|
||||||
|
Colors.red.shade900.red,
|
||||||
|
Colors.red.shade900.green,
|
||||||
|
Colors.red.shade900.blue,
|
||||||
|
0.3,
|
||||||
|
),
|
||||||
|
warningColor: Colors.orange,
|
||||||
|
errorColor: Colors.red,
|
||||||
|
baseGameColor: Colors.blue,
|
||||||
|
expansionColor: Colors.yellow,
|
||||||
|
linkColor: Colors.orange,
|
||||||
|
loadAfterColor: Colors.blue,
|
||||||
|
loadBeforeColor: Colors.green,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AppThemeExtension dark() {
|
||||||
|
return light(); // For now, we use the same values for both light and dark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double lerpDouble(double a, double b, double t) {
|
||||||
|
return a + (b - a) * t;
|
||||||
|
}
|
||||||
|
|
||||||
// Constants for file paths
|
// Constants for file paths
|
||||||
final String root =
|
final String root =
|
||||||
Platform.isWindows
|
Platform.isWindows
|
||||||
@@ -53,6 +222,7 @@ class RimWorldModManager extends StatelessWidget {
|
|||||||
backgroundColor: Color(0xFF2A3440),
|
backgroundColor: Color(0xFF2A3440),
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
),
|
),
|
||||||
|
extensions: [AppThemeExtension.dark()],
|
||||||
),
|
),
|
||||||
home: const ModManagerHomePage(),
|
home: const ModManagerHomePage(),
|
||||||
);
|
);
|
||||||
@@ -255,7 +425,7 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: AppThemeExtension.of(context).paddingRegular,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
// Search field
|
// Search field
|
||||||
@@ -336,15 +506,14 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
_incompatibleMods.isNotEmpty ||
|
_incompatibleMods.isNotEmpty ||
|
||||||
(_loadOrderErrors?.isNotEmpty ?? false))
|
(_loadOrderErrors?.isNotEmpty ?? false))
|
||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
margin: EdgeInsets.symmetric(
|
||||||
padding: const EdgeInsets.all(8.0),
|
horizontal:
|
||||||
|
AppThemeExtension.of(context).paddingRegular.horizontal,
|
||||||
|
vertical: AppThemeExtension.of(context).paddingSmall.vertical,
|
||||||
|
),
|
||||||
|
padding: AppThemeExtension.of(context).paddingRegular,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Color.fromRGBO(
|
color: AppThemeExtension.of(context).errorBackgroundColor,
|
||||||
Colors.red.shade900.red,
|
|
||||||
Colors.red.shade900.green,
|
|
||||||
Colors.red.shade900.blue,
|
|
||||||
0.3
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(4.0),
|
borderRadius: BorderRadius.circular(4.0),
|
||||||
border: Border.all(color: Colors.red.shade800),
|
border: Border.all(color: Colors.red.shade800),
|
||||||
),
|
),
|
||||||
@@ -357,12 +526,18 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
padding: const EdgeInsets.only(bottom: 4.0),
|
padding: const EdgeInsets.only(bottom: 4.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.loop, color: Colors.orange, size: 16),
|
Icon(
|
||||||
|
Icons.loop,
|
||||||
|
color: AppThemeExtension.of(context).warningColor,
|
||||||
|
size: AppThemeExtension.of(context).iconSizeSmall,
|
||||||
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Dependency cycle detected: ${_cycleInfo!.join(" -> ")}',
|
'Dependency cycle detected: ${_cycleInfo!.join(" -> ")}',
|
||||||
style: const TextStyle(color: Colors.orange),
|
style: TextStyle(
|
||||||
|
color: AppThemeExtension.of(context).warningColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -376,10 +551,10 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Icon(
|
Icon(
|
||||||
Icons.warning,
|
Icons.warning,
|
||||||
color: Colors.orange,
|
color: AppThemeExtension.of(context).warningColor,
|
||||||
size: 16,
|
size: AppThemeExtension.of(context).iconSizeSmall,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -388,7 +563,12 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'${_incompatibleMods.length} incompatible mod pairs:',
|
'${_incompatibleMods.length} incompatible mod pairs:',
|
||||||
style: const TextStyle(color: Colors.orange),
|
style: TextStyle(
|
||||||
|
color:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).warningColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
if (_incompatibleMods.length <= 3)
|
if (_incompatibleMods.length <= 3)
|
||||||
...List.generate(_incompatibleMods.length, (
|
...List.generate(_incompatibleMods.length, (
|
||||||
@@ -408,7 +588,10 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
'• $mod1 ↔ $mod2',
|
'• $mod1 ↔ $mod2',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.orange.shade300,
|
color: Colors.orange.shade300,
|
||||||
fontSize: 12,
|
fontSize:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).textSizeSmall,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -425,19 +608,21 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Icon(
|
Icon(
|
||||||
Icons.error_outline,
|
Icons.error_outline,
|
||||||
color: Colors.red,
|
color: AppThemeExtension.of(context).errorColor,
|
||||||
size: 16,
|
size: AppThemeExtension.of(context).iconSizeSmall,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text(
|
Text(
|
||||||
'Dependency errors:',
|
'Dependency errors:',
|
||||||
style: TextStyle(color: Colors.red),
|
style: TextStyle(
|
||||||
|
color: AppThemeExtension.of(context).errorColor,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
...List.generate(
|
...List.generate(
|
||||||
_loadOrderErrors!.length > 5
|
_loadOrderErrors!.length > 5
|
||||||
@@ -452,7 +637,10 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
'• ${_loadOrderErrors![index]}',
|
'• ${_loadOrderErrors![index]}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.red.shade300,
|
color: Colors.red.shade300,
|
||||||
fontSize: 12,
|
fontSize:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).textSizeSmall,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -467,7 +655,10 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
'(${_loadOrderErrors!.length - 5} more errors...)',
|
'(${_loadOrderErrors!.length - 5} more errors...)',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.red.shade300,
|
color: Colors.red.shade300,
|
||||||
fontSize: 12,
|
fontSize:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).textSizeSmall,
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -488,7 +679,7 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
// LEFT PANEL - All available mods (alphabetical)
|
// LEFT PANEL - All available mods (alphabetical)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: const EdgeInsets.all(8.0),
|
margin: AppThemeExtension.of(context).paddingRegular,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
@@ -503,11 +694,12 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
),
|
),
|
||||||
if (_searchQuery.isNotEmpty)
|
if (_searchQuery.isNotEmpty)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(4.0),
|
padding: AppThemeExtension.of(context).paddingSmall,
|
||||||
child: Text(
|
child: Text(
|
||||||
'Searching: "$_searchQuery"',
|
'Searching: "$_searchQuery"',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize:
|
||||||
|
AppThemeExtension.of(context).textSizeSmall,
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
color: Colors.grey.shade400,
|
color: Colors.grey.shade400,
|
||||||
),
|
),
|
||||||
@@ -528,32 +720,54 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
mod.name,
|
mod.name,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color:
|
color:
|
||||||
isActive ? Colors.green : Colors.white,
|
isActive
|
||||||
|
? AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).enabledModColor
|
||||||
|
: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'ID: ${mod.id}\nSize: ${mod.size} files',
|
'ID: ${mod.id}\nSize: ${mod.size} files',
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
|
tileColor:
|
||||||
|
isActive
|
||||||
|
? AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).enabledModBackgroundColor
|
||||||
|
: null,
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (mod.isBaseGame)
|
if (mod.isBaseGame)
|
||||||
const Tooltip(
|
Tooltip(
|
||||||
message: 'Base Game',
|
message: 'Base Game',
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.home,
|
Icons.home,
|
||||||
color: Colors.blue,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).baseGameColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (mod.isExpansion)
|
if (mod.isExpansion)
|
||||||
const Tooltip(
|
Tooltip(
|
||||||
message: 'Expansion',
|
message: 'Expansion',
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.star,
|
Icons.star,
|
||||||
color: Colors.yellow,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).expansionColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
@@ -561,30 +775,48 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
Tooltip(
|
Tooltip(
|
||||||
message:
|
message:
|
||||||
'Dependencies:\n${mod.dependencies.join('\n')}',
|
'Dependencies:\n${mod.dependencies.join('\n')}',
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
Icons.link,
|
Icons.link,
|
||||||
color: Colors.orange,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).linkColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (mod.loadAfter.isNotEmpty)
|
if (mod.loadAfter.isNotEmpty)
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message:
|
message:
|
||||||
'Loads after:\n${mod.loadAfter.join('\n')}',
|
'Loads after:\n${mod.loadAfter.join('\n')}',
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
Icons.arrow_downward,
|
Icons.arrow_downward,
|
||||||
color: Colors.blue,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).loadAfterColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (mod.loadBefore.isNotEmpty)
|
if (mod.loadBefore.isNotEmpty)
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message:
|
message:
|
||||||
'Loads before:\n${mod.loadBefore.join('\n')}',
|
'Loads before:\n${mod.loadBefore.join('\n')}',
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
Icons.arrow_upward,
|
Icons.arrow_upward,
|
||||||
color: Colors.green,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).loadBeforeColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -605,7 +837,7 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
// RIGHT PANEL - Active mods (load order)
|
// RIGHT PANEL - Active mods (load order)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: const EdgeInsets.all(8.0),
|
margin: AppThemeExtension.of(context).paddingRegular,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
@@ -619,13 +851,14 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: AppThemeExtension.of(context).paddingRegular,
|
||||||
child: Text(
|
child: Text(
|
||||||
_searchQuery.isNotEmpty
|
_searchQuery.isNotEmpty
|
||||||
? 'Searching: "$_searchQuery"'
|
? 'Searching: "$_searchQuery"'
|
||||||
: 'Larger mods are prioritized during auto-sorting.',
|
: 'Larger mods are prioritized during auto-sorting.',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize:
|
||||||
|
AppThemeExtension.of(context).textSizeSmall,
|
||||||
color: Colors.grey.shade400,
|
color: Colors.grey.shade400,
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
),
|
),
|
||||||
@@ -659,10 +892,10 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Card(
|
child: Card(
|
||||||
margin: const EdgeInsets.symmetric(
|
margin:
|
||||||
horizontal: 8.0,
|
AppThemeExtension.of(
|
||||||
vertical: 4.0,
|
context,
|
||||||
),
|
).paddingRegular,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: SizedBox(
|
leading: SizedBox(
|
||||||
width: 50,
|
width: 50,
|
||||||
@@ -680,7 +913,12 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color:
|
color:
|
||||||
_searchQuery.isNotEmpty
|
_searchQuery.isNotEmpty
|
||||||
? const Color.fromRGBO(0, 0, 255, 0.2)
|
? const Color.fromRGBO(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255,
|
||||||
|
0.2,
|
||||||
|
)
|
||||||
: null,
|
: null,
|
||||||
borderRadius:
|
borderRadius:
|
||||||
BorderRadius.circular(4),
|
BorderRadius.circular(4),
|
||||||
@@ -692,7 +930,10 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
'$actualLoadOrderPosition',
|
'$actualLoadOrderPosition',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 12,
|
fontSize:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).textSizeSmall,
|
||||||
color:
|
color:
|
||||||
_searchQuery.isNotEmpty
|
_searchQuery.isNotEmpty
|
||||||
? Colors.blue.shade300
|
? Colors.blue.shade300
|
||||||
@@ -712,8 +953,11 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
'This mod contains ${mod.size} files.',
|
'This mod contains ${mod.size} files.',
|
||||||
child: Text(
|
child: Text(
|
||||||
'${mod.size}',
|
'${mod.size}',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 10,
|
fontSize:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).textSizeSmall,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -727,37 +971,60 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
title: Text(mod.name),
|
title: Text(mod.name),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
mod.id,
|
mod.id,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: TextStyle(
|
||||||
|
fontSize:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).textSizeSmall,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (mod.isBaseGame)
|
if (mod.isBaseGame)
|
||||||
const Tooltip(
|
Tooltip(
|
||||||
message: 'Base Game',
|
message: 'Base Game',
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.home,
|
Icons.home,
|
||||||
color: Colors.blue,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).baseGameColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (mod.isExpansion)
|
if (mod.isExpansion)
|
||||||
const Tooltip(
|
Tooltip(
|
||||||
message: 'Expansion',
|
message: 'Expansion',
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.star,
|
Icons.star,
|
||||||
color: Colors.yellow,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).expansionColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (mod.dependencies.isNotEmpty)
|
if (mod.dependencies.isNotEmpty)
|
||||||
Tooltip(
|
Tooltip(
|
||||||
message:
|
message:
|
||||||
'Dependencies:\n${mod.dependencies.join('\n')}',
|
'Dependencies:\n${mod.dependencies.join('\n')}',
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
Icons.link,
|
Icons.link,
|
||||||
color: Colors.orange,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).linkColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
@@ -765,10 +1032,16 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
Tooltip(
|
Tooltip(
|
||||||
message:
|
message:
|
||||||
'Loads after other mods:\n${mod.loadAfter.join('\n')}',
|
'Loads after other mods:\n${mod.loadAfter.join('\n')}',
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
Icons.arrow_downward,
|
Icons.arrow_downward,
|
||||||
color: Colors.blue,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).loadAfterColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
@@ -776,10 +1049,16 @@ class _ModManagerPageState extends State<ModManagerPage> {
|
|||||||
Tooltip(
|
Tooltip(
|
||||||
message:
|
message:
|
||||||
'Loads before other mods:\n${mod.loadBefore.join('\n')}',
|
'Loads before other mods:\n${mod.loadBefore.join('\n')}',
|
||||||
child: const Icon(
|
child: Icon(
|
||||||
Icons.arrow_upward,
|
Icons.arrow_upward,
|
||||||
color: Colors.green,
|
color:
|
||||||
size: 24,
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).loadBeforeColor,
|
||||||
|
size:
|
||||||
|
AppThemeExtension.of(
|
||||||
|
context,
|
||||||
|
).iconSizeRegular,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Reference in New Issue
Block a user