/// <inheritdoc /> public override void Draw(Rect inRect) { // Check if the filtered list has changed if (filterChanged) { // Try lock the filtered widget list, otherwise wait until the next cycle to refresh content if (Monitor.TryEnter(filteredUserWidgetsLock)) { // Replace the list content with the new list of filtered widgets userListFlexContainer.Contents.Clear(); userListFlexContainer.Contents.AddRange(filteredUnblockedUserWidgets); if (filteredBlockedUserWidgets.Any()) { userListFlexContainer.Contents.Add(new SpacerWidget(height: BLOCKED_SPACER_MARGIN_TOP)); userListFlexContainer.Contents.Add(new TextWidget("Phinix_chat_blockedUsers".Translate(), anchor: TextAnchor.LowerCenter)); userListFlexContainer.Contents.Add(new SpacerWidget(height: BLOCKED_SPACER_MARGIN_BOTTOM)); userListFlexContainer.Contents.AddRange(filteredBlockedUserWidgets); } // Unset the filter changed flag filterChanged = false; Monitor.Exit(filteredUserWidgetsLock); } } // Set up the scrollable container Rect innerContainer = new Rect( x: inRect.xMin, y: inRect.yMin, width: inRect.width - SCROLLBAR_WIDTH, height: userListFlexContainer.CalcHeight(inRect.width - SCROLLBAR_WIDTH) ); // Start scrolling Widgets.BeginScrollView(inRect, ref scrollPos, innerContainer); // Draw the flex container userListFlexContainer.Draw(innerContainer); // Stop scrolling Widgets.EndScrollView(); }
public override void Draw(Rect inRect) { // Try and append new widgets if (Monitor.TryEnter(newMessageWidgetsLock)) { if (newMessageWidgets.Count > 0) { // Append each new widget to the flex container foreach (ChatMessageWidget widget in newMessageWidgets) { chatFlexContainer.Add(widget); } // Clear the new widget list and mark the messages as read newMessageWidgets.Clear(); Client.Instance.MarkAsRead(); } Monitor.Exit(newMessageWidgetsLock); } // Set up the scrollable container Rect innerContainer = new Rect( x: inRect.xMin, y: inRect.yMin, width: inRect.width - SCROLLBAR_WIDTH, height: chatFlexContainer.CalcHeight(inRect.width - SCROLLBAR_WIDTH) ); // Get a copy of the old scroll position Vector2 oldChatScroll = new Vector2(chatScroll.x, chatScroll.y); // Start scrolling Widgets.BeginScrollView(inRect, ref chatScroll, innerContainer); // Draw the flex container chatFlexContainer.Draw(innerContainer); // Stop scrolling Widgets.EndScrollView(); // Enter the logic to get sticky scrolling to work #region Sticky scroll logic // Credit to Aze for figuring out how to get the bottom scroll pos bool scrolledToBottom = chatScroll.y.Equals(innerContainer.height - inRect.height); bool scrollChanged = !chatScroll.y.Equals(oldChatScroll.y); float heightDifference = oldHeight - innerContainer.height; if (scrollChanged) { if (scrolledToBottom) { // Enable sticky scroll stickyScroll = true; } else { // Not at bottom, disable sticky scroll stickyScroll = false; } } else if (!heightDifference.Equals(0f)) { if (stickyScroll || scrollToBottom) { // Scroll to bottom chatScroll.y = innerContainer.height - inRect.height; scrollToBottom = false; } } // Update old height for the next pass oldHeight = innerContainer.height; #endregion }