source: 2014/24/EemeliK/Zombieland/Jypeli/GameObjects/HorizontalLayout.cs @ 5974

Revision 5974, 8.5 KB checked in by empaheik, 4 years ago (diff)
Line 
1#region MIT License
2/*
3 * Copyright (c) 2009-2012 University of Jyväskylä, Department of Mathematical
4 * Information Technology.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#endregion
25
26/*
27 * Authors: Tomi Karppinen, Tero Jäntti
28 */
29
30using System.Collections.Generic;
31using System.ComponentModel;
32
33namespace Jypeli
34{
35    /// <summary>
36    /// Asettelee widgetit riviin vaakasuunnassa.
37    /// </summary>
38    public class HorizontalLayout : ILayout
39    {
40        private Sizing _horizontalSizing;
41        private Sizing _verticalSizing;
42        private Vector _preferredSize;
43        private double _spaceRequestedByExpandingObjects;
44        private double _spaceRequestedByFixedSizeObjects;
45        private double _spacing = 0;
46        private double _topPadding = 0;
47        private double _bottomPadding = 0;
48        private double _leftPadding = 0;
49        private double _rightPadding = 0;
50
51        [EditorBrowsable(EditorBrowsableState.Never)]
52        public GameObject Parent { get; set; }
53
54        /// <summary>
55        /// Olioiden väliin jäävä tyhjä tila.
56        /// </summary>
57        public double Spacing
58        {
59            get { return _spacing; }
60            set { _spacing = value; NotifyParent(); }
61        }
62
63        /// <summary>
64        /// Yläreunaan jäävä tyhjä tila.
65        /// </summary>
66        public double TopPadding
67        {
68            get { return _topPadding; }
69            set { _topPadding = value; NotifyParent(); }
70        }
71
72        /// <summary>
73        /// Alareunaan jäävä tyhjä tila.
74        /// </summary>
75        public double BottomPadding
76        {
77            get { return _bottomPadding; }
78            set { _bottomPadding = value; NotifyParent(); }
79        }
80
81        /// <summary>
82        /// Vasempaan reunaan jäävä tyhjä tila.
83        /// </summary>
84        public double LeftPadding
85        {
86            get { return _leftPadding; }
87            set { _leftPadding = value; NotifyParent(); }
88        }
89
90        /// <summary>
91        /// Oikeaan reunaan jäävä tyhjä tila.
92        /// </summary>
93        public double RightPadding
94        {
95            get { return _rightPadding; }
96            set { _rightPadding = value; NotifyParent(); }
97        }
98
99        private void NotifyParent()
100        {
101            if (Parent != null)
102            {
103                Parent.NotifyParentAboutChangedSizingAttributes();
104            }
105        }
106
107        /// <summary>
108        /// Luo uuden asettelijan.
109        /// </summary>
110        public HorizontalLayout()
111        {
112        }
113
114        [EditorBrowsable(EditorBrowsableState.Never)]
115        public void UpdateSizeHints(IList<GameObject> objects)
116        {
117            if (objects.Count == 0)
118                return;
119
120            double maxHeight = 0;
121            double widthOfExpandingObjects = 0;
122            double widthOfFixedSizeObjects = 0;
123            Sizing horizontalSizing = Sizing.FixedSize;
124            Sizing verticalSizing = Sizing.FixedSize;
125
126            foreach (var o in objects)
127            {
128                if (o.PreferredSize.Y > maxHeight)
129                {
130                    maxHeight = o.PreferredSize.Y;
131                }
132
133                if (o.HorizontalSizing == Sizing.Expanding)
134                {
135                    widthOfExpandingObjects += o.PreferredSize.X;
136                    horizontalSizing = Sizing.Expanding;
137                }
138                else if (o.HorizontalSizing == Sizing.FixedSize)
139                {
140                    widthOfFixedSizeObjects += o.PreferredSize.X;
141                }
142
143                if (o.VerticalSizing != Sizing.FixedSize)
144                {
145                    verticalSizing = Sizing.Expanding;
146                }
147            }
148
149            double preferredWidth = LeftPadding + widthOfExpandingObjects + widthOfFixedSizeObjects + ((objects.Count - 1) * Spacing) + RightPadding;
150            double preferredHeight = TopPadding + maxHeight + BottomPadding;
151
152            _horizontalSizing = horizontalSizing;
153            _verticalSizing = verticalSizing;
154            _spaceRequestedByExpandingObjects = widthOfExpandingObjects;
155            _spaceRequestedByFixedSizeObjects = widthOfFixedSizeObjects;
156            _preferredSize = new Vector(preferredWidth, preferredHeight);
157        }
158
159        [EditorBrowsable(EditorBrowsableState.Never)]
160        public Sizing HorizontalSizing
161        {
162            get { return _horizontalSizing; }
163        }
164
165        [EditorBrowsable(EditorBrowsableState.Never)]
166        public Sizing VerticalSizing
167        {
168            get { return _verticalSizing; }
169        }
170
171        [EditorBrowsable(EditorBrowsableState.Never)]
172        public Vector PreferredSize
173        {
174            get { return _preferredSize; }
175        }
176
177
178        [EditorBrowsable(EditorBrowsableState.Never)]
179        public void Update(IList<GameObject> objects, Vector maximumSize)
180        {
181            double contentWidth = maximumSize.X - (LeftPadding + RightPadding);
182            double preferredContentWidth = PreferredSize.X - (LeftPadding + RightPadding);
183            double contentHeight = maximumSize.Y - (TopPadding + BottomPadding);
184            double fixedScale = 1.0;
185            double expandingScale = 0.0;
186            double left = -maximumSize.X / 2 + LeftPadding;
187            double availableSpaceForObjects = contentWidth - (objects.Count - 1) * Spacing;
188
189            if ((availableSpaceForObjects < _spaceRequestedByFixedSizeObjects) && (_spaceRequestedByFixedSizeObjects > 0.0))
190            {
191                // Not enough space for all the fixed-size objects, they must be shrinked.
192                fixedScale = availableSpaceForObjects / _spaceRequestedByFixedSizeObjects;
193
194                // No space is left for expanding-size objects.
195                expandingScale = 0;
196            }
197            else if ((maximumSize.X < PreferredSize.X) && (_spaceRequestedByExpandingObjects > 0.0))
198            {
199                // Not as much space as was requested.
200
201                fixedScale = 1;
202
203                // The expanding objects must be shrinked.
204                double availableSpaceForExpandingObjects = availableSpaceForObjects - _spaceRequestedByFixedSizeObjects;
205                expandingScale = availableSpaceForExpandingObjects / _spaceRequestedByExpandingObjects;
206            }
207            else
208            {
209                // Enough space is available.
210
211                fixedScale = 1;
212
213                if (_spaceRequestedByExpandingObjects > 0)
214                {
215                    // The expanding-size objects shall use up all the extra space that is available.
216                    expandingScale = (availableSpaceForObjects - _spaceRequestedByFixedSizeObjects) / _spaceRequestedByExpandingObjects;
217                }
218            }
219
220            foreach (var o in objects)
221            {
222                double scale = (o.HorizontalSizing == Sizing.FixedSize) ? fixedScale : expandingScale;
223                double width = o.PreferredSize.X * scale;
224                double height = o.PreferredSize.Y;
225
226                if ((o.PreferredSize.Y > contentHeight) || (o.VerticalSizing == Sizing.Expanding))
227                {
228                    height = contentHeight;
229                }
230
231                o.Size = new Vector(width, height);
232                o.X = left + width / 2;
233                o.Y = (maximumSize.Y / 2) - (TopPadding + contentHeight / 2);
234
235                left += width + Spacing;
236            }
237        }
238    }
239}
Note: See TracBrowser for help on using the repository browser.