1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 20:42:21 +02:00

BMP loading, show workspace icon files on startup panel

This commit is contained in:
Brian Fiete 2025-02-01 10:39:04 -08:00
parent c8394bef26
commit 05cda98c85
11 changed files with 725 additions and 4 deletions

View file

@ -1,3 +1,5 @@
#pragma warning disable 168
using System;
using System.IO;
using System.Collections;
@ -9,6 +11,7 @@ using IDE.util;
using Beefy.events;
using Beefy.theme;
using System.Diagnostics;
using Beefy.utils;
namespace IDE.ui
{
@ -17,6 +20,7 @@ namespace IDE.ui
class RecentWorkspacesScrollWidget : ScrollableWidget
{
public Font mTitleFont;
public bool mHasIcons;
public this()
{
@ -31,7 +35,7 @@ namespace IDE.ui
public override void Resize(float x, float y, float width, float height)
{
const float MARGIN = 3;
const float MARGIN = 0;
float currentY = 0;
float fillWidth = width - (mVertScrollbar?.Width).GetValueOrDefault();
@ -40,7 +44,7 @@ namespace IDE.ui
{
for (let widget in mScrollContent.mChildWidgets)
{
widget.Resize(0, currentY, fillWidth, GS!(30));
widget.Resize(0, currentY, fillWidth, GS!(33));
currentY += widget.Height + MARGIN;
}
}
@ -60,7 +64,7 @@ namespace IDE.ui
g.SetFont(mTitleFont);
using (g.PushColor(gApp.mSettings.mUISettings.mColors.mText))
g.DrawString("Recent Workspaces", 0, GS!(-30), .Centered, mWidth, .Ellipsis);
g.DrawString("Recent Workspaces", GS!(2), GS!(-30), .Centered, mWidth - GS!(4), .Ellipsis);
base.Draw(g);
}
@ -70,6 +74,8 @@ namespace IDE.ui
{
public static Font s_Font;
append String mPath;
public bool mTriedLoadIcon;
public Image mIcon ~ delete _;
public bool mPinned;
public RecentWorkspacesScrollWidget mRecentsParent;
@ -91,9 +97,67 @@ namespace IDE.ui
}
if (!mTriedLoadIcon)
{
mTriedLoadIcon = true;
StructuredData sd = scope .();
if (sd.Load(scope $"{mPath}/BeefProj.toml") case .Ok)
{
using (sd.Open("Platform"))
{
using (sd.Open("Windows"))
{
var iconFileName = sd.GetString("IconFile", .. scope .());
iconFileName.Replace("$(ProjectDir)", mPath);
iconFileName.Replace("$(WorkspaceDir)", mPath);
var iconFilePath = IO.Path.GetAbsolutePath(iconFileName, mPath, .. scope .());
if (File.Exists(iconFilePath))
{
int wantSize = 32;
if (var image = ResourceGen.LoadIcon(iconFilePath, wantSize))
{
if ((image.mWidth != wantSize) || (image.mHeight != wantSize))
{
image.Scale(wantSize / Math.Max(image.mWidth, image.mHeight));
}
mIcon = image;
mRecentsParent.mHasIcons = true;
}
}
}
}
}
}
g.SetFont(s_Font);
using (g.PushColor(gApp.mSettings.mUISettings.mColors.mText))
g.DrawString(mPath, 10, 0, .Left, mWidth - 10);
{
String drawStr = scope String();
int lastSlash = Math.Max(mPath.LastIndexOf('\\'), mPath.LastIndexOf('/'));
if (lastSlash != -1)
{
drawStr.Append(Font.EncodeColor(0x80FFFFFF));
drawStr.Append(mPath.Substring(0, lastSlash + 1));
drawStr.Append(Font.EncodePopColor());
drawStr.Append(mPath.Substring(lastSlash + 1));
}
else
{
drawStr.Append(mPath);
}
float drawX = GS!(50);
g.DrawString(drawStr, drawX, GS!(3), .Left, mWidth - drawX - GS!(2), .Ellipsis);
}
if (mIcon != null)
g.DrawCentered(mIcon, GS!(24), mHeight / 2);
else
{
using (g.PushColor(0x80FFFFFF))
g.DrawCentered(DarkTheme.sDarkTheme.GetImage(.Workspace), GS!(24), mHeight / 2);
}
}
public override void MouseEnter()

View file

@ -1,8 +1,12 @@
#pragma warning disable 168
using System;
using System.IO;
using System.Collections;
using System.Text;
using System.Diagnostics;
using Beefy.gfx;
namespace IDE.util
{
class ResourceGen
@ -62,6 +66,60 @@ namespace IDE.util
FileStream mOutStream = new FileStream() ~ delete _;
public static Result<Image> LoadIcon(String iconFile, int wantSize = -1)
{
FileStream stream = scope FileStream();
if (stream.Open(iconFile, .Read) case .Err)
{
return .Err;
}
let iconDir = Try!(stream.Read<IconDir>());
if ((iconDir.mReserved != 0) || (iconDir.mType != 1) || (iconDir.mCount > 0x100))
{
return .Err;
}
var entries = scope List<IconDirectoryEntry>();
for (int idx < iconDir.mCount)
{
entries.Add(Try!(stream.Read<IconDirectoryEntry>()));
}
int bestIdx = iconDir.mCount - 1;
for (int idx < iconDir.mCount)
{
let iconEntry = ref entries[idx];
if (iconEntry.mWidth >= wantSize)
{
bestIdx = idx;
break;
}
}
let iconEntry = ref entries[bestIdx];
Try!(stream.Seek(iconEntry.mImageOffset));
if (iconEntry.mBytesInRes > 1024*1024)
{
return .Err;
}
uint8* data = new:ScopedAlloc! uint8[iconEntry.mBytesInRes]*;
Try!(stream.TryRead(.(data, iconEntry.mBytesInRes)));
String bmpPath = scope $"@{(int)(void*)data:X}:{iconEntry.mBytesInRes}.bmp";
var image = Image.LoadFromFile(bmpPath);
if (image != null)
return image;
return .Err;
}
public Result<void> AddIcon(String iconFile)
{
if (!iconFile.EndsWith(".ico", .OrdinalIgnoreCase))