internal void NotifyReplyClicked(ThreadViewerMessageTile messageTile) { ctlMessageComposer.ReplyToMessage(messageTile.LoadedMessage); // Scroll to the bottom of the window for (Widget widget = ctlVBox; widget != null; widget = widget.Parent) { var scrolledWindow = widget as ScrolledWindow; if (scrolledWindow != null) { scrolledWindow.Vadjustment.Value = scrolledWindow.Vadjustment.Upper; } } ctlMessageComposer.FocusEditor(); }
void RebuildView() { // Remove the old items var children = ctlVBox.AllChildren.OfType <Bin>() .Where(x => x is ThreadViewerMessageTile || x is ThreadViewerDivider) .ToArray(); foreach (var child in children) { ctlVBox.Remove(child); } tilesByMessageId.Clear(); var oldReplyToMessage = ctlMessageComposer.MessageBeingRepliedTo; ctlMessageComposer.SetIdle(); if (messagesToLoad == null || messagesToLoad.Count == 0) { return; } var trimmedList = messagesToLoad; // Don't show more than MaxMessagesToShow, since the rendering chokes // when there are too many controls. // TODO: Should we shown an ellipsis in this case? int trimIndex = trimmedList.Count - MaxMessagesToShow; if (trimIndex > 0) { trimmedList = messagesToLoad.Skip(trimIndex).ToArray(); } long lastThreadId = -1; int counter = 0; ThreadViewerMessageTile tileWidget = null; foreach (var message in trimmedList) { if (counter > 0 && lastThreadId != message.ThreadId) { // If the previous control is a tileWidget, then // hide its separator if (tileWidget != null) { tileWidget.ShowSeparator = false; } // Add a divider var dividerWidget = new ThreadViewerDivider(); dividerWidget.Name = "DividerTile" + counter.ToString(); dividerWidget.Events = EventMask.ButtonPressMask; ctlVBox.Add(dividerWidget); Box.BoxChild box2 = (Box.BoxChild) this.ctlVBox[dividerWidget]; box2.Position = counter; box2.Expand = false; box2.Fill = false; ++counter; dividerWidget.Show(); } lastThreadId = message.ThreadId; tileWidget = new ThreadViewerMessageTile(this); tileWidget.Name = "MessageTile" + counter.ToString(); tileWidget.Events = EventMask.ButtonPressMask; tileWidget.LoadMessage(message); if (messageToHighlight != null) { if (message.MessageId == messageToHighlight.MessageId) { tileWidget.Highlighted = true; } } ctlVBox.Add(tileWidget); tilesByMessageId.Add(message.MessageId, tileWidget); Box.BoxChild box = (Box.BoxChild) this.ctlVBox[tileWidget]; box.Position = counter; box.Expand = false; box.Fill = false; ++counter; tileWidget.Show(); // Attempt to restore the reply context if (message == oldReplyToMessage) { ctlMessageComposer.ReplyToMessage(oldReplyToMessage); oldReplyToMessage = null; } } if (ctlMessageComposer.ComposerMode == MessageComposerMode.Idle) { // If we lost our message, then default to replying to the whole thread ctlMessageComposer.ReplyToThread(trimmedList.Last().Thread); } SetThreadReadWithoutEvents(threadToLoad != null ? threadToLoad.Read : false); finishedLoading = false; }