SteamAchievementManager主题定制:打造个性化视觉体验

SteamAchievementManager主题定制:打造个性化视觉体验

【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 【免费下载链接】SteamAchievementManager 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager

Steam Achievement Manager(以下简称SAM)作为一款开源的Steam成就管理工具,默认提供了简洁的黑色主题界面。然而对于长期使用的玩家而言,单一的视觉风格可能导致审美疲劳。本文将系统讲解如何通过资源替换、样式修改和高级定制等方式,打造完全个性化的SAM视觉体验,涵盖从基础图标替换到深度主题定制的完整流程。

主题定制基础:界面构成分析

SAM的用户界面主要由Manager类(SAM.Game/Manager.cs)和对应的设计文件(Manager.Designer.cs)控制。通过分析源码可知,应用采用了Windows Forms框架构建,界面元素主要包括:

  • 核心容器组件_MainTabControl(主选项卡)、_AchievementsTabPage(成就选项卡)、_StatisticsTabPage(统计选项卡)
  • 列表控件_AchievementListView(成就列表,继承自DoubleBufferedListView
  • 工具栏_MainToolStrip(主工具栏)、_AchievementsToolStrip(成就工具栏)
  • 状态栏_MainStatusStrip(包含_GameStatusLabel_DownloadStatusLabel

界面渲染流程

mermaid

关键样式定义在Manager.Designer.csInitializeComponent方法中,例如成就列表的默认样式:

this._AchievementListView.BackColor = System.Drawing.Color.Black;
this._AchievementListView.ForeColor = System.Drawing.Color.White;
this._AchievementListView.GridLines = true;

初级定制:资源文件替换

最简单的定制方式是替换程序使用的图标和图片资源。SAM将所有UI资源集中存储在SAM.Game/Resources目录下,包含以下关键文件:

Resources/
├── arrow-circle-double.png   # 箭头图标
├── reset-icon.png            # 重置按钮图标
├── download-cloud.png        # 下载状态图标
├── lock--pencil.png          # 锁定图标
├── lock-unlock.png           # 解锁图标
├── lock.png                  # 锁定状态图标
├── poop-smiley-sad-enlarged.png # 错误图标
├── poop-smiley-sad.png       # 警告图标
└── transmitter.png           # 传输图标

替换步骤

  1. 准备替换资源:创建尺寸和格式相同的PNG图片(建议保持原名)
  2. 编译资源文件:通过Visual Studio的资源设计器或手动编辑Resources.resx文件
  3. 验证资源引用:确保工具栏按钮正确引用新资源,如锁定按钮:
this._LockAllButton.Image = global::SAM.Game.Resources.Lock;

批量替换脚本

对于需要频繁更换主题的用户,可以创建批处理脚本自动替换资源文件:

#!/bin/bash
# theme_apply.sh - 应用自定义主题资源

# 备份原始资源
mkdir -p Resources_backup
cp SAM.Game/Resources/*.png Resources_backup/

# 复制新主题资源
cp custom_theme/*.png SAM.Game/Resources/

# 重新构建项目
dotnet build SAM.sln

中级定制:颜色方案修改

SAM的界面颜色主要通过代码直接设置,要修改颜色方案需调整Manager.Designer.cs中的相关属性。以下是关键控件的颜色定义位置及修改建议:

主要界面元素定制

控件名称默认颜色设置修改建议
_AchievementListViewBackColor = Color.Black
ForeColor = Color.White
改为深色主题:#1E1E1E背景,#D4D4D4前景
_StatisticsDataGridView默认系统样式设置BackgroundColorForegroundColor属性
_MainToolStrip系统默认工具栏样式通过Renderer属性自定义绘制
_MainStatusStrip系统默认状态栏样式设置BackColorForeColor属性

实现深色主题的代码修改

打开Manager.Designer.cs,找到InitializeComponent方法,修改以下部分:

// 修改成就列表颜色
this._AchievementListView.BackColor = Color.FromArgb(30, 30, 30);  // 深灰背景
this._AchievementListView.ForeColor = Color.FromArgb(212, 212, 212); // 浅灰文字
this._AchievementListView.GridLines = true;
this._AchievementListView.GridLineColor = Color.FromArgb(60, 60, 60); // 灰色网格线

// 修改数据表格颜色
this._StatisticsDataGridView.BackgroundColor = Color.FromArgb(30, 30, 30);
this._StatisticsDataGridView.ForeColor = Color.FromArgb(212, 212, 212);
this._StatisticsDataGridView.GridColor = Color.FromArgb(60, 60, 60);
this._StatisticsDataGridView.ColumnHeadersDefaultCellStyle.BackColor = Color.FromArgb(45, 45, 45);
this._StatisticsDataGridView.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;

// 修改选项卡颜色
this._MainTabControl.BackColor = Color.FromArgb(30, 30, 30);
this._MainTabControl.ForeColor = Color.White;
foreach (TabPage page in this._MainTabControl.TabPages)
{
    page.BackColor = Color.FromArgb(30, 30, 30);
}

运行时主题切换

要实现运行时切换主题,可在Manager.cs中添加主题管理类:

public class ThemeManager
{
    private Manager _form;
    
    public ThemeManager(Manager form)
    {
        _form = form;
    }
    
    public void ApplyDarkTheme()
    {
        // 深色主题设置
        _form._AchievementListView.BackColor = Color.FromArgb(30, 30, 30);
        _form._AchievementListView.ForeColor = Color.FromArgb(212, 212, 212);
        // 其他控件设置...
    }
    
    public void ApplyLightTheme()
    {
        // 浅色主题设置
        _form._AchievementListView.BackColor = Color.White;
        _form._AchievementListView.ForeColor = Color.Black;
        // 其他控件设置...
    }
}

在主窗体构造函数中初始化并应用主题:

public Manager(long gameId, API.Client client)
{
    InitializeComponent();
    var themeManager = new ThemeManager(this);
    
    // 从配置文件加载主题偏好
    if (Properties.Settings.Default.Theme == "dark")
    {
        themeManager.ApplyDarkTheme();
    }
    else
    {
        themeManager.ApplyLightTheme();
    }
    // ...其他初始化代码
}

高级定制:自定义控件绘制

对于更深度的视觉定制,需要重写控件的绘制逻辑。SAM中DoubleBufferedListView类(SAM.Game/DoubleBufferedListView.cs)已为自定义绘制做好准备,该类继承自ListView并启用了双缓冲以减少闪烁。

自定义成就列表项绘制

重写DoubleBufferedListViewOnDrawItem方法,实现个性化成就项显示:

protected override void OnDrawItem(DrawListViewItemEventArgs e)
{
    // 获取成就数据
    var achievement = e.Item.Tag as Stats.AchievementInfo;
    if (achievement == null)
    {
        base.OnDrawItem(e);
        return;
    }
    
    // 自定义背景绘制
    var backColor = achievement.IsAchieved 
        ? Color.FromArgb(50, 100, 50)  // 已解锁:深绿色背景
        : Color.FromArgb(100, 50, 50);  // 未解锁:深红色背景
    
    using (var brush = new SolidBrush(backColor))
    {
        e.Graphics.FillRectangle(brush, e.Bounds);
    }
    
    // 绘制文本
    var textColor = Color.White;
    using (var font = new Font("Segoe UI", 9))
    using (var brush = new SolidBrush(textColor))
    {
        // 绘制成就名称
        var nameRect = new Rectangle(
            e.Bounds.Left + 64,  // 图标宽度+边距
            e.Bounds.Top,
            e.Bounds.Width - 64,
            e.Bounds.Height / 2);
        e.Graphics.DrawString(e.Item.Text, font, brush, nameRect);
        
        // 绘制成就描述
        if (e.Item.SubItems.Count > 1)
        {
            var descRect = new Rectangle(
                e.Bounds.Left + 64,
                e.Bounds.Top + e.Bounds.Height / 2,
                e.Bounds.Width - 64,
                e.Bounds.Height / 2);
            e.Graphics.DrawString(e.Item.SubItems[1].Text, font, brush, descRect);
        }
    }
    
    // 绘制选中状态
    if ((e.State & ListViewItemStates.Selected) != 0)
    {
        using (var pen = new Pen(Color.Blue, 2))
        {
            e.Graphics.DrawRectangle(pen, e.Bounds);
        }
    }
}

实现进度条式成就显示

对于需要展示进度的成就,可扩展Stats.AchievementInfo类添加进度属性,并在绘制时显示进度条:

// 在Stats/AchievementInfo.cs中添加进度属性
public class AchievementInfo
{
    // ...现有属性
    public float Progress { get; set; }  // 0.0f - 1.0f
    public bool IsProgressive { get; set; }
}

// 在OnDrawSubItem中绘制进度条
protected override void OnDrawSubItem(DrawListViewSubItemEventArgs e)
{
    if (e.ColumnIndex != 1)  // 假设第二列显示进度
    {
        base.OnDrawSubItem(e);
        return;
    }
    
    var achievement = e.Item.Tag as Stats.AchievementInfo;
    if (achievement == null || !achievement.IsProgressive)
    {
        base.OnDrawSubItem(e);
        return;
    }
    
    // 绘制进度条背景
    using (var brush = new SolidBrush(Color.DarkGray))
    {
        e.Graphics.FillRectangle(brush, e.Bounds);
    }
    
    // 绘制进度条前景
    var progressWidth = (int)(e.Bounds.Width * achievement.Progress);
    using (var brush = new SolidBrush(Color.LightGreen))
    {
        e.Graphics.FillRectangle(brush, 
            e.Bounds.Left, e.Bounds.Top, 
            progressWidth, e.Bounds.Height);
    }
    
    // 绘制进度文本
    var text = $"{(int)(achievement.Progress * 100)}%";
    using (var font = new Font("Segoe UI", 8))
    using (var brush = new SolidBrush(Color.Black))
    {
        var format = new StringFormat { Alignment = StringAlignment.Center };
        e.Graphics.DrawString(text, font, brush, e.Bounds, format);
    }
}

主题包系统:分享与应用主题

为了让主题定制可分享、可复用,可以实现主题包系统,将所有资源和样式定义打包为独立文件。

主题包结构设计

theme_pack/
├── manifest.json       # 主题元数据
├── resources/          # 替换资源
│   ├── lock.png
│   ├── unlock.png
│   ...
└── styles.json         # 颜色和样式定义

manifest.json示例:

{
  "name": "Cyberpunk 2077 Theme",
  "author": "Customizer",
  "version": "1.0",
  "description": "Neon-colored theme inspired by Cyberpunk 2077",
  "preview": "preview.png"
}

styles.json示例:

{
  "colors": {
    "background": "#1a1a2e",
    "foreground": "#e2e2e2",
    "accent": "#ff2a6d",
    "gridLines": "#444466",
    "achievementUnlocked": "#05d9e8",
    "achievementLocked": "#ff2a6d"
  },
  "fonts": {
    "default": "Consolas, 9pt",
    "header": "Segoe UI Bold, 10pt"
  }
}

主题加载器实现

创建ThemeLoader类处理主题包加载:

public class ThemeLoader
{
    public Theme LoadTheme(string packagePath)
    {
        // 加载清单
        var manifestPath = Path.Combine(packagePath, "manifest.json");
        var manifest = JsonSerializer.Deserialize<ThemeManifest>(
            File.ReadAllText(manifestPath));
        
        // 加载样式
        var stylesPath = Path.Combine(packagePath, "styles.json");
        var styles = JsonSerializer.Deserialize<ThemeStyles>(
            File.ReadAllText(stylesPath));
        
        // 加载资源
        var resources = new Dictionary<string, Image>();
        var resourceDir = Path.Combine(packagePath, "resources");
        foreach (var file in Directory.GetFiles(resourceDir))
        {
            var name = Path.GetFileNameWithoutExtension(file);
            resources[name] = Image.FromFile(file);
        }
        
        return new Theme(manifest, styles, resources);
    }
    
    public void ApplyTheme(Theme theme, Manager form)
    {
        // 应用颜色样式
        form._AchievementListView.BackColor = ColorTranslator.FromHtml(
            theme.Styles.Colors.Background);
        form._AchievementListView.ForeColor = ColorTranslator.FromHtml(
            theme.Styles.Colors.Foreground);
            
        // 应用字体样式
        form._AchievementListView.Font = new Font(
            theme.Styles.Fonts.Default.Split(',')[0].Trim(),
            float.Parse(theme.Styles.Fonts.Default.Split(',')[1].Trim().Replace("pt", "")));
            
        // 替换资源
        foreach (var resource in theme.Resources)
        {
            typeof(Resources).GetProperty(resource.Key)?.SetValue(null, resource.Value);
        }
    }
}

常见问题与解决方案

资源替换后界面无变化

  1. 检查资源命名:确保替换文件与原始文件名称完全一致
  2. 清理并重建项目:Visual Studio可能缓存旧资源,执行Clean后重新Build
  3. 验证资源引用:在设计器中确认控件确实引用了目标资源

自定义绘制导致性能问题

  • 优化绘制逻辑:减少OnDrawItem中的复杂计算
  • 启用双缓冲:确保控件的DoubleBuffered属性设为true
  • 限制重绘区域:使用Invalidate(Rectangle)而非Invalidate()重绘特定区域

主题应用不完整

  • 检查所有控件:某些颜色可能分散在多个初始化位置
  • 处理动态创建的控件:确保主题应用代码覆盖运行时创建的控件
  • 保存主题设置:使用Properties.Settings持久化主题偏好

总结与进阶方向

通过本文介绍的方法,你已经能够实现从简单图标替换到深度界面定制的全流程主题开发。SAM的模块化设计为进一步扩展提供了可能,未来可以探索以下进阶方向:

  1. 实时预览系统:添加主题编辑器,支持所见即所得的样式调整
  2. 动态效果:实现控件过渡动画、悬停效果和状态变化动画
  3. 字体定制:支持自定义字体和图标字体(如Font Awesome)
  4. 系统主题集成:跟随Windows系统深色/浅色模式自动切换

完整的主题定制不仅能提升个人使用体验,还能为SAM社区贡献独特价值。鼓励将优秀的主题分享到项目社区,让更多用户享受个性化的Steam成就管理体验。

要获取最新版本的SteamAchievementManager,请访问官方仓库:https://gitcode.com/gh_mirrors/st/SteamAchievementManager

【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 【免费下载链接】SteamAchievementManager 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值