示例#1
0
        /// <summary>
        /// Reserves a rectangular area for the given image in this.Maze.
        /// The chosen location is remembered in this.imageLocations.
        /// Returns true if the reservation was successful.
        /// </summary>
        /// <param name="contourImage"></param>
        /// <returns></returns>
        private bool AddImage(ContourImage contourImage)
        {
            Image img     = contourImage.DisplayedImage;
            int   padding = MazePainter.ApplyScaleFactor(8) + this.wallWidth;
            int   sqW     = (img.Width + padding) / this.gridWidth + 1;
            int   sqH     = (img.Height + padding) / this.gridWidth + 1;

            int xOffsetImg = (sqW * gridWidth - img.Width) / 2;
            int yOffsetImg = (sqH * gridWidth - img.Height) / 2;

            OutlineShape shape = (ContourImage.DisplayProcessedImage ? contourImage.GetCoveredShape(gridWidth, wallWidth, xOffsetImg, yOffsetImg) : null);

            Rectangle rect;

            if (Maze.ReserveRectangle(sqW, sqH, 2, shape, out rect))
            {
                // Remember the image data and location.  It will be painted in PaintMaze().
                int x = rect.X * gridWidth + xOffset + xOffsetImg;
                int y = rect.Y * gridWidth + yOffset + yOffsetImg;
                imageLocations.Add(new Rectangle(x, y, img.Width, img.Height));
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#2
0
        public void Setup()
        {
            if (painter.HasBufferAlternate)
            {
                // the Setup() method was already executed for creating the alternate buffer
                this.Invalidate();
                return;
            }

            if (settingsData != null)
            {
                this.TakeParametersFrom(settingsData);
                return;
            }

            #region Set up the painter.

            painter.Setup();

            MazePainter.SuggestWidths(painter.GridWidth, painter.VisibleWalls, out int squareWidth, out int pathWidth, out int wallWidth);

            this.Setup(squareWidth, wallWidth, pathWidth);

            #endregion
        }
        /// <summary>
        /// Constructor.
        /// Creates and starts an AriadneController.
        /// </summary>
        /// <param name="windowHandleArg"></param>
        private ScreenSaverPreviewController(string windowHandleArg)
        {
            // Get the window in which we are supposed to paint.
            this.parentHwnd      = (IntPtr)UInt32.Parse(windowHandleArg);
            this.targetRectangle = Platform.GetClientRectangle(parentHwnd);
            //Log.WriteLine("targetRectangle = " + targetRectangle);

            // Create a MazePainter.
            this.targetGraphics = Graphics.FromHwnd(parentHwnd);
            this.painter        = new MazePainter(targetGraphics, targetRectangle, this as IMazePainterClient, true);

            // Create and display the first maze.
            this.OnNew(null, null);

            // Create an AriadneController.
            SolverController controller = new SolverController(null, painter, null);

            this.ariadneController       = new AriadneController(this, controller);
            ariadneController.RepeatMode = true;

            // Start the AriadneController.
            ariadneController.Start();

            // Start a supervisor timer.
            CreateSupervisorTimer();
        }
示例#4
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public SolverController(
     IMazeForm mazeForm, MazePainter mazePainter,
     ProgressBar visitedProgressBar)
 {
     this.mazeForm           = mazeForm;
     this.mazePainter        = mazePainter;
     this.visitedProgressBar = visitedProgressBar;
 }
        /// <summary>
        /// Will stop the AriadneController and de-construct this object.
        /// </summary>
        private void TargetWindowClosing(object sender, FormClosingEventArgs e)
        {
            // When the form is closed, stop the controller.
            ariadneController.Stop();

            // Discard all member variables.
            this.ariadneController = null;
            this.painter           = null;
        }
示例#6
0
        /// <summary>
        /// Reserves a region of the maze covered by the coveringControl.
        /// This MazeUserControl and the coveringControl must have the same Parent, i.e. a common coordinate system.
        /// </summary>
        /// <param name="coveringControl"></param>
        /// <exception cref="ArgumentException">The given Control has a differnent Parent.</exception>
        public bool ReserveArea(Control coveringControl)
        {
            if (coveringControl.Parent != this.Parent)
            {
                throw new ArgumentException("Must have the same Parent.", nameof(coveringControl));
            }

            // Dimensions of the control in square coordinates.
            int x, y, w, h;

            x = XCoordinate(coveringControl.Left, true);
            y = YCoordinate(coveringControl.Top, true);

            w = 1 + XCoordinate(coveringControl.Right - 1, false) - x;
            h = 1 + YCoordinate(coveringControl.Bottom - 1, false) - y;

            int padding = wallWidth + MazePainter.ApplyScaleFactor(6);

            if (0 < x && x + w < Maze.XSize)
            {
                w = 1 + (coveringControl.Width + padding) / gridWidth;
            }
            if (0 < y && y + h < Maze.YSize)
            {
                h = 1 + (coveringControl.Height + padding) / gridWidth;
            }

            bool result = Maze.ReserveRectangle(x, y, w, h, null);

            // Move the control into the center of the reserved area.
            if (result)
            {
                int cx = coveringControl.Left;
                int cy = coveringControl.Top;

                if (0 < x && x + w < Maze.XSize)
                {
                    cx  = this.Location.X + xOffset + x * gridWidth;
                    cx += 1 + (w * gridWidth - wallWidth - coveringControl.Width) / 2;
                }
                if (0 < y && y + h < Maze.YSize)
                {
                    cy  = this.Location.Y + yOffset + y * gridWidth;
                    cy += 1 + (h * gridWidth - wallWidth - coveringControl.Height) / 2;
                }

                // Adjust the control's location
                coveringControl.Location = new Point(cx, cy);
                controlLocations.Add(coveringControl.Bounds);
            }

            return(result);
        }
示例#7
0
        /// <summary>
        /// Create controllers for our maze's embedded mazes.
        /// </summary>
        private void CreateEmbeddedSolvers()
        {
            this.mazePainter.ClearSharedPainters();

            foreach (Maze embeddedMaze in Maze.EmbeddedMazes)
            {
                MazePainter embeddedPainter = this.mazePainter.CreateSharedPainter(embeddedMaze);
                embeddedPainter.BlinkingCounter = -1;
                EmbeddedSolverController embeddedController = new EmbeddedSolverController(this, embeddedPainter);
                this.embeddedControllers.Add(embeddedController);

                embeddedController.StartDelayRelativeDistance = 0.2 + 0.4 * Maze.Random.NextDouble();
            }
        }
        /// <summary>
        /// Creates a new maze.
        /// </summary>
        public void OnNew(object sender, EventArgs e)
        {
            #region Set up the painter.

            painter.Setup();

            int squareWidth;
            int pathWidth;
            int wallWidth;
            MazePainter.SuggestWidths(painter.GridWidth, painter.VisibleWalls, out squareWidth, out pathWidth, out wallWidth);

            painter.Setup(squareWidth, wallWidth, pathWidth);

            #endregion

            painter.Reset();
            painter.BlinkingCounter = 0;

            // Create and display a maze.
            painter.CreateMaze(null);
            painter.PaintMaze(null);
        }
        /// <summary>
        /// Creates a ScreenSaverController instance,
        /// draws an initial maze
        /// and starts an AriadneController.
        /// </summary>
        /// <param name="windowHandleArg">The MazePainter will draw on this window.</param>
        /// <remarks>
        /// If this is not the primary screen, no cotroller is started,
        /// the application will terminate and the screen will stay blank.
        /// </remarks>
        public ScreenSaverController(string windowHandleArg)
        {
            #region Evaluate the given window's properties.
            var windowHandle    = (IntPtr)UInt32.Parse(windowHandleArg);
            var targetGraphics  = Graphics.FromHwnd(windowHandle);
            var targetRectangle = Platform.GetClientRectangle(windowHandle);
            //Log.WriteLine("targetRectangle = " + targetRectangle, true); // {X=0,Y=0,Width=1366,Height=768}
            #endregion

#if true
            #region Blank secondary screen(s).
            // ... because more than one of these mazes is just too distracting.  :-)
            if (!IsOnPrimaryScreen(windowHandle))
            {
                // We don't have to do anything, really.
                // xscreensaver has given us a blank (black) window and we may
                // terminate the application
                //Log.WriteLine("Goodbye on " + targetRectangle, true);
                //Application.Run();
                Application.Exit();
            }
            #endregion
#endif

            // Create an ImageLoader, now that it is clear that we will need it.
            Directory.ResultValidForSeconds = -1;
            var imageLoader = ImageLoader.GetScreenSaverImageLoader(Screen.PrimaryScreen.Bounds);

            #region Create a MazePainter.
            this.painter = new MazePainter(targetGraphics, targetRectangle, this as IMazePainterClient);
            #endregion

            #region Create a MazeUserControl.
            this.mazeUserControl             = new MazeUserControl(painter, targetRectangle.Size);
            this.mazeUserControl.ImageLoader = imageLoader;
            this.mazeUserControl.MazeForm    = this;
            #endregion

            #region Apply some registered options.
            if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_PAINT_ALL_WALLS) == false)
            {
                painter.RandomizeWallVisibility = true;
            }
            ContourImage.DisplayProcessedImage = RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_IMAGE_SUBTRACT_BACKGROUND);

            // Load background images.
            if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_BACKGROUND_IMAGES))
            {
                string imageFolder = RegisteredOptions.GetStringSetting(RegisteredOptions.OPT_BACKGROUND_IMAGE_FOLDER);
                if (imageFolder == "")
                {
                    imageFolder = RegisteredOptions.GetStringSetting(RegisteredOptions.OPT_IMAGE_FOLDER);
                }
                int percentage = ((RegisteredOptions.GetIntSetting(RegisteredOptions.OPT_IMAGE_NUMBER) > 0) ? 20 : 100);
                painter.CreateBackgroundImageLoader(imageFolder, percentage);
            }

            if (RegisteredOptions.GetBoolSetting(RegisteredOptions.OPT_SHOW_DETAILS_BOX))
            {
                this.infoPanelPainter = new InfoPanelPainter(painter);
            }
            #endregion

            // Create and display the first maze.
            this.OnNew(null, null);

            #region Create and start an AriadneController.
            SolverController controller = new SolverController(this, painter, null);
            this.ariadneController       = new AriadneController(this, controller);
            ariadneController.RepeatMode = true;
            ariadneController.Start();
            #endregion
        }
示例#10
0
 /// <summary>
 /// Create an object that provides useful functionality to a ScreenSaverController.
 /// Note: This object will not be displayed on any form.
 /// </summary>
 public MazeUserControl(MazePainter painter, Size size)
 {
     this.painter  = painter;
     this.Location = new Point(0, 0);
     this.Size     = size;
 }
示例#11
0
 public MazeUserControl()
 {
     InitializeComponent();
     this.painter = new MazePainter(this.CreateGraphics(), this.DisplayRectangle, this as IMazePainterClient);
 }
示例#12
0
        /// <summary>
        /// Update the other controls to reflect the derived changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDataChanged(object sender, EventArgs e)
        {
            // Avoid an infinite recursion
            if (_busyOnDataChanged)
            {
                return;
            }

            try
            {
                _busyOnDataChanged = true;

                #region Layout data

                if (data.AutoGridWidthModified)
                {
                    if (!data.AutoGridWidth)
                    {
                        data.AutoSquareWidth = true;
                        data.AutoPathWidth   = true;
                        data.AutoWallWidth   = true;
                    }
                }
                if (data.AutoSquareWidthModified || data.AutoPathWidthModified || data.AutoWallWidthModified)
                {
                    if (!data.AutoSquareWidth || !data.AutoPathWidth || !data.AutoWallWidth)
                    {
                        data.AutoGridWidth = true;
                    }
                }

                bool gridWithModifiedManually = data.GridWidthModified;

                if (data.GridWidthModified)
                {
                    data.AutoGridWidth = false;

                    int  squareWidth, pathWidth, wallWidth;
                    bool visibleWalls = (data.WallVisibility != AriadneSettingsData.WallVisibilityEnum.Never);
                    MazePainter.SuggestWidths(data.GridWidth, visibleWalls, out squareWidth, out pathWidth, out wallWidth);

                    data.WallWidth   = wallWidth;
                    data.SquareWidth = squareWidth;
                    data.PathWidth   = pathWidth;
                }
                if (data.PathWidthModified)
                {
                    data.AutoPathWidth = gridWithModifiedManually;
                    data.SquareWidth   = Math.Max(data.PathWidth, data.SquareWidth);
                }
                if (data.SquareWidthModified)
                {
                    data.AutoSquareWidth = gridWithModifiedManually;
                    data.PathWidth       = Math.Min(data.PathWidth, data.SquareWidth);
                    data.GridWidth       = Math.Min(data.SquareWidth + data.WallWidth, MazePainter.MaxGridWidth);
                    data.WallWidth       = data.GridWidth - data.SquareWidth;
                }
                if (data.WallWidthModified)
                {
                    data.AutoWallWidth = gridWithModifiedManually;
                    data.GridWidth     = Math.Min(data.SquareWidth + data.WallWidth, MazePainter.MaxGridWidth);
                    data.SquareWidth   = data.GridWidth - data.WallWidth;
                }

                if (gridWithModifiedManually || (data.AutoGridWidthModified && !data.AutoGridWidth))
                {
                    data.AutoSquareWidth = true;
                    data.AutoPathWidth   = true;
                    data.AutoWallWidth   = true;
                }
                if (!data.AutoSquareWidth || !data.AutoPathWidth || !data.AutoWallWidth)
                {
                    data.AutoGridWidth = true;
                }

                #endregion

                #region Shape data

                if (data.MazeWidthModified)
                {
                    data.AutoMazeWidth = false;
                }
                if (data.MazeHeightModified)
                {
                    data.AutoMazeHeight = false;
                }
                if (data.SeedModified)
                {
                    data.AutoSeed = false;
                }

                #endregion

                CalculateResultingArea();
                data.ClearModifedFlags();
                dataBindingSource.ResetCurrentItem();
            }
            finally
            {
                _busyOnDataChanged = false;
            }
        }
示例#13
0
        public InfoPanelPainter(MazePainter mazePainter)
        {
            this.mazePainter = mazePainter;

            #region Create Control objects

            outerInfoPanel = new Panel
            {
                Location  = new Point(0, 0), // will be relocated later
                Size      = new Size(444, 44),
                Padding   = new Padding(3),
                BackColor = Control.DefaultBackColor,
            };

            innerInfoPanel = new Panel
            {
                Location    = new Point(3, 3),
                Size        = new Size(438, 38),
                BorderStyle = BorderStyle.Fixed3D,
                Padding     = new Padding(2),
                //BackColor = Color.Beige,
            };

            infoLabelCaption = new Label
            {
                Location  = new Point(2, 1),
                Size      = new Size(430, 16),
                Padding   = new Padding(0),
                Text      = "Caption",
                TextAlign = ContentAlignment.MiddleCenter,
            };

            infoLabelStatus = new Label
            {
                Location  = new Point(2, 17),
                Size      = new Size(430, 16),
                Padding   = new Padding(0),
                Text      = "Status",
                TextAlign = ContentAlignment.MiddleCenter,
            };

            outerInfoPanel.Controls.Add(innerInfoPanel);
            innerInfoPanel.Controls.Add(infoLabelCaption);
            innerInfoPanel.Controls.Add(infoLabelStatus);

            innerInfoPanel.ResumeLayout(false);
            outerInfoPanel.ResumeLayout(true);

            #endregion

            #region Create a bitmap for rendering the Controls

            //targetGraphics = graphics;
            bitmap         = new Bitmap(outerInfoPanel.Size.Width, outerInfoPanel.Size.Height);
            bitmapGraphics = Graphics.FromImage(bitmap);

            // Approximate a standard label's settings
            bitmapGraphics.SmoothingMode     = SmoothingMode.AntiAlias;
            bitmapGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            bitmapGraphics.PixelOffsetMode   = PixelOffsetMode.HighQuality;
            bitmapGraphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

            #endregion

            Paint();
        }