static public void ApplyProperties(CElement view, PropertyPrototype[] properties, Dictionary <string, object> objectsMap) { foreach (var property in properties) { try { switch (property.Kind) { case PropertyPrototype.PropertyPrototypeKind.AssignFrom: AssignPropertyFrom(view, objectsMap, property); break; case PropertyPrototype.PropertyPrototypeKind.BindValue: BindProperty(view, objectsMap, property); break; case PropertyPrototype.PropertyPrototypeKind.TextRepresentation: AssignPropertyText(view, objectsMap, property); break; } } catch (Exception e) { LogHelper.LogException($"Exception thrown during field assignment; target object: \"{view}\"; property: \"{property}\"; exception", e); } } }
private static void AssignPropertyText(CElement view, Dictionary <string, object> objectsMap, PropertyPrototype property) { var propName = property.Name; var propInfo = view.GetType().GetMember(propName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(); // todo: if (propInfo == null) { Log.Error($"Unable to resolve node {propName} for object {view}"); return; } if (!propInfo.CanWrite()) { Log.Error($"Unable to assign property {propName} of object {view}"); return; } var valueType = property.TypeHint ?? propInfo.MemberType(); valueType = Nullable.GetUnderlyingType(valueType) ?? valueType; var value = ParseFromText(property.Value, property.Translate, valueType); propInfo.SetValue(view, value); $"Assigned {value} to {propName}".Log(); }
/// <summary> /// sends view to the bottom of the views stack /// </summary> /// <param name="element"></param> public void SendToBack(CElement element) { if (!elements.Remove(element)) { throw new InvalidOperationException($"view {element} in not a subview of {this}"); } elements.Insert(0, element); SetNeedsUpdateLayout(); }
/// <summary> /// brings view to the top of the views stack /// </summary> /// <param name="element"></param> public void BringToFront(CElement element) { if (!elements.Remove(element)) { throw new InvalidOperationException($"view {element} in not a subview of {this}"); } elements.Add(element); SetNeedsUpdateLayout(); }
public static void ConstrainSize(this CElement element, double width, double height, ClStrength strength = null) { if (strength == null) { strength = ClStrength.Default; } element.AddConstraint(new ClLinearConstraint(element.width, toLinearExpression(width), strength)); element.AddConstraint(new ClLinearConstraint(element.height, toLinearExpression(height), strength)); }
public static void Center(this CElement parent, CElement child, EdgeInsets insets, ClStrength strength = null) { if (strength == null) { strength = ClStrength.Default; } parent.AddConstraint(parent.centerX ^ ((insets.Left - insets.Right) / 2) + child.centerX, strength); parent.AddConstraint(parent.centerY ^ ((insets.Top - insets.Bottom) / 2) + child.centerY, strength); }
public static void Center(this CElement parent, CElement child, ClStrength strength = null) { if (strength == null) { strength = ClStrength.Default; } parent.AddConstraint(parent.centerX ^ child.centerX, strength); parent.AddConstraint(parent.centerY ^ child.centerY, strength); }
public static void MakeSizeIntristic(this CElement element, EdgeInsets insets, ClStrength strength = null) { if (strength == null) { strength = ClStrength.Default; } element.AddConstraint(element.width ^ element.intrinsicWidth + insets.Width, strength); element.AddConstraint(element.height ^ element.intrinsicHeight + insets.Height, strength); }
private static void BindProperty(CElement view, Dictionary <string, object> objectsMap, PropertyPrototype property) { // todo exceptions var propName = property.Name; var srcPath = property.Path; object srcValue = objectsMap[srcPath.Object]; object srcObject = null; Type srcType = null; if (srcValue is Type) { srcType = (Type)srcValue; srcObject = null; } else { srcType = srcValue.GetType(); srcObject = srcValue; } var srcProp = srcType.GetMember(srcPath.Member, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).FirstOrDefault(); // todo: propper overload resolving if (srcProp == null) { Log.Error($"Unable to assign property \"{propName}\" of object \"{view}\": source object \"{srcPath}\" does not exists"); return; } var dstProp = view.GetType().GetMember(propName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(); // todo: propper overload resolving if (dstProp != null && !IsCompatibleBindable(dstProp.MemberType(), srcProp.MemberType())) { dstProp = view.GetType().GetMember(propName + "Prop", BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(); // todo: propper overload resolving } if (dstProp != null && IsCompatibleBindable(dstProp.MemberType(), srcProp.MemberType())) { var dstObj = dstProp.GetValue(view); dstProp.MemberType().GetMethod(nameof(Bindable <object> .Bind), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(object), typeof(MemberInfo) }, null) .Invoke(dstObj, new object[] { srcObject, srcProp }); $"Binded {srcProp} of {srcValue} to {dstProp}".Log(); } else { if (dstProp == null) { Log.Error($"Unable to assign property \"{propName}\" of object \"{view}\": property \"{propName}\" does not exists"); } else { Log.Error($"Unable to assign property \"{propName}\" of object \"{view}\": \"{srcValue}\" is not of compatible type"); } } }
public static void Embed(this CElement parent, CElement child, EdgeInsets insets, ClStrength strength = null) { if (strength == null) { strength = ClStrength.Default; } parent.AddConstraint(new ClLinearConstraint(parent.top, child.top - insets.Top, strength)); parent.AddConstraint(new ClLinearConstraint(parent.right, child.right + insets.Right, strength)); parent.AddConstraint(new ClLinearConstraint(parent.bottom, child.bottom + insets.Bottom, strength)); parent.AddConstraint(new ClLinearConstraint(parent.left, child.left - insets.Left, strength)); }
public void MoveToPosition(CElement element, int position) { if (position < 0 && position >= elements.Count()) { throw new ArgumentException("position is out of bounds", "position"); } if (!elements.Remove(element)) { throw new InvalidOperationException($"view {element} in not a subview of {this}"); } elements.Insert(position, element); SetNeedsUpdateLayout(); }
/// <summary> /// Removes all constraints leading into element /// </summary> /// <param name="element"></param> /// <returns>isolated constraints of element not connected to outside tree</returns> private List <ClConstraint> ShearConstraints(CElement element) { var cns = Solver.AllConstraints(); var detachedAnchors = new HashSet <ClVariable>(element.allAnchors()); var movedConstraints = new List <ClConstraint>(); foreach (var cn in cns) { bool hasDetached = false; bool hasAttached = false; foreach (var var in cn.Expression.Terms.Keys) { if (detachedAnchors.Contains(var)) { hasDetached = true; } else { hasAttached = true; } if (hasAttached && hasDetached) { break; } } if (hasDetached) { constraints.Remove(cn); Solver.RemoveConstraint(cn); if (!hasAttached) { movedConstraints.Add(cn); } } } foreach (var var in detachedAnchors) { Solver.RemoveVariable(var); } return(movedConstraints); }
/// <summary> /// Removes the subview /// </summary> /// <param name="element">children to remove</param> public void RemoveElement(CElement element) { if (!elements.Remove(element)) { throw new InvalidOperationException($"view {element} is not a subview of {this}"); } List <ClConstraint> movedConstraints = ShearConstraints(element); elements.Remove(element); element.parent_ = null; //Log.Message($"moved constraints:\n{string.Join("\n", movedConstraints)}"); foreach (var cn in movedConstraints) { element.AddConstraint(cn); } SetNeedsUpdateLayout(); }
public static void StackLeft(this CElement parent, StackOptions options, IEnumerable items) { Stack(parent, toRight, options, items); }
public static void StackRight(this CElement parent, StackOptions options, params object[] items) { StackRight(parent, options, (IEnumerable)items); }
public virtual void DestroyGui() { gui = null; settingsView = null; }
public static void StackBottom(this CElement parent, StackOptions options, IEnumerable items) { Stack(parent, toTop, options, items); }
private static void Stack(CElement parent, AnchorMapper mapper, StackOptions options, IEnumerable items) { ClLinearExpression trailing = mapper.Leading(parent) + mapper.GetLeadingExpression(options) * mapper.multipler; bool isFirst = true; foreach (var item in items) { CElement element = null; ClLinearExpression size = null; if (item is CElement) { element = item as CElement; size = null; } else { var type = item.GetType(); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ValueTuple <,>)) { var maybeElement = type.GetField("Item1").GetValue(item); var maybeVar = type.GetField("Item2").GetValue(item); element = maybeElement as CElement; size = toLinearExpression(maybeVar); } } if (element != null) { var child = element; if (!isFirst) { trailing = trailing + options.Spacing; } parent.AddConstraint(new ClLinearConstraint(trailing, new ClLinearExpression(mapper.Leading(child)), options.Strength)); trailing = new ClLinearExpression(mapper.Trailing(child)); if (size != null) { parent.AddConstraint(new ClLinearConstraint(mapper.Size(child), size, options.Strength)); } else if (options.IntrinsicIfNotSet) { parent.AddConstraint(mapper.Size(child) ^ mapper.IntrinsicSize(child)); } if (options.ConstrainSides) { parent.AddConstraints(options.Strength, mapper.SideA(child) ^ mapper.SideA(parent) + mapper.GetSideAExpression(options) * mapper.multipler, mapper.SideB(child) ^ mapper.SideB(parent) - mapper.GetSideBExpression(options) * mapper.multipler ); } if (options.AlignToCenter) { parent.AddConstraints(options.Strength, mapper.Center(child) ^ mapper.Center(parent) ); } isFirst = false; } else { trailing = trailing + toLinearExpression(item) * mapper.multipler; } } if (options.ConstrainEnd) { parent.AddConstraint(trailing + mapper.GetTrailingExpression(options) * mapper.multipler ^ mapper.Trailing(parent), options.Strength); } }
public static void StackBottom(this CElement parent, params object[] items) { StackBottom(parent, (IEnumerable)items); }
public static void StackBottom(this CElement parent, IEnumerable items) { Stack(parent, toTop, StackOptions.Default, items); }
public static void StackRight(this CElement parent, IEnumerable items) { Stack(parent, toLeft, StackOptions.Default, items); }