aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/GraphicObjects/Grid.cs
blob: 57ceda5eb0a0e3a02c47009718ce35e377fcfb23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.ComponentModel;

namespace Crow
{
	/// <summary>
	/// Simple grid container
	/// Allow symetric placement of children on a grid,
	/// excedental child (above grid sizing) are ignored
	/// and invisible child keep their place in the grid
	/// </summary>
    public class Grid : Group
    {
		#region CTOR
		public Grid()
			: base()
		{            
		}
		#endregion

		#region Private fields
        int _spacing;
		int _columnCount;
		int _rowCount;
		#endregion

		public override void AddChild (GraphicObject child)
		{
			base.AddChild (child);
			this.RegisterForLayouting (LayoutingType.ArrangeChildren);
		}
		public override void RemoveChild (GraphicObject child)
		{
			base.RemoveChild (child);
			this.RegisterForLayouting (LayoutingType.ArrangeChildren);
		}

		#region Public Properties
        [XmlAttributeAttribute()][DefaultValue(2)]
        public int Spacing
        {
			get { return _spacing; }
            set { _spacing = value; }
        }
        [XmlAttributeAttribute()][DefaultValue(1)]
        public virtual int ColumnCount
        {
            get { return _columnCount; }
            set { 
				if (_columnCount == value)
					return;

				_columnCount = value; 

				NotifyValueChanged ("ColumnCount", ColumnCount);
				this.RegisterForLayouting (LayoutingType.ArrangeChildren);
			}
        }
		[XmlAttributeAttribute()][DefaultValue(1)]
		public virtual int RowCount
		{
			get { return _rowCount; }
			set { 
				if (_rowCount == value)
					return;

				_rowCount = value; 

				NotifyValueChanged ("RowCount", RowCount);
				this.RegisterForLayouting (LayoutingType.ArrangeChildren);
			}
		}
		public virtual int CaseWidth {
			get { return (Slot.Width - (ColumnCount - 1) * Spacing) / ColumnCount; }
		}
		public virtual int CaseHeight {
			get { return (Slot.Height - (RowCount - 1) * Spacing) / RowCount; }
		}

		#endregion

		#region GraphicObject Overrides
//		protected override Size measureRawSize ()
//		{
//			Size tmp = new Size ();
//
//			foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) {
//				tmp.Width = Math.Max (tmp.Width, c.Slot.Width);
//				tmp.Height = Math.Max (tmp.Height, c.Slot.Height);
//			}
//
//			tmp.Width *= (ColumnCount - 1) * Spacing / ColumnCount;;
//			tmp.Height *= (RowCount - 1) * Spacing / RowCount;
//			tmp.Width += 2 * Margin;
//			tmp.Height += 2 * Margin;
//
//			return tmp;
//		}
		public virtual void ComputeChildrenPositions()
		{
			int slotWidth = CaseWidth;
			int slotHeight = CaseHeight;
			for (int curY = 0; curY < RowCount; curY++) {
				for (int curX = 0; curX < ColumnCount; curX++) {
					int idx = curY * ColumnCount + curX;
					if (idx >= Children.Count)
						return;
					GraphicObject c = Children [idx];
					if (!c.Visible)
						continue;
					//ensure Item are not realigned
					c.HorizontalAlignment = HorizontalAlignment.Left;
					c.VerticalAlignment = VerticalAlignment.Top;
					c.Left = curX * (slotWidth + Spacing);
					c.Top = curY * (slotHeight + Spacing);
					c.Width = slotWidth;
					c.Height = slotHeight;
				}
			}
		}


		public override bool UpdateLayout (LayoutingType layoutType)
		{
			RegisteredLayoutings &= (~layoutType);

			if (layoutType == LayoutingType.ArrangeChildren) {				

				ComputeChildrenPositions ();

				//if no layouting remains in queue for item, registre for redraw
				if (RegisteredLayoutings == LayoutingType.None && IsDirty)
					CurrentInterface.EnqueueForRepaint (this);
				
				return true;
			}

			return base.UpdateLayout(layoutType);
		}
		#endregion

    
	}
}