Skip to content

Commit

Permalink
[Property Editor] Densify Property Editor inputs (#8803)
Browse files Browse the repository at this point in the history
  • Loading branch information
elliette authored Jan 23, 2025
1 parent 6086fe8 commit fde8f8b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class _DropdownInput<T> extends StatelessWidget with _PropertyInputMixin<T> {
final theme = Theme.of(context);
return DropdownButtonFormField(
value: property.valueDisplay,
decoration: decoration(property, theme: theme),
decoration: decoration(property, theme: theme, padding: denseSpacing),
isExpanded: true,
items:
property.propertyOptions.map((option) {
Expand Down Expand Up @@ -133,6 +133,8 @@ class _TextInput<T> extends StatefulWidget with _PropertyInputMixin<T> {
class _TextInputState extends State<_TextInput> {
String currentValue = '';

double paddingDiffComparedToDropdown = 1.0;

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
Expand All @@ -142,7 +144,14 @@ class _TextInputState extends State<_TextInput> {
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: widget.property.inputValidator,
inputFormatters: [FilteringTextInputFormatter.singleLineFormatter],
decoration: widget.decoration(widget.property, theme: theme),
decoration: widget.decoration(
widget.property,
theme: theme,
// Note: The text input has an extra pixel compared to the dropdown
// input. Therefore, to have their sizes match, subtract a half pixel
// from the padding.
padding: defaultSpacing - (paddingDiffComparedToDropdown / 2),
),
style: theme.fixedFontStyle,
onChanged: (newValue) {
setState(() {
Expand Down Expand Up @@ -179,15 +188,17 @@ mixin _PropertyInputMixin<T> {
return;
}

final value = property.convertFromString(valueAsString) as T?;
final value = property.convertFromInputString(valueAsString) as T?;
await controller.editArgument(name: argName, value: value);
}

InputDecoration decoration(
EditableProperty property, {
required ThemeData theme,
required double padding,
}) {
return InputDecoration(
contentPadding: EdgeInsets.all(padding),
helperText: property.isRequired ? '*required' : '',
errorText: property.errorText,
isDense: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class EditableString extends EditableProperty {
EditableString(super.argument);

@override
String? convertFromString(String? valueAsString) => valueAsString;
String? convertFromInputString(String? valueAsString) => valueAsString;

@override
String get dartType => 'String';
Expand All @@ -26,7 +26,7 @@ class EditableBool extends EditableProperty with FiniteValuesProperty {
EditableBool(super.argument);

@override
Object? convertFromString(String? valueAsString) =>
Object? convertFromInputString(String? valueAsString) =>
valueAsString == 'true' || valueAsString == 'false'
? valueAsString == 'true'
: valueAsString; // The boolean value might be an expression.
Expand All @@ -41,30 +41,49 @@ class EditableDouble extends EditableProperty with NumericProperty {
EditableDouble(super.argument);

@override
double? convertFromString(String? valueAsString) =>
double? convertFromInputString(String? valueAsString) =>
toNumber(valueAsString) as double?;
}

class EditableInt extends EditableProperty with NumericProperty {
EditableInt(super.argument);

@override
int? convertFromString(String? valueAsString) =>
int? convertFromInputString(String? valueAsString) =>
toNumber(valueAsString) as int?;
}

class EditableEnum extends EditableProperty with FiniteValuesProperty {
EditableEnum(super.argument);

@override
String? convertFromString(String? valueAsString) => valueAsString;
String? convertFromInputString(String? valueAsString) =>
valueAsString == null ? null : _enumLonghand(valueAsString);

@override
String get dartType => options?.first.split('.').first ?? type;

@override
String get valueDisplay => _enumShorthand(displayValue ?? value.toString());

@override
Set<String> get propertyOptions {
return {...(options ?? []), valueDisplay, if (isNullable) 'null'};
final shorthandOptions = (options ?? <String>[]).map(_enumShorthand);
return {...shorthandOptions, valueDisplay, if (isNullable) 'null'};
}

String _enumShorthand(String fullEnumValue) {
if (fullEnumValue.startsWith(dartType)) {
return fullEnumValue.split(dartType).last;
}
return fullEnumValue;
}

String _enumLonghand(String enumShorthandValue) {
if (enumShorthandValue.startsWith('.')) {
return '$dartType$enumShorthandValue';
}
return enumShorthandValue;
}
}

Expand Down Expand Up @@ -101,7 +120,7 @@ class EditableProperty extends EditableArgument {
}

@mustBeOverridden
Object? convertFromString(String? _) {
Object? convertFromInputString(String? _) {
throw UnimplementedError();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class _PropertiesList extends StatelessWidget {

final PropertyEditorController controller;

static const itemPadding = densePadding;
static const itemPadding = borderPadding;

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -118,36 +118,46 @@ class _PropertyLabels extends StatelessWidget {

final EditableProperty property;

static const _widthForFullLabels = 60;

@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final isSet = property.hasArgument;
final isDefault = property.isDefault;

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isSet)
Padding(
padding: const EdgeInsets.all(_PropertiesList.itemPadding),
child: RoundedLabel(
labelText: 'set',
backgroundColor: colorScheme.primary,
textColor: colorScheme.onPrimary,
tooltipText: 'Property argument is set.',
),
),
if (isDefault)
const Padding(
padding: EdgeInsets.all(_PropertiesList.itemPadding),
child: RoundedLabel(
labelText: 'default',
tooltipText: 'Property argument matches the default value.',
),
),
],
return LayoutBuilder(
builder: (context, constraints) {
final width = constraints.maxWidth;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isSet)
Padding(
padding: const EdgeInsets.all(_PropertiesList.itemPadding),
child: RoundedLabel(
labelText: _maybeTruncateLabel('set', width: width),
backgroundColor: colorScheme.primary,
textColor: colorScheme.onPrimary,
tooltipText: 'Property argument is set.',
),
),
if (isDefault)
Padding(
padding: const EdgeInsets.all(_PropertiesList.itemPadding),
child: RoundedLabel(
labelText: _maybeTruncateLabel('default', width: width),
tooltipText: 'Property argument matches the default value.',
),
),
],
);
},
);
}

String _maybeTruncateLabel(String labelText, {required double width}) =>
width >= _widthForFullLabels ? labelText : labelText[0].toUpperCase();
}

class _PropertyInput extends StatelessWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,17 +224,17 @@ void main() {
await _verifyDropdownMenuItems(
alignInput,
menuOptions: [
'Alignment.bottomCenter',
'Alignment.bottomLeft',
'Alignment.bottomRight',
'Alignment.center',
'Alignment.centerLeft',
'Alignment.centerRight',
'Alignment.topCenter',
'Alignment.topLeft',
'Alignment.topRight',
'.bottomCenter',
'.bottomLeft',
'.bottomRight',
'.center',
'.centerLeft',
'.centerRight',
'.topCenter',
'.topLeft',
'.topRight',
],
selectedOption: 'Alignment.center',
selectedOption: '.center',
tester: tester,
);
});
Expand Down Expand Up @@ -368,8 +368,8 @@ void main() {
final alignInput = _findDropdownButtonFormField('align');
await _selectDropdownMenuItem(
alignInput,
optionToSelect: 'Alignment.topLeft',
currentlySelected: 'Alignment.center',
optionToSelect: '.topLeft',
currentlySelected: '.center',
tester: tester,
);

Expand All @@ -390,7 +390,7 @@ void main() {
await _selectDropdownMenuItem(
alignInput,
optionToSelect: 'null',
currentlySelected: 'Alignment.center',
currentlySelected: '.center',
tester: tester,
);

Expand Down

0 comments on commit fde8f8b

Please sign in to comment.