add a title to the logging console (#2066)
add a title to the logging console
diff --git a/packages/devtools_app/lib/src/common_widgets.dart b/packages/devtools_app/lib/src/common_widgets.dart
index 757d8ce..78cf724 100644
--- a/packages/devtools_app/lib/src/common_widgets.dart
+++ b/packages/devtools_app/lib/src/common_widgets.dart
@@ -22,6 +22,8 @@
const defaultDialogRadius = 20.0;
+const areaPaneHeaderHeight = 36.0;
+
List<Widget> headerInColumn(TextTheme textTheme, String title) {
return [
Text(title, style: textTheme.headline6),
@@ -418,6 +420,84 @@
}
}
+/// A wrapper around a FlatButton, an Icon, and an optional Tooltip; used for
+/// small toolbar actions.
+class ToolbarAction extends StatelessWidget {
+ const ToolbarAction({
+ @required this.icon,
+ @required this.onPressed,
+ this.tooltip,
+ Key key,
+ }) : super(key: key);
+
+ final IconData icon;
+ final String tooltip;
+ final VoidCallback onPressed;
+
+ @override
+ Widget build(BuildContext context) {
+ final button = FlatButton(
+ padding: EdgeInsets.zero,
+ materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
+ onPressed: onPressed,
+ child: Icon(icon, size: actionsIconSize),
+ );
+
+ return tooltip == null
+ ? button
+ : Tooltip(
+ message: tooltip,
+ waitDuration: tooltipWait,
+ child: button,
+ );
+ }
+}
+
+/// Create a bordered, fixed-height header area with a title and optional child
+/// 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.
+SizedBox areaPaneHeader(
+ BuildContext context, {
+ @required String title,
+ bool needsTopBorder = true,
+ List<Widget> actions = const [],
+ double rightPadding = densePadding,
+}) {
+ final theme = Theme.of(context);
+
+ return SizedBox(
+ height: areaPaneHeaderHeight,
+ child: Container(
+ decoration: BoxDecoration(
+ border: Border(
+ top: needsTopBorder
+ ? BorderSide(color: theme.focusColor)
+ : BorderSide.none,
+ bottom: BorderSide(color: theme.focusColor),
+ ),
+ 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.of(context).textTheme.subtitle2,
+ ),
+ ),
+ ...actions,
+ ],
+ ),
+ ),
+ );
+}
+
/// A FlatButton used to close a containing dialog.
class DialogCloseButton extends StatelessWidget {
@override
diff --git a/packages/devtools_app/lib/src/console.dart b/packages/devtools_app/lib/src/console.dart
index fe0ec2e..2941bb3 100644
--- a/packages/devtools_app/lib/src/console.dart
+++ b/packages/devtools_app/lib/src/console.dart
@@ -135,38 +135,6 @@
// CONTROLS
-/// A pre-configured IconButton that fits the ux of the Console widget.
-///
-/// The customizations are:
-/// * Icon size: [actionsIconSize]
-/// * Do not show [tooltip] if the button is disabled
-/// * [VisualDensity.compact]
-class ConsoleControl extends StatelessWidget {
- const ConsoleControl({
- this.icon,
- this.tooltip,
- this.onPressed,
- this.buttonKey,
- });
-
- final IconData icon;
- final String tooltip;
- final VoidCallback onPressed;
- final Key buttonKey;
-
- @override
- Widget build(BuildContext context) {
- final disabled = onPressed == null;
- return IconButton(
- icon: Icon(icon, size: actionsIconSize),
- onPressed: onPressed,
- tooltip: disabled ? null : tooltip,
- visualDensity: VisualDensity.compact,
- key: buttonKey,
- );
- }
-}
-
/// A Console Control to "delete" the contents of the console.
///
/// This just preconfigures a ConsoleControl with the `delete` icon,
@@ -184,11 +152,11 @@
@override
Widget build(BuildContext context) {
- return ConsoleControl(
+ return ToolbarAction(
icon: Icons.delete,
tooltip: tooltip,
onPressed: onPressed,
- buttonKey: buttonKey,
+ key: buttonKey,
);
}
}
@@ -215,13 +183,13 @@
@override
Widget build(BuildContext context) {
final disabled = dataProvider == null;
- return ConsoleControl(
+ return ToolbarAction(
icon: Icons.content_copy,
tooltip: tooltip,
onPressed: disabled
? null
: () => copyToClipboard(dataProvider(), successMessage, context),
- buttonKey: buttonKey,
+ key: buttonKey,
);
}
}
diff --git a/packages/devtools_app/lib/src/debugger/codeview.dart b/packages/devtools_app/lib/src/debugger/codeview.dart
index 4c6854a..dd54894 100644
--- a/packages/devtools_app/lib/src/debugger/codeview.dart
+++ b/packages/devtools_app/lib/src/debugger/codeview.dart
@@ -284,18 +284,18 @@
theme,
child: Row(
children: [
- DebuggerToolbarAction(
- Icons.chevron_left,
+ ToolbarAction(
+ icon: Icons.chevron_left,
onPressed:
scriptsHistory.hasPrevious ? scriptsHistory.moveBack : null,
),
- DebuggerToolbarAction(
- Icons.chevron_right,
+ ToolbarAction(
+ icon: Icons.chevron_right,
onPressed:
scriptsHistory.hasNext ? scriptsHistory.moveForward : null,
),
const SizedBox(width: denseSpacing),
- const VerticalDivider(),
+ const VerticalDivider(thickness: 1.0),
const SizedBox(width: defaultSpacing),
Expanded(
child: Text(
@@ -304,7 +304,6 @@
),
),
const SizedBox(width: denseSpacing),
- const VerticalDivider(),
PopupMenuButton<ScriptRef>(
itemBuilder: _buildScriptMenuFromHistory,
enabled: scriptsHistory.hasScripts,
diff --git a/packages/devtools_app/lib/src/debugger/common.dart b/packages/devtools_app/lib/src/debugger/common.dart
index 74c5394..561344d 100644
--- a/packages/devtools_app/lib/src/debugger/common.dart
+++ b/packages/devtools_app/lib/src/debugger/common.dart
@@ -4,8 +4,8 @@
import 'package:flutter/material.dart';
+import '../common_widgets.dart';
import '../theme.dart';
-import 'debugger_screen.dart';
/// Create a header area for a debugger component.
///
@@ -23,7 +23,7 @@
),
padding: const EdgeInsets.only(left: defaultSpacing),
alignment: Alignment.centerLeft,
- height: DebuggerScreen.debuggerPaneHeaderHeight,
+ height: areaPaneHeaderHeight,
child: child != null ? child : Text(text, style: theme.textTheme.subtitle2),
);
}
@@ -45,24 +45,3 @@
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
);
}
-
-/// A wrapper around a FlatButton and an Icon, used for small toolbar actions.
-class DebuggerToolbarAction extends StatelessWidget {
- const DebuggerToolbarAction(
- this.icon, {
- @required this.onPressed,
- });
-
- final IconData icon;
- final VoidCallback onPressed;
-
- @override
- Widget build(BuildContext context) {
- return FlatButton(
- padding: EdgeInsets.zero,
- materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
- onPressed: onPressed,
- child: Icon(icon, size: actionsIconSize),
- );
- }
-}
diff --git a/packages/devtools_app/lib/src/debugger/console.dart b/packages/devtools_app/lib/src/debugger/console.dart
index 45b634a..231f205 100644
--- a/packages/devtools_app/lib/src/debugger/console.dart
+++ b/packages/devtools_app/lib/src/debugger/console.dart
@@ -8,7 +8,6 @@
import '../common_widgets.dart';
import '../console.dart';
import '../utils.dart';
-import 'common.dart';
import 'debugger_controller.dart';
// TODO(devoncarew): Show some small UI indicator when we receive stdout/stderr.
@@ -60,20 +59,25 @@
return OutlineDecoration(
child: Console(
- title: debuggerSectionTitle(Theme.of(context), text: 'Console'),
+ title: areaPaneHeader(
+ context,
+ title: 'Console',
+ needsTopBorder: false,
+ actions: [
+ CopyToClipboardControl(
+ dataProvider: disabled ? null : () => _lines.join('\n'),
+ successMessage:
+ 'Copied $numLines ${pluralize('line', numLines)}.',
+ buttonKey: DebuggerConsole.copyToClipboardButtonKey,
+ ),
+ DeleteControl(
+ buttonKey: DebuggerConsole.clearStdioButtonKey,
+ tooltip: 'Clear console output',
+ onPressed: disabled ? null : widget.controller.clearStdio,
+ ),
+ ],
+ ),
lines: _lines,
- controls: [
- CopyToClipboardControl(
- dataProvider: disabled ? null : () => _lines.join('\n'),
- successMessage: 'Copied $numLines ${pluralize('line', numLines)}.',
- buttonKey: DebuggerConsole.copyToClipboardButtonKey,
- ),
- DeleteControl(
- onPressed: disabled ? null : widget.controller.clearStdio,
- tooltip: 'Clear console output',
- buttonKey: DebuggerConsole.clearStdioButtonKey,
- ),
- ],
),
);
}
diff --git a/packages/devtools_app/lib/src/debugger/debugger_screen.dart b/packages/devtools_app/lib/src/debugger/debugger_screen.dart
index e156a09..a5ab625 100644
--- a/packages/devtools_app/lib/src/debugger/debugger_screen.dart
+++ b/packages/devtools_app/lib/src/debugger/debugger_screen.dart
@@ -21,7 +21,6 @@
import 'breakpoints.dart';
import 'call_stack.dart';
import 'codeview.dart';
-import 'common.dart';
import 'console.dart';
import 'controls.dart';
import 'debugger_controller.dart';
@@ -37,8 +36,6 @@
const DebuggerScreen()
: super('debugger', title: 'Debugger', icon: Octicons.bug);
- static const debuggerPaneHeaderHeight = 36.0;
-
@override
String get docPageId => screenId;
@@ -211,20 +208,20 @@
totalHeight: constraints.maxHeight,
initialFractions: const [0.38, 0.38, 0.24],
minSizes: const [0.0, 0.0, 0.0],
- headers: [
- debuggerPaneHeader(
+ headers: <SizedBox>[
+ areaPaneHeader(
context,
- callStackTitle,
+ title: callStackTitle,
needsTopBorder: false,
- rightChild:
- // ignore: avoid_redundant_argument_values
- debugShowCallStackCount ? _callStackRightChild() : null,
+ actions: debugShowCallStackCount ? [_callStackRightChild()] : [],
),
- debuggerPaneHeader(context, variablesTitle),
- debuggerPaneHeader(
+ areaPaneHeader(context, title: variablesTitle),
+ areaPaneHeader(
context,
- breakpointsTitle,
- rightChild: _breakpointsRightChild(),
+ title: breakpointsTitle,
+ actions: [
+ _breakpointsRightChild(),
+ ],
rightPadding: 0.0,
),
],
@@ -254,8 +251,8 @@
return Row(children: [
BreakpointsCountBadge(breakpoints: breakpoints),
ActionButton(
- child: DebuggerToolbarAction(
- Icons.delete,
+ child: ToolbarAction(
+ icon: Icons.delete,
onPressed:
breakpoints.isNotEmpty ? controller.clearBreakpoints : null,
),
@@ -367,44 +364,3 @@
return 'paused$reason$fileName $pos';
}
}
-
-FlexSplitColumnHeader debuggerPaneHeader(
- BuildContext context,
- String title, {
- bool needsTopBorder = true,
- Widget rightChild,
- double rightPadding = 4.0,
-}) {
- final theme = Theme.of(context);
-
- return FlexSplitColumnHeader(
- height: DebuggerScreen.debuggerPaneHeaderHeight,
- child: Container(
- decoration: BoxDecoration(
- border: Border(
- top: needsTopBorder
- ? BorderSide(color: theme.focusColor)
- : BorderSide.none,
- bottom: BorderSide(color: theme.focusColor),
- ),
- color: titleSolidBackgroundColor(theme),
- ),
- padding: EdgeInsets.only(left: defaultSpacing, right: rightPadding),
- alignment: Alignment.centerLeft,
- height: DebuggerScreen.debuggerPaneHeaderHeight,
- child: Row(
- children: [
- Expanded(
- child: Text(
- title,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- style: Theme.of(context).textTheme.subtitle2,
- ),
- ),
- if (rightChild != null) rightChild,
- ],
- ),
- ),
- );
-}
diff --git a/packages/devtools_app/lib/src/debugger/scripts.dart b/packages/devtools_app/lib/src/debugger/scripts.dart
index c87a49b..e7250d7 100644
--- a/packages/devtools_app/lib/src/debugger/scripts.dart
+++ b/packages/devtools_app/lib/src/debugger/scripts.dart
@@ -69,14 +69,16 @@
return OutlineDecoration(
child: Column(
children: [
- debuggerPaneHeader(
+ areaPaneHeader(
context,
- 'Libraries',
+ title: 'Libraries',
needsTopBorder: false,
- rightChild: CountBadge(
- filteredItems: _filteredItems,
- items: _items,
- ),
+ actions: [
+ CountBadge(
+ filteredItems: _filteredItems,
+ items: _items,
+ ),
+ ],
),
Container(
decoration: BoxDecoration(
diff --git a/packages/devtools_app/lib/src/flex_split_column.dart b/packages/devtools_app/lib/src/flex_split_column.dart
index 032bb32..a549f8d 100644
--- a/packages/devtools_app/lib/src/flex_split_column.dart
+++ b/packages/devtools_app/lib/src/flex_split_column.dart
@@ -43,7 +43,7 @@
/// 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<FlexSplitColumnHeader> headers;
+ final List<SizedBox> headers;
/// The children that will be laid out below each corresponding header in
/// [headers].
@@ -71,7 +71,7 @@
@visibleForTesting
static List<Widget> buildChildrenWithFirstHeader(
List<Widget> children,
- List<FlexSplitColumnHeader> headers,
+ List<SizedBox> headers,
) {
return [
Column(
@@ -87,7 +87,7 @@
@visibleForTesting
static List<double> modifyInitialFractionsToIncludeFirstHeader(
List<double> initialFractions,
- List<FlexSplitColumnHeader> headers,
+ List<SizedBox> headers,
double totalHeight,
) {
var totalHeaderHeight = 0.0;
@@ -110,7 +110,7 @@
@visibleForTesting
static List<double> modifyMinSizesToIncludeFirstHeader(
List<double> minSizes,
- List<FlexSplitColumnHeader> headers,
+ List<SizedBox> headers,
) {
return [
minSizes[0] + headers[0].height,
@@ -129,11 +129,3 @@
);
}
}
-
-// TODO(kenz): add support for arbitrarily sized widgets.
-class FlexSplitColumnHeader extends SizedBox {
- const FlexSplitColumnHeader({
- @required double height,
- @required Widget child,
- }) : super(height: height, child: child);
-}
diff --git a/packages/devtools_app/lib/src/logging/logging_screen.dart b/packages/devtools_app/lib/src/logging/logging_screen.dart
index 33ec5d5..3d8b125 100644
--- a/packages/devtools_app/lib/src/logging/logging_screen.dart
+++ b/packages/devtools_app/lib/src/logging/logging_screen.dart
@@ -130,7 +130,7 @@
Expanded(
child: Split(
axis: Axis.vertical,
- initialFractions: const [0.78, 0.22],
+ initialFractions: const [0.72, 0.28],
children: [
OutlineDecoration(
child: LogsTable(
@@ -250,15 +250,21 @@
Widget _buildSimpleLog(BuildContext context, LogData log) {
final disabled = log?.details == null || log.details.isEmpty;
+
return OutlineDecoration(
child: Console(
+ title: areaPaneHeader(
+ context,
+ title: 'Details',
+ needsTopBorder: false,
+ actions: [
+ CopyToClipboardControl(
+ dataProvider: disabled ? null : () => log?.prettyPrinted,
+ buttonKey: LogDetails.copyToClipboardButtonKey,
+ ),
+ ],
+ ),
lines: log?.prettyPrinted?.split('\n'),
- controls: [
- CopyToClipboardControl(
- dataProvider: disabled ? null : () => log?.prettyPrinted,
- buttonKey: LogDetails.copyToClipboardButtonKey,
- ),
- ],
),
);
}
diff --git a/packages/devtools_app/test/debugger_screen_test.dart b/packages/devtools_app/test/debugger_screen_test.dart
index 26c7a06..57a3bb6 100644
--- a/packages/devtools_app/test/debugger_screen_test.dart
+++ b/packages/devtools_app/test/debugger_screen_test.dart
@@ -128,7 +128,7 @@
final clearStdioElement =
find.byKey(DebuggerConsole.clearStdioButtonKey).evaluate().first;
- final clearStdioButton = clearStdioElement.widget as IconButton;
+ final clearStdioButton = clearStdioElement.widget as ToolbarAction;
expect(clearStdioButton.onPressed, isNull);
});
diff --git a/packages/devtools_app/test/flex_split_column_test.dart b/packages/devtools_app/test/flex_split_column_test.dart
index 026d2a3..963d78e 100644
--- a/packages/devtools_app/test/flex_split_column_test.dart
+++ b/packages/devtools_app/test/flex_split_column_test.dart
@@ -15,10 +15,10 @@
const children = [SizedBox(), SizedBox(), SizedBox(), SizedBox()];
const firstHeaderKey = Key('first header');
const headers = [
- FlexSplitColumnHeader(height: 50.0, child: SizedBox(key: firstHeaderKey)),
- FlexSplitColumnHeader(height: 50.0, child: SizedBox()),
- FlexSplitColumnHeader(height: 50.0, child: SizedBox()),
- FlexSplitColumnHeader(height: 50.0, child: SizedBox()),
+ SizedBox(height: 50.0, key: firstHeaderKey),
+ SizedBox(height: 50.0),
+ SizedBox(height: 50.0),
+ SizedBox(height: 50.0),
];
const initialFractions = [0.25, 0.25, 0.25, 0.25];
const minSizes = [10.0, 10.0, 10.0, 10.0];
diff --git a/packages/devtools_app/test/logging_screen_test.dart b/packages/devtools_app/test/logging_screen_test.dart
index a460b05..7305cdb 100644
--- a/packages/devtools_app/test/logging_screen_test.dart
+++ b/packages/devtools_app/test/logging_screen_test.dart
@@ -163,7 +163,7 @@
.byKey(LogDetails.copyToClipboardButtonKey)
.evaluate()
.first
- .widget as IconButton;
+ .widget as ToolbarAction;
expect(
copyButton().onPressed,