diff --git a/assets/images/app-icon-128.png b/assets/images/app-icon-128.png new file mode 100644 index 0000000..d8975dc Binary files /dev/null and b/assets/images/app-icon-128.png differ diff --git a/assets/images/app-icon-16.png b/assets/images/app-icon-16.png new file mode 100644 index 0000000..d288a20 Binary files /dev/null and b/assets/images/app-icon-16.png differ diff --git a/assets/images/app-icon-24.png b/assets/images/app-icon-24.png new file mode 100644 index 0000000..3639bf3 Binary files /dev/null and b/assets/images/app-icon-24.png differ diff --git a/assets/images/app-icon-256.png b/assets/images/app-icon-256.png new file mode 100644 index 0000000..e9e231b Binary files /dev/null and b/assets/images/app-icon-256.png differ diff --git a/assets/images/app-icon-32.png b/assets/images/app-icon-32.png new file mode 100644 index 0000000..64cfdfd Binary files /dev/null and b/assets/images/app-icon-32.png differ diff --git a/assets/images/app-icon-48.png b/assets/images/app-icon-48.png new file mode 100644 index 0000000..85f9914 Binary files /dev/null and b/assets/images/app-icon-48.png differ diff --git a/assets/images/app-icon-64.png b/assets/images/app-icon-64.png new file mode 100644 index 0000000..c4ca5fa Binary files /dev/null and b/assets/images/app-icon-64.png differ diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/assets/AssetManager.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/assets/AssetManager.java index c74663e..673fcf5 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/assets/AssetManager.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/assets/AssetManager.java @@ -282,6 +282,59 @@ public final class AssetManager { return getImageOrDefault("app-logo", width, height, fallbackSupplier); } + private static final int[] ICON_SIZES = {16, 24, 32, 48, 64, 128, 256}; + + /** + * Retorna a lista de imagens multi-resolução do ícone da aplicação + * para configuração do Stage JavaFX principal (16, 24, 32, 48, 64, 128, 256 px). + */ + public static List getApplicationIcons() { + List icons = new ArrayList<>(); + for (int size : ICON_SIZES) { + String path = "/assets/images/app-icon-" + size + ".png"; + InputStream in = AssetManager.class.getResourceAsStream(path); + if (in != null) { + try (in) { + icons.add(new Image(in)); + } catch (Exception e) { + logger.debug("Falha ao carregar ícone {}: {}", path, e.getMessage()); + } + } else { + InputStream fallback = AssetManager.class.getResourceAsStream("/assets/images/app-icon.png"); + if (fallback != null) { + try (fallback) { + icons.add(new Image(fallback, size, size, true, true)); + } catch (Exception ignored) { + } + } + } + } + return icons; + } + + /** + * Carrega a imagem da bandeja do sistema nativa (AWT TrayIcon) em alta fidelidade. + */ + public static java.awt.Image getTrayIconImage() { + String[] preferredPaths = { + "/assets/images/app-icon-32.png", + "/assets/images/app-icon-16.png", + "/assets/images/app-icon.png" + }; + + for (String path : preferredPaths) { + InputStream in = AssetManager.class.getResourceAsStream(path); + if (in != null) { + try (in) { + return javax.imageio.ImageIO.read(in); + } catch (Exception e) { + logger.debug("Falha ao ler recurso AWT {}: {}", path, e.getMessage()); + } + } + } + return null; + } + private static String cleanBaseName(String name) { String clean = name; int dotIdx = clean.lastIndexOf('.'); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/tray/SystemTrayManager.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/tray/SystemTrayManager.java index 80f90b3..29b90fc 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/tray/SystemTrayManager.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/tray/SystemTrayManager.java @@ -189,9 +189,15 @@ public class SystemTrayManager { } /** - * Gera dinamicamente um ícone vetorial de 32x32 com o padrão de cores CyberCore (#38bdf8). + * Obtém o ícone oficial da marca CyberCore em alta resolução para a bandeja do sistema, + * com fallback vetorial dinâmico caso o recurso não esteja disponível. */ private Image createTrayIconImage() { + Image trayAsset = br.com.cybercore.signer.ui.assets.AssetManager.getTrayIconImage(); + if (trayAsset != null) { + return trayAsset; + } + int size = 32; BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); diff --git a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java index 0c5230a..09c77ee 100644 --- a/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java +++ b/modules/cybercore-ui/src/main/java/br/com/cybercore/signer/ui/view/MainAppView.java @@ -155,6 +155,7 @@ public final class MainAppView { ThemeManager.addListener(theme -> updateThemeToggleButton()); stage.setTitle(CyberCoreUiConstants.APP_NAME); + stage.getIcons().addAll(br.com.cybercore.signer.ui.assets.AssetManager.getApplicationIcons()); stage.setScene(scene); if (Boolean.getBoolean("cybercore.diag.plain-stage")) { diff --git a/modules/cybercore-ui/src/main/resources/assets/images/app-icon-128.png b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-128.png new file mode 100644 index 0000000..d8975dc Binary files /dev/null and b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-128.png differ diff --git a/modules/cybercore-ui/src/main/resources/assets/images/app-icon-16.png b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-16.png new file mode 100644 index 0000000..d288a20 Binary files /dev/null and b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-16.png differ diff --git a/modules/cybercore-ui/src/main/resources/assets/images/app-icon-24.png b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-24.png new file mode 100644 index 0000000..3639bf3 Binary files /dev/null and b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-24.png differ diff --git a/modules/cybercore-ui/src/main/resources/assets/images/app-icon-256.png b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-256.png new file mode 100644 index 0000000..e9e231b Binary files /dev/null and b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-256.png differ diff --git a/modules/cybercore-ui/src/main/resources/assets/images/app-icon-32.png b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-32.png new file mode 100644 index 0000000..64cfdfd Binary files /dev/null and b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-32.png differ diff --git a/modules/cybercore-ui/src/main/resources/assets/images/app-icon-48.png b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-48.png new file mode 100644 index 0000000..85f9914 Binary files /dev/null and b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-48.png differ diff --git a/modules/cybercore-ui/src/main/resources/assets/images/app-icon-64.png b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-64.png new file mode 100644 index 0000000..c4ca5fa Binary files /dev/null and b/modules/cybercore-ui/src/main/resources/assets/images/app-icon-64.png differ diff --git a/modules/cybercore-ui/src/test/java/br/com/cybercore/signer/ui/assets/AssetManagerTest.java b/modules/cybercore-ui/src/test/java/br/com/cybercore/signer/ui/assets/AssetManagerTest.java index fd785de..534909c 100644 --- a/modules/cybercore-ui/src/test/java/br/com/cybercore/signer/ui/assets/AssetManagerTest.java +++ b/modules/cybercore-ui/src/test/java/br/com/cybercore/signer/ui/assets/AssetManagerTest.java @@ -104,4 +104,15 @@ class AssetManagerTest { AssetManager.setExternalOverridesEnabled(null); } } + + @Test + @DisplayName("Deve fornecer ícones multi-resolução da aplicação e imagem para a bandeja nativa") + void shouldProvideMultiResolutionIconsAndTrayImage() { + java.util.List icons = AssetManager.getApplicationIcons(); + assertThat(icons).isNotEmpty(); + assertThat(icons.size()).isGreaterThanOrEqualTo(5); + + java.awt.Image trayImage = AssetManager.getTrayIconImage(); + assertThat(trayImage).isNotNull(); + } }