· 6 years ago · Mar 02, 2020, 04:56 AM
1import 'dart:async';
2import 'dart:ffi';
3import 'dart:io';
4import 'dart:typed_data';
5
6import 'package:NVRCmdResponsePlugin/cmdBase.dart';
7import 'package:cortex_go/Screens/zoomWidget.dart';
8import 'package:cortex_go/cortex_icons_icons.dart';
9import 'package:cortex_go/joystick.dart';
10import 'package:cortex_go/manager/layoutBase.dart';
11import 'package:cortex_go/manager/nvr.dart';
12import 'package:cortex_go/manager/nvrManager.dart';
13import 'package:cortex_go/zoom_widget/zoom_widget.dart';
14import 'package:flutter/cupertino.dart';
15import 'dart:ui' as ui;
16import 'package:cortex_go/Screens/tile_popup.dart';
17import 'package:example/vlc_player_controller.dart';
18
19import 'package:flutter/material.dart';
20
21//import '../../plugins/example/lib/vlc_player_controller.dart';
22double x, y, _zoom = 1;
23typedef void FullScreenTileCallback(int tileNumber);
24typedef void SelectAllTileCallback(bool select);
25typedef void HideBottomNavigator();
26typedef void HideDrawer();
27typedef void SetStateTile();
28/**
29 * Class : This class is created inside layout class.
30 * This start call get frame API when camera is attached this class.
31 * This is done through shecdular or timer(TODO: Experiment and find optimized way to call get frame repeatedly)
32 *
33 */
34Uint8List gloFrame = null;
35getgloFrame() {
36 return gloFrame;
37}
38
39setFrame(frame) {
40 gloFrame = frame;
41}
42
43class Tile extends StatefulWidget {
44 final int tileNumber;
45 final NVRManager nvrManager;
46 final FullScreenTileCallback fullScreenTileCallback;
47 final SelectAllTileCallback selectAllTileCallback;
48 final HideBottomNavigator hideBottomNavigator;
49 final HideDrawer hideDrawer;
50 final StreamResolutionType resType;
51 SetStateTile tileSetState;
52 bool selectTile = false;
53 double height;
54 double width;
55 Tile({
56 Key key,
57 @required this.tileNumber,
58 @required this.nvrManager,
59 @required this.fullScreenTileCallback,
60 @required this.selectAllTileCallback,
61 @required this.hideBottomNavigator,
62 @required this.hideDrawer,
63 @required this.resType,
64 @required this.selectTile,
65 this.width,
66 this.height,
67 }) : super(key: key);
68
69 //int _tileNumber = tileNumber;
70 @override
71 _Tile createState() => new _Tile();
72
73 //void setTileNumber(int itr) {_tileNumber = itr;}
74
75 //int getTileNumber() {return _tileNumber;}
76
77}
78
79class _Tile extends State<Tile> with TickerProviderStateMixin{
80 //double width = 40.0, height = 40.0;
81 Offset positionB;
82 int _tileNumber = -1;
83 int _cameraPort = -1;
84 ui.Image _frame = null;
85 double _width;
86 double _height;
87 bool _isCameraAttached = false;
88 //bool clickDetected = false;
89 bool doubleClickDetected = false;
90 GlobalKey key = GlobalKey();
91 GlobalKey popupkey = GlobalKey();
92 bool buildCompleted = true;
93 //PopupMenu menu;
94 OverlayEntry overlayEntry = null;
95 final FocusNode _focusNode = FocusNode();
96 String _cameraName = "Not Connected";
97 int _textureId = null;
98 NVR _nvr = null;
99 IPCamera _ipCamera = null;
100 VlcPlayerController _controller;
101 Timer _getFrameTimer = null;
102 Stream<int> stream = null;
103 var squareScaleA = 1.0;
104 var squareScaleB = 1.0;
105 AnimationController _controllerA;
106 AnimationController _controllerB;
107 Offset off;
108
109 //RenderBox box;
110 //Offset position;
111
112 int _res = 1; //Default SD
113/**
114 * Constructor class
115 */
116 _Tile() {
117 //_width = width;
118 //_height = height;
119 }
120 /**
121 * Method to update the frame
122 */
123 Future<void> updateFrame(Uint8List frame, String ipCameraName) async {
124 ui.Image image = await loadImage(frame);
125 if (this.mounted == true) {
126 setState(() {
127 _cameraName = ipCameraName;
128 //overlayEntry.markNeedsBuild();
129 _isCameraAttached = true;
130 setFrame(frame);
131 _frame = image;
132 });
133 }
134 }
135
136 void tileState() {
137 setState(() {});
138 }
139
140 @override
141 void initState() {
142 _controllerA = AnimationController(
143 vsync: this,
144 lowerBound: 1.0,
145 upperBound: 2,
146 duration: Duration(seconds: 1));
147 _controllerA.addListener(() {
148 setState(() {
149 squareScaleA = _controllerA.value;
150 });
151 });
152 _controllerB = AnimationController(
153 vsync: this,
154 lowerBound: 0.5,
155 upperBound: 1.0,
156 duration: Duration(seconds: 1));
157 _controllerB.addListener(() {
158 setState(() {
159 squareScaleB = _controllerB.value;
160 });
161 });
162
163
164 positionB = Offset(0, 0);
165 print('callback function set');
166 WidgetsBinding.instance.addPostFrameCallback((_) {
167 //box = key.currentContext.findRenderObject();
168
169 //position =
170 // box.localToGlobal(Offset.zero);
171 this.widget.tileSetState = this.tileState;
172 _tileNumber = this.widget.tileNumber;
173 print('************Test ${_tileNumber} ');
174 if (this.updateFrame != null) {
175 widget.nvrManager.setTileCallback(widget.tileNumber, this.updateFrame);
176 }
177 });
178 _focusNode.addListener(() {
179 print("Has focus: ${_focusNode.hasFocus}");
180 });
181 super.initState();
182 }
183
184 @override
185 void didUpdateWidget(Tile oldWidget) {
186 print("****didUpdateWidget ${this.widget.tileNumber}");
187 /* if (_nvr != null) {
188 Future(() async {
189 print("Stop Steaming");
190 //await stopVideoStreaming(_nvr, _ipCamera,this.widget.resType);
191 }).then((value) {
192 print(
193 "Dragged NVR ${_nvr.getNVRName()} IP Camera ${_ipCamera.getCameraName()}");
194 _controller = new VideoPlayerController();
195 _nvr.startStreamCamera(
196 _ipCamera, StreamResolutionType.StreamResolutionHD, _controller);
197 //_controller.initialize();
198 getFrame(this.widget.resType);
199 });
200 } */
201 super.didUpdateWidget(oldWidget);
202 }
203
204 @override
205 void deactivate() {
206 //This same work similiar to stopvideostreaming function but there no setState
207 if (_nvr != null) {
208 print(
209 "***************************Stoping the streaming ${_ipCamera.getCameraName()}");
210 //_getFrameTimer.cancel();
211 _cameraName = "Not Connected"; //_ipCamera.getCameraName();
212
213 _isCameraAttached = false;
214 // _textureId = null;
215 _frame = null;
216
217 _nvr.stopStreamCamera(_ipCamera, this.widget.resType);
218 if (_controller != null) {
219 _controller.dispose();
220 }
221 }
222 print("****deactivate ${this.widget.tileNumber}");
223 //stopVideoSteaming(_nvr, _ipCamera, this.widget.resType);
224 //stopVideoSteaming(_nvr, _ipCamera,this.widget.resType);
225 super.deactivate();
226 }
227
228 @override
229 void dispose() {
230 _controllerA.dispose();
231 _controllerB.dispose();
232 print("****dispose ${this.widget.tileNumber}");
233 //widget.nvrManager.setTileCallback(widget.tileNumber, null);
234
235 super.dispose();
236 }
237
238 Future<void> stopVideoStreaming(
239 NVR nvr, IPCamera ipCamera, StreamResolutionType resolution) async {
240 if (nvr != null) {
241 print(
242 "***************************Stoping the streaming ${ipCamera.getCameraName()}");
243 //_getFrameTimer.cancel();
244 _cameraName = "Not Connected"; //_ipCamera.getCameraName();
245
246 _isCameraAttached = false;
247 _textureId = null;
248 _frame = null;
249 if (this.mounted) {
250 setState(() {});
251 }
252
253 await nvr.stopStreamCamera(ipCamera, resolution);
254 if (_controller != null) {
255 _controller.dispose();
256 }
257 }
258 }
259
260 Future<void> getFrame(StreamResolutionType resolution) async {
261 //print("****************************${_textureId}");
262 if (this.mounted) {
263 //_textureId = _controller.textureId;
264 setState(() {
265 _cameraName = _ipCamera.getCameraName();
266 //overlayEntry.markNeedsBuild();
267 _isCameraAttached = true;
268 });
269 Duration interval = Duration(milliseconds: 10);
270 stream = Stream<int>.periodic(interval, transform);
271
272 stream = stream.takeWhile(condition);
273
274 await for (int i in stream) {
275 Uint8List encodedData =
276 await _nvr.getFrameAndDecode(_ipCamera, resolution);
277 if (encodedData != null) {
278 Uint8List rawFrame =
279 await _controller.makeSnapshot(_tileNumber, encodedData);
280 if (rawFrame != null) {
281 ui.Image image = await loadImage(rawFrame);
282 setFrame(rawFrame);
283 _frame = image;
284 setState(() {});
285 }
286 }
287 }
288
289 //print("****************************${_ipCamera.getCameraName()}");
290 //print("****************************${_textureId}");
291 /*_getFrameTimer = Timer.periodic(
292 Duration(milliseconds: 20 + _tileNumber),
293 (Timer t) =>
294 _nvr.getFrameAndDecode(_ipCamera, resolution));
295 //print("****************************is Active${_getFrameTimer.isActive}");*/
296 }
297 }
298
299 int transform(int x) {}
300
301 bool condition(int x) {
302 return _isCameraAttached;
303 }
304
305 Future<void> tileSwap(NVR nvr, IPCamera ipCamera) async {
306 if (nvr != null && ipCamera != null) {
307 _controller = new VlcPlayerController();
308 int streamType =
309 await nvr.startStreamCamera(ipCamera, this.widget.resType);
310 await _controller.startStream(_tileNumber, streamType);
311 //_controller.initialize();
312 _nvr = nvr;
313 _ipCamera = ipCamera;
314
315 getFrame(this.widget.resType);
316 }
317 }
318
319/**s
320 * Method to set the tile number
321 */
322 void setTileNumber(int tileNumber) {
323 _tileNumber = this.widget.tileNumber;
324 }
325
326 /**
327 * Method to get Tile Number
328 */
329 int getTileNumber() {
330 return this.widget.tileNumber;
331 }
332
333/**
334 * Method to set the IP Camera object and NVR socket
335 *
336 * This will start the scheduler to get the frame
337 *
338 */
339 void setCameraObject(IPCamera ipCamera, RawSocket nvrSocket) {}
340
341/**
342 * Method to set the tile resoultion if it not set then it SD
343 */
344 void setTileRes(int res) {
345 _res = res;
346 }
347
348/**
349 * Method to stop the get frame call and remove the camera details
350 */
351 void removeCamera() {
352 _isCameraAttached = false;
353 }
354
355 Future<ui.Image> loadImage(List<int> img) async {
356 final Completer<ui.Image> completer = new Completer();
357 //ui.decodeImageFromPixels(img, 352, 288, ui.PixelFormat.rgba8888,
358 //(ui.Image img) {
359 //ui.decodeImageFromPixels(img, 2592, 1520, ui.PixelFormat.rgba8888, (ui.Image img) {
360 ui.decodeImageFromList(img, (ui.Image img) {
361 return completer.complete(img);
362 });
363 return completer.future;
364 }
365
366 Widget showCameraName() {
367 return Align(
368 alignment: Alignment.bottomLeft,
369 //bottom: this.widget.height - 10,
370 child: Padding(
371 padding: const EdgeInsets.only(
372 left: 2.0,
373 right: 2.0,
374 bottom: 2.0,
375 ),
376 child: new Container(
377 padding: new EdgeInsets.only(left: 5),
378 alignment: Alignment.centerLeft,
379 //width: this.widget.width,
380 height: 20,
381 color: Color.fromARGB(128, 0, 0, 0), //Colors.grey.withOpacity(0.5),
382 child: new Material(
383 color: Color.fromARGB(0, 0, 0, 0),
384 child: new Text(
385 _cameraName,
386 textAlign: TextAlign.start,
387 style: new TextStyle(
388 fontWeight: FontWeight.w200,
389 //fontSize: 14.0,
390 color: Colors.white,
391 ),
392 ),
393 ),
394 ),
395 ));
396 }
397
398 void showOverlay(BuildContext context) async {
399 if (buildCompleted == true) {
400 RenderBox box = key.currentContext.findRenderObject();
401
402 Offset position =
403 box.localToGlobal(Offset.zero); //this is global position
404 double y = position.dy;
405 double x = position.dx;
406 print("*****Posistion ${position.dx}, ${position.dy}");
407 if (overlayEntry != null) {
408 overlayEntry.remove();
409 }
410 OverlayState overlayState = Overlay.of(this.context);
411 overlayEntry = OverlayEntry(
412 builder: (context) => Positioned(
413 //Use a Material Widget
414 top: y + box.size.height - this.widget.height * 5 / 100,
415 left: x,
416
417 //bottom: this.widget.height - 10,
418 child: new Container(
419 padding: new EdgeInsets.only(left: 5),
420 alignment: Alignment.centerLeft,
421 width: this.widget.width,
422 height: this.widget.height * 5 / 100,
423 color:
424 Color.fromARGB(128, 0, 0, 0), //Colors.grey.withOpacity(0.5),
425 child: new Material(
426 color: Color.fromARGB(0, 0, 0, 0),
427 child: new Text(
428 _cameraName,
429 textAlign: TextAlign.start,
430 style: new TextStyle(
431 fontWeight: FontWeight.w200,
432 fontSize: 14.0,
433 color: Colors.white,
434 ),
435 ),
436 ),
437 )),
438 );
439
440 // overlayState.insert(overlayEntry);
441 //await Future.delayed(Duration(milliseconds: 500));
442
443 }
444 }
445
446/**
447 * Method create and return CustomPaint widget
448 */
449 Widget getPaintWidget() {
450 return new RepaintBoundary(
451 child: new CustomPaint(
452 isComplex: true,
453 willChange: false,
454 painter: new ImageEditor(
455 key: key,
456 image: _frame,
457 width: this.widget.width,
458 height: this.widget.height),
459 ));
460 }
461
462/**
463 * Method to return the tile widget.
464 */
465 GestureDetector getTileWidget(BuildContext context) {
466 //print('Tile Number inside widget = ${ this.widget.width}');
467 PopupMenu.context = context;
468 if (_isCameraAttached == true) {
469 DraggedData draggedData = new DraggedData(_nvr, _ipCamera);
470 draggedData.setTileSwapCallback(this.tileSwap);
471 return new GestureDetector(
472 onTap: () {
473 if (!this.widget.nvrManager.isDeviceBarVisiable()) {
474 this.widget.hideBottomNavigator();
475 }
476
477 setState(() {
478 widget.selectTile = !widget.selectTile;
479 });
480 },
481 onDoubleTap: () {
482 if (doubleClickDetected == false) {
483 Future(() async {
484 print("FullScreen***********MOde");
485 await stopVideoStreaming(_nvr, _ipCamera, this.widget.resType);
486 }).then((value) async {
487 _controller = new VlcPlayerController();
488 int streamType = await _nvr.startStreamCamera(
489 _ipCamera, StreamResolutionType.StreamResolutionHD);
490 await _controller.startStream(_tileNumber, streamType);
491 //_controller.initialize();
492 getFrame(StreamResolutionType.StreamResolutionHD);
493 doubleClickDetected = true;
494 });
495 } else {
496 Future(() async {
497 print("Stop Steaming");
498 await stopVideoStreaming(
499 _nvr, _ipCamera, StreamResolutionType.StreamResolutionHD);
500 }).then((value) async {
501 _controller = new VlcPlayerController();
502 int streamType =
503 await _nvr.startStreamCamera(_ipCamera, this.widget.resType);
504 await _controller.startStream(_tileNumber, streamType);
505 //_controller.initialize();
506 getFrame(this.widget.resType);
507 doubleClickDetected = false;
508 });
509 }
510 this.widget.fullScreenTileCallback(this.widget.tileNumber);
511 //setState(() {
512 // doubleClickDetected = true;
513 //});
514 },
515 // onHorizontalDragStart: (DragStartDetails start) {
516 // print(start.globalPosition.toString());
517 // },
518 // onHorizontalDragEnd: (DragEndDetails start) {
519 // print(start.toString());
520 // },
521 child: Stack(
522 children: <Widget>[
523 DragTarget<DraggedData>(
524 onWillAccept: (data) {
525 print(data);
526 NVR rNVR = data.getNVRObject();
527 IPCamera rIPcamera = data.getIPCameraObject();
528 if ((rNVR.getNVRName().compareTo(_nvr.getNVRName()) != 0) ||
529 (rIPcamera
530 .getCameraName()
531 .compareTo(_ipCamera.getCameraName()) !=
532 0)) {
533 print(
534 "True 1 --> ${rNVR.getNVRName()} ${rIPcamera.getCameraName()}");
535 print(
536 "True 2 --> ${_nvr.getNVRName()} ${_ipCamera.getCameraName()}");
537 return true;
538 } else {
539 print(
540 "False 1 --> ${rNVR.getNVRName()} ${rIPcamera.getCameraName()}");
541 print(
542 "False 2 --> ${_nvr.getNVRName()} ${_ipCamera.getCameraName()}");
543 return false;
544 }
545 },
546 onLeave: (data) {
547 print(data);
548 },
549 onAccept: (data) {
550 //print(data.toString());
551 NVR rNVR = _nvr;
552 IPCamera rIPcamera = _ipCamera;
553
554 _nvr = data.getNVRObject();
555 _ipCamera = data.getIPCameraObject();
556 Future(() async {
557 print("Stop Steaming");
558 await stopVideoStreaming(
559 rNVR, rIPcamera, this.widget.resType);
560 }).then((value) async {
561 Future(() async {
562 print(
563 "*************************************Dragged NVR ${_nvr.getNVRName()} IP Camera ${_ipCamera.getCameraName()}");
564 _controller = new VlcPlayerController();
565
566 int streamType = await _nvr.startStreamCamera(
567 _ipCamera, this.widget.resType);
568 await _controller.startStream(_tileNumber, streamType);
569 }).then((value) async {
570 //_controller.initialize();
571 getFrame(this.widget.resType);
572
573 TileSwapCallback tileSwapCallback =
574 data.getTileSwapCallback();
575 if (tileSwapCallback != null) {
576 tileSwapCallback(rNVR, rIPcamera);
577 }
578 });
579 });
580 },
581 builder: (xb, yb, z) {
582 return Container(
583 decoration: (widget.selectTile)
584 ? new BoxDecoration(color: Colors.yellow)
585 : new BoxDecoration(color: Colors.white),
586 width: double.infinity,
587 height: double.infinity,
588 padding: (widget.selectTile)
589 ? EdgeInsets.all(2.0)
590 : EdgeInsets.all(0.0),
591 child: Draggable<DraggedData>(
592 data: draggedData,
593 dragAnchor: DragAnchor.pointer,
594 feedback: Container(
595 width: 100,
596 height: 100,
597 child: Card(
598 key: key,
599 elevation: 1.0,
600 margin: EdgeInsets.all(1.0),
601 child: getPaintWidget()),
602 ),
603 onDragCompleted: () {
604 stopVideoStreaming(
605 _nvr, _ipCamera, this.widget.resType);
606 },
607 childWhenDragging: Image.asset(
608 "images/DTlogo.png",
609 fit: BoxFit.fitHeight,
610 frameBuilder: (BuildContext context, Widget child,
611 int frame, bool wasSynchronouslyLoaded) {
612 if (wasSynchronouslyLoaded) {
613 return child;
614 }
615 return AnimatedOpacity(
616 child: child,
617 opacity: frame == null ? 0 : 1,
618 duration: const Duration(seconds: 3),
619 curve: Curves.easeInOutExpo,
620 );
621 },
622 ),
623 child: Card(
624 key: key,
625 elevation: 1.0,
626 margin: EdgeInsets.all(1.0),
627 child: Listener(
628 onPointerSignal: (p){
629
630
631 off = p.localPosition;
632 print(off);
633
634 },
635 child: Container(
636 child: Transform.scale(
637 alignment: FractionalOffset(0.01, 0.020),
638 origin: off,
639 scale: squareScaleA,
640 child: Listener(
641 onPointerSignal: (p){
642 if(p.toString().split(':')[2].contains('-')){
643 if(_controllerA.isCompleted && _controllerA.isAnimating){
644
645 }else{
646 _controllerA.forward(from: 1);
647 }
648
649
650 }else{
651 if(_controllerA.isCompleted){
652 _controllerA.reverse();
653 }
654
655
656
657 }
658
659 },
660 child: getPaintWidget())),
661 )), //,
662 )),
663 );
664 },
665 ),
666 Align(
667 alignment: Alignment.topRight,
668 child: Container(
669 key: popupkey,
670 padding: EdgeInsets.only(right: 10.0),
671 height: 50.0,
672 width: 50.0,
673 color: Color.fromARGB(0, 0, 0, 0),
674 child: IconButton(
675 icon: Icon(Icons.menu, color: Colors.white),
676 onPressed: () {
677 // setState(() {});
678 // print('inside stack');
679 showPopUp();
680 }),
681 ),
682 ),
683 showCameraName(),
684 Visibility(
685 visible: widget.selectTile &&
686 widget.nvrManager.getLayout() == LayoutType.Layout1x1,
687 child: Joystick(
688 size: 100,
689 isDraggable: true,
690 backgroundColor:
691 Theme.of(context).primaryColor.withOpacity(0.5),
692 iconColor: Colors.white70,
693 ),
694 ),
695 Visibility(
696 visible: widget.selectTile &&
697 widget.nvrManager.getLayout() == LayoutType.Layout1x1,
698 child: ZoomWid(
699 onZoomInPressed: () {
700 print("zoom in");
701 },
702 onZoomOutPressed: () {
703 print("zoom out");
704 },
705 width: 60,
706 height: 130,
707 isDraggable: true,
708 iconColor: Colors.white70,
709 ),
710 )
711 ],
712 ),
713 );
714 } else {
715 return new GestureDetector(
716 onTap: () {
717 if (!this.widget.nvrManager.isDeviceBarVisiable()) {
718 this.widget.hideBottomNavigator();
719 }
720
721 setState(() {
722 widget.selectTile = !widget.selectTile;
723 });
724 },
725 onDoubleTap: () {
726 this.widget.fullScreenTileCallback(this.widget.tileNumber);
727 //setState(() {
728 // doubleClickDetected = true;
729 //});
730 },
731 // onHorizontalDragStart: (DragStartDetails start) {
732 // print(start..globalPosition.toString());
733 // },
734 // onHorizontalDragEnd: (DragEndDetails stop) {
735 // print(stop.toString());
736 // },
737 child: Stack(
738 children: <Widget>[
739 DragTarget<DraggedData>(
740 onWillAccept: (data) {
741 return true;
742 },
743 onAccept: (data) {
744 //print(data);
745
746 //_cameraName = "ipCameraName";
747 _nvr = data.getNVRObject();
748 _ipCamera = data.getIPCameraObject();
749 print(
750 "Dragged NVR ${_nvr.getNVRName()} IP Camera ${_ipCamera.getCameraName()} Stream Res ${this.widget.resType}");
751 _controller = new VlcPlayerController();
752 Future(() async {
753 int streamType = await _nvr.startStreamCamera(
754 _ipCamera, this.widget.resType);
755 await _controller.startStream(_tileNumber, streamType);
756 // _controller.initialize();
757 getFrame(this.widget.resType);
758 });
759 },
760 builder: (x, y, z) {
761 return Container(
762 width: double.infinity,
763 height: double.infinity,
764 //width: this.widget.width,
765 //height: this.widget.height,
766 decoration: (widget.selectTile)
767 ? new BoxDecoration(color: Colors.yellow)
768 : new BoxDecoration(color: Colors.white),
769 padding: (widget.selectTile)
770 ? EdgeInsets.all(2.0)
771 : EdgeInsets.all(0.0),
772 child: new Card(
773 color: Color.fromARGB(
774 255, 60, 101, 129), // Theme.of(context).accentColor,//
775 key: key,
776 elevation: 1.0,
777 margin: EdgeInsets.all(1.0),
778 child: Draggable<String>(
779 data: "data",
780 feedback: Container(
781 child: Card(
782 color: Colors.black,
783 ),
784 ),
785 childWhenDragging: Container(
786 width: double.infinity,
787 height: double.infinity,
788 child: Center(child: Text("Drag")),
789 ),
790 child: Image.asset(
791 "images/DTlogo.png",
792 fit: BoxFit.fitHeight,
793 frameBuilder: (BuildContext context, Widget child,
794 int frame, bool wasSynchronouslyLoaded) {
795 if (wasSynchronouslyLoaded) {
796 return child;
797 }
798 return AnimatedOpacity(
799 child: child,
800 opacity: frame == null ? 0 : 1,
801 duration: const Duration(seconds: 3),
802 curve: Curves.easeInOutExpo,
803 );
804 },
805 ),
806 ),
807 ),
808 );
809 },
810 ),
811 Align(
812 alignment: Alignment.topRight,
813 child: Container(
814 key: popupkey,
815 padding: EdgeInsets.only(right: 10.0),
816 height: 50.0,
817 width: 50.0,
818 color: Color.fromARGB(0, 0, 0, 0),
819 child: IconButton(
820 icon: Icon(Icons.menu, color: Colors.white),
821 onPressed: () {
822 // setState(() {});
823 showPopUp();
824 }),
825 ),
826 ),
827 showCameraName(),
828
829
830 /* Visibility(
831 visible: clickDetected,
832 child: Positioned(
833 left: positionB.dx,
834 top: positionB.dy ,
835 child: Draggable<void>(
836
837 child: Container(
838 width: 60,
839 height: 130,
840 decoration: BoxDecoration(
841 shape: BoxShape.rectangle,
842 border: Border.all(width: 3.0, color: Colors.white70),
843 borderRadius: BorderRadius.circular(50),
844 ),
845 child: Column(
846 mainAxisAlignment: MainAxisAlignment.spaceBetween,
847 children: <Widget>[
848 GestureDetector(
849 onTap: (){
850 //zoom in
851 },
852 child: Padding(
853 padding: EdgeInsets.all(8),
854 child: Icon(Icons.zoom_in,size: 35, color: Colors.white70)),
855 ),
856 GestureDetector(
857 onTap: (){
858 //zoom out
859 },
860 child: Padding(
861 padding: EdgeInsets.all(8),
862 child: Icon(Icons.zoom_out,size: 35, color: Colors.white70)),
863 ),
864 ],
865 ),
866 ),
867 feedback: Container(
868 width: 60,
869 height: 130,
870 decoration: BoxDecoration(
871 shape: BoxShape.rectangle,
872 border: Border.all(width: 3.0, color: Colors.white70),
873 borderRadius: BorderRadius.circular(50),
874 ),
875 child: Column(
876 mainAxisAlignment: MainAxisAlignment.spaceBetween,
877 children: <Widget>[
878 GestureDetector(
879 onTap: (){
880 //zoom in
881 },
882 child: Padding(
883 padding: EdgeInsets.all(8),
884 child: Icon(Icons.zoom_in,size: 35, color: Colors.white70)),
885 ),
886 GestureDetector(
887 onTap: (){
888 //zoom out
889 },
890 child: Padding(
891 padding: EdgeInsets.all(8),
892 child: Icon(Icons.zoom_out,size: 35, color: Colors.white70)),
893 ),
894 ],
895 ),
896 ),
897 onDraggableCanceled: (Velocity velocity, Offset offset){
898 setState(() {positionB = offset;print(positionB);});
899 },
900 ),
901 ),
902 ),*/
903 ],
904 ),
905 );
906 }
907 }
908
909 @override
910 Widget build(BuildContext context) {
911 return getTileWidget(context);
912 }
913
914 void showPopUp() {
915 print(" inside popup function");
916 PopupMenu menu = PopupMenu(
917 itemWidth: 110.0,
918 itemHeight: 60.0,
919 // backgroundColor: Colors.teal,
920 // lineColor: Colors.tealAccent,
921 maxColumn: 1,
922 enableDismiss: true,
923 items: [
924 MenuItem(
925 title: 'Select All',
926 image: Icon(Icons.select_all, color: Colors.white)),
927 MenuItem(
928 title: 'Unselect All',
929 image: Icon(CortexIcons.ungroup, color: Colors.white)),
930 MenuItem(
931 title: 'Instant Playback',
932 image: Icon(CortexIcons.PlayBack31, color: Colors.white)),
933 MenuItem(
934 title: 'Remove Video',
935 image: Icon(CortexIcons.CameraClose, color: Colors.white)),
936 ],
937 onClickMenu: (MenuItemProvider item) {
938 if (item.menuTitle == "Select All") {
939 print("Select All Clicked");
940 this.widget.selectAllTileCallback(true);
941 } else if (item.menuTitle == "Unselect All") {
942 print("Unselect All Clicked");
943 this.widget.selectAllTileCallback(false);
944 } else if (item.menuTitle == "Show Camera Name") {
945 print("Show Camera Name clicked");
946 } else if (item.menuTitle == "EPTZ") {
947 print("EPTZ Clicked");
948 } else if (item.menuTitle == "Instant Playback") {
949 print("Instant Playback Clicked");
950 } else if (item.menuTitle == "Swap Video") {
951 print("Swap Video Clicked");
952 } else if (item.menuTitle == "Remove Video") {
953 print("Remove Video Clicked");
954 if (_isCameraAttached) {
955 Future(() async {
956 print("Stop Steaming");
957 await stopVideoStreaming(_nvr, _ipCamera, this.widget.resType);
958 print("Camera removed");
959 });
960 } else {
961 print("Camera not connected");
962 }
963 }
964 setState(() {});
965 }, //onClickMenu,
966 onDismiss: () {},
967 ); //onDismiss);
968 menu.show(widgetKey: popupkey);
969 }
970}
971
972class ImageEditor extends CustomPainter {
973 ImageEditor({
974 this.key,
975 this.image,
976 this.width,
977 this.height,
978 });
979 GlobalKey key;
980 ui.Image image;
981 double width;
982 double height;
983
984 @override
985 void paint(Canvas canvas, Size size) {
986 RenderBox box = key.currentContext.findRenderObject();
987
988 Offset position = box.localToGlobal(Offset.zero); //this is global position
989 width = box.size.width;
990 height = box.size.height;
991 //print('*******${width}');
992 //print('*******${height}');
993 double y = position.dy;
994 double x = position.dx;
995
996 if (image != null) {
997 final Size imageSize =
998 Size(image.width.toDouble(), image.height.toDouble());
999 final Rect inputSubrect = const Offset(0.0, 0.0) & imageSize;
1000 Rect outputSubrect = const Offset(0.0, 0.0) & Size(width, height);
1001 canvas.drawImageRect(image, inputSubrect, outputSubrect, new Paint());
1002
1003 //canvas.drawImage(image, new Offset(0.0, 0.0), new Paint());
1004 }
1005 }
1006
1007 @override
1008 bool shouldRepaint(ImageEditor oldDelegate) {
1009 return this.image != oldDelegate.image;
1010 }
1011}