Skip to content

Commit

Permalink
Move some common widgets and utilities to devtools_app_shared (#7979)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenzieschmoll authored Jun 25, 2024
1 parent 0771921 commit 8396449
Show file tree
Hide file tree
Showing 21 changed files with 713 additions and 671 deletions.
1 change: 0 additions & 1 deletion packages/devtools_app/lib/src/framework/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import 'package:shared_preferences/shared_preferences.dart';

import '../shared/analytics/analytics.dart' as ga;
import '../shared/analytics/constants.dart' as gac;
import '../shared/common_widgets.dart';
import '../shared/config_specific/import_export/import_export.dart';
import '../shared/connection_info.dart';
import '../shared/globals.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:devtools_app_shared/ui.dart';
import 'package:devtools_app_shared/utils.dart';
import 'package:flutter/material.dart';

import '../../../shared/common_widgets.dart';
import '../../../shared/primitives/utils.dart';
import '../../../shared/ui/utils.dart';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:devtools_app_shared/ui.dart';
import 'package:flutter/material.dart';

import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/common_widgets.dart';
import '../controller/chart_pane_controller.dart';
import '../data/primitives.dart';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'package:flutter/material.dart';

import '../../../../../shared/analytics/analytics.dart' as ga;
import '../../../../../shared/analytics/constants.dart' as gac;
import '../../../../../shared/common_widgets.dart';
import '../../../../../shared/globals.dart';
import '../../../../../shared/memory/classes.dart';
import '../../../../../shared/primitives/utils.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'dart:developer';
import 'package:devtools_app_shared/ui.dart';
import 'package:flutter/material.dart';

import '../../../../shared/common_widgets.dart';
import '../../../../shared/globals.dart';
import '../../../../shared/ui/filter.dart';
import '../../cpu_profile_model.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../../../shared/analytics/constants.dart' as gac;
import '../../../shared/common_widgets.dart';
import '../../../shared/ui/drop_down_button.dart';
import '../../debugger/program_explorer.dart';
import '../../debugger/program_explorer_model.dart';
Expand Down
228 changes: 0 additions & 228 deletions packages/devtools_app/lib/src/shared/common_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import 'package:flutter/services.dart';
import 'package:vm_service/vm_service.dart';

import '../screens/debugger/debugger_controller.dart';
import '../screens/inspector/layout_explorer/ui/theme.dart';
import 'analytics/analytics.dart' as ga;
import 'analytics/constants.dart' as gac;
import 'config_specific/copy_to_clipboard/copy_to_clipboard.dart';
Expand Down Expand Up @@ -726,233 +725,6 @@ class InformationButton extends StatelessWidget {
}
}

class RoundedCornerOptions {
const RoundedCornerOptions({
this.showTopLeft = true,
this.showTopRight = true,
this.showBottomLeft = true,
this.showBottomRight = true,
});

/// Static constant instance with all borders hidden
static const empty = RoundedCornerOptions(
showTopLeft: false,
showTopRight: false,
showBottomLeft: false,
showBottomRight: false,
);

final bool showTopLeft;
final bool showTopRight;
final bool showBottomLeft;
final bool showBottomRight;
}

class RoundedDropDownButton<T> extends StatelessWidget {
const RoundedDropDownButton({
super.key,
this.value,
this.onChanged,
this.isDense = false,
this.isExpanded = false,
this.style,
this.selectedItemBuilder,
this.items,
this.roundedCornerOptions,
});

final T? value;

final ValueChanged<T?>? onChanged;

final bool isDense;

final bool isExpanded;

final TextStyle? style;

final DropdownButtonBuilder? selectedItemBuilder;

final List<DropdownMenuItem<T>>? items;

final RoundedCornerOptions? roundedCornerOptions;

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final bgColor = theme.colorScheme.backgroundColorSelected;

Radius selectRadius(bool show) {
return show ? defaultRadius : Radius.zero;
}

final style = this.style ?? theme.regularTextStyle;
final showTopLeft = roundedCornerOptions?.showTopLeft ?? true;
final showTopRight = roundedCornerOptions?.showTopRight ?? true;
final showBottomLeft = roundedCornerOptions?.showBottomLeft ?? true;
final showBottomRight = roundedCornerOptions?.showBottomRight ?? true;

final button = Center(
child: SizedBox(
height: defaultButtonHeight - 2.0, // subtract 2.0 for width of border
child: DropdownButtonHideUnderline(
child: DropdownButton<T>(
padding: const EdgeInsets.only(
left: defaultSpacing,
right: borderPadding,
),
value: value,
onChanged: onChanged,
isDense: isDense,
isExpanded: isExpanded,
borderRadius: BorderRadius.only(
topLeft: selectRadius(showTopLeft),
topRight: selectRadius(showTopRight),
bottomLeft: selectRadius(showBottomLeft),
bottomRight: selectRadius(showBottomRight),
),
style: style,
selectedItemBuilder: selectedItemBuilder,
items: items,
focusColor: bgColor,
),
),
),
);

if (roundedCornerOptions == RoundedCornerOptions.empty) return button;

return RoundedOutlinedBorder(
showTopLeft: showTopLeft,
showTopRight: showTopRight,
showBottomLeft: showBottomLeft,
showBottomRight: showBottomRight,
child: button,
);
}
}

class DevToolsClearableTextField extends StatelessWidget {
DevToolsClearableTextField({
super.key,
required this.labelText,
TextEditingController? controller,
this.hintText,
this.prefixIcon,
this.additionalSuffixActions = const <Widget>[],
this.onChanged,
this.onSubmitted,
this.autofocus = false,
this.enabled,
this.roundedBorder = false,
}) : controller = controller ?? TextEditingController();

final TextEditingController controller;
final String? hintText;
final Widget? prefixIcon;
final List<Widget> additionalSuffixActions;
final String labelText;
final void Function(String)? onChanged;
final void Function(String)? onSubmitted;
final bool autofocus;
final bool? enabled;
final bool roundedBorder;

static const _contentVerticalPadding = 6.0;

/// This is the default border radius used by the [OutlineInputBorder]
/// constructor.
static const _defaultInputBorderRadius =
BorderRadius.all(Radius.circular(4.0));

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return SizedBox(
height: defaultTextFieldHeight,
child: TextField(
autofocus: autofocus,
controller: controller,
enabled: enabled,
onChanged: onChanged,
onSubmitted: onSubmitted,
style: theme.regularTextStyle,
decoration: InputDecoration(
isDense: true,
contentPadding: const EdgeInsets.only(
top: _contentVerticalPadding,
bottom: _contentVerticalPadding,
left: denseSpacing,
right: densePadding,
),
constraints: BoxConstraints(
minHeight: defaultTextFieldHeight,
maxHeight: defaultTextFieldHeight,
),
border: OutlineInputBorder(
borderRadius: roundedBorder
? const BorderRadius.all(defaultRadius)
: _defaultInputBorderRadius,
),
labelText: labelText,
labelStyle: theme.subtleTextStyle,
hintText: hintText,
hintStyle: theme.subtleTextStyle,
prefixIcon: prefixIcon,
suffix: SizedBox(
height: inputDecorationElementHeight,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
clearInputButton(
() {
controller.clear();
onChanged?.call('');
},
),
...additionalSuffixActions,
],
),
),
),
),
);
}
}

Widget clearInputButton(VoidCallback onPressed) {
return inputDecorationSuffixButton(
icon: Icons.clear,
onPressed: onPressed,
tooltip: 'Clear',
);
}

Widget closeSearchDropdownButton(VoidCallback? onPressed) {
return inputDecorationSuffixButton(icon: Icons.close, onPressed: onPressed);
}

Widget inputDecorationSuffixButton({
required IconData icon,
required VoidCallback? onPressed,
String? tooltip,
}) {
return maybeWrapWithTooltip(
tooltip: tooltip,
child: SizedBox(
height: inputDecorationElementHeight,
width: inputDecorationElementHeight + denseSpacing,
child: IconButton(
padding: EdgeInsets.zero,
onPressed: onPressed,
iconSize: defaultIconSize,
splashRadius: defaultIconSize,
icon: Icon(icon),
),
),
);
}

class OutlinedRowGroup extends StatelessWidget {
const OutlinedRowGroup({super.key, required this.children, this.borderColor});

Expand Down
3 changes: 2 additions & 1 deletion packages/devtools_app/lib/src/shared/file_import.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ class _FileImportContainerState extends State<FileImportContainer> {
textAlign: TextAlign.left,
),
),
if (importedFile != null) clearInputButton(_clearFile),
if (importedFile != null)
InputDecorationSuffixButton.clear(onPressed: _clearFile),
],
);
}
Expand Down
26 changes: 0 additions & 26 deletions packages/devtools_app/lib/src/shared/primitives/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -950,32 +950,6 @@ extension StringExtension on String {
);
}

/// Whether [query] is a case insensitive "fuzzy match" for this String.
///
/// For example, the query "hwf" would be a fuzzy match for the String
/// "hello_world_file".
bool caseInsensitiveFuzzyMatch(String query) {
query = query.toLowerCase();
final lowercase = toLowerCase();
final it = query.characters.iterator;
var strIndex = 0;
while (it.moveNext()) {
final char = it.current;
var foundChar = false;
for (int i = strIndex; i < lowercase.length; i++) {
if (lowercase[i] == char) {
strIndex = i + 1;
foundChar = true;
break;
}
}
if (!foundChar) {
return false;
}
}
return true;
}

/// Whether [other] is a case insensitive match for this String.
///
/// If [pattern] is a [RegExp], this method will return true if and only if
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'package:devtools_app_shared/ui.dart';
import 'package:flutter/material.dart';

import '../analytics/analytics.dart' as ga;
import '../common_widgets.dart';

/// A [DropDownButton] implementation that reports selection changes to our
/// analytics.
Expand Down
9 changes: 5 additions & 4 deletions packages/devtools_app/lib/src/shared/ui/search.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ class _SearchFieldSuffix extends StatelessWidget {
assert(supportsNavigation || onClose != null);
return supportsNavigation
? SearchNavigationControls(controller, onClose: onClose)
: closeSearchDropdownButton(onClose);
: InputDecorationSuffixButton.close(onPressed: onClose);
}
}

Expand Down Expand Up @@ -1403,15 +1403,16 @@ class SearchNavigationControls extends StatelessWidget {
child: PaddedDivider.vertical(),
),
),
inputDecorationSuffixButton(
InputDecorationSuffixButton(
icon: Icons.keyboard_arrow_up,
onPressed: numMatches > 1 ? controller.previousMatch : null,
),
inputDecorationSuffixButton(
InputDecorationSuffixButton(
icon: Icons.keyboard_arrow_down,
onPressed: numMatches > 1 ? controller.nextMatch : null,
),
if (onClose != null) closeSearchDropdownButton(onClose),
if (onClose != null)
InputDecorationSuffixButton.close(onPressed: onClose),
],
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:devtools_app/devtools_app.dart';
import 'package:devtools_app/src/screens/memory/framework/memory_tabs.dart';
import 'package:devtools_app/src/screens/memory/panes/tracing/tracing_pane_controller.dart';
import 'package:devtools_app/src/screens/memory/panes/tracing/tracing_tree.dart';
import 'package:devtools_app_shared/ui.dart';
import 'package:devtools_app_shared/utils.dart';
import 'package:devtools_test/devtools_test.dart';
import 'package:devtools_test/helpers.dart';
Expand Down
Loading

0 comments on commit 8396449

Please sign in to comment.