Skip to content

Commit bc9f521

Browse files
committed
Support apps with max size
1 parent 0e2eafe commit bc9f521

6 files changed

Lines changed: 62 additions & 23 deletions

File tree

src/components/BorderedApp/BorderedApp.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ function BorderedApp({
4242
initialDimensions,
4343
initialPosition,
4444
minDimensions = { height: 350, width: 350 },
45+
maxDimensions,
4546
menus,
4647
zIndex,
4748
hidden,
@@ -67,6 +68,7 @@ function BorderedApp({
6768
} = usePositionableElement({
6869
elementRef: appRef,
6970
minDimensions,
71+
maxDimensions,
7072
initialPosition,
7173
windowType: type,
7274
windowId: id,

src/components/BottomBar/Launcher/Launcher.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ interface LauncherProps {
1414
WindowTitle: string;
1515
windowId?: string;
1616
initialDimensions: Dimensions;
17+
minDimensions?: Dimensions;
18+
maxDimensions?: Dimensions;
1719
menus?: Array<MenuItemProps>;
1820
appContent: JSX.Element;
1921
icon: string;
@@ -24,6 +26,8 @@ function Launcher({
2426
windowId,
2527
WindowTitle,
2628
initialDimensions,
29+
minDimensions,
30+
maxDimensions,
2731
menus,
2832
appContent,
2933
icon,
@@ -51,6 +55,8 @@ function Launcher({
5155
title: WindowTitle,
5256
type: windowType,
5357
initialDimensions,
58+
minDimensions,
59+
maxDimensions,
5460
initialPosition: {
5561
x: getInitialPosition("x"),
5662
y: getInitialPosition("y"),

src/hooks/useDragToResize.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,20 @@ export interface Position {
2020
type MouseMovementHandler = (
2121
initialRect: Partial<Rect>,
2222
mouseDownPosition: Position,
23-
mouseMoveEvent: MouseEvent
23+
mouseMoveEvent: MouseEvent,
2424
) => number;
2525

2626
interface UseDragToResizeProps {
2727
elementRef: React.RefObject<HTMLElement>;
2828
elementRect: MutableRefObject<Partial<Rect>>;
2929
minDimensions: Dimensions;
30+
maxDimensions?: Dimensions;
3031
}
3132

3233
function useDragToResize({
3334
elementRef,
3435
minDimensions,
36+
maxDimensions,
3537
elementRect,
3638
}: UseDragToResizeProps) {
3739
const resizeHandleN = useRef<HTMLDivElement>(null);
@@ -86,7 +88,11 @@ function useDragToResize({
8688
const newLeft =
8789
leftFn?.(initialRect, startPos, mouseMoveEvent) ?? initialRect.left;
8890

89-
if (newWidth >= minDimensions.width) {
91+
if (
92+
newWidth >= minDimensions.width &&
93+
(!maxDimensions || newWidth <= maxDimensions.width)
94+
) {
95+
console.log("maxwidth", maxDimensions?.width, "new width", newWidth);
9096
elementRect.current.width = newWidth;
9197
elementRef.current.style.width = `${elementRect.current.width}px`;
9298
elementRect.current.left = newLeft;
@@ -101,7 +107,10 @@ function useDragToResize({
101107
const newTop =
102108
topFn?.(initialRect, startPos, mouseMoveEvent) ?? initialRect.top;
103109

104-
if (newHeight >= minDimensions.height) {
110+
if (
111+
newHeight >= minDimensions.height &&
112+
(!maxDimensions || newHeight <= maxDimensions.height)
113+
) {
105114
elementRect.current.height = newHeight;
106115
elementRef.current.style.height = `${elementRect.current.height}px`;
107116
elementRect.current.top = newTop;
@@ -122,37 +131,37 @@ function useDragToResize({
122131
const nHeightFn: MouseMovementHandler = (
123132
initialRect,
124133
mouseDownPosition,
125-
mouseMoveEvent
134+
mouseMoveEvent,
126135
) => (initialRect.height ?? 0) + mouseDownPosition.y - mouseMoveEvent.pageY;
127136

128137
const nTopFn: MouseMovementHandler = (
129138
initialRect,
130139
mouseDownPosition,
131-
mouseMoveEvent
140+
mouseMoveEvent,
132141
) => (initialRect.top ?? 0) - mouseDownPosition.y + mouseMoveEvent.pageY;
133142

134143
const eWidthFn: MouseMovementHandler = (
135144
initialRect,
136145
mouseDownPosition,
137-
mouseMoveEvent
146+
mouseMoveEvent,
138147
) => (initialRect.width ?? 0) - mouseDownPosition.x + mouseMoveEvent.pageX;
139148

140149
const sHeightFn: MouseMovementHandler = (
141150
initialRect,
142151
mouseDownPosition,
143-
mouseMoveEvent
152+
mouseMoveEvent,
144153
) => (initialRect.height ?? 0) - mouseDownPosition.y + mouseMoveEvent.pageY;
145154

146155
const wWidthFn: MouseMovementHandler = (
147156
initialRect,
148157
mouseDownPosition,
149-
mouseMoveEvent
158+
mouseMoveEvent,
150159
) => (initialRect.width ?? 0) + mouseDownPosition.x - mouseMoveEvent.pageX;
151160

152161
const wLeftFn: MouseMovementHandler = (
153162
initialRect,
154163
mouseDownPosition,
155-
mouseMoveEvent
164+
mouseMoveEvent,
156165
) => (initialRect.left ?? 0) - mouseDownPosition.x + mouseMoveEvent.pageX;
157166
//#endregion
158167

@@ -242,19 +251,19 @@ function useDragToResize({
242251
_resizeWRef?.current?.removeEventListener("mousedown", handleMouseDownW);
243252
_resizeNERef?.current?.removeEventListener(
244253
"mousedown",
245-
handleMouseDownNE
254+
handleMouseDownNE,
246255
);
247256
_resizeSERef?.current?.removeEventListener(
248257
"mousedown",
249-
handleMouseDownSE
258+
handleMouseDownSE,
250259
);
251260
_resizeSWRef?.current?.removeEventListener(
252261
"mousedown",
253-
handleMouseDownSW
262+
handleMouseDownSW,
254263
);
255264
_resizeNWRef?.current?.removeEventListener(
256265
"mousedown",
257-
handleMouseDownNW
266+
handleMouseDownNW,
258267
);
259268
};
260269
//#endregion

src/hooks/usePositionableElement.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import useWindowMinMax from "./useWindowMinMax";
66
interface UsePositionableElementProps {
77
elementRef: React.RefObject<HTMLElement>;
88
minDimensions: Dimensions;
9+
maxDimensions?: Dimensions;
910
windowType: string;
1011
windowId: string;
1112
initialPosition: Position;
@@ -20,6 +21,7 @@ interface UsePositionableElementProps {
2021
function usePositionableElement({
2122
elementRef,
2223
minDimensions,
24+
maxDimensions,
2325
windowType,
2426
windowId,
2527
initialPosition,
@@ -56,6 +58,7 @@ function usePositionableElement({
5658
elementRef,
5759
elementRect,
5860
minDimensions,
61+
maxDimensions,
5962
});
6063

6164
// The move hook allows the app to be moved when
@@ -71,6 +74,7 @@ function usePositionableElement({
7174
const { maximize, minimize } = useWindowMinMax({
7275
windowRef: elementRef,
7376
windowRect: elementRect,
77+
maxDimensions,
7478
windowType,
7579
windowId,
7680
});

src/hooks/useWindowMinMax.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { MutableRefObject, useEffect, useRef } from "react";
22
import useWindowManagerStore from "../stores/windowManagerStore";
3-
import { Rect } from "./useDragToResize";
3+
import { Dimensions, Rect } from "./useDragToResize";
44

55
function toPx(value: number) {
66
return `${value}px`;
@@ -9,6 +9,7 @@ function toPx(value: number) {
99
interface UseWindowMinMaxProps {
1010
windowRef: React.RefObject<HTMLElement>;
1111
windowRect: MutableRefObject<Partial<Rect>>;
12+
maxDimensions?: Dimensions;
1213
windowType: string;
1314
windowId: string;
1415
}
@@ -17,6 +18,7 @@ function useWindowMinMax({
1718
windowRef,
1819
windowId,
1920
windowType,
21+
maxDimensions,
2022
}: UseWindowMinMaxProps) {
2123
const winMan = useWindowManagerStore();
2224
const oldTransition = useRef<string>("");
@@ -28,15 +30,26 @@ function useWindowMinMax({
2830
const window = windowRef.current;
2931
if (!boundary || !window) return;
3032

31-
windowRect.current.top = boundary.y;
32-
windowRect.current.left = boundary.x;
33-
windowRect.current.width = boundary.width;
34-
windowRect.current.height = boundary.height;
33+
// If the window/app being maximised has max dimensions set (present via maxDimensions prop)
34+
// then we'll leave it's anchor (top/left) in the current position and just
35+
// increase the width and height to the max allowed values
36+
if (maxDimensions) {
37+
windowRect.current.width = maxDimensions.width;
38+
windowRect.current.height = maxDimensions.height;
39+
window.style.width = toPx(maxDimensions.width);
40+
window.style.height = toPx(maxDimensions.height);
41+
} else {
42+
// For windows/apps that do not have a max set, we max them to fill the main content area
43+
windowRect.current.top = boundary.y;
44+
windowRect.current.left = boundary.x;
45+
windowRect.current.width = boundary.width;
46+
windowRect.current.height = boundary.height;
3547

36-
window.style.top = toPx(boundary.y);
37-
window.style.left = toPx(boundary.x);
38-
window.style.width = toPx(boundary.width);
39-
window.style.height = toPx(boundary.height);
48+
window.style.top = toPx(boundary.y);
49+
window.style.left = toPx(boundary.x);
50+
window.style.width = toPx(boundary.width);
51+
window.style.height = toPx(boundary.height);
52+
}
4053
}
4154

4255
function minimize() {
@@ -47,6 +60,8 @@ function useWindowMinMax({
4760
oldTransform.current = window.style.transform;
4861
oldOpacity.current = window.style.opacity;
4962

63+
// TODO: this is a crap animation and could deffo be improved.
64+
// Consider using gsap, motion etc to do something a little nicer.
5065
window.style.transition = "all 0.2s linear";
5166
window.style.opacity = "0";
5267
window.style.transform = "scale(0.2) translate(0, 500%)";

src/programs/Calculator/CalculatorLauncher/CalculatorLauncher.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ function CalculatorLauncher({}: CalculatorLauncherProps) {
1111
<Launcher
1212
windowType={windowType}
1313
WindowTitle="Calculator"
14+
// TODO: Consider supoprting an `allowResize` prop, instead of having to repeat the initial dimensions for both min and max
1415
initialDimensions={{ height: 400, width: 400 }}
16+
maxDimensions={{ height: 400, width: 400 }}
17+
minDimensions={{ height: 400, width: 400 }}
1518
icon=""
1619
menus={[]}
1720
appContent={<Calculator />}
18-
></Launcher>
21+
/>
1922
);
2023
}
2124

0 commit comments

Comments
 (0)