/// <summary> /// Handle mouse hover over an item to display a tooltip. /// </summary> protected override void OnMouseHover(EventArgs e) { base.OnMouseHover(e); CanvasElementBase item = CanvasItemLayout.ItemFromPosition(_lastMousePosition); if (item != null && item.HasToolTip) { _tooltip.Show(item.ToolTipString, this, _lastMousePosition.X + 16, _lastMousePosition.Y, 2500); } }
/// <summary> /// Insert a separator item in the layout. /// </summary> /// <param name="layout">A canvas layout object</param> /// <param name="height">Height of line</param> protected void AddSeparatorItem(CanvasItemLayout layout, int height) { const string _separatorChar = "•"; layout.Add(new CanvasText { Text = _separatorChar, Font = Font, LineHeight = height, ForeColour = Selected ? UI.System.SelectionTextColour : UI.Forums.HeaderFooterColour, }); }
/// <summary> /// Handle mouse movement to set the cursor. /// </summary> protected override void OnMouseMove(MouseEventArgs e) { if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { if (_dragBoxFromMouseDown != Rectangle.Empty && !_dragBoxFromMouseDown.Contains(e.X, e.Y)) { // OK - it is definitely a drag so handle it as such. DoDragDrop(this, DragDropEffects.All | DragDropEffects.Link); return; } } base.OnMouseMove(e); CanvasElementBase item = CanvasItemLayout.ItemFromPosition(e.Location); Cursor = (item != null && item.ID != ActionID.None) ? Cursors.Hand : Cursors.Default; _lastMousePosition = e.Location; }
/// <summary> /// Add a new button control to the layout. /// </summary> public override void Add(CanvasItemLayout layout, Rectangle clientBounds, Point position) { Control = new Button { Text = Text, Font = Font, AutoSize = true, ForeColor = ForeColour, Location = position }; Control.Click += ButtonOnClick; layout.Container.Controls.Add(Control); Bounds = new Rectangle(position.X, position.Y, Control.Size.Width, Math.Max(Control.Size.Height, LineHeight) + SpaceAfter); _layout = layout; }
/// <summary> /// Paint this item. We handle the painting for the background, separator, selection /// and the interior. The layout handles the painting for the components. /// </summary> protected override void OnPaint(PaintEventArgs e) { if (!_suspendPaint) { base.OnPaint(e); Rectangle drawRect = ClientRectangle; // Draw the top border for all except the first item if (Separator) { using (Pen separatorPen = new Pen(SeparatorColour)) { e.Graphics.DrawLine(separatorPen, drawRect.X, drawRect.Y, drawRect.X + drawRect.Width, drawRect.Y); } drawRect.Y += _separatorBarHeight; drawRect.Height -= _separatorBarHeight; } // Indent for canvas item level. Reduce(ref drawRect, GetIndent(), _interItemSpacing); // Draw the selection around the control. using (Pen edgePen = new Pen(Selected ? SelectionColour : BackColor)) { Color fillColour = Selected ? SelectionColour : ItemColour; using (Brush backBrush = new SolidBrush(fillColour)) { RectangleF rectangle = new RectangleF(drawRect.Left, drawRect.Top, drawRect.Width - 1, drawRect.Height - 1); e.Graphics.FillRoundedRectangle(edgePen, backBrush, rectangle); } } CanvasItemLayout.BackColor = Selected ? SelectionColour : ItemColour; // Draw the inner item contents. CanvasItemLayout.Draw(e.Graphics); } }
/// <summary> /// Initialises a new instance of the <see cref="CanvasElementBase"/> class and assigns /// this component the default ID of ComponentTypes.None. /// </summary> public CanvasElementBase(CanvasItemLayout.ItemType type) { Type = type; Visible = true; ID = ActionID.None; }
/// <summary> /// Override to add the given component to the layout using the specified client bounds and /// position within the client. /// </summary> /// <param name="layout">The containing canvas item layout</param> /// <param name="clientBounds">The client bounds for the layout, relative to the canvas item top left corner</param> /// <param name="position">The current position within the layout</param> public virtual void Add(CanvasItemLayout layout, Rectangle clientBounds, Point position) { }
/// <summary> /// Select all text in the item. /// </summary> public void SelectAll() { CanvasItemLayout.SelectAll(); }
/// <summary> /// Build the layout for this item from the message. /// </summary> protected override CanvasItemLayout BuildLayout() { CanvasItemLayout newLayout = new CanvasItemLayout(this, DrawRectangle); newLayout.Add(new CanvasImage { ImageWidth = 100, ImageHeight = 100, Image = Program.CIXReaderLogo, Margin = new Rectangle(0, 0, 10, 0) }); newLayout.AddNewColumn(); newLayout.Add(new CanvasText { Text = Resources.WelcomeTitle, Font = UI.GetFont(UI.System.font, 20), ForeColour = UI.Forums.BodyColour }); newLayout.AddNewLine(); newLayout.Add(new CanvasHTMLText { Text = Resources.WelcomeSubtitle, Font = _font, ForeColour = UI.Forums.BodyColour }); newLayout.AddNewLine(); if (Threads.Count > 0) { newLayout.Add(new CanvasText { Text = Resources.TopThreads, Font = _headerFont, ForeColour = UI.Forums.BodyColour, Margin = new Rectangle(0, 0, 0, 15) }); newLayout.AddNewLine(); } foreach (CIXThread thread in Threads) { newLayout.AddBeginSection(); newLayout.Add(new CanvasImage { ID = ActionID.AuthorImage, ImageWidth = 40, ImageHeight = 40, Tag = thread.Author, Margin = new Rectangle(0, 0, 5, 0), Image = Mugshot.MugshotForUser(thread.Author, true).RealImage }); newLayout.AddNewColumn(); string bodyText = thread.Body ?? string.Empty; newLayout.Add(new CanvasText { ID = ActionID.GoToSource, Text = bodyText.FirstLine().TruncateByWordWithLimit(80), Font = _font, Tag = thread, Alignment = CanvasTextAlign.Top, LineHeight = _headerLineHeight, ForeColour = UI.Forums.BodyColour }); newLayout.AddNewLine(); newLayout.Add(new CanvasText { ID = ActionID.AuthorImage, Text = string.Format(Resources.StartedBy, thread.Author), Font = _font, Alignment = CanvasTextAlign.Top, Tag = thread.Author, LineHeight = _headerLineHeight, ForeColour = UI.Forums.HeaderFooterColour }); AddSeparatorItem(newLayout, _headerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.GoToSource, Text = string.Format("{0}/{1}", thread.Forum, thread.Topic), Font = _font, Tag = thread, Alignment = CanvasTextAlign.Top, LineHeight = _headerLineHeight, Margin = new Rectangle(0, 0, 0, 15), ForeColour = UI.System.LinkColour }); AddSeparatorItem(newLayout, _headerLineHeight); newLayout.Add(new CanvasText { Text = string.Format("posted at {0}", thread.Date.FriendlyString(true)), Font = _font, Tag = thread, Alignment = CanvasTextAlign.Top, LineHeight = _headerLineHeight, Margin = new Rectangle(0, 0, 0, 15), ForeColour = UI.Forums.HeaderFooterColour }); newLayout.AddEndSection(); } if (OnlineUsers.Users != null) { newLayout.Add(new CanvasText { Text = Resources.OnlineUsers, Font = _headerFont, ForeColour = UI.Forums.BodyColour, Margin = new Rectangle(0, 0, 0, 15) }); newLayout.AddNewLine(); foreach (OnlineUser user in OnlineUsers.Users) { newLayout.Add(new CanvasImage { ID = ActionID.AuthorImage, Image = Mugshot.MugshotForUser(user.Name, true).RealImage, Text = user.Name, Font = UI.GetFont(UI.System.font, 8), Tag = user.Name, NoWrap = true, ForeColour = UI.System.ForegroundColour, ImageWidth = 80, ImageHeight = 80 }); } } return newLayout; }
/// <summary> /// Add a new image control to the layout. /// </summary> public override void Add(CanvasItemLayout layout, Rectangle clientBounds, Point position) { _layout = layout; SetPosition(position, clientBounds); }
/// <summary> /// Handle mouse clicks on the control. /// </summary> /// <param name="e">Mouse event argument</param> protected override void OnMouseClick(MouseEventArgs e) { _view.HandleSelect(this, CanvasItemLayout.ItemFromPosition(e.Location)); }
/// <summary> /// Pass the clear selection through to the canvas item. /// </summary> public void ClearSelection() { CanvasItemLayout.ClearSelection(); }
/// <summary> /// Build the layout for this item. /// </summary> protected override CanvasItemLayout BuildLayout() { CanvasItemLayout newLayout = new CanvasItemLayout(this, DrawRectangle); if (Items != null) { // Title newLayout.Add(new CanvasText { ID = ActionID.None, ForeColour = UI.System.ForegroundColour, Alignment = CanvasTextAlign.Top, LineHeight = 30, Font = UI.GetFont(UI.System.font, 12), Text = Title }); newLayout.AddNewLine(); // Iterate and show an image for every profile. foreach (string username in Items) { newLayout.Add(new CanvasImage { ID = ActionID.AuthorImage, Image = Mugshot.MugshotForUser(username, true).RealImage, Text = username, Font = UI.GetFont(UI.System.font, 8), Tag = username, NoWrap = SingleLine, ForeColour = UI.System.ForegroundColour, ImageWidth = 80, ImageHeight = 80 }); } newLayout.AddNewLine(); } return newLayout; }
/// <summary> /// Build the layout for this item from the message. /// </summary> protected override CanvasItemLayout BuildLayout() { CanvasItemLayout newLayout = new CanvasItemLayout(this, DrawRectangle); if (Message != null) { newLayout.Add(new CanvasImage { ID = ActionID.AuthorImage, Image = Image, ImageWidth = 50, ImageHeight = 50 }); newLayout.AddNewColumn(); newLayout.Add(new CanvasText { ID = ActionID.Profile, Text = Message.Author, Font = _authorFont, LineHeight = _headerLineHeight, ForeColour = UI.Forums.HeaderFooterColour, }); AddSeparatorItem(newLayout, _headerLineHeight); newLayout.Add(new CanvasText { Text = FullDateString ? Message.Date.ToString("d MMM yyyy") + " " + Message.Date.ToShortTimeString() : Message.Date.FriendlyString(true), Font = _font, LineHeight = _headerLineHeight, ForeColour = UI.Forums.HeaderFooterColour, }); newLayout.AddNewLine(); newLayout.Add(new CanvasHTMLText { Text = Message.Body, Font = _font, ExpandInlineImages = _view.ExpandInlineImages, DisableMarkup = _view.DisableMarkup, ForeColour = ForeColor }); newLayout.AddNewLine(); } return newLayout; }
/// <summary> /// Build the layout for this item from the message. /// </summary> protected override CanvasItemLayout BuildLayout() { CanvasItemLayout newLayout = new CanvasItemLayout(this, DrawRectangle); if (Message != null) { if (Full) { return BuildFullLayout(newLayout, false); } if (Minimal) { return BuildMinimalLayout(newLayout); } // Handle collapsed messages especially if (Collapsed) { return BuildCollapsedLayout(newLayout); } // Need to reset the item colour because the item may have changed from being local ItemColour = (Message.IsDraft) ? UI.Forums.DraftColour : (!Message.IsRoot) ? UI.Forums.CommentColour : UI.Forums.RootColour; newLayout = BuildFullLayout(newLayout, true); } return newLayout; }
/// <summary> /// Add a new static text component in the layout at the given position and wrapped to fit within /// the client bounds. /// </summary> public override void Add(CanvasItemLayout layout, Rectangle clientBounds, Point position) { _layout = layout; SetPosition(position, clientBounds); }
/// <summary> /// Build the layout for a collapsed root message. /// </summary> private CanvasItemLayout BuildCollapsedLayout(CanvasItemLayout newLayout) { // Need to reset the item colour because the item may have changed from being local ItemColour = UI.Forums.CollapsedColour; newLayout.Add(new CanvasImage { ID = ActionID.AuthorImage, Image = Image, ImageWidth = 50, ImageHeight = 50 }); newLayout.AddNewColumn(); newLayout.Add(new CanvasImage { ID = ActionID.Expand, Image = Resources.ExpandArrow, LineHeight = _headerLineHeight }); newLayout.Add(new CanvasImage { ID = ActionID.Read, Image = Message.Unread ? Resources.UnreadMessage : Resources.ReadMessage, LineHeight = _headerLineHeight }); newLayout.Add(new CanvasText { ID = ActionID.Profile, Text = Message.Author, Font = _headerFont, LineHeight = _headerLineHeight, ForeColour = ReadColourForMessage(), }); AddSeparatorItem(newLayout, _headerLineHeight); newLayout.Add(new CanvasText { Text = DateForMessage(), Font = _headerFont, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); newLayout.AddNewLine(); // First two lines of the message body string bodyText = Message.Body ?? string.Empty; newLayout.Add(new CanvasText { Text = bodyText.FirstLine(), Font = _headerFont, LineHeight = _compactHeight, ForeColour = Selected ? UI.System.SelectionTextColour : ForeColor, }); newLayout.AddNewLine(); // Footer line newLayout.Add(new CanvasImage { ID = ActionID.Expand, Image = Resources.Bubble, ImageWidth = 14, ImageHeight = 14 }); newLayout.Add(new CanvasText { ID = ActionID.Expand, Text = (Message.ChildCount > 1) ? string.Format(Resources.ManyReplies, Message.ChildCount) : Resources.OneReply, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); AddSeparatorItem(newLayout, _footerLineHeight); // Ignore newLayout.Add(new CanvasText { ID = ActionID.Ignore, Text = Message.Ignored ? Resources.Unignore : Resources.Ignore, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); return newLayout; }
/// <summary> /// Build the layout for a full message. /// </summary> private CanvasItemLayout BuildFullLayout(CanvasItemLayout newLayout, bool canExpandRoot) { bool isWithdrawn = Message.IsWithdrawn; if (Image != null) { newLayout.Add(new CanvasImage { ID = ActionID.AuthorImage, Image = Image, ImageWidth = 50, ImageHeight = 50, Margin = new Rectangle(0, 0, 7, 0) }); newLayout.AddNewColumn(); } if (canExpandRoot) { if (Message.IsRoot && Message.ChildCount > 0) { newLayout.Add(new CanvasImage { ID = ActionID.Expand, Image = Resources.CollapseArrow }); } newLayout.Add(new CanvasImage { ID = ActionID.Read, Image = ReadImageForMessage(), LineHeight = _headerLineHeight }); } newLayout.Add(new CanvasText { ID = ActionID.Profile, Text = Message.Author, Font = _headerFont, LineHeight = _headerLineHeight, ForeColour = ReadColourForMessage(), }); AddSeparatorItem(newLayout, _headerLineHeight); newLayout.Add(new CanvasText { Text = DateForMessage(), Font = _headerFont, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); newLayout.Add(new CanvasImage { ID = ActionID.Star, Image = Message.Starred ? Resources.ActiveStar : Resources.InactiveStar, LineHeight = _headerLineHeight }); if (Message.IsDraft) { newLayout.Add(new CanvasImage { ID = ActionID.Edit, Image = Resources.Draft, LineHeight = _headerLineHeight }); } newLayout.Add(new CanvasText { ID = ActionID.Link, Text = string.Format(" {0}", !Message.IsPseudo ? Message.RemoteID.ToString(CultureInfo.InvariantCulture) : Resources.DraftText), Font = _headerFont, ToolTipString = (ShowTooltips) ? Resources.LinkTooltip : null, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); if (!Message.IsRoot) { AddSeparatorItem(newLayout, _headerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.Original, Text = string.Format(Resources.ReplyToMessage, Message.CommentID), Font = _headerFont, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); } newLayout.AddNewLine(); if (ShowFolder) { newLayout.Add(new CanvasImage { ID = ActionID.GoToSource, Image = Resources.Topic, LineHeight = _headerLineHeight }); Folder topic = Message.Topic; Folder forum = topic.ParentFolder; newLayout.Add(new CanvasText { Text = string.Format("{0}/{1}", forum.Name, topic.Name), Font = _font, ID = ActionID.GoToSource, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); newLayout.AddNewLine(); } string bodyText = Message.Body ?? string.Empty; newLayout.Add(new CanvasHTMLText { Text = bodyText, Font = _font, ExpandInlineImages = _view.ExpandInlineImages, Highlight = Highlight, DisableMarkup = _view.DisableMarkup, LineHeight = (Level == 0 || Selected) ? 0 : _compactHeight, BackColor = Color.Transparent, ForeColour = (Message.Ignored || isWithdrawn) ? HeaderFooterColour() : ForeColor, SpaceAfter = 5 }); newLayout.AddNewLine(); // Add an e-mail link to contact the author newLayout.Add(new CanvasImage { ID = ActionID.Email, Image = Resources.Mail, LineHeight = _footerLineHeight }); // The user can only comment on messages which have been synced with the server. // Otherwise for draft messages that are not pending, they can edit them as long // as the network is offline as otherwise the transition from draft to sync will // be too quick. Folder folder = Message.Topic; Folder forumFolder = folder.ParentFolder; DirForum dirforum = CIX.DirectoryCollection.ForumByName(forumFolder.Name); bool isModerator = dirforum != null && dirforum.IsModerator; bool canReply = !(folder.Flags.HasFlag(FolderFlags.OwnerCommentsOnly) && !Message.IsMine); if (folder.IsReadOnly && !isModerator) { canReply = false; } if (canReply) { if (!Message.IsPseudo) { AddSeparatorItem(newLayout, _footerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.Reply, Text = Resources.Comment, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); } else if (Message.IsDraft) { AddSeparatorItem(newLayout, _footerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.Edit, Text = Resources.Edit, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); } } // Ignore if (!Message.IsPseudo) { AddSeparatorItem(newLayout, _footerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.Ignore, Text = Message.Ignored ? Resources.Unignore : Resources.Ignore, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); AddSeparatorItem(newLayout, _footerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.Priority, Text = Message.Priority ? Resources.Normal : Resources.Priority, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); } // Allow withdraw if we own this message or we are a moderator // of the forum. if ((Message.IsMine || isModerator) && !Message.IsPseudo && !isWithdrawn) { AddSeparatorItem(newLayout, _footerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.Withdraw, Text = Resources.Withdraw, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); } // Allow delete if this is a local draft if (Message.IsPseudo) { AddSeparatorItem(newLayout, _footerLineHeight); newLayout.Add(new CanvasText { ID = ActionID.Delete, Text = Resources.Delete, Font = _footerFont, LineHeight = _footerLineHeight, ForeColour = HeaderFooterColour(), }); } return newLayout; }
/// <summary> /// Build the layout for this item from the message. /// </summary> protected override CanvasItemLayout BuildLayout() { CanvasItemLayout newLayout = new CanvasItemLayout(this, DrawRectangle); if (Folder != null) { // Forum category icon, if one is present. At some point we should // replace this with an actual forum icon. Image categoryImage = null; if (Forum != null) { categoryImage = CategoryFolder.IconForCategory(Forum.Cat); } if (categoryImage == null) { categoryImage = Resources.Categories; } if (categoryImage != null) { newLayout.Add(new CanvasImage { ID = ActionID.None, Image = categoryImage, ImageWidth = 50, ImageHeight = 50 }); newLayout.AddNewColumn(); } // Forum name newLayout.Add(new CanvasText { ID = ActionID.None, Text = Folder.Name, Font = NameFont, LineHeight = NameFont.Height + 10, ForeColour = UI.System.ForegroundColour }); newLayout.AddNewLine(); // Forum title. if (Forum != null && !string.IsNullOrEmpty(Forum.Title)) { newLayout.Add(new CanvasHTMLText { ID = ActionID.None, Text = Forum.Title, Font = TitleFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); newLayout.AddNewLine(); } // Forum description. if (Forum != null && !string.IsNullOrEmpty(Forum.Desc)) { newLayout.Add(new CanvasHTMLText { ID = ActionID.None, HTMLText = Forum.Desc, Font = DescriptionFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); newLayout.AddNewLine(); } // If the Join is pending, say so. if (Forum != null && Forum.JoinPending) { newLayout.Add(new CanvasImage { Image = Resources.Warning, ImageWidth = 16, ImageHeight = 16 }); newLayout.Add(new CanvasText { ID = ActionID.None, Text = Resources.JoinPending, LineHeight = 16, Margin = new Rectangle(0, 0, 0, 15), Font = Font }); newLayout.AddNewLine(); } // If a Resign is pending, say so. if (Folder.ResignPending) { newLayout.Add(new CanvasImage { Image = Resources.Warning, ImageWidth = 16, ImageHeight = 16 }); newLayout.Add(new CanvasText { ID = ActionID.None, Text = Resources.ResignPending, LineHeight = 16, Margin = new Rectangle(0, 0, 0, 15), Font = Font, }); newLayout.AddNewLine(); } // If the Join failed, say so too. if (Folder.Flags.HasFlag(FolderFlags.JoinFailed)) { newLayout.Add(new CanvasImage { Image = Resources.Error1, ImageWidth = 16, ImageHeight = 16 }); newLayout.Add(new CanvasText { ID = ActionID.None, Text = Resources.JoinFailure, LineHeight = 16, Font = Font, Margin = new Rectangle(0, 0, 0, 15) }); newLayout.AddNewLine(); } // Resign/Join button // Don't display if the forum doesn't permit the user to resign it. if (Folder.CanResign) { if (Folder.IsResigned || Folder.Flags.HasFlag(FolderFlags.JoinFailed) || Folder.ResignPending) { newLayout.Add(new CanvasButton { ID = ActionID.JoinForum, Text = Resources.JoinForum, Font = DescriptionFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); } else { newLayout.Add(new CanvasButton { ID = ActionID.ResignForum, Text = Resources.ResignForum, Font = DescriptionFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); } } // Delete button // Offer the option to delete the folder if we're not joined to it newLayout.Add(new CanvasButton { ID = ActionID.Delete, Text = Resources.DeleteFolder, Font = DescriptionFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); // Add Participants button newLayout.Add(new CanvasButton { ID = ActionID.Participants, Text = Resources.Participants, Font = DescriptionFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); // Refresh button newLayout.Add(new CanvasButton { ID = ActionID.Refresh, Text = Resources.RefreshText, Font = DescriptionFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); // Manage Forum button if (Forum != null && Forum.IsModerator) { newLayout.Add(new CanvasButton { ID = ActionID.ManageForum, Text = Resources.ManageForum, Font = DescriptionFont, ForeColour = UI.System.ForegroundColour, SpaceAfter = 15 }); } } return newLayout; }
/// <summary> /// Build the layout for a minimal message. /// </summary> private CanvasItemLayout BuildMinimalLayout(CanvasItemLayout newLayout) { ItemColour = Message.IsPseudo ? UI.Forums.DraftColour : Message.IsRoot ? UI.Forums.RootColour : UI.Forums.CommentColour; if (Message.IsRoot && Message.ChildCount > 0 && !Flat) { newLayout.Add(new CanvasImage { ID = ActionID.Expand, Image = Collapsed ? Resources.ExpandArrow : Resources.CollapseArrow }); } newLayout.Add(new CanvasImage { ID = ActionID.Read, Image = ReadImageForMessage(), LineHeight = _headerLineHeight }); newLayout.Add(new CanvasText { ID = ActionID.Profile, Text = Message.Author, Font = _footerFont, LineHeight = _headerLineHeight, ForeColour = ReadColourForMessage(), }); AddSeparatorItem(newLayout, _headerLineHeight); newLayout.Add(new CanvasText { Text = DateForMessage(), Font = _footerFont, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); newLayout.Add(new CanvasImage { ID = ActionID.Star, Image = Message.Starred ? Resources.ActiveStar : Resources.InactiveStar, LineHeight = _headerLineHeight }); if (!Message.IsPseudo) { newLayout.Add(new CanvasText { Text = Message.RemoteID.ToString(CultureInfo.InvariantCulture), ID = ActionID.Link, Font = _footerFont, ToolTipString = (ShowTooltips) ? Resources.LinkTooltip : null, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); AddSeparatorItem(newLayout, _headerLineHeight); } string bodyText = Message.Body ?? string.Empty; newLayout.Add(new CanvasText { Text = bodyText.FirstLine(), Font = _footerFont, LineHeight = _headerLineHeight, ForeColour = HeaderFooterColour(), }); return newLayout; }
/// <summary> /// Add a new HTML label within the layout at the given position. The client bounds determine the /// maximum extent of the text. /// </summary> public override void Add(CanvasItemLayout layout, Rectangle clientBounds, Point position) { int width = clientBounds.Width - (position.X - clientBounds.X); if (_text == null) { _text = new StringBuilder((HTMLText != null) ? HTMLWrap(HTMLText) : HTML(Text)); } // Do Smiley replacement if (!DisableMarkup) { ReplaceEmoticon(_text, emoSmiley); ReplaceEmoticon(_text, emoFrown); ReplaceEmoticon(_text, emoLaugh); ReplaceEmoticon(_text, emoWink); ReplaceEmoticon(_text, emoShades); } string stylesheet = string.Format("pre {{ white-space: pre-wrap; margin-top: 0px }}\n" + "div {{ color: rgb({0}) }}\n" + "::selection {{ color: rgb({1}); background-color: rgb({2}) }}\n" + "blockquote {{ color: rgb({3}) }}\n" + "blockquote blockquote {{ color: rgb({4}) }}\n" + "blockquote blockquote blockquote {{ color: rgb({5}) }}", UI.ToString(layout.Container.Selected ? UI.Forums.SelectionTextColour : ForeColour), UI.ToString(layout.Container.Selected ? UI.Forums.SelectionColour : UI.Forums.SelectionTextColour), UI.ToString(layout.Container.Selected ? UI.Forums.SelectionTextColour : UI.Forums.SelectionColour), UI.ToString(layout.Container.Selected ? UI.Forums.SelectionTextColour : UI.Forums.Level1QuoteColour), UI.ToString(layout.Container.Selected ? UI.Forums.SelectionTextColour : UI.Forums.Level2QuoteColour), UI.ToString(layout.Container.Selected ? UI.Forums.SelectionTextColour : UI.Forums.Level3QuoteColour)); Size size = new Size(width, MaxHeight); HtmlLabel label = new HtmlLabel { AutoSizeHeightOnly = false, AutoSize = true, Size = size, MaximumSize = size, Location = position, ForeColor = ForeColour, BaseStylesheet = stylesheet, BackColor = Color.Transparent, IsSelectionEnabled = true, Visible = true }; Control = label; label.LinkClicked += OnLinkClicked; label.Click += OnClick; label.MouseDown += OnMouseDown; label.MouseMove += OnMouseMove; label.ImageLoad += LabelOnImageLoad; label.PreviewKeyDown += OnPreviewKeyDown; label.KeyDown += OnKeyDown; label.ContextMenuInvoked += OnContextMenuInvoked; label.LinkHover += OnLinkHover; try { label.Text = _text.ToString(); } catch (Exception) { // This can crash in HtmlRenderer so we need this safeguard. label.Text = string.Empty; } layout.Container.Controls.Add(Control); Bounds = new Rectangle(position.X, position.Y, Control.Size.Width, Control.Size.Height + SpaceAfter); _layout = layout; }