diff --git a/apps/arstack_studio/CMakeLists.txt b/apps/arstack_studio/CMakeLists.txt index ddfed8eb6..a5a678d06 100644 --- a/apps/arstack_studio/CMakeLists.txt +++ b/apps/arstack_studio/CMakeLists.txt @@ -41,6 +41,16 @@ qt_add_executable(arstack_studio ${ARSTACK_STUDIO_CORE_SOURCES} ) +# Studio-only branding: never use the root assets/ (Workbench) icons. +set(ARSTACK_STUDIO_BRAND_DIR "${CMAKE_CURRENT_LIST_DIR}/../../assets/studio_icon") +qt_add_resources(arstack_studio "studio_brand_icon" + PREFIX "/studio-brand" + BASE "${ARSTACK_STUDIO_BRAND_DIR}" + FILES + "${ARSTACK_STUDIO_BRAND_DIR}/android-chrome-192x192.png" + "${ARSTACK_STUDIO_BRAND_DIR}/android-chrome-512x512.png" +) + # S8 is intentionally a separate, headless executable. It links the same # production controller/worker sources as Studio but exposes no test command in # the release application. Friend-only seams let the harness inject deterministic @@ -171,5 +181,14 @@ target_compile_definitions(arstack_session_harness PRIVATE ) if(WIN32) + # PE resource gives ARStackStudio.exe its Explorer, shortcut and taskbar icon. + enable_language(RC) + set(ARSTACK_STUDIO_ICON_ICO "${ARSTACK_STUDIO_BRAND_DIR}/ARStackStudio.ico") + configure_file( + "${CMAKE_CURRENT_LIST_DIR}/packaging/ARStackStudioIcon.rc.in" + "${CMAKE_CURRENT_BINARY_DIR}/ARStackStudioIcon.rc" + @ONLY + ) + target_sources(arstack_studio PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/ARStackStudioIcon.rc") set_target_properties(arstack_studio PROPERTIES WIN32_EXECUTABLE TRUE) endif() \ No newline at end of file diff --git a/apps/arstack_studio/packaging/ARStackStudio.iss b/apps/arstack_studio/packaging/ARStackStudio.iss index d0013daf6..e33848a44 100644 --- a/apps/arstack_studio/packaging/ARStackStudio.iss +++ b/apps/arstack_studio/packaging/ARStackStudio.iss @@ -23,6 +23,9 @@ #define ProductRegistry "Software\ARStack61850\ARStack Studio" #endif +; Resolve relative to this .iss file, independent of the compiler working dir. +#define StudioIconFile AddBackslash(SourcePath) + "..\..\..\assets\studio_icon\ARStackStudio.ico" + [Setup] AppId={#ProductId} AppName={#ProductName} @@ -33,6 +36,8 @@ AppPublisherURL=https://github.com/masarray/arstack61850 AppSupportURL=https://github.com/masarray/arstack61850/issues AppUpdatesURL=https://github.com/masarray/arstack61850/releases UninstallDisplayName={#ProductName} +UninstallDisplayIcon={app}\ARStackStudio.exe +SetupIconFile={#StudioIconFile} DefaultDirName={localappdata}\Programs\{#ProductFolder} DefaultGroupName={#ProductName} OutputBaseFilename={#ProductOutput} diff --git a/apps/arstack_studio/packaging/ARStackStudioIcon.rc.in b/apps/arstack_studio/packaging/ARStackStudioIcon.rc.in new file mode 100644 index 000000000..69500dcb6 --- /dev/null +++ b/apps/arstack_studio/packaging/ARStackStudioIcon.rc.in @@ -0,0 +1,2 @@ +// Studio-only Windows PE icon. CMake expands the absolute ICO path. +1 ICON "@ARSTACK_STUDIO_ICON_ICO@" diff --git a/apps/arstack_studio/src/main.cpp b/apps/arstack_studio/src/main.cpp index f208cd705..d53ca895b 100644 --- a/apps/arstack_studio/src/main.cpp +++ b/apps/arstack_studio/src/main.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -446,6 +447,10 @@ int main(int argc, char* argv[]) { QCoreApplication::setApplicationName(QStringLiteral("ARStack Studio")); QCoreApplication::setApplicationVersion(QStringLiteral(ARSTACK_STUDIO_VERSION)); #endif + QIcon studioIcon; + studioIcon.addFile(QStringLiteral(":/studio-brand/android-chrome-192x192.png")); + studioIcon.addFile(QStringLiteral(":/studio-brand/android-chrome-512x512.png")); + app.setWindowIcon(studioIcon); // S6 ownership starts before any firmware process, QML object, or serial // worker exists. A second Studio process therefore cannot race for the diff --git a/assets/studio_icon/ARStackStudio.ico b/assets/studio_icon/ARStackStudio.ico new file mode 100644 index 000000000..b8289491c Binary files /dev/null and b/assets/studio_icon/ARStackStudio.ico differ