1using System.Reflection;
55 widgetScissorRectangle = scissorRectangle;
62 drawItem.ScissorRectangle = scissorRectangle;
68 drawItem.Widget = widget;
74 foreach (
Widget child
in containerWidget.Children) {
82 drawItem.Widget = widget;
83 drawItem.IsOverdraw =
true;
86 if (widgetScissorRectangle.HasValue) {
89 drawItem.ScissorRectangle = widgetScissorRectangle;
114 "OnDrawItemAssigned",
116 loader.OnDrawItemAssigned(
this);
126 int currentLayer = 0;
132 if (drawItem.
Layer != currentLayer) {
133 currentLayer = drawItem.
Layer;
137 if (drawItem.
Widget !=
null) {
138 Action afterWidgetDraw =
null;
141 "BeforeWidgetDrawItemRender",
143 loader.BeforeWidgetDrawItemRender(
145 out
bool skipVanillaDraw,
146 out Action afterDrawAction,
147 ref scissorRectangle,
150 if (afterDrawAction !=
null) {
151 afterWidgetDraw += afterDrawAction;
153 skip |= skipVanillaDraw;
165 afterWidgetDraw?.Invoke();
173 Display.ScissorRectangle = scissorRectangle;
195 drawItem.Widget =
null;
197 drawItem.IsOverdraw =
false;
198 drawItem.ScissorRectangle =
null;
282 if (value.m_widget !=
null
283 && value.m_widget !=
this) {
284 throw new InvalidOperationException(
"WidgetInput already assigned to another widget.");
286 value.m_widget =
this;
290 m_widgetsHierarchyInput.m_widget =
null;
305 while (widget !=
null);
351 public virtual string Name {
get;
set; }
353 public object Tag {
get;
set; }
409 [Obsolete(
"Use MarginLeft, MarginTop, MarginRight and MarginBottom instead.")]
487 if (node.Name.LocalName.Contains(
".")) {
488 throw new NotImplementedException(
"Node property specification not implemented.");
490#pragma warning disable IL2072
492#pragma warning restore IL2072
493 throw new Exception($
"Type \"{node.Name.LocalName}\" is not a Widget.");
498 loader.OnWidgetConstruct(ref widget);
503 widget.LoadContents(eventsTarget, node);
511 "OnWidgetContentsLoaded",
513 loader.OnWidgetContentsLoaded(
this);
520#pragma warning disable IL2072
521 IEnumerable<PropertyInfo> runtimeProperties = GetType().GetRuntimeProperties().ToArray();
522#pragma warning restore IL2072
523 foreach (XAttribute attribute
in node.Attributes()) {
524 if (!attribute.IsNamespaceDeclaration
525 && !attribute.Name.LocalName.StartsWith(
'_')) {
526 if (attribute.Name.LocalName.Contains(
'.')) {
527 string[] array = attribute.Name.LocalName.Split(
'.');
528 if (array.Length != 2) {
529 throw new InvalidOperationException(
530 $
"Attached property reference must have form \"TypeName.PropertyName\", property \"{attribute.Name.LocalName}\" in widget of type \"{GetType().FullName}\"."
535 attribute.Name.NamespaceName !=
string.Empty ? attribute.Name.NamespaceName : node.Name.NamespaceName
537 string setterName = $
"Set{array[1]}";
538#pragma warning disable IL2072
539 MethodInfo methodInfo = type.GetRuntimeMethods().FirstOrDefault(mi => mi.Name == setterName && mi.IsPublic && mi.IsStatic);
540#pragma warning restore IL2072
541 if (!(methodInfo !=
null)) {
542 throw new InvalidOperationException(
543 $
"Attached property public static setter method \"{setterName}\" not found, property \"{attribute.Name.LocalName}\" in widget of type \"{GetType().FullName}\"."
546 ParameterInfo[] parameters = methodInfo.GetParameters();
547 if (parameters.Length != 2
548 || !(parameters[0].ParameterType == typeof(
Widget))) {
549 throw new InvalidOperationException(
550 $
"Attached property setter method must take 2 parameters and first one must be of type Widget, property \"{attribute.Name.LocalName}\" in widget of type \"{GetType().FullName}\"."
554 methodInfo.Invoke(
null, [
this, obj]);
557 PropertyInfo propertyInfo = runtimeProperties.FirstOrDefault(pi => pi.Name == attribute.Name.LocalName);
558 if (!(propertyInfo !=
null)) {
559 throw new InvalidOperationException(
560 $
"Property \"{attribute.Name.LocalName}\" not found in widget of type \"{GetType().FullName}\"."
563 if (attribute.Value.StartsWith(
'{')
564 && attribute.Value.EndsWith(
'}')) {
565 string name = attribute.Value.Substring(1, attribute.Value.Length - 2);
568 Log.
Error($
"Not Found Res [{name}][{propertyInfo.PropertyType.FullName}] when loading {GetType().FullName}");
571 propertyInfo.SetValue(
this, value,
null);
576 if (propertyInfo.PropertyType == typeof(
string)) {
577 obj2 = ((string)obj2).Replace(
"\\n",
"\n").Replace(
"\\t",
"\t");
579 propertyInfo.SetValue(
this, obj2,
null);
587 if (node.HasElements) {
589 throw new Exception($
"Type \"{node.Name.LocalName}\" is not a ContainerWidget, but it contains child widgets.");
591 foreach (XElement item
in node.Elements()) {
595 if (attributeValue !=
null) {
596 widget = containerWidget.Children.Find(attributeValue,
false);
598 if (widget !=
null) {
602 LoadWidget(eventsTarget, item, containerWidget);
622 if (parentWidget ==
null) {
655 m_actualSize.X = (num * parentActualSize.X + num3 * parentActualSize.
Y) / (num + num3);
656 m_actualSize.Y = (num2 * parentActualSize.X + num4 * parentActualSize.
Y) / (num2 + num4);
723 if (attributeValue !=
null
724 && attributeValue2 ==
null) {
730 if (attributeValue2 ==
null
731 || attributeValue !=
null) {
743 bool isMouseCursorVisible =
false;
750 rootWidget.
Measure(availableSize);
765 float num = m_layoutTransform.M11 * size.
X;
766 float num2 = m_layoutTransform.M21 * size.
Y;
767 float x = num + num2;
768 float num3 = m_layoutTransform.M12 * size.
X;
769 float num4 = m_layoutTransform.M22 * size.
Y;
770 float x2 = num3 + num4;
779 float num = m_globalTransform.M11 * size.
X;
780 float num2 = m_globalTransform.M21 * size.
Y;
781 float x = num + num2;
782 float num3 = m_globalTransform.M12 * size.
X;
783 float num4 = m_globalTransform.M22 * size.
Y;
784 float x2 = num3 + num4;
797 if (!
string.IsNullOrEmpty(namespaceName)) {
798 Uri uri =
new(namespaceName);
799 if (uri.Scheme ==
"runtime-namespace") {
802 throw new InvalidOperationException(
"Unknown uri scheme when loading widget. Scheme must be runtime-namespace.");
804 throw new InvalidOperationException(
"Namespace must be specified when creating types in XML.");
813 for (
int num = children.
Count - 1; num >= 0; num--) {
815 if (widget2 !=
null) {
822 && (predicate ==
null || predicate(widget))) {
841 for (
int num = children.
Count - 1; num >= 0; num--) {
842 if (num < children.
Count) {
849 "BeforeWidgetUpdate",
851 loader.BeforeWidgetUpdate(widget);
859 loader.AfterWidgetUpdate(widget);
static Rectangle ScissorRectangle
static void Error(object message)
static int Min(int x1, int x2)
static int Max(int x1, int x2)
static object ConvertFromString(Type type, string data)
static Type FindType(string typeName, bool skipSystemAssemblies, bool throwIfNotFound)
static object Get(Type type, string name)
static string PlatformString
virtual void ReturnDrawItemsToCache()
对 DrawItem 进行复用,并存储到缓存列表内。
virtual DrawItem GetDrawItemFromCache()
从缓存中获取一个 DrawItem 实例,用于减少实例创建次数以缓解 GC 压力。
readonly PrimitivesRenderer3D PrimitivesRenderer3D
virtual void CollateDrawItems(Widget widget, Rectangle scissorRectangle)
根据 Widget 的层级关系 以及 Widget 的各项绘制有关的属性生成 DrawItem。
readonly PrimitivesRenderer2D PrimitivesRenderer2D
virtual void RenderDrawItems()
virtual void AssignDrawItemsLayers()
指定 DrawItem 的 Layer(层级)。
static List< DrawItem > m_drawItemsCache
List< DrawItem > m_drawItems
readonly PrimitivesRenderer2D CursorPrimitivesRenderer2D
virtual void DrawWidgetsHierarchy(Widget rootWidget)
绘制 rootWidget 及其子 Widget。
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
static object GetAttributeValue(XElement node, string attributeName, Type type)
bool Intersection(BoundingRectangle r)
static Matrix Invert(Matrix m)
static readonly Matrix Identity
bool Intersection(Rectangle r)
static readonly Vector2 Zero
static Vector2 Transform(Vector2 v, Matrix m)