feat: add calculator app
This commit is contained in:
parent
1664b40480
commit
5734a26cb1
|
@ -87,6 +87,14 @@ useResizable(windowRef, {
|
|||
onResizeStart: () => { isResizing.value = true; },
|
||||
onResizeEnd: () => { isResizing.value = false; },
|
||||
constraints: draggableConstraints,
|
||||
maxSize: {
|
||||
width: props.instance.maxWidth,
|
||||
height: props.instance.maxHeight
|
||||
},
|
||||
minSize: {
|
||||
width: props.instance.minWidth,
|
||||
height: props.instance.minHeight
|
||||
},
|
||||
enabled: isDraggableAndResizable,
|
||||
});
|
||||
|
||||
|
|
|
@ -135,8 +135,9 @@ const formattedDisplay = computed(() => {
|
|||
background: var(--window-background);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
min-height: 400px; /* Ensure minimum height for all buttons */
|
||||
}
|
||||
|
||||
.display {
|
||||
|
@ -145,16 +146,17 @@ const formattedDisplay = computed(() => {
|
|||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
min-height: 60px;
|
||||
min-height: 55px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-shrink: 0; /* Prevent display from shrinking */
|
||||
}
|
||||
|
||||
.display-value {
|
||||
color: #00ff00;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 24px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
|
@ -166,19 +168,21 @@ const formattedDisplay = computed(() => {
|
|||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
flex: 1;
|
||||
min-height: 300px; /* Ensure enough space for all button rows */
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 50px;
|
||||
min-height: 48px;
|
||||
max-height: 65px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
|
|
|
@ -15,6 +15,8 @@ interface ResizeOptions {
|
|||
initialSize: { width: number; height: number; };
|
||||
initialPosition: { x: number; y: number; };
|
||||
constraints?: Ref<Constraints | undefined>;
|
||||
maxSize?: { width?: number; height?: number; };
|
||||
minSize?: { width?: number; height?: number; };
|
||||
enabled: Ref<boolean>;
|
||||
}
|
||||
|
||||
|
@ -22,7 +24,7 @@ export function useResizable(
|
|||
target: Ref<HTMLElement | null>,
|
||||
options: ResizeOptions
|
||||
) {
|
||||
const { onResize, onResizeStart, onResizeEnd, initialSize, initialPosition, constraints, enabled } = options;
|
||||
const { onResize, onResizeStart, onResizeEnd, initialSize, initialPosition, constraints, maxSize, minSize, enabled } = options;
|
||||
|
||||
let activeHandle: string | null = null;
|
||||
let initialMouseX = 0;
|
||||
|
@ -83,8 +85,19 @@ export function useResizable(
|
|||
if (y + height > bottom) { height = bottom - y; }
|
||||
}
|
||||
|
||||
width = Math.max(200, width);
|
||||
height = Math.max(150, height);
|
||||
// Apply minimum size constraints
|
||||
const minWidth = minSize?.width || 200;
|
||||
const minHeight = minSize?.height || 150;
|
||||
width = Math.max(minWidth, width);
|
||||
height = Math.max(minHeight, height);
|
||||
|
||||
// Apply maximum size constraints
|
||||
if (maxSize?.width) {
|
||||
width = Math.min(maxSize.width, width);
|
||||
}
|
||||
if (maxSize?.height) {
|
||||
height = Math.min(maxSize.height, height);
|
||||
}
|
||||
|
||||
onResize({ x, y, width, height });
|
||||
};
|
||||
|
|
19
lang/en.json
19
lang/en.json
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"startMenu": {
|
||||
"about": "About This Project",
|
||||
"systemSettings": "System Settings...",
|
||||
"toggleTheme": "Toggle Theme",
|
||||
"signOut": "Sign Out",
|
||||
"closeAllWindows": "Close All Windows"
|
||||
},
|
||||
"taskbar": {
|
||||
"language": "Language",
|
||||
"currentLanguage": "EN"
|
||||
},
|
||||
"common": {
|
||||
"createWindow": "Create Window",
|
||||
"close": "Close",
|
||||
"minimize": "Minimize",
|
||||
"maximize": "Maximize"
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"startMenu": {
|
||||
"about": "關於這個專案",
|
||||
"systemSettings": "系統設定...",
|
||||
"toggleTheme": "切換主題",
|
||||
"signOut": "登出",
|
||||
"closeAllWindows": "關閉所有視窗"
|
||||
},
|
||||
"taskbar": {
|
||||
"language": "語言",
|
||||
"currentLanguage": "注"
|
||||
},
|
||||
"common": {
|
||||
"createWindow": "建立視窗",
|
||||
"close": "關閉",
|
||||
"minimize": "最小化",
|
||||
"maximize": "最大化"
|
||||
}
|
||||
}
|
|
@ -22,6 +22,10 @@ export interface AppInstance {
|
|||
isMinimized: boolean;
|
||||
isMaximized: boolean;
|
||||
isFocused: boolean;
|
||||
maxWidth?: number;
|
||||
maxHeight?: number;
|
||||
minWidth?: number;
|
||||
minHeight?: number;
|
||||
}
|
||||
|
||||
let appInstanceIdCounter = 0;
|
||||
|
@ -61,6 +65,60 @@ export const useAppsStore = defineStore('apps', () => {
|
|||
return appInstances.value.find(instance => instance.isFocused);
|
||||
});
|
||||
|
||||
// Get default size and constraints for specific app
|
||||
function getAppSizeConstraints(appId: string) {
|
||||
const appConstraints: Record<string, {
|
||||
width: number;
|
||||
height: number;
|
||||
maxWidth?: number;
|
||||
maxHeight?: number;
|
||||
minWidth?: number;
|
||||
minHeight?: number;
|
||||
}> = {
|
||||
'calculator': {
|
||||
width: 300,
|
||||
height: 450,
|
||||
maxWidth: 350, // Prevent calculator from getting too wide
|
||||
maxHeight: 500, // Prevent calculator from getting too tall
|
||||
minWidth: 250, // Minimum usable width
|
||||
minHeight: 400 // Minimum usable height
|
||||
},
|
||||
'text-editor': {
|
||||
width: 600,
|
||||
height: 400,
|
||||
maxWidth: 1200,
|
||||
maxHeight: 800,
|
||||
minWidth: 400,
|
||||
minHeight: 300
|
||||
},
|
||||
'file-manager': {
|
||||
width: 800,
|
||||
height: 500,
|
||||
maxWidth: 1400,
|
||||
maxHeight: 900,
|
||||
minWidth: 600,
|
||||
minHeight: 400
|
||||
},
|
||||
'web-browser': {
|
||||
width: 1000,
|
||||
height: 600,
|
||||
maxWidth: 1600,
|
||||
maxHeight: 1000,
|
||||
minWidth: 800,
|
||||
minHeight: 500
|
||||
},
|
||||
};
|
||||
|
||||
return appConstraints[appId] || {
|
||||
width: 400,
|
||||
height: 300,
|
||||
maxWidth: 800,
|
||||
maxHeight: 600,
|
||||
minWidth: 300,
|
||||
minHeight: 200
|
||||
};
|
||||
}
|
||||
|
||||
// Actions
|
||||
function launchApp(appId: string) {
|
||||
const app = getAppById.value(appId);
|
||||
|
@ -69,6 +127,7 @@ export const useAppsStore = defineStore('apps', () => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const constraints = getAppSizeConstraints(appId);
|
||||
const newInstanceId = appInstanceIdCounter++;
|
||||
const newInstance: AppInstance = {
|
||||
id: `app-${appId}-${newInstanceId}`,
|
||||
|
@ -76,12 +135,16 @@ export const useAppsStore = defineStore('apps', () => {
|
|||
title: `${app.name} #${newInstanceId + 1}`,
|
||||
x: Math.random() * 200 + 50,
|
||||
y: Math.random() * 100 + 50 + 48, // Below taskbar
|
||||
width: 320,
|
||||
height: 400,
|
||||
width: constraints.width,
|
||||
height: constraints.height,
|
||||
zIndex: nextZIndex.value++,
|
||||
isMinimized: false,
|
||||
isMaximized: false,
|
||||
isFocused: true,
|
||||
maxWidth: constraints.maxWidth,
|
||||
maxHeight: constraints.maxHeight,
|
||||
minWidth: constraints.minWidth,
|
||||
minHeight: constraints.minHeight,
|
||||
};
|
||||
|
||||
// Unfocus all other instances
|
||||
|
|
Loading…
Reference in New Issue