public SpawnSelectorTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, MapPreviewWidget preview) { widget.IsVisible = () => preview.TooltipSpawnIndex != -1; var label = widget.Get <LabelWidget>("LABEL"); var flag = widget.Get <ImageWidget>("FLAG"); var team = widget.Get <LabelWidget>("TEAM"); var singleHeight = widget.Get("SINGLE_HEIGHT").Bounds.Height; var doubleHeight = widget.Get("DOUBLE_HEIGHT").Bounds.Height; var ownerFont = Game.Renderer.Fonts[label.Font]; var teamFont = Game.Renderer.Fonts[team.Font]; // Width specified in YAML is used as the margin between flag / label and label / border var labelMargin = widget.Bounds.Width; var cachedWidth = 0; var labelText = ""; string playerFaction = null; var playerTeam = -1; tooltipContainer.BeforeRender = () => { var occupant = preview.SpawnOccupants().Values.FirstOrDefault(c => c.SpawnPoint == preview.TooltipSpawnIndex); var teamWidth = 0; if (occupant == null) { labelText = "Available spawn"; playerFaction = null; playerTeam = 0; widget.Bounds.Height = singleHeight; } else { labelText = occupant.PlayerName; playerFaction = occupant.Faction; playerTeam = occupant.Team; widget.Bounds.Height = playerTeam > 0 ? doubleHeight : singleHeight; teamWidth = teamFont.Measure(team.GetText()).X; } label.Bounds.X = playerFaction != null ? flag.Bounds.Right + labelMargin : labelMargin; var textWidth = ownerFont.Measure(labelText).X; if (textWidth != cachedWidth) { label.Bounds.Width = textWidth; widget.Bounds.Width = 2 * label.Bounds.X + textWidth; } widget.Bounds.Width = Math.Max(teamWidth + 2 * labelMargin, label.Bounds.Right + labelMargin); team.Bounds.Width = widget.Bounds.Width; }; label.GetText = () => labelText; flag.IsVisible = () => playerFaction != null; flag.GetImageCollection = () => "flags"; flag.GetImageName = () => playerFaction; team.GetText = () => "Team {0}".F(playerTeam); team.IsVisible = () => playerTeam > 0; }
public WorldTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, CncWorldInteractionControllerWidget wic) { widget.IsVisible = () => wic.TooltipType != WorldTooltipType.None; var label = widget.GetWidget <LabelWidget>("LABEL"); var flag = widget.GetWidget <ImageWidget>("FLAG"); var owner = widget.GetWidget <LabelWidget>("OWNER"); var font = Game.Renderer.Fonts[label.Font]; var ownerFont = Game.Renderer.Fonts[owner.Font]; var cachedWidth = 0; var labelText = ""; var showOwner = false; var flagRace = ""; var ownerName = ""; var ownerColor = Color.White; var doubleHeight = 45; var singleHeight = 25; tooltipContainer.BeforeRender = () => { if (wic == null || wic.TooltipType == WorldTooltipType.None) { return; } labelText = wic.TooltipType == WorldTooltipType.Unexplored ? "Unexplored Terrain" : wic.ActorTooltip.Name(); var textWidth = font.Measure(labelText).X; if (textWidth != cachedWidth) { label.Bounds.Width = textWidth; widget.Bounds.Width = 2 * label.Bounds.X + textWidth; } var o = wic.ActorTooltip != null?wic.ActorTooltip.Owner() : null; showOwner = wic.TooltipType == WorldTooltipType.Actor && o != null && !o.NonCombatant; if (showOwner) { flagRace = o.Country.Race; ownerName = o.PlayerName; ownerColor = o.ColorRamp.GetColor(0); widget.Bounds.Height = doubleHeight; widget.Bounds.Width = Math.Max(widget.Bounds.Width, owner.Bounds.X + ownerFont.Measure(ownerName).X + 5); } else { widget.Bounds.Height = singleHeight; } }; label.GetText = () => labelText; flag.IsVisible = () => showOwner; flag.GetImageCollection = () => "flags"; flag.GetImageName = () => flagRace; owner.IsVisible = () => showOwner; owner.GetText = () => ownerName; owner.GetColor = () => ownerColor; }
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette) { var pm = palette.world.LocalPlayer.PlayerActor.Trait <PowerManager>(); var pr = palette.world.LocalPlayer.PlayerActor.Trait <PlayerResources>(); widget.IsVisible = () => palette.TooltipActor != null; var nameLabel = widget.GetWidget <LabelWidget>("NAME"); var requiresLabel = widget.GetWidget <LabelWidget>("REQUIRES"); var powerLabel = widget.GetWidget <LabelWidget>("POWER"); var timeLabel = widget.GetWidget <LabelWidget>("TIME"); var costLabel = widget.GetWidget <LabelWidget>("COST"); var font = Game.Renderer.Fonts[nameLabel.Font]; var requiresFont = Game.Renderer.Fonts[requiresLabel.Font]; string lastActor = null; tooltipContainer.BeforeRender = () => { var actor = palette.TooltipActor; if (actor == null || actor == lastActor) { return; } var info = Rules.Info[actor]; var tooltip = info.Traits.Get <TooltipInfo>(); var buildable = info.Traits.Get <BuildableInfo>(); var cost = info.Traits.Get <ValuedInfo>().Cost; var bi = info.Traits.GetOrDefault <BuildingInfo>(); nameLabel.GetText = () => tooltip.Name; var prereqs = buildable.Prerequisites.Select(a => ActorName(a)); var requiresString = prereqs.Any() ? "Requires {0}".F(prereqs.JoinWith(", ")) : ""; requiresLabel.GetText = () => requiresString; var power = bi != null ? bi.Power : 0; var powerString = "P: {0}".F(power); powerLabel.GetText = () => powerString; powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0) ? Color.White : Color.Red; powerLabel.IsVisible = () => power != 0; var timeString = "T: {0}".F(WidgetUtils.FormatTime(palette.CurrentQueue.GetBuildTime(actor))); timeLabel.GetText = () => timeString; var costString = "$: {0}".F(cost); costLabel.GetText = () => costString; costLabel.GetColor = () => pr.DisplayCash + pr.DisplayOre >= cost ? Color.White : Color.Red; var leftWidth = Math.Max(font.Measure(tooltip.Name).X, requiresFont.Measure(requiresString).X); var rightWidth = new [] { font.Measure(powerString).X, font.Measure(timeString).X, font.Measure(costString).X }.Aggregate(Math.Max); timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X; widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X; widget.Bounds.Height = power != 0 ? 65 : 45; lastActor = actor; }; }
public SupportPowerTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, SupportPowersWidget palette) { widget.IsVisible = () => palette.TooltipPower != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var timeLabel = widget.Get <LabelWidget>("TIME"); var descLabel = widget.Get <LabelWidget>("DESC"); var nameFont = Game.Renderer.Fonts[nameLabel.Font]; var timeFont = Game.Renderer.Fonts[timeLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var name = ""; var time = ""; var desc = ""; var baseHeight = widget.Bounds.Height; var timeOffset = timeLabel.Bounds.X; SupportPowerInstance lastPower = null; tooltipContainer.BeforeRender = () => { var sp = palette.TooltipPower; if (sp == null) { return; } if (sp.Info == null) { return; // no instances actually exist (race with destroy) } time = "{0} / {1}".F(WidgetUtils.FormatTime(sp.RemainingTime), WidgetUtils.FormatTime(sp.Info.ChargeTime * 25)); if (sp == lastPower) { return; } name = sp.Info.Description; desc = sp.Info.LongDesc.Replace("\\n", "\n"); var timeWidth = timeFont.Measure(time).X; var topWidth = nameFont.Measure(name).X + timeWidth + timeOffset; var descSize = descFont.Measure(desc); widget.Bounds.Width = 2 * nameLabel.Bounds.X + Math.Max(topWidth, descSize.X); widget.Bounds.Height = baseHeight + descSize.Y; timeLabel.Bounds.X = widget.Bounds.Width - nameLabel.Bounds.X - timeWidth; lastPower = sp; }; nameLabel.GetText = () => name; timeLabel.GetText = () => time; descLabel.GetText = () => desc; }
public SimpleTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Func <string> getText) { var label = widget.Get <LabelWidget>("LABEL"); var spacing = widget.Get("LINE_HEIGHT"); widget.RemoveChildren(); var font = Game.Renderer.Fonts[label.Font]; var horizontalPadding = label.Bounds.Width - widget.Bounds.Width; if (horizontalPadding <= 0) { horizontalPadding = 2 * label.Bounds.X; } var cachedText = ""; tooltipContainer.BeforeRender = () => { var text = getText(); if (text == cachedText) { return; } var lines = text.Split('\n'); var textWidth = font.Measure(text).X; // Set up label widgets widget.RemoveChildren(); var bottom = 0; for (var i = 0; i < lines.Length; i++) { var line = (LabelWidget)label.Clone(); var lineText = lines[i]; line.Bounds.Y += spacing.Bounds.Y + i * spacing.Bounds.Height; line.Bounds.Width = textWidth; line.GetText = () => lineText; widget.AddChild(line); bottom = line.Bounds.Y + line.Bounds.Height; } widget.Bounds.Width = horizontalPadding + textWidth; widget.Bounds.Height = bottom + spacing.Bounds.Y; cachedText = text; }; }
public ArmyTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Func <ArmyUnit> getTooltipUnit) { widget.IsVisible = () => getTooltipUnit() != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var descLabel = widget.Get <LabelWidget>("DESC"); var font = Game.Renderer.Fonts[nameLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; ArmyUnit lastArmyUnit = null; var descLabelPadding = descLabel.Bounds.Height; tooltipContainer.BeforeRender = () => { var armyUnit = getTooltipUnit(); if (armyUnit == null || armyUnit == lastArmyUnit) { return; } var tooltip = armyUnit.TooltipInfo; var name = tooltip?.Name ?? armyUnit.ActorInfo.Name; var buildable = armyUnit.BuildableInfo; nameLabel.Text = name; var nameSize = font.Measure(name); descLabel.Text = buildable.Description.Replace("\\n", "\n"); var descSize = descFont.Measure(descLabel.Text); descLabel.Bounds.Width = descSize.X; descLabel.Bounds.Height = descSize.Y + descLabelPadding; var leftWidth = Math.Max(nameSize.X, descSize.X); widget.Bounds.Width = leftWidth + 2 * nameLabel.Bounds.X; // Set the bottom margin to match the left margin var leftHeight = descLabel.Bounds.Bottom + descLabel.Bounds.X; widget.Bounds.Height = leftHeight; lastArmyUnit = armyUnit; }; }
public ClientTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, OrderManager orderManager, int clientIndex) { var admin = widget.Get <LabelWidget>("ADMIN"); var adminFont = Game.Renderer.Fonts[admin.Font]; var latency = widget.Get <LabelWidget>("LATENCY"); var latencyFont = Game.Renderer.Fonts[latency.Font]; var ip = widget.Get <LabelWidget>("IP"); var ipFont = Game.Renderer.Fonts[ip.Font]; var ipOffset = ip.Bounds.Y; var latencyOffset = latency.Bounds.Y; var tooltipHeight = widget.Bounds.Height; var margin = widget.Bounds.Width; tooltipContainer.IsVisible = () => (orderManager.LobbyInfo.ClientWithIndex(clientIndex) != null); tooltipContainer.BeforeRender = () => { var width = Math.Max(adminFont.Measure(admin.GetText()).X, Math.Max(ipFont.Measure(ip.GetText()).X, latencyFont.Measure(latency.GetText()).X)); widget.Bounds.Width = width + 2 * margin; latency.Bounds.Width = widget.Bounds.Width; ip.Bounds.Width = widget.Bounds.Width; admin.Bounds.Width = widget.Bounds.Width; ip.Bounds.Y = ipOffset; latency.Bounds.Y = latencyOffset; widget.Bounds.Height = tooltipHeight; if (admin.IsVisible()) { ip.Bounds.Y += admin.Bounds.Height; latency.Bounds.Y += admin.Bounds.Height; widget.Bounds.Height += admin.Bounds.Height; } }; admin.IsVisible = () => orderManager.LobbyInfo.ClientWithIndex(clientIndex).IsAdmin; latency.GetText = () => "Latency: {0}".F(LobbyUtils.LatencyDescription(orderManager.LobbyInfo.ClientWithIndex(clientIndex).Latency)); ip.GetText = () => LobbyUtils.DescriptiveIpAddress(orderManager.LobbyInfo.ClientWithIndex(clientIndex).IpAddress); }
public SimpleTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Func <string> getText) { var label = widget.Get <LabelWidget>("LABEL"); var font = Game.Renderer.Fonts[label.Font]; var cachedWidth = 0; var labelText = ""; tooltipContainer.BeforeRender = () => { labelText = getText(); var textWidth = font.Measure(labelText).X; if (textWidth != cachedWidth) { label.Bounds.Width = textWidth; widget.Bounds.Width = 2 * label.Bounds.X + textWidth; } }; label.GetText = () => labelText; }
public LatencyTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, OrderManager orderManager, Session.Client client) { var latencyPrefix = widget.Get <LabelWidget>("LATENCY_PREFIX"); var latencyPrefixFont = Game.Renderer.Fonts[latencyPrefix.Font]; var latency = widget.Get <LabelWidget>("LATENCY"); var latencyFont = Game.Renderer.Fonts[latency.Font]; var rightMargin = widget.Bounds.Width; latency.Bounds.X = latencyPrefix.Bounds.X + latencyPrefixFont.Measure(latencyPrefix.Text + " ").X; widget.IsVisible = () => client != null; tooltipContainer.BeforeRender = () => { if (widget.IsVisible()) { widget.Bounds.Width = latency.Bounds.X + latencyFont.Measure(latency.GetText()).X + rightMargin; } }; latency.GetText = () => LobbyUtils.LatencyDescription(client); latency.GetColor = () => LobbyUtils.LatencyColor(client); }
public SimpleTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Func <string> getText) { var label = widget.Get <LabelWidget>("LABEL"); var font = Game.Renderer.Fonts[label.Font]; var cachedWidth = 0; var cachedHeight = 0; var horizontalPadding = label.Bounds.Width - widget.Bounds.Width; if (horizontalPadding <= 0) { horizontalPadding = 2 * label.Bounds.X; } var vertcalPadding = widget.Bounds.Height - label.Bounds.Height; if (vertcalPadding <= 0) { vertcalPadding = 2 * label.Bounds.Y; } var labelText = ""; tooltipContainer.BeforeRender = () => { labelText = getText(); var textDim = font.Measure(labelText); if (textDim.X != cachedWidth || textDim.Y != cachedHeight) { label.Bounds.Width = textDim.X; widget.Bounds.Width = horizontalPadding + textDim.X; label.Bounds.Height = textDim.Y; widget.Bounds.Height = vertcalPadding + textDim.Y; cachedWidth = textDim.X; cachedHeight = textDim.Y; } }; label.GetText = () => labelText; }
public SupportPowerTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Func <SupportPowersWidget.SupportPowerIcon> getTooltipIcon, World world) { widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Power.Info != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY"); var timeLabel = widget.Get <LabelWidget>("TIME"); var descLabel = widget.Get <LabelWidget>("DESC"); var nameFont = Game.Renderer.Fonts[nameLabel.Font]; var hotkeyFont = Game.Renderer.Fonts[hotkeyLabel.Font]; var timeFont = Game.Renderer.Fonts[timeLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var baseHeight = widget.Bounds.Height; var timeOffset = timeLabel.Bounds.X; SupportPowerInstance lastPower = null; Hotkey lastHotkey = Hotkey.Invalid; var lastRemainingSeconds = 0; tooltipContainer.BeforeRender = () => { var icon = getTooltipIcon(); if (icon == null || icon.Power == null || icon.Power.Instances.Count == 0) { return; } var sp = icon.Power; // HACK: This abuses knowledge of the internals of WidgetUtils.FormatTime // to efficiently work when the label is going to change, requiring a panel relayout var remainingSeconds = (int)Math.Ceiling(sp.RemainingTicks * world.Timestep / 1000f); var hotkey = icon.Hotkey?.GetValue() ?? Hotkey.Invalid; if (sp == lastPower && hotkey == lastHotkey && lastRemainingSeconds == remainingSeconds) { return; } nameLabel.Text = sp.Info.Description; var nameSize = nameFont.Measure(nameLabel.Text); descLabel.Text = sp.Info.LongDesc.Replace("\\n", "\n"); var descSize = descFont.Measure(descLabel.Text); var customLabel = sp.TooltipTimeTextOverride(); if (customLabel == null) { var remaining = WidgetUtils.FormatTime(sp.RemainingTicks, world.Timestep); var total = WidgetUtils.FormatTime(sp.Info.ChargeInterval, world.Timestep); timeLabel.Text = $"{remaining} / {total}"; } else { timeLabel.Text = customLabel; } var timeSize = timeFont.Measure(timeLabel.Text); var hotkeyWidth = 0; hotkeyLabel.Visible = hotkey.IsValid(); if (hotkeyLabel.Visible) { var hotkeyText = $"({hotkey.DisplayString()})"; hotkeyWidth = hotkeyFont.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X; hotkeyLabel.Text = hotkeyText; hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X; } var timeWidth = timeSize.X; var topWidth = nameSize.X + hotkeyWidth + timeWidth + timeOffset; widget.Bounds.Width = 2 * nameLabel.Bounds.X + Math.Max(topWidth, descSize.X); widget.Bounds.Height = baseHeight + descSize.Y; timeLabel.Bounds.X = widget.Bounds.Width - nameLabel.Bounds.X - timeWidth; lastPower = sp; lastHotkey = hotkey; lastRemainingSeconds = remainingSeconds; }; timeLabel.GetColor = () => getTooltipIcon() != null && !getTooltipIcon().Power.Active ? Color.Red : Color.White; }
public WorldTooltipLogic(Widget widget, World world, TooltipContainerWidget tooltipContainer, ViewportControllerWidget viewport) { widget.IsVisible = () => viewport.TooltipType != WorldTooltipType.None; var label = widget.Get <LabelWidget>("LABEL"); var flag = widget.Get <ImageWidget>("FLAG"); var owner = widget.Get <LabelWidget>("OWNER"); var extras = widget.Get <LabelWidget>("EXTRA"); var font = Game.Renderer.Fonts[label.Font]; var ownerFont = Game.Renderer.Fonts[owner.Font]; var cachedWidth = 0; var labelText = ""; var showOwner = false; var flagRace = ""; var ownerName = ""; var ownerColor = Color.White; var extraText = ""; var singleHeight = widget.Get("SINGLE_HEIGHT").Bounds.Height; var doubleHeight = widget.Get("DOUBLE_HEIGHT").Bounds.Height; var extraHeightOnDouble = extras.Bounds.Y; var extraHeightOnSingle = extraHeightOnDouble - (doubleHeight - singleHeight); tooltipContainer.BeforeRender = () => { if (viewport == null || viewport.TooltipType == WorldTooltipType.None) { return; } var index = 0; extraText = ""; showOwner = false; Player o = null; switch (viewport.TooltipType) { case WorldTooltipType.Unexplored: labelText = "Unexplored Terrain"; break; case WorldTooltipType.Actor: { o = viewport.ActorTooltip.Owner; showOwner = !o.NonCombatant && viewport.ActorTooltip.TooltipInfo.IsOwnerRowVisible; var stance = o == null || world.RenderPlayer == null ? Stance.None : o.Stances[world.RenderPlayer]; labelText = viewport.ActorTooltip.TooltipInfo.TooltipForPlayerStance(stance); break; } case WorldTooltipType.FrozenActor: { o = viewport.FrozenActorTooltip.TooltipOwner; showOwner = !o.NonCombatant && viewport.FrozenActorTooltip.TooltipInfo.IsOwnerRowVisible; var stance = o == null || world.RenderPlayer == null ? Stance.None : o.Stances[world.RenderPlayer]; labelText = viewport.FrozenActorTooltip.TooltipInfo.TooltipForPlayerStance(stance); break; } } if (viewport.ActorTooltipExtra != null) { foreach (var info in viewport.ActorTooltipExtra) { if (info.IsTooltipVisible(world.LocalPlayer)) { if (index != 0) { extraText += "\n"; } extraText += info.TooltipText; index++; } } } var textWidth = Math.Max(font.Measure(labelText).X, font.Measure(extraText).X); if (textWidth != cachedWidth) { label.Bounds.Width = textWidth; widget.Bounds.Width = 2 * label.Bounds.X + textWidth; } if (showOwner) { flagRace = o.Country.Race; ownerName = o.PlayerName; ownerColor = o.Color.RGB; widget.Bounds.Height = doubleHeight; widget.Bounds.Width = Math.Max(widget.Bounds.Width, owner.Bounds.X + ownerFont.Measure(ownerName).X + label.Bounds.X); index++; } else { widget.Bounds.Height = singleHeight; } if (extraText != "") { widget.Bounds.Height += font.Measure(extraText).Y + extras.Bounds.Height; if (showOwner) { extras.Bounds.Y = extraHeightOnDouble; } else { extras.Bounds.Y = extraHeightOnSingle; } } }; label.GetText = () => labelText; flag.IsVisible = () => showOwner; flag.GetImageCollection = () => "flags"; flag.GetImageName = () => flagRace; owner.IsVisible = () => showOwner; owner.GetText = () => ownerName; owner.GetColor = () => ownerColor; extras.GetText = () => extraText; }
public ClientTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, OrderManager orderManager, int clientIndex) { var admin = widget.Get <LabelWidget>("ADMIN"); var adminFont = Game.Renderer.Fonts[admin.Font]; var latency = widget.Get <LabelWidget>("LATENCY"); var latencyFont = Game.Renderer.Fonts[latency.Font]; var latencyPrefix = widget.Get <LabelWidget>("LATENCY_PREFIX"); var latencyPrefixFont = Game.Renderer.Fonts[latencyPrefix.Font]; var ip = widget.Get <LabelWidget>("IP"); var ipFont = Game.Renderer.Fonts[ip.Font]; var location = widget.Get <LabelWidget>("LOCATION"); var locationFont = Game.Renderer.Fonts[location.Font]; var locationOffset = location.Bounds.Y; var ipOffset = ip.Bounds.Y; var latencyOffset = latency.Bounds.Y; var tooltipHeight = widget.Bounds.Height; var margin = widget.Bounds.Width; tooltipContainer.IsVisible = () => (orderManager.LobbyInfo.ClientWithIndex(clientIndex) != null); tooltipContainer.BeforeRender = () => { var latencyPrefixSize = latencyPrefix.Bounds.X + latencyPrefixFont.Measure(latencyPrefix.GetText() + " ").X; var width = Math.Max(locationFont.Measure(location.GetText()).X, (Math.Max(adminFont.Measure(admin.GetText()).X, Math.Max(ipFont.Measure(ip.GetText()).X, latencyPrefixSize + latencyFont.Measure(latency.GetText()).X)))); widget.Bounds.Width = width + 2 * margin; latency.Bounds.Width = widget.Bounds.Width; ip.Bounds.Width = widget.Bounds.Width; admin.Bounds.Width = widget.Bounds.Width; location.Bounds.Width = widget.Bounds.Width; ip.Bounds.Y = ipOffset; latency.Bounds.Y = latencyOffset; location.Bounds.Y = locationOffset; widget.Bounds.Height = tooltipHeight; if (admin.IsVisible()) { ip.Bounds.Y += admin.Bounds.Height; latency.Bounds.Y += admin.Bounds.Height; location.Bounds.Y += admin.Bounds.Height; widget.Bounds.Height += admin.Bounds.Height; } latencyPrefix.Bounds.Y = latency.Bounds.Y; latency.Bounds.X = latencyPrefixSize; }; admin.IsVisible = () => orderManager.LobbyInfo.ClientWithIndex(clientIndex).IsAdmin; latency.GetText = () => LobbyUtils.LatencyDescription(orderManager.LobbyInfo.ClientWithIndex(clientIndex).Latency); latency.GetColor = () => LobbyUtils.LatencyColor(orderManager.LobbyInfo.ClientWithIndex(clientIndex).Latency); var ipAddress = orderManager.LobbyInfo.ClientWithIndex(clientIndex).IpAddress; if ((ipAddress == null || ipAddress == "127.0.0.1") && UPnP.NatDevice != null) { ipAddress = UPnP.NatDevice.GetExternalIP().ToString(); } var cachedDescriptiveIP = LobbyUtils.DescriptiveIpAddress(ipAddress); ip.GetText = () => cachedDescriptiveIP; var cachedCountryLookup = LobbyUtils.LookupCountry(ipAddress); location.GetText = () => cachedCountryLookup; }
public SimpleProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Player player, Func <ProductionIcon> getTooltipIcon) { var world = player.World; var mapRules = world.Map.Rules; widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Actor != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY"); var requiresLabel = widget.Get <LabelWidget>("REQUIRES"); var timeLabel = widget.Get <LabelWidget>("TIME"); var timeIcon = widget.Get <ImageWidget>("TIME_ICON"); var descLabel = widget.Get <LabelWidget>("DESC"); var iconMargin = timeIcon.Bounds.X; var font = Game.Renderer.Fonts[nameLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var requiresFont = Game.Renderer.Fonts[requiresLabel.Font]; var formatBuildTime = new CachedTransform <int, string>(time => WidgetUtils.FormatTime(time, world.Timestep)); var requiresFormat = requiresLabel.Text; ActorInfo lastActor = null; Hotkey lastHotkey = Hotkey.Invalid; var descLabelY = descLabel.Bounds.Y; var descLabelPadding = descLabel.Bounds.Height; tooltipContainer.BeforeRender = () => { var tooltipIcon = getTooltipIcon(); if (tooltipIcon == null) { return; } var actor = tooltipIcon.Actor; if (actor == null) { return; } var hotkey = tooltipIcon.Hotkey != null?tooltipIcon.Hotkey.GetValue() : Hotkey.Invalid; if (actor == lastActor && hotkey == lastHotkey) { return; } var tooltip = actor.TraitInfos <TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault); var name = tooltip != null ? tooltip.Name : actor.Name; var buildable = actor.TraitInfo <BuildableInfo>(); var cost = 0; if (tooltipIcon.ProductionQueue != null) { cost = tooltipIcon.ProductionQueue.GetProductionCost(actor); } else { var valued = actor.TraitInfoOrDefault <ValuedInfo>(); if (valued != null) { cost = valued.Cost; } } nameLabel.Text = name; var nameSize = font.Measure(name); var hotkeyWidth = 0; hotkeyLabel.Visible = hotkey.IsValid(); if (hotkeyLabel.Visible) { var hotkeyText = "({0})".F(hotkey.DisplayString()); hotkeyWidth = font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X; hotkeyLabel.Text = hotkeyText; hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X; } var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)) .Where(s => !s.StartsWith("~", StringComparison.Ordinal) && !s.StartsWith("!", StringComparison.Ordinal)); var requiresSize = int2.Zero; if (prereqs.Any()) { requiresLabel.Text = requiresFormat.F(prereqs.JoinWith(", ")); requiresSize = requiresFont.Measure(requiresLabel.Text); requiresLabel.Visible = true; descLabel.Bounds.Y = descLabelY + requiresLabel.Bounds.Height; } else { requiresLabel.Visible = false; descLabel.Bounds.Y = descLabelY; } var buildTime = tooltipIcon.ProductionQueue == null ? 0 : tooltipIcon.ProductionQueue.GetBuildTime(actor, buildable); var timeModifier = tooltipIcon.ProductionQueue.Info.LowPowerModifier; timeLabel.Text = formatBuildTime.Update(buildTime * timeModifier / 100); timeLabel.TextColor = tooltipIcon.ProductionQueue.Info.LowPowerModifier > 100 ? Color.Red : Color.White; var timeSize = font.Measure(timeLabel.Text); descLabel.Text = buildable.Description.Replace("\\n", "\n"); var descSize = descFont.Measure(descLabel.Text); descLabel.Bounds.Width = descSize.X; descLabel.Bounds.Height = descSize.Y + descLabelPadding; var leftWidth = new[] { nameSize.X + hotkeyWidth, requiresSize.X, descSize.X }.Aggregate(Math.Max); var rightWidth = new[] { timeSize.X }.Aggregate(Math.Max); timeIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X; timeLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin; widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin; // Set the bottom margin to match the left margin var leftHeight = descLabel.Bounds.Bottom + descLabel.Bounds.X; // Set the bottom margin to match the top margin var rightHeight = timeIcon.Bounds.Bottom; widget.Bounds.Height = Math.Max(leftHeight, rightHeight); lastActor = actor; lastHotkey = hotkey; }; }
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette, World world) { var mapRules = palette.World.Map.Rules; var pm = palette.World.LocalPlayer.PlayerActor.Trait <PowerManager>(); var pr = palette.World.LocalPlayer.PlayerActor.Trait <PlayerResources>(); widget.IsVisible = () => palette.TooltipIcon != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY"); var requiresLabel = widget.Get <LabelWidget>("REQUIRES"); var powerLabel = widget.Get <LabelWidget>("POWER"); var powerIcon = widget.Get <ImageWidget>("POWER_ICON"); var timeLabel = widget.Get <LabelWidget>("TIME"); var timeIcon = widget.Get <ImageWidget>("TIME_ICON"); var costLabel = widget.Get <LabelWidget>("COST"); var costIcon = widget.Get <ImageWidget>("COST_ICON"); var descLabel = widget.Get <LabelWidget>("DESC"); var iconMargin = timeIcon.Bounds.X; var font = Game.Renderer.Fonts[nameLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var requiresFont = Game.Renderer.Fonts[requiresLabel.Font]; ActorInfo lastActor = null; tooltipContainer.BeforeRender = () => { if (palette.TooltipIcon == null) { return; } var actor = palette.TooltipIcon.Actor; if (actor == null || actor == lastActor) { return; } var tooltip = actor.TraitInfo <TooltipInfo>(); var buildable = actor.TraitInfo <BuildableInfo>(); var cost = actor.TraitInfo <ValuedInfo>().Cost; nameLabel.GetText = () => tooltip.Name; var hotkey = palette.TooltipIcon.Hotkey; var nameWidth = font.Measure(tooltip.Name).X; var hotkeyText = "({0})".F(hotkey.DisplayString()); var hotkeyWidth = hotkey.IsValid() ? font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X : 0; hotkeyLabel.GetText = () => hotkeyText; hotkeyLabel.Bounds.X = nameWidth + 2 * nameLabel.Bounds.X; hotkeyLabel.Visible = hotkey.IsValid(); var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)).Where(s => !s.StartsWith("~")); var requiresString = prereqs.Any() ? requiresLabel.Text.F(prereqs.JoinWith(", ")) : ""; requiresLabel.GetText = () => requiresString; var power = actor.TraitInfos <PowerInfo>().Where(i => i.UpgradeMinEnabledLevel < 1).Sum(i => i.Amount); var powerString = power.ToString(); powerLabel.GetText = () => powerString; powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0) ? Color.White : Color.Red; powerLabel.IsVisible = () => power != 0; powerIcon.IsVisible = () => power != 0; var lowpower = pm.PowerState != PowerState.Normal; var time = palette.CurrentQueue == null ? 0 : palette.CurrentQueue.GetBuildTime(actor.Name) * (lowpower ? palette.CurrentQueue.Info.LowPowerSlowdown : 1); var timeString = WidgetUtils.FormatTime(time, world.Timestep); timeLabel.GetText = () => timeString; timeLabel.GetColor = () => lowpower ? Color.Red : Color.White; var costString = cost.ToString(); costLabel.GetText = () => costString; costLabel.GetColor = () => pr.DisplayCash + pr.DisplayResources >= cost ? Color.White : Color.Red; var descString = tooltip.Description.Replace("\\n", "\n"); descLabel.GetText = () => descString; var leftWidth = new[] { nameWidth + hotkeyWidth, requiresFont.Measure(requiresString).X, descFont.Measure(descString).X }.Aggregate(Math.Max); var rightWidth = new[] { font.Measure(powerString).X, font.Measure(timeString).X, font.Measure(costString).X }.Aggregate(Math.Max); timeIcon.Bounds.X = powerIcon.Bounds.X = costIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X; timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin; widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin; var leftHeight = font.Measure(tooltip.Name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y; var rightHeight = font.Measure(powerString).Y + font.Measure(timeString).Y + font.Measure(costString).Y; widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y; lastActor = actor; }; }
public SpawnSelectorTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, MapPreviewWidget preview, bool showUnoccupiedSpawnpoints) { bool showTooltip = true; widget.IsVisible = () => preview.TooltipSpawnIndex != -1 && showTooltip; var label = widget.Get <LabelWidget>("LABEL"); var flag = widget.Get <ImageWidget>("FLAG"); var team = widget.Get <LabelWidget>("TEAM"); var singleHeight = widget.Get("SINGLE_HEIGHT").Bounds.Height; var doubleHeight = widget.Get("DOUBLE_HEIGHT").Bounds.Height; var ownerFont = Game.Renderer.Fonts[label.Font]; var teamFont = Game.Renderer.Fonts[team.Font]; // Width specified in YAML is used as the margin between flag / label and label / border var labelMargin = widget.Bounds.Width; var labelText = ""; string playerFaction = null; var playerTeam = -1; tooltipContainer.BeforeRender = () => { showTooltip = true; var teamWidth = 0; if (preview.SpawnOccupants().TryGetValue(preview.TooltipSpawnIndex, out var occupant)) { labelText = occupant.PlayerName; playerFaction = occupant.Faction; playerTeam = occupant.Team; widget.Bounds.Height = playerTeam > 0 ? doubleHeight : singleHeight; teamWidth = teamFont.Measure(team.GetText()).X; } else { if (!showUnoccupiedSpawnpoints) { showTooltip = false; return; } labelText = "Available spawn"; playerFaction = null; playerTeam = 0; widget.Bounds.Height = singleHeight; } label.Bounds.X = playerFaction != null ? flag.Bounds.Right + labelMargin : labelMargin; label.Bounds.Width = ownerFont.Measure(labelText).X; widget.Bounds.Width = Math.Max(teamWidth + 2 * labelMargin, label.Bounds.Right + labelMargin); team.Bounds.Width = widget.Bounds.Width; }; label.GetText = () => labelText; flag.IsVisible = () => playerFaction != null; flag.GetImageCollection = () => "flags"; flag.GetImageName = () => playerFaction; team.GetText = () => "Team {0}".F(playerTeam); team.IsVisible = () => playerTeam > 0; }
public WorldTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ViewportControllerWidget viewport) { widget.IsVisible = () => viewport.TooltipType != WorldTooltipType.None; var label = widget.Get <LabelWidget>("LABEL"); var flag = widget.Get <ImageWidget>("FLAG"); var owner = widget.Get <LabelWidget>("OWNER"); var font = Game.Renderer.Fonts[label.Font]; var ownerFont = Game.Renderer.Fonts[owner.Font]; var cachedWidth = 0; var labelText = ""; var showOwner = false; var flagRace = ""; var ownerName = ""; var ownerColor = Color.White; var singleHeight = widget.Get("SINGLE_HEIGHT").Bounds.Height; var doubleHeight = widget.Get("DOUBLE_HEIGHT").Bounds.Height; tooltipContainer.BeforeRender = () => { if (viewport == null || viewport.TooltipType == WorldTooltipType.None) { return; } Player o = null; switch (viewport.TooltipType) { case WorldTooltipType.Unexplored: labelText = "Unexplored Terrain"; break; case WorldTooltipType.Actor: labelText = viewport.ActorTooltip.Name(); o = viewport.ActorTooltip.Owner(); break; case WorldTooltipType.FrozenActor: labelText = viewport.FrozenActorTooltip.TooltipName; o = viewport.FrozenActorTooltip.TooltipOwner; break; } var textWidth = font.Measure(labelText).X; if (textWidth != cachedWidth) { label.Bounds.Width = textWidth; widget.Bounds.Width = 2 * label.Bounds.X + textWidth; } showOwner = o != null && !o.NonCombatant; if (showOwner) { flagRace = o.Country.Race; ownerName = o.PlayerName; ownerColor = o.Color.RGB; widget.Bounds.Height = doubleHeight; widget.Bounds.Width = Math.Max(widget.Bounds.Width, owner.Bounds.X + ownerFont.Measure(ownerName).X + label.Bounds.X); } else { widget.Bounds.Height = singleHeight; } }; label.GetText = () => labelText; flag.IsVisible = () => showOwner; flag.GetImageCollection = () => "flags"; flag.GetImageName = () => flagRace; owner.IsVisible = () => showOwner; owner.GetText = () => ownerName; owner.GetColor = () => ownerColor; }
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Player player, Func <ProductionIcon> getTooltipIcon) { var world = player.World; var mapRules = world.Map.Rules; var pm = player.PlayerActor.TraitOrDefault <PowerManager>(); var pr = player.PlayerActor.Trait <PlayerResources>(); widget.IsVisible = () => getTooltipIcon() != null && getTooltipIcon().Actor != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY"); var requiresLabel = widget.Get <LabelWidget>("REQUIRES"); var powerLabel = widget.Get <LabelWidget>("POWER"); var powerIcon = widget.Get <ImageWidget>("POWER_ICON"); var timeLabel = widget.Get <LabelWidget>("TIME"); var timeIcon = widget.Get <ImageWidget>("TIME_ICON"); var costLabel = widget.Get <LabelWidget>("COST"); var costIcon = widget.Get <ImageWidget>("COST_ICON"); var descLabel = widget.Get <LabelWidget>("DESC"); var iconMargin = timeIcon.Bounds.X; var font = Game.Renderer.Fonts[nameLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var requiresFont = Game.Renderer.Fonts[requiresLabel.Font]; var formatBuildTime = new CachedTransform <int, string>(time => WidgetUtils.FormatTime(time, world.Timestep)); var requiresFormat = requiresLabel.Text; ActorInfo lastActor = null; Hotkey lastHotkey = Hotkey.Invalid; var lastPowerState = pm == null ? PowerState.Normal : pm.PowerState; tooltipContainer.BeforeRender = () => { var tooltipIcon = getTooltipIcon(); if (tooltipIcon == null) { return; } var actor = tooltipIcon.Actor; if (actor == null) { return; } var hotkey = tooltipIcon.Hotkey != null?tooltipIcon.Hotkey.GetValue() : Hotkey.Invalid; if (actor == lastActor && hotkey == lastHotkey && (pm == null || pm.PowerState == lastPowerState)) { return; } var tooltip = actor.TraitInfos <TooltipInfo>().FirstOrDefault(info => info.EnabledByDefault); var name = tooltip != null ? tooltip.Name : actor.Name; var buildable = actor.TraitInfo <BuildableInfo>(); var cost = actor.TraitInfo <ValuedInfo>().Cost; nameLabel.Text = name; var nameSize = font.Measure(name); var hotkeyWidth = 0; hotkeyLabel.Visible = hotkey.IsValid(); if (hotkeyLabel.Visible) { var hotkeyText = "({0})".F(hotkey.DisplayString()); hotkeyWidth = font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X; hotkeyLabel.Text = hotkeyText; hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X; } var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)) .Where(s => !s.StartsWith("~", StringComparison.Ordinal) && !s.StartsWith("!", StringComparison.Ordinal)); requiresLabel.Text = prereqs.Any() ? requiresFormat.F(prereqs.JoinWith(", ")) : ""; var requiresSize = requiresFont.Measure(requiresLabel.Text); var powerSize = new int2(0, 0); if (pm != null) { var power = actor.TraitInfos <PowerInfo>().Where(i => i.EnabledByDefault).Sum(i => i.Amount); powerLabel.Text = power.ToString(); powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0) ? Color.White : Color.Red; powerLabel.Visible = power != 0; powerIcon.Visible = power != 0; powerSize = font.Measure(powerLabel.Text); } var buildTime = tooltipIcon.ProductionQueue == null ? 0 : tooltipIcon.ProductionQueue.GetBuildTime(actor, buildable); var timeMultiplier = pm != null && pm.PowerState != PowerState.Normal ? tooltipIcon.ProductionQueue.Info.LowPowerSlowdown : 1; timeLabel.Text = formatBuildTime.Update(buildTime * timeMultiplier); timeLabel.TextColor = (pm != null && pm.PowerState != PowerState.Normal && tooltipIcon.ProductionQueue.Info.LowPowerSlowdown > 1) ? Color.Red : Color.White; var timeSize = font.Measure(timeLabel.Text); costLabel.Text = cost.ToString(); costLabel.GetColor = () => pr.Cash + pr.Resources >= cost ? Color.White : Color.Red; var costSize = font.Measure(costLabel.Text); descLabel.Text = buildable.Description.Replace("\\n", "\n"); var descSize = descFont.Measure(descLabel.Text); var leftWidth = new[] { nameSize.X + hotkeyWidth, requiresSize.X, descSize.X }.Aggregate(Math.Max); var rightWidth = new[] { powerSize.X, timeSize.X, costSize.X }.Aggregate(Math.Max); timeIcon.Bounds.X = powerIcon.Bounds.X = costIcon.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X; timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin; widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin; var leftHeight = nameSize.Y + requiresSize.Y + descSize.Y; var rightHeight = powerSize.Y + timeSize.Y + costSize.Y; widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y; lastActor = actor; lastHotkey = hotkey; if (pm != null) { lastPowerState = pm.PowerState; } }; }
public SupportPowerTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, SupportPowersWidget palette, World world, PlayerResources playerResources) { widget.IsVisible = () => palette.TooltipIcon != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY"); var timeLabel = widget.Get <LabelWidget>("TIME"); var descLabel = widget.Get <LabelWidget>("DESC"); var costLabel = widget.Get <LabelWidget>("COST"); var nameFont = Game.Renderer.Fonts[nameLabel.Font]; var timeFont = Game.Renderer.Fonts[timeLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var costFont = Game.Renderer.Fonts[costLabel.Font]; var name = ""; var time = ""; var desc = ""; var baseHeight = widget.Bounds.Height; var timeOffset = timeLabel.Bounds.X; var costOffset = costLabel.Bounds.X; SupportPowerInstance lastPower = null; tooltipContainer.BeforeRender = () => { var icon = palette.TooltipIcon; if (icon == null) { return; } var sp = icon.Power; if (sp.Info == null) { return; // no instances actually exist (race with destroy) } var remaining = WidgetUtils.FormatTime(sp.RemainingTime, world.Timestep); var total = WidgetUtils.FormatTime(sp.Info.ChargeTime * 25, world.Timestep); time = "{0} / {1}".F(remaining, total); if (sp == lastPower) { return; } var cost = sp.Info.Cost; var costString = costLabel.Text + cost.ToString(); costLabel.GetText = () => costString; costLabel.GetColor = () => playerResources.Cash + playerResources.Resources >= cost ? Color.White : Color.Red; costLabel.IsVisible = () => cost != 0; name = sp.Info.Description; desc = sp.Info.LongDesc.Replace("\\n", "\n"); var hotkey = icon.Hotkey; var hotkeyText = "({0})".F(hotkey.DisplayString()); var hotkeyWidth = hotkey.IsValid() ? nameFont.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X : 0; hotkeyLabel.GetText = () => hotkeyText; hotkeyLabel.Bounds.X = nameFont.Measure(name).X + 2 * nameLabel.Bounds.X; hotkeyLabel.Visible = hotkey.IsValid(); var timeWidth = timeFont.Measure(time).X; var costWidth = costFont.Measure(costString).X; var topWidth = nameFont.Measure(name).X + hotkeyWidth + timeWidth + timeOffset; if (cost != 0) { topWidth += costWidth + costOffset; } var descSize = descFont.Measure(desc); widget.Bounds.Width = 2 * nameLabel.Bounds.X + Math.Max(topWidth, descSize.X); widget.Bounds.Height = baseHeight + descSize.Y; timeLabel.Bounds.X = widget.Bounds.Width - nameLabel.Bounds.X - timeWidth; if (cost != 0) { timeLabel.Bounds.X -= costWidth + costOffset; costLabel.Bounds.X = widget.Bounds.Width - nameLabel.Bounds.X - costWidth; } lastPower = sp; }; nameLabel.GetText = () => name; timeLabel.GetText = () => time; descLabel.GetText = () => desc; }
public SupportPowerTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, Player player, SupportPowersWidget palette, World world, PlayerResources playerResources) { widget.IsVisible = () => palette.TooltipIcon != null && palette.TooltipIcon.Power.Info != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var hotkeyLabel = widget.Get <LabelWidget>("HOTKEY"); var timeLabel = widget.Get <LabelWidget>("TIME"); var descLabel = widget.Get <LabelWidget>("DESC"); var costLabel = widget.Get <LabelWidget>("COST"); var nameFont = Game.Renderer.Fonts[nameLabel.Font]; var hotkeyFont = Game.Renderer.Fonts[hotkeyLabel.Font]; var timeFont = Game.Renderer.Fonts[timeLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var costFont = Game.Renderer.Fonts[costLabel.Font]; var baseHeight = widget.Bounds.Height; var timeOffset = timeLabel.Bounds.X; var costOffset = costLabel.Bounds.X; SupportPowerInstance lastPower = null; Hotkey lastHotkey = Hotkey.Invalid; var lastRemainingSeconds = 0; tooltipContainer.BeforeRender = () => { var icon = palette.TooltipIcon; if (icon == null) { return; } var sp = icon.Power; // HACK: This abuses knowledge of the internals of WidgetUtils.FormatTime // to efficiently work when the label is going to change, requiring a panel relayout var remainingSeconds = (int)Math.Ceiling(sp.RemainingTime * world.Timestep / 1000f); var hotkey = icon.Hotkey != null?icon.Hotkey.GetValue() : Hotkey.Invalid; if (sp == lastPower && hotkey == lastHotkey && lastRemainingSeconds == remainingSeconds) { return; } var cost = sp.Info.Cost; var costString = costLabel.Text + cost.ToString(); costLabel.GetText = () => costString; costLabel.GetColor = () => playerResources.Cash + playerResources.Resources >= cost ? Color.White : Color.Red; costLabel.IsVisible = () => cost != 0; nameLabel.Text = sp.Info.Description; var nameSize = nameFont.Measure(nameLabel.Text); descLabel.Text = sp.Info.LongDesc.Replace("\\n", "\n"); var descSize = descFont.Measure(descLabel.Text); var remaining = WidgetUtils.FormatTime(sp.RemainingTime, world.Timestep); var total = WidgetUtils.FormatTime(sp.Info.ChargeTime * 25, world.Timestep); timeLabel.Text = "{0} / {1}".F(remaining, total); var timeSize = timeFont.Measure(timeLabel.Text); var hotkeyWidth = 0; hotkeyLabel.Visible = hotkey.IsValid(); if (hotkeyLabel.Visible) { var hotkeyText = "({0})".F(hotkey.DisplayString()); hotkeyWidth = hotkeyFont.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X; hotkeyLabel.Text = hotkeyText; hotkeyLabel.Bounds.X = nameSize.X + 2 * nameLabel.Bounds.X; } var timeWidth = timeSize.X; var costWidth = costFont.Measure(costString).X; var topWidth = nameSize.X + hotkeyWidth + timeWidth + timeOffset; if (cost != 0) { topWidth += costWidth + costOffset; } widget.Bounds.Width = 2 * nameLabel.Bounds.X + Math.Max(topWidth, descSize.X); widget.Bounds.Height = baseHeight + descSize.Y; timeLabel.Bounds.X = widget.Bounds.Width - nameLabel.Bounds.X - timeWidth; if (cost != 0) { timeLabel.Bounds.X -= costWidth + costOffset; costLabel.Bounds.X = widget.Bounds.Width - nameLabel.Bounds.X - costWidth; } lastPower = sp; lastHotkey = hotkey; lastRemainingSeconds = remainingSeconds; }; timeLabel.GetColor = () => palette.TooltipIcon != null && !palette.TooltipIcon.Power.Active ? Color.Red : Color.White; }
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette) { var mapRules = palette.World.Map.Rules; var pm = palette.World.LocalPlayer.PlayerActor.Trait <PowerManager>(); var pr = palette.World.LocalPlayer.PlayerActor.Trait <PlayerResources>(); widget.IsVisible = () => palette.TooltipActor != null; var nameLabel = widget.Get <LabelWidget>("NAME"); var requiresLabel = widget.Get <LabelWidget>("REQUIRES"); var powerLabel = widget.Get <LabelWidget>("POWER"); var timeLabel = widget.Get <LabelWidget>("TIME"); var costLabel = widget.Get <LabelWidget>("COST"); var descLabel = widget.Get <LabelWidget>("DESC"); var font = Game.Renderer.Fonts[nameLabel.Font]; var descFont = Game.Renderer.Fonts[descLabel.Font]; var requiresFont = Game.Renderer.Fonts[requiresLabel.Font]; string lastActor = null; tooltipContainer.BeforeRender = () => { var actor = palette.TooltipActor; if (actor == null || actor == lastActor) { return; } var info = mapRules.Actors[actor]; var tooltip = info.Traits.Get <TooltipInfo>(); var buildable = info.Traits.Get <BuildableInfo>(); var cost = info.Traits.Get <ValuedInfo>().Cost; var bi = info.Traits.GetOrDefault <BuildingInfo>(); nameLabel.GetText = () => tooltip.Name; var prereqs = buildable.Prerequisites.Select(a => ActorName(mapRules, a)); var requiresString = prereqs.Any() ? requiresLabel.Text.F(prereqs.JoinWith(", ")) : ""; requiresLabel.GetText = () => requiresString; var power = bi != null ? bi.Power : 0; var powerString = "P: {0}".F(power); powerLabel.GetText = () => powerString; powerLabel.GetColor = () => ((pm.PowerProvided - pm.PowerDrained) >= -power || power > 0) ? Color.White : Color.Red; powerLabel.IsVisible = () => power != 0; var lowpower = pm.PowerState != PowerState.Normal; var time = palette.CurrentQueue.GetBuildTime(actor) * ((lowpower) ? palette.CurrentQueue.Info.LowPowerSlowdown : 1); var timeString = "T: {0}".F(WidgetUtils.FormatTime(time)); timeLabel.GetText = () => timeString; timeLabel.GetColor = () => lowpower ? Color.Red : Color.White; var costString = "$: {0}".F(cost); costLabel.GetText = () => costString; costLabel.GetColor = () => pr.DisplayCash + pr.DisplayOre >= cost ? Color.White : Color.Red; var descString = tooltip.Description.Replace("\\n", "\n"); descLabel.GetText = () => descString; var leftWidth = new[] { font.Measure(tooltip.Name).X, requiresFont.Measure(requiresString).X, descFont.Measure(descString).X }.Aggregate(Math.Max); var rightWidth = new[] { font.Measure(powerString).X, font.Measure(timeString).X, font.Measure(costString).X }.Aggregate(Math.Max); timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = leftWidth + 2 * nameLabel.Bounds.X; widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X; var leftHeight = font.Measure(tooltip.Name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y; var rightHeight = font.Measure(powerString).Y + font.Measure(timeString).Y + font.Measure(costString).Y; widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y; lastActor = actor; }; }
public ClientTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, OrderManager orderManager, int clientIndex) { var admin = widget.Get <LabelWidget>("ADMIN"); var adminFont = Game.Renderer.Fonts[admin.Font]; var latency = widget.GetOrNull <LabelWidget>("LATENCY"); if (latency != null) { latencyFont = Game.Renderer.Fonts[latency.Font]; } var latencyPrefix = widget.GetOrNull <LabelWidget>("LATENCY_PREFIX"); if (latencyPrefix != null) { latencyPrefixFont = Game.Renderer.Fonts[latencyPrefix.Font]; } var ip = widget.Get <LabelWidget>("IP"); var addressFont = Game.Renderer.Fonts[ip.Font]; var location = widget.Get <LabelWidget>("LOCATION"); var locationFont = Game.Renderer.Fonts[location.Font]; var locationOffset = location.Bounds.Y; var addressOffset = ip.Bounds.Y; var latencyOffset = latency == null ? 0 : latency.Bounds.Y; var tooltipHeight = widget.Bounds.Height; var margin = widget.Bounds.Width; widget.IsVisible = () => (orderManager.LobbyInfo.ClientWithIndex(clientIndex) != null); tooltipContainer.BeforeRender = () => { if (!widget.IsVisible()) { return; } var latencyPrefixSize = latencyPrefix == null ? 0 : latencyPrefix.Bounds.X + latencyPrefixFont.Measure(latencyPrefix.GetText() + " ").X; var locationWidth = locationFont.Measure(location.GetText()).X; var adminWidth = adminFont.Measure(admin.GetText()).X; var addressWidth = addressFont.Measure(ip.GetText()).X; var latencyWidth = latencyFont == null ? 0 : latencyPrefixSize + latencyFont.Measure(latency.GetText()).X; var width = Math.Max(locationWidth, Math.Max(adminWidth, Math.Max(addressWidth, latencyWidth))); widget.Bounds.Width = width + 2 * margin; if (latency != null) { latency.Bounds.Width = widget.Bounds.Width; } ip.Bounds.Width = widget.Bounds.Width; admin.Bounds.Width = widget.Bounds.Width; location.Bounds.Width = widget.Bounds.Width; ip.Bounds.Y = addressOffset; if (latency != null) { latency.Bounds.Y = latencyOffset; } location.Bounds.Y = locationOffset; widget.Bounds.Height = tooltipHeight; if (admin.IsVisible()) { ip.Bounds.Y += admin.Bounds.Height; if (latency != null) { latency.Bounds.Y += admin.Bounds.Height; } location.Bounds.Y += admin.Bounds.Height; widget.Bounds.Height += admin.Bounds.Height; } if (latencyPrefix != null) { latencyPrefix.Bounds.Y = latency.Bounds.Y; } if (latency != null) { latency.Bounds.X = latencyPrefixSize; } }; admin.IsVisible = () => orderManager.LobbyInfo.ClientWithIndex(clientIndex).IsAdmin; var client = orderManager.LobbyInfo.ClientWithIndex(clientIndex); var ping = orderManager.LobbyInfo.PingFromClient(client); if (latency != null) { latency.GetText = () => LobbyUtils.LatencyDescription(ping); latency.GetColor = () => LobbyUtils.LatencyColor(ping); } var address = LobbyUtils.GetExternalIP(clientIndex, orderManager); var cachedDescriptiveIP = LobbyUtils.DescriptiveIpAddress(address); ip.GetText = () => cachedDescriptiveIP; var cachedCountryLookup = GeoIP.LookupCountry(address); location.GetText = () => cachedCountryLookup; }