Skip to content

Commit

Permalink
Files view- first draft for having a files view
Browse files Browse the repository at this point in the history
  • Loading branch information
tzachshabtay committed Jan 23, 2019
1 parent 7a04a56 commit 7afdf14
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 5 deletions.
218 changes: 218 additions & 0 deletions Source/Editor/AGS.Editor/Components/FileSelector/FilesView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AGS.API;
using AGS.Engine;

namespace AGS.Editor
{
[RequiredComponent(typeof(IInventoryWindowComponent))]
public class FilesView : AGSComponent
{
private IInventoryWindowComponent _invWindow;
private string _folder;
private ITextConfig _textConfig, _hoverTextConfig;
private ButtonAnimation _labelIdle, _labelHover, _iconIdle, _iconHover;
private readonly IFileSystem _files;
private readonly IGameFactory _factory;

private string[] imageSuffixes = { ".png", ".jpg", ".jpeg", ".gif", ".bmp" };
private string[] audioSuffixes = { ".wav", ".ogg", ".flac" };

public FilesView(IFileSystem files, IGameFactory factory)
{
_files = files;
_factory = factory;
configureTextConfig();
}

public override void Init()
{
base.Init();
Entity.Bind<IInventoryWindowComponent>(c => { _invWindow = c; configureInvWindow(); refreshInvWindow(); }, _ => _invWindow = null);
}

public string Folder
{
get => _folder;
set
{
_folder = value;
refreshInvWindow();
}
}

private void configureInvWindow()
{
}

private void configureTextConfig()
{
var textConfig = AGSTextConfig.Clone(GameViewColors.TextboxTextConfig);
textConfig.Alignment = Alignment.MiddleCenter;
textConfig.Font = _factory.Fonts.LoadFont(textConfig.Font.FontFamily, 8f, FontStyle.Regular);
textConfig.AutoFit = AutoFit.TextShouldWrapAndLabelShouldFitHeight;
textConfig.PaddingRight = 10f;
_textConfig = textConfig;
_hoverTextConfig = AGSTextConfig.ChangeColor(textConfig, GameViewColors.HoveredText, Colors.White, 0f);

_labelIdle = new ButtonAnimation(null, _textConfig, null);
_labelHover = new ButtonAnimation(null, _hoverTextConfig, null);
_iconIdle = new ButtonAnimation(null, FontIcons.LargeIconConfig, null);
_iconHover = new ButtonAnimation(null, FontIcons.LargeIconConfigHovered, null);
}

private async void refreshInvWindow()
{
var folder = _folder;
var invWindow = _invWindow;
if (folder == null || invWindow == null) return;
var files = await Task.Run(() => _files.GetFiles(folder));
foreach (var file in files)
{
IObject graphics = await getGraphics(file);
var item = _factory.Inventory.GetInventoryItem(graphics, graphics);
invWindow.Inventory.Items.Add(item);
}
}

private Task<IObject> getGraphics(string file)
{
if (imageSuffixes.Any(file.EndsWith))
{
return getImage(file);
}
if (audioSuffixes.Any(file.EndsWith))
{
return getAudio(file);
}
return getFile(file);
}

private async Task<IObject> getImage(string file)
{
const float padding = 50f;
file = Path.GetFullPath(file);
var size = _invWindow.ItemSize;
var image = await _factory.Graphics.LoadImageAsync(file);
var obj = _factory.UI.GetPanel($"File_{file}", image, 0f, 0f, Entity as IObject);
obj.Enabled = true;
obj.ClickThrough = false;
obj.IsPixelPerfect = false;
obj.CurrentSprite.Pivot = (0.5f, 1f);
obj.CurrentSprite.ScaleTo(size.Width - padding, size.Height - padding);
obj.CurrentSprite.Y = -padding / 2f;
var label = _factory.UI.GetLabel($"FileLabel_{file}", getFileDisplayName(file),
size.Width, 1f, -size.Width / 2f, -size.Height + 5f, obj, _textConfig);
label.Enabled = true;
Action onHover = () => obj.CurrentSprite.ScaleTo(size.Width - padding/2f, size.Height - padding/2f);
Action onLeave = () => obj.CurrentSprite.ScaleTo(size.Width - padding, size.Height - padding);
HoverEffect.Add(onHover, onLeave, (obj, null, null), (label, _labelIdle, _labelHover));
return obj;
}

private async Task<IObject> getAudio(string file)
{
await Task.Yield();
var size = _invWindow.ItemSize;
var icon = _factory.UI.GetLabel($"File_{file}", "", size.Width, size.Height, 0f, 0f, Entity as IObject,
AGSTextConfig.Clone(FontIcons.LargeIconConfig));
icon.Text = FontIcons.AudioFile;
icon.IsPixelPerfect = false;
icon.Enabled = true;
icon.Pivot = (0.5f, 1f);
var label = _factory.UI.GetLabel($"FileLabel_{file}", getFileDisplayName(file),
size.Width, 1f, size.Width / 2f, 20f, icon, _textConfig);
label.Pivot = (0.5f, 1f);

var idleConfig = AGSTextConfig.ChangeColor(FontIcons.ButtonConfig, GameViewColors.Button, Colors.White, 0f);
var idle = new ButtonAnimation(null, idleConfig, Colors.Transparent);
var hover = new ButtonAnimation(null, AGSTextConfig.ChangeColor(FontIcons.ButtonConfig, Colors.DarkOrange, Colors.White, 0f), null);
var pushed = new ButtonAnimation(null, AGSTextConfig.ChangeColor(FontIcons.ButtonConfig, GameViewColors.PushedButton, Colors.White, 0f), null);
var playButton = _factory.UI.GetButton($"AudioButtin_{file}", idle, hover, pushed,
size.Width / 2f, size.Height / 2f - 10f, icon, width: size.Width / 6f, height: size.Height / 6f);
playButton.Text = FontIcons.Play;
playButton.Pivot = new PointF(0.5f, 0.5f);
playButton.Visible = false;
IAudioClip clip = null;
ISound sound = null;
TaskCompletionSource<object> tcs = null;
Action onPlayPause = async () =>
{
playButton.Text = playButton.Text == FontIcons.Play ? FontIcons.Pause : FontIcons.Play;
if (tcs == null)
{
tcs = new TaskCompletionSource<object>();
clip = await _factory.Sound.LoadAudioClipAsync(Path.GetFullPath(file), $"tmp_{file}");
tcs.TrySetResult(null);
}
else await tcs.Task;
if (playButton.Text == FontIcons.Play)
{
sound?.Pause();
}
else
{
if (sound == null) sound = clip.Play(true);
else sound.Resume();
}

};
playButton.MouseClicked.Subscribe(onPlayPause);

Action onHover = () => { icon.Text = FontIcons.File; playButton.Visible = true; };
Action onLeave = () => { if (tcs != null) return; icon.Text = FontIcons.AudioFile; playButton.Visible = false; };
HoverEffect.Add(onHover, onLeave, (icon, _iconIdle, _iconHover), (label, _labelIdle, _labelHover), (playButton, null, null));
return icon;
}

private async Task<IObject> getFile(string file)
{
await Task.Yield();
var size = _invWindow.ItemSize;
var icon = _factory.UI.GetLabel($"File_{file}", "", size.Width, size.Height, 0f, 0f, Entity as IObject,
FontIcons.LargeIconConfig);
icon.Text = FontIcons.File;
icon.IsPixelPerfect = false;
icon.Enabled = true;
icon.Pivot = (0.5f, 1f);
var label = _factory.UI.GetLabel($"FileLabel_{file}", getFileDisplayName(file),
size.Width, 1f, size.Width / 2f, 20f, icon, _textConfig);
label.Pivot = (0.5f, 1f);
HoverEffect.Add((icon, _iconIdle, _iconHover), (label, _labelIdle, _labelHover));
return icon;
}

private string getFileDisplayName(string file)
{
file = Path.GetFileName(file);
StringBuilder sb = new StringBuilder(file.Length * 2);
int index = 0;
const int lineLength = 16;
const int keepingSuffix = 8;
const int trimStart = lineLength + keepingSuffix + 1;
foreach (var c in file)
{
index++;
if (index == lineLength + 1)
{
sb.Append(' '); //Adding spaces as System.Drawing only seems to support word-wrap
}
if (index == trimStart && file.Length > lineLength)
{
sb.Append("...");
continue;
}
if (index > trimStart && file.Length > lineLength && index < file.Length - keepingSuffix)
{
continue;
}
sb.Append(c);
}
return sb.ToString();
}
}
}
13 changes: 13 additions & 0 deletions Source/Editor/AGS.Editor/Skins/FontIcons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,20 @@ public static void Init(IFontFactory fontLoader)
paddingLeft: -1f, paddingTop: 0f, paddingBottom: 0f, paddingRight: 0f, outlineWidth: 1f);

TinyButtonConfigHovered = AGSTextConfig.ChangeColor(TinyButtonConfig, Colors.Black, Colors.White, 0f);

var largeFont = fontLoader.LoadFontFromPath(path, 56f, FontStyle.Regular);
LargeIconConfig = fontLoader.GetTextConfig(font: largeFont, autoFit: AutoFit.TextShouldFitLabel, alignment: Alignment.MiddleCenter,
paddingLeft: -1f, paddingTop: 0f, paddingBottom: 0f, paddingRight: 0f, outlineWidth: 1f);

LargeIconConfigHovered = AGSTextConfig.ChangeColor(LargeIconConfig, GameViewColors.HoveredText, Colors.White, 0f);
}

public static IFont Font { get; private set; }

public static ITextConfig LargeIconConfig { get; private set; }

public static ITextConfig LargeIconConfigHovered { get; private set; }

public static ITextConfig IconConfig { get; private set; }

public static ITextConfig ButtonConfig { get; private set; }
Expand Down Expand Up @@ -63,5 +73,8 @@ public static void Init(IFontFactory fontLoader)

public const string Folder = "\uf07b";
public const string FolderOpen = "\uf07c";

public const string File = "\uf15b";
public const string AudioFile = "\uf1c7";
}
}
48 changes: 46 additions & 2 deletions Source/Engine/AGS.Engine/Graphics/Effects/HoverEffect.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using AGS.API;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using AGS.API;

namespace AGS.Engine
{
Expand All @@ -11,5 +14,46 @@ public static void Add(IObject obj, Color idleTint, Color hoverTint)
uiEvents.MouseEnter.Subscribe(_ => obj.Tint = hoverTint);
uiEvents.MouseLeave.Subscribe(_ => obj.Tint = idleTint);
}
}

public static void Add(params (IObject obj, ButtonAnimation idle, ButtonAnimation hover)[] effects)
{
Add(null, null, effects);
}

public static void Add(Action onEnter, Action onLeave, params (IObject obj, ButtonAnimation idle, ButtonAnimation hover)[] effects)
{
int numHovered = 0;
foreach (var (obj, idle, _) in effects)
{
idle?.StartAnimation(obj);
var uiEvents = obj.AddComponent<IUIEvents>();
uiEvents.MouseEnter.Subscribe(_ =>
{
numHovered++;
foreach (var (o, _, hover) in effects)
{
hover?.StartAnimation(o);
}
onEnter?.Invoke();
});
uiEvents.MouseLeave.Subscribe(async _ =>
{
numHovered--;
Trace.Assert(numHovered >= 0);
if (numHovered == 0)
{
await Task.Delay(10);
if (numHovered == 0)
{
foreach (var (o, i, _) in effects)
{
i?.StartAnimation(o);
}
onLeave?.Invoke();
}
}
});
}
}
}
}
2 changes: 2 additions & 0 deletions Source/Engine/AGS.Engine/Misc/Utils/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ public static SizeF GetTextSize(this ITextConfig config, string text, SizeF labe
}
}

public static void StartAnimation(this ButtonAnimation button, IObject obj) => button.StartAnimation(obj, obj.GetComponent<ITextComponent>(), obj, obj);

public static void StartAnimation(this ButtonAnimation button, IAnimationComponent animationComponent,
ITextComponent textComponent, IImageComponent imageComponent, IBorderComponent borderComponent)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private void onRepeatedlyExecute()
obj.Visible = true;

x += stepX;
if (x >= _scale.Width)
if (x + stepX/2f >= _scale.Width)
{
x = stepX/2f;
y -= stepY;
Expand All @@ -147,5 +147,4 @@ private bool isRefreshNeeded()
return false;
}
}
}

}

0 comments on commit 7afdf14

Please sign in to comment.