public static string WrapText(string text, int width, SpriteFontMSDF font) { var textSize = font.Measure(text); if (textSize.X > width) { var lines = text.Split('\n').ToList(); for (var i = 0; i < lines.Count; i++) { var line = lines[i]; if (font.Measure(line).X <= width) { continue; } // Scan forwards until we find the last word that fits // This guarantees a small bound on the amount of string we need to search before a linebreak var start = 0; while (true) { var spaceIndex = line.IndexOf(' ', start); if (spaceIndex == -1) { break; } var fragmentWidth = font.Measure(line.Substring(0, spaceIndex)).X; if (fragmentWidth > width) { break; } start = spaceIndex + 1; } if (start > 0) { lines[i] = line.Substring(0, start - 1); lines.Insert(i + 1, line.Substring(start)); } } return(string.Join("\n", lines)); } return(text); }
public override void Draw() { var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset; overlayFont = Game.Renderer.Fonts["TinyBold"]; holdOffset = iconOffset - overlayFont.Measure(HoldText) / 2; readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2; timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, worldRenderer.World.Timestep)) / 2; // Icons foreach (var p in icons.Values) { WidgetUtils.DrawSHPCentered(p.Sprite, p.Pos + iconOffset, p.Palette); // Charge progress var sp = p.Power; clock.PlayFetchIndex(ClockSequence, () => sp.TotalTime == 0 ? clock.CurrentSequence.Length - 1 : (sp.TotalTime - sp.RemainingTime) * (clock.CurrentSequence.Length - 1) / sp.TotalTime); clock.Tick(); WidgetUtils.DrawSHPCentered(clock.Image, p.Pos + iconOffset, p.IconClockPalette); } // Overlay foreach (var p in icons.Values) { if (p.Power.Ready) { overlayFont.DrawTextWithContrast(ReadyText, p.Pos + readyOffset, Color.White, Color.Black, 1); } else if (!p.Power.Active) { overlayFont.DrawTextWithContrast(HoldText, p.Pos + holdOffset, Color.White, Color.Black, 1); } else { overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(p.Power.RemainingTime, worldRenderer.World.Timestep), p.Pos + timeOffset, Color.White, Color.Black, 1); } } }
public override void Draw() { var preview = Preview(); if (preview == null) { return; } // Stash a copy of the minimap to ensure consistency // (it may be modified by another thread) minimap = preview.GetMinimap(); if (minimap == null) { return; } // Update map rect previewScale = Math.Min(RenderBounds.Width / minimap.Size.X, RenderBounds.Height / minimap.Size.Y); var w = (int)(previewScale * minimap.Size.X); var h = (int)(previewScale * minimap.Size.Y); var x = RenderBounds.X + (RenderBounds.Width - w) / 2; var y = RenderBounds.Y + (RenderBounds.Height - h) / 2; mapRect = new Rectangle(x, y, w, h); Game.Renderer.RgbaSpriteRenderer.DrawSprite(minimap, new float2(mapRect.Location), new float2(mapRect.Size)); TooltipSpawnIndex = -1; if (ShowSpawnPoints) { var colors = SpawnOccupants().ToDictionary(c => c.Key, c => c.Value.Color); var spawnPoints = preview.SpawnPoints; var gridType = preview.GridType; foreach (var p in spawnPoints) { var owned = colors.ContainsKey(p); var pos = ConvertToPreview(p, gridType); var sprite = owned ? spawnClaimed : spawnUnclaimed; var offset = new int2(sprite.Bounds.Width, sprite.Bounds.Height) / 2; if (owned) { WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, sprite.Bounds.Width - 2, sprite.Bounds.Height - 2), colors[p]); } Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos - offset); var number = Convert.ToChar('A' + spawnPoints.IndexOf(p)).ToString(); var textOffset = spawnFont.Measure(number) / 2 + spawnLabelOffset; spawnFont.DrawTextWithContrast(number, pos - textOffset, spawnColor, spawnContrastColor, 1); if (((pos - Viewport.LastMousePos).ToFloat2() / offset.ToFloat2()).LengthSquared <= 1) { TooltipSpawnIndex = spawnPoints.IndexOf(p) + 1; } } } }
public void Render(WorldRenderer wr) { var screenPos = wr.Viewport.Zoom * (wr.ScreenPosition(pos) - wr.Viewport.TopLeft.ToFloat2()) - 0.5f * font.Measure(text).ToFloat2(); var screenPxPos = new float2((float)Math.Round(screenPos.X), (float)Math.Round(screenPos.Y)); font.DrawTextWithContrast(text, screenPxPos, color, bgDark, bgLight, 1); }
public static string TruncateText(string text, int width, SpriteFontMSDF font) { var trimmedWidth = font.Measure(text).X; if (trimmedWidth <= width) { return(text); } var trimmed = text; while (trimmedWidth > width && trimmed.Length > 3) { trimmed = text.Substring(0, trimmed.Length - 4) + "..."; trimmedWidth = font.Measure(trimmed).X; } return(trimmed); }
public override void Display() { if (r == null || loadTimer.Elapsed.TotalSeconds < 0.25) { return; } loadTimer.Restart(); loadTick = ++loadTick % 8; r.BeginFrame(int2.Zero, 1f); r.RgbaSpriteRenderer.DrawSprite(gdiLogo, gdiPos); r.RgbaSpriteRenderer.DrawSprite(nodLogo, nodPos); r.RgbaSpriteRenderer.DrawSprite(evaLogo, evaPos); WidgetUtils.DrawPanelPartial(bounds, PanelSides.Edges, borderTop, borderBottom, borderLeft, borderRight, cornerTopLeft, cornerTopRight, cornerBottomLeft, cornerBottomRight, null); var barY = bounds.Height - 78; // The fonts dictionary may change when switching between the mod and content installer if (r.Fonts != rendererFonts) { rendererFonts = r.Fonts; loadingFont = r.Fonts["BigBold"]; loadingText = loadInfo["Text"]; loadingPos = new float2((bounds.Width - loadingFont.Measure(loadingText).X) / 2, barY); versionFont = r.Fonts["Regular"]; var versionSize = versionFont.Measure(versionText); versionPos = new float2(bounds.Width - 107 - versionSize.X / 2, 115 - versionSize.Y / 2); } if (loadingFont != null) { loadingFont.DrawText(loadingText, loadingPos, Color.Gray); } if (versionFont != null) { versionFont.DrawTextWithContrast(versionText, versionPos, Color.White, Color.Black, 2); } for (var i = 0; i <= 8; i++) { var block = loadTick == i ? brightBlock : dimBlock; r.RgbaSpriteRenderer.DrawSprite(block, new float2(bounds.Width / 2 - 114 - i * 32, barY)); r.RgbaSpriteRenderer.DrawSprite(block, new float2(bounds.Width / 2 + 114 + i * 32 - 16, barY)); } r.EndFrame(nih); }
IEnumerable <IRenderable> RenderInner(Actor self, WorldRenderer wr) { if (IsTraitDisabled || self.IsDead || !self.IsInWorld) { return(Enumerable.Empty <IRenderable>()); } if (self.World.RenderPlayer != null) { var stance = self.Owner.Stances[self.World.RenderPlayer]; if (!Info.ValidStances.HasStance(stance)) { return(Enumerable.Empty <IRenderable>()); } } if (!ShouldRender(self) || self.World.FogObscures(self)) { return(Enumerable.Empty <IRenderable>()); } var bounds = decorationBounds.FirstNonEmptyBounds(self, wr); var halfSize = font.Measure(Info.Text) / 2; var boundsOffset = new int2(bounds.Left + bounds.Right, bounds.Top + bounds.Bottom) / 2; var sizeOffset = new int2(); if (Info.ReferencePoint.HasFlag(ReferencePoints.Top)) { boundsOffset -= new int2(0, bounds.Height / 2); sizeOffset += new int2(0, halfSize.Y); } else if (Info.ReferencePoint.HasFlag(ReferencePoints.Bottom)) { boundsOffset += new int2(0, bounds.Height / 2); sizeOffset -= new int2(0, halfSize.Y); } if (Info.ReferencePoint.HasFlag(ReferencePoints.Left)) { boundsOffset -= new int2(bounds.Width / 2, 0); sizeOffset += new int2(halfSize.X, 0); } else if (Info.ReferencePoint.HasFlag(ReferencePoints.Right)) { boundsOffset += new int2(bounds.Width / 2, 0); sizeOffset -= new int2(halfSize.X, 0); } return(new IRenderable[] { new TextRenderable(font, wr.ProjectedPosition(boundsOffset + sizeOffset), Info.ZOffset, color, Info.Text) }); }
IEnumerable <IRenderable> DrawControlGroup(Actor self, WorldRenderer wr) { var group = self.World.Selection.GetControlGroupForActor(self); if (group == null) { yield break; } var bounds = decorationBounds.FirstNonEmptyBounds(self, wr); var number = group.Value.ToString(); var halfSize = font.Measure(number) / 2; var boundsOffset = new int2(bounds.Left + bounds.Right, bounds.Top + bounds.Bottom) / 2; var sizeOffset = new int2(); if (info.ReferencePoint.HasFlag(ReferencePoints.Top)) { boundsOffset -= new int2(0, bounds.Height / 2); sizeOffset += new int2(0, halfSize.Y); } else if (info.ReferencePoint.HasFlag(ReferencePoints.Bottom)) { boundsOffset += new int2(0, bounds.Height / 2); sizeOffset -= new int2(0, halfSize.Y); } if (info.ReferencePoint.HasFlag(ReferencePoints.Left)) { boundsOffset -= new int2(bounds.Width / 2, 0); sizeOffset += new int2(halfSize.X, 0); } else if (info.ReferencePoint.HasFlag(ReferencePoints.Right)) { boundsOffset += new int2(bounds.Width / 2, 0); sizeOffset -= new int2(halfSize.X, 0); } var screenPos = boundsOffset + sizeOffset + info.ScreenOffset; yield return(new TextRenderable(font, wr.ProjectedPosition(screenPos), info.ZOffset, color, number)); }
public override void Draw() { var iconOffsetToCenter = 0.5f * IconSize.ToFloat2() + IconSpriteOffset; timeOffset = iconOffsetToCenter - overlayFont.Measure(WidgetUtils.FormatTime(0, World.Timestep)) / 2; queuedOffset = new float2(4, 2); holdOffset = iconOffsetToCenter - overlayFont.Measure(HoldText) / 2; readyOffset = iconOffsetToCenter - overlayFont.Measure(ReadyText) / 2; if (ChromeMetrics.TryGet("InfiniteOffset", out infiniteOffset)) { infiniteOffset += queuedOffset; } else { infiniteOffset = queuedOffset; } if (CurrentQueue == null) { return; } var buildableItems = CurrentQueue.BuildableItems(); var pios = currentQueue.Actor.Owner.PlayerActor.TraitsImplementing <IProductionIconOverlay>(); // Icons foreach (ProductionIcon icon in icons.Values) { WidgetUtils.DrawSHPCentered(icon.Sprite, icon.Pos + iconOffsetToCenter, icon.Palette, icon.RenderSize); //этот метод использует размер от icon.Sprite.Size для размера в FastQuad // Draw the ProductionIconOverlay's sprite var pio = pios.FirstOrDefault(p => p.IsOverlayActive(icon.Actor)); if (pio != null) { WidgetUtils.DrawSHPCentered(pio.Sprite, icon.Pos + iconOffsetToCenter + pio.Offset(IconSize), worldRenderer.Palette(pio.Palette), 1f); } // Build progress if (icon.Queued.Count > 0) { var first = icon.Queued[0]; if (1 == 2) { clock.PlayFetchIndex(ClockSequence, () => (first.TotalTime - first.RemainingTime) * (clock.CurrentSequence.Length - 1) / first.TotalTime); clock.Tick(); WidgetUtils.DrawSHPCentered(clock.Image, icon.Pos + iconOffsetToCenter, icon.IconClockPalette, icon.RenderSize); } else { int currentframe = (first.TotalTime - first.RemainingTime) * (59) / first.TotalTime; float3 offs = iconOffsetToCenter - 0.5f * icon.RenderSize.ToFloat2(); // из-за icon.Pos + iconOffsetToCenter и DrawSHPCentered Game.Renderer.Flush(); // делаем, это тут, так как рисуем вне очереди, то управляем очередью. Game.Renderer.sproc.AddCommand(1, currentframe, 59, 0, 0, new int2(0, 0), icon.Pos + offs, icon.RenderSize, icon.Sprite, icon.Palette); Game.Renderer.sproc.ExecCommandBuffer(); } } else if (!buildableItems.Any(a => a.Name == icon.Name)) { WidgetUtils.DrawSHPCentered(cantBuild.Image, icon.Pos + iconOffsetToCenter, icon.IconDarkenPalette, icon.RenderSize); } } // Overlays foreach (ProductionIcon icon in icons.Values) { var total = icon.Queued.Count; if (total > 0) { var first = icon.Queued[0]; var waiting = !CurrentQueue.IsProducing(first) && !first.Done; if (first.Done) { if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber * worldRenderer.World.Timestep / 360 % 2 == 0) { overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, Color.White, Color.Black, 1); } else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor) { overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, ReadyTextAltColor, Color.Black, 1); } } else if (first.Paused) { overlayFont.DrawTextWithContrast(HoldText, icon.Pos + holdOffset, Color.White, Color.Black, 1); } else if (!waiting && DrawTime) { overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.Queue.RemainingTimeActual(first), World.Timestep), icon.Pos + timeOffset, Color.White, Color.Black, 1); } if (first.Infinite) { symbolFont.DrawTextWithContrast(InfiniteSymbol, icon.Pos + infiniteOffset, Color.White, Color.Black, 1); } else if (total > 1 || waiting) { overlayFont.DrawTextWithContrast(total.ToString(), icon.Pos + queuedOffset, Color.White, Color.Black, 1); } } } }