Skip to content

Commit

Permalink
Add in a list of all sources to the view
Browse files Browse the repository at this point in the history
Add search functionality

Filter by default to the main package
  • Loading branch information
Dave Shuckerow committed Feb 21, 2020
1 parent e8030a2 commit 4bc5643
Showing 1 changed file with 146 additions and 13 deletions.
159 changes: 146 additions & 13 deletions packages/devtools_app/lib/src/debugger/flutter/debugger_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ class DebuggerScreenBody extends StatefulWidget {
}

class DebuggerScreenBodyState extends State<DebuggerScreenBody> {
ScriptRef loadingScript;
Script script;
ScriptList scriptList;

@override
void initState() {
Expand All @@ -43,14 +45,25 @@ class DebuggerScreenBodyState extends State<DebuggerScreenBody> {
serviceManager.service
.getScripts(serviceManager.isolateManager.selectedIsolate.id)
.then((scripts) async {
final scriptRef = scripts.scripts
.where((ref) => ref.uri.contains('package:flutter'))
.first;
final _script = await serviceManager.service.getObject(
serviceManager.isolateManager.selectedIsolate.id,
scriptRef.id,
) as Script;
setState(() => script = _script);
setState(() {
scriptList = scripts;
});
});
}

Future<void> onScriptSelected(ScriptRef ref) async {
if (ref == null) return;
setState(() {
loadingScript = ref;
script = null;
});
final result = await serviceManager.service.getObject(
serviceManager.isolateManager.selectedIsolate.id,
ref.id,
) as Script;

setState(() {
script = result;
});
}

Expand All @@ -60,13 +73,128 @@ class DebuggerScreenBodyState extends State<DebuggerScreenBody> {
axis: Axis.horizontal,
initialFirstFraction: 0.25,
// TODO(https://github.com/flutter/devtools/issues/1648): Debug panes.
firstChild: const Text('Debugger details'),
firstChild: ScriptPicker(
scripts: scriptList,
onSelected: onScriptSelected,
selected: loadingScript,
),
// TODO(https://github.com/flutter/devtools/issues/1648): Debug controls.
secondChild: CodeView(
script: script,
secondChild: loadingScript != null && script == null
? const Center(child: CircularProgressIndicator())
: CodeView(
script: script,
),
);
}
}

/// Picker that takes a [ScriptList] and allows selection of one of the scripts inside.
class ScriptPicker extends StatefulWidget {
const ScriptPicker({Key key, this.scripts, this.onSelected, this.selected})
: super(key: key);

final ScriptList scripts;
final void Function(ScriptRef scriptRef) onSelected;
final ScriptRef selected;

@override
ScriptPickerState createState() => ScriptPickerState();
}

class ScriptPickerState extends State<ScriptPicker> {
List<ScriptRef> _filtered;
TextEditingController filterController = TextEditingController();

@override
void initState() {
super.initState();
if (_isNotLoaded) initFilter();
}

@override
void didUpdateWidget(ScriptPicker oldWidget) {
super.didUpdateWidget(oldWidget);
if (_isNotLoaded) {
initFilter();
} else if (oldWidget.scripts != widget.scripts) {
updateFilter(filterController.text);
}
}

void initFilter() {
// Make an educated guess as to the main package to slim down the initial list of scripts we show.
if (widget.scripts?.scripts != null) {
final mainFile = widget.scripts.scripts
.firstWhere((ref) => ref.uri.contains('main.dart'));
filterController.text = mainFile.uri.split('/').first;
updateFilter(filterController.text);
}
}

void updateFilter(String value) {
setState(() {
if (widget.scripts?.scripts == null) {
_filtered = null;
} else {
_filtered = widget.scripts.scripts
.where(
(ref) => ref.uri.contains(value.toLowerCase()),
)
.toList();
}
});
}

Widget _buildScript(ScriptRef ref) {
final selectedColor = Theme.of(context).selectedRowColor;
return Material(
color: ref == widget.selected ? selectedColor : null,
child: InkWell(
onTap: () => widget.onSelected(ref),
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text('${ref?.uri?.split('/')?.last} (${ref?.uri})'),
),
),
),
);
}

bool get _isNotLoaded => _filtered == null || widget.scripts?.scripts == null;

@override
Widget build(BuildContext context) {
if (_isNotLoaded) {
return const Center(child: CircularProgressIndicator());
}
final items = _filtered;
return Column(
mainAxisSize: MainAxisSize.max,
children: [
TextField(
controller: filterController,
onChanged: updateFilter,
),
Expanded(
child: Scrollbar(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: ListView.builder(
itemBuilder: (context, index) => _buildScript(items[index]),
itemCount: items.length,
itemExtent: 32.0,
),
),
),
),
),
],
);
}
}

class CodeView extends StatelessWidget {
Expand All @@ -79,7 +207,12 @@ class CodeView extends StatelessWidget {
// TODO(https://github.com/flutter/devtools/issues/1648): Line numbers,
// syntax highlighting and breakpoint markers.
if (script == null) {
return const Center(child: CircularProgressIndicator());
return Center(
child: Text(
'No script selected',
style: Theme.of(context).textTheme.subtitle1,
),
);
}
return DefaultTextStyle(
style: Theme.of(context)
Expand All @@ -88,8 +221,8 @@ class CodeView extends StatelessWidget {
.copyWith(fontFamily: 'RobotoMono'),
child: Scrollbar(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Text(script.source),
),
),
Expand Down

0 comments on commit 4bc5643

Please sign in to comment.