Skip to content

Commit

Permalink
Add selection styling to Logs table (#2485)
Browse files Browse the repository at this point in the history
* Add selection styling to Logs table
  • Loading branch information
kenzieschmoll authored Nov 4, 2020
1 parent fae594b commit b7bff74
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 23 deletions.
22 changes: 22 additions & 0 deletions packages/devtools_app/lib/src/logging/logging_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ class LoggingController {
return _cachedFilteredData;
}

final _selectedLog = ValueNotifier<LogData>(null);

ValueListenable<LogData> get selectedLog => _selectedLog;

final List<StreamSubscription> _subscriptions = [];

final Reporter onLogsUpdated = Reporter();
Expand All @@ -219,11 +223,26 @@ class LoggingController {
set filterText(String value) {
_filterText = value;
_cachedFilteredData = null;
_updateSelection();

onLogsUpdated.notify();
_updateStatus();
}

void selectLog(LogData data) {
_selectedLog.value = data;
}

void _updateSelection() {
final selected = _selectedLog.value;
if (selected != null) {
final List<LogData> items = filteredData;
if (!items.contains(selected)) {
_selectedLog.value = null;
}
}
}

/// ObjectGroup for Flutter (null for non-Flutter apps).
ObjectGroup objectGroup;

Expand Down Expand Up @@ -253,6 +272,7 @@ class LoggingController {
void clear() {
data.clear();
_cachedFilteredData = null;
_selectedLog.value = null;
_updateStatus();
}

Expand Down Expand Up @@ -505,6 +525,8 @@ class LoggingController {
data = data.sublist(itemsToRemove);
}

_updateSelection();

onLogsUpdated.notify();
_updateStatus();
}
Expand Down
51 changes: 34 additions & 17 deletions packages/devtools_app/lib/src/logging/logging_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

Expand All @@ -18,6 +19,7 @@ import '../split.dart';
import '../table.dart';
import '../table_data.dart';
import '../theme.dart';
import '../ui/colors.dart';
import '../ui/service_extension_widgets.dart';
import '../utils.dart';
import 'logging_controller.dart';
Expand Down Expand Up @@ -87,16 +89,14 @@ class _LoggingScreenState extends State<LoggingScreenBody>
controller.filterText = filterController.text;
});

addAutoDisposeListener(controller.onLogsUpdated, () {
selected = controller.selectedLog.value;
addAutoDisposeListener(controller.selectedLog, () {
setState(() {
if (selected != null) {
final List<LogData> items = controller.filteredData;
if (!items.contains(selected)) {
selected = null;
}
}
selected = controller.selectedLog.value;
});
});

addAutoDisposeListener(controller.onLogsUpdated);
}

@override
Expand Down Expand Up @@ -133,7 +133,8 @@ class _LoggingScreenState extends State<LoggingScreenBody>
OutlineDecoration(
child: LogsTable(
data: controller.filteredData,
onItemSelected: _select,
onItemSelected: controller.selectLog,
selectionNotifier: controller.selectedLog,
),
),
LogDetails(log: selected),
Expand All @@ -143,10 +144,6 @@ class _LoggingScreenState extends State<LoggingScreenBody>
]);
}

void _select(LogData log) {
setState(() => selected = log);
}

void _clearLogs() {
setState(() {
controller.clear();
Expand All @@ -156,10 +153,16 @@ class _LoggingScreenState extends State<LoggingScreenBody>
}

class LogsTable extends StatelessWidget {
LogsTable({Key key, this.data, this.onItemSelected}) : super(key: key);
LogsTable({
Key key,
this.data,
this.onItemSelected,
this.selectionNotifier,
}) : super(key: key);

final List<LogData> data;
final ItemCallback<LogData> onItemSelected;
final ValueListenable<LogData> selectionNotifier;

final ColumnData<LogData> when = _WhenColumn();
final ColumnData<LogData> kind = _KindColumn();
Expand All @@ -175,6 +178,7 @@ class LogsTable extends StatelessWidget {
autoScrollContent: true,
keyFactory: (LogData data) => ValueKey<LogData>(data),
onItemSelected: onItemSelected,
selectionNotifier: selectionNotifier,
sortColumn: when,
sortDirection: SortDirection.ascending,
);
Expand Down Expand Up @@ -298,7 +302,11 @@ class _KindColumn extends ColumnData<LogData>
String getValue(LogData dataObject) => dataObject.kind;

@override
Widget build(BuildContext context, LogData item) {
Widget build(
BuildContext context,
LogData item, {
bool isRowSelected = false,
}) {
final String kind = item.kind;

Color color = const Color.fromARGB(0xff, 0x61, 0x61, 0x61);
Expand Down Expand Up @@ -346,13 +354,22 @@ class _MessageColumn extends ColumnData<LogData>
dataObject.summary ?? dataObject.details;

@override
Widget build(BuildContext context, LogData data) {
Widget build(
BuildContext context,
LogData data, {
bool isRowSelected = false,
}) {
TextStyle textStyle = fixedFontStyle(context);
if (isRowSelected) {
textStyle = textStyle.copyWith(color: defaultSelectionForegroundColor);
}

if (data.kind == 'flutter.frame') {
const Color color = Color.fromARGB(0xff, 0x00, 0x91, 0xea);
final Text text = Text(
getDisplayValue(data),
overflow: TextOverflow.ellipsis,
style: fixedFontStyle(context),
style: textStyle,
);

double frameLength = 0.0;
Expand Down Expand Up @@ -382,7 +399,7 @@ class _MessageColumn extends ColumnData<LogData>
// TODO(helin24): Recompute summary length considering ansi codes.
// The current summary is generally the first 200 chars of details.
getDisplayValue(data),
fixedFontStyle(context),
textStyle,
),
),
overflow: TextOverflow.ellipsis,
Expand Down
12 changes: 10 additions & 2 deletions packages/devtools_app/lib/src/network/network_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,11 @@ class UriColumn extends ColumnData<NetworkRequest>
}

@override
Widget build(BuildContext context, NetworkRequest data) {
Widget build(
BuildContext context,
NetworkRequest data, {
bool isRowSelected = false,
}) {
final value = getDisplayValue(data);

return Tooltip(
Expand Down Expand Up @@ -350,7 +354,11 @@ class StatusColumn extends ColumnData<NetworkRequest>
}

@override
Widget build(BuildContext context, NetworkRequest data) {
Widget build(
BuildContext context,
NetworkRequest data, {
bool isRowSelected = false,
}) {
final theme = Theme.of(context);
return Text(
getDisplayValue(data),
Expand Down
24 changes: 21 additions & 3 deletions packages/devtools_app/lib/src/table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class FlatTable<T> extends StatefulWidget {
this.onSortChanged,
this.searchMatchesNotifier,
this.activeSearchMatchNotifier,
this.selectionNotifier,
}) : assert(columns != null),
assert(keyFactory != null),
assert(data != null),
Expand Down Expand Up @@ -84,6 +85,8 @@ class FlatTable<T> extends StatefulWidget {

final ValueListenable<T> activeSearchMatchNotifier;

final ValueListenable<T> selectionNotifier;

@override
FlatTableState<T> createState() => FlatTableState<T>();
}
Expand Down Expand Up @@ -167,6 +170,9 @@ class FlatTableState<T> extends State<FlatTable<T>>
columns: widget.columns,
columnWidths: columnWidths,
backgroundColor: alternatingColorForIndexWithContext(index, context),
isSelected: widget.selectionNotifier != null
? node == widget.selectionNotifier.value
: false,
searchMatchesNotifier: widget.searchMatchesNotifier,
activeSearchMatchNotifier: widget.activeSearchMatchNotifier,
);
Expand Down Expand Up @@ -881,7 +887,7 @@ abstract class ColumnRenderer<T> {
///
/// This method can return `null` to indicate that the default rendering
/// should be used instead.
Widget build(BuildContext context, T data);
Widget build(BuildContext context, T data, {bool isRowSelected = false});
}

/// Callback for when a specific item in a table is selected.
Expand All @@ -908,6 +914,7 @@ class TableRow<T> extends StatefulWidget {
this.onExpansionCompleted,
this.isExpanded = false,
this.isExpandable = false,
this.isSelected = false,
this.isShown = true,
this.searchMatchesNotifier,
this.activeSearchMatchNotifier,
Expand All @@ -930,6 +937,7 @@ class TableRow<T> extends StatefulWidget {
}) : node = null,
isExpanded = false,
isExpandable = false,
isSelected = false,
expandableColumn = null,
isShown = true,
backgroundColor = null,
Expand All @@ -945,6 +953,7 @@ class TableRow<T> extends StatefulWidget {
final List<ColumnData<T>> columns;
final ItemCallback<T> onPressed;
final List<double> columnWidths;
final bool isSelected;

/// Which column, if any, should show expansion affordances
/// and nested rows.
Expand Down Expand Up @@ -1126,6 +1135,9 @@ class _TableRowState<T> extends State<TableRow<T>>
Color _searchAwareBackgroundColor() {
final backgroundColor =
widget.backgroundColor ?? titleSolidBackgroundColor(Theme.of(context));
if (widget.isSelected) {
return defaultSelectionColor;
}
final searchAwareBackgroundColor = isSearchMatch
? Color.alphaBlend(
isActiveSearchMatch
Expand Down Expand Up @@ -1199,7 +1211,11 @@ class _TableRowState<T> extends State<TableRow<T>>
assert(padding >= 0);

if (column is ColumnRenderer) {
content = (column as ColumnRenderer).build(context, node);
content = (column as ColumnRenderer).build(
context,
node,
isRowSelected: widget.isSelected,
);
}
content ??= Text(
column.getDisplayValue(node),
Expand Down Expand Up @@ -1259,7 +1275,9 @@ class _TableRowState<T> extends State<TableRow<T>>
}

TextStyle contentTextStyle(ColumnData<T> column) {
final textColor = column.getTextColor(widget.node);
final textColor = widget.isSelected
? defaultSelectionForegroundColor
: column.getTextColor(widget.node);
final fontStyle = fixedFontStyle(context);
return textColor == null ? fontStyle : fontStyle.copyWith(color: textColor);
}
Expand Down
1 change: 1 addition & 0 deletions packages/devtools_app/lib/src/ui/colors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extension FlameChartColorScheme on ColorScheme {
isLight ? Colors.black54 : const Color.fromARGB(255, 200, 200, 200);
}

const defaultSelectionForegroundColor = Colors.black;
const defaultSelectionColor = Color(0xFF36C6F4);

const searchMatchColor = Colors.yellow;
Expand Down
12 changes: 11 additions & 1 deletion packages/devtools_app/test/support/mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,17 @@ class MockConnectedApp extends Mock implements ConnectedApp {}
class MockBannerMessagesController extends Mock
implements BannerMessagesController {}

class MockLoggingController extends Mock implements LoggingController {}
class MockLoggingController extends Mock implements LoggingController {
@override
ValueListenable<LogData> get selectedLog => _selectedLog;

final _selectedLog = ValueNotifier<LogData>(null);

@override
void selectLog(LogData data) {
_selectedLog.value = data;
}
}

class MockMemoryController extends Mock implements MemoryController {}

Expand Down

0 comments on commit b7bff74

Please sign in to comment.