From 8b25fd4692acf95ef0d5e2ebb8913432e28c62ac Mon Sep 17 00:00:00 2001 From: AndyZ54 Date: Thu, 5 Oct 2023 17:42:20 -0400 Subject: [PATCH 1/7] added slider to cameras --- lib/src/widgets/atomic/video_feed.dart | 123 ++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/lib/src/widgets/atomic/video_feed.dart b/lib/src/widgets/atomic/video_feed.dart index ee8bfa4b45..d931f77d08 100644 --- a/lib/src/widgets/atomic/video_feed.dart +++ b/lib/src/widgets/atomic/video_feed.dart @@ -59,6 +59,43 @@ class VideoFeed extends StatefulWidget { VideoFeedState createState() => VideoFeedState(); } +/// Docs +class SliderSettings extends StatelessWidget { + /// Docs + final String label; + /// Docs + final double value; + /// Docs + final ValueChanged onChanged; + + /// Docs + const SliderSettings({ + required this.label, + required this.value, + required this.onChanged, + }); + + @override + Widget build(BuildContext context) => Column( + children: [ + Row ( + mainAxisSize: MainAxisSize.min, + children: [ + Text(label), + const Text(": "), + Text(value.floor().toString()), + ], + ), + Slider( + value: value, + onChanged: onChanged, + min: 0, + max: 100, + ), + ], + ); +} + /// The logic for updating a [VideoFeed]. /// /// This widget listens to [VideoModel.frameUpdater] to sync its framerate with other [VideoFeed]s. @@ -73,6 +110,80 @@ class VideoFeedState extends State { /// A helper class responsible for managing and loading an image. final imageLoader = ImageLoader(); + /// Checks if the current slider for video camera is open + bool isOpened = false; + + /// Docs + double zoom = 0.0; + /// Docs + double pan = 0.0; + /// Docs + double volume = 0.0; + /// Docs + double brightness = 0.0; + + /// Docs + PersistentBottomSheetController? controller; + void _showSettingsPanel() { + if (!isOpened) { + controller = Scaffold.of(context).showBottomSheet( + (context) => StatefulBuilder( + builder: (BuildContext context, StateSetter setState) => Container( + padding: const EdgeInsets.all(10), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row ( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + + children: [ + const Text( + "Settings", + style: TextStyle( + fontSize: 20, fontWeight: FontWeight.bold,), + ), + IconButton( + icon: const Icon(Icons.close), + onPressed: () { + controller!.close(); + isOpened = false; + }, + ), + ], + ), + SliderSettings( + label: "Zoom", + value: zoom, + onChanged: (val) => setState(() => zoom = val), + ), + SliderSettings( + label: "Pan", + value: pan, + onChanged: (val) => setState(() => pan = val), + ), + SliderSettings( + label: "Volume", + value: volume, + onChanged: (val) => setState(() => volume = val), + ), + SliderSettings( + label: "Brightness", + value: brightness, + onChanged: (val) => setState(() => brightness = val), + ), + ], + ), + ), + ), + ), + ); + } else { + controller!.close(); + controller = null; + } + isOpened = !isOpened; + } @override void initState() { super.initState(); @@ -134,7 +245,17 @@ class VideoFeedState extends State { ViewsSelector(currentView: widget.name.humanName), ], ), - Positioned(left: 5, bottom: 5, child: Text(data.details.name.humanName)), + Positioned( + left: 5, + bottom: 5, + child: Row( + children: [ + Text(data.details.name.humanName), + IconButton(onPressed: _showSettingsPanel, icon: const Icon(Icons.tune)) + + ], + ), + ), ], ); From 0c2344530e2e04f7ac3e622551843741d6715364 Mon Sep 17 00:00:00 2001 From: AndyZ54 Date: Thu, 5 Oct 2023 21:01:22 -0400 Subject: [PATCH 2/7] Centered Settings, changed docs --- lib/src/widgets/atomic/video_feed.dart | 123 +++++++++++++------------ 1 file changed, 64 insertions(+), 59 deletions(-) diff --git a/lib/src/widgets/atomic/video_feed.dart b/lib/src/widgets/atomic/video_feed.dart index d931f77d08..8dfaa7c168 100644 --- a/lib/src/widgets/atomic/video_feed.dart +++ b/lib/src/widgets/atomic/video_feed.dart @@ -59,16 +59,16 @@ class VideoFeed extends StatefulWidget { VideoFeedState createState() => VideoFeedState(); } -/// Docs +/// Class that defines a slider for camera controls class SliderSettings extends StatelessWidget { - /// Docs + /// Name of the slider final String label; - /// Docs + /// Valude corresponding to the slider final double value; - /// Docs + /// Value to change the position of the slider final ValueChanged onChanged; - /// Docs + /// Constructor for SliderSettings const SliderSettings({ required this.label, required this.value, @@ -83,6 +83,7 @@ class SliderSettings extends StatelessWidget { children: [ Text(label), const Text(": "), + // Will this incur some computation cost? is doing .floor().toString() fine? Text(value.floor().toString()), ], ), @@ -113,69 +114,74 @@ class VideoFeedState extends State { /// Checks if the current slider for video camera is open bool isOpened = false; - /// Docs - double zoom = 0.0; - /// Docs - double pan = 0.0; - /// Docs - double volume = 0.0; - /// Docs - double brightness = 0.0; + /// Value for zoom + double zoom = 0; + /// Value for pan + double pan = 0; + /// Value for focus + double focus = 0; + /// Value for brightness + double brightness = 0; - /// Docs - PersistentBottomSheetController? controller; + /// Controller for the BottomSheet + PersistentBottomSheetController? controller; void _showSettingsPanel() { if (!isOpened) { controller = Scaffold.of(context).showBottomSheet( (context) => StatefulBuilder( - builder: (BuildContext context, StateSetter setState) => Container( - padding: const EdgeInsets.all(10), - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row ( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - - children: [ - const Text( + builder: (BuildContext context, StateSetter setState) => Container( + padding: const EdgeInsets.all(10), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Stack ( + alignment: Alignment.center, + children: [ + const Align( + child: + Text( "Settings", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold,), + ), ), - IconButton( - icon: const Icon(Icons.close), - onPressed: () { - controller!.close(); - isOpened = false; - }, - ), - ], - ), - SliderSettings( - label: "Zoom", - value: zoom, - onChanged: (val) => setState(() => zoom = val), - ), - SliderSettings( - label: "Pan", - value: pan, - onChanged: (val) => setState(() => pan = val), - ), - SliderSettings( - label: "Volume", - value: volume, - onChanged: (val) => setState(() => volume = val), - ), - SliderSettings( - label: "Brightness", - value: brightness, - onChanged: (val) => setState(() => brightness = val), - ), - ], - ), + Align( + alignment: Alignment.centerRight, + child: IconButton( + icon: const Icon(Icons.close), + onPressed: () { + controller!.close(); + isOpened = false; + }, + ), + ), + ], + ), + SliderSettings( + label: "Zoom", + value: zoom, + onChanged: (val) => setState(() => zoom = val), + ), + SliderSettings( + label: "Pan", + value: pan, + onChanged: (val) => setState(() => pan = val), + ), + SliderSettings( + label: "Focus", + value: focus, + onChanged: (val) => setState(() => focus = val), + ), + SliderSettings( + label: "Brightness", + value: brightness, + onChanged: (val) => setState(() => brightness = val), + ), + ], ), ), + ), ), ); } else { @@ -251,8 +257,7 @@ class VideoFeedState extends State { child: Row( children: [ Text(data.details.name.humanName), - IconButton(onPressed: _showSettingsPanel, icon: const Icon(Icons.tune)) - + IconButton(onPressed: _showSettingsPanel, icon: const Icon(Icons.tune)), ], ), ), From 011ad7e5d6458b814f6d789b8a242026f8d92dc5 Mon Sep 17 00:00:00 2001 From: AndyZ54 Date: Thu, 5 Oct 2023 21:09:36 -0400 Subject: [PATCH 3/7] Changed controller.close --- lib/src/widgets/atomic/video_feed.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/widgets/atomic/video_feed.dart b/lib/src/widgets/atomic/video_feed.dart index 8dfaa7c168..28872337dc 100644 --- a/lib/src/widgets/atomic/video_feed.dart +++ b/lib/src/widgets/atomic/video_feed.dart @@ -185,7 +185,7 @@ class VideoFeedState extends State { ), ); } else { - controller!.close(); + controller?.close(); controller = null; } isOpened = !isOpened; From aa8af54b1377e0d379d26c0a9f1626228f7a8325 Mon Sep 17 00:00:00 2001 From: AndyZ54 Date: Tue, 10 Oct 2023 17:56:34 -0400 Subject: [PATCH 4/7] Removed redundant default value --- lib/src/widgets/atomic/video_feed.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/widgets/atomic/video_feed.dart b/lib/src/widgets/atomic/video_feed.dart index 28872337dc..aa7466f897 100644 --- a/lib/src/widgets/atomic/video_feed.dart +++ b/lib/src/widgets/atomic/video_feed.dart @@ -90,7 +90,6 @@ class SliderSettings extends StatelessWidget { Slider( value: value, onChanged: onChanged, - min: 0, max: 100, ), ], From c8561f3940865c18484a1a58f7562eafa5f08bba Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Wed, 11 Oct 2023 19:25:11 -0400 Subject: [PATCH 5/7] Some UI changes --- lib/src/widgets/atomic/video_feed.dart | 121 ++++++++++++------------- 1 file changed, 56 insertions(+), 65 deletions(-) diff --git a/lib/src/widgets/atomic/video_feed.dart b/lib/src/widgets/atomic/video_feed.dart index aa7466f897..66ea6440b5 100644 --- a/lib/src/widgets/atomic/video_feed.dart +++ b/lib/src/widgets/atomic/video_feed.dart @@ -123,72 +123,51 @@ class VideoFeedState extends State { double brightness = 0; /// Controller for the BottomSheet - PersistentBottomSheetController? controller; - void _showSettingsPanel() { - if (!isOpened) { - controller = Scaffold.of(context).showBottomSheet( - (context) => StatefulBuilder( - builder: (BuildContext context, StateSetter setState) => Container( - padding: const EdgeInsets.all(10), - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Stack ( - alignment: Alignment.center, - children: [ - const Align( - child: - Text( - "Settings", - style: TextStyle( - fontSize: 20, fontWeight: FontWeight.bold,), - ), - ), - Align( - alignment: Alignment.centerRight, - child: IconButton( - icon: const Icon(Icons.close), - onPressed: () { - controller!.close(); - isOpened = false; - }, - ), - ), - ], - ), - SliderSettings( - label: "Zoom", - value: zoom, - onChanged: (val) => setState(() => zoom = val), - ), - SliderSettings( - label: "Pan", - value: pan, - onChanged: (val) => setState(() => pan = val), - ), - SliderSettings( - label: "Focus", - value: focus, - onChanged: (val) => setState(() => focus = val), - ), - SliderSettings( - label: "Brightness", - value: brightness, - onChanged: (val) => setState(() => brightness = val), - ), - ], - ), - ), + PersistentBottomSheetController? controller; + + void _showSettingsPanel() => controller = Scaffold.of(context).showBottomSheet( + (context) => Container( + padding: const EdgeInsets.all(10), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row(children: [ + Spacer(), + Text("Settings for ${data.details.name.humanName}"), + Spacer(), + IconButton( + icon: const Icon(Icons.close), + onPressed: () { + controller!.close(); + isOpened = false; + }, ), + ]), + SliderSettings( + label: "Zoom", + value: zoom, + onChanged: (val) => setState(() => zoom = val), + ), + SliderSettings( + label: "Pan", + value: pan, + onChanged: (val) => setState(() => pan = val), + ), + SliderSettings( + label: "Focus", + value: focus, + onChanged: (val) => setState(() => focus = val), + ), + SliderSettings( + label: "Brightness", + value: brightness, + onChanged: (val) => setState(() => brightness = val), ), - ); - } else { - controller?.close(); - controller = null; - } - isOpened = !isOpened; - } + ], + ), + ), + ); + @override void initState() { super.initState(); @@ -255,8 +234,20 @@ class VideoFeedState extends State { bottom: 5, child: Row( children: [ + IconButton( + onPressed: () { + print("Is opened? $isOpened"); + if (isOpened) { + controller?.close(); + controller = null; + } else { + _showSettingsPanel(); + } + isOpened = !isOpened; + }, + icon: const Icon(Icons.tune), + ), Text(data.details.name.humanName), - IconButton(onPressed: _showSettingsPanel, icon: const Icon(Icons.tune)), ], ), ), From 56d429df505aa4bf747dbf6c7c750c24e5622fa6 Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Wed, 11 Oct 2023 23:14:58 -0400 Subject: [PATCH 6/7] More refactoring --- lib/src/widgets/atomic/video_feed.dart | 81 +++++++++++++------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/lib/src/widgets/atomic/video_feed.dart b/lib/src/widgets/atomic/video_feed.dart index 66ea6440b5..1c122a43b2 100644 --- a/lib/src/widgets/atomic/video_feed.dart +++ b/lib/src/widgets/atomic/video_feed.dart @@ -123,49 +123,10 @@ class VideoFeedState extends State { double brightness = 0; /// Controller for the BottomSheet - PersistentBottomSheetController? controller; + PersistentBottomSheetController? controller; void _showSettingsPanel() => controller = Scaffold.of(context).showBottomSheet( - (context) => Container( - padding: const EdgeInsets.all(10), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row(children: [ - Spacer(), - Text("Settings for ${data.details.name.humanName}"), - Spacer(), - IconButton( - icon: const Icon(Icons.close), - onPressed: () { - controller!.close(); - isOpened = false; - }, - ), - ]), - SliderSettings( - label: "Zoom", - value: zoom, - onChanged: (val) => setState(() => zoom = val), - ), - SliderSettings( - label: "Pan", - value: pan, - onChanged: (val) => setState(() => pan = val), - ), - SliderSettings( - label: "Focus", - value: focus, - onChanged: (val) => setState(() => focus = val), - ), - SliderSettings( - label: "Brightness", - value: brightness, - onChanged: (val) => setState(() => brightness = val), - ), - ], - ), - ), + (context) => VideoSettingsWidget(name: data.details.name, onClosed: () { controller?.close(); isOpened = false; }), ); @override @@ -236,7 +197,6 @@ class VideoFeedState extends State { children: [ IconButton( onPressed: () { - print("Is opened? $isOpened"); if (isOpened) { controller?.close(); controller = null; @@ -272,3 +232,40 @@ class VideoFeedState extends State { return "Unknown error"; } } + +class VideoSettingsWidget extends StatelessWidget { + final CameraName name; + final VoidCallback onClosed; + const VideoSettingsWidget({required this.name, required this.onClosed}); + + @override + Widget build(BuildContext context) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row(children: [ + const Spacer(), + Text("Settings for ${name.humanName}"), + const Spacer(), + IconButton( + icon: const Icon(Icons.close), + onPressed: onClosed, + ), + ],), + SliderSettings( + label: "Zoom", + value: 0, + onChanged: (val) { }, + ), + SliderSettings( + label: "Pan", + value: 25, + onChanged: (val) { }, + ), + SliderSettings( + label: "Focus", + value: 50, + onChanged: (val) { }, + ), + ], + ); +} From 83a9f18b4cc1298a8e6fc105bb06e5c9f1d2ea2e Mon Sep 17 00:00:00 2001 From: Levi Lesches Date: Wed, 11 Oct 2023 23:22:20 -0400 Subject: [PATCH 7/7] Enabled zoom slider --- lib/src/widgets/atomic/video_feed.dart | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/src/widgets/atomic/video_feed.dart b/lib/src/widgets/atomic/video_feed.dart index 1c122a43b2..b4cb9b2359 100644 --- a/lib/src/widgets/atomic/video_feed.dart +++ b/lib/src/widgets/atomic/video_feed.dart @@ -233,28 +233,37 @@ class VideoFeedState extends State { } } -class VideoSettingsWidget extends StatelessWidget { +class VideoSettingsWidget extends StatefulWidget { final CameraName name; final VoidCallback onClosed; const VideoSettingsWidget({required this.name, required this.onClosed}); + @override + VideoSettingsState createState() => VideoSettingsState(); +} + +class VideoSettingsState extends State { + // I only did zoom for now but this state is not how we'll actually do it! + // This is just for testing the UI, so you don't need to set up all of them. + double zoom = 0; + @override Widget build(BuildContext context) => Column( mainAxisSize: MainAxisSize.min, children: [ Row(children: [ const Spacer(), - Text("Settings for ${name.humanName}"), + Text("Settings for ${widget.name.humanName}"), const Spacer(), IconButton( icon: const Icon(Icons.close), - onPressed: onClosed, + onPressed: widget.onClosed, ), ],), SliderSettings( label: "Zoom", - value: 0, - onChanged: (val) { }, + value: zoom, + onChanged: (val) => setState(() => zoom = val), ), SliderSettings( label: "Pan",