예제 #1
0
        public void BuildMusicTable()
        {
            if (!musicPlaylist.IsMusicAvailable)
            {
                return;
            }

            var music = musicPlaylist.AvailablePlaylist();

            currentSong = musicPlaylist.CurrentSong();

            musicList.RemoveChildren();
            foreach (var song in music)
            {
                var item  = ScrollItemWidget.Setup(song.Filename, itemTemplate, () => currentSong == song, () => { currentSong = song; Play(); }, () => { });
                var label = item.Get <LabelWithTooltipWidget>("TITLE");
                WidgetUtils.TruncateLabelToTooltip(label, song.Title);

                item.Get <LabelWidget>("LENGTH").GetText = () => SongLengthLabel(song);
                musicList.AddChild(item);
            }

            if (currentSong != null && !musicPlaylist.CurrentSongIsBackground)
            {
                musicList.ScrollToItem(currentSong.Filename);
            }
        }
예제 #2
0
        void AddAsset(ScrollPanelWidget list, string filepath, IReadOnlyPackage package, ScrollItemWidget template)
        {
            var item = ScrollItemWidget.Setup(template,
                                              () => currentFilename == filepath && currentPackage == package,
                                              () => { LoadAsset(package, filepath); });

            var label = item.Get <LabelWithTooltipWidget>("TITLE");

            WidgetUtils.TruncateLabelToTooltip(label, filepath);
            label.GetTooltipText = () => $"{filepath}\n{package.Name}";

            item.IsVisible = () =>
            {
                if (assetVisByName.TryGetValue(filepath, out var visible))
                {
                    return(visible);
                }

                visible = FilterAsset(filepath);
                assetVisByName.Add(filepath, visible);
                return(visible);
            };

            list.AddChild(item);
        }
예제 #3
0
        public void BuildSoundTable()
        {
            currentSoundAvaliable = GetSound(soundIndex, out currentSound);

            soundList.RemoveChildren();
            foreach (var sound in sounds)
            {
                var item = ScrollItemWidget.Setup(sound.Key, itemTemplate, () => currentSound.Key == sound.Key,
                                                  () => {
                    currentSound = new KeyValuePair <string, string[]>(sound.Key, sound.Value == SoundPlayType.Voice ? voiceSounds[sound.Key] : notificationSounds[sound.Key]);;
                    Play();
                },
                                                  () => { });
                var label = item.Get <LabelWithTooltipWidget>("TITLE");
                WidgetUtils.TruncateLabelToTooltip(label, sound.Key);

                //item.Get<LabelWidget>("LENGTH").GetText = () => SongLengthLabel(sound);
                soundList.AddChild(item);
            }

            if (currentSoundAvaliable)
            {
                soundList.ScrollToItem(currentSound.Key);
            }
        }
예제 #4
0
        void LoadGames(ScrollItemWidget gameTemplate, ScrollItemWidget newTemplate, World world)
        {
            gameList.RemoveChildren();
            if (isSavePanel)
            {
                var item = ScrollItemWidget.Setup(newTemplate,
                                                  () => selectedSave == null,
                                                  () => Select(null),
                                                  () => { });
                gameList.AddChild(item);
            }

            var savePaths = Directory.GetFiles(baseSavePath, "*.orasav", SearchOption.AllDirectories)
                            .OrderByDescending(p => File.GetLastWriteTime(p))
                            .ToList();

            foreach (var savePath in savePaths)
            {
                games.Add(savePath);

                // Create the item manually so the click handlers can refer to itself
                // This simplifies the rename handling (only needs to update ItemKey)
                var item = gameTemplate.Clone() as ScrollItemWidget;
                item.ItemKey    = savePath;
                item.IsVisible  = () => true;
                item.IsSelected = () => selectedSave == item.ItemKey;
                item.OnClick    = () => Select(item.ItemKey);

                if (isSavePanel)
                {
                    item.OnDoubleClick = () => Save(world);
                }
                else
                {
                    item.OnDoubleClick = Load;
                }

                var title = Path.GetFileNameWithoutExtension(savePath);
                var label = item.Get <LabelWithTooltipWidget>("TITLE");
                WidgetUtils.TruncateLabelToTooltip(label, title);

                var date = File.GetLastWriteTime(savePath).ToString("yyyy-MM-dd HH:mm:ss");
                item.Get <LabelWidget>("DATE").GetText = () => date;

                gameList.AddChild(item);
            }
        }
예제 #5
0
        void RenameReplay(ReplayMetadata replay, string newFilenameWithoutExtension)
        {
            try
            {
                var item = replayState[replay].Item;
                replay.RenameFile(newFilenameWithoutExtension);
                item.Text = newFilenameWithoutExtension;

                var label = item.Get <LabelWithTooltipWidget>("TITLE");
                WidgetUtils.TruncateLabelToTooltip(label, item.Text);
            }
            catch (Exception ex)
            {
                Log.Write("debug", ex.ToString());
                return;
            }
        }
예제 #6
0
        void CreateMissionGroup(string title, IEnumerable <MapPreview> previews)
        {
            var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });

            header.Get <LabelWidget>("LABEL").GetText = () => title;
            missionList.AddChild(header);

            foreach (var preview in previews)
            {
                var item = ScrollItemWidget.Setup(template,
                                                  () => selectedMap != null && selectedMap.Uid == preview.Uid,
                                                  () => SelectMap(preview),
                                                  StartMissionClicked);

                var label = item.Get <LabelWithTooltipWidget>("TITLE");
                WidgetUtils.TruncateLabelToTooltip(label, preview.Title);

                missionList.AddChild(item);
            }
        }
예제 #7
0
        void AddReplay(ReplayMetadata replay, ScrollItemWidget template)
        {
            replays.Add(replay);

            var item = ScrollItemWidget.Setup(template,
                                              () => selectedReplay == replay,
                                              () => SelectReplay(replay),
                                              () => WatchReplay());

            replayState[replay] = new ReplayState
            {
                Item    = item,
                Visible = true
            };

            item.Text = Path.GetFileNameWithoutExtension(replay.FilePath);
            var label = item.Get <LabelWithTooltipWidget>("TITLE");

            WidgetUtils.TruncateLabelToTooltip(label, item.Text);

            item.IsVisible = () => replayState[replay].Visible;
            replayList.AddChild(item);
        }
        public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, World world, Dictionary <string, MiniYaml> logicArgs)
        {
            this.world   = world;
            this.modData = modData;
            panel        = widget;

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName);
                sourceDropdown.GetText = () => sourceName.Update(assetSource);
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteWidget.GetPalette = () => currentPalette;
                spriteWidget.IsVisible  = () => !isVideoLoaded && !isLoadError && currentSprites != null;
            }

            var playerWidget = panel.GetOrNull <VqaPlayerWidget>("PLAYER");

            if (playerWidget != null)
            {
                playerWidget.IsVisible = () => isVideoLoaded && !isLoadError;
            }

            var modelWidget = panel.GetOrNull <ModelWidget>("VOXEL");

            if (modelWidget != null)
            {
                modelWidget.GetVoxel         = () => currentVoxel;
                currentPalette               = modelWidget.Palette;
                modelWidget.GetPalette       = () => currentPalette;
                modelWidget.GetPlayerPalette = () => currentPalette;
                modelWidget.GetRotation      = () => modelOrientation;
                modelWidget.IsVisible        = () => !isVideoLoaded && !isLoadError && currentVoxel != null;
            }

            var errorLabelWidget = panel.GetOrNull("ERROR");

            if (errorLabelWidget != null)
            {
                errorLabelWidget.IsVisible = () => isLoadError;
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world);
                paletteDropDown.GetText     = () => currentPalette;
            }

            var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER");

            if (colorPreview != null)
            {
                colorPreview.Color = Game.Settings.Player.Color;
            }

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => currentPalette != colorPreview.PaletteName;
                colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, world);
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color;
            }

            filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnTextEdited = () => ApplyFilter();
            filenameInput.OnEscKey     = filenameInput.YieldKeyboardFocus;

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) ||
                                           (isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1);
            }

            frameSlider = panel.GetOrNull <SliderWidget>("FRAME_SLIDER");
            if (frameSlider != null)
            {
                frameSlider.OnChange += x =>
                {
                    if (!isVideoLoaded)
                    {
                        currentFrame = (int)Math.Round(x);
                    }
                };

                frameSlider.GetValue   = () => isVideoLoaded ? player.Video.CurrentFrame : currentFrame;
                frameSlider.IsDisabled = () => isVideoLoaded;
            }

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () =>
                                    isVideoLoaded ?
                                    "{0} / {1}".F(player.Video.CurrentFrame + 1, player.Video.Frames) :
                                    "{0} / {1}".F(currentFrame, currentSprites.Length - 1);
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Play();
                    }
                    else
                    {
                        animateFrames = true;
                    }
                };

                playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Pause();
                    }
                    else
                    {
                        animateFrames = false;
                    }
                };

                pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : animateFrames;
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    else
                    {
                        if (frameSlider != null)
                        {
                            frameSlider.Value = 0;
                        }

                        currentFrame  = 0;
                        animateFrames = false;
                    }
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        nextButton.OnClick = SelectNextFrame;
                    }
                };

                nextButton.IsVisible = () => !isVideoLoaded;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        SelectPreviousFrame();
                    }
                };

                prevButton.IsVisible = () => !isVideoLoaded;
            }

            var voxelContainer = panel.GetOrNull("VOXEL_SELECTOR");

            if (voxelContainer != null)
            {
                voxelContainer.IsVisible = () => currentVoxel != null;
            }

            var rollSlider = panel.GetOrNull <SliderWidget>("ROLL_SLIDER");

            if (rollSlider != null)
            {
                rollSlider.OnChange += x =>
                {
                    var roll = (int)x;
                    modelOrientation = modelOrientation.WithRoll(new WAngle(roll));
                };

                rollSlider.GetValue = () => modelOrientation.Roll.Angle;
            }

            var pitchSlider = panel.GetOrNull <SliderWidget>("PITCH_SLIDER");

            if (pitchSlider != null)
            {
                pitchSlider.OnChange += x =>
                {
                    var pitch = (int)x;
                    modelOrientation = modelOrientation.WithPitch(new WAngle(pitch));
                };

                pitchSlider.GetValue = () => modelOrientation.Pitch.Angle;
            }

            var yawSlider = panel.GetOrNull <SliderWidget>("YAW_SLIDER");

            if (yawSlider != null)
            {
                yawSlider.OnChange += x =>
                {
                    var yaw = (int)x;
                    modelOrientation = modelOrientation.WithYaw(new WAngle(yaw));
                };

                yawSlider.GetValue = () => modelOrientation.Yaw.Angle;
            }

            var assetBrowserModData = modData.Manifest.Get <AssetBrowser>();

            allowedExtensions = assetBrowserModData.SupportedExtensions;

            acceptablePackages = modData.ModFiles.MountedPackages.Where(p =>
                                                                        p.Contents.Any(c => allowedExtensions.Contains(Path.GetExtension(c).ToLowerInvariant())));

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    Ui.CloseWindow();
                    onExit();
                }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }

        Dictionary <string, bool> assetVisByName = new Dictionary <string, bool>();

        bool FilterAsset(string filename)
        {
            var filter = filenameInput.Text;

            if (string.IsNullOrWhiteSpace(filter))
            {
                return(true);
            }

            if (filename.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            return(false);
        }

        void ApplyFilter()
        {
            assetVisByName.Clear();
            assetList.Layout.AdjustChildren();
            assetList.ScrollToTop();

            // Select the first visible
            var firstVisible = assetVisByName.FirstOrDefault(kvp => kvp.Value);

            if (firstVisible.Key != null && modData.DefaultFileSystem.TryGetPackageContaining(firstVisible.Key, out var package, out var filename))
            {
                LoadAsset(package, filename);
            }
        }

        void AddAsset(ScrollPanelWidget list, string filepath, IReadOnlyPackage package, ScrollItemWidget template)
        {
            var item = ScrollItemWidget.Setup(template,
                                              () => currentFilename == filepath && currentPackage == package,
                                              () => { LoadAsset(package, filepath); });

            var label = item.Get <LabelWithTooltipWidget>("TITLE");

            WidgetUtils.TruncateLabelToTooltip(label, filepath);

            item.IsVisible = () =>
            {
                if (assetVisByName.TryGetValue(filepath, out var visible))
                {
                    return(visible);
                }

                visible = FilterAsset(filepath);
                assetVisByName.Add(filepath, visible);
                return(visible);
            };

            list.AddChild(item);
        }

        bool LoadAsset(IReadOnlyPackage package, string filename)
        {
            if (isVideoLoaded)
            {
                player.Stop();
                player        = null;
                isVideoLoaded = false;
            }

            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!package.Contains(filename))
            {
                return(false);
            }

            isLoadError = false;

            try
            {
                currentPackage  = package;
                currentFilename = filename;
                var prefix = "";
                var fs     = modData.DefaultFileSystem as OpenRA.FileSystem.FileSystem;

                if (fs != null)
                {
                    prefix = fs.GetPrefix(package);
                    if (prefix != null)
                    {
                        prefix += "|";
                    }
                }

                if (Path.GetExtension(filename.ToLowerInvariant()) == ".vqa")
                {
                    player = panel.Get <VqaPlayerWidget>("PLAYER");
                    player.Load(prefix + filename);
                    player.DrawOverlay = false;
                    isVideoLoaded      = true;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)player.Video.Frames - 1;
                        frameSlider.Ticks        = 0;
                    }

                    return(true);
                }

                if (Path.GetExtension(filename.ToLowerInvariant()) == ".vxl")
                {
                    var voxelName = Path.GetFileNameWithoutExtension(filename);
                    currentVoxel   = world.ModelCache.GetModel(voxelName);
                    currentSprites = null;
                }
                else
                {
                    currentSprites = world.Map.Rules.Sequences.SpriteCache[prefix + filename];
                    currentFrame   = 0;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)currentSprites.Length - 1;
                        frameSlider.Ticks        = currentSprites.Length;
                    }

                    currentVoxel = null;
                }
            }
            catch (Exception ex)
            {
                isLoadError = true;
                Log.AddChannel("assetbrowser", "assetbrowser.log");
                Log.Write("assetbrowser", "Error reading {0}:{3} {1}{3}{2}", filename, ex.Message, ex.StackTrace, Environment.NewLine);

                return(false);
            }

            return(true);
        }

        bool ShowSourceDropdown(DropDownButtonWidget dropdown)
        {
            var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName);
            Func <IReadOnlyPackage, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => assetSource == source,
                                                  () => { assetSource = source; PopulateAssetList(); });

                item.Get <LabelWidget>("LABEL").GetText = () => sourceName.Update(source);
                return(item);
            };

            var sources = new[] { (IReadOnlyPackage)null }.Concat(acceptablePackages);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem);
            return(true);
        }

        void PopulateAssetList()
        {
            assetList.RemoveChildren();

            var files = new SortedList <string, List <IReadOnlyPackage> >();

            if (assetSource != null)
            {
                foreach (var content in assetSource.Contents)
                {
                    files.Add(content, new List <IReadOnlyPackage> {
                        assetSource
                    });
                }
            }
            else
            {
                foreach (var mountedPackage in modData.ModFiles.MountedPackages)
                {
                    foreach (var content in mountedPackage.Contents)
                    {
                        if (!files.ContainsKey(content))
                        {
                            files.Add(content, new List <IReadOnlyPackage> {
                                mountedPackage
                            });
                        }
                        else
                        {
                            files[content].Add(mountedPackage);
                        }
                    }
                }
            }

            foreach (var file in files.OrderBy(s => s.Key))
            {
                if (!allowedExtensions.Any(ext => file.Key.EndsWith(ext, true, CultureInfo.InvariantCulture)))
                {
                    continue;
                }

                foreach (var package in file.Value)
                {
                    AddAsset(assetList, file.Key, package, template);
                }
            }
        }

        bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world)
        {
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (name, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => currentPalette == name,
                                                  () => currentPalette = name);
                item.Get <LabelWidget>("LABEL").GetText = () => name;

                return(item);
            };

            var palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>()
                           .SelectMany(p => p.PaletteNames);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem);
            return(true);
        }

        string GetSourceDisplayName(IReadOnlyPackage source)
        {
            if (source == null)
            {
                return("All Packages");
            }

            // Packages that are explicitly mounted in the filesystem use their explicit mount name
            var fs   = (OpenRA.FileSystem.FileSystem)modData.DefaultFileSystem;
            var name = fs.GetPrefix(source);

            // Fall back to the path relative to the mod, engine, or support dir
            if (name == null)
            {
                name = source.Name;
                var compare = Platform.CurrentPlatform == PlatformType.Windows ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
                if (name.StartsWith(modData.Manifest.Package.Name, compare))
                {
                    name = "$" + modData.Manifest.Id + "/" + name.Substring(modData.Manifest.Package.Name.Length + 1);
                }
                else if (name.StartsWith(Platform.EngineDir, compare))
                {
                    name = "./" + name.Substring(Platform.EngineDir.Length);
                }
                else if (name.StartsWith(Platform.SupportDir, compare))
                {
                    name = "^" + name.Substring(Platform.SupportDir.Length);
                }
            }

            if (name.Length > 18)
            {
                name = "..." + name.Substring(name.Length - 15);
            }

            return(name);
        }
    }
예제 #9
0
        void EnumerateMaps(MapClassification tab, ScrollItemWidget template)
        {
            if (!int.TryParse(mapFilter, out var playerCountFilter))
            {
                playerCountFilter = -1;
            }

            var maps = tabMaps[tab]
                       .Where(m => category == null || m.Categories.Contains(category))
                       .Where(m => mapFilter == null ||
                              (m.Title != null && m.Title.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
                              (m.Author != null && m.Author.IndexOf(mapFilter, StringComparison.OrdinalIgnoreCase) >= 0) ||
                              m.PlayerCount == playerCountFilter)
                       .OrderBy(m => m.PlayerCount)
                       .ThenBy(m => m.Title);

            scrollpanels[tab].RemoveChildren();
            foreach (var loop in maps)
            {
                var preview = loop;

                // Access the minimap to trigger async generation of the minimap.
                preview.GetMinimap();

                Action dblClick = () =>
                {
                    if (onSelect != null)
                    {
                        Ui.CloseWindow();
                        onSelect(preview.Uid);
                    }
                };

                var item = ScrollItemWidget.Setup(preview.Uid, template, () => selectedUid == preview.Uid,
                                                  () => selectedUid = preview.Uid, dblClick);
                item.IsVisible = () => item.RenderBounds.IntersectsWith(scrollpanels[tab].RenderBounds);

                var titleLabel = item.Get <LabelWithTooltipWidget>("TITLE");
                if (titleLabel != null)
                {
                    WidgetUtils.TruncateLabelToTooltip(titleLabel, preview.Title);
                }

                var previewWidget = item.Get <MapPreviewWidget>("PREVIEW");
                previewWidget.Preview = () => preview;

                var detailsWidget = item.GetOrNull <LabelWidget>("DETAILS");
                if (detailsWidget != null)
                {
                    var type    = preview.Categories.FirstOrDefault();
                    var details = "";
                    if (type != null)
                    {
                        details = type + " ";
                    }

                    details += $"({preview.PlayerCount} players)";
                    detailsWidget.GetText = () => details;
                }

                var authorWidget = item.GetOrNull <LabelWithTooltipWidget>("AUTHOR");
                if (authorWidget != null)
                {
                    WidgetUtils.TruncateLabelToTooltip(authorWidget, $"Created by {preview.Author}");
                }

                var sizeWidget = item.GetOrNull <LabelWidget>("SIZE");
                if (sizeWidget != null)
                {
                    var size = preview.Bounds.Width + "x" + preview.Bounds.Height;
                    var numberPlayableCells = preview.Bounds.Width * preview.Bounds.Height;
                    if (numberPlayableCells >= 120 * 120)
                    {
                        size += " (Huge)";
                    }
                    else if (numberPlayableCells >= 90 * 90)
                    {
                        size += " (Large)";
                    }
                    else if (numberPlayableCells >= 60 * 60)
                    {
                        size += " (Medium)";
                    }
                    else
                    {
                        size += " (Small)";
                    }
                    sizeWidget.GetText = () => size;
                }

                scrollpanels[tab].AddChild(item);
            }

            if (tab == currentTab)
            {
                visibleMaps = maps.Select(m => m.Uid).ToArray();
                SetupGameModeDropdown(currentTab, gameModeDropdown, template);
            }

            if (visibleMaps.Contains(selectedUid))
            {
                scrollpanels[tab].ScrollToItem(selectedUid);
            }
        }
예제 #10
0
        List <Widget> LoadGameRows(List <GameServer> games, out ScrollItemWidget nextServerRow)
        {
            nextServerRow = null;
            var rows = new List <Widget>();
            var mods = games.GroupBy(g => g.ModLabel)
                       .OrderByDescending(g => GroupSortOrder(g.First()))
                       .ThenByDescending(g => g.Count());

            foreach (var modGames in mods)
            {
                if (modGames.All(Filtered))
                {
                    continue;
                }

                var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { });

                var headerTitle = modGames.First().ModLabel;
                header.Get <LabelWidget>("LABEL").GetText = () => headerTitle;
                rows.Add(header);

                Func <GameServer, int> listOrder = g =>
                {
                    // Servers waiting for players are always first
                    if (g.State == (int)ServerState.WaitingPlayers && g.Players > 0)
                    {
                        return(0);
                    }

                    // Then servers with spectators
                    if (g.State == (int)ServerState.WaitingPlayers && g.Spectators > 0)
                    {
                        return(1);
                    }

                    // Then active games
                    if (g.State >= (int)ServerState.GameStarted)
                    {
                        return(2);
                    }

                    // Empty servers are shown at the end because a flood of empty servers
                    // at the top of the game list make the community look dead
                    return(3);
                };

                foreach (var modGamesByState in modGames.GroupBy(listOrder).OrderBy(g => g.Key))
                {
                    // Sort 'Playing' games by Started, others by number of players
                    foreach (var game in modGamesByState.Key == 2 ? modGamesByState.OrderByDescending(g => g.Started) : modGamesByState.OrderByDescending(g => g.Players))
                    {
                        if (Filtered(game))
                        {
                            continue;
                        }

                        var canJoin = game.IsJoinable;
                        var item    = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => SelectServer(game), () => onJoin(game));
                        var title   = item.GetOrNull <LabelWithTooltipWidget>("TITLE");
                        if (title != null)
                        {
                            WidgetUtils.TruncateLabelToTooltip(title, game.Name);
                            title.GetColor = () => canJoin ? title.TextColor : incompatibleGameColor;
                        }

                        var password = item.GetOrNull <ImageWidget>("PASSWORD_PROTECTED");
                        if (password != null)
                        {
                            password.IsVisible    = () => game.Protected;
                            password.GetImageName = () => canJoin ? "protected" : "protected-disabled";
                        }

                        var auth = item.GetOrNull <ImageWidget>("REQUIRES_AUTHENTICATION");
                        if (auth != null)
                        {
                            auth.IsVisible    = () => game.Authentication;
                            auth.GetImageName = () => canJoin ? "authentication" : "authentication-disabled";

                            if (game.Protected && password != null)
                            {
                                auth.Bounds.X -= password.Bounds.Width + 5;
                            }
                        }

                        var players = item.GetOrNull <LabelWithTooltipWidget>("PLAYERS");
                        if (players != null)
                        {
                            var label = "{0} / {1}".F(game.Players + game.Bots, game.MaxPlayers + game.Bots)
                                        + (game.Spectators > 0 ? " + {0}".F(game.Spectators) : "");

                            var color = canJoin ? players.TextColor : incompatibleGameColor;
                            players.GetText  = () => label;
                            players.GetColor = () => color;

                            if (game.Clients.Any())
                            {
                                var displayClients = game.Clients.Select(c => c.Name);
                                if (game.Clients.Length > 10)
                                {
                                    displayClients = displayClients
                                                     .Take(9)
                                                     .Append("+ {0} other players".F(game.Clients.Length - 9));
                                }

                                var tooltip = displayClients.JoinWith("\n");
                                players.GetTooltipText = () => tooltip;
                            }
                            else
                            {
                                players.GetTooltipText = null;
                            }
                        }

                        var state = item.GetOrNull <LabelWidget>("STATUS");
                        if (state != null)
                        {
                            var label = game.State >= (int)ServerState.GameStarted ?
                                        "Playing" : "Waiting";
                            state.GetText = () => label;

                            var color = GetStateColor(game, state, !canJoin);
                            state.GetColor = () => color;
                        }

                        var location = item.GetOrNull <LabelWidget>("LOCATION");
                        if (location != null)
                        {
                            var font  = Game.Renderer.Fonts[location.Font];
                            var label = WidgetUtils.TruncateText(game.Location, location.Bounds.Width, font);
                            location.GetText  = () => label;
                            location.GetColor = () => canJoin ? location.TextColor : incompatibleGameColor;
                        }

                        if (currentServer != null && game.Address == currentServer.Address)
                        {
                            nextServerRow = item;
                        }

                        rows.Add(item);
                    }
                }
            }

            return(rows);
        }