Example #1
0
 public static void Postfix(REPropertySet __instance, FieldInfo targetField, object target)
 {
     if (__instance is REEnumSet enumSet)
     {
         Type enumType  = targetField.FieldType;
         var  enumType2 = HintExtension.GetMappedEnumWithHints(enumType);
         if (HasHint(enumType2))
         {
             var panel = enumSet.GetComponentInChildren <UIPanel>();
             panel.objectUserData = new EnumSetHint(enumSet);
         }
     }
 }
Example #2
0
        public string GetHint()
        {
            Type enumType = enumSet_.GetTargetField().FieldType;
            int  i        = dd.GetHoverIndex();

            if (i >= 0)
            {
                string itemName = dd.items[i];
                return(HintExtension.GetEnumMappedHint(enumType, itemName));
            }
            else if (dd.containsMouse)
            {
                Type enumType2 = HintExtension.GetMappedEnumWithHints(enumType);
                return(enumType2.GetHints().JoinLines());
            }
            return(null);
        }
        /// <summary>
        /// replace built-in fields
        /// </summary>
        public static bool Prefix(string groupName, FieldInfo field, object target,
                                  RoadEditorPanel __instance)
        {
            if (NetInfoExtionsion.EditedNetInfo == null)
            {
                return(true); // ignore this outside of asset editor.
            }
            if (RoadEditorPanelExtensions.RequiresUserFlag(field.FieldType))
            {
                return(true);
            }
            if (field.HasAttribute <BitMaskAttribute>() && field.HasAttribute <CustomizablePropertyAttribute>())
            {
                UIComponent container = __instance.m_Container;
                if (!string.IsNullOrEmpty(groupName))
                {
                    container = __instance.GetGroupPanel(groupName).Container;
                }
                var att = field.GetAttribute <CustomizablePropertyAttribute>();

                var enumType = field.FieldType;
                enumType = HintExtension.GetMappedEnumWithHints(enumType);

                var hints = field.GetHints();
                if (field.Name == "m_stopType")
                {
                    hints.Add("set this for the pedestrian lane that contains the bus/tram stop.");
                }
                hints.AddRange(enumType.GetHints());
                string hint = hints.JoinLines();
                Log.Debug($"{field} -> hint is: " + hint);

                var bitMaskPanel = BitMaskPanel.Add(
                    roadEditorPanel: __instance,
                    container: container,
                    label: att.name,
                    enumType: enumType,
                    setHandler: val => field.SetValue(target, val),
                    getHandler: () => (int)field.GetValue(target),
                    hint: hint);
                return(false);
            }
            return(true);
        }
        public static void OnDPTMoreOptions(UICustomControl dpt)
        {
            Log.Debug("OnDPTMoreOptions() called");
            VerifySelectedDPTs(dpt);
            if (!SelectedDPTs.Contains(dpt))
            {
                DeselectAllDPTs();
            }

            var groupPanel = dpt.GetComponentInParent <RoadEditorCollapsiblePanel>();
            var sidePanel  = dpt.GetComponentInParent <RoadEditorPanel>();

            Log.Debug($"dpt={dpt} " +
                      $"groupPanel={groupPanel} " +
                      $"sidePanel={sidePanel}");

            object target  = GetDPTTargetObject(dpt);
            object element = GetDPTTargetElement(dpt);
            IEnumerable <object> elements;

            if (SelectedDPTs.Any())
            {
                elements = SelectedDPTs.Select(_dpt => GetDPTTargetElement(_dpt));
            }
            else
            {
                elements = new object[] { element }
            };

            if (target is NetLaneProps netLaneProps &&
                element is NetLaneProps.Prop)
            {
                var lane = sidePanel.GetTarget() as NetInfo.Lane;
                Assertion.AssertNotNull(lane, "sidePanel.target is lane");
                bool forward        = lane.IsGoingForward();
                bool backward       = lane.IsGoingBackward();
                bool unidirectional = forward || backward;

                var    panel          = MiniPanel.Display();
                var    f_props        = typeof(NetLaneProps).GetField(nameof(NetLaneProps.m_props));
                var    original_props = elements.Select(_p => _p as NetLaneProps.Prop);
                var    cloned_props   = original_props.Select(_p => _p.Clone());
                string strAll         = cloned_props.Count() > 1 ? " all" : "";

                panel.AddButton("Duplicate" + strAll, null, delegate() {
                    AddProps(groupPanel, cloned_props.ToArray());
                });

                if (cloned_props.Any(_p => _p.CanInvert()))
                {
                    string hint = HintExtension.GetHintSwichLHT_RHT(unidirectional);
                    panel.AddButton(
                        "LHT duplicate" + strAll,
                        hint,
                        delegate() {
                        try {
                            var arProsp = cloned_props.ToArray();
                            foreach (var item in arProsp)
                            {
                                item.ToggleRHT_LHT(unidirectional);
                            }
                            AddProps(groupPanel, arProsp);
                        } catch (Exception ex) {
                            Log.Exception(ex);
                        }
                    });
                }
                panel.AddButton("Copy" + strAll, null, delegate() {
                    ClipBoard.SetData(cloned_props);
                });
                panel.AddButton("Copy" + strAll + " to other elevations", null, delegate() {
                    foreach (var item in cloned_props)
                    {
                        PropHelpers.CopyPropsToOtherElevations(item);
                    }
                });
                panel.AddButton("Add" + strAll + " to Template", null, delegate() {
                    SaveTemplatePanel.Display(cloned_props);
                });
                if (cloned_props.Count() >= 2)
                {
                    panel.AddButton("Displace all", null, delegate() {
                        DisplaceAll(original_props);
                    });
                }
            }
        /// <summary>
        /// Adds new custom fields after a built-in field.
        /// or modify the name of the built-in fields
        /// </summary>
        public static void Postfix(string groupName, FieldInfo field, object target, RoadEditorPanel __instance)
        {
            try {
                if (target is NetLaneProps.Prop prop)
                {
                    Log.Debug($"{__instance.name}.CreateGenericField.Postfix({groupName},{field},{target})\n" /* + Environment.StackTrace*/);

                    ReplaceLabel(__instance, "Start Flags Required:", "Tail Flags Required:");
                    ReplaceLabel(__instance, "Start Flags Forbidden:", "Tail Flags Forbidden:");
                    ReplaceLabel(__instance, "End Flags Required:", "Head Flags Required:");
                    ReplaceLabel(__instance, "End Flags Forbidden:", "Head Flags Forbidden:");


                    if (field.Name == nameof(NetLaneProps.Prop.m_endFlagsForbidden))
                    {
                        Assert(prop.LocateEditProp(out _, out var lane), "could not locate prop");
                        bool forward        = lane.IsGoingForward();
                        bool backward       = lane.IsGoingBackward();
                        bool unidirectional = forward || backward;
                        if (ModSettings.ARMode)
                        {
                            var metadata = prop.GetOrCreateMetaData();
                            foreach (var field2 in metadata.GetFieldsWithAttribute <CustomizablePropertyAttribute>())
                            {
                                CreateExtendedComponent(groupName, field2, metadata, __instance);
                            }
                        }
                        if (!unidirectional)
                        {
                            ButtonPanel.Add(
                                roadEditorPanel: __instance,
                                container: __instance.m_Container,
                                label: "Switch Forward/Backward",
                                null,
                                action: () => {
                                prop.ToggleForwardBackward();
                                __instance.OnObjectModified();
                                __instance.Reset();
                            });
                        }

                        ButtonPanel.Add(
                            roadEditorPanel: __instance,
                            container: __instance.m_Container,
                            label: "Switch RHT/LHT",
                            HintExtension.GetHintSwichLHT_RHT(unidirectional),
                            action: () => {
                            prop.ToggleRHT_LHT(unidirectional);
                            __instance.OnObjectModified();
                            __instance.Reset();
                        });
                    }
                }
                else if (target is NetInfo.Node node)
                {
                    Log.Debug($"{__instance.name}.CreateGenericField.Postfix({groupName},{field},{target})\n" /* + Environment.StackTrace*/);
                    if (ModSettings.ARMode)
                    {
                        if (field.Name == nameof(NetInfo.Node.m_flagsForbidden))
                        {
                            var fields = typeof(NetInfoExtionsion.Node).GetFields()
                                         .Where(_field => _field.HasAttribute <CustomizablePropertyAttribute>());
                            var node2 = node.GetOrCreateMetaData();
                            foreach (var field2 in fields)
                            {
                                CreateExtendedComponent(groupName, field2, node2, __instance);
                            }
                        }
                    }
                }
                else if (target is NetInfo.Segment segment)
                {
                    Log.Debug($"{__instance.name}.CreateGenericField.Postfix({groupName}, {field}, {target})\n" /* + Environment.StackTrace*/);
                    if (ModSettings.ARMode)
                    {
                        var segment2 = segment.GetOrCreateMetaData();
                        AssertNotNull(segment2, $"{segment}");
                        var fieldForward = typeof(NetInfoExtionsion.Segment).GetField(
                            nameof(NetInfoExtionsion.Segment.Forward));
                        if (field.Name == nameof(NetInfo.Segment.m_forwardForbidden))
                        {
                            CreateExtendedComponent(groupName, fieldForward, segment2, __instance);
                        }
                        else if (field.Name == nameof(NetInfo.Segment.m_backwardForbidden))
                        {
                            var fields = segment2
                                         .GetFieldsWithAttribute <CustomizablePropertyAttribute>()
                                         .Where(_f => _f != fieldForward);
                            int totalCount = typeof(NetInfoExtionsion.Segment)
                                             .GetFieldsWithAttribute <CustomizablePropertyAttribute>()
                                             .Count();
                            foreach (var field2 in fields)
                            {
                                CreateExtendedComponent(groupName, field2, segment2, __instance);
                            }
                        }
                    }
                }
                else if (target is NetInfo netInfo)
                {
                    if (ModSettings.ARMode)
                    {
                        // replace "Pavement Width" with Pavement Width Left
                        ReplaceLabel(__instance, "Pavement Width", "Pavement Width Left");
                        // inject our own field
                        if (field.Name == nameof(NetInfo.m_pavementWidth))
                        {
                            Log.Debug($"{__instance.name}.CreateGenericField.Postfix({groupName},{field},{target})\n" /* + Environment.StackTrace*/);
                            var net = netInfo.GetOrCreateMetaData();
                            AssertNotNull(net, $"{netInfo}");
                            var f = net.GetType().GetField(nameof(net.PavementWidthRight));
                            __instance.CreateGenericField(groupName, f, net);
                        }
                    }
                }
            } catch (Exception e) {
                Log.Exception(e);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="groupName"></param>
        /// <param name="fieldInfo"></param>
        /// <param name="target"></param>
        /// <param name="instance"></param>
        /// <param name="prefix"></param>
        public static void CreateExtendedComponent(
            string groupName, FieldInfo fieldInfo, object target, RoadEditorPanel instance, string prefix = "")
        {
            //Assert(string.IsNullOrEmpty(groupName), "groupName is empty");
            UIComponent container = instance.m_Container;  //instance.component.GetComponentInChildren<UIScrollablePanel>();

            if (!string.IsNullOrEmpty(groupName))
            {
                container = instance.GetGroupPanel(groupName).Container;
            }

            AssertNotNull(container, "container");
            Log.Debug("CreateExtendedComponent():container=" + container);

            Assert(fieldInfo.HasAttribute <CustomizablePropertyAttribute>(), "HasAttribute:CustomizablePropertyAttribute");
            AssertNotNull(target, "target");
            AssertNotNull(target, "fieldInfo");
            AssertNotNull(target, "RoadEditorPanel instance");
            Log.Debug(
                $"CreateExtendedComponent(groupName={groupName}, fieldInfo={fieldInfo}, target={target}, instance={instance.name}) called",
                false);

            var att        = fieldInfo.GetAttribute <CustomizablePropertyAttribute>();
            var optionals  = fieldInfo.GetAttributes <OptionalAttribute>();
            var optionals2 = target.GetType().GetAttributes <OptionalAttribute>();

            foreach (var optional in optionals.Concat(optionals2))
            {
                if (optional != null && !ModSettings.GetOption(optional.Option))
                {
                    Log.Debug($"Hiding {target.GetType().Name}::`{att.name}` because {optional.Option} is disabled");
                    return;
                }
            }

            var hints = fieldInfo.GetHints();

            hints.AddRange(fieldInfo.FieldType.GetHints());
            string hint = hints.JoinLines();

            Log.Debug("hint is " + hint);

            if (fieldInfo.FieldType.HasAttribute <FlagPairAttribute>())
            {
                int GetRequired()
                {
                    object subTarget = fieldInfo.GetValue(target);

                    return((int)GetFieldValue(subTarget, "Required"));
                }

                void SetRequired(int flags)
                {
                    var subTarget = fieldInfo.GetValue(target);

                    SetFieldValue(target: subTarget, fieldName: "Required", value: flags);
                    fieldInfo.SetValue(target, subTarget);
                }

                int GetForbidden()
                {
                    object subTarget = fieldInfo.GetValue(target);

                    return((int)GetFieldValue(subTarget, "Forbidden"));
                }

                void SetForbidden(int flags)
                {
                    var subTarget = fieldInfo.GetValue(target);

                    SetFieldValue(target: subTarget, fieldName: "Forbidden", value: flags);
                    fieldInfo.SetValue(target, subTarget);
                }

                Type enumType = fieldInfo.FieldType.GetField("Required").FieldType;
                enumType = HintExtension.GetMappedEnumWithHints(enumType);

                var panel0 = BitMaskPanel.Add(
                    roadEditorPanel: instance,
                    container: container,
                    label: prefix + att.name + " Flags Required",
                    enumType: enumType,
                    setHandler: SetRequired,
                    getHandler: GetRequired,
                    hint: hint);
                panel0.EventPropertyChanged += instance.OnObjectModified;
                var panel1 = BitMaskPanel.Add(
                    roadEditorPanel: instance,
                    container: container,
                    label: prefix + att.name + " Flags Forbidden",
                    enumType: enumType,
                    setHandler: SetForbidden,
                    getHandler: GetForbidden,
                    hint: hint);
                panel1.EventPropertyChanged += instance.OnObjectModified;
            }
            else if (fieldInfo.FieldType == typeof(NetInfoExtionsion.Range) &&
                     fieldInfo.Name.ToLower().Contains("speed"))
            {
                var panel = SpeedRangePanel.Add(
                    roadEditorPanel: instance,
                    container: container,
                    label: prefix + att.name,
                    target: target,
                    fieldInfo: fieldInfo);
                panel.EventPropertyChanged += instance.OnObjectModified;
            }
            else
            {
                Log.Error($"CreateExtendedComponent: Unhandled field: {fieldInfo} att:{att.name} ");
            }
        }
Example #7
0
        /// <summary>
        /// Adds new custom fields after a built-in field.
        /// or modify the name of the built-in fields
        /// </summary>
        public static void Postfix(string groupName, FieldInfo field, object target, RoadEditorPanel __instance)
        {
            try {
                if (target is NetLaneProps.Prop prop)
                {
                    Log.Debug($"{__instance.name}.CreateGenericField.Postfix({groupName},{field},{target})" /* + Environment.StackTrace*/);
                    if (ModSettings.ARMode)
                    {
                        var metadata = prop.GetOrCreateMetaData();
                        foreach (var field2 in field.GetAfterFields(metadata))
                        {
                            CreateGenericComponentExt(
                                roadEditorPanel: __instance, groupName: groupName,
                                target: target, metadata: metadata, extensionField: field2);
                        }
                    }

                    if (typeof(NetInfoExtionsion.LaneProp).ComesAfter(field))
                    {
                        Assert(prop.LocateEditProp(out _, out var lane), "could not locate prop");
                        bool forward        = lane.IsGoingForward();
                        bool backward       = lane.IsGoingBackward();
                        bool unidirectional = forward || backward;
                        if (!unidirectional)
                        {
                            ButtonPanel.Add(
                                roadEditorPanel: __instance,
                                container: __instance.m_Container,
                                label: "Switch Forward/Backward",
                                null,
                                action: () => {
                                prop.ToggleForwardBackward();
                                __instance.OnObjectModified();
                                __instance.Reset();
                            });
                        }

                        ButtonPanel.Add(
                            roadEditorPanel: __instance,
                            container: __instance.m_Container,
                            label: "Switch RHT/LHT",
                            HintExtension.GetHintSwichLHT_RHT(unidirectional),
                            action: () => {
                            prop.ToggleRHT_LHT(unidirectional);
                            __instance.OnObjectModified();
                            __instance.Reset();
                        });
                    }

                    ReplaceLabel(__instance, "Start Flags Required:", "Tail Node Flags Required:");
                    ReplaceLabel(__instance, "Start Flags Forbidden:", "Tail  Node Flags Forbidden:");
                    ReplaceLabel(__instance, "End Flags Required:", "Head  Node Flags Required:");
                    ReplaceLabel(__instance, "End Flags Forbidden:", "Head  Node Flags Forbidden:");
                }
                else if (target is NetInfo.Node node)
                {
                    Log.Debug($"{__instance.name}.CreateGenericField.Postfix({groupName},{field},{target})" /* + Environment.StackTrace*/);
                    if (ModSettings.ARMode)
                    {
                        var metadata = node.GetOrCreateMetaData();
                        foreach (var field2 in field.GetAfterFields(metadata))
                        {
                            CreateGenericComponentExt(
                                roadEditorPanel: __instance, groupName: groupName,
                                target: target, metadata: metadata, extensionField: field2);
                        }
                    }
                }
                else if (target is NetInfo.Segment segment)
                {
                    Log.Debug($"{__instance.name}.CreateGenericField.Postfix({groupName}, {field}, {target})" /* + Environment.StackTrace*/);
                    if (ModSettings.ARMode)
                    {
                        var metadata = segment.GetOrCreateMetaData();
                        AssertNotNull(metadata, $"{segment}");
                        foreach (var field2 in field.GetAfterFields(metadata))
                        {
                            CreateGenericComponentExt(
                                roadEditorPanel: __instance, groupName: groupName,
                                target: target, metadata: metadata, extensionField: field2);
                        }
                    }
                }
                else if (target is NetInfo netInfo)
                {
                    if (ModSettings.ARMode)
                    {
                        ReplaceLabel(__instance, "Pavement Width", "Pavement Width Left");
                        var net = netInfo.GetOrCreateMetaData();
                        AssertNotNull(net, $"{netInfo}");
                        foreach (var field2 in net.GetFieldsWithAttribute <CustomizablePropertyAttribute>())
                        {
                            if (field2.ComesAfter(field))
                            {
                                Log.Debug($"calling {__instance.name}.CreateGenericField({groupName},{field2},{net}) ...");
                                __instance.CreateGenericField(groupName, field2, net);
                            }
                        }
                        if (field.Name == nameof(NetInfo.m_surfaceLevel))
                        {
                            Log.Debug("adding QuayRoads button");
                            var qrButtonPanel = ButtonPanel.Add(
                                roadEditorPanel: __instance,
                                container: __instance.GetGroupPanel("Properties").m_Panel,
                                label: "Edit QuayRoads profile",
                                hint: "",
                                action: () => QuayRoadsPanel.GetOrOpen(netInfo, __instance));
                            qrButtonPanel.EventDestroy += (_, _) => { QuayRoadsPanel.CloseIfOpen(netInfo); };
                        }
                    }
                }
            } catch (Exception e) {
                Log.Exception(e);
            }
        }