[9102] | 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 |
|
---|
| 42 | using System;
|
---|
| 43 | using System.Collections.Generic;
|
---|
| 44 | using System.Text;
|
---|
| 45 | using System.Drawing;
|
---|
| 46 | using System.Reflection;
|
---|
| 47 | using System.Windows.Forms;
|
---|
| 48 | using System.IO;
|
---|
| 49 | using ILNumerics.Drawing;
|
---|
| 50 | using ILNumerics.Drawing.Interfaces;
|
---|
| 51 | using ILNumerics.Drawing.Collections;
|
---|
| 52 | using ILNumerics.Drawing.Graphs;
|
---|
| 53 | using ILNumerics.Drawing.Labeling;
|
---|
| 54 | using ILNumerics.Drawing.Misc;
|
---|
| 55 | using System.Diagnostics;
|
---|
| 56 |
|
---|
| 57 | namespace ILNumerics.Drawing {
|
---|
| 58 |
|
---|
| 59 | /// <summary>
|
---|
| 60 | /// Basic abstract base class for GL dependent display.
|
---|
| 61 | /// </summary>
|
---|
| 62 | /// <remarks>This control is the main plot control of ILNumerics.</remarks>
|
---|
| 63 | public abstract class ILPanel : Control {
|
---|
| 64 |
|
---|
| 65 | #region attributes
|
---|
| 66 | protected ILRendererManager m_textRendererManager;
|
---|
| 67 | protected ILClippingData m_clippingView;
|
---|
| 68 | protected ILAxisCollection m_axes;
|
---|
| 69 | protected ILGraphCollection m_graphs;
|
---|
| 70 | protected ILTextureManager m_textureManager;
|
---|
| 71 | protected Point m_mouseStart;
|
---|
| 72 | protected bool m_isDragging;
|
---|
| 73 | protected bool m_active = false;
|
---|
| 74 | protected bool m_drawHidden = true;
|
---|
| 75 | protected bool m_ready = false;
|
---|
| 76 | private bool m_isStartingUp = true;
|
---|
| 77 | protected ILCamera m_camera;
|
---|
| 78 | protected ILCamera m_defaultView;
|
---|
| 79 | protected bool m_autoDefaultView = true;
|
---|
| 80 | protected InteractiveModes m_selectingMode = InteractiveModes.Rotating;
|
---|
| 81 | protected InteractiveModes m_oldSelectingMode;
|
---|
| 82 | protected bool m_isCtrlKeyDown;
|
---|
| 83 | protected ILPoint3Df m_scaling;
|
---|
| 84 | protected Projection m_projection = Projection.Orthographic;
|
---|
| 85 | protected Color m_backColor = Color.FromKnownColor(KnownColor.Control);
|
---|
| 86 | protected Color m_cubeBGColor = Color.FromArgb(250, 250, 250);
|
---|
| 87 | protected ILColormap m_colormap;
|
---|
| 88 | protected ILLegend m_legend;
|
---|
| 89 | protected ZoomModes m_zoomMode = ZoomModes.RollHard;
|
---|
| 90 | protected ILZoomAction m_zoomAction;
|
---|
| 91 | protected float m_zoomOffset = 50f;
|
---|
| 92 | protected GraphicDeviceType m_graphicsDevice;
|
---|
| 93 | protected ILLineProperties m_selectionRectangle;
|
---|
| 94 | protected bool m_fillBackground = true;
|
---|
| 95 | private AutoZoomOptions m_autoZoomOptions = AutoZoomOptions.OnDataChanges;
|
---|
| 96 | protected ILLayoutData m_layoutData = new ILLayoutData();
|
---|
| 97 | protected ILLightCollection m_lights = new ILLightCollection();
|
---|
| 98 | protected ILRenderProperties m_renderProperties;
|
---|
| 99 | protected ILAction m_action;
|
---|
| 100 | protected List<ILGraph> m_sortingCacheList = new List<ILGraph>();
|
---|
| 101 | /// <summary>
|
---|
| 102 | /// pixel size of the current PlotCubeScreenRectangle
|
---|
| 103 | /// </summary>
|
---|
| 104 | protected RectangleF m_plotBoxScreenRectF;
|
---|
| 105 | protected PlotBoxScreenSizeMode m_plotBoxScreenSizeMode;
|
---|
| 106 | protected AspectRatioMode m_aspectRatio;
|
---|
| 107 | protected double[] m_clipplanes = new double[24];
|
---|
| 108 |
|
---|
| 109 | private const int MAXRENDERPASSES = 2;
|
---|
| 110 | private const float LABELS_VERTICAL_MIN_RHO = 0.8f;
|
---|
| 111 | protected const float pi05 = (float) Math.PI / 2;
|
---|
| 112 | protected const float pi2 = (float) Math.PI * 2;
|
---|
| 113 | protected const float pi32 = (float) Math.PI / 2 * 3;
|
---|
| 114 | protected const float pi4 = (float) Math.PI / 4;
|
---|
| 115 | protected const float pi8 = (float) Math.PI / 8;
|
---|
| 116 | #endregion
|
---|
| 117 |
|
---|
| 118 | #region properties
|
---|
| 119 | /// <summary>
|
---|
| 120 | /// Gets the mode for automatic view angle updates or sets it
|
---|
| 121 | /// </summary>
|
---|
| 122 | public bool AutoDefaultView {
|
---|
| 123 | get { return m_autoDefaultView; }
|
---|
| 124 | set { m_autoDefaultView = value; }
|
---|
| 125 | }
|
---|
| 126 | /// <summary>
|
---|
| 127 | /// Determines how the projected data plots are mapped to PlotCubeScreenRectF
|
---|
| 128 | /// </summary>
|
---|
| 129 | public AspectRatioMode AspectRatio {
|
---|
| 130 | get { return m_aspectRatio; }
|
---|
| 131 | set { m_aspectRatio = value; }
|
---|
| 132 | }
|
---|
| 133 | /// <summary>
|
---|
| 134 | /// The normalizes projected size (range 0..1) of plot cube on 2D client area, on set: also sets PlotCubeScreenMode -> Manual
|
---|
| 135 | /// </summary>
|
---|
| 136 | public RectangleF PlotBoxScreenRect {
|
---|
| 137 | get { return m_plotBoxScreenRectF; }
|
---|
| 138 | set {
|
---|
| 139 | m_plotBoxScreenRectF = value;
|
---|
| 140 | m_plotBoxScreenSizeMode = PlotBoxScreenSizeMode.Manual;
|
---|
| 141 | //Invalidate();
|
---|
| 142 | }
|
---|
| 143 | }
|
---|
| 144 | /// <summary>
|
---|
| 145 | /// Options for determining the size of the plot cube on the 2D screen client area, default: optimal
|
---|
| 146 | /// </summary>
|
---|
| 147 | public PlotBoxScreenSizeMode PlotBoxScreenSizeMode {
|
---|
| 148 | get { return m_plotBoxScreenSizeMode; }
|
---|
| 149 | set {
|
---|
| 150 | m_plotBoxScreenSizeMode = value;
|
---|
| 151 | if (value == PlotBoxScreenSizeMode.Maximum) {
|
---|
| 152 | m_plotBoxScreenRectF = new RectangleF(0, 0, 1f, 1f);
|
---|
| 153 | }
|
---|
| 154 | }
|
---|
| 155 | }
|
---|
| 156 | /// <summary>
|
---|
| 157 | /// Access collection of lights for configuration
|
---|
| 158 | /// </summary>
|
---|
| 159 | public ILLightCollection Lights {
|
---|
| 160 | get { return m_lights; }
|
---|
| 161 | }
|
---|
| 162 | /// <summary>
|
---|
| 163 | /// Legend for panel's graphs
|
---|
| 164 | /// </summary>
|
---|
| 165 | public ILLegend Legend {
|
---|
| 166 | get {
|
---|
| 167 | return m_legend;
|
---|
| 168 | }
|
---|
| 169 | }
|
---|
| 170 | /// <summary>
|
---|
| 171 | /// Get texture manager instance, storing all textures used in the scene
|
---|
| 172 | /// </summary>
|
---|
| 173 | internal ILTextureManager TextureManager {
|
---|
| 174 | get {
|
---|
| 175 | return m_textureManager;
|
---|
| 176 | }
|
---|
| 177 | }
|
---|
| 178 | /// <summary>
|
---|
| 179 | /// Colormap used to translate color indices into true colors
|
---|
| 180 | /// </summary>
|
---|
| 181 | public ILColormap Colormap {
|
---|
| 182 | get {
|
---|
| 183 | return m_colormap;
|
---|
| 184 | }
|
---|
| 185 | set {
|
---|
| 186 | m_colormap = value;
|
---|
| 187 | OnColormapChanged();
|
---|
| 188 | }
|
---|
| 189 | }
|
---|
| 190 | /// <summary>
|
---|
| 191 | /// Determines if background of the rendering cube will be filled with the CubeBackgroundColor property value
|
---|
| 192 | /// </summary>
|
---|
| 193 | public bool BackgroundFilled {
|
---|
| 194 | get {
|
---|
| 195 | return m_fillBackground;
|
---|
| 196 | }
|
---|
| 197 | set {
|
---|
| 198 | m_fillBackground = value;
|
---|
| 199 | //Invalidate();
|
---|
| 200 | }
|
---|
| 201 | }
|
---|
| 202 | /// <summary>
|
---|
| 203 | /// True: the control will always be drawn, even if it does not own the focus
|
---|
| 204 | /// </summary>
|
---|
| 205 | public bool DrawInactive {
|
---|
| 206 | get {
|
---|
| 207 | return m_drawHidden;
|
---|
| 208 | }
|
---|
| 209 | set {
|
---|
| 210 | m_drawHidden = value;
|
---|
| 211 | //Invalidate();
|
---|
| 212 | }
|
---|
| 213 | }
|
---|
| 214 | /// <summary>
|
---|
| 215 | /// Get/set the background color for the inner cube drawing
|
---|
| 216 | /// </summary>
|
---|
| 217 | public Color BackColorCube {
|
---|
| 218 | get {
|
---|
| 219 | return m_cubeBGColor;
|
---|
| 220 | }
|
---|
| 221 | set {
|
---|
| 222 | m_cubeBGColor = value;
|
---|
| 223 | //Invalidate();
|
---|
| 224 | }
|
---|
| 225 | }
|
---|
| 226 | /// <summary>
|
---|
| 227 | /// View settings, get access to the clipping limits for all axises
|
---|
| 228 | /// </summary>
|
---|
| 229 | public ILClippingData Limits {
|
---|
| 230 | get {
|
---|
| 231 | return m_clippingView;
|
---|
| 232 | }
|
---|
| 233 | }
|
---|
| 234 | /// <summary>
|
---|
| 235 | /// Get the type of device currently used for rendering
|
---|
| 236 | /// </summary>
|
---|
| 237 | public GraphicDeviceType GraphicDeviceType {
|
---|
| 238 | get {
|
---|
| 239 | return m_graphicsDevice;
|
---|
| 240 | }
|
---|
| 241 | }
|
---|
| 242 | /// <summary>
|
---|
| 243 | /// Get/set properties for selection rectangle, drawn when zooming with the mouse
|
---|
| 244 | /// </summary>
|
---|
| 245 | public ILLineProperties SelectionRectangle {
|
---|
| 246 | get {
|
---|
| 247 | return m_selectionRectangle;
|
---|
| 248 | }
|
---|
| 249 | }
|
---|
| 250 | /// <summary>
|
---|
| 251 | /// color of the figure background
|
---|
| 252 | /// </summary>
|
---|
| 253 | public override Color BackColor {
|
---|
| 254 | get {
|
---|
| 255 | return m_backColor;
|
---|
| 256 | }
|
---|
| 257 | set {
|
---|
| 258 | m_backColor = value;
|
---|
| 259 | //Invalidate();
|
---|
| 260 | }
|
---|
| 261 | }
|
---|
| 262 | /// <summary>
|
---|
| 263 | /// type of projection: orthographic (default) or perspective
|
---|
| 264 | /// </summary>
|
---|
| 265 | public Projection Projection {
|
---|
| 266 | get {
|
---|
| 267 | return m_projection;
|
---|
| 268 | }
|
---|
| 269 | set {
|
---|
| 270 | m_projection = value;
|
---|
| 271 | //Invalidate();
|
---|
| 272 | }
|
---|
| 273 | }
|
---|
| 274 | /// <summary>
|
---|
| 275 | /// Get or set viewport properties (distance & angles)
|
---|
| 276 | /// </summary>
|
---|
| 277 | /// <remarks>Changing </remarks>
|
---|
| 278 | public ILCamera Camera {
|
---|
| 279 | get {
|
---|
| 280 | return m_camera;
|
---|
| 281 | }
|
---|
| 282 | }
|
---|
| 283 | /// <summary>
|
---|
| 284 | /// Get the current mode for mouse interaction or set's it
|
---|
| 285 | /// </summary>
|
---|
| 286 | public InteractiveModes InteractiveMode {
|
---|
| 287 | get {
|
---|
| 288 | return m_selectingMode;
|
---|
| 289 | }
|
---|
| 290 | set {
|
---|
| 291 | m_selectingMode = value;
|
---|
| 292 | m_oldSelectingMode = value;
|
---|
| 293 | //if (value == InteractiveModes.Rotating)
|
---|
| 294 | // m_axes[AxisNames.ZAxis].Visible = true;
|
---|
| 295 | //else if (value == InteractiveModes.ZoomRectangle)
|
---|
| 296 | // m_axes[AxisNames.ZAxis].Visible = false;
|
---|
| 297 | }
|
---|
| 298 | }
|
---|
| 299 | /// <summary>
|
---|
| 300 | /// Gives all graphs as value collection (readonly)
|
---|
| 301 | /// </summary>
|
---|
| 302 | public ILGraphCollection Graphs {
|
---|
| 303 | get {
|
---|
| 304 | if (m_graphs == null)
|
---|
| 305 | CreateControl();
|
---|
| 306 | return m_graphs;
|
---|
| 307 | }
|
---|
| 308 | }
|
---|
| 309 | /// <summary>
|
---|
| 310 | /// Get axes collection - holds all 3 axes
|
---|
| 311 | /// </summary>
|
---|
| 312 | public ILAxisCollection Axes {
|
---|
| 313 | get {
|
---|
| 314 | if (m_axes == null)
|
---|
| 315 | CreateControl();
|
---|
| 316 | return m_axes;
|
---|
| 317 | }
|
---|
| 318 | }
|
---|
| 319 | /// <summary>
|
---|
| 320 | /// (experimental) content for graphs will be clipped outside the unit cube
|
---|
| 321 | /// </summary>
|
---|
| 322 | /// <remarks>For 2D plots, not clipping the vertex data may lead to hiding
|
---|
| 323 | /// the labels drawn next to axes. For 3D plots Clipping may cause unexpected behavior.
|
---|
| 324 | /// <para>Therefore Clipping will be activated for 2D plots by default and
|
---|
| 325 | /// deactivated for 3D plots by default.</para></remarks>
|
---|
| 326 | public bool ClipViewData {
|
---|
| 327 | get {
|
---|
| 328 | return m_renderProperties.Clipping;
|
---|
| 329 | }
|
---|
| 330 | set {
|
---|
| 331 | m_renderProperties.Clipping = value;
|
---|
| 332 | }
|
---|
| 333 | }
|
---|
| 334 | /// <summary>
|
---|
| 335 | /// Manager providing collection of available IILTextRenderer types
|
---|
| 336 | /// </summary>
|
---|
| 337 | /// <remarks>IILTextRenderer are used to draw labels for axis of this panel (device specific).
|
---|
| 338 | /// <para>Text renderer objects must be instantiated through the ILTextRendererManager instance's
|
---|
| 339 | /// CreateInstance() method.</para></remarks>
|
---|
| 340 | public ILRendererManager TextRendererManager {
|
---|
| 341 | get {
|
---|
| 342 | return m_textRendererManager;
|
---|
| 343 | }
|
---|
| 344 | }
|
---|
| 345 | /// <summary>
|
---|
| 346 | /// Get or set default camera position for reset of the scene
|
---|
| 347 | /// </summary>
|
---|
| 348 | /// <remarks>The default position is used when the scene is reset. That
|
---|
| 349 | /// reset is usually triggered by double clicking the panel with the mouse.
|
---|
| 350 | /// <para>setting this value to null will make the panel ignore any double
|
---|
| 351 | /// clicks, which enables the user to manually react to double click via the
|
---|
| 352 | /// common DoubleClick event of the panel and reset the camera position from
|
---|
| 353 | /// outside the component.</para></remarks>
|
---|
| 354 | public ILCamera DefaultView {
|
---|
| 355 | get {
|
---|
| 356 | return m_defaultView;
|
---|
| 357 | }
|
---|
| 358 | protected set {
|
---|
| 359 | if (value != null) {
|
---|
| 360 | m_defaultView = value;
|
---|
| 361 | m_autoDefaultView = false;
|
---|
| 362 | } else {
|
---|
| 363 | m_autoDefaultView = true;
|
---|
| 364 | }
|
---|
| 365 | }
|
---|
| 366 | }
|
---|
| 367 | /// <summary>
|
---|
| 368 | /// Options for the view cube adapting data limit changes
|
---|
| 369 | /// </summary>
|
---|
| 370 | public AutoZoomOptions AutoZoomContent {
|
---|
| 371 | get {
|
---|
| 372 | return m_autoZoomOptions;
|
---|
| 373 | }
|
---|
| 374 | set {
|
---|
| 375 | m_autoZoomOptions = value;
|
---|
| 376 | }
|
---|
| 377 | }
|
---|
| 378 | /// <summary>
|
---|
| 379 | /// choose the ramp for zooming
|
---|
| 380 | /// </summary>
|
---|
| 381 | public ZoomModes ZoomMode {
|
---|
| 382 | get { return m_zoomMode; }
|
---|
| 383 | set { m_zoomMode = value; }
|
---|
| 384 | }
|
---|
| 385 | /// <summary>
|
---|
| 386 | /// How much the view cube will be shrinked/expanded on zooming operations (percent)
|
---|
| 387 | /// </summary>
|
---|
| 388 | public float ZoomOffset {
|
---|
| 389 | set { m_zoomOffset = value; }
|
---|
| 390 | get { return m_zoomOffset; }
|
---|
| 391 |
|
---|
| 392 | }
|
---|
| 393 | protected ILZoomAction ZoomAction {
|
---|
| 394 | get {
|
---|
| 395 | return m_zoomAction;
|
---|
| 396 | }
|
---|
| 397 | }
|
---|
| 398 | #endregion
|
---|
| 399 |
|
---|
| 400 | #region constructors
|
---|
| 401 | protected ILPanel(GraphicDeviceType graphicsDevice) : base () {
|
---|
| 402 | #if TRACE
|
---|
| 403 | Trace.TraceInformation("{0},{1} ILPanel.ctor()",DateTime.Now, Environment.TickCount);
|
---|
| 404 | #endif
|
---|
| 405 | this.DoubleBuffered = false;
|
---|
| 406 | //BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
---|
| 407 | m_plotBoxScreenSizeMode = PlotBoxScreenSizeMode.Optimal;
|
---|
| 408 | m_graphicsDevice = graphicsDevice;
|
---|
| 409 | m_textureManager = new ILTextureManager(m_graphicsDevice);
|
---|
| 410 | m_textureManager.DefaultHeight = 500;
|
---|
| 411 | m_textureManager.DefaultWidth = 500;
|
---|
| 412 | m_selectionRectangle = new ILLineProperties();
|
---|
| 413 | m_selectionRectangle.Antialiasing = false;
|
---|
| 414 | m_selectionRectangle.Color = Color.Blue;
|
---|
| 415 | m_selectionRectangle.Width = 1;
|
---|
| 416 | m_selectionRectangle.Style = LineStyle.Solid;
|
---|
| 417 | m_selectionRectangle.Changed += new EventHandler(m_selectionRectangle_Changed);
|
---|
| 418 | m_camera = new ILCamera((float)0.0f,0.0f,10.0f);
|
---|
| 419 | m_defaultView = new ILCamera(m_camera);
|
---|
| 420 | m_defaultView.Changed += new EventHandler(m_defaultView_Changed);
|
---|
| 421 | m_renderProperties = new ILRenderProperties ();
|
---|
| 422 | m_renderProperties.Camera = Camera;
|
---|
| 423 | m_textRendererManager = new ILRendererManager(this);
|
---|
| 424 | m_clippingView = new ILClippingData();
|
---|
| 425 | m_clippingView.AllowZeroVolume = false;
|
---|
| 426 | m_layoutData = new ILLayoutData(m_camera);
|
---|
| 427 | m_clippingView.Changed += new ILClippingDataChangedEvent(m_viewLimits_Changed);
|
---|
| 428 | m_colormap = new ILColormap();
|
---|
| 429 | m_colormap.Changed += new EventHandler(m_colormap_Changed);
|
---|
| 430 | Padding = new Padding(5);
|
---|
| 431 | BackColor = Color.White;
|
---|
| 432 | Dock = DockStyle.Fill;
|
---|
| 433 | m_legend = ILLegend.Create(this);
|
---|
| 434 | m_legend.Changed += new EventHandler(m_legend_Changed);
|
---|
| 435 | m_active = false;
|
---|
| 436 | m_ready = false;
|
---|
| 437 | }
|
---|
| 438 |
|
---|
| 439 | #endregion
|
---|
| 440 |
|
---|
| 441 | #region public interface function
|
---|
| 442 | /// <summary>
|
---|
| 443 | /// Dispose this panel, frees all devices, graph- and axis collection
|
---|
| 444 | /// </summary>
|
---|
| 445 | public new void Dispose () {
|
---|
| 446 | Dispose(false);
|
---|
| 447 | }
|
---|
| 448 | /// <summary>
|
---|
| 449 | /// dispose this panel
|
---|
| 450 | /// </summary>
|
---|
| 451 | /// <param name="disposing">manual disposing</param>
|
---|
| 452 | /// <remarks>derived classed (ILDXPanel,ILOGLPanel) free their resources here</remarks>
|
---|
| 453 | protected override void Dispose(bool disposing) {
|
---|
| 454 | #if TRACE
|
---|
| 455 | Trace.TraceInformation("{0},{1} ILPanel.Dispose(bool) start",DateTime.Now, Environment.TickCount);
|
---|
| 456 | Trace.Indent();
|
---|
| 457 | #endif
|
---|
| 458 | m_ready = false;
|
---|
| 459 | if (m_graphs != null)
|
---|
| 460 | m_graphs.Dispose();
|
---|
| 461 | if (m_axes != null)
|
---|
| 462 | m_axes.Dispose();
|
---|
| 463 | if (m_textureManager != null)
|
---|
| 464 | m_textureManager.Dispose();
|
---|
| 465 | base.Dispose(disposing);
|
---|
| 466 | #if TRACE
|
---|
| 467 | Trace.Unindent();
|
---|
| 468 | Trace.TraceInformation("{0},{1} ILPanel.Dispose(bool) end",DateTime.Now, Environment.TickCount);
|
---|
| 469 | #endif
|
---|
| 470 | }
|
---|
| 471 |
|
---|
| 472 | /// <summary>
|
---|
| 473 | /// causes the panel to redraw
|
---|
| 474 | /// </summary>
|
---|
| 475 | public override void Refresh() {
|
---|
| 476 | if (InvokeRequired) {
|
---|
| 477 | Invoke((MethodInvoker) delegate () { Refresh(); });
|
---|
| 478 | } else {
|
---|
| 479 | base.Refresh();
|
---|
| 480 | }
|
---|
| 481 | }
|
---|
| 482 | #endregion
|
---|
| 483 |
|
---|
| 484 | #region events
|
---|
| 485 | /// <summary>
|
---|
| 486 | /// fired, if the data limits of any graphs changed
|
---|
| 487 | /// </summary>
|
---|
| 488 | public event ILClippingDataChangedEvent DataLimitsChanged;
|
---|
| 489 | /// <summary>
|
---|
| 490 | /// fired, if the clipping rectangle for viewing graphs changed
|
---|
| 491 | /// </summary>
|
---|
| 492 | public event ILClippingDataChangedEvent ViewLimitsChanged;
|
---|
| 493 | /// <summary>
|
---|
| 494 | /// fires, if the current colormap has changed
|
---|
| 495 | /// </summary>
|
---|
| 496 | public event EventHandler ColormapChanged;
|
---|
| 497 | /// <summary>
|
---|
| 498 | /// fired, if the internal graphics device reset (Direct3D devices only)
|
---|
| 499 | /// </summary>
|
---|
| 500 | public event ILGraphicsDeviceResetEvent GraphicsDeviceReset;
|
---|
| 501 | /// <summary>
|
---|
| 502 | /// fired, if the internal graphics device has been (re)created
|
---|
| 503 | /// </summary>
|
---|
| 504 | public event ILGraphicsDeviceCreatedEvent GraphicsDeviceCreated;
|
---|
| 505 | #endregion
|
---|
| 506 |
|
---|
| 507 | #region event handlers
|
---|
| 508 | protected void m_defaultView_Changed(object sender, EventArgs e) {
|
---|
| 509 | m_autoDefaultView = false;
|
---|
| 510 | }
|
---|
| 511 | protected override void OnHandleCreated(EventArgs e) {
|
---|
| 512 | #if TRACE
|
---|
| 513 | Trace.TraceInformation("{0},{1} ILPanel.OnHandleCreated() start",DateTime.Now, Environment.TickCount);
|
---|
| 514 | Trace.Indent();
|
---|
| 515 | #endif
|
---|
| 516 | base.OnHandleCreated(e);
|
---|
| 517 | this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);
|
---|
| 518 | this.SetStyle(ControlStyles.UserPaint,true);
|
---|
| 519 | #if TRACE
|
---|
| 520 | Trace.Unindent();
|
---|
| 521 | Trace.TraceInformation("{0},{1} ILPanel.OnHandleCreated() end",DateTime.Now, Environment.TickCount);
|
---|
| 522 | #endif
|
---|
| 523 | }
|
---|
| 524 | protected override void OnHandleDestroyed(EventArgs e) {
|
---|
| 525 | #if TRACE
|
---|
| 526 | Trace.TraceInformation("{0},{1} ILPanel.OnHandleDestroyed() start",DateTime.Now, Environment.TickCount);
|
---|
| 527 | Trace.Indent();
|
---|
| 528 | #endif
|
---|
| 529 | if (m_zoomAction != null) m_zoomAction.Cancel();
|
---|
| 530 | Dispose();
|
---|
| 531 | base.OnHandleDestroyed(e);
|
---|
| 532 | #if TRACE
|
---|
| 533 | Trace.Unindent();
|
---|
| 534 | Trace.TraceInformation("{0},{1} ILPanel.OnHandleDestroyed() end",DateTime.Now, Environment.TickCount);
|
---|
| 535 | #endif
|
---|
| 536 |
|
---|
| 537 | }
|
---|
| 538 | protected virtual void OnViewLimitsChanged(ClippingChangedEventArgs e) {
|
---|
| 539 | if (ViewLimitsChanged != null)
|
---|
| 540 | ViewLimitsChanged(this,e);
|
---|
| 541 | }
|
---|
| 542 | protected virtual void OnDataLimitsChanged(ClippingChangedEventArgs e) {
|
---|
| 543 | if (DataLimitsChanged != null)
|
---|
| 544 | DataLimitsChanged(this,e);
|
---|
| 545 | }
|
---|
| 546 | protected virtual void OnGraphicsDeviceReset() {
|
---|
| 547 | #if TRACE
|
---|
| 548 | Trace.TraceInformation("{0},{1} ILPanel.OnGraphicsDeviceReset() start",DateTime.Now, Environment.TickCount);
|
---|
| 549 | Trace.Indent();
|
---|
| 550 | #endif
|
---|
| 551 | Configure();
|
---|
| 552 | if (GraphicsDeviceReset != null) {
|
---|
| 553 | GraphicsDeviceReset(this,null);
|
---|
| 554 | }
|
---|
| 555 | #if TRACE
|
---|
| 556 | Trace.Unindent();
|
---|
| 557 | Trace.TraceInformation("{0},{1} ILPanel.OnGraphicsDeviceReset() end",DateTime.Now, Environment.TickCount);
|
---|
| 558 | #endif
|
---|
| 559 | }
|
---|
| 560 | protected virtual void OnGraphicsDeviceCreated() {
|
---|
| 561 | #if TRACE
|
---|
| 562 | Trace.TraceInformation("{0},{1} ILPanel.OnGraphicsDeviceCreated() start",DateTime.Now, Environment.TickCount);
|
---|
| 563 | Trace.Indent();
|
---|
| 564 | #endif
|
---|
| 565 | IILCreationFactory graphFact = GetCreationFactory();
|
---|
| 566 | m_graphs = new ILGraphCollection(graphFact);
|
---|
| 567 | m_graphs.CollectionChanged += new ILGraphCollectionChangedEvent(m_graphs_OnCollectionChanged);
|
---|
| 568 | m_graphs.Limits.Changed += new ILClippingDataChangedEvent(m_dataLimits_Changed);
|
---|
| 569 | m_graphs.GraphChanged += new ILGraphChangedEvent(m_graphs_GraphChanged);
|
---|
| 570 | m_axes = new ILAxisCollection(m_clippingView,graphFact);
|
---|
| 571 | if (GraphicsDeviceCreated!= null) {
|
---|
| 572 | GraphicsDeviceCreated(this,null);
|
---|
| 573 | }
|
---|
| 574 | //Invalidate();
|
---|
| 575 | #if TRACE
|
---|
| 576 | Trace.Unindent();
|
---|
| 577 | Trace.TraceInformation("{0},{1} ILPanel.OnGraphicsDeviceCreated() end",DateTime.Now, Environment.TickCount);
|
---|
| 578 | #endif
|
---|
| 579 | }
|
---|
| 580 |
|
---|
| 581 | protected virtual void OnColormapChanged() {
|
---|
| 582 | if (ColormapChanged != null)
|
---|
| 583 | ColormapChanged(this,null);
|
---|
| 584 | m_graphs.Invalidate();
|
---|
| 585 | }
|
---|
| 586 |
|
---|
| 587 | protected override void OnLostFocus(EventArgs e) {
|
---|
| 588 | base.OnLostFocus(e);
|
---|
| 589 | m_active = false;
|
---|
| 590 | }
|
---|
| 591 | protected override void OnGotFocus(EventArgs e) {
|
---|
| 592 | base.OnGotFocus(e);
|
---|
| 593 | m_active = true;
|
---|
| 594 | }
|
---|
| 595 | protected override void OnVisibleChanged(EventArgs e) {
|
---|
| 596 | if (IsHandleCreated && !IsDisposed) {
|
---|
| 597 | base.OnVisibleChanged(e);
|
---|
| 598 | if (Visible)
|
---|
| 599 | m_active = true;
|
---|
| 600 | else
|
---|
| 601 | m_active = false;
|
---|
| 602 | }
|
---|
| 603 | }
|
---|
| 604 | protected override void OnSizeChanged(EventArgs e) {
|
---|
| 605 | base.OnSizeChanged(e);
|
---|
| 606 | base.Invalidate();
|
---|
| 607 | }
|
---|
| 608 |
|
---|
| 609 | protected override void OnMouseMove(MouseEventArgs e) {
|
---|
| 610 | base.OnMouseMove(e);
|
---|
| 611 | if (m_selectingMode == InteractiveModes.Rotating) {
|
---|
| 612 | #region rotation
|
---|
| 613 | if (m_isDragging || (e.Button == System.Windows.Forms.MouseButtons.Left
|
---|
| 614 | && Math.Sqrt(Math.Pow(Math.Abs(e.X - m_mouseStart.X),2) + Math.Pow(Math.Abs(e.Y - m_mouseStart.Y),2)) > 3.0)) {
|
---|
| 615 | m_isDragging = true;
|
---|
| 616 | m_camera.EventingSuspend();
|
---|
| 617 | int distX = e.Location.X - m_mouseStart.X;
|
---|
| 618 | int distY = e.Location.Y - m_mouseStart.Y;
|
---|
| 619 | float tmp = m_camera.Phi - distX / 200.0f;
|
---|
| 620 | // if alt is pressed, lock on even angles
|
---|
| 621 | if (((Control.ModifierKeys & Keys.Alt) != 0)
|
---|
| 622 | && (Math.Abs(Math.Round(tmp/pi4) - (tmp / pi4)) < 0.05)) {
|
---|
| 623 | tmp = (float)(Math.Round(tmp / pi4) * pi4);
|
---|
| 624 | }
|
---|
| 625 | m_camera.Phi = tmp;
|
---|
| 626 | tmp = m_camera.Rho - distY / 200.0f;
|
---|
| 627 | // if alt is pressed, lock on even angles
|
---|
| 628 | if (((Control.ModifierKeys & Keys.Alt) != 0)
|
---|
| 629 | && (Math.Abs(Math.Round(tmp/pi8) - (tmp / pi8)) < 0.05)) {
|
---|
| 630 | tmp = (float)(Math.Round(tmp / pi8) * pi8);
|
---|
| 631 | }
|
---|
| 632 | m_camera.Rho = tmp;
|
---|
| 633 | if (m_camera.Rho > Math.PI) m_camera.Rho = (float)Math.PI;
|
---|
| 634 | if (m_camera.Rho < 0) m_camera.Rho = 0.0f;
|
---|
| 635 | m_camera.EventingResume();
|
---|
| 636 | m_mouseStart = e.Location;
|
---|
| 637 | Refresh();
|
---|
| 638 | }
|
---|
| 639 | #endregion
|
---|
| 640 | } else if (m_selectingMode == InteractiveModes.ZoomRectangle) {
|
---|
| 641 | #region selection rectangle
|
---|
| 642 | if (m_isDragging || (e.Button == System.Windows.Forms.MouseButtons.Left
|
---|
| 643 | && Math.Sqrt(Math.Pow(Math.Abs(e.X - m_mouseStart.X),2) + Math.Pow(Math.Abs(e.Y - m_mouseStart.Y),2)) > 3.0)) {
|
---|
| 644 | m_isDragging = true;
|
---|
| 645 | Cursor = Cursors.Cross;
|
---|
| 646 | Refresh();
|
---|
| 647 | }
|
---|
| 648 | #endregion
|
---|
| 649 | } else if (m_selectingMode == InteractiveModes.Translating) {
|
---|
| 650 | if (m_isDragging || (e.Button == System.Windows.Forms.MouseButtons.Left
|
---|
| 651 | && Math.Sqrt(Math.Pow(Math.Abs(e.X - m_mouseStart.X),2) + Math.Pow(Math.Abs(e.Y - m_mouseStart.Y),2)) > 1.0)) {
|
---|
| 652 | ILPoint3Df p1,p2,dummy;
|
---|
| 653 | Screen2World(m_mouseStart.X,Height - m_mouseStart.Y, out p1, out dummy);
|
---|
| 654 | Screen2World(e.X, Height - e.Y, out p2, out dummy);
|
---|
| 655 | if (m_projection == Projection.Perspective) {
|
---|
| 656 | p1 = ILPoint3Df.normalize(p1 - m_camera.Position) * m_camera.Distance;
|
---|
| 657 | p2 = ILPoint3Df.normalize(p2 - m_camera.Position) * m_camera.Distance;
|
---|
| 658 | }
|
---|
| 659 | p1 = p2 - p1;
|
---|
| 660 | m_camera.LookAt -= p1;
|
---|
| 661 | m_mouseStart = e.Location;
|
---|
| 662 | Refresh();
|
---|
| 663 | }
|
---|
| 664 |
|
---|
| 665 | }
|
---|
| 666 | }
|
---|
| 667 | protected override void OnMouseUp(MouseEventArgs e) {
|
---|
| 668 | base.OnMouseUp(e);
|
---|
| 669 | //System.Diagnostic.Debug.WriteLine("MouseUp");
|
---|
| 670 | if (m_selectingMode == InteractiveModes.ZoomRectangle && m_isDragging) {
|
---|
| 671 | Zoom(Screen2World2D(m_mouseStart.X,Height - m_mouseStart.Y),Screen2World2D(e.X, Height - e.Y));
|
---|
| 672 | }
|
---|
| 673 | m_isDragging = false;
|
---|
| 674 | Cursor = Cursors.Default;
|
---|
| 675 | }
|
---|
| 676 | protected override void OnMouseDown(MouseEventArgs e) {
|
---|
| 677 | base.OnMouseDown(e);
|
---|
| 678 | m_mouseStart = e.Location;
|
---|
| 679 | }
|
---|
| 680 | protected override void OnMouseClick(MouseEventArgs e) {
|
---|
| 681 | base.OnMouseClick(e);
|
---|
| 682 | //System.Diagnostic.Debug.WriteLine("Click");
|
---|
| 683 | if (m_isDragging == false && (m_selectingMode == InteractiveModes.ZoomRectangle
|
---|
| 684 | || m_selectingMode == InteractiveModes.Rotating)) {
|
---|
| 685 | // determine new center coords
|
---|
| 686 | ILPoint3Df near, far;
|
---|
| 687 | Screen2World(e.X,Height - e.Y, out near, out far); //Limits.CenterF.Z);
|
---|
| 688 | if (e.Button == System.Windows.Forms.MouseButtons.Left) {
|
---|
| 689 | Zoom(near,far,m_zoomOffset / 100);
|
---|
| 690 | }
|
---|
| 691 | else if (e.Button == System.Windows.Forms.MouseButtons.Right)
|
---|
| 692 | Zoom(near,far,- m_zoomOffset / 100);
|
---|
| 693 | }
|
---|
| 694 | }
|
---|
| 695 | protected override void OnMouseDoubleClick(MouseEventArgs e) {
|
---|
| 696 | base.OnMouseDoubleClick(e);
|
---|
| 697 | ResetView(true);
|
---|
| 698 | Refresh();
|
---|
| 699 | }
|
---|
| 700 | protected override void OnKeyDown(KeyEventArgs e) {
|
---|
| 701 | if (e.Control && !m_isCtrlKeyDown) {
|
---|
| 702 | m_oldSelectingMode = m_selectingMode;
|
---|
| 703 | m_selectingMode = InteractiveModes.Translating;
|
---|
| 704 | m_isCtrlKeyDown = true;
|
---|
| 705 | Cursor = Cursors.NoMove2D;
|
---|
| 706 | //m_isDragging = false;
|
---|
| 707 | }
|
---|
| 708 | base.OnKeyDown(e);
|
---|
| 709 | }
|
---|
| 710 | protected override void OnKeyUp(KeyEventArgs e) {
|
---|
| 711 | if (!e.Control) {
|
---|
| 712 | if (m_isCtrlKeyDown) {
|
---|
| 713 | m_isCtrlKeyDown = false;
|
---|
| 714 | m_selectingMode = m_oldSelectingMode;
|
---|
| 715 | }
|
---|
| 716 | Cursor = Cursors.Default;
|
---|
| 717 | //m_isDragging = false;
|
---|
| 718 | }
|
---|
| 719 | base.OnKeyUp(e);
|
---|
| 720 | }
|
---|
| 721 | protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
|
---|
| 722 | if (DesignMode) {
|
---|
| 723 | e.Graphics.Clear(Color.LightBlue);
|
---|
| 724 | return;
|
---|
| 725 | }
|
---|
| 726 | if (e.ClipRectangle.Width == 0 || e.ClipRectangle.Height == 0) {
|
---|
| 727 | #if TRACE
|
---|
| 728 | Trace.TraceInformation("{0},{1} ILPanel.OnPaint(): ClipRectangle.Size = empty -> skipping",DateTime.Now, Environment.TickCount);
|
---|
| 729 | #endif
|
---|
| 730 | return;
|
---|
| 731 | }
|
---|
| 732 | /* THIS IS PRELIMINARY IMPLEMENTATION! REASON: While using GDI renderer,
|
---|
| 733 | * it is importatnt, to have the whole (visible) surface area invalidated
|
---|
| 734 | * and available for clipping of the graphics objects in 'e'. Otherwise
|
---|
| 735 | * rendered objects will not show, after the buffers have swapped. The
|
---|
| 736 | * following code helps pick those situations, where the clipping region
|
---|
| 737 | * is only a subregion of the controls surface, but it introduces new
|
---|
| 738 | * problems, if the whole control is (partially) obscured by other controls.
|
---|
| 739 | * Since the GDI Renderer currently is not the recommended method of rendering,
|
---|
| 740 | * this code is commented until a better solution was found. */
|
---|
| 741 | // if (e.ClipRectangle.X > 0 || e.ClipRectangle.Y > 0) {
|
---|
| 742 | //#if TRACE
|
---|
| 743 | // Trace.TraceInformation("{0},{1} ILPanel.OnPaint(): partial clipping detected -> refreshing whole controls area",DateTime.Now, Environment.TickCount);
|
---|
| 744 | //#endif
|
---|
| 745 | // Refresh();
|
---|
| 746 | // return;
|
---|
| 747 | // }
|
---|
| 748 | try {
|
---|
| 749 | #if TRACE
|
---|
| 750 | Trace.TraceInformation("{0},{1} ILPanel.OnPaint(): started (re-)configure",DateTime.Now, Environment.TickCount);
|
---|
| 751 | Trace.Indent();
|
---|
| 752 | #endif
|
---|
| 753 | Configure();
|
---|
| 754 | if (m_isStartingUp && (m_autoZoomOptions != AutoZoomOptions.Never)) {
|
---|
| 755 | ResetView(true);
|
---|
| 756 | }
|
---|
| 757 | #if TRACE
|
---|
| 758 | Trace.Unindent();
|
---|
| 759 | Trace.TraceInformation("{0},{1} ILPanel.OnPaint(): rendering started",DateTime.Now, Environment.TickCount);
|
---|
| 760 | Trace.Indent();
|
---|
| 761 | Trace.TraceInformation(String.Format("this: {1}, ClipRectangle: {0}, Graphics.ClipBounds: L:{2} T:{3} W:{4} H:{5}"
|
---|
| 762 | ,e.ClipRectangle.ToString()
|
---|
| 763 | ,this.ClientRectangle.ToString()
|
---|
| 764 | ,e.Graphics.VisibleClipBounds.Left
|
---|
| 765 | ,e.Graphics.VisibleClipBounds.Top
|
---|
| 766 | ,e.Graphics.VisibleClipBounds.Width
|
---|
| 767 | ,e.Graphics.VisibleClipBounds.Height));
|
---|
| 768 | #endif
|
---|
| 769 | m_renderProperties.Graphics = e.Graphics;
|
---|
| 770 | m_renderProperties.Reason = RenderReason.PaintEvent;
|
---|
| 771 | m_renderProperties.MinX = int.MaxValue;
|
---|
| 772 | m_renderProperties.MinY = int.MaxValue;
|
---|
| 773 | m_renderProperties.MaxX = int.MinValue;
|
---|
| 774 | m_renderProperties.MaxY = int.MinValue;
|
---|
| 775 | RenderScene(m_renderProperties.Reset());
|
---|
| 776 | #if TRACE
|
---|
| 777 | Trace.Unindent();
|
---|
| 778 | Trace.TraceInformation("{0},{1} ILPanel.OnPaint(): rendering ended",DateTime.Now, Environment.TickCount);
|
---|
| 779 | #endif
|
---|
| 780 | if (m_isStartingUp) {
|
---|
| 781 | m_isStartingUp = false;
|
---|
| 782 | Refresh();
|
---|
| 783 | }
|
---|
| 784 | System.Diagnostics.Debug.WriteLine("Current Camera Setting: " + m_camera.ToString());
|
---|
| 785 | } catch (Exceptions.ILArgumentException exc) {
|
---|
| 786 | #if TRACE
|
---|
| 787 | Trace.TraceWarning("{0},{1} ILPanel.OnPaint(): rendering failed. reason: {2}",DateTime.Now, Environment.TickCount,exc.ToString());
|
---|
| 788 | Trace.Indent();
|
---|
| 789 | #endif
|
---|
| 790 | System.Diagnostics.Debug.WriteLine("ILPanel.OnPaint failed: " + exc.ToString());
|
---|
| 791 | throw new Exceptions.ILArgumentException("rendering failed. Details attached.",exc);
|
---|
| 792 | }
|
---|
| 793 | }
|
---|
| 794 | void m_legend_Changed(object sender, EventArgs e) {
|
---|
| 795 | Invalidate();
|
---|
| 796 | }
|
---|
| 797 |
|
---|
| 798 | void m_graphs_GraphChanged(object sender, ILGraphChangedEventArgs args) {
|
---|
| 799 | ResetView(false);
|
---|
| 800 | }
|
---|
| 801 | protected void m_graphs_OnCollectionChanged(object sender, ILGraphCollectionChangedEventArgs args) {
|
---|
| 802 | if (args.Reason == GraphCollectionChangeReason.Added) {
|
---|
| 803 | if (AutoDefaultView && (args.Configurator != null)) {
|
---|
| 804 | args.Configurator.ConfigurePanel(this);
|
---|
| 805 | }
|
---|
| 806 | }
|
---|
| 807 | }
|
---|
| 808 | protected void m_viewLimits_Changed(object sender, ClippingChangedEventArgs e) {
|
---|
| 809 | if (this.InvokeRequired && IsHandleCreated) {
|
---|
| 810 | try {
|
---|
| 811 | Invoke(new ILClippingDataChangedEvent(m_viewLimits_Changed), sender, e);
|
---|
| 812 | } catch (Exception) { }
|
---|
| 813 | } else {
|
---|
| 814 | m_camera.LookAt = m_clippingView.CenterF;
|
---|
| 815 | OnViewLimitsChanged(e);
|
---|
| 816 | }
|
---|
| 817 | }
|
---|
| 818 | protected void m_dataLimits_Changed(object sender, ClippingChangedEventArgs e) {
|
---|
| 819 | if (m_autoDefaultView) {
|
---|
| 820 | m_defaultView.EventingSuspend();
|
---|
| 821 | bool oldDefaultViewSetting = m_autoDefaultView;
|
---|
| 822 | m_defaultView.LookAt = m_graphs.Limits.CenterF;
|
---|
| 823 | m_defaultView.Distance = m_graphs.Limits.SphereRadius * 2;
|
---|
| 824 | m_defaultView.EventingResume(false);
|
---|
| 825 | }
|
---|
| 826 | if (m_autoZoomOptions == AutoZoomOptions.OnDataChanges)
|
---|
| 827 | ResetView(false);
|
---|
| 828 | OnDataLimitsChanged(e);
|
---|
| 829 | }
|
---|
| 830 |
|
---|
| 831 | protected void m_colormap_Changed(object sender, EventArgs e) {
|
---|
| 832 | OnColormapChanged();
|
---|
| 833 | }
|
---|
| 834 | void m_selectionRectangle_Changed(object sender, EventArgs e) {
|
---|
| 835 | // nothing to do here
|
---|
| 836 | }
|
---|
| 837 |
|
---|
| 838 | #endregion event handler
|
---|
| 839 |
|
---|
| 840 | #region virtual abstract interface
|
---|
| 841 | /// <summary>
|
---|
| 842 | /// Get current rendering device (implementation dependent)
|
---|
| 843 | /// </summary>
|
---|
| 844 | /// <returns></returns>
|
---|
| 845 | public abstract object GetDeviceContext();
|
---|
| 846 | /// <summary>
|
---|
| 847 | /// Causes a reconfiguration of all axes and graphs on the next paint event
|
---|
| 848 | /// </summary>
|
---|
| 849 | /// <remarks>Call this method after any changes to vertex relevant data. It causes all drawable objects to clear their caches and recalculate all vertex data.</remarks>
|
---|
| 850 | protected new void Invalidate() {
|
---|
| 851 | if (!m_ready) return;
|
---|
| 852 | m_ready = false;
|
---|
| 853 | m_graphs.Invalidate();
|
---|
| 854 | m_axes.Invalidate();
|
---|
| 855 | //base.Invalidate(this.ClientRectangle, true); <- this would cause an immediate redraw also. Use Refresh() for this!
|
---|
| 856 | }
|
---|
| 857 | /// <summary>
|
---|
| 858 | /// update viewing limits to show all data, rotate the scene to default (-> DefaultView)
|
---|
| 859 | /// </summary>
|
---|
| 860 | public virtual void ResetView() {
|
---|
| 861 | ResetView(true);
|
---|
| 862 | }
|
---|
| 863 | /// <summary>
|
---|
| 864 | /// update viewing limits to show all data, optionally reset the scene rotation
|
---|
| 865 | /// </summary>
|
---|
| 866 | /// <param name="resetRotation">true: rotate the scene to the default (-> DefaultView)</param>
|
---|
| 867 | public virtual void ResetView(bool resetRotation) {
|
---|
| 868 | if (m_zoomAction != null)
|
---|
| 869 | m_zoomAction.Cancel();
|
---|
| 870 | m_clippingView.EventingSuspend();
|
---|
| 871 | m_clippingView.CopyFrom(m_graphs.Limits);
|
---|
| 872 | m_clippingView.Update(m_clippingView.CenterF,1.1f);
|
---|
| 873 | m_clippingView.EventingResume();
|
---|
| 874 | if (m_defaultView != null && resetRotation) {
|
---|
| 875 | m_camera.LookAt = m_defaultView.LookAt;
|
---|
| 876 | m_camera.Phi = m_defaultView.Phi;
|
---|
| 877 | m_camera.Rho = m_defaultView.Rho;
|
---|
| 878 | m_camera.Distance = m_defaultView.Distance;
|
---|
| 879 | }
|
---|
| 880 | }
|
---|
| 881 | /// <summary>
|
---|
| 882 | /// Move & shrink/expand current view cube along a given line
|
---|
| 883 | /// </summary>
|
---|
| 884 | /// <param name="nearLineEnd"></param>
|
---|
| 885 | /// <param name="farLineEnd"></param>
|
---|
| 886 | /// <param name="offset"></param>
|
---|
| 887 | protected virtual void Zoom(ILPoint3Df nearLineEnd, ILPoint3Df farLineEnd, float offset) {
|
---|
| 888 | ILPoint3Df minCorner, maxCorner;
|
---|
| 889 | m_clippingView.GetZoomParameter(nearLineEnd,farLineEnd,offset, out minCorner, out maxCorner);
|
---|
| 890 | Zoom(minCorner,maxCorner);
|
---|
| 891 | //m_camera.LookAt = m_clippingView.CenterF;
|
---|
| 892 | }
|
---|
| 893 | /// <summary>
|
---|
| 894 | /// move the center of the viewing cube and expand / shrink the volume by offset
|
---|
| 895 | /// </summary>
|
---|
| 896 | /// <param name="center">new center</param>
|
---|
| 897 | /// <param name="offset">offset multiplicator, 1f means: no change</param>
|
---|
| 898 | protected virtual void Zoom(ILPoint3Df center, float offset) {
|
---|
| 899 | m_clippingView.Update(center,offset);
|
---|
| 900 | Refresh();
|
---|
| 901 | }
|
---|
| 902 | /// <summary>
|
---|
| 903 | /// Zoome the scene to new limits
|
---|
| 904 | /// </summary>
|
---|
| 905 | /// <param name="luCorner">'upper left' (first) corner of the new viewing cube</param>
|
---|
| 906 | /// <param name="rbCorner">'bottom right' (opposed) corner of the viewing cube</param>
|
---|
| 907 | protected virtual void Zoom(ILPoint3Df luCorner, ILPoint3Df rbCorner) {
|
---|
| 908 | if (m_zoomAction != null)
|
---|
| 909 | m_zoomAction.Cancel();
|
---|
| 910 | ILActionRamp ramp;
|
---|
| 911 | switch (m_zoomMode) {
|
---|
| 912 | case ZoomModes.Jump:
|
---|
| 913 | ramp = ILActionRamp.NoRamp;
|
---|
| 914 | break;
|
---|
| 915 | case ZoomModes.RollSoft:
|
---|
| 916 | ramp = ILActionRamp.Soft;
|
---|
| 917 | break;
|
---|
| 918 | case ZoomModes.RollHard:
|
---|
| 919 | ramp = ILActionRamp.Hard;
|
---|
| 920 | break;
|
---|
| 921 | case ZoomModes.RollOverride:
|
---|
| 922 | ramp = ILActionRamp.Override;
|
---|
| 923 | break;
|
---|
| 924 | default:
|
---|
| 925 | ramp = ILActionRamp.Linear;
|
---|
| 926 | break;
|
---|
| 927 | }
|
---|
| 928 | m_zoomAction = new ILZoomAction(m_clippingView.Min, luCorner, m_clippingView.Max, rbCorner, ramp, this);
|
---|
| 929 | m_zoomAction.Run();
|
---|
| 930 | }
|
---|
| 931 |
|
---|
| 932 |
|
---|
| 933 | /// <summary>
|
---|
| 934 | /// Transform two coordinates for a line from world to screen coordinates
|
---|
| 935 | /// </summary>
|
---|
| 936 | /// <param name="start">1st coordinate (world)</param>
|
---|
| 937 | /// <param name="end">2nd coordinate (world)</param>
|
---|
| 938 | /// <param name="start2D">[output] 1st coordinate (screen pixels)</param>
|
---|
| 939 | /// <param name="end2D">[output] 2nd coordinate (screen pixels)</param>
|
---|
| 940 | /// <remarks>This function is provided by the concrete derived class, using the
|
---|
| 941 | /// current rendering framework.</remarks>
|
---|
| 942 | public abstract void World2Screen(ILPoint3Df start, ILPoint3Df end, out Point start2D, out Point end2D);
|
---|
| 943 |
|
---|
| 944 | /// <summary>
|
---|
| 945 | /// Transform from a point on screen into world coordinates [depricated]
|
---|
| 946 | /// </summary>
|
---|
| 947 | /// <param name="x">screen x</param>
|
---|
| 948 | /// <param name="y">screen y: GL viewport coord! -> (0,0) is lower left corner!</param>
|
---|
| 949 | /// <returns>world coordinate point</returns>
|
---|
| 950 | public abstract ILPoint3Df Screen2World2D(int x, int y);
|
---|
| 951 | /// <summary>
|
---|
| 952 | /// gives the line in world coords, a specific point on screen lays on
|
---|
| 953 | /// </summary>
|
---|
| 954 | /// <param name="x">screen x</param>
|
---|
| 955 | /// <param name="y">screen y: GL viewport coord! -> (0,0) is lower left corner</param>
|
---|
| 956 | /// <param name="farClip">far end point of the resulting line in world coords</param>
|
---|
| 957 | /// <param name="nearClip">near end point of the resulting line in world coords</param>
|
---|
| 958 | public abstract void Screen2World(int x, int y, out ILPoint3Df nearClip, out ILPoint3Df farClip);
|
---|
| 959 |
|
---|
| 960 | /// <summary>
|
---|
| 961 | /// Transform world coordinate to screen coordinate under current transformation
|
---|
| 962 | /// </summary>
|
---|
| 963 | /// <param name="worldPoint">world coordinate</param>
|
---|
| 964 | /// <returns>screen location</returns>
|
---|
| 965 | /// <remarks>the actual transform is carried out in the derived specialized class,
|
---|
| 966 | /// where the current transformation matrices are known</remarks>
|
---|
| 967 | public abstract Point World2Screen(ILPoint3Df worldPoint);
|
---|
| 968 | /// <summary>
|
---|
| 969 | /// Transform world coordinate to screen coordinate, provide (custom) modelview matrix
|
---|
| 970 | /// </summary>
|
---|
| 971 | /// <param name="worldPoint"></param>
|
---|
| 972 | /// <param name="modelview">(custom) model view matrix. The parameter must match the format required by the deriving concrete ILPanel class. ILOGLPanel: double[16]</param>
|
---|
| 973 | /// <returns>screen location</returns>
|
---|
| 974 | /// <remarks>the actual transform is carried out in the derived specialized class,
|
---|
| 975 | /// where the current transformation matrices are known</remarks>
|
---|
| 976 | public abstract Point World2Screen(ILPoint3Df worldPoint, double[] modelview);
|
---|
| 977 |
|
---|
| 978 | /// <summary>
|
---|
| 979 | /// Draws content of this subfigure into predefined bitmap
|
---|
| 980 | /// </summary>
|
---|
| 981 | /// <param name="bitmap">predefined bitmap to draw content into. The size must have been initialized according to 'bounds'.</param>
|
---|
| 982 | /// <param name="bounds">Rectangle specifying the region to be copied.</param>
|
---|
| 983 | public new abstract void DrawToBitmap(Bitmap bitmap, Rectangle bounds);
|
---|
| 984 | #endregion
|
---|
| 985 |
|
---|
| 986 | #region helper functions
|
---|
| 987 | /// <summary>
|
---|
| 988 | /// draws the selection rectangle with GDI functions
|
---|
| 989 | /// </summary>
|
---|
| 990 | /// <param name="endPoint">end point</param>
|
---|
| 991 | /// <remarks>The start point is stored in the member m_mouseStart.</remarks>
|
---|
| 992 | protected virtual void drawSelectionRect(Point endPoint) {
|
---|
| 993 | Graphics g = Graphics.FromHwnd(this.Handle);
|
---|
| 994 | Pen pen = new Pen(m_selectionRectangle.Color, 1.0f);
|
---|
| 995 | Point[] points = new Point[3];
|
---|
| 996 | // upper left corner
|
---|
| 997 | points[0] = new Point(m_mouseStart.X, m_mouseStart.Y + (endPoint.Y - m_mouseStart.Y) / 4);
|
---|
| 998 | points[1] = new Point(m_mouseStart.X, m_mouseStart.Y);
|
---|
| 999 | points[2] = new Point(m_mouseStart.X + (endPoint.X - m_mouseStart.X) / 4, m_mouseStart.Y);
|
---|
| 1000 | g.DrawLines(pen, points);
|
---|
| 1001 | // lower left corner
|
---|
| 1002 | points[0] = new Point(m_mouseStart.X, endPoint.Y - (endPoint.Y - m_mouseStart.Y) / 4);
|
---|
| 1003 | points[1] = new Point(m_mouseStart.X, endPoint.Y);
|
---|
| 1004 | points[2] = new Point(m_mouseStart.X + (endPoint.X - m_mouseStart.X) / 4, endPoint.Y);
|
---|
| 1005 | g.DrawLines(pen, points);
|
---|
| 1006 | // lower right corner
|
---|
| 1007 | points[0] = new Point(endPoint.X, endPoint.Y - (endPoint.Y - m_mouseStart.Y) / 4);
|
---|
| 1008 | points[1] = new Point(endPoint.X, endPoint.Y);
|
---|
| 1009 | points[2] = new Point(endPoint.X - (endPoint.X - m_mouseStart.X) / 4, endPoint.Y);
|
---|
| 1010 | g.DrawLines(pen, points);
|
---|
| 1011 | // upper right corner
|
---|
| 1012 | points[0] = new Point(endPoint.X, m_mouseStart.Y + (endPoint.Y - m_mouseStart.Y) / 4);
|
---|
| 1013 | points[1] = new Point(endPoint.X, m_mouseStart.Y);
|
---|
| 1014 | points[2] = new Point(endPoint.X - (endPoint.X - m_mouseStart.X) / 4, m_mouseStart.Y);
|
---|
| 1015 | g.DrawLines(pen, points);
|
---|
| 1016 | }
|
---|
| 1017 | public static short StippleFromLineStyle(LineStyle style, ref int stipFactr) {
|
---|
| 1018 | short ret = 1;
|
---|
| 1019 | switch (style) {
|
---|
| 1020 | case LineStyle.Dashed:
|
---|
| 1021 | ret = (short)255;
|
---|
| 1022 | stipFactr = 2;
|
---|
| 1023 | break;
|
---|
| 1024 | case LineStyle.PointDash:
|
---|
| 1025 | ret = (short)255 + 4096;
|
---|
| 1026 | stipFactr = 1;
|
---|
| 1027 | break;
|
---|
| 1028 | case LineStyle.Dotted:
|
---|
| 1029 | ret = (short)13107; // 3 + 48 + 768 + 8192 + 4096;
|
---|
| 1030 | stipFactr = 2;
|
---|
| 1031 | break;
|
---|
| 1032 | case LineStyle.UserPattern:
|
---|
| 1033 | break;
|
---|
| 1034 | // ret = 0;
|
---|
| 1035 | case LineStyle.None:
|
---|
| 1036 | break;
|
---|
| 1037 | default: // solid
|
---|
| 1038 | ret = (short)-1;
|
---|
| 1039 | break;
|
---|
| 1040 | }
|
---|
| 1041 | return ret;
|
---|
| 1042 | }
|
---|
| 1043 | private void calculateDefaultView(bool setPositions, bool setDirection) {
|
---|
| 1044 | m_defaultView.EventingSuspend();
|
---|
| 1045 | if (setPositions) {
|
---|
| 1046 | m_defaultView.LookAt = m_graphs.Limits.CenterF;
|
---|
| 1047 | m_defaultView.Distance = m_clippingView.SphereRadius * 2f;
|
---|
| 1048 | }
|
---|
| 1049 | if (setDirection) {
|
---|
| 1050 | m_defaultView.Phi = 0; // -(float)Math.PI / 2;
|
---|
| 1051 | m_defaultView.Rho = 0;
|
---|
| 1052 | }
|
---|
| 1053 | m_defaultView.EventingResume(false);
|
---|
| 1054 | }
|
---|
| 1055 | #endregion
|
---|
| 1056 |
|
---|
| 1057 | #region private rendering setup helper
|
---|
| 1058 | protected void helperUpdateMatrices(float width2D, float height2D, out float worldSceneWidth, out float worldSceneHeight, out ILPoint3Df top, out ILPoint3Df moveOffset)
|
---|
| 1059 | {
|
---|
| 1060 | float localPlotCubeScreenRectLeft;
|
---|
| 1061 | float localPlotCubeScreenRectWidth;
|
---|
| 1062 |
|
---|
| 1063 | float localPlotCubeScreenRectTop;
|
---|
| 1064 | float localPlotCubeScreenRectHeight;
|
---|
| 1065 |
|
---|
| 1066 | float offsetX;
|
---|
| 1067 | float offsetY;
|
---|
| 1068 |
|
---|
| 1069 | localPlotCubeScreenRectHeight = m_plotBoxScreenRectF.Height;
|
---|
| 1070 | localPlotCubeScreenRectWidth = m_plotBoxScreenRectF.Width;
|
---|
| 1071 | localPlotCubeScreenRectTop = m_plotBoxScreenRectF.Top;
|
---|
| 1072 | localPlotCubeScreenRectLeft = m_plotBoxScreenRectF.Left;
|
---|
| 1073 |
|
---|
| 1074 | if (AspectRatio == AspectRatioMode.StretchToFill)
|
---|
| 1075 | {
|
---|
| 1076 | worldSceneWidth = width2D / localPlotCubeScreenRectWidth;
|
---|
| 1077 | worldSceneHeight = height2D / localPlotCubeScreenRectHeight;
|
---|
| 1078 | }
|
---|
| 1079 | else
|
---|
| 1080 | { //if (RenderAspectRatioMode == RenderAspectRatioMode.MaintainRatios) {
|
---|
| 1081 | float plotCubeScreenRectAspectRatio =
|
---|
| 1082 | (m_plotBoxScreenRectF.Width * ClientSize.Width)
|
---|
| 1083 | / (m_plotBoxScreenRectF.Height * ClientSize.Height);
|
---|
| 1084 | float dataAspectRatio = width2D / height2D;
|
---|
| 1085 | if (plotCubeScreenRectAspectRatio > dataAspectRatio)
|
---|
| 1086 | {
|
---|
| 1087 | // width > height
|
---|
| 1088 | worldSceneHeight = height2D;
|
---|
| 1089 | worldSceneWidth = worldSceneHeight * dataAspectRatio;
|
---|
| 1090 | // enlarge the scene, so we have rendering margin outside the data cube
|
---|
| 1091 | worldSceneHeight /= localPlotCubeScreenRectHeight;
|
---|
| 1092 | worldSceneWidth /= (localPlotCubeScreenRectWidth * (dataAspectRatio / plotCubeScreenRectAspectRatio));
|
---|
| 1093 | }
|
---|
| 1094 | else
|
---|
| 1095 | {
|
---|
| 1096 | // height >= width
|
---|
| 1097 | worldSceneWidth = width2D;
|
---|
| 1098 | worldSceneHeight = worldSceneWidth / dataAspectRatio;
|
---|
| 1099 | // enlarge the scene, so we have rendering margin outside the data cube
|
---|
| 1100 | worldSceneWidth /= localPlotCubeScreenRectWidth;
|
---|
| 1101 | worldSceneHeight /= (localPlotCubeScreenRectHeight / (dataAspectRatio / plotCubeScreenRectAspectRatio));
|
---|
| 1102 | }
|
---|
| 1103 | }
|
---|
| 1104 | // one more pixel please...
|
---|
| 1105 | worldSceneHeight = (worldSceneHeight / ClientSize.Height * (ClientSize.Height + 1));
|
---|
| 1106 | worldSceneWidth = (worldSceneWidth / ClientSize.Width * (ClientSize.Width + 1));
|
---|
| 1107 | // if PlotCubeScreenRect is not centered, we move the scene out of center accordingly (..further down)
|
---|
| 1108 | top = new ILPoint3Df(-m_camera.SinPhi * m_camera.CosRho, m_camera.CosPhi * m_camera.CosRho, m_camera.SinRho);
|
---|
| 1109 | ILPoint3Df moveX = ILPoint3Df.crossN(m_camera.Position - m_camera.LookAt, top);
|
---|
| 1110 | offsetX = -(localPlotCubeScreenRectLeft + (localPlotCubeScreenRectWidth / 2f) - 0.5f) * worldSceneWidth;
|
---|
| 1111 | offsetY = -(localPlotCubeScreenRectTop + (localPlotCubeScreenRectHeight / 2f) - 0.5f) * worldSceneHeight;
|
---|
| 1112 | moveOffset = top * offsetY + moveX * offsetX;
|
---|
| 1113 | }
|
---|
| 1114 | protected virtual void RenderScene(ILRenderProperties p) {
|
---|
| 1115 | //System.Diagnostics.Debug.Print("m_camera:{0}", m_camera);
|
---|
| 1116 | if (!DesignMode) {
|
---|
| 1117 | lock (m_sortingCacheList) {
|
---|
| 1118 | iRenderingState1(p); //make current
|
---|
| 1119 | // configure axes (determine tick labels in mode 'auto')
|
---|
| 1120 | m_axes.XAxis.Configure(p);
|
---|
| 1121 | m_axes.YAxis.Configure(p);
|
---|
| 1122 | m_axes.ZAxis.Configure(p);
|
---|
| 1123 |
|
---|
| 1124 |
|
---|
| 1125 | //computeLayoutData(p);
|
---|
| 1126 | float rotatedViewLimitX, rotatedViewLimitY, rotatedViewLimitZ;
|
---|
| 1127 | GetTransformedSize(out rotatedViewLimitX, out rotatedViewLimitY, out rotatedViewLimitZ);
|
---|
| 1128 |
|
---|
| 1129 | // determine needed margins according to current tic label collections (which are left over from last rendering run or empty)
|
---|
| 1130 | Size ticLabelsMargins = GetMaxTicLabelSize(p.Graphics);
|
---|
| 1131 | updatePlotCubeScreenRect(rotatedViewLimitX, rotatedViewLimitY, ticLabelsMargins);
|
---|
| 1132 | p.PassCount = 0;
|
---|
| 1133 | for (; p.PassCount < MAXRENDERPASSES; p.PassCount++) {
|
---|
| 1134 | UpdateMatrices(rotatedViewLimitX, rotatedViewLimitY, rotatedViewLimitZ);
|
---|
| 1135 |
|
---|
| 1136 | updateTickLabelLines();
|
---|
| 1137 | updateLabelPositions(p);
|
---|
| 1138 | if (p.PassCount == 0) {
|
---|
| 1139 | }
|
---|
| 1140 | iRenderingState2(p); // do the actual drawing
|
---|
| 1141 | //iRenderingState3(p);
|
---|
| 1142 | #region check if we can fit the plot cube more precisely
|
---|
| 1143 | if (m_plotBoxScreenSizeMode == PlotBoxScreenSizeMode.StrictOptimal) {
|
---|
| 1144 | float t = m_plotBoxScreenRectF.Top;
|
---|
| 1145 | float l = m_plotBoxScreenRectF.Left;
|
---|
| 1146 | float r = m_plotBoxScreenRectF.Right;
|
---|
| 1147 | float b = m_plotBoxScreenRectF.Bottom, tmp;
|
---|
| 1148 | bool resize = false;
|
---|
| 1149 | tmp = (float)p.MinX / ClientSize.Width;
|
---|
| 1150 | if (tmp < l) {
|
---|
| 1151 | if (p.MinX != 0) {
|
---|
| 1152 | l -= tmp;
|
---|
| 1153 | resize = true;
|
---|
| 1154 | }
|
---|
| 1155 | } else if (l > 0) {
|
---|
| 1156 | l = 0;
|
---|
| 1157 | resize = true;
|
---|
| 1158 | }
|
---|
| 1159 | tmp = (float)p.MaxX / ClientSize.Width;
|
---|
| 1160 | if (tmp > r) {
|
---|
| 1161 | if (p.MaxX != (ClientSize.Width - 1)) {
|
---|
| 1162 | r += (1 - tmp);
|
---|
| 1163 | resize = true;
|
---|
| 1164 | }
|
---|
| 1165 | } else if (r < 1) {
|
---|
| 1166 | r = (float)(ClientSize.Width - 1) / ClientSize.Width;
|
---|
| 1167 | resize = true;
|
---|
| 1168 | }
|
---|
| 1169 | tmp = (float)p.MinY / ClientSize.Height;
|
---|
| 1170 | if (tmp < t) {
|
---|
| 1171 | if (p.MinY != 0) {
|
---|
| 1172 | t -= tmp;
|
---|
| 1173 | resize = true;
|
---|
| 1174 | }
|
---|
| 1175 | } else if (t > 0) {
|
---|
| 1176 | t = 0;
|
---|
| 1177 | resize = true;
|
---|
| 1178 | }
|
---|
| 1179 | tmp = (float)p.MaxY / ClientSize.Height;
|
---|
| 1180 | if (tmp > b) {
|
---|
| 1181 | if (p.MaxY != (ClientSize.Height - 1)) {
|
---|
| 1182 | b += (1 - tmp);
|
---|
| 1183 | resize = true;
|
---|
| 1184 | }
|
---|
| 1185 | } else if (b < 1) {
|
---|
| 1186 | b = (float)(ClientSize.Height - 1) / ClientSize.Height;
|
---|
| 1187 | resize = true;
|
---|
| 1188 | }
|
---|
| 1189 | if (resize) {
|
---|
| 1190 | // ... there is still room left we can use for enlarging the render cube
|
---|
| 1191 | m_plotBoxScreenRectF = new RectangleF(l, t, r - l, b - t);
|
---|
| 1192 | p.Reason = RenderReason.RecalcLabels;
|
---|
| 1193 | p.MaxY = int.MinValue;
|
---|
| 1194 | p.MaxX = int.MinValue;
|
---|
| 1195 | p.MinY = int.MaxValue;
|
---|
| 1196 | p.MinX = int.MaxValue;
|
---|
| 1197 | }
|
---|
| 1198 | continue;
|
---|
| 1199 | }
|
---|
| 1200 | #endregion
|
---|
| 1201 | break;
|
---|
| 1202 | }
|
---|
| 1203 | iRenderingState3(p);
|
---|
| 1204 | }
|
---|
| 1205 |
|
---|
| 1206 | }
|
---|
| 1207 | }
|
---|
| 1208 | protected abstract void iRenderingState1(ILRenderProperties p);
|
---|
| 1209 | /// <summary>
|
---|
| 1210 | /// [internal] Configure this panel, to make it ready for output, set "m_ready = true" at end!
|
---|
| 1211 | /// </summary>
|
---|
| 1212 | protected virtual void Configure() {
|
---|
| 1213 | foreach (ILGraph graph in m_graphs) {
|
---|
| 1214 | graph.Configure();
|
---|
| 1215 | }
|
---|
| 1216 | // update clipping view
|
---|
| 1217 | m_clipplanes[0] = -1.0; m_clipplanes[3] = m_clippingView.Max.X;
|
---|
| 1218 | m_clipplanes[4] = 1.0; m_clipplanes[7] = -m_clippingView.Min.X;
|
---|
| 1219 | m_clipplanes[9] = -1.0; m_clipplanes[11] = m_clippingView.Max.Y;
|
---|
| 1220 | m_clipplanes[13] = 1.0; m_clipplanes[15] = -m_clippingView.Min.Y;
|
---|
| 1221 | m_clipplanes[18] = -1.0; m_clipplanes[19] = m_clippingView.Max.Z;
|
---|
| 1222 | m_clipplanes[22] = 1.0; m_clipplanes[23] = -m_clippingView.Min.Z;
|
---|
| 1223 |
|
---|
| 1224 | m_ready = true;
|
---|
| 1225 | }
|
---|
| 1226 | /// <summary>
|
---|
| 1227 | /// draw the scene: all axes, graphs, background etc. (device dependant)
|
---|
| 1228 | /// </summary>
|
---|
| 1229 | /// <param name="p"></param>
|
---|
| 1230 | protected abstract void iRenderingState2(ILRenderProperties p);
|
---|
| 1231 | protected abstract void iRenderingState3(ILRenderProperties p);
|
---|
| 1232 | protected abstract void UpdateMatrices(float width2D, float height2D, float depth2D);
|
---|
| 1233 | /// <summary>
|
---|
| 1234 | /// initialize all device specific classes, first called after the panel has been created
|
---|
| 1235 | /// </summary>
|
---|
| 1236 | /// <remarks>derived types should init all devices here</remarks>
|
---|
| 1237 | protected virtual void Initialize() { }
|
---|
| 1238 | protected PointF GetXTickLabelLine(out Point start2D, out Point end2D) {
|
---|
| 1239 | PointF anchor = new PointF(0,0); // TickLabelAlign.left;
|
---|
| 1240 | ILPoint3Df start = new ILPoint3Df(), end = new ILPoint3Df();
|
---|
| 1241 | ILTickCollection ticks = m_axes[0].LabeledTicks;
|
---|
| 1242 | float tickLen = (ticks.Direction == TickDirection.Outside) ?
|
---|
| 1243 | ticks.TickFraction : 0f;
|
---|
| 1244 | float padX = ticks.Padding, padY = padX;
|
---|
| 1245 | switch (m_camera.Quadrant) {
|
---|
| 1246 | case CameraQuadrant.TopLeftFront:
|
---|
| 1247 | start.X = m_clippingView.Min.X;
|
---|
| 1248 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1249 | start.Z = m_clippingView.Min.Z;
|
---|
| 1250 | end.X = m_clippingView.Max.X;
|
---|
| 1251 | end.Y = start.Y;
|
---|
| 1252 | end.Z = start.Z;
|
---|
| 1253 | anchor = new PointF(0,0); //TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1254 | padX = -m_camera.SinPhi * padX;
|
---|
| 1255 | padY = (m_camera.CosPhi - m_camera.SinRho * m_camera.SinPhi) * (padY) + m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1256 | break;
|
---|
| 1257 | case CameraQuadrant.TopLeftBack:
|
---|
| 1258 | start.X = m_clippingView.Min.X;
|
---|
| 1259 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1260 | start.Z = m_clippingView.Min.Z;
|
---|
| 1261 | end.X = m_clippingView.Max.X;
|
---|
| 1262 | end.Y = start.Y;
|
---|
| 1263 | end.Z = start.Z;
|
---|
| 1264 | anchor = new PointF(1,0); //TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1265 | padX *= m_camera.SinPhi;
|
---|
| 1266 | padY = (-m_camera.CosPhi - m_camera.SinRho * m_camera.SinPhi) * padY + m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1267 | break;
|
---|
| 1268 | case CameraQuadrant.TopRightBack:
|
---|
| 1269 | start.X = m_clippingView.Min.X;
|
---|
| 1270 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1271 | start.Z = m_clippingView.Min.Z;
|
---|
| 1272 | end.X = m_clippingView.Max.X;
|
---|
| 1273 | end.Y = start.Y;
|
---|
| 1274 | end.Z = start.Z;
|
---|
| 1275 | anchor = new PointF(0,0); //TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1276 | padX *= m_camera.SinPhi;
|
---|
| 1277 | padY = (-m_camera.CosPhi + m_camera.SinRho * m_camera.SinPhi) * padY - m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1278 | break;
|
---|
| 1279 | case CameraQuadrant.TopRightFront:
|
---|
| 1280 | start.X = m_clippingView.Min.X;
|
---|
| 1281 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1282 | start.Z = m_clippingView.Min.Z;
|
---|
| 1283 | end.X = m_clippingView.Max.X;
|
---|
| 1284 | end.Y = start.Y;
|
---|
| 1285 | end.Z = start.Z;
|
---|
| 1286 | if (m_camera.Is2DView) {
|
---|
| 1287 | anchor = new PointF(.5f, 0); //TickLabelAlign.center | TickLabelAlign.top;
|
---|
| 1288 | } else {
|
---|
| 1289 | anchor = new PointF(1,0); //TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1290 | }
|
---|
| 1291 | padX *= -m_camera.SinPhi;
|
---|
| 1292 | padY = (m_camera.CosPhi + m_camera.SinRho * m_camera.SinPhi) * padY - m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1293 | break;
|
---|
| 1294 | case CameraQuadrant.BottomLeftFront:
|
---|
| 1295 | start.X = m_clippingView.Min.X;
|
---|
| 1296 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1297 | start.Z = m_clippingView.Min.Z;
|
---|
| 1298 | end.X = m_clippingView.Max.X;
|
---|
| 1299 | end.Y = start.Y;
|
---|
| 1300 | end.Z = start.Z;
|
---|
| 1301 | anchor = new PointF(1,0); //TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1302 | padX *= m_camera.SinPhi;
|
---|
| 1303 | padY = (m_camera.CosPhi - m_camera.SinRho * m_camera.SinPhi) * padY + m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1304 | break;
|
---|
| 1305 | case CameraQuadrant.BottomLeftBack:
|
---|
| 1306 | start.X = m_clippingView.Min.X;
|
---|
| 1307 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1308 | start.Z = m_clippingView.Min.Z;
|
---|
| 1309 | end.X = m_clippingView.Max.X;
|
---|
| 1310 | end.Y = start.Y;
|
---|
| 1311 | end.Z = start.Z;
|
---|
| 1312 | anchor = new PointF(0,0); //TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1313 | padX *= -m_camera.SinPhi;
|
---|
| 1314 | padY = (-m_camera.CosPhi - m_camera.SinRho * m_camera.SinPhi) * padY + m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1315 | break;
|
---|
| 1316 | case CameraQuadrant.BottomRightBack:
|
---|
| 1317 | start.X = m_clippingView.Min.X;
|
---|
| 1318 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1319 | start.Z = m_clippingView.Min.Z;
|
---|
| 1320 | end.X = m_clippingView.Max.X;
|
---|
| 1321 | end.Y = start.Y;
|
---|
| 1322 | end.Z = start.Z;
|
---|
| 1323 | anchor = new PointF(1,0); //TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1324 | padX *= -m_camera.SinPhi;
|
---|
| 1325 | padY = (-m_camera.CosPhi + m_camera.SinRho * m_camera.SinPhi) * padY - m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1326 | break;
|
---|
| 1327 | default: // BottomRightFront
|
---|
| 1328 | start.X = m_clippingView.Min.X;
|
---|
| 1329 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1330 | start.Z = m_clippingView.Min.Z;
|
---|
| 1331 | end.X = m_clippingView.Max.X;
|
---|
| 1332 | end.Y = start.Y;
|
---|
| 1333 | end.Z = start.Z;
|
---|
| 1334 | anchor = new PointF(0,0); //TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1335 | padX *= m_camera.SinPhi;
|
---|
| 1336 | padY = (m_camera.CosPhi + m_camera.SinRho * m_camera.SinPhi) * padY - m_camera.SinPhi * ticks.Font.Height / 2;
|
---|
| 1337 | break;
|
---|
| 1338 | }
|
---|
| 1339 | World2Screen(start, end, out start2D, out end2D);
|
---|
| 1340 | // align in screen coords
|
---|
| 1341 | // int offY = (int)((m_camera.SinRho - (m_camera.SinPhi % Math.PI))
|
---|
| 1342 | // * m_axes[0].LabeledTicks.Font.Height / 2
|
---|
| 1343 | // + padY);
|
---|
| 1344 | // add padding
|
---|
| 1345 | //System.Diagnostics.Debug.WriteLine(m_camera.Phi);
|
---|
| 1346 | start2D.Y += (int)padY + 1;
|
---|
| 1347 | end2D.Y += (int)padY + 1;
|
---|
| 1348 | start2D.X += (int)(padX + 1);
|
---|
| 1349 | end2D.X += (int)(padX + 1);
|
---|
| 1350 | return anchor;
|
---|
| 1351 | }
|
---|
| 1352 | protected PointF GetYTickLabelLine(out Point start2D, out Point end2D) {
|
---|
| 1353 | PointF anchor; // = new PointF(0,0); // TickLabelAlign.left;
|
---|
| 1354 | ILPoint3Df start = new ILPoint3Df(), end = new ILPoint3Df();
|
---|
| 1355 | ILTickCollection ticks = m_axes[1].LabeledTicks;
|
---|
| 1356 | float tickLen = (ticks.Direction == TickDirection.Outside) ?
|
---|
| 1357 | ticks.TickFraction : 0f;
|
---|
| 1358 | float padX = ticks.Padding, padY = padX;
|
---|
| 1359 | if (m_camera.Is2DView) {
|
---|
| 1360 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1361 | start.Y = m_clippingView.Min.Y;
|
---|
| 1362 | start.Z = m_clippingView.Min.Z;
|
---|
| 1363 | end.X = start.X;
|
---|
| 1364 | end.Y = m_clippingView.Max.Y;
|
---|
| 1365 | end.Z = start.Z;
|
---|
| 1366 | anchor = new PointF(1, 0); // TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1367 | padX *= -m_camera.CosPhi;
|
---|
| 1368 | padY = (-m_camera.SinPhi + m_camera.SinRho * m_camera.CosPhi) * padY - m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1369 | } else {
|
---|
| 1370 | switch (m_camera.Quadrant) {
|
---|
| 1371 | case CameraQuadrant.TopLeftFront:
|
---|
| 1372 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1373 | start.Y = m_clippingView.Min.Y;
|
---|
| 1374 | start.Z = m_clippingView.Min.Z;
|
---|
| 1375 | end.X = start.X;
|
---|
| 1376 | end.Y = m_clippingView.Max.Y;
|
---|
| 1377 | end.Z = start.Z;
|
---|
| 1378 | anchor = new PointF(1, 0); // TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1379 | padX *= -m_camera.CosPhi;
|
---|
| 1380 | padY = (-m_camera.SinPhi + m_camera.SinRho * m_camera.CosPhi) * padY - m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1381 | break;
|
---|
| 1382 | case CameraQuadrant.TopLeftBack:
|
---|
| 1383 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1384 | start.Y = m_clippingView.Min.Y;
|
---|
| 1385 | start.Z = m_clippingView.Min.Z;
|
---|
| 1386 | end.X = start.X;
|
---|
| 1387 | end.Y = m_clippingView.Max.Y;
|
---|
| 1388 | end.Z = start.Z;
|
---|
| 1389 | anchor = new PointF(0, 0); // TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1390 | padX *= -m_camera.CosPhi;
|
---|
| 1391 | padY = (-m_camera.SinPhi - m_camera.SinRho * m_camera.CosPhi) * padY + m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1392 | break;
|
---|
| 1393 | case CameraQuadrant.TopRightBack:
|
---|
| 1394 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1395 | start.Y = m_clippingView.Min.Y;
|
---|
| 1396 | start.Z = m_clippingView.Min.Z;
|
---|
| 1397 | end.X = start.X;
|
---|
| 1398 | end.Y = m_clippingView.Max.Y;
|
---|
| 1399 | end.Z = start.Z;
|
---|
| 1400 | anchor = new PointF(1,0); // TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1401 | padX *= m_camera.CosPhi;
|
---|
| 1402 | padY = (m_camera.SinPhi - m_camera.SinRho * m_camera.CosPhi) * padY + m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1403 | break;
|
---|
| 1404 | case CameraQuadrant.TopRightFront:
|
---|
| 1405 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1406 | start.Y = m_clippingView.Min.Y;
|
---|
| 1407 | start.Z = m_clippingView.Min.Z;
|
---|
| 1408 | end.X = start.X;
|
---|
| 1409 | end.Y = m_clippingView.Max.Y;
|
---|
| 1410 | end.Z = start.Z;
|
---|
| 1411 | anchor = new PointF(0,0); // TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1412 | padX *= m_camera.CosPhi;
|
---|
| 1413 | padY = (m_camera.SinPhi + m_camera.SinRho * m_camera.CosPhi) * padY - m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1414 | break;
|
---|
| 1415 | case CameraQuadrant.BottomLeftFront:
|
---|
| 1416 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1417 | start.Y = m_clippingView.Min.Y;
|
---|
| 1418 | start.Z = m_clippingView.Min.Z;
|
---|
| 1419 | end.X = start.X;
|
---|
| 1420 | end.Y = m_clippingView.Max.Y;
|
---|
| 1421 | end.Z = start.Z;
|
---|
| 1422 | anchor = new PointF(0,0); // TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1423 | padX *= m_camera.CosPhi;
|
---|
| 1424 | padY = (-m_camera.SinPhi + m_camera.SinRho * m_camera.CosPhi) * padY - m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1425 | break;
|
---|
| 1426 | case CameraQuadrant.BottomLeftBack:
|
---|
| 1427 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1428 | start.Y = m_clippingView.Min.Y;
|
---|
| 1429 | start.Z = m_clippingView.Min.Z;
|
---|
| 1430 | end.X = start.X;
|
---|
| 1431 | end.Y = m_clippingView.Max.Y;
|
---|
| 1432 | end.Z = start.Z;
|
---|
| 1433 | anchor = new PointF(1,0); // TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1434 | padX *= m_camera.CosPhi;
|
---|
| 1435 | padY = (-m_camera.SinPhi - m_camera.SinRho * m_camera.CosPhi) * padY + m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1436 | break;
|
---|
| 1437 | case CameraQuadrant.BottomRightBack:
|
---|
| 1438 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1439 | start.Y = m_clippingView.Min.Y;
|
---|
| 1440 | start.Z = m_clippingView.Min.Z;
|
---|
| 1441 | end.X = start.X;
|
---|
| 1442 | end.Y = m_clippingView.Max.Y;
|
---|
| 1443 | end.Z = start.Z;
|
---|
| 1444 | anchor = new PointF(0,0); // TickLabelAlign.left | TickLabelAlign.top;
|
---|
| 1445 | padX *= -m_camera.CosPhi;
|
---|
| 1446 | padY = (m_camera.SinPhi - m_camera.SinRho * m_camera.CosPhi) * padY + m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1447 | break;
|
---|
| 1448 | default: // BottomRightFront
|
---|
| 1449 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1450 | start.Y = m_clippingView.Min.Y;
|
---|
| 1451 | start.Z = m_clippingView.Min.Z;
|
---|
| 1452 | end.X = start.X;
|
---|
| 1453 | end.Y = m_clippingView.Max.Y;
|
---|
| 1454 | end.Z = start.Z;
|
---|
| 1455 | anchor = new PointF(1,0); // TickLabelAlign.right | TickLabelAlign.top;
|
---|
| 1456 | padX *= -m_camera.CosPhi;
|
---|
| 1457 | padY = (m_camera.SinPhi + m_camera.SinRho * m_camera.CosPhi) * padY - m_camera.CosPhi * ticks.Font.Height / 2;
|
---|
| 1458 | break;
|
---|
| 1459 | }
|
---|
| 1460 | }
|
---|
| 1461 | World2Screen(start, end, out start2D, out end2D);
|
---|
| 1462 | // align in screen coords
|
---|
| 1463 | //int offY = (int)(Math.Abs(m_camera.CosPhi) * ticks.Font.Height / 2);
|
---|
| 1464 | //offY -= (int)(Math.Sin(m_camera.Rho) * ticks.Font.Height / 2);
|
---|
| 1465 | start2D.Y += (int)padY;
|
---|
| 1466 | end2D.Y += (int)padY;
|
---|
| 1467 | start2D.X += (int)padX;
|
---|
| 1468 | end2D.X += (int)padX;
|
---|
| 1469 | return anchor;
|
---|
| 1470 | }
|
---|
| 1471 | protected PointF GetZTickLabelLine(out Point start2D, out Point end2D) {
|
---|
| 1472 | PointF anchor = new PointF(1, .5f); // TickLabelAlign.vertCenter | TickLabelAlign.right;
|
---|
| 1473 | ILPoint3Df start = new ILPoint3Df(), end = new ILPoint3Df();
|
---|
| 1474 | ILTickCollection ticks = m_axes[2].LabeledTicks;
|
---|
| 1475 | float tickLen = 0;
|
---|
| 1476 | if (ticks.Direction == TickDirection.Outside)
|
---|
| 1477 | tickLen = ticks.TickFraction;
|
---|
| 1478 | start.Z = m_clippingView.Min.Z;
|
---|
| 1479 | switch (m_camera.Quadrant) {
|
---|
| 1480 | case CameraQuadrant.TopLeftFront:
|
---|
| 1481 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1482 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1483 | break;
|
---|
| 1484 | case CameraQuadrant.TopLeftBack:
|
---|
| 1485 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1486 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1487 | break;
|
---|
| 1488 | case CameraQuadrant.TopRightBack:
|
---|
| 1489 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1490 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1491 | break;
|
---|
| 1492 | case CameraQuadrant.TopRightFront:
|
---|
| 1493 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1494 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1495 | break;
|
---|
| 1496 | case CameraQuadrant.BottomLeftFront:
|
---|
| 1497 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1498 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1499 | break;
|
---|
| 1500 | case CameraQuadrant.BottomLeftBack:
|
---|
| 1501 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1502 | start.Y = m_clippingView.Max.Y + tickLen;
|
---|
| 1503 | break;
|
---|
| 1504 | case CameraQuadrant.BottomRightBack:
|
---|
| 1505 | start.X = m_clippingView.Max.X + tickLen;
|
---|
| 1506 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1507 | break;
|
---|
| 1508 | case CameraQuadrant.BottomRightFront:
|
---|
| 1509 | start.X = m_clippingView.Min.X - tickLen;
|
---|
| 1510 | start.Y = m_clippingView.Min.Y - tickLen;
|
---|
| 1511 | break;
|
---|
| 1512 | default:
|
---|
| 1513 | break;
|
---|
| 1514 | }
|
---|
| 1515 | end = start;
|
---|
| 1516 | end.Z = m_clippingView.Max.Z;
|
---|
| 1517 | World2Screen(start, end, out start2D, out end2D);
|
---|
| 1518 | start2D.X -= (ticks.Padding - 1);
|
---|
| 1519 | end2D.X -= (ticks.Padding - 1);
|
---|
| 1520 | return anchor;
|
---|
| 1521 | }
|
---|
| 1522 | /// <summary>
|
---|
| 1523 | /// Get size of projected view cube - after (!) rotation but before projection -> world space
|
---|
| 1524 | /// includes the bounding box, tightly enclosing the current view limits setting
|
---|
| 1525 | /// No labels, No ticks included!! Just the data cube with roatation!
|
---|
| 1526 | /// </summary>
|
---|
| 1527 | /// <param name="x">out, screen size for X</param>
|
---|
| 1528 | /// <param name="y">out, screen size for Y</param>
|
---|
| 1529 | /// <param name="z">out, screen size for Z</param>
|
---|
| 1530 | protected virtual void GetTransformedSize(out float x, out float y, out float z) {
|
---|
| 1531 | float xSize = m_clippingView.WidthF; // the unrotated width - without labels size
|
---|
| 1532 | float ySize = m_clippingView.HeightF; // dito for height
|
---|
| 1533 | float zSize = m_clippingView.DepthF;
|
---|
| 1534 | if (m_camera.Rho != 0.0f || m_camera.Phi != 0.0f) { // standard 2D view?
|
---|
| 1535 | float cosPhi = Math.Abs(m_camera.CosPhi);
|
---|
| 1536 | float sinPhi = Math.Abs(m_camera.SinPhi);
|
---|
| 1537 | x = (cosPhi * xSize + sinPhi * ySize); //zSize * Math.Abs(m_camera.SinRho) + (Math.Abs(m_camera.CosRho) *
|
---|
| 1538 | y = zSize * Math.Abs(m_camera.SinRho)
|
---|
| 1539 | + (Math.Abs(m_camera.CosRho) * (sinPhi * xSize + cosPhi * ySize));
|
---|
| 1540 | z = zSize * Math.Abs(m_camera.CosRho)
|
---|
| 1541 | + (Math.Abs(m_camera.SinRho) * (sinPhi * xSize + cosPhi * ySize));
|
---|
| 1542 | } else {
|
---|
| 1543 | x = xSize;
|
---|
| 1544 | y = ySize;
|
---|
| 1545 | z = zSize;
|
---|
| 1546 | }
|
---|
| 1547 | }
|
---|
| 1548 |
|
---|
| 1549 | private void axisLabelVertical2D(ILAxis axis) {
|
---|
| 1550 | ILLabel label = axis.Label;
|
---|
| 1551 | ILTickCollection ticks = axis.LabeledTicks;
|
---|
| 1552 | Size tickSize = ticks.Size, labelSize = label.Size;
|
---|
| 1553 | label.Orientation = TextOrientation.Vertical;
|
---|
| 1554 | label.Anchor = new PointF(.5f, 0);
|
---|
| 1555 | label.m_position.X = ticks.m_lineEnd.X - tickSize.Width - ticks.Padding - label.Padding;
|
---|
| 1556 | switch (label.Alignment) {
|
---|
| 1557 | case LabelAlign.Center:
|
---|
| 1558 | label.m_position.Y = (ticks.m_lineEnd.Y + ticks.m_lineStart.Y) / 2;
|
---|
| 1559 | break;
|
---|
| 1560 | case LabelAlign.Upper:
|
---|
| 1561 | label.m_position.Y = ticks.m_lineEnd.Y + labelSize.Width / 2;
|
---|
| 1562 | break;
|
---|
| 1563 | default: // lower
|
---|
| 1564 | label.m_position.Y = ticks.m_lineStart.Y - labelSize.Width / 2;
|
---|
| 1565 | break;
|
---|
| 1566 | }
|
---|
| 1567 | if (label.m_position.Y < labelSize.Width / 2) {
|
---|
| 1568 | label.m_position.Y = labelSize.Width / 2;
|
---|
| 1569 | }
|
---|
| 1570 | if (label.m_position.Y > ClientSize.Height - 1 - labelSize.Width / 2) {
|
---|
| 1571 | label.m_position.Y = ClientSize.Height - 1 - labelSize.Width / 2;
|
---|
| 1572 | }
|
---|
| 1573 | }
|
---|
| 1574 | private void positionZAxisLabel(ILAxis axis) {
|
---|
| 1575 | ILLabel label = axis.Label;
|
---|
| 1576 | ILTickCollection ticks = axis.LabeledTicks;
|
---|
| 1577 | Size tickSize = ticks.Size, labelSize = label.Size;
|
---|
| 1578 | label.Orientation = TextOrientation.Vertical;
|
---|
| 1579 | label.Anchor = new PointF(.5f, 0);
|
---|
| 1580 | switch (label.Alignment) {
|
---|
| 1581 | case LabelAlign.Center:
|
---|
| 1582 | label.m_position.Y = (ticks.m_lineStart.Y + ticks.m_lineEnd.Y) / 2;
|
---|
| 1583 | break;
|
---|
| 1584 | case LabelAlign.Upper:
|
---|
| 1585 | label.m_position.Y = ticks.m_lineEnd.Y - labelSize.Width / 2;
|
---|
| 1586 | break;
|
---|
| 1587 | default: // lower
|
---|
| 1588 | label.m_position.Y = ticks.m_lineStart.Y + labelSize.Width / 2 ;
|
---|
| 1589 | break;
|
---|
| 1590 | }
|
---|
| 1591 | label.m_position.X = ticks.m_lineStart.X - tickSize.Width - ticks.Padding - label.Padding;
|
---|
| 1592 | if (label.m_position.Y < labelSize.Width / 2) {
|
---|
| 1593 | label.m_position.Y = labelSize.Width / 2;
|
---|
| 1594 | }
|
---|
| 1595 | if (label.m_position.Y > ClientSize.Height - 1 - labelSize.Width / 2) {
|
---|
| 1596 | label.m_position.Y = ClientSize.Height - 1 - labelSize.Width / 2;
|
---|
| 1597 | //label.Orientation = TextOrientation.Horizontal;
|
---|
| 1598 | //label.m_position.X = label.Padding;
|
---|
| 1599 | //label.m_position.Y = label.Padding;
|
---|
| 1600 | }
|
---|
| 1601 | }
|
---|
| 1602 | private void axisLabel_BottomRightTopLeft(ILRenderProperties p, ILAxis axis) {
|
---|
| 1603 | ILLabel label = axis.Label;
|
---|
| 1604 | ILTickCollection ticks = axis.LabeledTicks;
|
---|
| 1605 | Size tickSize = ticks.Size, labelSize = label.Size;
|
---|
| 1606 | label.Anchor = new PointF(.5f, 0);
|
---|
| 1607 | bool horiz = decideLabelHorizontalOrientation(p, m_camera, axis);
|
---|
| 1608 | if (horiz) {
|
---|
| 1609 | #region Horizontal
|
---|
| 1610 | label.Orientation = TextOrientation.Horizontal;
|
---|
| 1611 | switch (label.Alignment) {
|
---|
| 1612 | case LabelAlign.Center:
|
---|
| 1613 | label.m_position.X = (ticks.m_lineStart.X + ticks.m_lineEnd.X) / 2;
|
---|
| 1614 | break;
|
---|
| 1615 | case LabelAlign.Upper:
|
---|
| 1616 | label.m_position.X = ticks.m_lineEnd.X + labelSize.Width / 2;
|
---|
| 1617 | break;
|
---|
| 1618 | default: // lower
|
---|
| 1619 | label.m_position.X = ticks.m_lineStart.X - labelSize.Width / 2;
|
---|
| 1620 | break;
|
---|
| 1621 | }
|
---|
| 1622 | label.m_position.Y = ticks.m_lineStart.Y + tickSize.Height + ticks.Padding + label.Padding;
|
---|
| 1623 | if (label.m_position.X < labelSize.Width / 2) {
|
---|
| 1624 | label.m_position.X = labelSize.Width / 2;
|
---|
| 1625 | }
|
---|
| 1626 | #endregion
|
---|
| 1627 | } else {
|
---|
| 1628 | #region Vertical
|
---|
| 1629 | label.Orientation = TextOrientation.Vertical;
|
---|
| 1630 | switch (label.Alignment) {
|
---|
| 1631 | case LabelAlign.Center:
|
---|
| 1632 | label.m_position.Y = (ticks.m_lineStart.Y + ticks.m_lineEnd.Y) / 2;
|
---|
| 1633 | break;
|
---|
| 1634 | case LabelAlign.Upper:
|
---|
| 1635 | label.m_position.Y = ticks.m_lineEnd.Y + labelSize.Width / 2;
|
---|
| 1636 | break;
|
---|
| 1637 | default: // lower
|
---|
| 1638 | label.m_position.Y = ticks.m_lineStart.Y - labelSize.Width / 2;
|
---|
| 1639 | break;
|
---|
| 1640 | }
|
---|
| 1641 | label.m_position.X = ticks.m_lineEnd.X - tickSize.Width - label.Padding - ticks.Padding;
|
---|
| 1642 | if (label.m_position.Y < labelSize.Width / 2)
|
---|
| 1643 | label.m_position.Y = labelSize.Width / 2;
|
---|
| 1644 | if (label.m_position.Y > ClientSize.Height - 1 - labelSize.Width / 2) {
|
---|
| 1645 | label.m_position.Y = ClientSize.Height - 1 - labelSize.Width / 2;
|
---|
| 1646 | }
|
---|
| 1647 | #endregion
|
---|
| 1648 | }
|
---|
| 1649 | }
|
---|
| 1650 | private void axisLabel_BottomLeftTopRight(ILRenderProperties p, ILAxis axis) {
|
---|
| 1651 | ILLabel label = axis.Label;
|
---|
| 1652 | ILTickCollection ticks = axis.LabeledTicks;
|
---|
| 1653 | Size tickSize = ticks.Size, labelSize = label.Size;
|
---|
| 1654 | bool horiz = decideLabelHorizontalOrientation(p, m_camera, axis);
|
---|
| 1655 | if (horiz) {
|
---|
| 1656 | #region Horizontal
|
---|
| 1657 | label.Orientation = TextOrientation.Horizontal;
|
---|
| 1658 | label.Anchor = new PointF(0.5f,0);
|
---|
| 1659 | switch (label.Alignment) {
|
---|
| 1660 | case LabelAlign.Center:
|
---|
| 1661 | label.m_position.X = (ticks.m_lineEnd.X + ticks.m_lineStart.X) / 2;
|
---|
| 1662 | break;
|
---|
| 1663 | case LabelAlign.Upper:
|
---|
| 1664 | label.m_position.X = ticks.m_lineEnd.X - label.Size.Width / 2;
|
---|
| 1665 | break;
|
---|
| 1666 | default: // lower
|
---|
| 1667 | label.m_position.X = ticks.m_lineStart.X + label.Size.Width / 2;
|
---|
| 1668 | break;
|
---|
| 1669 | }
|
---|
| 1670 | label.m_position.Y = ticks.m_lineStart.Y + tickSize.Height + ticks.Padding + label.Padding;
|
---|
| 1671 | if (label.m_position.X > ClientSize.Width - labelSize.Width / 2) {
|
---|
| 1672 | label.m_position.X = ClientSize.Width - labelSize.Width / 2;
|
---|
| 1673 | }
|
---|
| 1674 | #endregion
|
---|
| 1675 | } else {
|
---|
| 1676 | #region Vertical
|
---|
| 1677 | label.Orientation = TextOrientation.Vertical;
|
---|
| 1678 | label.Anchor = new PointF(0.5f, 1);
|
---|
| 1679 | switch (label.Alignment) {
|
---|
| 1680 | case LabelAlign.Center:
|
---|
| 1681 | label.m_position.Y = (ticks.m_lineEnd.Y + ticks.m_lineStart.Y) / 2;
|
---|
| 1682 | break;
|
---|
| 1683 | case LabelAlign.Upper:
|
---|
| 1684 | label.m_position.Y = ticks.m_lineEnd.Y + labelSize.Width / 2;
|
---|
| 1685 | break;
|
---|
| 1686 | default: // lower
|
---|
| 1687 | label.m_position.Y = ticks.m_lineStart.Y - labelSize.Width / 2;
|
---|
| 1688 | break;
|
---|
| 1689 | }
|
---|
| 1690 | label.m_position.X = ticks.m_lineEnd.X + tickSize.Width + ticks.Padding + label.Padding;
|
---|
| 1691 | if (label.m_position.Y > ClientSize.Height - 1 - labelSize.Width / 2) {
|
---|
| 1692 | label.m_position.Y = ClientSize.Height - 1 - labelSize.Width / 2;
|
---|
| 1693 | }
|
---|
| 1694 | #endregion
|
---|
| 1695 | }
|
---|
| 1696 | }
|
---|
| 1697 | private void axisLabel_TopRightBottomLeft(ILRenderProperties p, ILAxis axis) {
|
---|
| 1698 | ILLabel label = axis.Label;
|
---|
| 1699 | ILTickCollection ticks = axis.LabeledTicks;
|
---|
| 1700 | Size tickSize = ticks.Size, labelSize = label.Size;
|
---|
| 1701 | bool horiz = decideLabelHorizontalOrientation(p, m_camera, axis);
|
---|
| 1702 | label.Anchor = new PointF(.5f, 0);
|
---|
| 1703 | if (horiz) {
|
---|
| 1704 | #region Horizontal
|
---|
| 1705 | label.Orientation = TextOrientation.Horizontal;
|
---|
| 1706 | switch (label.Alignment) {
|
---|
| 1707 | case LabelAlign.Center:
|
---|
| 1708 | label.m_position.X = (ticks.m_lineEnd.X + ticks.m_lineStart.X) / 2;
|
---|
| 1709 | break;
|
---|
| 1710 | case LabelAlign.Upper:
|
---|
| 1711 | label.m_position.X = ticks.m_lineEnd.X + labelSize.Width / 2;
|
---|
| 1712 | break;
|
---|
| 1713 | default: // lower
|
---|
| 1714 | label.m_position.X = ticks.m_lineStart.X - labelSize.Width / 2;
|
---|
| 1715 | break;
|
---|
| 1716 | }
|
---|
| 1717 | label.m_position.Y = ticks.m_lineEnd.Y + tickSize.Height + ticks.Padding + label.Padding;
|
---|
| 1718 | if (label.m_position.X < labelSize.Width / 2)
|
---|
| 1719 | label.m_position.X = labelSize.Width / 2;
|
---|
| 1720 | if (label.m_position.X > ClientSize.Width - labelSize.Width / 2 - 1)
|
---|
| 1721 | label.m_position.X = ClientSize.Width - labelSize.Width / 2 - 1;
|
---|
| 1722 | #endregion
|
---|
| 1723 | } else {
|
---|
| 1724 | #region Vertical
|
---|
| 1725 | label.Orientation = TextOrientation.Vertical;
|
---|
| 1726 | switch (label.Alignment) {
|
---|
| 1727 | case LabelAlign.Center:
|
---|
| 1728 | label.m_position.Y = (ticks.m_lineEnd.Y + ticks.m_lineStart.Y) / 2;
|
---|
| 1729 | break;
|
---|
| 1730 | case LabelAlign.Upper:
|
---|
| 1731 | label.m_position.Y = ticks.m_lineEnd.Y - labelSize.Width / 2;
|
---|
| 1732 | break;
|
---|
| 1733 | default: // lower
|
---|
| 1734 | label.m_position.Y = ticks.m_lineStart.Y + labelSize.Width / 2;
|
---|
| 1735 | break;
|
---|
| 1736 | }
|
---|
| 1737 | label.m_position.X = ticks.m_lineStart.X + tickSize.Width + ticks.Padding + label.Padding;
|
---|
| 1738 | if (label.m_position.Y < labelSize.Width / 2) {
|
---|
| 1739 | label.m_position.Y = labelSize.Width / 2;
|
---|
| 1740 | }
|
---|
| 1741 | if (label.m_position.Y > ClientSize.Height - 1 - labelSize.Width / 2) {
|
---|
| 1742 | label.m_position.Y = ClientSize.Height - 1 - labelSize.Width / 2;
|
---|
| 1743 | }
|
---|
| 1744 | #endregion
|
---|
| 1745 | }
|
---|
| 1746 | }
|
---|
| 1747 | private void axisLabel_TopLeftBottomRight(ILRenderProperties p, ILAxis axis) {
|
---|
| 1748 | ILLabel label = axis.Label;
|
---|
| 1749 | ILTickCollection ticks = axis.LabeledTicks;
|
---|
| 1750 | Size tickSize = ticks.Size, labelSize = label.Size;
|
---|
| 1751 | bool horiz = decideLabelHorizontalOrientation(p, m_camera, axis);
|
---|
| 1752 | label.Anchor = new PointF(.5f, 0);
|
---|
| 1753 | if (horiz) {
|
---|
| 1754 | #region Horizontal
|
---|
| 1755 | label.Orientation = TextOrientation.Horizontal;
|
---|
| 1756 | switch (label.Alignment) {
|
---|
| 1757 | case LabelAlign.Center:
|
---|
| 1758 | label.m_position.X = (ticks.m_lineEnd.X + ticks.m_lineStart.X) / 2;
|
---|
| 1759 | break;
|
---|
| 1760 | case LabelAlign.Upper:
|
---|
| 1761 | label.m_position.X = ticks.m_lineEnd.X - labelSize.Width / 2;
|
---|
| 1762 | break;
|
---|
| 1763 | default: // lower
|
---|
| 1764 | label.m_position.X = ticks.m_lineStart.X + labelSize.Width / 2;
|
---|
| 1765 | break;
|
---|
| 1766 | }
|
---|
| 1767 | label.m_position.Y = ticks.m_lineEnd.Y + tickSize.Height + ticks.Padding + label.Padding;
|
---|
| 1768 | if (label.m_position.X < labelSize.Width / 2) {
|
---|
| 1769 | label.m_position.X = labelSize.Width / 2;
|
---|
| 1770 | }
|
---|
| 1771 | #endregion
|
---|
| 1772 | } else {
|
---|
| 1773 | #region Vertical
|
---|
| 1774 | label.Orientation = TextOrientation.Vertical;
|
---|
| 1775 | switch (label.Alignment) {
|
---|
| 1776 | case LabelAlign.Center:
|
---|
| 1777 | label.m_position.Y = (ticks.m_lineEnd.Y + ticks.m_lineStart.Y) / 2;
|
---|
| 1778 | break;
|
---|
| 1779 | case LabelAlign.Upper:
|
---|
| 1780 | label.m_position.Y = ticks.m_lineEnd.Y - labelSize.Width / 2;
|
---|
| 1781 | break;
|
---|
| 1782 | default: // lower
|
---|
| 1783 | label.m_position.Y = ticks.m_lineStart.Y + labelSize.Width / 2;
|
---|
| 1784 | break;
|
---|
| 1785 | }
|
---|
| 1786 | label.m_position.X = ticks.m_lineStart.X - tickSize.Width - ticks.Padding - label.Padding;
|
---|
| 1787 | if (label.m_position.Y < labelSize.Width / 2) {
|
---|
| 1788 | label.m_position.Y = labelSize.Width / 2;
|
---|
| 1789 | }
|
---|
| 1790 | if (label.m_position.Y > ClientSize.Height - 1 - labelSize.Width / 2) {
|
---|
| 1791 | label.m_position.Y = ClientSize.Height - 1 - labelSize.Width / 2;
|
---|
| 1792 | }
|
---|
| 1793 | #endregion
|
---|
| 1794 | }
|
---|
| 1795 | }
|
---|
| 1796 |
|
---|
| 1797 | // return true if the label needs horizontal orientation
|
---|
| 1798 | private bool decideLabelHorizontalOrientation(ILRenderProperties p, ILCamera m_camera, ILAxis axis) {
|
---|
| 1799 | if (p.Reason == RenderReason.RecalcLabels) {
|
---|
| 1800 | return axis.Label.Orientation == TextOrientation.Horizontal;
|
---|
| 1801 | }
|
---|
| 1802 | float offX = axis.LabeledTicks.m_lineStart.X - axis.LabeledTicks.m_lineEnd.X;
|
---|
| 1803 | float offY = axis.LabeledTicks.m_lineStart.Y - axis.LabeledTicks.m_lineEnd.Y;
|
---|
| 1804 | return offY * offY < offX * offX;
|
---|
| 1805 | //if (axis.Index == 0) {
|
---|
| 1806 | // b = (float)((1.0 - m_camera.SinRho * 0.9) * Math.Sin(m_camera.Phi * 2.0f));
|
---|
| 1807 | //} else if (axis.Index == 1) {
|
---|
| 1808 |
|
---|
| 1809 | //}
|
---|
| 1810 | //return (m_camera.SinRho >= LABELS_VERTICAL_MIN_RHO
|
---|
| 1811 | // || Math.Sign(Math.Cos(m_camera.Phi * 2.0)) != (axis.Index * 2 - 1));
|
---|
| 1812 | }
|
---|
| 1813 | private int GetMargin4OptimalLabelX() {
|
---|
| 1814 | return 0;
|
---|
| 1815 | }
|
---|
| 1816 | private int GetMargin4OptimalLabelY() {
|
---|
| 1817 | return 0;
|
---|
| 1818 | }
|
---|
| 1819 | private Size GetMaxTicLabelSize(Graphics gr) {
|
---|
| 1820 | Size ret = m_axes.MeasureMaxTickLabelSize(gr);
|
---|
| 1821 | // add label sizes
|
---|
| 1822 | int maxHeight = 0;
|
---|
| 1823 | if (m_axes[0].Label.Visible && !String.IsNullOrEmpty(m_axes[0].Label.Text)) {
|
---|
| 1824 | maxHeight = m_axes[0].Label.Size.Height;
|
---|
| 1825 | }
|
---|
| 1826 | if (m_axes[1].Label.Visible && !String.IsNullOrEmpty(m_axes[1].Label.Text)) {
|
---|
| 1827 | if (maxHeight < m_axes[1].Label.Size.Height)
|
---|
| 1828 | maxHeight = m_axes[1].Label.Size.Height;
|
---|
| 1829 | }
|
---|
| 1830 | if (m_axes[2].Label.Visible && !String.IsNullOrEmpty(m_axes[2].Label.Text)) {
|
---|
| 1831 | if (maxHeight < m_axes[2].Label.Size.Height)
|
---|
| 1832 | maxHeight = m_axes[2].Label.Size.Height;
|
---|
| 1833 | }
|
---|
| 1834 | ret = new Size(ret.Width + maxHeight, ret.Height + maxHeight);
|
---|
| 1835 | return ret;
|
---|
| 1836 | }
|
---|
| 1837 |
|
---|
| 1838 | /// <summary>
|
---|
| 1839 | /// calculate the real pixels of the plot cube rectangle for drawing into
|
---|
| 1840 | /// </summary>
|
---|
| 1841 | /// <param name="xSize"></param>
|
---|
| 1842 | /// <param name="ySize"></param>
|
---|
| 1843 | private void updatePlotCubeScreenRect(float xSize, float ySize, Size tickLabelMargins) {
|
---|
| 1844 | switch (PlotBoxScreenSizeMode) {
|
---|
| 1845 | //case PlotCubeScreenSizeMode.Maximum: // <- will be done in PlotCubeScreenSizeMode.set()
|
---|
| 1846 | // m_plotCubeScreenRectF = new RectangleF(0.0f, 0.0f, 1.0f, 1.0f);
|
---|
| 1847 | // break;
|
---|
| 1848 | case PlotBoxScreenSizeMode.Optimal:
|
---|
| 1849 | case PlotBoxScreenSizeMode.StrictOptimal:
|
---|
| 1850 | float saveX, saveY;
|
---|
| 1851 | saveX = ((float)tickLabelMargins.Width / ClientSize.Width);
|
---|
| 1852 | if (saveX < 0) saveX = 0;
|
---|
| 1853 | if (saveX > 1) saveX = 1;
|
---|
| 1854 | saveY = ((float)tickLabelMargins.Height / ClientSize.Height);
|
---|
| 1855 | if (saveY < 0) saveY = 0;
|
---|
| 1856 | if (saveY > 1) saveY = 1;
|
---|
| 1857 | m_plotBoxScreenRectF = new RectangleF(saveX, saveY, 1f - (2 * saveX), 1f - (2 * saveY));
|
---|
| 1858 | break;
|
---|
| 1859 | default: // manual: use predefined PlotCubeScreenRectF
|
---|
| 1860 | break;
|
---|
| 1861 | }
|
---|
| 1862 | }
|
---|
| 1863 |
|
---|
| 1864 | private void updateLabelPositions(ILRenderProperties p) {
|
---|
| 1865 | positionZAxisLabel(m_axes[2]);
|
---|
| 1866 | switch (m_camera.Quadrant) {
|
---|
| 1867 | case CameraQuadrant.TopRightFront:
|
---|
| 1868 | axisLabel_TopLeftBottomRight(p, m_axes[0]);
|
---|
| 1869 | // special case: 2D view?
|
---|
| 1870 | if (m_camera.SinPhi < 1e-5 && m_camera.SinRho < 1e-5) {
|
---|
| 1871 | axisLabelVertical2D(m_axes[1]);
|
---|
| 1872 | } else {
|
---|
| 1873 | axisLabel_BottomLeftTopRight(p, m_axes[1]);
|
---|
| 1874 | }
|
---|
| 1875 | break;
|
---|
| 1876 | case CameraQuadrant.TopRightBack:
|
---|
| 1877 | axisLabel_TopRightBottomLeft(p, m_axes[0]);
|
---|
| 1878 | axisLabel_TopLeftBottomRight(p, m_axes[1]);
|
---|
| 1879 | break;
|
---|
| 1880 | case CameraQuadrant.TopLeftFront:
|
---|
| 1881 | axisLabel_BottomLeftTopRight(p, m_axes[0]);
|
---|
| 1882 | axisLabel_BottomRightTopLeft(p, m_axes[1]);
|
---|
| 1883 | break;
|
---|
| 1884 | case CameraQuadrant.TopLeftBack:
|
---|
| 1885 | axisLabel_BottomRightTopLeft(p, m_axes[0]);
|
---|
| 1886 | axisLabel_TopRightBottomLeft(p, m_axes[1]);
|
---|
| 1887 | break;
|
---|
| 1888 | case CameraQuadrant.BottomLeftFront:
|
---|
| 1889 | axisLabel_TopLeftBottomRight(p, m_axes[0]);
|
---|
| 1890 | axisLabel_TopRightBottomLeft(p, m_axes[1]);
|
---|
| 1891 | break;
|
---|
| 1892 | case CameraQuadrant.BottomLeftBack:
|
---|
| 1893 | axisLabel_TopRightBottomLeft(p, m_axes[0]);
|
---|
| 1894 | axisLabel_BottomRightTopLeft(p, m_axes[1]);
|
---|
| 1895 | break;
|
---|
| 1896 | case CameraQuadrant.BottomRightBack:
|
---|
| 1897 | axisLabel_BottomRightTopLeft(p, m_axes[0]);
|
---|
| 1898 | axisLabel_BottomLeftTopRight(p, m_axes[1]);
|
---|
| 1899 | break;
|
---|
| 1900 | case CameraQuadrant.BottomRightFront:
|
---|
| 1901 | axisLabel_BottomLeftTopRight(p, m_axes[0]);
|
---|
| 1902 | axisLabel_TopLeftBottomRight(p, m_axes[1]);
|
---|
| 1903 | break;
|
---|
| 1904 | default:
|
---|
| 1905 | break;
|
---|
| 1906 | }
|
---|
| 1907 | }
|
---|
| 1908 |
|
---|
| 1909 | private void updateTickLabelLines() {
|
---|
| 1910 | // determine tick label lines
|
---|
| 1911 | ILTickCollection ticks = m_axes[2].LabeledTicks;
|
---|
| 1912 | ticks.m_anchor = GetZTickLabelLine(out ticks.m_lineStart, out ticks.m_lineEnd);
|
---|
| 1913 | ticks = m_axes[1].LabeledTicks;
|
---|
| 1914 | ticks.m_anchor = GetYTickLabelLine(out ticks.m_lineStart, out ticks.m_lineEnd);
|
---|
| 1915 | ticks = m_axes[0].LabeledTicks;
|
---|
| 1916 | ticks.m_anchor = GetXTickLabelLine(out ticks.m_lineStart, out ticks.m_lineEnd);
|
---|
| 1917 | }
|
---|
| 1918 | #endregion
|
---|
| 1919 |
|
---|
| 1920 | #region factory member
|
---|
| 1921 |
|
---|
| 1922 | /// <summary>
|
---|
| 1923 | /// create OpenGL panel
|
---|
| 1924 | /// </summary>
|
---|
| 1925 | /// <returns>OpenGL panel</returns>
|
---|
| 1926 | public static ILPanel Create () {
|
---|
| 1927 | return Create(GraphicDeviceType.OpenGL);
|
---|
| 1928 | }
|
---|
| 1929 | /// <summary>
|
---|
| 1930 | /// create graphic device specific panel
|
---|
| 1931 | /// </summary>
|
---|
| 1932 | /// <param name="type">specify GL type. Supported are: OpenGL (recommended) or Direct3D (alpha state)</param>
|
---|
| 1933 | /// <returns>GL specific panel</returns>
|
---|
| 1934 | public static ILPanel Create (GraphicDeviceType type) {
|
---|
| 1935 | ILPanel ret; Type panelType; Assembly assembly;
|
---|
| 1936 | string myPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
---|
| 1937 | switch (type) {
|
---|
| 1938 | case GraphicDeviceType.Direct3D:
|
---|
| 1939 | //must create DXPanel dynamically ?
|
---|
| 1940 | // actually not, because DX is split into individual assembly
|
---|
| 1941 | // but under mono it seems the runtime tries to load the d3d part
|
---|
| 1942 | // anyway, so we do without a compile time reference.
|
---|
| 1943 | assembly = Assembly.LoadFile(Path.Combine(myPath,"ILNumerics.DrawingD3D.dll"));
|
---|
| 1944 | panelType = assembly.GetType("ILNumerics.Drawing.Platform.OpenGL.ILDXPanel");
|
---|
| 1945 | ret = (ILPanel)panelType.InvokeMember("ILDXPanel",
|
---|
| 1946 | BindingFlags.DeclaredOnly | BindingFlags.Public
|
---|
| 1947 | | BindingFlags.NonPublic | BindingFlags.Instance
|
---|
| 1948 | | BindingFlags.CreateInstance,
|
---|
| 1949 | null, null, null);
|
---|
| 1950 | return ret;
|
---|
| 1951 | default:
|
---|
| 1952 | // the default is to use OpenGL, which is included into the main assembly (this one)
|
---|
| 1953 | assembly = Assembly.GetExecutingAssembly();
|
---|
| 1954 | panelType = assembly.GetType("ILNumerics.Drawing.Platform.OpenGL.ILOGLPanel");
|
---|
| 1955 | ret = (ILPanel)panelType.InvokeMember("ILOGLPanel",
|
---|
| 1956 | BindingFlags.DeclaredOnly | BindingFlags.Public
|
---|
| 1957 | | BindingFlags.NonPublic | BindingFlags.Instance
|
---|
| 1958 | | BindingFlags.CreateInstance,
|
---|
| 1959 | null, null, null);
|
---|
| 1960 | return ret;
|
---|
| 1961 | }
|
---|
| 1962 | }
|
---|
| 1963 |
|
---|
| 1964 | /// <summary>
|
---|
| 1965 | /// Create GL dependend graph factory
|
---|
| 1966 | /// </summary>
|
---|
| 1967 | /// <returns>ILGraphFactory,will be used for creating all graphs</returns>
|
---|
| 1968 | /// <remarks>derived types may return GL dependend factory</remarks>
|
---|
| 1969 | internal abstract IILCreationFactory GetCreationFactory();
|
---|
| 1970 | #endregion
|
---|
| 1971 |
|
---|
| 1972 |
|
---|
| 1973 | }
|
---|
| 1974 | }
|
---|