Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
DefaultSliderRenderer.cs
Go to the documentation of this file.
1 using System;
2 
3 using SiliconStudio.Core;
4 using SiliconStudio.Core.Mathematics;
5 using SiliconStudio.Paradox.Graphics;
6 using SiliconStudio.Paradox.UI.Controls;
7 
8 namespace SiliconStudio.Paradox.UI.Renderers
9 {
10  /// <summary>
11  /// The default renderer for <see cref="Slider"/>.
12  /// </summary>
13  internal class DefaultSliderRenderer : ElementRenderer
14  {
15  public DefaultSliderRenderer(IServiceRegistry services)
16  : base(services)
17  {
18  }
19 
20  public override void RenderColor(UIElement element, UIRenderingContext context)
21  {
22  base.RenderColor(element, context);
23 
24  var slider = (Slider)element;
25  if(slider.Orientation == Orientation.InDepth)
26  return; // No rendering for in-depth slider for the moment.
27 
28  var axis = (int)slider.Orientation;
29  var axisPrime = (axis + 1) % 2;
30  var color = slider.RenderOpacity * Color.White;
31  var isGaugeReverted = axis == 1 ? !slider.IsDirectionReversed : slider.IsDirectionReversed; // we want the track going up from the bottom in vertical mode by default
32  var sliderRatio = slider.Value / (slider.Maximum - slider.Minimum);
33  var trackOffsets = new Vector2(slider.TrackStartingOffsets[axis], slider.TrackStartingOffsets[axisPrime]);
34  var fullGaugeSize = slider.RenderSizeInternal[axis] - trackOffsets.X - trackOffsets.Y;
35  var trackIdealSize = slider.TrackBackgroundImage != null ? new Vector2?(slider.TrackBackgroundImage.ImageIdealSize) : null;
36 
37  // draws the track background
38  var image = slider.TrackBackgroundImage;
39  if (image != null)
40  {
41  var imageAxis = (int)image.Orientation;
42  var imageOrientation = (ImageOrientation)(axis ^ imageAxis);
43  var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, (axis & imageAxis) == 1);
44 
45  Batch.DrawImage(image.Texture, image.TextureAlpha, ref worldMatrix, ref image.RegionInternal, ref slider.RenderSizeInternal, ref image.BordersInternal, ref color, context.DepthBias, imageOrientation);
46  context.DepthBias += 1;
47  }
48 
49  // draw the track foreground
50  image = slider.TrackForegroundImage;
51  if (image != null)
52  {
53  var imageAxis = (int)image.Orientation;
54  var imageOrientation = (ImageOrientation)(axis ^ imageAxis);
55  var shouldRotate180Degrees = (axis & imageAxis) == 1;
56 
57  var size = new Vector3();
58  size[axis] = sliderRatio * fullGaugeSize;
59  size[axisPrime] = image.ImageIdealSize.Y;
60  if (trackIdealSize.HasValue)
61  size[axisPrime] *= slider.RenderSizeInternal[axisPrime] / trackIdealSize.Value.Y;
62 
63  var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, shouldRotate180Degrees);
64  var halfSizeLeft = (slider.RenderSizeInternal[axis] - size[axis]) / 2;
65  var worldTranslation = GetAdjustedTranslation(isGaugeReverted ? halfSizeLeft - trackOffsets.Y : trackOffsets.X - halfSizeLeft, shouldRotate180Degrees);
66  worldMatrix.M41 += worldTranslation * worldMatrix[(axis << 2) + 0];
67  worldMatrix.M42 += worldTranslation * worldMatrix[(axis << 2) + 1];
68  worldMatrix.M43 += worldTranslation * worldMatrix[(axis << 2) + 2];
69 
70  var borders = image.BordersInternal;
71  var borderStartIndex = (imageAxis <<1 ) + (slider.IsDirectionReversed? 1 : 0);
72  var borderStopIndex = (imageAxis << 1) + (slider.IsDirectionReversed ? 0 : 1);
73  borders[borderStartIndex] = Math.Min(borders[borderStartIndex], size[axis]);
74  borders[borderStopIndex] = Math.Max(0, size[axis] - fullGaugeSize + borders[borderStopIndex]);
75 
76  var position = image.RegionInternal.Location;
77  var oldRegionSize = new Vector2(image.RegionInternal.Width, image.RegionInternal.Height);
78  var originalBordersSize = image.BordersInternal[borderStartIndex] + image.BordersInternal[borderStopIndex];
79 
80  var newRegionSize = oldRegionSize;
81  newRegionSize[imageAxis] = borders[borderStartIndex] + borders[borderStopIndex] + (oldRegionSize[imageAxis] - originalBordersSize) * Math.Min(1, (size[axis] - borders[borderStartIndex]) / (fullGaugeSize - originalBordersSize));
82  if (slider.IsDirectionReversed)
83  {
84  position[imageAxis] = position[imageAxis] + oldRegionSize[imageAxis] - newRegionSize[imageAxis];
85  }
86  var region = new RectangleF(position.X, position.Y, newRegionSize.X, newRegionSize.Y);
87 
88  Batch.DrawImage(image.Texture, image.TextureAlpha, ref worldMatrix, ref region, ref size, ref borders, ref color, context.DepthBias, imageOrientation);
89  context.DepthBias += 1;
90  }
91 
92  // draws the ticks
93  image = slider.TickImage;
94  if (slider.AreTicksDisplayed && image != null)
95  {
96  var imageAxis = (int)image.Orientation;
97  var imageOrientation = (ImageOrientation)(axis ^ imageAxis);
98  var shouldRotate180Degrees = (axis & imageAxis) == 1;
99 
100  var size = new Vector3();
101  size[axis] = image.ImageIdealSize.X;
102  size[axisPrime] = image.ImageIdealSize.Y;
103  if (trackIdealSize.HasValue)
104  size[axisPrime] *= slider.RenderSizeInternal[axisPrime] / trackIdealSize.Value.Y;
105 
106  var startOffset = new Vector2(GetAdjustedTranslation(slider.TickOffset, shouldRotate180Degrees));
107  startOffset[axis] = GetAdjustedTranslation(- fullGaugeSize / 2, shouldRotate180Degrees);
108  if (trackIdealSize.HasValue)
109  startOffset[axisPrime] *= slider.RenderSizeInternal[axisPrime] / trackIdealSize.Value.Y;
110 
111  var stepOffset = GetAdjustedTranslation(fullGaugeSize / slider.TickFrequency, shouldRotate180Degrees);
112 
113  var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, shouldRotate180Degrees);
114  worldMatrix.M41 += startOffset[axis] * worldMatrix[(axis << 2) + 0] + startOffset[axisPrime] * worldMatrix[(axisPrime << 2) + 0];
115  worldMatrix.M42 += startOffset[axis] * worldMatrix[(axis << 2) + 1] + startOffset[axisPrime] * worldMatrix[(axisPrime << 2) + 1];
116  worldMatrix.M43 += startOffset[axis] * worldMatrix[(axis << 2) + 2] + startOffset[axisPrime] * worldMatrix[(axisPrime << 2) + 2];
117 
118  for (int i = 0; i < slider.TickFrequency + 1; i++)
119  {
120  Batch.DrawImage(image.Texture, image.TextureAlpha, ref worldMatrix, ref image.RegionInternal, ref size, ref image.BordersInternal, ref color, context.DepthBias, imageOrientation, SwizzleMode.None, true);
121 
122  worldMatrix.M41 += stepOffset * worldMatrix[(axis << 2) + 0];
123  worldMatrix.M42 += stepOffset * worldMatrix[(axis << 2) + 1];
124  worldMatrix.M43 += stepOffset * worldMatrix[(axis << 2) + 2];
125  }
126  context.DepthBias += 1;
127  }
128 
129  //draws the thumb
130  image = slider.MouseOverState == MouseOverState.MouseOverElement ? slider.MouseOverThumbImage : slider.ThumbImage;
131  if (image != null)
132  {
133  var imageAxis = (int)image.Orientation;
134  var imageOrientation = (ImageOrientation)(axis ^ imageAxis);
135  var shouldRotate180Degrees = (axis & imageAxis) == 1;
136 
137  var size = new Vector3();
138  size[axis] = image.ImageIdealSize.X;
139  size[axisPrime] = image.ImageIdealSize.Y;
140  if (trackIdealSize.HasValue)
141  size[axisPrime] *= slider.RenderSizeInternal[axisPrime] / trackIdealSize.Value.Y;
142 
143  var revertedRatio = isGaugeReverted ? 1 - sliderRatio : sliderRatio;
144  var offset = GetAdjustedTranslation((revertedRatio - 0.5f) * fullGaugeSize, shouldRotate180Degrees);
145  var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, shouldRotate180Degrees);
146  worldMatrix.M41 += offset * worldMatrix[(axis << 2) + 0];
147  worldMatrix.M42 += offset * worldMatrix[(axis << 2) + 1];
148  worldMatrix.M43 += offset * worldMatrix[(axis << 2) + 2];
149 
150  Batch.DrawImage(image.Texture, image.TextureAlpha, ref worldMatrix, ref image.RegionInternal, ref size, ref image.BordersInternal, ref color, context.DepthBias, imageOrientation);
151 
152  context.DepthBias += 1;
153  }
154  }
155 
156  private float GetAdjustedTranslation(float value, bool shouldRotate)
157  {
158  return !shouldRotate ? value : -value;
159  }
160 
161  /// <summary>
162  /// Get a copy of the world matrix and rotate it by 180 degree if necessary.
163  /// </summary>
164  /// <param name="worldMatrix"></param>
165  /// <param name="shouldRotate"></param>
166  /// <returns></returns>
167  private static Matrix GetAdjustedWorldMatrix(ref Matrix worldMatrix, bool shouldRotate)
168  {
169  if (!shouldRotate)
170  return worldMatrix;
171 
172  var rotatedMatrix = worldMatrix;
173  rotatedMatrix.M11 = -rotatedMatrix.M11;
174  rotatedMatrix.M12 = -rotatedMatrix.M12;
175  rotatedMatrix.M13 = -rotatedMatrix.M13;
176  rotatedMatrix.M14 = -rotatedMatrix.M14;
177  rotatedMatrix.M21 = -rotatedMatrix.M21;
178  rotatedMatrix.M22 = -rotatedMatrix.M22;
179  rotatedMatrix.M23 = -rotatedMatrix.M23;
180  rotatedMatrix.M24 = -rotatedMatrix.M24;
181 
182  return rotatedMatrix;
183  }
184  }
185 }
SiliconStudio.Paradox.Games.Mathematics.Vector2 Vector2
Represents a two dimensional mathematical vector.
Definition: Vector2.cs:42
A service registry is a IServiceProvider that provides methods to register and unregister services...
Represents a slider element.
Definition: Slider.cs:16
SiliconStudio.Core.Mathematics.Vector3 Vector3
Android.Widget.Orientation Orientation
Definition: Section.cs:9
_In_ size_t _In_ size_t size
Definition: DirectXTexP.h:175
SiliconStudio.Core.Mathematics.RectangleF RectangleF
Definition: SpriteFont.cs:17
ImageOrientation
Defines the possible rotations to apply on image regions.
Represents a 4x4 mathematical matrix.
Definition: Matrix.cs:47