/** * CatOS Event Handler Module * Manages all user interactions and system events */ class EventHandler { constructor(core) { this.core = core; } setup(core) { this.core = core; // Desktop icon interactions document.querySelectorAll('.desktop-icon').forEach(icon => { icon.addEventListener('dblclick', this.handleIconDoubleClick.bind(this)); icon.addEventListener('click', this.handleIconClick.bind(this)); }); // Start button document.getElementById('start-button').addEventListener('click', this.toggleStartMenu.bind(this)); // Start menu apps document.querySelectorAll('.menu-app').forEach(app => { app.addEventListener('click', this.handleMenuAppClick.bind(this)); }); // Desktop context menu document.getElementById('desktop').addEventListener('contextmenu', this.showContextMenu.bind(this)); // Close context menu on click document.addEventListener('click', this.hideContextMenu.bind(this)); // Close start menu on outside click document.addEventListener('click', (e) => { if (!e.target.closest('.start-button') && !e.target.closest('.start-menu')) { this.hideStartMenu(); } }); // Keyboard shortcuts document.addEventListener('keydown', this.handleKeyboard.bind(this)); // Window container clicks (deselect icons) document.getElementById('windows-container').addEventListener('click', (e) => { if (e.target.id === 'windows-container') { this.deselectAllIcons(); } }); // Context menu actions document.querySelectorAll('.context-item').forEach(item => { item.addEventListener('click', this.handleContextMenuAction.bind(this)); }); } // Icon interactions handleIconClick(e) { this.deselectAllIcons(); e.currentTarget.classList.add('selected'); // Add cat-like feedback e.currentTarget.style.transform = 'scale(0.95)'; setTimeout(() => { e.currentTarget.style.transform = ''; }, 150); } handleIconDoubleClick(e) { const icon = e.currentTarget; const appType = icon.dataset.app; const projectId = icon.dataset.project; // Add launch animation icon.style.animation = 'bounce 0.5s ease'; setTimeout(() => { icon.style.animation = ''; }, 500); if (appType === 'project-viewer' && projectId) { this.core.appManager.launchApp('project-viewer', { projectId }); } else { this.core.appManager.launchApp(appType); } } deselectAllIcons() { document.querySelectorAll('.desktop-icon.selected').forEach(icon => { icon.classList.remove('selected'); }); } // Start Menu Management toggleStartMenu() { const menu = document.getElementById('start-menu'); const button = document.getElementById('start-button'); if (this.core.startMenuOpen) { this.hideStartMenu(); } else { menu.classList.add('show'); button.classList.add('active'); this.core.startMenuOpen = true; } } hideStartMenu() { const menu = document.getElementById('start-menu'); const button = document.getElementById('start-button'); menu.classList.remove('show'); button.classList.remove('active'); this.core.startMenuOpen = false; } handleMenuAppClick(e) { const app = e.currentTarget; const appType = app.dataset.app; // Close start menu with animation this.hideStartMenu(); // Small delay for better UX setTimeout(() => { this.core.appManager.launchApp(appType); }, 150); } // Context Menu showContextMenu(e) { e.preventDefault(); const contextMenu = document.getElementById('context-menu'); contextMenu.style.left = e.clientX + 'px'; contextMenu.style.top = e.clientY + 'px'; contextMenu.classList.add('show'); // Ensure menu stays within viewport const rect = contextMenu.getBoundingClientRect(); if (rect.right > window.innerWidth) { contextMenu.style.left = (window.innerWidth - rect.width - 10) + 'px'; } if (rect.bottom > window.innerHeight) { contextMenu.style.top = (window.innerHeight - rect.height - 10) + 'px'; } } hideContextMenu(e) { const contextMenu = document.getElementById('context-menu'); if (!e.target.closest('.context-menu')) { contextMenu.classList.remove('show'); } } handleContextMenuAction(e) { const action = e.currentTarget.dataset.action; switch(action) { case 'refresh': this.refreshDesktop(); break; case 'new-folder': this.createNewFolder(); break; case 'properties': this.showDesktopProperties(); break; } this.hideContextMenu({ target: document.body }); } refreshDesktop() { this.core.setRandomWallpaper(); this.core.showNotification('🔄 Desktop Refreshed', 'New wallpaper loaded! Looking purrfect! 😸'); } createNewFolder() { this.core.showNotification('📁 Feature Coming Soon', 'Folder creation will be available in the next CatOS update! 🐱‍💻'); } showDesktopProperties() { this.core.appManager.launchApp('about'); } // Keyboard shortcuts handleKeyboard(e) { // System shortcuts if (e.ctrlKey || e.metaKey) { switch(e.key) { case '`': // Ctrl+` opens terminal e.preventDefault(); this.core.appManager.launchApp('terminal'); break; case 'r': // Ctrl+R refreshes desktop if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') { e.preventDefault(); this.refreshDesktop(); } break; } } // Special keys switch(e.key) { case 'F1': e.preventDefault(); this.core.appManager.launchApp('about'); break; case 'F5': e.preventDefault(); this.refreshDesktop(); break; case 'Delete': // Delete selected desktop items (if any) const selected = document.querySelector('.desktop-icon.selected'); if (selected) { this.core.showNotification('🗑️ Cannot Delete', 'System items are protected by cat law! 😹'); } break; case 'Escape': // Close context menu and start menu this.hideContextMenu({ target: document.body }); if (this.core.startMenuOpen) { this.hideStartMenu(); } break; } // Easter eggs this.handleEasterEggs(e); } handleEasterEggs(e) { // Konami code for cats: ↑↑↓↓←→←→BA if (!this.konamiSequence) { this.konamiSequence = []; } const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'KeyB', 'KeyA']; if (e.code === konamiCode[this.konamiSequence.length]) { this.konamiSequence.push(e.code); if (this.konamiSequence.length === konamiCode.length) { this.activateCatMode(); this.konamiSequence = []; } } else { this.konamiSequence = []; } // Cat sound effects if (e.key === 'm' && !e.target.matches('input, textarea')) { this.playMeowSound(); } } activateCatMode() { this.core.showNotification('🎉 Cat Mode Activated!', 'You found the secret cat code! Enjoy the purr-ks! 😸'); // Add some fun visual effects document.body.style.animation = 'rainbow 2s infinite'; // Add temporary CSS for rainbow effect if (!document.getElementById('cat-mode-styles')) { const style = document.createElement('style'); style.id = 'cat-mode-styles'; style.textContent = ` @keyframes rainbow { 0% { filter: hue-rotate(0deg); } 100% { filter: hue-rotate(360deg); } } `; document.head.appendChild(style); } // Reset after 5 seconds setTimeout(() => { document.body.style.animation = ''; }, 5000); } playMeowSound() { // Visual feedback for meow (since we can't guarantee audio) const meows = ['😸', '🙀', '😻', '😹', '😾', '🐱']; const meow = meows[Math.floor(Math.random() * meows.length)]; const meowElement = document.createElement('div'); meowElement.textContent = meow; meowElement.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 3rem; z-index: 9999; pointer-events: none; animation: meowPop 1s ease forwards; `; // Add meow animation CSS if not already present if (!document.getElementById('meow-styles')) { const style = document.createElement('style'); style.id = 'meow-styles'; style.textContent = ` @keyframes meowPop { 0% { transform: translate(-50%, -50%) scale(0); opacity: 1; } 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 1; } 100% { transform: translate(-50%, -50%) scale(1.5); opacity: 0; } } `; document.head.appendChild(style); } document.body.appendChild(meowElement); setTimeout(() => { if (meowElement.parentNode) { meowElement.parentNode.removeChild(meowElement); } }, 1000); } } // Export for use in main system window.CatOSEventHandler = EventHandler;