TreeRenderer.cs :  » Game » SokoSolve-Sokoban » SokoSolve » Common » Structures » Evaluation » Visualisation » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » SokoSolve Sokoban 
SokoSolve Sokoban » SokoSolve » Common » Structures » Evaluation » Visualisation » TreeRenderer.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using SokoSolve.Common.Math;

namespace SokoSolve.Common.Structures.Evaluation.Visualisation{
    /// <summary>
    /// Render a large tree, using depth
    /// </summary>
    public class TreeRenderer<T> where T : IEvaluationNode
    {
        /// <summary>
        /// Strong Contructor
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="graphics"></param>
        public TreeRenderer(Tree<T> tree, Graphics graphics)
        {
            this.tree = tree;
            this.graphics = graphics;
        }

        /// <summary>
        /// Initialise and Draw
        /// </summary>
        public void Draw()
        {
            Init();

            graphics.DrawRectangle(new Pen(Color.Black), windowRect.ToDrawingRect() );


            foreach (SegmentRegion region in regions)
            {
                foreach (TreeNode<T> node in region.nodes)
                {
                    VectorInt pos = GetPixelFromLogical(node);
                    RenderNode(pos.X, pos.Y, node);
                }
            }
        }

        class SegmentRegion
        {
            public int MaxRegionNodeWidth;
            public List<TreeNode<T>> nodes;
            public SizeInt Region;
            public TreeRenderer<T> parent;

            /// <summary>
            /// Find the position within the region
            /// </summary>
            /// <param name="node"></param>
            /// <returns></returns>
            public VectorInt GetNodePosition(TreeNode<T> node)
            {
                int idx = nodes.IndexOf(node);
                if (idx < 0) return VectorInt.Null;
                int layer = idx / MaxRegionNodeWidth;
                int offset = idx % MaxRegionNodeWidth;
                return new VectorInt(offset, layer);
            }

            /// <summary>
            /// Find the position within the region
            /// </summary>
            /// <param name="node"></param>
            /// <returns></returns>
            public VectorInt GetNodePixelPosition(TreeNode<T> node)
            {
                VectorInt logical = GetNodePosition(node);
                if (logical.Y == 0)
                {
                    return logical.Multiply(parent.nodeSize).Add(parent.globalOffset);
                }
                else
                {
                    return logical.Multiply(parent.nodeSize).Add(parent.globalOffset).Add(parent.indent*parent.nodeSize.Width, 0);
                }
                
            }
        }

        /// <summary>
        /// Get the drawing position for a node
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public VectorInt GetPixelFromLogical(TreeNode<T> node)
        {
            if (node.Depth >= regions.Count) return VectorInt.Null;

            SegmentRegion region = regions[node.Depth];
            if (region == null) return VectorInt.Null; 

            int height = 0;
            for (int cc = 0; cc < node.Depth; cc++)
            {
                height += regions[cc].Region.Height;
            }

            return region.GetNodePixelPosition(node).Add(0, height);
        }


        /// <summary>
        /// From a pixel position find the node
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public TreeNode<T> GetNodeFromPixel(VectorInt position)
        {
            VectorInt rel = position.Subtract(windowRect.TopLeft);
            if (rel.X < 0 || rel.Y < 0) return null;

            VectorInt cell = rel.Divide(nodeSize.ToVectorInt);
            
            // Lookup segment
            if (cell.Y >= segments.Segments.Count) return null;
            if (segments.Segments[cell.Y] == null) return null;
            if (cell.X >= segments.Segments[cell.Y].Count) return null;

            return segments.Segments[cell.Y].Nodes[cell.X];
        }

        /// <summary>
        /// Render a Node
        /// </summary>
        /// <param name="x"></param>
        /// <param name="ccy"></param>
        /// <param name="node"></param>
        virtual protected void RenderNode(int x, int ccy, TreeNode<T> node)
        {
            graphics.FillRectangle(GetBrush(node), x, ccy, nodeSize.Width, nodeSize.Height);
            graphics.DrawRectangle(GetPen(node), x, ccy, nodeSize.Width, nodeSize.Height);
        }

        /// <summary>
        /// Get a brush for a node fill
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        virtual protected Brush GetBrush(TreeNode<T> node)
        {
            if (node.Data.IsChildrenEvaluated) return new SolidBrush(Color.Black);
            if (node.Data.IsStateEvaluated) return new SolidBrush(Color.Blue);

            return new SolidBrush(Color.Green);
        }

        /// <summary>
        /// Get a pen for the node border
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        virtual protected Pen GetPen(TreeNode<T> node)
        {
           if (node.Data.IsChildrenEvaluated) return new Pen(Color.Black);
           if (node.Data.IsStateEvaluated) return new Pen(Color.Blue);

            return new Pen(Color.WhiteSmoke);
        }

        /// <summary>
        /// Initialise
        /// </summary>
        private void Init()
        {
            segments = new TreeSegmenter<T>(tree, maxDepth, 2000);
            segments.PerformSegment();   

            regions = new List<SegmentRegion>(segments.Segments.Count);

            foreach (TreeSegmenter<T>.TreeSegment segment in segments.Segments)
            {
                SegmentRegion region = new SegmentRegion();
                region.parent = this;
                region.MaxRegionNodeWidth = maxWidth;
                region.Region = new SizeInt(maxWidth*nodeSize.Width+ 50, (segment.Count / maxWidth)*nodeSize.Height);
                region.nodes = segment.Nodes;
                
                regions.Add(region);
            }
        }

        public TreeNode<T> GetNode(int x, int y)
        {
            return GetNodeFromPixel(new VectorInt(x, y));
        }

        public RectangleInt WindowRect
        {
            get { return windowRect; }
            set { windowRect = value; }
        }

        public SizeInt NodeSize
        {
            get { return nodeSize; }
            set { nodeSize = value; }
        }

        public int MaxDepth
        {
            get { return maxDepth; }
            set { maxDepth = value; }
        }

        public int MaxWidth
        {
            get { return maxWidth; }
            set { maxWidth = value; }
        }

        

        private RectangleInt windowRect = new  RectangleInt(new VectorInt(0,0), new SizeInt(640, 480));
        private SizeInt nodeSize = new SizeInt(4, 4);   // with padding

        private Tree<T> tree;
        protected Graphics graphics;
        private TreeSegmenter<T> segments;
        private List<SegmentRegion> regions;
        private int maxDepth = 150;
        private int maxWidth = 150;
        VectorInt globalOffset = new VectorInt(1,20);
        private int indent = 3;
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.