Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Drawing/Misc/ILAxis.cs @ 9102

Last change on this file since 9102 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 16.3 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40#pragma warning disable 1591
41
42using System;
43using System.Collections.Generic;
44using System.Text;
45using System.Drawing;
46using ILNumerics.Drawing.Interfaces;
47using ILNumerics.Exceptions;
48using ILNumerics.Drawing.Collections;
49using ILNumerics.Drawing.Labeling;
50using ILNumerics.Drawing;
51
52namespace ILNumerics.Drawing {
53    /// <summary>
54    /// Axis object for ILPanel
55    /// </summary>
56    public abstract class ILAxis : IDisposable {
57
58        #region attributes
59       
60        public event EventHandler Changed;
61        protected ILTickCollection m_labeledTicks;
62        protected ICollection<UnlabeledTick> m_unLabeledTicks;
63        protected ILLineProperties m_grid;
64        protected ILLineProperties m_nearLines;
65        protected ILLineProperties m_farLines;
66        protected ILClippingData m_clipping;
67        protected ILLabel m_label;
68        protected AxisType m_axisType;
69        protected AxisNames m_axisName;
70        protected bool m_visible = true;
71        protected bool m_invalidated = true;
72        protected ILLayoutData m_layoutData;
73        private ILLabeledTickProvider m_labelProvider;
74        protected ILPanel m_panel;
75        #endregion
76
77        #region properties
78
79        /// <summary>
80        /// Panel hosting the axis (readonly)
81        /// </summary>
82        ILPanel Panel {
83            get { return m_panel; }
84        }
85
86        /// <summary>
87        /// Used to retrieve/specify the delegate computing nice labels for axis
88        /// </summary>
89        /// <remarks>One can replace the default tick provider by a user
90        /// defined labeled tick computation function. Therefore simply set this property to
91        /// your own ILLabeledTickProvider function.
92        /// </remarks>
93        public ILLabeledTickProvider LabeledTickProvider {
94            get {
95                return m_labelProvider;
96            }
97            set {
98                if (value == null) return;
99                m_labelProvider = value;
100            }
101        }
102        /// <summary>
103        /// get properties for far axis lines (opposite label side) or sets it
104        /// </summary>
105        public ILLineProperties FarLines {
106            get {
107                return m_farLines;
108            }
109            set {
110                m_farLines = value;
111                OnChange();
112            }
113        }
114        /// <summary>
115        /// get properties for near axis lines (opposite label side) or sets it
116        /// </summary>
117        public ILLineProperties NearLines {
118            get {
119                return m_nearLines;
120            }
121            set {
122                m_nearLines = value;
123                OnChange();
124            }
125        }
126        /// <summary>
127        /// label to be displayed next to this axis
128        /// </summary>
129        public ILLabel Label {
130            get {
131                return m_label;
132            }
133            set {
134                m_label = value;
135                OnChange();
136            }
137        }
138        /// <summary>
139        /// Switch visibility on/ off
140        /// </summary>
141        public bool Visible {
142            get {
143                return m_visible;
144            }
145            set {
146                m_visible = value;
147                OnChange();
148            }
149        }
150        /// <summary>
151        /// axis type
152        /// </summary>
153        public AxisType AxisType {
154            get {
155                return m_axisType;
156            }
157            set {
158                m_axisType = value;
159                OnChange();
160            }
161        }
162        /// <summary>
163        /// Gives access to the collection of labeled ticks
164        /// </summary>
165        public ILTickCollection LabeledTicks {
166           get {
167               return m_labeledTicks;
168           }
169        }
170        /// <summary>
171        /// access to the collection of unlabeled ticks (not used)
172        /// </summary>
173        public ICollection<UnlabeledTick> UnlabeledTicks {
174            get {
175                return m_unLabeledTicks;
176            }
177        }
178        /// <summary>
179        /// access to a specific axis by number
180        /// </summary>
181        public int Index {
182            get {
183                return (int)m_axisName;
184            }
185        }
186        /// <summary>
187        /// access grid lines properties
188        /// </summary>
189        public ILLineProperties Grid {
190            get {
191                return m_grid;
192            }
193        }
194        /// <summary>
195        /// access axis limits
196        /// </summary>
197        public ILClippingData Limits {
198            get {
199                return m_clipping;
200            }
201        }
202
203        #endregion
204
205        #region Event handling
206        /// <summary>
207        /// fires a changed event
208        /// </summary>
209        protected void OnChange() {
210            Invalidate();
211            if (Changed != null) {
212                Changed(this,null);
213            }
214        }
215        /// <summary>
216        /// occures if the registered clipping data have changed
217        /// </summary>
218        /// <param name="sender">ILClipping data</param>
219        /// <param name="e">clipping changed event args</param>
220        void m_clipping_Changed(object sender, ClippingChangedEventArgs e) {
221            Invalidate();
222        }
223        void m_labeledTicks_Changed(object sender, ILAxisChangedEventArgs args) {
224            Invalidate();
225        }
226        void m_grid_Changed(object sender, EventArgs e) {
227            Invalidate();
228        }
229        void m_label_Changed(object sender, EventArgs e) {
230            Invalidate();
231        }
232        #endregion
233
234        #region constructor
235        /// <summary>
236        /// construct ILAxis object. This contructor is not to be called directly.
237        /// </summary>
238        /// <param name="name">type of the axis: XAxis,YAxis,ZAxis</param>
239        /// <param name="clippingView">Clipping data to be registered into the axis.</param>
240        /// <param name="layoutData">additional layout data, does currently only contain the camera [depricated]</param>
241        /// <param name="panel">panel hosting the scene</param>
242        /// <remarks>ILAxis objects are created GL-device dependend by use of a device dependend ILPanel instance's
243        /// member ILPanel.CreateAxis(). This acts like a factory pattern. The specific axis derivate will be
244        /// created by the derived ILPanel object (ILDXPanel or ILOGLPanel).</remarks>
245        public ILAxis (AxisNames name, ILClippingData clippingView,
246                       ILLayoutData layoutData,ILPanel panel) {
247            m_panel = panel;
248            m_axisName = name;
249            m_labeledTicks = new ILTickCollection(panel,m_axisName);
250            m_layoutData = layoutData;
251            m_labelProvider = null;
252            m_labeledTicks.Changed += new AxisChangedEventHandler(m_labeledTicks_Changed);
253            m_unLabeledTicks = new List<UnlabeledTick>(10);
254            m_grid = new ILLineProperties();
255            m_grid.Style = LineStyle.Dashed;
256            m_grid.Color = Color.FromArgb(220, 220, 225);
257            m_grid.Width = 1;
258
259            m_grid.Changed += new EventHandler(m_grid_Changed);
260            m_clipping = clippingView;
261            m_axisType = AxisType.Linear;
262            m_nearLines = new ILLineProperties();
263            m_nearLines.Color = Color.DarkBlue;
264            m_nearLines.Width = 1;
265            m_nearLines.Antialiasing = true;
266            m_nearLines.Changed +=new EventHandler(m_grid_Changed);
267            m_farLines = new ILLineProperties();
268            m_farLines.Color = Color.DarkBlue;
269            m_farLines.Width = 1;
270            m_farLines.Antialiasing = true;
271            m_farLines.Changed +=new EventHandler(m_grid_Changed);
272            m_label = new ILLabel(panel);
273            m_label.Changed += new EventHandler(m_label_Changed);
274            m_clipping.Changed += new ILClippingDataChangedEvent(m_clipping_Changed);
275            m_invalidated = true;
276        }
277        #endregion
278
279        #region abstract interface
280        /// <summary>
281        /// this function does the drawing of the axis lines
282        /// </summary>
283        /// <param name="p">render properties</param>
284        /// <param name="background">true: draw background only, false: draw foreground only</param>
285        /// <remarks>This function is called in the general rendering algorithm. I.e. <b>before</b> the surface buffers has been swapped.</remarks>
286        protected abstract void iDrawAxis(ILRenderProperties p, bool background);
287        /// <summary>
288        /// (internal use) do the drawing of axis' label
289        /// </summary>
290        /// <param name="p">render properties</param>
291        /// <remarks>When this function is called, depends on the DrawAfterBufferSwaped setting
292        /// of the current TextRenderer.</remarks>
293        protected virtual void iDrawLabel(ILRenderProperties p) {
294            if (m_visible)
295                m_label.Draw(p);
296        }
297
298        /// <summary>
299        /// (internal use) draw tick labels
300        /// </summary>
301        /// <param name="p">render properties</param>
302        protected virtual void iDrawTickLabels(ILRenderProperties p) {
303            if (m_visible)
304                m_labeledTicks.Draw(p,m_clipping.Min[Index],m_clipping.Max[Index]);
305        }
306        /// <summary>
307        /// Do all rendering for the grid of the axis
308        /// </summary>
309        protected abstract void drawGrid();
310
311        /// <summary>
312        /// draw this axis in the back (behind the graphs)
313        /// </summary>
314        /// <param name="p">render properties</param>
315        /// <remarks>This method is used internally. There should be no need to call it directly.</remarks>
316        internal virtual void RenderState1(ILRenderProperties p) {
317            if (m_invalidated) {
318                Configure(p);
319                p.Canceled = true;
320            }
321            if (!m_labeledTicks.Renderer.DrawAfterBufferSwapped)
322                iDrawTickLabels(p);
323            if (!m_label.Renderer.DrawAfterBufferSwapped)
324                iDrawLabel(p);
325            iDrawAxis(p,true);
326        }
327        /// <summary>
328        /// Do rendering of foreground (before the graphs)
329        /// </summary>
330        /// <param name="p">render properties</param>
331        public virtual void RenderState2(ILRenderProperties p) {
332            //if (m_invalidated)
333            //    Configure(p);
334            iDrawAxis(p,false);
335        }
336        /// <summary>
337        /// do rendering after the buffers have been swapped
338        /// </summary>
339        /// <param name="p">render properties</param>
340        public virtual void RenderState3(ILRenderProperties p) {
341            if (m_labeledTicks.Renderer.DrawAfterBufferSwapped)
342                iDrawTickLabels(p);
343            if (m_label.Renderer.DrawAfterBufferSwapped)
344                iDrawLabel(p);
345        }
346
347        /// <summary>
348        /// update axis (recalculate number &amp; position of labels in auto mode, recreate vertices)
349        /// </summary>
350        /// <param name="p">render properties</param>
351        /// <remarks>This method is used internally. There should be no need to call it directly.</remarks>
352        internal virtual void Configure(ILRenderProperties p) {
353            if (m_clipping.Min.IsEmtpy() || m_clipping.Max.IsEmtpy()) return;
354            if (p.PassCount > 0) return;
355            if (m_labeledTicks.Mode == TickMode.Auto) {
356                int tickCount = GetMaxTickCount(p);
357                if (m_labelProvider != null) {
358                    string format = String.Format("g{0}",m_labeledTicks.Precision);
359                    m_labeledTicks.Replace(
360                        m_labelProvider(m_clipping.Min[Index],m_clipping.Max[Index],tickCount));
361                } else {
362                    m_labeledTicks.CreateAuto(m_clipping.Min[Index],m_clipping.Max[Index],tickCount);
363                }
364            }
365            PrepareMeshes(p);
366            PrepareLabels(p);
367            m_invalidated = false;
368        }
369        /// <summary>
370        /// recreate vertices
371        /// </summary>
372        /// <param name="p">render properties</param>
373        public abstract void PrepareMeshes(ILRenderProperties p);
374        /// <summary>
375        /// recreate labels
376        /// </summary>
377        /// <param name="p">render properties</param>
378        public virtual void PrepareLabels(ILRenderProperties p) {
379            // prepare textrenderer
380        }
381
382        /// <summary>
383        /// number of ticks optimally fitting on screen
384        /// </summary>
385        /// <param name="p">render properties</param>
386        /// <returns>optimal number of ticks for this axis</returns>
387        internal int GetMaxTickCount(ILRenderProperties p) {
388            //System.Diagnostics.Debug.Assert(m_labeledTicks.Mode == TickMode.Auto);
389            SizeF rect = m_labeledTicks.Size;
390            Point s = new Point(),e = new Point();
391            s = m_labeledTicks.m_lineStart;
392            e = m_labeledTicks.m_lineEnd;
393            s.X = (int)(Math.Floor((float)Math.Abs(e.X - s.X) / (float)(rect.Width + m_labeledTicks.Padding)));
394            s.Y = (int)(Math.Floor((float) Math.Abs(e.Y - s.Y) / (float)(rect.Height + m_labeledTicks.Padding)));
395            return (int)Math.Floor(Math.Max((double)s.X,s.Y) + 1);
396        }
397       
398        /// <summary>
399        /// determine number of primitives (lines) to be drawn for this axis
400        /// </summary>
401        /// <returns>number of primitives</returns>
402        internal int countPrimitves() {
403            return (m_visible)?
404                (m_labeledTicks.Count + 1 + m_unLabeledTicks.Count) * 4 : 4;
405        }
406
407        /// <summary>
408        /// Invalidate this axis, causes recreation on next render
409        /// </summary>
410        public virtual void Invalidate() {
411            m_invalidated = true;
412        }
413
414        /// <summary>
415        /// (internal use) dispose off this axis' elements
416        /// </summary>
417        public virtual void Dispose() {
418            if (m_labeledTicks != null)
419                m_labeledTicks.Dispose();
420            if (m_label != null) {
421                m_label.Dispose();
422            }
423        }
424
425        #endregion
426
427        #region private helper
428        #endregion
429    }
430}
Note: See TracBrowser for help on using the repository browser.