Example #1
0
        // Create a new larger zoomable popup so that the user can inspect the image details
        private void Canvas_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            int height = 480;

            if (sender is Canvas canvas && canvas.Tag != null)
            {
                Image   image   = EpisodePopup.CreateImage((ImageRow)canvas.Tag, 0, height);
                Canvas  clone   = CreateCanvasWithBoundingBoxesAndImage(image, height, 0, ((ImageRow)canvas.Tag).ID);
                Zoombox zoombox = CreateZoombox();
                zoombox.Content = clone;

                this.InspectionPopup.Child     = zoombox;
                this.InspectionPopup.Placement = PlacementMode.MousePoint;
                this.InspectionPopup.IsOpen    = true;
            }
        }
Example #2
0
        public void Show(bool isVisible, int maxNumberImagesToDisplay)
        {
            ImageRow currentImageRow = timelapseWindow?.DataHandler?.ImageCache?.Current;
            TimeSpan timeThreshold   = timelapseWindow.State.EpisodeTimeThreshold;

            if (isVisible == false || currentImageRow == null || FileDatabase == null)
            {
                // Hide the popup if asked or if basic data isn't available, including deleting the children
                this.IsOpen = false;
                this.Child  = null;
                return;
            }

            // Images or placeholders will be contained in a horizontal stack panel, which in turn is the popup's child
            StackPanel sp = new StackPanel
            {
                Orientation = Orientation.Horizontal
            };

            this.Child = sp;

            double width = 0;  // Used to calculate the placement offset of the popup relative to the placement target
            double height;

            // Add a visual marker to show the position of the label in the image list
            Label label = EpisodePopup.CreateLabel("^", this.ImageHeight);

            label.VerticalAlignment = VerticalAlignment.Top;
            width += label.Width;
            height = label.Height;
            sp.Children.Add(label);

            int       margin = 2;
            FileTable fileTable; // To hold the results of the database selection as a table of ImageRows

            // We will only consider images whose relative path is the same as the current file
            string relativePath = currentImageRow.RelativePath;

            // Calculate the lower and upper extent of the range of dates we should examine
            // The maximum date range we need to consider would be the current date plus/minus the (time threshold * the number of images we could display),
            // While this could produce more hits than we need, it should give us a relatively short table of possible candidates
            DateTime lowerDateTime  = currentImageRow.DateTime - TimeSpan.FromTicks(timeThreshold.Ticks * maxNumberImagesToDisplay);
            DateTime upperDateTime  = currentImageRow.DateTime + TimeSpan.FromTicks(timeThreshold.Ticks * maxNumberImagesToDisplay);
            string   slowerDateTime = DateTimeHandler.ToStringDatabaseDateTime(lowerDateTime);
            string   supperDateTime = DateTimeHandler.ToStringDatabaseDateTime(upperDateTime);

            // Get a table of files (sorted by datetime) with that relative path which falls between the lower and upper date range
            DataTable dt = this.FileDatabase.GetIDandDateWithRelativePathAndBetweenDates(relativePath, slowerDateTime, supperDateTime);

            // Find the current image in that table by its ID
            int rowWithCurrentImageRowID = -1;
            int availableRows            = dt.Rows.Count;

            for (int i = 0; i < availableRows; i++)
            {
                if (Convert.ToInt64(dt.Rows[i][0]) == currentImageRow.ID)
                {
                    rowWithCurrentImageRowID = i;
                    break;
                }
            }

            // From that current image, alternate between going to the previous/next row.
            // If the date difference between alternating successive images is less than the time threshold,
            // display it.
            int      goBackwardsRow        = rowWithCurrentImageRowID - 1;
            int      goForwardsRow         = rowWithCurrentImageRowID + 1;
            int      imagesLeftToDisplay   = maxNumberImagesToDisplay;
            DateTime lastBackwardsDateTime = currentImageRow.DateTime;
            DateTime lastForwardsDateTime  = currentImageRow.DateTime;

            while (true && (goBackwardsRow >= 0 || goForwardsRow < availableRows))
            {
                // Abort when there is no more work to do
                if (imagesLeftToDisplay <= 0)
                {
                    break;
                }

                // Start on the left
                if (goBackwardsRow >= 0)
                {
                    // Add a popup image to the left of the caret
                    using (fileTable = this.FileDatabase.SelectFileInDataTableById(dt.Rows[goBackwardsRow][0].ToString()))
                    {
                        if (fileTable.Any())
                        {
                            if ((lastBackwardsDateTime - fileTable[0].DateTime).Duration() <= timeThreshold)
                            {
                                Image image = EpisodePopup.CreateImage(fileTable[0], margin, this.ImageHeight);
                                width += image.Source.Width;
                                height = Math.Max(height, image.Source.Height);

                                // Create a canvas containing the image and bounding boxes (if detections are on)
                                sp.Children.Insert(0, CreateCanvasWithBoundingBoxesAndImage(image, height, margin, fileTable[0].ID));
                                imagesLeftToDisplay--;
                                lastBackwardsDateTime = fileTable[0].DateTime;
                            }
                            else
                            {
                                // Stop searching backwards
                                goBackwardsRow = -1;
                            }
                        }
                    }
                    goBackwardsRow--;
                }

                // Now try to add a popup image to the right if we still have some more  images left to display
                if (goForwardsRow < availableRows && imagesLeftToDisplay > 0)
                {
                    using (fileTable = this.FileDatabase.SelectFileInDataTableById(dt.Rows[goForwardsRow][0].ToString()))
                    {
                        if (fileTable.Any())
                        {
                            if ((lastForwardsDateTime - fileTable[0].DateTime).Duration() <= timeThreshold)
                            {
                                Image image = EpisodePopup.CreateImage(fileTable[0], margin, this.ImageHeight);
                                width += image.Source.Width;
                                height = Math.Max(height, image.Source.Height);

                                // Create a canvas containing the image and bounding box
                                sp.Children.Add(CreateCanvasWithBoundingBoxesAndImage(image, height, margin, fileTable[0].ID));
                                imagesLeftToDisplay--;
                                lastBackwardsDateTime = fileTable[0].DateTime;
                            }
                            else
                            {
                                // Stop searching forwards
                                goForwardsRow = availableRows;
                            }
                        }
                    }
                    goForwardsRow++;
                }
            }

            label.Height = Math.Max(label.Height, height); // So it extends to the top of the popup
            // Position and open the popup so it appears horizontallhy centered just above the cursor
            this.HorizontalOffset = this.markableCanvas.ActualWidth / 2.0 - width / 2.0;
            this.VerticalOffset   = -height - 2 * margin;
            this.IsOpen           = true;

            // Cleanup
            dt.Dispose();
        }