Skip to content
Snippets Groups Projects
Commit 5c5a46fa authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Add Activity Parameters widgets

parent eb9c090b
No related branches found
No related tags found
1 merge request!9Resolve "Add ActivityParameters widgets"
Pipeline #7035 passed
## 0.5.0
- Add activity parameters widgets
## 0.4.0 ## 0.4.0
- Add activity actions buttons - Add activity actions buttons
......
...@@ -23,6 +23,16 @@ export 'settings/application_settings_theme_card.dart' show ApplicationSettingsT ...@@ -23,6 +23,16 @@ export 'settings/application_settings_theme_card.dart' show ApplicationSettingsT
export 'settings/application_theme_mode_cubit.dart' export 'settings/application_theme_mode_cubit.dart'
show ApplicationThemeModeCubit, ApplicationThemeModeState; show ApplicationThemeModeCubit, ApplicationThemeModeState;
export 'parameters/application_config_definition.dart'
show
ApplicationConfigDefinition,
ApplicationSettingsParameter,
ApplicationSettingsParameterItemValue;
export 'parameters/pages/parameters.dart' show PageParameters;
export 'parameters/settings/settings_activity_cubit.dart'
show ActivitySettingsCubit, ActivitySettingsState;
export 'parameters/models/settings/settings_activity.dart' show ActivitySettings;
// dependencies // dependencies
export 'package:easy_localization/easy_localization.dart' export 'package:easy_localization/easy_localization.dart'
......
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class ApplicationConfigDefinition {
final String appTitle;
final List<ApplicationSettingsParameter> activitySettings;
final void Function(BuildContext context) startNewActivity;
final void Function(BuildContext context) deleteCurrentActivity;
final void Function(BuildContext context) resumeActivity;
const ApplicationConfigDefinition({
required this.appTitle,
required this.activitySettings,
required this.startNewActivity,
required this.deleteCurrentActivity,
required this.resumeActivity,
});
ApplicationSettingsParameter getFromCode(String paramCode) {
final List<ApplicationSettingsParameter> settings = activitySettings;
return settings.where((setting) => setting.code == paramCode).firstOrNull ??
ApplicationSettingsParameter.empty();
}
}
class ApplicationSettingsParameter {
final String code;
final bool displayedOnTop;
final List<ApplicationSettingsParameterItemValue> values;
final Widget Function({
required BuildContext context,
required double size,
required ApplicationSettingsParameterItemValue itemValue,
required VoidCallback onPressed,
})? builder;
final CustomPainter Function(BuildContext context, String value)? customPainter;
final int Function(String value)? intValueGetter;
final Color Function(String value)? colorGetter;
const ApplicationSettingsParameter({
required this.code,
this.displayedOnTop = true,
required this.values,
this.builder,
this.customPainter,
this.colorGetter,
this.intValueGetter,
});
List<String> get allowedValues {
return values.map((ApplicationSettingsParameterItemValue item) => item.value).toList();
}
String get defaultValue => values.firstWhere((element) => element.isDefault).value;
factory ApplicationSettingsParameter.empty() {
return ApplicationSettingsParameter(
code: '',
values: [
ApplicationSettingsParameterItemValue.empty(),
],
intValueGetter: (value) => 0,
);
}
Widget buildParameterItem({
required BuildContext context,
required ApplicationSettingsParameter parameter,
required ApplicationSettingsParameterItemValue itemValue,
required double size,
required VoidCallback? onPressed,
}) {
final Color buttonColorActive = (onPressed != null) ? Colors.blue : Colors.grey;
final Color buttonColorInactive = Theme.of(context).colorScheme.surface;
const double buttonBorderWidth = 4.0;
const double buttonBorderRadius = 12.0;
final ActivitySettingsCubit activitySettingsCubit =
BlocProvider.of<ActivitySettingsCubit>(context);
final String currentValue = activitySettingsCubit.get(code);
final bool isSelected = (currentValue == itemValue.value);
final Color buttonColor = isSelected ? buttonColorActive : buttonColorInactive;
Widget content = SizedBox.shrink();
if (builder != null) {
content = builder!(
context: context,
size: size,
itemValue: itemValue,
onPressed: onPressed ?? () {},
);
} else {
if (customPainter != null) {
content = StyledButton(
color: itemValue.color ?? Colors.grey,
onPressed: onPressed ?? () {},
child: CustomPaint(
size: Size(size, size),
willChange: false,
painter: customPainter!(context, itemValue.value),
isComplex: true,
),
);
} else {
content = StyledButton.text(
color: itemValue.color ?? Colors.grey,
caption: itemValue.text ?? itemValue.value,
onPressed: onPressed ?? () {},
);
}
}
return Container(
decoration: BoxDecoration(
color: buttonColor,
borderRadius: BorderRadius.circular(buttonBorderRadius),
border: Border.all(
color: buttonColor,
width: buttonBorderWidth,
),
),
child: content,
);
}
}
class ApplicationSettingsParameterItemValue {
final String value;
final bool isDefault;
final Color? color;
final String? text;
const ApplicationSettingsParameterItemValue({
required this.value,
this.isDefault = false,
this.color,
this.text,
});
factory ApplicationSettingsParameterItemValue.empty() {
return ApplicationSettingsParameterItemValue(
value: '',
isDefault: true,
);
}
@override
String toString() {
return value;
}
}
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class ActivitySettings {
final Map<String, String> values;
final ApplicationConfigDefinition appConfig;
ActivitySettings({
required this.appConfig,
required this.values,
});
factory ActivitySettings.createDefault({
required ApplicationConfigDefinition appConfig,
}) {
Map<String, String> values = {};
for (var setting in appConfig.activitySettings) {
values[setting.code] = setting.defaultValue;
}
return ActivitySettings(
appConfig: appConfig,
values: values,
);
}
String get(String code) {
if (values.keys.contains(code)) {
if (appConfig.getFromCode(code).allowedValues.contains(values[code])) {
return values[code] ?? appConfig.getFromCode(code).defaultValue;
}
}
return appConfig.getFromCode(code).defaultValue;
}
int getAsInt(String parameterCode) {
final ApplicationSettingsParameter parameter = appConfig.getFromCode(parameterCode);
if (values.keys.contains(parameterCode)) {
if (parameter.allowedValues.contains(values[parameterCode])) {
if (parameter.intValueGetter != null) {
return parameter.intValueGetter!(get(parameterCode));
} else {
return int.parse(get(parameterCode));
}
}
}
if (parameter.intValueGetter != null) {
return parameter.intValueGetter!(parameter.defaultValue);
} else {
return int.parse(parameter.defaultValue);
}
}
void dump() {
printlog('$ActivitySettings:');
values.forEach((code, value) {
printlog(' $code: $value');
});
printlog('');
}
@override
String toString() {
return '$ActivitySettings(${toJson()})';
}
Map<String, dynamic>? toJson() {
return values;
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
class PageParameters extends StatelessWidget {
const PageParameters({
super.key,
required this.config,
required this.canBeResumed,
});
final ApplicationConfigDefinition config;
final bool canBeResumed;
final double separatorHeight = 8.0;
@override
Widget build(BuildContext context) {
final List<Widget> lines = [];
// Activity settings (top)
for (ApplicationSettingsParameter parameter in config.activitySettings) {
if (parameter.displayedOnTop) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
parameter: parameter,
isEnabled: !canBeResumed,
),
));
lines.add(SizedBox(height: separatorHeight));
}
}
lines.add(Expanded(
child: SizedBox(height: separatorHeight),
));
if (canBeResumed) {
// Resume activity
lines.add(AspectRatio(
aspectRatio: 3,
child: ActivityButtonResumeSaved(
onPressed: () {
config.resumeActivity(context);
},
),
));
// Delete saved activity
lines.add(SizedBox.square(
dimension: MediaQuery.of(context).size.width / 5,
child: ActivityButtonDeleteSaved(
onPressed: () {
config.deleteCurrentActivity(context);
},
),
));
} else {
// Start new activity
lines.add(
AspectRatio(
aspectRatio: 3,
child: ActivityButtonStartNew(
onPressed: () {
config.startNewActivity(context);
},
),
),
);
}
lines.add(SizedBox(height: separatorHeight));
// Activity settings (bottom)
for (ApplicationSettingsParameter parameter in config.activitySettings) {
if (!parameter.displayedOnTop) {
lines.add(Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: buildParametersLine(
parameter: parameter,
isEnabled: !canBeResumed,
),
));
lines.add(SizedBox(height: separatorHeight));
}
}
return Column(
children: lines,
);
}
List<Widget> buildParametersLine({
required ApplicationSettingsParameter parameter,
required bool isEnabled,
}) {
final List<ApplicationSettingsParameterItemValue> items = parameter.values;
final List<Widget> parameterButtons = [];
if (items.length <= 1) {
return [];
}
for (ApplicationSettingsParameterItemValue item in items) {
final Widget parameterButton = BlocBuilder<ActivitySettingsCubit, ActivitySettingsState>(
builder: (BuildContext context, ActivitySettingsState activitySettingsState) {
final ActivitySettingsCubit activitySettingsCubit =
BlocProvider.of<ActivitySettingsCubit>(context);
final double displayWidth = MediaQuery.of(context).size.width;
final double itemWidth = displayWidth / items.length - 4;
return SizedBox.square(
dimension: itemWidth,
child: parameter.buildParameterItem(
context: context,
parameter: parameter,
itemValue: item,
size: itemWidth,
onPressed: isEnabled
? () {
activitySettingsCubit.set(parameter.code, item.value);
}
: null,
),
);
},
);
parameterButtons.add(parameterButton);
}
return parameterButtons;
}
}
import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
part 'settings_activity_state.dart';
class ActivitySettingsCubit extends HydratedCubit<ActivitySettingsState> {
final ApplicationConfigDefinition appConfig;
ActivitySettingsCubit({
required this.appConfig,
}) : super(
ActivitySettingsState(
settings: ActivitySettings.createDefault(
appConfig: appConfig,
),
),
);
void setValues({
Map<String, String>? values,
}) {
emit(
ActivitySettingsState(
settings: ActivitySettings(
appConfig: appConfig,
values: values ?? state.settings.values,
),
),
);
}
String get(String code) {
return state.settings.get(code);
}
void set(String code, String value) {
Map<String, String> values = state.settings.values;
values[code] = value;
setValues(
values: values,
);
}
@override
ActivitySettingsState? fromJson(Map<String, dynamic> json) {
Map<String, String> values = {};
json.forEach((key, value) {
values[key] = value as String;
});
return ActivitySettingsState(
settings: ActivitySettings(
appConfig: appConfig,
values: values,
),
);
}
@override
Map<String, dynamic>? toJson(ActivitySettingsState state) {
return state.settings.values;
}
}
part of 'settings_activity_cubit.dart';
@immutable
class ActivitySettingsState extends Equatable {
const ActivitySettingsState({
required this.settings,
});
final ActivitySettings settings;
@override
List<dynamic> get props => <dynamic>[
settings,
];
}
...@@ -3,7 +3,7 @@ description: "Flutter custom toolbox for org.benoitharrault.* projects." ...@@ -3,7 +3,7 @@ description: "Flutter custom toolbox for org.benoitharrault.* projects."
publish_to: "none" publish_to: "none"
version: 0.4.0 version: 0.5.0
homepage: https://git.harrault.fr/android/flutter-toolbox homepage: https://git.harrault.fr/android/flutter-toolbox
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment