/// <summary> /// Generates the trade row based on the cached state variables. /// This only needs to be run once. /// </summary> /// <returns>Generated trade row</returns> private Displayable generateTradeRow() { // Create a row to hold everything HorizontalFlexContainer row = new HorizontalFlexContainer(DEFAULT_SPACING); // Create a column to hold the text VerticalFlexContainer textColumn = new VerticalFlexContainer(0f); // Trade with ... label textColumn.Add( new Container( new DynamicTextWidget( textCallback: () => "Phinix_trade_activeTrade_tradeWithLabel".Translate(TextHelper.StripRichText(cachedOtherPartyDisplayName)), anchor: TextAnchor.MiddleLeft ), height: TRADE_WITH_LABEL_HEIGHT ) ); // Accepted state label textColumn.Add( new Container( new DynamicTextWidget( textCallback: () => ("Phinix_trade_activeTrade_theyHave" + (!cachedOtherPartyAccepted ? "Not" : "") + "Accepted").Translate(), font: GameFont.Tiny, anchor: TextAnchor.MiddleLeft ), height: ACCEPTED_STATE_LABEL_HEIGHT ) ); // Add the text column to the row row.Add(textColumn); // Open button row.Add( new Container( new ButtonWidget( label: "Phinix_trade_activeTrade_openButton".Translate(), clickAction: () => Find.WindowStack.Add(new TradeWindow(TradeId)) ), width: BUTTON_WIDTH ) ); // Cancel button row.Add( new Container( new ButtonWidget( label: "Phinix_trade_cancelButton".Translate(), clickAction: () => Client.Instance.CancelTrade(TradeId) ), width: BUTTON_WIDTH ) ); return(row); }
/// <inheritdoc /> public override void Draw(Rect inRect) { // Check if the child is non-fluid and smaller than the allocated space if (!child.IsFluidHeight && inRect.height > child.CalcHeight(inRect.width)) { // Create a flex container to hold the child and spacers VerticalFlexContainer column = new VerticalFlexContainer(0f); // Sandwich the child between two spacers column.Add(new SpacerWidget()); column.Add(child); column.Add(new SpacerWidget()); // Draw the container column.Draw(inRect); } else { // Just draw the child, there's no padding to be done here child.Draw(inRect); } }
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 }
/// <inheritdoc /> public override void Draw(Rect inRect) { // Try get the other party's UUID and display name if (!Client.Instance.TryGetOtherPartyUuid(tradeId, out string otherPartyUuid) || !Client.Instance.TryGetDisplayName(otherPartyUuid, out string otherPartyDisplayName)) { // Failed to get the other party's display name throw new Exception("Failed to get the other party's display name when drawing a TradeRow"); } // Try get the other party's accepted state if (!Client.Instance.TryGetPartyAccepted(tradeId, otherPartyUuid, out bool otherPartyAccepted)) { // Failed to get the other party's accepted state throw new Exception("Failed to get whether the other party has accepted or not when drawing a TradeRow"); } // Create a row to hold everything HorizontalFlexContainer row = new HorizontalFlexContainer(DEFAULT_SPACING); // Create a column to hold the text VerticalFlexContainer textColumn = new VerticalFlexContainer(0f); // Trade with ... label textColumn.Add( new Container( new TextWidget( text: "Phinix_trade_activeTrade_tradeWithLabel".Translate(TextHelper.StripRichText(otherPartyDisplayName)), anchor: TextAnchor.MiddleLeft ), height: TRADE_WITH_LABEL_HEIGHT ) ); // Accepted state label textColumn.Add( new Container( new TextWidget( text: ("Phinix_trade_activeTrade_theyHave" + (!otherPartyAccepted ? "Not" : "") + "Accepted").Translate(), font: GameFont.Tiny, anchor: TextAnchor.MiddleLeft ), height: ACCEPTED_STATE_LABEL_HEIGHT ) ); // Add the text column to the row row.Add(textColumn); // Open button row.Add( new Container( new ButtonWidget( label: "Phinix_trade_activeTrade_openButton".Translate(), clickAction: () => Find.WindowStack.Add(new TradeWindow(tradeId)) ), width: BUTTON_WIDTH ) ); // Cancel button row.Add( new Container( new ButtonWidget( label: "Phinix_trade_cancelButton".Translate(), clickAction: () => Client.Instance.CancelTrade(tradeId) ), width: BUTTON_WIDTH ) ); // Draw a background highlight if (drawAlternateBackground) { Widgets.DrawHighlight(inRect); } // Draw the row row.Draw(inRect); }