diff --git a/assets/toolkit/appicon/toolkitIcon.svg b/assets/toolkit/appicon/toolkitIcon.svg
new file mode 100644
index 0000000..b5b4ae9
--- /dev/null
+++ b/assets/toolkit/appicon/toolkitIcon.svg
@@ -0,0 +1,1934 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Drop Shadow
+
+
+
+
+
+
+
+
+ Icon Mask
+
+
+
+ App Icon Guides
+
+ App Icon Guides
+
+ Outer Bounding Box
+
+
+ Inner Bounding Box
+
+
+ Icon Grid Bounding Box
+
+
+ Icon Grid
+
+
+ Grid Circle 1
+
+
+ Grid Circle 2
+
+
+ Grid Circle 3
+
+
+ Tool Angle
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ FOURdst
+ Toolbox
+
diff --git a/electron/index.html b/electron/index.html
index ee1ccdb..17da275 100644
--- a/electron/index.html
+++ b/electron/index.html
@@ -18,6 +18,10 @@
@@ -160,6 +164,70 @@
+
+
diff --git a/electron/main.js b/electron/main.js
index e5033ef..0d8303f 100644
--- a/electron/main.js
+++ b/electron/main.js
@@ -1,9 +1,8 @@
-const { app, BrowserWindow, ipcMain, dialog, nativeTheme } = require('electron');
+const { app, BrowserWindow, ipcMain, dialog, shell, nativeTheme } = require('electron');
const path = require('path');
-const fs = require('fs-extra');
+const { spawn } = require('child_process');
const yaml = require('js-yaml');
const AdmZip = require('adm-zip');
-const { spawn } = require('child_process');
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) {
diff --git a/electron/renderer.js b/electron/renderer.js
index 8c75d26..96bf366 100644
--- a/electron/renderer.js
+++ b/electron/renderer.js
@@ -207,33 +207,61 @@ function setupEventListeners() {
// Check if bundle is signed and show warning before bundle-modifying operations
function checkSignatureAndWarn(operation, operationName = 'operation') {
- console.log('checkSignatureAndWarn called for:', operationName);
- console.log('currentBundle:', currentBundle);
-
- // Check if current bundle has a valid signature
const isSigned = currentBundle &&
currentBundle.report &&
currentBundle.report.signature &&
currentBundle.report.signature.status &&
['TRUSTED', 'UNTRUSTED'].includes(currentBundle.report.signature.status);
- console.log('Bundle signature status:', currentBundle?.report?.signature?.status);
- console.log('isSigned:', isSigned);
-
if (isSigned) {
- // Bundle is signed, show warning modal
- console.log('Bundle is signed, showing warning modal');
pendingOperation = operation;
signatureWarningModal.classList.remove('hidden');
return false; // Don't execute operation immediately
} else {
- // Bundle is not signed, execute operation directly
- console.log('Bundle is not signed, executing operation directly');
operation();
return true; // Operation executed
}
}
+ // Info Modal functionality
+ const infoBtn = document.getElementById('info-btn');
+ const infoModal = document.getElementById('info-modal');
+ const infoTabLinks = document.querySelectorAll('.info-tab-link');
+ const infoTabPanes = document.querySelectorAll('.info-tab-pane');
+ const githubLink = document.getElementById('github-link');
+
+ // Show info modal
+ infoBtn.addEventListener('click', () => {
+ infoModal.classList.remove('hidden');
+ });
+
+ // Hide info modal - make it globally accessible
+ window.hideInfoModal = function() {
+ infoModal.classList.add('hidden');
+ };
+
+ // Tab switching functionality
+ infoTabLinks.forEach(tabLink => {
+ tabLink.addEventListener('click', () => {
+ const targetTab = tabLink.getAttribute('data-tab');
+
+ // Remove active class from all tabs and panes
+ infoTabLinks.forEach(link => link.classList.remove('active'));
+ infoTabPanes.forEach(pane => pane.classList.remove('active'));
+
+ // Add active class to clicked tab and corresponding pane
+ tabLink.classList.add('active');
+ document.getElementById(targetTab).classList.add('active');
+ });
+ });
+
+ // GitHub link functionality
+ githubLink.addEventListener('click', (e) => {
+ e.preventDefault();
+ const { ipcRenderer } = require('electron');
+ ipcRenderer.invoke('open-external', 'https://github.com/tboudreaux/4DSTAR');
+ });
+
// Old modal code removed - now using tab-based interface
// Create modern table-based interface for fillable targets
diff --git a/electron/styles.css b/electron/styles.css
index ff0cf47..2f37c03 100644
--- a/electron/styles.css
+++ b/electron/styles.css
@@ -102,10 +102,39 @@ body {
}
.sidebar-footer {
- padding: 20px;
- text-align: center;
+ padding: 12px 16px 16px 16px;
font-size: 0.8rem;
color: var(--text-light);
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+}
+
+/* Info Button in Sidebar */
+.info-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ background: rgba(255, 255, 255, 0.1);
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ border-radius: 6px;
+ padding: 8px 12px;
+ cursor: pointer;
+ font-size: 12px;
+ transition: all 0.2s ease;
+ width: fit-content;
+}
+
+.info-button:hover {
+ background: rgba(255, 255, 255, 0.2);
+ border-color: rgba(255, 255, 255, 0.3);
+}
+
+.info-icon {
+ font-size: 14px;
}
/* Content Area */
@@ -584,67 +613,16 @@ body {
max-width: 500px;
}
-#signature-warning-modal h2 {
- color: #f59e0b;
- margin-bottom: 16px;
- display: flex;
- align-items: center;
- gap: 8px;
+.signature-warning-content {
+ text-align: center;
}
-.warning-content {
- margin-bottom: 24px;
-}
-
-.warning-content p {
- margin-bottom: 12px;
- line-height: 1.5;
-}
-
-.warning-content ul {
- margin: 12px 0;
- padding-left: 24px;
-}
-
-.warning-content li {
- margin-bottom: 6px;
- line-height: 1.4;
-}
-
-.modal-actions {
- display: flex;
- gap: 12px;
- justify-content: flex-end;
-}
-
-.modal-actions button {
- padding: 10px 20px;
- border: none;
- border-radius: 6px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 600;
- transition: background-color 0.2s;
-}
-
-/* Signature Warning Banner in Save Modal */
-.signature-warning-section {
- margin-bottom: 20px;
-}
-
-.warning-banner {
- display: flex;
- align-items: flex-start;
- gap: 12px;
- padding: 16px;
+.warning-message {
+ margin: 20px 0;
+ padding: 20px;
background-color: #fef3c7;
border: 1px solid #f59e0b;
border-radius: 8px;
- margin-bottom: 16px;
-}
-
-.warning-icon {
- font-size: 20px;
flex-shrink: 0;
margin-top: 2px;
}
@@ -757,3 +735,135 @@ body {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
+
+/* Info Modal */
+.info-modal-content {
+ max-width: 600px;
+ max-height: 80vh;
+}
+
+.info-modal-body {
+ padding: 0;
+}
+
+.info-tab-nav {
+ display: flex;
+ border-bottom: 1px solid var(--border-color);
+ background-color: #f8f9fa;
+}
+
+.info-tab-link {
+ flex: 1;
+ padding: 12px 16px;
+ border: none;
+ background: none;
+ cursor: pointer;
+ font-weight: 500;
+ color: #6b7280;
+ transition: all 0.2s ease;
+ border-bottom: 2px solid transparent;
+}
+
+.info-tab-link:hover {
+ background-color: #e5e7eb;
+ color: #374151;
+}
+
+.info-tab-link.active {
+ color: #3b82f6;
+ border-bottom-color: #3b82f6;
+ background-color: white;
+}
+
+.info-tab-content {
+ padding: 24px;
+ max-height: 400px;
+ overflow-y: auto;
+}
+
+.info-tab-pane {
+ display: none;
+}
+
+.info-tab-pane.active {
+ display: block;
+}
+
+.info-tab-pane h4 {
+ margin-top: 0;
+ margin-bottom: 16px;
+ color: #1f2937;
+ font-size: 1.25rem;
+}
+
+.info-tab-pane h5 {
+ margin-top: 20px;
+ margin-bottom: 12px;
+ color: #374151;
+ font-size: 1rem;
+}
+
+.info-tab-pane p {
+ margin-bottom: 12px;
+ line-height: 1.6;
+}
+
+.info-tab-pane ul {
+ margin: 12px 0;
+ padding-left: 20px;
+}
+
+.info-tab-pane li {
+ margin-bottom: 8px;
+ line-height: 1.5;
+}
+
+.info-links {
+ margin-top: 20px;
+ padding-top: 16px;
+ border-top: 1px solid var(--border-color);
+}
+
+.info-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ color: #3b82f6;
+ text-decoration: none;
+ font-weight: 500;
+ padding: 8px 12px;
+ border-radius: 6px;
+ transition: background-color 0.2s;
+}
+
+.info-link:hover {
+ background-color: #eff6ff;
+ text-decoration: none;
+}
+
+.link-icon {
+ font-size: 16px;
+}
+
+.license-content {
+ margin-top: 16px;
+}
+
+.license-text {
+ width: 100%;
+ height: 200px;
+ margin-top: 12px;
+ padding: 12px;
+ border: 1px solid var(--border-color);
+ border-radius: 6px;
+ font-family: 'Courier New', monospace;
+ font-size: 12px;
+ line-height: 1.4;
+ resize: vertical;
+ background-color: #f8f9fa;
+}
+
+.funding-content,
+.help-content {
+ line-height: 1.6;
+}