void Populate(object callbacks, object o, RootElement root) { MemberInfo last_radio_index = null; var members = o.GetType().GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); Section section = null; foreach (var mi in members) { Type mType = GetTypeForMember(mi); if (mType == null) continue; string caption = null; object[] attrs = mi.GetCustomAttributes(false); bool skip = false; foreach (var attr in attrs) { if (attr is SkipAttribute) skip = true; if (attr is CaptionAttribute) caption = ((CaptionAttribute)attr).Caption; else if (attr is SectionAttribute) { if (section != null) root.Add(section); var sa = attr as SectionAttribute; section = new Section(sa.Caption, sa.Footer); } } if (skip) continue; if (caption == null) caption = MakeCaption(mi.Name); if (section == null) section = new Section(); Element element = null; if (mType == typeof(string)) { PasswordAttribute pa = null; AlignmentAttribute align = null; EntryAttribute ea = null; object html = null; EventHandler invoke = null; bool multi = false; foreach (object attr in attrs) { if (attr is PasswordAttribute) pa = attr as PasswordAttribute; else if (attr is EntryAttribute) ea = attr as EntryAttribute; else if (attr is MultilineAttribute) multi = true; else if (attr is HtmlAttribute) html = attr; else if (attr is AlignmentAttribute) align = attr as AlignmentAttribute; if (attr is OnTapAttribute) { string mname = ((OnTapAttribute)attr).Method; if (callbacks == null) { throw new Exception("Your class contains [OnTap] attributes, but you passed a null object for `context' in the constructor"); } var method = callbacks.GetType().GetMethod(mname); if (method == null) throw new Exception("Did not find method " + mname); invoke = delegate { method.Invoke(method.IsStatic ? null : callbacks, new object[0]); }; } } string value = (string)GetValue(mi, o); if (pa != null) element = new EntryElement(caption, value) { Hint = pa.Placeholder, Password = true }; else if (ea != null) element = new EntryElement(caption, value) { Hint = ea.Placeholder }; else if (multi) element = new MultilineElement(caption, value); else if (html != null) element = new HtmlElement(caption, value); else { var selement = new StringElement(caption, value); element = selement; if (align != null) selement.Alignment = align.Alignment; } if (invoke != null) { // ((StringElement)element).Click += invoke; } } else if (mType == typeof(float)) { var floatElement = new FloatElement(null, null, (int)GetValue(mi, o)); floatElement.Caption = caption; element = floatElement; foreach (object attr in attrs) { if (attr is RangeAttribute) { var ra = attr as RangeAttribute; floatElement.MinValue = ra.Low; floatElement.MaxValue = ra.High; floatElement.ShowCaption = ra.ShowCaption; } } } else if (mType == typeof(bool)) { bool checkbox = false; foreach (object attr in attrs) { if (attr is CheckboxAttribute) checkbox = true; } if (checkbox) element = new CheckboxElement(caption, (bool)GetValue(mi, o)); else element = new BooleanElement(caption, (bool)GetValue(mi, o)); } else if (mType == typeof(DateTime)) { var dateTime = (DateTime)GetValue(mi, o); bool asDate = false, asTime = false; foreach (object attr in attrs) { if (attr is DateAttribute) asDate = true; else if (attr is TimeAttribute) asTime = true; } if (asDate) element = new DateElement(caption, dateTime); else if (asTime) element = new TimeElement(caption, dateTime); else element = new DateTimeElement(caption, dateTime); } else if (mType.IsEnum) { var csection = new Section(); ulong evalue = Convert.ToUInt64(GetValue(mi, o), null); int idx = 0; int selected = 0; foreach (var fi in mType.GetFields(BindingFlags.Public | BindingFlags.Static)) { ulong v = Convert.ToUInt64(GetValue(fi, null)); if (v == evalue) selected = idx; csection.Add(new RadioElement(MakeCaption(fi.Name))); idx++; } element = new RootElement(caption, new RadioGroup(null, selected)) { csection }; } else if (mType == typeof(ImageView)) { element = new ImageElement(null); // (ImageView)GetValue(mi, o)); } else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(mType)) { var csection = new Section(); int count = 0; if (last_radio_index == null) throw new Exception("IEnumerable found, but no previous int found"); foreach (var e in (IEnumerable)GetValue(mi, o)) { csection.Add(new RadioElement(e.ToString())); count++; } int selected = (int)GetValue(last_radio_index, o); if (selected >= count || selected < 0) selected = 0; element = new RootElement(caption, new MemberRadioGroup(null, selected, last_radio_index)) { csection }; last_radio_index = null; } else if (typeof(int) == mType) { foreach (object attr in attrs) { if (attr is RadioSelectionAttribute) { last_radio_index = mi; break; } } } else { var nested = GetValue(mi, o); if (nested != null) { var newRoot = new RootElement(caption); Populate(callbacks, nested, newRoot); element = newRoot; } } if (element == null) continue; section.Add(element); mappings[element] = new MemberAndInstance(mi, o); } root.Add(section); }
// // Creates one of the various StringElement classes, based on the // properties set. It tries to load the most memory efficient one // StringElement, if not, it fallsback to MultilineStringElement or // StyledStringElement // static Element LoadString (JsonObject json, object data) { string value = null; string caption = value; string background = null; NSAction ontap = null; NSAction onaccessorytap = null; int? lines = null; UITableViewCellAccessory? accessory = null; UILineBreakMode? linebreakmode = null; UITextAlignment? alignment = null; UIColor textcolor = null, detailcolor = null; UIFont font = null; UIFont detailfont = null; UITableViewCellStyle style = UITableViewCellStyle.Value1; foreach (var kv in json){ string kvalue = (string) kv.Value; switch (kv.Key){ case "caption": caption = kvalue; break; case "value": value = kvalue; break; case "background": background = kvalue; break; case "style": style = ToCellStyle (kvalue); break; case "ontap": case "onaccessorytap": string sontap = kvalue; int p = sontap.LastIndexOf ('.'); if (p == -1) break; NSAction d = delegate { string cname = sontap.Substring (0, p); string mname = sontap.Substring (p+1); foreach (var a in AppDomain.CurrentDomain.GetAssemblies ()){ Type type = a.GetType (cname); if (type != null){ var mi = type.GetMethod (mname, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (mi != null) mi.Invoke (null, new object [] { data }); break; } } }; if (kv.Key == "ontap") ontap = d; else onaccessorytap = d; break; case "lines": int res; if (int.TryParse (kvalue, out res)) lines = res; break; case "accessory": accessory = ToAccessory (kvalue); break; case "textcolor": textcolor = ParseColor (kvalue); break; case "linebreak": linebreakmode = ToLinebreakMode (kvalue); break; case "font": font = ToFont (kvalue); break; case "subtitle": value = kvalue; style = UITableViewCellStyle.Subtitle; break; case "detailfont": detailfont = ToFont (kvalue); break; case "alignment": alignment = ToAlignment (kvalue); break; case "detailcolor": detailcolor = ParseColor (kvalue); break; case "type": break; default: Console.WriteLine ("Unknown attribute: '{0}'", kv.Key); break; } } if (caption == null) caption = ""; if (font != null || style != UITableViewCellStyle.Value1 || detailfont != null || linebreakmode.HasValue || textcolor != null || accessory.HasValue || onaccessorytap != null || background != null || detailcolor != null){ StyledStringElement styled; if (lines.HasValue){ styled = new StyledMultilineElement (caption, value, style); styled.Lines = lines.Value; } else { styled = new StyledStringElement (caption, value, style); } if (ontap != null) styled.Tapped += ontap; if (onaccessorytap != null) styled.AccessoryTapped += onaccessorytap; if (font != null) styled.Font = font; if (detailfont != null) styled.SubtitleFont = detailfont; if (detailcolor != null) styled.DetailColor = detailcolor; if (textcolor != null) styled.TextColor = textcolor; if (accessory.HasValue) styled.Accessory = accessory.Value; if (linebreakmode.HasValue) styled.LineBreakMode = linebreakmode.Value; if (background != null){ if (background.Length > 1 && background [0] == '#') styled.BackgroundColor = ParseColor (background); else styled.BackgroundUri = new Uri (background); } if (alignment.HasValue) styled.Alignment = alignment.Value; return styled; } else { StringElement se; if (lines == 0) se = new MultilineElement (caption, value); else se = new StringElement (caption, value); if (alignment.HasValue) se.Alignment = alignment.Value; if (ontap != null) se.Tapped += ontap; return se; } }
void Populate(object callbacks, object o, RootElement root) { MemberInfo last_radio_index = null; var members = o.GetType().GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); Section section = null; foreach (var mi in members) { Type mType = GetTypeForMember(mi); if (mType == null) { continue; } string caption = null; object [] attrs = mi.GetCustomAttributes(false); bool skip = false; foreach (var attr in attrs) { if (attr is SkipAttribute || attr is System.Runtime.CompilerServices.CompilerGeneratedAttribute) { skip = true; } else if (attr is CaptionAttribute) { caption = ((CaptionAttribute)attr).Caption; } else if (attr is SectionAttribute) { if (section != null) { root.Add(section); } var sa = attr as SectionAttribute; section = new Section(sa.Caption, sa.Footer); } } if (skip) { continue; } if (caption == null) { caption = MakeCaption(mi.Name); } if (section == null) { section = new Section(); } Element element = null; if (mType == typeof(string)) { PasswordAttribute pa = null; AlignmentAttribute align = null; EntryAttribute ea = null; object html = null; Action invoke = null; bool multi = false; foreach (object attr in attrs) { if (attr is PasswordAttribute) { pa = attr as PasswordAttribute; } else if (attr is EntryAttribute) { ea = attr as EntryAttribute; } else if (attr is MultilineAttribute) { multi = true; } else if (attr is HtmlAttribute) { html = attr; } else if (attr is AlignmentAttribute) { align = attr as AlignmentAttribute; } if (attr is OnTapAttribute) { string mname = ((OnTapAttribute)attr).Method; if (callbacks == null) { throw new Exception("Your class contains [OnTap] attributes, but you passed a null object for `context' in the constructor"); } var method = callbacks.GetType().GetMethod(mname); if (method == null) { throw new Exception("Did not find method " + mname); } invoke = delegate { method.Invoke(method.IsStatic ? null : callbacks, new object [0]); }; } } string value = (string)GetValue(mi, o); if (pa != null) { element = new EntryElement(caption, pa.Placeholder, value, true); } else if (ea != null) { element = new EntryElement(caption, ea.Placeholder, value) { KeyboardType = ea.KeyboardType, AutocapitalizationType = ea.AutocapitalizationType, AutocorrectionType = ea.AutocorrectionType, ClearButtonMode = ea.ClearButtonMode } } ; else if (multi) { element = new MultilineElement(caption, value); } else if (html != null) { element = new HtmlElement(caption, value); } else { var selement = new StringElement(caption, value); element = selement; if (align != null) { selement.Alignment = align.Alignment; } } if (invoke != null) { ((StringElement)element).Tapped += invoke; } } else if (mType == typeof(float)) { var floatElement = new FloatElement(null, null, (float)GetValue(mi, o)); floatElement.Caption = caption; element = floatElement; foreach (object attr in attrs) { if (attr is RangeAttribute) { var ra = attr as RangeAttribute; floatElement.MinValue = (float)ra.Low; floatElement.MaxValue = (float)ra.High; floatElement.ShowCaption = ra.ShowCaption; } } } else if (mType == typeof(bool)) { bool checkbox = false; foreach (object attr in attrs) { if (attr is CheckboxAttribute) { checkbox = true; } } if (checkbox) { element = new CheckboxElement(caption, (bool)GetValue(mi, o)); } else { element = new BooleanElement(caption, (bool)GetValue(mi, o)); } } else if (mType == typeof(DateTime)) { var dateTime = (DateTime)GetValue(mi, o); bool asDate = false, asTime = false; foreach (object attr in attrs) { if (attr is DateAttribute) { asDate = true; } else if (attr is TimeAttribute) { asTime = true; } } // if (asDate) // element = new DateElement (caption, dateTime); // else if (asTime) // element = new TimeElement (caption, dateTime); // else // element = new DateTimeElement (caption, dateTime); } else if (mType.IsEnum) { var csection = new Section(); ulong evalue = Convert.ToUInt64(GetValue(mi, o), null); int idx = 0; int selected = 0; foreach (var fi in mType.GetFields(BindingFlags.Public | BindingFlags.Static)) { ulong v = Convert.ToUInt64(GetValue(fi, null)); if (v == evalue) { selected = idx; } CaptionAttribute ca = Attribute.GetCustomAttribute(fi, typeof(CaptionAttribute)) as CaptionAttribute; csection.Add(new RadioElement(ca != null ? ca.Caption : MakeCaption(fi.Name))); idx++; } element = new RootElement(caption, new RadioGroup(null, selected)) { csection }; } else if (mType == typeof(UIImage)) { element = new ImageElement((UIImage)GetValue(mi, o)); } else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(mType)) { var csection = new Section(); int count = 0; if (last_radio_index == null) { throw new Exception("IEnumerable found, but no previous int found"); } foreach (var e in (IEnumerable)GetValue(mi, o)) { csection.Add(new RadioElement(e.ToString())); count++; } int selected = (int)GetValue(last_radio_index, o); if (selected >= count || selected < 0) { selected = 0; } element = new RootElement(caption, new MemberRadioGroup(null, selected, last_radio_index)) { csection }; last_radio_index = null; } else if (typeof(int) == mType) { foreach (object attr in attrs) { if (attr is RadioSelectionAttribute) { last_radio_index = mi; break; } } } else { var nested = GetValue(mi, o); if (nested != null) { var newRoot = new RootElement(caption); Populate(callbacks, nested, newRoot); element = newRoot; } } if (element == null) { continue; } section.Add(element); mappings [element] = new MemberAndInstance(mi, o); } root.Add(section); }
public static RootElement TestElements() { RootElement re1 = new RootElement("re1"); Debug.WriteLine(re1.ToString()); Section s1 = new Section(); Debug.WriteLine(s1.ToString()); //Section s2 = new Section(new Android.Views.View(a1)); //Debug.WriteLine(s2.ToString()); Section s3 = new Section("s3"); Debug.WriteLine(s3.ToString()); //Section s4 = new Section // ( // new Android.Views.View(a1) // , new Android.Views.View(a1) // ); //Debug.WriteLine(s4.ToString()); Section s5 = new Section("caption", "footer"); Debug.WriteLine(s5.ToString()); StringElement se1 = new StringElement("se1"); Debug.WriteLine(se1.ToString()); StringElement se2 = new StringElement("se2", delegate() { }); Debug.WriteLine(se2.ToString()); //StringElement se3 = new StringElement("se3", 4); StringElement se4 = new StringElement("se4", "v4"); Debug.WriteLine(se4.ToString()); //StringElement se5 = new StringElement("se5", "v5", delegate() { }); // removed - protected (all with LayoutID) // StringElement se6 = new StringElement("se6", "v6", 4); // Debug.WriteLine(se6.ToString()); // not cross platform! // TODO: make it!?!?!? // AchievementElement BooleanElement be1 = new BooleanElement("be1", true); Debug.WriteLine(be1.ToString()); BooleanElement be2 = new BooleanElement("be2", false, "key"); Debug.WriteLine(be2.ToString()); // Abstract // BoolElement be3 = new BoolElement("be3", true); CheckboxElement cb1 = new CheckboxElement("cb1"); Debug.WriteLine(cb1.ToString()); CheckboxElement cb2 = new CheckboxElement("cb2", true); Debug.WriteLine(cb2.ToString()); CheckboxElement cb3 = new CheckboxElement("cb3", false, "group1"); Debug.WriteLine(cb3.ToString()); CheckboxElement cb4 = new CheckboxElement("cb4", false, "subcaption", "group2"); Debug.WriteLine(cb4.ToString()); DateElement de1 = new DateElement("dt1", DateTime.Now); Debug.WriteLine(de1.ToString()); // TODO: see issues // https://github.com/kevinmcmahon/MonoDroid.Dialog/issues?page=1&state=open EntryElement ee1 = new EntryElement("ee1", "ee1"); Debug.WriteLine(ee1.ToString()); EntryElement ee2 = new EntryElement("ee2", "ee2 placeholder", "ee2 value"); Debug.WriteLine(ee2.ToString()); EntryElement ee3 = new EntryElement("ee3", "ee3 placeholder", "ee3 value", true); Debug.WriteLine(ee3.ToString()); FloatElement fe1 = new FloatElement("fe1"); Debug.WriteLine(fe1.ToString()); FloatElement fe2 = new FloatElement(-0.1f, 0.1f, 3.2f); Debug.WriteLine(fe2.ToString()); FloatElement fe3 = new FloatElement ( null , null // no ctors new Android.Graphics.Bitmap() , 1.0f ); Debug.WriteLine(fe3.ToString()); HtmlElement he1 = new HtmlElement("he1", "http://holisiticware.net"); Debug.WriteLine(he1.ToString()); // TODO: image as filename - cross-platform ImageElement ie1 = new ImageElement(null); Debug.WriteLine(ie1.ToString()); // TODO: not in Kevin's MA.D // ImageStringElement MultilineElement me1 = new MultilineElement("me1"); Debug.WriteLine(me1.ToString()); MultilineElement me2 = new MultilineElement("me2", delegate() { }); Debug.WriteLine(me2.ToString()); MultilineElement me3 = new MultilineElement("me3", "me3 value"); Debug.WriteLine(me3.ToString()); RadioElement rde1 = new RadioElement("rde1"); Debug.WriteLine(rde1.ToString()); RadioElement rde2 = new RadioElement("rde1", "group3"); Debug.WriteLine(rde2.ToString()); // TODO: not in Kevin's MA.D // StyledMultilineElement TimeElement te1 = new TimeElement("TimeElement", DateTime.Now); Debug.WriteLine(te1.ToString()); re1.Add(s1); //re1.Add(s2); re1.Add(s3); //re1.Add(s4); re1.Add(s5); return re1; }
// // Creates one of the various StringElement classes, based on the // properties set. It tries to load the most memory efficient one // StringElement, if not, it fallsback to MultilineStringElement or // StyledStringElement // static Element LoadString(JsonObject json, object data) { string value = null; string caption = value; string background = null; Action ontap = null; Action onaccessorytap = null; int? lines = null; UITableViewCellAccessory?accessory = null; UILineBreakMode? linebreakmode = null; UITextAlignment? alignment = null; UIColor textcolor = null, detailcolor = null; UIFont font = null; UIFont detailfont = null; UITableViewCellStyle style = UITableViewCellStyle.Value1; foreach (var kv in json) { string kvalue = (string)kv.Value; switch (kv.Key) { case "caption": caption = kvalue; break; case "value": value = kvalue; break; case "background": background = kvalue; break; case "style": style = ToCellStyle(kvalue); break; case "ontap": case "onaccessorytap": string sontap = kvalue; int p = sontap.LastIndexOf('.'); if (p == -1) { break; } Action d = delegate { string cname = sontap.Substring(0, p); string mname = sontap.Substring(p + 1); foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { Type type = a.GetType(cname); if (type != null) { var mi = type.GetMethod(mname, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (mi != null) { mi.Invoke(null, new object [] { data }); } break; } } }; if (kv.Key == "ontap") { ontap = d; } else { onaccessorytap = d; } break; case "lines": int res; if (int.TryParse(kvalue, out res)) { lines = res; } break; case "accessory": accessory = ToAccessory(kvalue); break; case "textcolor": textcolor = ParseColor(kvalue); break; case "linebreak": linebreakmode = ToLinebreakMode(kvalue); break; case "font": font = ToFont(kvalue); break; case "subtitle": value = kvalue; style = UITableViewCellStyle.Subtitle; break; case "detailfont": detailfont = ToFont(kvalue); break; case "alignment": alignment = ToAlignment(kvalue); break; case "detailcolor": detailcolor = ParseColor(kvalue); break; case "type": break; default: Console.WriteLine("Unknown attribute: '{0}'", kv.Key); break; } } if (caption == null) { caption = ""; } if (font != null || style != UITableViewCellStyle.Value1 || detailfont != null || linebreakmode.HasValue || textcolor != null || accessory.HasValue || onaccessorytap != null || background != null || detailcolor != null) { StyledStringElement styled; if (lines.HasValue) { styled = new StyledMultilineElement(caption, value, style); styled.Lines = lines.Value; } else { styled = new StyledStringElement(caption, value, style); } if (ontap != null) { styled.Tapped += ontap; } if (onaccessorytap != null) { styled.AccessoryTapped += onaccessorytap; } if (font != null) { styled.Font = font; } if (detailfont != null) { styled.SubtitleFont = detailfont; } if (detailcolor != null) { styled.DetailColor = detailcolor; } if (textcolor != null) { styled.TextColor = textcolor; } if (accessory.HasValue) { styled.Accessory = accessory.Value; } if (linebreakmode.HasValue) { styled.LineBreakMode = linebreakmode.Value; } if (background != null) { if (background.Length > 1 && background [0] == '#') { styled.BackgroundColor = ParseColor(background); } else { styled.BackgroundUri = new Uri(background); } } if (alignment.HasValue) { styled.Alignment = alignment.Value; } return(styled); } else { StringElement se; if (lines == 0) { se = new MultilineElement(caption, value); } else { se = new StringElement(caption, value); } if (alignment.HasValue) { se.Alignment = alignment.Value; } if (ontap != null) { se.Tapped += ontap; } return(se); } }