public static Inline ToInline(TagNode node, TextPointer start = null, TextPointer end = null) { var parameter = node.AttributeValues.Count > 0 ? node.AttributeValues.Values.First() : null; switch (node.Tag.Name) { case "b": return(new Bold()); case "i": return(new Italic()); case "u": return(new Underline()); case "s": return(new Span { TextDecorations = TextDecorations.Strikethrough }); case "sub": return(new Span { BaselineAlignment = BaselineAlignment.Subscript, FontSize = 9 }); case "sup": return(new Span { BaselineAlignment = BaselineAlignment.Superscript, FontSize = 9 }); case "url": parameter = parameter ?? node.ToText(); var copyItem = new MenuItem { Header = Strings.Chat_CopyLink }; copyItem.Click += (sender, args) => Clipboard.SetText(parameter); var incognitoItem = new MenuItem { Header = Strings.Chat_OpenIncognito }; incognitoItem.Click += (sender, args) => { using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice")) { switch (key?.GetValue("Progid")?.ToString()) { case "FirefoxURL": Process.Start("firefox.exe", "-private-window " + parameter); break; case "ChromeHTML": Process.Start("chrome.exe", "-incognito " + parameter); break; default: Process.Start("iexplore.exe", "-private " + parameter); break; } } }; var link = new Hyperlink { NavigateUri = new Uri(parameter), ToolTip = parameter, ContextMenu = new ContextMenu { Items = { copyItem, incognitoItem } } }; link.RequestNavigate += (sender, e) => { if (UserSettings.Instance.General.AlwaysIncognito) { incognitoItem.RaiseEvent(new RoutedEventArgs(MenuItem.ClickEvent)); } else { Process.Start(e.Uri.ToString()); } }; return(link); case "big": return(new Span { FontSize = App.Current.Theme.FontSizeBig }); case "small": return(new Span { FontSize = App.Current.Theme.FontSizeSmall }); case "color": return(new Span { Foreground = GetColor(parameter) }); case "icon": return(new InlineUIContainer(new Image { Source = new BitmapImage(new Uri(CharacterViewModel.GetAvatar(node.ToText()))), Height = 50, Width = 50 }) { BaselineAlignment = BaselineAlignment.Center }); case "eicon": var source = new BitmapImage(new Uri($"https://static.f-list.net/images/eicon/{node.ToText().ToLower()}.gif")); var image = new Image { Height = 50, Width = 50 }; ImageBehavior.SetAnimatedSource(image, source); return(new InlineUIContainer(image)); case "session": //TODO channellistitem var session = new Hyperlink { Inlines = { new InlineUIContainer(new Path { Data = Icons.Channel, Fill = App.Current.Theme.Foreground, Margin = new Thickness(0, 0, 5, 0) }) }, NavigateUri = new Uri("http://x.com") }; var id = node.ToText(); session.RequestNavigate += (sender, args) => Mvx.GetSingleton <IChannelManager>().JoinChannel(id); node.SubNodes.Clear(); node.SubNodes.Add(new TextNode(parameter)); return(session); case "user": return(new InlineUIContainer(new Views.UserView { Character = Mvx.GetSingleton <CharacterViewModels>().GetCharacterViewModel(node.ToText()) })); } return(new Span()); }
private async Task <bool> AddProfile(SpannableStringBuilder builder, TagNode node, IDictionary <int, Bitmap> inlines, LinearLayout parent, GravityFlags gravity) { if (!layoutTags.Contains(node.Tag.Name)) { return(false); } AddTextView(builder, parent, gravity); var parameter = node.AttributeValues.Count > 0 ? node.AttributeValues.Values.First() : null; LinearLayout newParent; switch (node.Tag.Name) { case "collapse": newParent = new CollapsingView(Activity) { LayoutParameters = defaultLayoutParams, Title = parameter }; break; case "indent": newParent = new LinearLayout(Activity) { LayoutParameters = defaultLayoutParams, Orientation = Orientation.Vertical }; newParent.SetPaddingRelative(MLHelpers.DpToPixelsInt(10), 0, 0, 0); break; case "left": case "center": case "right": newParent = new LinearLayout(Activity) { LayoutParameters = defaultLayoutParams, Orientation = Orientation.Vertical }; gravity = node.Tag.Name == "center" ? GravityFlags.Center : node.Tag.Name == "right" ? GravityFlags.End : GravityFlags.Start; newParent.SetHorizontalGravity(gravity); break; case "hr": var value = new TypedValue(); Activity.Theme.ResolveAttribute(Resource.Attribute.colorAccent, value, true); var hr = new View(Activity) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, MLHelpers.DpToPixelsInt(2)) }; hr.SetBackgroundColor(new Color(value.Data)); parent.AddView(hr); return(true); case "heading": var heading = new TextView(Activity) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) { BottomMargin = MLHelpers.DpToPixelsInt(5) }, Text = node.ToText() }; heading.SetTextSize(ComplexUnitType.Sp, 22); parent.AddView(heading); return(true); case "img": var image = new ImageView(Activity) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) }; image.SetImageBitmap(inlines[int.Parse(parameter)]); parent.AddView(image); return(true); case "quote": newParent = new LinearLayout(Activity) { LayoutParameters = defaultLayoutParams, Orientation = Orientation.Vertical }; var padding = MLHelpers.DpToPixelsInt(5); newParent.SetPadding(padding, padding, padding, padding); newParent.SetBackgroundResource(Resource.Drawable.background_quote); var text = new TextView(Activity) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) { BottomMargin = MLHelpers.DpToPixelsInt(5) }, Text = Strings.Profile_Quote }; text.SetTypeface(null, TypefaceStyle.Bold); newParent.AddView(text); return(true); default: return(false); } parent.AddView(newParent); var remaining = await BBCodeBinding.GetFormatted(node, (n, b) => AddProfile(b, n, inlines, newParent, gravity)); AddTextView(remaining, newParent, gravity); return(true); }
private static async Task <bool> ApplyCustomHandlers(SpannableStringBuilder builder, TagNode node, Func <TagNode, SpannableStringBuilder, Task <bool> > customHandler) { if (customHandler != null && await customHandler(node, builder)) { return(true); } var start = builder.Length(); var parameter = node.AttributeValues.Count > 0 ? node.AttributeValues.Values.First() : null; switch (node.Tag.Name) { case "session": builder.Append(" " + parameter); builder.SetSpan(new ImageSpan(sessionIcon.Value), start, start + 1, SpanTypes.MarkMark); builder.SetSpan(new ClickableSpan(view => { var channel = parameter; var channelManager = Mvx.GetSingleton <IChannelManager>(); if (channelManager.JoinedChannels.ContainsKey(channel)) { ViewChannel(channel); return; } NotifyCollectionChangedEventHandler listener = null; listener = (sender, args) => { if (args.Action != NotifyCollectionChangedAction.Add || args.NewItems.Cast <Channel>().All(x => x.Name != channel)) { return; } ViewChannel(channel); channelManager.JoinedChannels.CollectionChanged -= listener; }; channelManager.JoinedChannels.CollectionChanged += listener; channelManager.JoinChannel(channel); }), start + 1, builder.Length(), 0); return(true); case "icon": case "eicon": builder.Append(' '); var icon = node.Tag.Name == "icon" ? Helpers.GetAvatar(node.ToText()) : $"https://static.f-list.net/images/eicon/{node.ToText()}.gif"; var image = new BitmapDrawable(await Mvx.GetSingleton <IMvxImageCache <Bitmap> >().RequestImage(icon)); var size = MLHelpers.DpToPixelsInt(40); image.SetBounds(0, 0, size, size); builder.SetSpan(new ImageSpan(image), start, start + 1, 0); return(true); case "user": var name = node.ToText(); builder.Append(" " + name); var character = Mvx.GetSingleton <ICharacterManager>().GetCharacter(name); builder.SetSpan(new ImageSpan(StatusIconConverter.GetDrawable(character.Status)), start, start + 1, SpanTypes.MarkMark); builder.SetSpan(new PureClickableSpan(view => { Mvx.GetSingleton <IViewModelNavigator>().Show <CharacterViewModel, string>(character.Name); }), start, builder.Length(), 0); builder.SetSpan(new ForegroundColorSpan(new Color(CharacterViewModel.GetColor(character).ARGB)), start + 1, builder.Length(), 0); if (character.IsBookmarked || character.IsFriend) { builder.SetSpan(new ColoredUnderlineSpan(unchecked ((int)0xff00cc00)), start + 1, builder.Length(), 0); } return(true); default: return(false); } }