/** * UI HELPERS * Quick utility functions for creating themed UI elements * Uses UITheme for consistent styling */ class UIHelpers { /** * Create themed button */ static createButton(scene, x, y, text, callback, buttonType = 'primary') { const theme = window.UITheme; const btnStyle = theme.buttons[buttonType] || theme.buttons.primary; // Button background const width = Math.max(120, text.length * 10 + 40); const height = 40; const button = scene.add.container(x, y); // Background rectangle const bg = scene.add.rectangle(0, 0, width, height, parseInt(btnStyle.background.replace('#', '0x')), 1); bg.setStrokeStyle(2, parseInt(btnStyle.border.replace('#', '0x'))); // Text const btnText = scene.add.text(0, 0, text, { fontFamily: theme.fonts.primary, fontSize: theme.fontSizes.medium, color: btnStyle.text }); btnText.setOrigin(0.5); button.add([bg, btnText]); // Make interactive bg.setInteractive({ useHandCursor: true }); // Hover effect bg.on('pointerover', () => { bg.setFillStyle(parseInt(btnStyle.backgroundHover.replace('#', '0x'))); }); bg.on('pointerout', () => { bg.setFillStyle(parseInt(btnStyle.background.replace('#', '0x'))); }); // Click if (callback) { bg.on('pointerdown', callback); } return button; } /** * Create themed panel */ static createPanel(scene, x, y, width, height, panelType = 'wooden') { const theme = window.UITheme; return theme.createPanel(scene, x, y, width, height, panelType); } /** * Create themed text */ static createText(scene, x, y, text, style = 'normal') { const theme = window.UITheme; const textStyle = theme.applyTextStyle(null, style); const textObj = scene.add.text(x, y, text, textStyle); return textObj; } /** * Create header text */ static createHeader(scene, x, y, text) { return this.createText(scene, x, y, text, 'header'); } /** * Create progress bar */ static createProgressBar(scene, x, y, width, height, progress = 0.5) { const theme = window.UITheme; const container = scene.add.container(x, y); // Background const bg = scene.add.rectangle(0, 0, width, height, theme.getColor('backgrounds.dark'), 1); bg.setStrokeStyle(2, theme.getColor('secondary.steel')); bg.setOrigin(0, 0.5); // Fill const fill = scene.add.rectangle(2, 0, (width - 4) * progress, height - 4, theme.getColor('states.success'), 1); fill.setOrigin(0, 0.5); container.add([bg, fill]); // Update method container.setProgress = function (value) { fill.width = Math.max(0, Math.min(width - 4, (width - 4) * value)); }; return container; } /** * Create tooltip */ static createTooltip(scene, x, y, text) { const theme = window.UITheme; const tooltip = scene.add.container(x, y); tooltip.setDepth(100000); // Measure text const tempText = scene.add.text(0, 0, text, { fontFamily: theme.fonts.primary, fontSize: theme.fontSizes.small }); const textWidth = tempText.width; const textHeight = tempText.height; tempText.destroy(); // Background const padding = 8; const bg = scene.add.rectangle(0, 0, textWidth + padding * 2, textHeight + padding * 2, theme.getColor('backgrounds.overlay')); bg.setStrokeStyle(1, theme.getColor('primary.lightBrown')); // Text const tooltipText = scene.add.text(0, 0, text, { fontFamily: theme.fonts.primary, fontSize: theme.fontSizes.small, color: theme.colors.text.primary }); tooltipText.setOrigin(0.5); tooltip.add([bg, tooltipText]); tooltip.setAlpha(0); // Show/hide methods tooltip.show = function () { this.setAlpha(1); }; tooltip.hide = function () { this.setAlpha(0); }; return tooltip; } /** * Create notification popup */ static createNotification(scene, text, duration = 2000, type = 'info') { const theme = window.UITheme; const width = scene.cameras.main.width; const height = scene.cameras.main.height; const notification = scene.add.container(width / 2, height - 100); notification.setScrollFactor(0); notification.setDepth(100000); // Background color based on type let bgColor = theme.getColor('states.' + type); if (!bgColor) bgColor = theme.getColor('backgrounds.medium'); // Background const bg = scene.add.rectangle(0, 0, 300, 60, bgColor, 0.95); bg.setStrokeStyle(2, theme.getColor('primary.darkBrown')); // Text const notifText = scene.add.text(0, 0, text, { fontFamily: theme.fonts.primary, fontSize: theme.fontSizes.medium, color: theme.colors.text.primary, align: 'center', wordWrap: { width: 280 } }); notifText.setOrigin(0.5); notification.add([bg, notifText]); // Animate in notification.setAlpha(0); notification.y = height - 50; scene.tweens.add({ targets: notification, alpha: 1, y: height - 100, duration: 300, ease: 'Back.easeOut' }); // Animate out scene.tweens.add({ targets: notification, alpha: 0, y: height - 50, duration: 300, delay: duration, onComplete: () => { notification.destroy(); } }); return notification; } /** * Create icon button (emoji/icon only) */ static createIconButton(scene, x, y, icon, callback, size = 40) { const theme = window.UITheme; const button = scene.add.container(x, y); // Background const bg = scene.add.circle(0, 0, size / 2, theme.getColor('primary.mediumBrown'), 1); bg.setStrokeStyle(2, theme.getColor('primary.darkBrown')); // Icon const iconText = scene.add.text(0, 0, icon, { fontSize: (size * 0.6) + 'px' }); iconText.setOrigin(0.5); button.add([bg, iconText]); // Interactive bg.setInteractive({ useHandCursor: true }); bg.on('pointerover', () => { bg.setFillStyle(theme.getColor('primary.lightBrown')); }); bg.on('pointerout', () => { bg.setFillStyle(theme.getColor('primary.mediumBrown')); }); if (callback) { bg.on('pointerdown', callback); } return button; } /** * Create checkbox */ static createCheckbox(scene, x, y, label, isChecked = false, callback) { const theme = window.UITheme; const checkbox = scene.add.container(x, y); // Box const size = 20; const box = scene.add.rectangle(0, 0, size, size, theme.getColor('backgrounds.light'), 1); box.setStrokeStyle(2, theme.getColor('primary.darkBrown')); box.setOrigin(0, 0.5); // Checkmark const check = scene.add.text(size / 2, 0, '✓', { fontSize: '18px', color: theme.colors.accent.forestGreen }); check.setOrigin(0.5); check.setVisible(isChecked); // Label const labelText = scene.add.text(size + 10, 0, label, { fontFamily: theme.fonts.primary, fontSize: theme.fontSizes.normal, color: theme.colors.text.primary }); labelText.setOrigin(0, 0.5); checkbox.add([box, check, labelText]); // State checkbox.checked = isChecked; // Interactive box.setInteractive({ useHandCursor: true }); box.on('pointerdown', () => { checkbox.checked = !checkbox.checked; check.setVisible(checkbox.checked); if (callback) { callback(checkbox.checked); } }); return checkbox; } } // Make globally available window.UIHelpers = UIHelpers; console.log('🎨 UI Helpers loaded');