Skip to content

Commit

Permalink
Refactor areaPaneHeader into a widget (#2924)
Browse files Browse the repository at this point in the history
  • Loading branch information
rrousselGit authored Apr 21, 2021
1 parent 12ad534 commit c6c42fe
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 93 deletions.
10 changes: 4 additions & 6 deletions packages/devtools_app/lib/src/app_size/app_size_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,8 @@ class _AnalysisViewState extends State<AnalysisView> with AutoDisposeMixin {
return OutlineDecoration(
child: Column(
children: [
areaPaneHeader(
context,
title: _generateSingleFileHeaderText(),
AreaPaneHeader(
title: Text(_generateSingleFileHeaderText()),
needsTopBorder: false,
),
Expanded(
Expand Down Expand Up @@ -443,9 +442,8 @@ class _DiffViewState extends State<DiffView> with AutoDisposeMixin {
return OutlineDecoration(
child: Column(
children: [
areaPaneHeader(
context,
title: _generateDualFileHeaderText(),
AreaPaneHeader(
title: Text(_generateDualFileHeaderText()),
needsTopBorder: false,
),
Expanded(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ class _CallGraphWithDominatorsState extends State<CallGraphWithDominators> {
Widget build(BuildContext context) {
return Column(
children: [
areaPaneHeader(
context,
title: showCallGraph ? 'Call Graph' : 'Dominator Tree',
AreaPaneHeader(
title: Text(showCallGraph ? 'Call Graph' : 'Dominator Tree'),
needsTopBorder: false,
needsBottomBorder: false,
needsLeftBorder: true,
Expand Down
97 changes: 57 additions & 40 deletions packages/devtools_app/lib/src/common_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -650,49 +650,66 @@ class ToolbarAction extends StatelessWidget {
/// on the right-hand side.
///
/// This is typically used as a title for a logical area of the screen.
// TODO(devoncarew): Refactor this into an 'AreaPaneHeader' widget.
// TODO(peterdjlee): Consider passing in a list of widgets for content instead of String title.
SizedBox areaPaneHeader(
BuildContext context, {
@required String title,
bool needsTopBorder = true,
bool needsBottomBorder = true,
bool needsLeftBorder = false,
List<Widget> actions = const [],
double rightPadding = densePadding,
bool tall = false,
}) {
final theme = Theme.of(context);
return SizedBox(
height:
tall ? areaPaneHeaderHeight + 2 * densePadding : areaPaneHeaderHeight,
child: Container(
decoration: BoxDecoration(
border: Border(
top: needsTopBorder ? defaultBorderSide(theme) : BorderSide.none,
bottom:
needsBottomBorder ? defaultBorderSide(theme) : BorderSide.none,
left: needsLeftBorder ? defaultBorderSide(theme) : BorderSide.none,
class AreaPaneHeader extends StatelessWidget implements PreferredSizeWidget {
const AreaPaneHeader({
Key key,
@required this.title,
this.needsTopBorder = true,
this.needsBottomBorder = true,
this.needsLeftBorder = false,
this.actions = const [],
this.rightPadding = densePadding,
this.tall = false,
}) : super(key: key);

final Widget title;
final bool needsTopBorder;
final bool needsBottomBorder;
final bool needsLeftBorder;
final List<Widget> actions;
final double rightPadding;
final bool tall;

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return SizedBox.fromSize(
size: preferredSize,
child: Container(
decoration: BoxDecoration(
border: Border(
top: needsTopBorder ? defaultBorderSide(theme) : BorderSide.none,
bottom:
needsBottomBorder ? defaultBorderSide(theme) : BorderSide.none,
left: needsLeftBorder ? defaultBorderSide(theme) : BorderSide.none,
),
color: titleSolidBackgroundColor(theme),
),
color: titleSolidBackgroundColor(theme),
),
padding: EdgeInsets.only(left: defaultSpacing, right: rightPadding),
alignment: Alignment.centerLeft,
child: Row(
children: [
Expanded(
child: Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: theme.textTheme.subtitle2,
padding: EdgeInsets.only(left: defaultSpacing, right: rightPadding),
alignment: Alignment.centerLeft,
child: Row(
children: [
Expanded(
child: DefaultTextStyle(
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: theme.textTheme.subtitle2,
child: title,
),
),
),
...actions,
],
...actions,
],
),
),
),
);
);
}

@override
Size get preferredSize {
return Size.fromHeight(
tall ? areaPaneHeaderHeight + 2 * densePadding : areaPaneHeaderHeight,
);
}
}

BorderSide defaultBorderSide(ThemeData theme) {
Expand Down
5 changes: 2 additions & 3 deletions packages/devtools_app/lib/src/debugger/console.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ class _DebuggerConsoleState extends State<DebuggerConsole> {
children: [
Expanded(
child: Console(
title: areaPaneHeader(
context,
title: 'Console',
title: AreaPaneHeader(
title: const Text('Console'),
needsTopBorder: false,
actions: [
CopyToClipboardControl(
Expand Down
14 changes: 6 additions & 8 deletions packages/devtools_app/lib/src/debugger/debugger_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -213,16 +213,14 @@ class DebuggerScreenBodyState extends State<DebuggerScreenBody>
totalHeight: constraints.maxHeight,
initialFractions: const [0.40, 0.40, 0.20],
minSizes: const [0.0, 0.0, 0.0],
headers: <SizedBox>[
areaPaneHeader(
context,
title: callStackTitle,
headers: <PreferredSizeWidget>[
const AreaPaneHeader(
title: Text(callStackTitle),
needsTopBorder: false,
),
areaPaneHeader(context, title: variablesTitle),
areaPaneHeader(
context,
title: breakpointsTitle,
const AreaPaneHeader(title: Text(variablesTitle)),
AreaPaneHeader(
title: const Text(breakpointsTitle),
actions: [
_breakpointsRightChild(),
],
Expand Down
5 changes: 2 additions & 3 deletions packages/devtools_app/lib/src/debugger/scripts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,8 @@ class ScriptPickerState extends State<ScriptPicker> {
return OutlineDecoration(
child: Column(
children: [
areaPaneHeader(
context,
title: 'Libraries',
AreaPaneHeader(
title: const Text('Libraries'),
needsTopBorder: false,
actions: [
CountBadge(
Expand Down
22 changes: 13 additions & 9 deletions packages/devtools_app/lib/src/flex_split_column.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ class FlexSplitColumn extends StatelessWidget {
assert(children.length == initialFractions.length),
_children = buildChildrenWithFirstHeader(children, headers),
_initialFractions = modifyInitialFractionsToIncludeFirstHeader(
initialFractions, headers, totalHeight),
initialFractions,
headers,
totalHeight,
),
_minSizes = modifyMinSizesToIncludeFirstHeader(minSizes, headers),
super(key: key) {
if (minSizes != null) {
Expand All @@ -43,7 +46,7 @@ class FlexSplitColumn extends StatelessWidget {
/// creators of [FlexSplitColumn] can be unaware of the under-the-hood
/// calculations necessary to achieve the UI requirements specified by
/// [initialFractions] and [minSizes].
final List<SizedBox> headers;
final List<PreferredSizeWidget> headers;

/// The children that will be laid out below each corresponding header in
/// [headers].
Expand Down Expand Up @@ -71,7 +74,7 @@ class FlexSplitColumn extends StatelessWidget {
@visibleForTesting
static List<Widget> buildChildrenWithFirstHeader(
List<Widget> children,
List<SizedBox> headers,
List<PreferredSizeWidget> headers,
) {
return [
Column(
Expand All @@ -87,20 +90,21 @@ class FlexSplitColumn extends StatelessWidget {
@visibleForTesting
static List<double> modifyInitialFractionsToIncludeFirstHeader(
List<double> initialFractions,
List<SizedBox> headers,
List<PreferredSizeWidget> headers,
double totalHeight,
) {
var totalHeaderHeight = 0.0;
for (var header in headers) {
totalHeaderHeight += header.height;
totalHeaderHeight += header.preferredSize.height;
}
final intendedContentHeight = totalHeight - totalHeaderHeight;
final intendedChildHeights = List<double>.generate(initialFractions.length,
(i) => intendedContentHeight * initialFractions[i]);
final trueContentHeight = intendedContentHeight + headers[0].height;
final trueContentHeight =
intendedContentHeight + headers[0].preferredSize.height;
return List<double>.generate(initialFractions.length, (i) {
if (i == 0) {
return (intendedChildHeights[i] + headers[0].height) /
return (intendedChildHeights[i] + headers[0].preferredSize.height) /
trueContentHeight;
}
return intendedChildHeights[i] / trueContentHeight;
Expand All @@ -110,10 +114,10 @@ class FlexSplitColumn extends StatelessWidget {
@visibleForTesting
static List<double> modifyMinSizesToIncludeFirstHeader(
List<double> minSizes,
List<SizedBox> headers,
List<PreferredSizeWidget> headers,
) {
return [
minSizes[0] + headers[0].height,
minSizes[0] + headers[0].preferredSize.height,
...minSizes.sublist(1),
];
}
Expand Down
5 changes: 2 additions & 3 deletions packages/devtools_app/lib/src/logging/logging_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,8 @@ class _LogDetailsState extends State<LogDetails>

return OutlineDecoration(
child: ConsoleFrame(
title: areaPaneHeader(
context,
title: 'Details',
title: AreaPaneHeader(
title: const Text('Details'),
needsTopBorder: false,
actions: [
CopyToClipboardControl(
Expand Down
5 changes: 2 additions & 3 deletions packages/devtools_app/lib/src/performance/event_details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ class EventDetails extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
areaPaneHeader(
context,
AreaPaneHeader(
needsTopBorder: false,
title: _generateHeaderText(selectedEvent),
title: Text(_generateHeaderText(selectedEvent)),
),
Expanded(
child: selectedEvent != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ class _TimelineFlameChartContainerState
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
areaPaneHeader(
context,
title: 'Timeline Events',
AreaPaneHeader(
title: const Text('Timeline Events'),
tall: true,
needsTopBorder: false,
rightPadding: 0.0,
Expand Down
6 changes: 4 additions & 2 deletions packages/devtools_app/lib/src/split.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class Split extends StatefulWidget {
/// Splitter widgets to divide [children].
///
/// If this is null, a default splitter will be used to divide [children].
final List<SizedBox> splitters;
final List<PreferredSizeWidget> splitters;

/// The key passed to the divider between children[index] and
/// children[index + 1].
Expand Down Expand Up @@ -288,7 +288,9 @@ class _SplitState extends State<Split> {
} else {
var totalSize = 0.0;
for (var splitter in widget.splitters) {
totalSize += isHorizontal ? splitter.width : splitter.height;
totalSize += isHorizontal
? splitter.preferredSize.width
: splitter.preferredSize.height;
}
return totalSize;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ class VMInfoList extends StatelessWidget {
final theme = Theme.of(context);
return Column(
children: [
areaPaneHeader(
context,
title: title,
AreaPaneHeader(
title: Text(title),
needsTopBorder: false,
),
if (rowKeyValues != null)
Expand Down
20 changes: 16 additions & 4 deletions packages/devtools_app/test/flex_split_column_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,22 @@ void main() {
const children = [SizedBox(), SizedBox(), SizedBox(), SizedBox()];
const firstHeaderKey = Key('first header');
const headers = [
SizedBox(height: 50.0, key: firstHeaderKey),
SizedBox(height: 50.0),
SizedBox(height: 50.0),
SizedBox(height: 50.0),
PreferredSize(
preferredSize: Size.fromHeight(50),
child: SizedBox(height: 50.0, key: firstHeaderKey),
),
PreferredSize(
preferredSize: Size.fromHeight(50),
child: SizedBox(height: 50.0),
),
PreferredSize(
preferredSize: Size.fromHeight(50),
child: SizedBox(height: 50.0),
),
PreferredSize(
preferredSize: Size.fromHeight(50),
child: SizedBox(height: 50.0),
),
];
const initialFractions = [0.25, 0.25, 0.25, 0.25];
const minSizes = [10.0, 10.0, 10.0, 10.0];
Expand Down
12 changes: 9 additions & 3 deletions packages/devtools_app/test/split_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -780,15 +780,21 @@ const _k3 = Key('child 3');
const _w1 = Text('content1', key: _k1);
const _w2 = Text('content2', key: _k2);
const _w3 = Text('content3', key: _k3);
const _mediumSplitter = SizedBox(height: 20, width: 20);
const _largeSplitter = SizedBox(height: 40, width: 40);
const _mediumSplitter = PreferredSize(
preferredSize: Size(20, 20),
child: SizedBox(height: 20, width: 20),
);
const _largeSplitter = PreferredSize(
preferredSize: Size(40, 40),
child: SizedBox(height: 40, width: 40),
);

Split buildSplit(
Axis axis, {
@required List<double> initialFractions,
List<Widget> children,
List<double> minSizes,
List<SizedBox> splitters,
List<PreferredSizeWidget> splitters,
}) {
children ??= const [_w1, _w2];
return Split(
Expand Down

0 comments on commit c6c42fe

Please sign in to comment.