diff --git a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs index 7644831c93..5d7af738b3 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/AssetBrowserLogic.cs @@ -14,6 +14,7 @@ using System.Globalization; using System.IO; using System.Linq; using OpenRA.FileFormats; +using OpenRA.Graphics; using OpenRA.Traits; using OpenRA.Widgets; @@ -23,17 +24,19 @@ namespace OpenRA.Mods.RA.Widgets.Logic { Widget panel; - ShpImageWidget spriteWidget; TextFieldWidget filenameInput; SliderWidget frameSlider; - ButtonWidget playButton, pauseButton; ScrollPanelWidget assetList; ScrollItemWidget template; IFolder assetSource = null; List availableShps = new List(); + bool animateFrames = false; - PaletteFromFile currentPalette; + string currentPalette; + string currentFilename; + Sprite[] currentSprites; + int currentFrame; static readonly string[] AllowedExtensions = { ".shp", ".r8", "tmp", ".tem", ".des", ".sno", ".int" }; @@ -41,94 +44,139 @@ namespace OpenRA.Mods.RA.Widgets.Logic public AssetBrowserLogic(Widget widget, Action onExit, World world) { panel = widget; - - var sourceDropdown = panel.Get("SOURCE_SELECTOR"); - sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown); - sourceDropdown.GetText = () => - { - var name = assetSource != null ? assetSource.Name.Replace(Platform.SupportDir, "^") : "All Packages"; - - if (name.Length > 15) - name = "..." + name.Substring(name.Length - 15); - - return name; - }; - assetSource = FileSystem.MountedFolders.First(); - spriteWidget = panel.Get("SPRITE"); + var ticker = panel.GetOrNull("ANIMATION_TICKER"); + if (ticker != null) + { + ticker.OnTick = () => + { + if (animateFrames) + SelectNextFrame(); + }; + } - currentPalette = world.WorldActor.TraitsImplementing().First(p => p.Name == spriteWidget.Palette); + var sourceDropdown = panel.GetOrNull("SOURCE_SELECTOR"); + if (sourceDropdown != null) + { + sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown); + sourceDropdown.GetText = () => + { + var name = assetSource != null ? assetSource.Name.Replace(Platform.SupportDir, "^") : "All Packages"; + if (name.Length > 15) + name = "..." + name.Substring(name.Length - 15); - var paletteDropDown = panel.Get("PALETTE_SELECTOR"); - paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world); - paletteDropDown.GetText = () => currentPalette.Name; + return name; + }; + } - var colorPreview = panel.Get("COLOR_MANAGER"); - colorPreview.Color = Game.Settings.Player.Color; + var spriteWidget = panel.GetOrNull("SPRITE"); + if (spriteWidget != null) + { + spriteWidget.GetSprite = () => currentSprites != null ? currentSprites[currentFrame] : null; + currentPalette = spriteWidget.Palette; + spriteWidget.GetPalette = () => currentPalette; + } - var color = panel.Get("COLOR"); - color.IsDisabled = () => currentPalette.Name != colorPreview.Palette; - color.OnMouseDown = _ => ShowColorDropDown(color, colorPreview, world); - var block = panel.Get("COLORBLOCK"); - block.GetColor = () => Game.Settings.Player.Color.RGB; + var paletteDropDown = panel.GetOrNull("PALETTE_SELECTOR"); + if (paletteDropDown != null) + { + paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world); + paletteDropDown.GetText = () => currentPalette; + } + + var colorPreview = panel.GetOrNull("COLOR_MANAGER"); + if (colorPreview != null) + colorPreview.Color = Game.Settings.Player.Color; + + var colorDropdown = panel.GetOrNull("COLOR"); + if (colorDropdown != null) + { + colorDropdown.IsDisabled = () => currentPalette != colorPreview.Palette; + colorDropdown.OnMouseDown = _ => ShowColorDropDown(colorDropdown, colorPreview, world); + panel.Get("COLORBLOCK").GetColor = () => Game.Settings.Player.Color.RGB; + } filenameInput = panel.Get("FILENAME_INPUT"); filenameInput.OnEnterKey = () => LoadAsset(filenameInput.Text); + var frameContainer = panel.GetOrNull("FRAME_SELECTOR"); + if (frameContainer != null) + frameContainer.IsVisible = () => currentSprites != null && currentSprites.Length > 1; + frameSlider = panel.Get("FRAME_SLIDER"); - frameSlider.MaximumValue = (float)spriteWidget.FrameCount; - frameSlider.Ticks = spriteWidget.FrameCount + 1; - frameSlider.IsVisible = () => spriteWidget.FrameCount > 0; - frameSlider.OnChange += x => { spriteWidget.Frame = (int)Math.Round(x); }; - frameSlider.GetValue = () => spriteWidget.Frame; + frameSlider.OnChange += x => { currentFrame = (int)Math.Round(x); }; + frameSlider.GetValue = () => currentFrame; - panel.Get("FRAME_COUNT").GetText = () => "{0} / {1}".F(spriteWidget.Frame + 1, spriteWidget.FrameCount + 1); + var frameText = panel.GetOrNull("FRAME_COUNT"); + if (frameText != null) + frameText.GetText = () => "{0} / {1}".F(currentFrame + 1, currentSprites.Length); - playButton = panel.Get("BUTTON_PLAY"); - playButton.OnClick = () => + var playButton = panel.GetOrNull("BUTTON_PLAY"); + if (playButton != null) { - spriteWidget.LoopAnimation = true; - playButton.Visible = false; - pauseButton.Visible = true; - }; - pauseButton = panel.Get("BUTTON_PAUSE"); - pauseButton.OnClick = () => - { - spriteWidget.LoopAnimation = false; - playButton.Visible = true; - pauseButton.Visible = false; - }; + playButton.OnClick = () => animateFrames = true; + playButton.IsVisible = () => !animateFrames; + } - panel.Get("BUTTON_STOP").OnClick = () => + var pauseButton = panel.GetOrNull("BUTTON_PAUSE"); + if (pauseButton != null) { - spriteWidget.LoopAnimation = false; - frameSlider.Value = 0; - spriteWidget.Frame = 0; - playButton.Visible = true; - pauseButton.Visible = false; - }; + pauseButton.OnClick = () => animateFrames = false; + pauseButton.IsVisible = () => animateFrames; + } - panel.Get("BUTTON_NEXT").OnClick = () => { spriteWidget.RenderNextFrame(); }; - panel.Get("BUTTON_PREV").OnClick = () => { spriteWidget.RenderPreviousFrame(); }; - - panel.Get("LOAD_BUTTON").OnClick = () => + var stopButton = panel.GetOrNull("BUTTON_STOP"); + if (stopButton != null) { - LoadAsset(filenameInput.Text); - }; + stopButton.OnClick = () => + { + frameSlider.Value = 0; + currentFrame = 0; + animateFrames = false; + }; + } + + var nextButton = panel.GetOrNull("BUTTON_NEXT"); + if (nextButton != null) + nextButton.OnClick = SelectNextFrame; + + var prevButton = panel.GetOrNull("BUTTON_PREV"); + if (prevButton != null) + prevButton.OnClick = SelectPreviousFrame; + + var loadButton = panel.GetOrNull("LOAD_BUTTON"); + if (loadButton != null) + loadButton.OnClick = () => LoadAsset(filenameInput.Text); assetList = panel.Get("ASSET_LIST"); template = panel.Get("ASSET_TEMPLATE"); PopulateAssetList(); - panel.Get("CLOSE_BUTTON").OnClick = () => { Ui.CloseWindow(); onExit(); }; + var closeButton = panel.GetOrNull("CLOSE_BUTTON"); + if (closeButton != null) + closeButton.OnClick = () => { Ui.CloseWindow(); onExit(); }; + } + + void SelectNextFrame() + { + currentFrame++; + if (currentFrame >= currentSprites.Length) + currentFrame = 0; + } + + void SelectPreviousFrame() + { + currentFrame--; + if (currentFrame < 0) + currentFrame = currentSprites.Length - 1; } void AddAsset(ScrollPanelWidget list, string filepath, ScrollItemWidget template) { var filename = Path.GetFileName(filepath); var item = ScrollItemWidget.Setup(template, - () => spriteWidget.Image == filename, + () => currentFilename == filename, () => { filenameInput.Text = filename; LoadAsset(filename); }); item.Get("TITLE").GetText = () => filepath; @@ -143,10 +191,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic if (!FileSystem.Exists(filename)) return false; - spriteWidget.Frame = 0; - spriteWidget.Image = filename; - frameSlider.MaximumValue = (float)spriteWidget.FrameCount; - frameSlider.Ticks = spriteWidget.FrameCount + 1; + currentFilename = filename; + currentSprites = Game.modData.SpriteLoader.LoadAllSprites(filename); + currentFrame = 0; + frameSlider.MaximumValue = (float)currentSprites.Length - 1; + frameSlider.Ticks = currentSprites.Length; + return true; } @@ -196,10 +246,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic { Func setupItem = (palette, itemTemplate) => { + var name = palette.Name; var item = ScrollItemWidget.Setup(itemTemplate, - () => currentPalette.Name == palette.Name, - () => { currentPalette = palette; spriteWidget.Palette = currentPalette.Name; }); - item.Get("LABEL").GetText = () => palette.Name; + () => currentPalette == name, + () => currentPalette = name); + item.Get("LABEL").GetText = () => name; + return item; }; diff --git a/mods/cnc/chrome/assetbrowser.yaml b/mods/cnc/chrome/assetbrowser.yaml index 6cce12007f..73cb7518d3 100644 --- a/mods/cnc/chrome/assetbrowser.yaml +++ b/mods/cnc/chrome/assetbrowser.yaml @@ -5,6 +5,7 @@ Container@ASSETBROWSER_PANEL: Width:695 Height:435 Children: + LogicTicker@ANIMATION_TICKER: ColorPreviewManager@COLOR_MANAGER: Label@ASSETBROWSER_TITLE: Width:PARENT_RIGHT @@ -63,7 +64,6 @@ Container@ASSETBROWSER_PANEL: Y:365 Width:160 Height:25 - Text:mouse2.shp Button@LOAD_BUTTON: X:15 Y:395 @@ -104,10 +104,9 @@ Container@ASSETBROWSER_PANEL: Height:325 Background:scrollpanel-bg Children: - ShpImage@SPRITE: + Sprite@SPRITE: Width:PARENT_RIGHT Height:PARENT_BOTTOM - Image:mouse2 Container@FRAME_SELECTOR: X:190 Y:395 diff --git a/mods/ra/chrome/assetbrowser.yaml b/mods/ra/chrome/assetbrowser.yaml index bf01849800..ace25b9e70 100644 --- a/mods/ra/chrome/assetbrowser.yaml +++ b/mods/ra/chrome/assetbrowser.yaml @@ -5,6 +5,7 @@ Background@ASSETBROWSER_PANEL: Width:700 Height:500 Children: + LogicTicker@ANIMATION_TICKER: ColorPreviewManager@COLOR_MANAGER: Label@ASSETBROWSER_TITLE: Y:20 @@ -58,7 +59,6 @@ Background@ASSETBROWSER_PANEL: Y:395 Width:160 Height:25 - Text:mouse.shp Button@LOAD_BUTTON: X:20 Y:425 @@ -99,10 +99,9 @@ Background@ASSETBROWSER_PANEL: Height:330 Background:dialog3 Children: - ShpImage@SPRITE: + Sprite@SPRITE: Width:PARENT_RIGHT Height:PARENT_BOTTOM - Image:mouse Container@FRAME_SELECTOR: X:190 Y:425