Files
novafarma/src/ui/UIHelpers.js

313 lines
8.5 KiB
JavaScript

/**
* 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');