Skip to content

Commit

Permalink
refactor(Studio): Rework MarkDown display for changelogs
Browse files Browse the repository at this point in the history
  • Loading branch information
psyGamer committed Oct 27, 2024
1 parent 56e4927 commit 1bf113a
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 4 deletions.
32 changes: 28 additions & 4 deletions .github/workflows/Build.CelesteStudio.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ jobs:
run: sed -i "s/-dev/-$(git rev-parse --short HEAD)/" Studio/CelesteStudio/Studio.cs
if: ${{ inputs.build-cfg == 'Debug' }}

- name: Download changelog
- name: Download changelogs
uses: actions/download-artifact@v4
with:
pattern: changelog-studio
pattern: changelog-*
if: ${{ inputs.build-cfg == 'Release' }}
- name: Move changelog into Assets
run: mv changelog-studio/studio_changelog.md Studio/CelesteStudio/Assets/Changelog.md
- name: Move changelogs into Assets
run: |
mv changelog-version/version_info.txt Studio/CelesteStudio/Assets/VersionInfo.txt
mv changelog-studio/studio_changelog.md Studio/CelesteStudio/Assets/Changelog.md
if: ${{ inputs.build-cfg == 'Release' }}

- name: Publish x64
Expand Down Expand Up @@ -76,6 +78,17 @@ jobs:
run: sed -i "s/-dev/-$(git rev-parse --short HEAD)/" Studio/CelesteStudio/Studio.cs
if: ${{ inputs.build-cfg == 'Debug' }}

- name: Download changelogs
uses: actions/download-artifact@v4
with:
pattern: changelog-*
if: ${{ inputs.build-cfg == 'Release' }}
- name: Move changelogs into Assets
run: |
mv changelog-version/version_info.txt Studio/CelesteStudio/Assets/VersionInfo.txt
mv changelog-studio/studio_changelog.md Studio/CelesteStudio/Assets/Changelog.md
if: ${{ inputs.build-cfg == 'Release' }}

- name: Publish x64
run: dotnet publish Studio/CelesteStudio.GTK -c ${{ inputs.build-cfg }} -r linux-x64 --output build-x64

Expand Down Expand Up @@ -118,6 +131,17 @@ jobs:
run: zsh -c "sed -i '' -e "s/-dev/-$(git rev-parse --short HEAD)/" Studio/CelesteStudio/Studio.cs"
if: ${{ inputs.build-cfg == 'Debug' }}

- name: Download changelogs
uses: actions/download-artifact@v4
with:
pattern: changelog-*
if: ${{ inputs.build-cfg == 'Release' }}
- name: Move changelogs into Assets
run: |
mv changelog-version/version_info.txt Studio/CelesteStudio/Assets/VersionInfo.txt
mv changelog-studio/studio_changelog.md Studio/CelesteStudio/Assets/Changelog.md
if: ${{ inputs.build-cfg == 'Release' }}

- name: Publish x64
run: dotnet publish Studio/CelesteStudio.Mac -c ${{ inputs.build-cfg }} -r osx-x64 --output build-x64
- name: Publish ARM64
Expand Down
8 changes: 8 additions & 0 deletions Studio/CelesteStudio/Assets/Changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Features
- Cool new stuff
- oadw wdwj ijoiw jdwi
- dwij wdjiow oiwjoi jdwoij idwi djwoij
- aoiwjdj woidjw iwdoidj wij idwji djwio jdwoij iojwd jwioj dowjoi jwoidjwi jwidijwoidjwoi jiowj dwjoidjwji jwdj iwjd woijdiwoj iwjo jwdij woidjwoi

## Bug Fixes
- Hallo Welt hihihi ha
2 changes: 2 additions & 0 deletions Studio/CelesteStudio/Assets/VersionInfo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
v3.41.5
v3.4.0
3 changes: 3 additions & 0 deletions Studio/CelesteStudio/CelesteStudio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@

<!-- Changelogs -->
<ItemGroup>
<EmbeddedResource Condition="Exists('Assets\VersionInfo.txt')" Include="Assets\VersionInfo.txt" LogicalName="VersionInfo.txt"/>
<EmbeddedResource Condition="Exists('Assets\Changelog.md')" Include="Assets\Changelog.md" LogicalName="Changelog.md"/>

<EmbeddedResource Include="Assets\Changelogs\v3.0.0.md" LogicalName="Changelogs/v3.0.0.md"/>
<EmbeddedResource Include="Assets\Changelogs\v3.0.0\*.png" LogicalName="Changelogs/v3.0.0/%(Filename).png"/>

Expand Down
149 changes: 149 additions & 0 deletions Studio/CelesteStudio/Dialog/ChangelogDialog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
using CelesteStudio.Controls;
using CelesteStudio.Util;
using Eto.Drawing;
using Eto.Forms;
using SkiaSharp;
using StudioCommunication.Util;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace CelesteStudio.Dialog;

public class ChangelogDialog : Eto.Forms.Dialog {

private class ContentDrawable(string title, Dictionary<string, List<string>> categories) : SkiaDrawable {
private static SKColorF TextColor => Eto.Platform.Instance.IsWpf && Settings.Instance.Theme.DarkMode
? new SKColorF(1.0f - SystemColors.ControlText.R, 1.0f - SystemColors.ControlText.G, 1.0f - SystemColors.ControlText.B)
: SystemColors.ControlText.ToSkia();

protected override void Draw(PaintEventArgs e, SKSurface surface, SKImageInfo info) {
surface.Canvas.Clear();

var textColor = TextColor;

using var titleFont = new SKFont(SKFontManager.Default.MatchTypeface(SKTypeface.Default, SKFontStyle.Bold), 28.0f);
using var titlePaint = new SKPaint(titleFont);
titlePaint.ColorF = textColor;
titlePaint.IsAntialias = true;
titlePaint.TextAlign = SKTextAlign.Center;

using var headingFont = new SKFont(SKTypeface.Default, 24.0f);
using var headingPaint = new SKPaint(headingFont);
headingPaint.ColorF = textColor;
headingPaint.IsAntialias = true;

using var entryFont = new SKFont(SKTypeface.Default, 13.0f);
using var entryPaint = new SKPaint(entryFont);
entryPaint.ColorF = textColor;
entryPaint.IsAntialias = true;

float yOffset = 0.0f;
// Title
foreach (string line in WrapLines(title, Width, titlePaint)) {
surface.Canvas.DrawText(line, Width / 2.0f, yOffset + titleFont.Offset(), titlePaint);
yOffset += titleFont.LineHeight();
}
yOffset += titleFont.LineHeight() * 0.25f;
surface.Canvas.DrawLine(0.0f, yOffset, Width, yOffset, titlePaint);
yOffset += titleFont.LineHeight() * 0.5f;

foreach ((string categoryName, var entries) in categories) {
// Heading
foreach (string line in WrapLines(categoryName, Width, headingPaint)) {
surface.Canvas.DrawText(line, 0.0f, yOffset + headingFont.Offset(), headingPaint);
yOffset += headingFont.LineHeight();
}
yOffset += headingFont.LineHeight() * 0.5f;

// Entries
foreach (string entry in entries) {
surface.Canvas.DrawCircle(10.0f, yOffset + entryFont.LineHeight() / 2.0f, 2.5f, entryPaint);

foreach (string line in WrapLines(entry, Width, entryPaint)) {
surface.Canvas.DrawText(line, 20.0f, yOffset + entryFont.Offset(), entryPaint);
yOffset += entryFont.LineHeight();
}
}

yOffset += headingFont.LineHeight() * 0.5f;
}

Height = (int)yOffset;
}

// Doesn't use SKPaint.BreakText(), since that doesn't respect word boundaries
private IEnumerable<string> WrapLines(string longLine, float maxWidth, SKPaint textPaint) {
float lineLength = 0.0f;
var line = new StringBuilder();

foreach (string word in longLine.Split(' ')) {
string wordWithSpace = word + " ";
float wordWithSpaceLength = textPaint.MeasureText(wordWithSpace);

if (lineLength + wordWithSpaceLength > maxWidth) {
yield return line.ToString();
line.Clear();
line.Append(wordWithSpace);
lineLength = wordWithSpaceLength;
} else {
line.Append(wordWithSpace);
lineLength += wordWithSpaceLength;
}
}

if (line.Length != 0) {
yield return line.ToString();
}
}
}

private ChangelogDialog(string title, IEnumerable<string> changelogLines) {
// Parse changelog information, generated by Scripts/generate_release.py
const string categoryPrefix = "## ";
const string entryPrefix = "- ";

Dictionary<string, List<string>> categories = [];
List<string> currentEntries = [];

foreach (string line in changelogLines) {
if (line.StartsWith(categoryPrefix)) {
categories[line[categoryPrefix.Length..].Trim()] = currentEntries = [];
} else if (line.StartsWith(entryPrefix)) {
currentEntries.Add(line[entryPrefix.Length..].Trim());
}
}

Title = $"What's new in {title}?";
Content = new Scrollable {
Content = new ContentDrawable(title, categories),
Padding = new Padding(20, 10),
Border = BorderType.None,
};
Padding = 0;
MinimumSize = new Size(400, 300);
Size = new Size(800, 600);

Resizable = true;

Studio.RegisterDialog(this);
}

public static void Show() {
using var versionInfoData = Assembly.GetExecutingAssembly().GetManifestResourceStream("VersionInfo.txt");
using var changelogData = Assembly.GetExecutingAssembly().GetManifestResourceStream("Changelog.md");
if (versionInfoData == null || changelogData == null) {
return;
}

using var versionInfoReader = new StreamReader(versionInfoData);
using var changelogReader = new StreamReader(changelogData);

string[] versions = versionInfoReader.ReadToEnd().SplitLines().ToArray();
string title = $"CelesteTAS {versions[0]} / Studio {versions[1]}";

new ChangelogDialog(title, changelogReader.ReadToEnd().SplitLines()).ShowModal();
}
}

0 comments on commit 1bf113a

Please sign in to comment.