Enhancement: Create Icon Viewer tool for debugging icon theme problems

This commit is contained in:
Rory Fewell
2025-10-21 19:23:48 +01:00
parent 315ff425a5
commit f4e8fe7e4d
13 changed files with 462 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
cmake_minimum_required(VERSION 3.12)
project(
wintc-icondbg
VERSION 1.0
DESCRIPTION "Windows Total Conversion icon debugging tool."
LANGUAGES C
)
set(PROJECT_ANYARCH false)
set(PROJECT_FREESTATUS true)
set(PROJECT_MAINTAINER "Rory Fewell <roryf@oddmatics.uk>")
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
include(GNUInstallDirs)
include(../../packaging/cmake-inc/common/CMakeLists.txt)
include(../../packaging/cmake-inc/linking/CMakeLists.txt)
include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
include(../../packaging/cmake-inc/resources/CMakeLists.txt)
wintc_resolve_library(glib-2.0 GLIB)
wintc_resolve_library(gtk+-3.0 GTK3)
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
wintc_compile_resources()
add_executable(
wintc-icondbg
src/application.c
src/application.h
src/main.c
src/resources.c
src/window.c
src/window.h
)
target_compile_options(
wintc-icondbg
PRIVATE ${WINTC_COMPILE_OPTIONS}
)
target_include_directories(
wintc-icondbg
SYSTEM
PRIVATE ${GLIB_INCLUDE_DIRS}
PRIVATE ${GTK3_INCLUDE_DIRS}
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
)
target_link_directories(
wintc-icondbg
PRIVATE ${GLIB_LIBRARY_DIRS}
PRIVATE ${GTK3_LIBRARY_DIRS}
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
)
target_link_libraries(
wintc-icondbg
PRIVATE ${GLIB_LIBRARIES}
PRIVATE ${GTK3_LIBRARIES}
PRIVATE ${WINTC_COMGTK_LIBRARIES}
)
# Installation
#
wintc_configure_and_install_packaging()
wintc_install_icons_into_package()
install(
FILES wintc-icondbg.desktop
DESTINATION share/applications
)
install(
TARGETS wintc-icondbg
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

7
tools/icondbg/README.MD Normal file
View File

@@ -0,0 +1,7 @@
# icondbg
This directory contains the source code for the Icon Viewer tool.
<img width="337" height="215" alt="Image" src="https://github.com/user-attachments/assets/dfbe803b-b7ed-4e98-825e-0fd8ce721939" />
## Usage
This tool is for testing the currently active icon theme using `gtk_icon_theme_load_icon()`. Can be used in conjuction with a debug build of GTK to deep dive into icon bugs.

3
tools/icondbg/deps Normal file
View File

@@ -0,0 +1,3 @@
bt,rt:glib2
bt,rt:gtk3
bt,rt:wintc-comgtk

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,70 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include "application.h"
#include "window.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCIconDbgApplication
{
GtkApplication __parent__;
};
//
// FORWARD DECLARATIONS
//
static void wintc_icon_dbg_application_activate(
GApplication* application
);
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE(
WinTCIconDbgApplication,
wintc_icon_dbg_application,
GTK_TYPE_APPLICATION
)
static void wintc_icon_dbg_application_class_init(
WinTCIconDbgApplicationClass* klass
)
{
GApplicationClass* application_class = G_APPLICATION_CLASS(klass);
application_class->activate = wintc_icon_dbg_application_activate;
}
static void wintc_icon_dbg_application_init(
WINTC_UNUSED(WinTCIconDbgApplication* self)
) { }
//
// CLASS VIRTUAL METHODS
//
static void wintc_icon_dbg_application_activate(
GApplication* application
)
{
GtkWidget* new_window =
wintc_icon_dbg_window_new(WINTC_ICON_DBG_APPLICATION(application));
gtk_widget_show_all(new_window);
}
//
// PUBLIC FUNCTIONS
//
WinTCIconDbgApplication* wintc_icon_dbg_application_new(void)
{
return WINTC_ICON_DBG_APPLICATION(
g_object_new(
wintc_icon_dbg_application_get_type(),
"application-id", "uk.co.oddmatics.wintc.samples.icondbg",
NULL
)
);
}

View File

@@ -0,0 +1,25 @@
#ifndef __APPLICATION_H__
#define __APPLICATION_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
#define WINTC_TYPE_ICON_DBG_APPLICATION (wintc_icon_dbg_application_get_type())
G_DECLARE_FINAL_TYPE(
WinTCIconDbgApplication,
wintc_icon_dbg_application,
WINTC,
ICON_DBG_APPLICATION,
GtkApplication
)
//
// PUBLIC FUNCTIONS
//
WinTCIconDbgApplication* wintc_icon_dbg_application_new(void);
#endif

20
tools/icondbg/src/main.c Normal file
View File

@@ -0,0 +1,20 @@
#include <glib.h>
#include "application.h"
int main(
int argc,
char* argv[]
)
{
WinTCIconDbgApplication* app = wintc_icon_dbg_application_new();
int status;
g_set_application_name("IconDbg");
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkListStore" id="model-sizes">
<columns>
<column type="gchararray" />
</columns>
<data>
<row>
<col id="0">16x16</col>
</row>
<row>
<col id="0">24x24</col>
</row>
<row>
<col id="0">32x32</col>
</row>
<row>
<col id="0">48x48</col>
</row>
</data>
</object>
<object class="GtkPaned" id="paned-root">
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="entry-icon-name">
</object>
</child>
<child>
<object class="GtkComboBox" id="combo-size">
<property name="active">0</property>
<property name="model">model-sizes</property>
<child>
<object class="GtkCellRendererText" />
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="button-load">
<property name="label" translatable="no">Load</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkImage" id="img-icon">
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/uk/oddmatics/wintc/icondbg">
<file>icondbg.ui</file>
</gresource>
</gresources>

147
tools/icondbg/src/window.c Normal file
View File

@@ -0,0 +1,147 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include "application.h"
#include "window.h"
//
// FORWARD DECLARATIONS
//
static void on_button_load_clicked(
GtkButton* self,
gpointer user_data
);
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCIconDbgWindow
{
GtkApplicationWindow __parent__;
// UI
//
GtkWidget* entry_icon_name;
GtkWidget* combo_size;
GtkWidget* img_icon;
};
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
WinTCIconDbgWindow,
wintc_icon_dbg_window,
GTK_TYPE_APPLICATION_WINDOW
)
static void wintc_icon_dbg_window_class_init(
WINTC_UNUSED(WinTCIconDbgWindowClass* klass)
) {}
static void wintc_icon_dbg_window_init(
WinTCIconDbgWindow* self
)
{
GtkBuilder* builder;
GtkWidget* button_load;
GtkWidget* paned_root;
gtk_window_set_default_size(
GTK_WINDOW(self),
400,
300
);
builder =
gtk_builder_new_from_resource(
"/uk/oddmatics/wintc/icondbg/icondbg.ui"
);
wintc_builder_get_objects(
builder,
"button-load", &button_load,
"entry-icon-name", &(self->entry_icon_name),
"combo-size", &(self->combo_size),
"img-icon", &(self->img_icon),
"paned-root", &paned_root,
NULL
);
gtk_container_add(
GTK_CONTAINER(self),
GTK_WIDGET(gtk_builder_get_object(builder, "paned-root"))
);
g_signal_connect(
button_load,
"clicked",
G_CALLBACK(on_button_load_clicked),
self
);
g_object_unref(builder);
}
//
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_icon_dbg_window_new(
WinTCIconDbgApplication* app
)
{
return GTK_WIDGET(
g_object_new(
WINTC_TYPE_ICON_DBG_WINDOW,
"application", GTK_APPLICATION(app),
"title", "Icon Viewer",
NULL
)
);
}
//
// CALLBACKS
//
static void on_button_load_clicked(
WINTC_UNUSED(GtkButton* self),
gpointer user_data
)
{
WinTCIconDbgWindow* wnd = WINTC_ICON_DBG_WINDOW(user_data);
// Retrieve the details on what we need to load
//
const gchar* icon_name;
gint icon_size;
icon_name = gtk_entry_get_text(GTK_ENTRY(wnd->entry_icon_name));
icon_size = gtk_combo_box_get_active(GTK_COMBO_BOX(wnd->combo_size));
icon_size = (icon_size + 1) * 16;
// Attempt to load the icon
//
GError* error = NULL;
GdkPixbuf* pixbuf_icon =
gtk_icon_theme_load_icon(
gtk_icon_theme_get_default(),
icon_name,
icon_size,
GTK_ICON_LOOKUP_FORCE_SIZE,
&error
);
if (!pixbuf_icon)
{
wintc_display_error_and_clear(&error, GTK_WINDOW(wnd));
return;
}
gtk_image_set_from_pixbuf(
GTK_IMAGE(wnd->img_icon),
pixbuf_icon
);
g_object_unref(pixbuf_icon);
}

View File

@@ -0,0 +1,29 @@
#ifndef __WINDOW_H__
#define __WINDOW_H__
#include <glib.h>
#include <gtk/gtk.h>
#include "application.h"
//
// GTK OOP BOILERPLATE
//
#define WINTC_TYPE_ICON_DBG_WINDOW (wintc_icon_dbg_window_get_type())
G_DECLARE_FINAL_TYPE(
WinTCIconDbgWindow,
wintc_icon_dbg_window,
WINTC,
ICON_DBG_WINDOW,
GtkApplicationWindow
)
//
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_icon_dbg_window_new(
WinTCIconDbgApplication* app
);
#endif

View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Name=Icon Viewer (WinTC)
Comment=Development tool for debugging icon lookup problems.
Exec=wintc-icondbg
Icon=wintc-icondbg
Terminal=false
StartupNotify=false
Type=Application
Categories=Utility;GTK;X-WinTC-Dev;