Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 38 additions & 41 deletions device_preview/lib/src/device_preview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class DevicePreview extends StatefulWidget {
this.devices,
this.data,
this.isToolbarVisible = true,
this.overlayNavigatorRequestsFocus = false,
this.availableLocales,
this.defaultDevice,
this.tools = defaultTools,
Expand All @@ -69,6 +70,11 @@ class DevicePreview extends StatefulWidget {
/// Indicates whether the tool bar should be visible or not.
final bool isToolbarVisible;

/// Controls whether the internal overlay navigator should request focus.
///
/// Defaults to false so the previewed app keeps the primary focus.
final bool overlayNavigatorRequestsFocus;

/// The configuration. If not precised, it is loaded from preferences.
final DevicePreviewData? data;

Expand Down Expand Up @@ -133,9 +139,7 @@ class DevicePreview extends StatefulWidget {

/// The currently selected device.
static DeviceInfo selectedDevice(BuildContext context) {
return context.select(
(DevicePreviewStore store) => store.deviceInfo,
);
return context.select((DevicePreviewStore store) => store.deviceInfo);
}

/// The simulated target platform for the currently selected device.
Expand Down Expand Up @@ -235,10 +239,7 @@ class DevicePreview extends StatefulWidget {
///
/// If [enablePreview] is set to `true`, then the device preview is also enabled
/// when appearing.
static void showToolbar(
BuildContext context, {
bool enablePreview = true,
}) {
static void showToolbar(BuildContext context, {bool enablePreview = true}) {
final store = Provider.of<DevicePreviewStore>(context);
store.data = store.data.copyWith(
isToolbarVisible: true,
Expand All @@ -250,10 +251,7 @@ class DevicePreview extends StatefulWidget {
///
/// If [disablePreview] is set to `false`, then the device preview stays active even
/// if the toolbar is not visible anymore.
static void hideToolbar(
BuildContext context, {
bool disablePreview = true,
}) {
static void hideToolbar(BuildContext context, {bool disablePreview = true}) {
final store = Provider.of<DevicePreviewStore>(context);
store.data = store.data.copyWith(
isToolbarVisible: false,
Expand Down Expand Up @@ -381,9 +379,7 @@ class _DevicePreviewState extends State<DevicePreview> {
final image = await boundary.toImage(
pixelRatio: store.deviceInfo.pixelRatio,
);
final byteData = await image.toByteData(
format: format,
);
final byteData = await image.toByteData(format: format);
final bytes = byteData!.buffer.asUint8List();
final screenshot = DeviceScreenshot(
device: store.deviceInfo,
Expand Down Expand Up @@ -438,7 +434,8 @@ class _DevicePreviewState extends State<DevicePreview> {

return Container(
color: widget.backgroundColor ?? theme.canvasColor,
padding: widget.padding ??
padding:
widget.padding ??
EdgeInsets.only(
top: 20 + mediaQuery.viewPadding.top,
right: 20 + mediaQuery.viewPadding.right,
Expand Down Expand Up @@ -485,10 +482,7 @@ class _DevicePreviewState extends State<DevicePreview> {
@override
Widget build(BuildContext context) {
if (!widget.enabled) {
return Builder(
key: _appKey,
builder: widget.builder,
);
return Builder(key: _appKey, builder: widget.builder);
}

return ChangeNotifierProvider(
Expand All @@ -507,10 +501,7 @@ class _DevicePreviewState extends State<DevicePreview> {
);

if (!isInitialized) {
return Builder(
key: _appKey,
builder: widget.builder,
);
return Builder(key: _appKey, builder: widget.builder);
}

final isEnabled = context.select(
Expand All @@ -525,7 +516,8 @@ class _DevicePreviewState extends State<DevicePreview> {
(DevicePreviewStore store) => store.settings.backgroundTheme,
);

final isToolbarVisible = widget.isToolbarVisible &&
final isToolbarVisible =
widget.isToolbarVisible &&
context.select(
(DevicePreviewStore store) => store.data.isToolbarVisible,
);
Expand Down Expand Up @@ -560,11 +552,12 @@ class _DevicePreviewState extends State<DevicePreview> {
: BorderRadius.zero;
final double rightPanelOffset = !isSmall
? (isEnabled
? ToolPanel.panelWidth - 10
: (64 + mediaQuery.padding.right))
? ToolPanel.panelWidth - 10
: (64 + mediaQuery.padding.right))
: 0;
final double bottomPanelOffset = isSmall
? mediaQuery.padding.bottom + 52
: 0;
final double bottomPanelOffset =
isSmall ? mediaQuery.padding.bottom + 52 : 0;
return Stack(
children: <Widget>[
if (isToolbarVisible && isSmall)
Expand Down Expand Up @@ -612,9 +605,7 @@ class _DevicePreviewState extends State<DevicePreview> {
child: ClipRRect(
borderRadius: borderRadius,
child: isEnabled
? Builder(
builder: _buildPreview,
)
? Builder(builder: _buildPreview)
: Builder(
key: _appKey,
builder: widget.builder,
Expand All @@ -633,17 +624,23 @@ class _DevicePreviewState extends State<DevicePreview> {
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
child: Navigator(
onGenerateInitialRoutes: (navigator, name) {
return [
MaterialPageRoute(
builder: (context) => Scaffold(
key: scaffoldKey,
backgroundColor: Colors.transparent,
child: FocusScope(
canRequestFocus:
widget.overlayNavigatorRequestsFocus,
child: Navigator(
requestFocus:
widget.overlayNavigatorRequestsFocus,
onGenerateInitialRoutes: (navigator, name) {
return [
MaterialPageRoute(
builder: (context) => Scaffold(
key: scaffoldKey,
backgroundColor: Colors.transparent,
),
),
),
];
},
];
},
),
),
),
),
Expand Down
29 changes: 15 additions & 14 deletions device_preview/lib/src/views/large.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import 'package:provider/provider.dart';
/// The tool layout when the screen is large.
class DevicePreviewLargeLayout extends StatefulWidget {
/// Create a new panel from the given tools grouped as [slivers].
const DevicePreviewLargeLayout({
super.key,
required this.slivers,
});
const DevicePreviewLargeLayout({super.key, required this.slivers});

/// The sections containing the tools.
///
Expand Down Expand Up @@ -59,19 +56,23 @@ class DevicePreviewLargeLayoutState extends State<DevicePreviewLargeLayout> {
width: ToolPanel.panelWidth,
child: MediaQuery(
data: mediaQuery.copyWith(
padding: mediaQuery.padding.copyWith(left: 0) +
padding:
mediaQuery.padding.copyWith(left: 0) +
const EdgeInsets.only(left: 40),
),
child: Navigator(
onGenerateInitialRoutes: (navigator, initialRoute) {
return [
MaterialPageRoute(
builder: (context) => ToolPanel(
slivers: widget.slivers,
child: FocusScope(
canRequestFocus: false,
child: Navigator(
requestFocus: false,
onGenerateInitialRoutes: (navigator, initialRoute) {
return [
MaterialPageRoute(
builder: (context) =>
ToolPanel(slivers: widget.slivers),
),
),
];
},
];
},
),
),
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ Future<dynamic> _openDeviceSizeAdjustDialog({
context: context,
builder: (context) {
var navigator = Navigator.of(context);
var textEditingController =
TextEditingController(text: initialValue.toString());
var textEditingController = TextEditingController(
text: initialValue.toString(),
);
textEditingController.selection = TextSelection(
baseOffset: 0,
extentOffset: textEditingController.text.length,
Expand All @@ -24,7 +25,8 @@ Future<dynamic> _openDeviceSizeAdjustDialog({
content: Form(
key: formKey,
child: TextFormField(
autofocus: true,
autofocus: false,
canRequestFocus: false,
onSaved: (String? value) => navigator.pop(double.tryParse(value!)),
keyboardType: TextInputType.number,
validator: (value) {
Expand All @@ -44,10 +46,7 @@ Future<dynamic> _openDeviceSizeAdjustDialog({
),
),
actions: [
TextButton(
onPressed: navigator.pop,
child: const Text('Close'),
),
TextButton(onPressed: navigator.pop, child: const Text('Close')),
TextButton(
child: const Text('Confirm'),
onPressed: () {
Expand Down Expand Up @@ -149,11 +148,7 @@ List<Widget> buildCustomDeviceTiles(BuildContext context) {
value: customDevice.pixelRatio,
onChanged: (v) {
final store = context.read<DevicePreviewStore>();
store.updateCustomDevice(
customDevice.copyWith(
pixelRatio: v,
),
);
store.updateCustomDevice(customDevice.copyWith(pixelRatio: v));
},
min: 1,
max: 4,
Expand Down Expand Up @@ -248,17 +243,11 @@ List<Widget> buildCustomDeviceTiles(BuildContext context) {
..._allPlatforms.map(
(p) => ListTile(
leading: TargetPlatformIcon(platform: p),
title: Text(
p.name,
),
title: Text(p.name),
onTap: () {
final store = context.read<DevicePreviewStore>();
if (customDevice != null) {
store.updateCustomDevice(
customDevice.copyWith(
platform: p,
),
);
store.updateCustomDevice(customDevice.copyWith(platform: p));
}
},
),
Expand All @@ -270,20 +259,12 @@ List<Widget> buildCustomDeviceTiles(BuildContext context) {
children: [
..._allDeviceTypes.map(
(type) => ListTile(
leading: DeviceTypeIcon(
type: type,
),
title: Text(
type.name,
),
leading: DeviceTypeIcon(type: type),
title: Text(type.name),
onTap: () {
final store = context.read<DevicePreviewStore>();
if (customDevice != null) {
store.updateCustomDevice(
customDevice.copyWith(
type: type,
),
);
store.updateCustomDevice(customDevice.copyWith(type: type));
}
},
),
Expand Down
63 changes: 30 additions & 33 deletions device_preview/lib/src/views/tool_panel/tool_panel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ class ToolPanel extends StatelessWidget {
///
/// The [isModal] indicates whether the panel is shown modally as a new page, or if it
/// stays visible on one side of the parent layout.
const ToolPanel({
Key? key,
required this.slivers,
this.isModal = false,
}) : super(key: key);
const ToolPanel({Key? key, required this.slivers, this.isModal = false})
: super(key: key);

/// Indicates whether the panel is shown modally as a new page, or if it
/// stays visible on one side of the parent layout.
Expand All @@ -30,28 +27,32 @@ class ToolPanel extends StatelessWidget {
@override
Widget build(BuildContext context) {
final rootContext = context;
return Navigator(
onGenerateInitialRoutes: (nav, name) {
return [
MaterialPageRoute(
builder: (context) {
final toolbarTheme = context.select(
(DevicePreviewStore store) => store.settings.toolbarTheme,
);
return Theme(
data: toolbarTheme.asThemeData(),
child: _ToolPanel(
sections: slivers,
isModal: isModal,
onClose: () {
Navigator.maybePop(rootContext);
},
),
);
},
),
];
},
return FocusScope(
canRequestFocus: false,
child: Navigator(
requestFocus: false,
onGenerateInitialRoutes: (nav, name) {
return [
MaterialPageRoute(
builder: (context) {
final toolbarTheme = context.select(
(DevicePreviewStore store) => store.settings.toolbarTheme,
);
return Theme(
data: toolbarTheme.asThemeData(),
child: _ToolPanel(
sections: slivers,
isModal: isModal,
onClose: () {
Navigator.maybePop(rootContext);
},
),
);
},
),
];
},
),
);
}
}
Expand Down Expand Up @@ -107,17 +108,13 @@ class _ToolPanel extends StatelessWidget {
),
body: Stack(
children: [
CustomScrollView(
slivers: sections,
),
CustomScrollView(slivers: sections),
IgnorePointer(
ignoring: isEnabled,
child: AnimatedOpacity(
opacity: isEnabled ? 0 : 1,
duration: const Duration(milliseconds: 200),
child: Container(
color: const Color(0xCC000000),
),
child: Container(color: const Color(0xCC000000)),
),
),
],
Expand Down
Loading