Skip to content

Commit

Permalink
Merge pull request #7 from devklick/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
devklick authored Oct 21, 2023
2 parents e3b9192 + 7a20cce commit a79e01a
Show file tree
Hide file tree
Showing 17 changed files with 120 additions and 33 deletions.
9 changes: 8 additions & 1 deletion src/components/AppSideBar/AppSideBar.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useSystemSettings from "../../stores/systemSettingsStore";
import { StyledItem, StyledItemContainer, StyledSideBar } from "./styles";

interface SideBarItem {
Expand All @@ -11,11 +12,17 @@ interface AppSideBarProps {
}

function AppSideBar({ items }: AppSideBarProps) {
const settings = useSystemSettings();
return (
<StyledSideBar>
<StyledItemContainer>
{items.map((item) => (
<StyledItem onClick={item.onClick} key={item.title}>
<StyledItem
onClick={item.onClick}
key={item.title}
active={item.isActive ?? false}
activeColor={settings.accentColor}
>
{item.title}
</StyledItem>
))}
Expand Down
6 changes: 4 additions & 2 deletions src/components/AppSideBar/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ export const StyledItemContainer = styled.div`
box-sizing: border-box;
`;

export const StyledItem = styled.div`
export const StyledItem = styled.div<{ active: boolean; activeColor: string }>`
border-radius: 10px;
padding: 6px 10px;
box-sizing: border-box;
box-shadow: 2px 2px 4px rgb(0, 0, 0, 0);
background-color: ${(props) =>
props.active ? props.activeColor : undefined};
&:hover {
backdrop-filter: brightness(150%);
background-color: ${(props) => props.activeColor};
transition: ease-in 0.2s;
}
&:active {
Expand Down
7 changes: 6 additions & 1 deletion src/components/BorderedApp/BorderedApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useRef } from "react";
import useWindowManagerStore, {
BaseProps,
} from "../../stores/windowManagerStore";
import { Dimensions } from "../../hooks/useDragToResize";
import { Dimensions, Position } from "../../hooks/useDragToResize";
import BorderedAppMenu from "./BorderedAppMenu/BorderedAppMenu";
import usePositionableElement from "../../hooks/usePositionableElement";
import useSystemSettings from "../../stores/systemSettingsStore";
Expand All @@ -27,6 +27,7 @@ interface BorderedAppProps extends BaseProps {
type: string;
id: string;
initialDimensions: Dimensions;
initialPosition: Position;
maxDimensions?: Dimensions;
minDimensions?: Dimensions;
menus?: Array<MenuItemProps>;
Expand All @@ -38,6 +39,7 @@ function BorderedApp({
id,
children,
initialDimensions,
initialPosition,
minDimensions = { height: 350, width: 350 },
menus,
zIndex,
Expand All @@ -64,19 +66,22 @@ function BorderedApp({
} = usePositionableElement({
elementRef: appRef,
minDimensions,
initialPosition,
windowType: type,
windowId: id,
});

function onClickClose() {
winMan.closeWindow(type, id);
}
console.log("Bordered app, hidden", String(hidden));

return (
<StyledBorderedApp
ref={appRef}
onMouseDown={() => winMan.focusWindow(type, id)}
initialDimensions={initialDimensions}
initialPosition={initialPosition}
zIndex={zIndex}
backgroundColor={settings.mainColor}
display={hidden === true ? "none" : "grid"}
Expand Down
5 changes: 4 additions & 1 deletion src/components/BorderedApp/styles.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import styled from "@emotion/styled";
import { Dimensions } from "../../hooks/useDragToResize";
import { Dimensions, Position } from "../../hooks/useDragToResize";

interface StyledBorderedAppProps {
initialDimensions: Dimensions;
initialPosition: Position;
zIndex: number | undefined;
backgroundColor: string;
display: "none" | "grid";
Expand All @@ -25,6 +26,8 @@ export const StyledBorderedApp = styled.div<StyledBorderedAppProps>`
z-index: ${(props) => props.zIndex};
background-color: ${(props) => props.backgroundColor};
display: ${(props) => props.display};
left: ${(props) => props.initialPosition.x}px;
top: ${(props) => props.initialPosition.y}px;
`;
export const StyledCorner = styled.div<{
location: "ne" | "se" | "sw" | "nw";
Expand Down
70 changes: 57 additions & 13 deletions src/components/BottomBar/Launcher/Launcher.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useRef } from "react";
import { useRef, useState } from "react";
import { v4 as uuid } from "uuid";

import useConditionalClick from "../../../hooks/useConditionalClick";
import useWindowManagerStore from "../../../stores/windowManagerStore";
import BorderedApp from "../../BorderedApp";
import { Dimensions } from "../../../hooks/useDragToResize";
import { Dimensions, Position } from "../../../hooks/useDragToResize";
import { MenuItemProps } from "../../MenuItems";

import { StyledIcon, StyledLauncher } from "./styles";
import ContextMenu from "../../ContextMenu";
interface LauncherProps {
windowType: string;
WindowTitle: string;
Expand All @@ -29,16 +30,31 @@ function Launcher({
}: React.PropsWithChildren<LauncherProps>) {
const winMan = useWindowManagerStore();
const ref = useRef<HTMLDivElement>(null);
const [contextOpen, setContextOpen] = useState(false);

function addWindow() {
const id = windowId ?? uuid();
const boundingRect = winMan.contentRef.current?.getBoundingClientRect();
function getInitialPosition(axis: "x" | "y"): number {
if (!boundingRect) return 0;
const dimension = axis === "x" ? "width" : "height";
return (
(boundingRect[axis] ?? 0) +
(boundingRect[dimension] ?? 0) / 2 -
initialDimensions[dimension] / 2
);
}
winMan.addWindow(windowType, id, {
component: BorderedApp,
props: {
id,
title: WindowTitle,
type: windowType,
initialDimensions,
initialPosition: {
x: getInitialPosition("x"),
y: getInitialPosition("y"),
},
menus,
},
key: id,
Expand All @@ -50,6 +66,7 @@ function Launcher({
// we want to focus them. This means revealing them if they
// are minimized and bring them to the top of the window stack.
if (winMan.windowsOfTypeExist(windowType)) {
console.log("Attempting to focus windows");
winMan.focusWindowsOfType(windowType);
return;
}
Expand All @@ -58,10 +75,7 @@ function Launcher({
addWindow();
}
function onRightClick() {
// TODO: Display a context menu with various options that are
// specified by the program-specific launcher and passed via props.
// This will include things like "open new window", "close windows", etc.
console.log("right clicked");
setContextOpen(true);
}

useConditionalClick({
Expand All @@ -76,14 +90,44 @@ function Launcher({
clickHandler: onRightClick,
});

function getContextMenu() {
const items: Array<MenuItemProps> = [
{
title: "New Window",
action: () => {
addWindow();
setContextOpen(false);
},
},
];
return (
<ContextMenu
close={() => setContextOpen(false)}
items={items}
position={getContextPosition(items.length)}
/>
);
}
function getContextPosition(numberOfItems: number): Position {
const rect = ref.current?.getBoundingClientRect();
if (!rect) return { x: 0, y: 0 };
console.log(rect);
return {
x: rect.x,
y: rect.y - 20 - numberOfItems * 30,
};
}
return (
<StyledLauncher ref={ref} tabIndex={1} className="launcher">
<StyledIcon
src={icon}
className="launcher-icon"
alt={windowType}
></StyledIcon>
</StyledLauncher>
<>
{contextOpen && getContextMenu()}
<StyledLauncher ref={ref} tabIndex={1} className="launcher">
<StyledIcon
src={icon}
className="launcher-icon"
alt={windowType}
></StyledIcon>
</StyledLauncher>
</>
);
}

Expand Down
2 changes: 2 additions & 0 deletions src/components/ContextMenu/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import MenuItems, { MenuItemProps } from "../MenuItems";
import useDetectMouseDownOutside from "../../hooks/useDetectMouseDownOutside";

import { StyledContextMenu } from "./styles";
import useBindKeyToAction from "../../hooks/useBindKeyToAction";

interface ContextMenuProps {
items: Array<MenuItemProps>;
Expand All @@ -14,6 +15,7 @@ function ContextMenu({ items, position, close }: ContextMenuProps) {
const elementRef = useRef<HTMLDivElement>(null);

useDetectMouseDownOutside({ elementRef, onMouseDown: close });
useBindKeyToAction({ keys: ["Escape"], action: close });

return (
<StyledContextMenu position={position} ref={elementRef}>
Expand Down
2 changes: 2 additions & 0 deletions src/components/MenuItems/MenuItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function MenuItem({
const hoverOpenDelayRef = useRef<NodeJS.Timeout>();
const hoverCloseDelayRef = useRef<NodeJS.Timeout>();
const [open, setOpen] = useState<boolean>(false);
const settings = useSystemSettings();

useEffect(() => {
return () => {
Expand Down Expand Up @@ -130,6 +131,7 @@ function MenuItem({
onClick={handleOnClick}
onMouseEnter={handleOnMouseEnter}
onMouseLeave={handleOnMouseLeave}
hoverColor={settings.accentColor}
>
<span>{title}</span>
{items && open && (
Expand Down
5 changes: 4 additions & 1 deletion src/components/MenuItems/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export const StyledItemsContent = styled.div`
box-sizing: border-box;
`;

export const StyledMenuItem = styled.div`
export const StyledMenuItem = styled.div<{ hoverColor: string }>`
padding: 5px 12px;
height: 20px;
:hover {
background-color: ${(props) => props.hoverColor};
}
`;
10 changes: 6 additions & 4 deletions src/hooks/usePositionableElement.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useRef } from "react";
import useDragToResize, { Dimensions, Rect } from "./useDragToResize";
import useDragToResize, { Dimensions, Position, Rect } from "./useDragToResize";
import useDragToMove from "./useDragToMove";
import useWindowMinMax from "./useWindowMinMax";

Expand All @@ -8,6 +8,7 @@ interface UsePositionableElementProps {
minDimensions: Dimensions;
windowType: string;
windowId: string;
initialPosition: Position;
}

/**
Expand All @@ -21,6 +22,7 @@ function usePositionableElement({
minDimensions,
windowType,
windowId,
initialPosition,
}: UsePositionableElementProps) {
// Hold a single ref for the elements rect,
// so we dont have to call getBoundingClientRect every
Expand All @@ -40,11 +42,11 @@ function usePositionableElement({
elementRect.current = {
height: rect.height,
width: rect.width,
left: rect.left,
top: rect.top,
left: initialPosition.x,
top: initialPosition.y,
};
}
}, [elementRef]);
}, [elementRef, initialPosition.x, initialPosition.y]);

// The resize hook allows the app to be resized
// by dragging the corners or edges of the element.
Expand Down
3 changes: 1 addition & 2 deletions src/hooks/useWindowMinMax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,11 @@ function useWindowMinMax({
const window = windowRef.current;
if (!window?.style) return;
if (e.target !== window) return;
winMan.hideWindow(windowType, windowId);

window.style.display = "none";
window.style.transition = oldTransition.current;
window.style.transform = oldTransform.current;
window.style.opacity = oldOpacity.current;
winMan.hideWindow(windowType, windowId);
}

useEffect(() => {
Expand Down
1 change: 1 addition & 0 deletions src/programs/Calculator/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const StyledInputOutput = styled.div<{
direction: "input" | "output";
}>`
box-shadow: 0px 0px 4px rgb(0, 0, 0, 0.5) inset;
font-size: ${(props) => (props.direction === "input" ? 22 : 18)}px;
width: 100%;
height: 100%;
display: flex;
Expand Down
7 changes: 6 additions & 1 deletion src/programs/FileBrowser/DirectoryOrFile/DirectoryOrFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import InputField from "../../../components/InputField";
import Row from "../../../components/Row";
import Button from "../../../components/Button";
import { StyledFolderIcon, StyledItem, StyledItemName } from "./styles";
import useSystemSettings from "../../../stores/systemSettingsStore";

interface DirectoryOrFileProps {
fsObject: FSObject;
Expand All @@ -38,6 +39,7 @@ function DirectoryOrFile({
const [contextAction, setContextAction] = useState<ContextMenuAction | null>(
null
);
const settings = useSystemSettings();

function handleRightClick(event: React.MouseEvent) {
clickPosition.current = { x: event.clientX, y: event.clientY };
Expand All @@ -49,6 +51,7 @@ function DirectoryOrFile({
return (
<StyledItem
selected={selected}
selectedColor={settings.accentColor}
onDoubleClick={() => openFSObject(fsObject)}
onClick={() => setSelected(fsObject.path)}
key={fsObject.path}
Expand Down Expand Up @@ -81,7 +84,9 @@ function DirectoryOrFile({
fsObject={fsObject}
/>
)}
{isFSDirectory(fsObject) ? <StyledFolderIcon /> : null}
{isFSDirectory(fsObject) ? (
<StyledFolderIcon fillColor={settings.iconColor} />
) : null}
<StyledItemName>{fsObject.name}</StyledItemName>
</StyledItem>
);
Expand Down
Loading

0 comments on commit a79e01a

Please sign in to comment.