Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add argument type #9

Merged
merged 15 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:example/stage_data/my_list_tile_widget_stage.dart';
import 'package:example/stage_data/my_other_widget_stage.dart';
import 'package:example/stage_data/my_widget_stage.dart';
import 'package:flutter/material.dart';
Expand All @@ -20,6 +21,7 @@ class _MyAppState extends State<MyApp> {
final widgetsOnStage = [
MyWidgetStageData(),
MyOtherWidgetStageData(),
MyListTileWidgetStage(),
];

@override
Expand Down
126 changes: 126 additions & 0 deletions example/lib/stage_data/my_list_tile_widget_stage.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:widget_stage/widget_stage.dart';

class MyListTileWidgetStage extends WidgetStageData {
MyListTileWidgetStage()
: _tileCount = IntFieldConfigurator(
value: 1,
name: 'tileCount',
type: FieldConfiguratorType.stage,
),
_listPadding = PaddingFieldConfigurator(
value: EdgeInsets.zero,
name: 'listPadding',
type: FieldConfiguratorType.stage,
),
_title = StringFieldConfigurator(value: 'My List Tile', name: 'title'),
_stageColor = ColorFieldConfigurator(
value: Colors.transparent,
name: 'stageColor',
type: FieldConfiguratorType.stage,
),
_circleColor = ColorFieldConfigurator(value: Colors.purple, name: 'circleColor'),
_tileColor = ColorFieldConfiguratorNullable(value: Colors.cyan, name: 'tileColor'),
_textColor = ColorFieldConfiguratorNullable(value: Colors.white, name: 'textColor'),
_borderRadius = DoubleFieldConfiguratorNullable(value: 10, name: 'borderRadius'),
_tileGap = DoubleFieldConfigurator(
value: 0,
name: 'tileSpace',
type: FieldConfiguratorType.stage,
);

@override
List<FieldConfigurator> get fieldConfigurators {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of marking every FieldConfigurator i would prefer to have two lists here instead. Like widgetFieldConfigurators and stageFieldConfiguators.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done b684705

return [
_tileCount,
_listPadding,
_title,
_tileGap,
_stageColor,
_circleColor,
_tileColor,
_borderRadius,
_textColor,
];
}

@override
String get name => 'MyListTileWidget';

final IntFieldConfigurator _tileCount;
final DoubleFieldConfigurator _tileGap;
final DoubleFieldConfiguratorNullable _borderRadius;
final PaddingFieldConfigurator _listPadding;
final StringFieldConfigurator _title;
final ColorFieldConfigurator _stageColor;
final ColorFieldConfigurator _circleColor;
final ColorFieldConfiguratorNullable _textColor;
final ColorFieldConfiguratorNullable _tileColor;

@override
Widget widgetBuilder(BuildContext context) {
return ColoredBox(
color: _stageColor.value,
child: ListView.builder(
padding: _listPadding.value,
itemCount: _tileCount.value,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.only(bottom: _tileGap.value),
child: _MyTitleTileWidget(
danielmolnar marked this conversation as resolved.
Show resolved Hide resolved
title: _title.value,
index: index,
circleColor: _circleColor.value,
tileColor: _tileColor.value,
borderRadius: _borderRadius.value,
textColor: _textColor.value,
),
);
},
),
);
}
}

class _MyTitleTileWidget extends StatelessWidget {
const _MyTitleTileWidget({
required this.index,
required this.title,
required this.circleColor,
this.tileColor,
this.borderRadius,
this.textColor,
});

final String title;
final Color circleColor;
final Color? tileColor;
final int index;
final double? borderRadius;
final Color? textColor;

@override
Widget build(BuildContext context) {
return Material(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius ?? 0),
color: tileColor,
),
child: ListTile(
title: Text(title),
leading: CircleAvatar(
radius: 15,
backgroundColor: circleColor,
child: Text(
'${index + 1}',
style: TextStyle(
color: textColor,
),
),
),
),
),
);
}
}
1 change: 1 addition & 0 deletions lib/src/field_configurators/bool_field_configurator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class BoolFieldConfigurator extends FieldConfigurator<bool> {
BoolFieldConfigurator({
required super.value,
required super.name,
super.type,
});

@override
Expand Down
1 change: 1 addition & 0 deletions lib/src/field_configurators/color_field_configurator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class ColorFieldConfigurator extends FieldConfigurator<Color> {
ColorFieldConfigurator({
required super.value,
required super.name,
super.type,
});

@override
Expand Down
1 change: 1 addition & 0 deletions lib/src/field_configurators/double_field_configurator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class DoubleFieldConfigurator extends FieldConfigurator<double> {
DoubleFieldConfigurator({
required super.value,
required super.name,
super.type,
});

@override
Expand Down
1 change: 1 addition & 0 deletions lib/src/field_configurators/enum_field_configurator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class EnumFieldConfigurator<T extends Enum> extends FieldConfigurator<T> {
required super.value,
required super.name,
required this.enumValues,
super.type,
});

final List<T> enumValues;
Expand Down
1 change: 1 addition & 0 deletions lib/src/field_configurators/int_field_configurator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class IntFieldConfigurator extends FieldConfigurator<int> {
IntFieldConfigurator({
required super.value,
required super.name,
super.type,
});

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class PaddingFieldConfigurator extends FieldConfigurator<EdgeInsets> {
PaddingFieldConfigurator({
required super.value,
required super.name,
super.type,
});

@override
Expand Down
1 change: 1 addition & 0 deletions lib/src/field_configurators/string_field_configurator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class StringFieldConfigurator extends FieldConfigurator<String> {
StringFieldConfigurator({
required super.value,
required super.name,
super.type,
});

@override
Expand Down
111 changes: 103 additions & 8 deletions lib/src/widget_stage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,49 @@ class _WidgetStageState extends State<WidgetStage> {

@override
Widget build(BuildContext context) {
final List<Widget> stageConfiguratorWidgets = () {
final stageConfigurators = (_stageController.selectedWidget?.fieldConfigurators ?? []).stageConfigurators;
if (stageConfigurators.isEmpty) return <Widget>[];
return stageConfigurators.map((configurator) {
if (configurator == stageConfigurators.first) {
return _LeadingFieldConfigurationWidget(
configurator: configurator,
title: 'Stage Arguments',
);
}
return Padding(
padding: configurator == stageConfigurators.last ? const EdgeInsets.only(bottom: 12.0) : EdgeInsets.zero,
child: FieldConfiguratorWidget(
fieldConfigurator: configurator,
child: configurator.build(context),
),
);
}).toList();
}();

final List<Widget> widgetConfiguratorWidgets = () {
final widgetConfigurators = (_stageController.selectedWidget?.fieldConfigurators ?? []).widgetConfigurators;
if (widgetConfigurators.isEmpty) return <Widget>[];
return widgetConfigurators.map((configurator) {
if (configurator == widgetConfigurators.first) {
return _LeadingFieldConfigurationWidget(
configurator: configurator,
title: 'Widget Arguments',
);
}
return FieldConfiguratorWidget(
fieldConfigurator: configurator,
child: configurator.build(context),
);
}).toList();
}();

return Scaffold(
body: Column(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Stage(
Expand All @@ -48,13 +86,10 @@ class _WidgetStageState extends State<WidgetStage> {
SizedBox(
width: 400,
child: ConfigurationBar(
fields: _stageController.selectedWidget?.fieldConfigurators.map((configurator) {
return FieldConfiguratorWidget(
fieldConfigurator: configurator,
child: configurator.build(context),
);
}).toList() ??
[],
fields: [
...stageConfiguratorWidgets,
...widgetConfiguratorWidgets,
],
),
),
],
Expand All @@ -66,6 +101,46 @@ class _WidgetStageState extends State<WidgetStage> {
}
}

class _LeadingFieldConfigurationWidget extends StatelessWidget {
const _LeadingFieldConfigurationWidget({
required this.title,
required this.configurator,
});

final FieldConfigurator configurator;
final String title;

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(bottom: 4.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey.shade400),
),
),
width: double.infinity,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The infinite width can be removed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that would result in a line that is as wide as the title instead of being as wide as the configuration bar.

child: Text(
textAlign: TextAlign.center,
title,
style: TextStyle(
color: Colors.grey.shade400,
),
),
),
const SizedBox(height: 24.0),
FieldConfiguratorWidget(
fieldConfigurator: configurator,
child: configurator.build(context),
),
],
);
}
}

/// The actual stage to display the widget.
class Stage extends StatelessWidget {
const Stage({
Expand Down Expand Up @@ -124,12 +199,15 @@ abstract class FieldConfigurator<T> extends ChangeNotifier {
FieldConfigurator({
required this.value,
required this.name,
});
FieldConfiguratorType? type,
}) : type = type ?? FieldConfiguratorType.widget;

T value;

String name;

final FieldConfiguratorType type;

bool get isNullable => null is T;

void updateValue(T value) {
Expand All @@ -156,3 +234,20 @@ class StageController extends ChangeNotifier {
notifyListeners();
}
}

/// Allows for separation of the configurators in the [ConfigurationBar] depending on whether they affect the
/// widget on the stage or the stage itself (e.g. amount of the same widget to display in a list).
enum FieldConfiguratorType {
widget,
stage,
}

extension FieldConfiguratorListExtensions on List<FieldConfigurator> {
List<FieldConfigurator> get stageConfigurators => where((configurator) {
return configurator.type == FieldConfiguratorType.stage;
}).toList();

List<FieldConfigurator> get widgetConfigurators => where((configurator) {
return configurator.type == FieldConfiguratorType.widget;
}).toList();
}