forked from stride3d/stride
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImageElement.cs
More file actions
165 lines (151 loc) · 5.45 KB
/
ImageElement.cs
File metadata and controls
165 lines (151 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
using System;
using System.ComponentModel;
using System.Diagnostics;
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Games;
using Stride.Graphics;
namespace Stride.UI.Controls
{
/// <summary>
/// Represents a control that displays an image.
/// </summary>
[DataContract(nameof(ImageElement))]
[DebuggerDisplay("ImageElement - Name={Name}")]
public class ImageElement : UIElement
{
private ISpriteProvider source;
private Sprite sprite;
private StretchType stretchType = StretchType.Uniform;
private StretchDirection stretchDirection = StretchDirection.Both;
/// <summary>
/// Gets or sets the <see cref="ISpriteProvider"/> for the image.
/// </summary>
/// <userdoc>The provider for the image.</userdoc>
[DataMember]
[Display(category: AppearanceCategory)]
[DefaultValue(null)]
public ISpriteProvider Source
{
get { return source; }
set
{
if (source == value)
return;
source = value;
OnSpriteChanged(source?.GetSprite());
}
}
/// <summary>
/// Gets or set the color used to tint the image. Default value is White.
/// </summary>
/// <remarks>The initial image color is multiplied by this color.</remarks>
/// <userdoc>The color used to tint the image. The default value is white.</userdoc>
[DataMember]
[Display(category: AppearanceCategory)]
public Color Color { get; set; } = Color.White;
/// <summary>
/// Gets or sets a value that describes how the image should be stretched to fill the destination rectangle.
/// </summary>
/// <userdoc>Indicates how the image should be stretched to fill the destination rectangle.</userdoc>
[DataMember]
[Display(category: LayoutCategory)]
[DefaultValue(StretchType.Uniform)]
public StretchType StretchType
{
get { return stretchType; }
set
{
stretchType = value;
InvalidateMeasure();
}
}
/// <summary>
/// Gets or sets a value that indicates how the image is scaled.
/// </summary>
/// <userdoc>Indicates how the image is scaled.</userdoc>
[DataMember]
[Display(category: LayoutCategory)]
[DefaultValue(StretchDirection.Both)]
public StretchDirection StretchDirection
{
get { return stretchDirection; }
set
{
stretchDirection = value;
InvalidateMeasure();
}
}
/// <summary>
/// Gets or sets the rotation angle in radians (clockwise around Z-axis).
/// </summary>
/// <remarks>The rotation is applied around the center of the image. Positive values rotate clockwise.</remarks>
/// <userdoc>The rotation angle in radians. Positive values rotate clockwise.</userdoc>
[DataMember]
[Display(category: LayoutCategory)]
[DefaultValue(0f)]
public float Rotation
{
get { return field; }
set
{
if (Math.Abs(field - value) < float.Epsilon)
return;
field = value;
UpdateLocalMatrix();
}
}
protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins)
{
return ImageSizeHelper.CalculateImageSizeFromAvailable(sprite, finalSizeWithoutMargins, StretchType, StretchDirection, false);
}
protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins)
{
return ImageSizeHelper.CalculateImageSizeFromAvailable(sprite, availableSizeWithoutMargins, StretchType, StretchDirection, true);
}
protected override void Update(GameTime time)
{
var currentSprite = source?.GetSprite();
if (sprite != currentSprite)
{
OnSpriteChanged(currentSprite);
}
}
private void InvalidateMeasure(object sender, EventArgs eventArgs)
{
InvalidateMeasure();
}
private void OnSpriteChanged(Sprite currentSprite)
{
if (sprite != null)
{
sprite.SizeChanged -= InvalidateMeasure;
sprite.BorderChanged -= InvalidateMeasure;
}
sprite = currentSprite;
InvalidateMeasure();
if (sprite != null)
{
sprite.SizeChanged += InvalidateMeasure;
sprite.BorderChanged += InvalidateMeasure;
}
}
/// <summary>
/// Updates the local transformation matrix based on the current rotation angle.
/// </summary>
private void UpdateLocalMatrix()
{
if (Math.Abs(Rotation) < float.Epsilon)
{
LocalMatrix = Matrix.Identity;
}
else
{
LocalMatrix = Matrix.RotationZ(Rotation);
}
}
}
}