Added window opening and closing

This commit is contained in:
Prozilla 2023-07-16 14:58:31 +02:00
parent 0008d7dc4b
commit 30046b6f77
No known key found for this signature in database
GPG key ID: 5858DFE71CAF31EE
11 changed files with 133 additions and 49 deletions

View file

@ -2,7 +2,7 @@
ProzillaOS is a web operating system inspired by Ubuntu Linux and Windows made with React by Prozilla. It aims to function much like a real operating system, with the exception of running entirely on the web.
> Please note that ProzillaOS is far from complete and many additional features will be added in the future.
> Please note that ProzillaOS is a WIP and far from complete and many additional features will be added in the future.
## Features

View file

@ -1,22 +1,16 @@
import { useEffect, useState } from "react";
import "./App.css";
import { TaskBar } from "./components/TaskBar.js";
import WindowsManager from "./modules/windows/windows.js";
export const windowsManager = new WindowsManager();
import { WindowsManagerProvider } from "./hooks/WindowsManagerContext.js";
import { WindowsView } from "./components/WindowsView.js";
function App() {
const [windows, setWindows] = useState([]);
useEffect(() => {
setWindows(Object.values(windowsManager.windows));
}, []);
return (
<div className="App">
<TaskBar/>
{windows}
</div>
<WindowsManagerProvider>
<div className="App">
<TaskBar/>
<WindowsView/>
</div>
</WindowsManagerProvider>
);
}

View file

@ -23,6 +23,7 @@
cursor: pointer;
border: none;
outline: none;
transition: background-color 100ms ease-in-out;
}
.Task-bar button:hover {

View file

@ -4,10 +4,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBatteryFull, faSearch, faVolumeHigh, faWifi } from "@fortawesome/free-solid-svg-icons";
import { ReactSVG } from "react-svg";
import ApplicationsManager from "../modules/applications/applications.js";
import { windowsManager } from "../App.js";
import { useWindowsManager } from "../hooks/WindowsManagerContext.js";
export function TaskBar() {
const [date, setDate] = useState(new Date());
const windowsManager = useWindowsManager();
useEffect(() => {
setInterval(() => {
@ -21,11 +22,11 @@ export function TaskBar() {
<button>
<FontAwesomeIcon icon={faSearch}/>
</button>
{ApplicationsManager.APPLICATIONS.forEach((app) =>
<button key={app.id} onClick={windowsManager.open(app.id)}>
{ApplicationsManager.APPLICATIONS.map((app) => {
return (<button key={app.id} onClick={() => { windowsManager.open(app.id); }}>
<ReactSVG src={process.env.PUBLIC_URL + `/media/applications/icons/${app.id}.svg`}/>
</button>
)}
</button>);
})}
</div>
<div className="Util-icons">
<button>

View file

@ -3,11 +3,14 @@ import "./Window.css";
import { faMinus, faXmark } from "@fortawesome/free-solid-svg-icons";
import { faSquare } from "@fortawesome/free-regular-svg-icons";
import { ReactSVG } from "react-svg";
import { windowsManager } from "../App.js";
import { useWindowsManager } from "../hooks/WindowsManagerContext.js";
export function Window({ id, app, size, position, focused = false, minimized = false, maximized = false }) {
const windowsManager = useWindowsManager();
return (
<div
key={id}
className="Window-container"
style={{
width: size.x,
@ -25,7 +28,7 @@ export function Window({ id, app, size, position, focused = false, minimized = f
<button>
<FontAwesomeIcon icon={faSquare}/>
</button>
<button onClick={windowsManager.close(id)}>
<button onClick={() => { windowsManager.close(id); }}>
<FontAwesomeIcon icon={faXmark}/>
</button>
</div>

View file

@ -0,0 +1,18 @@
import { Window } from "./Window.js";
import { useWindows } from "../hooks/WindowsContext.js";
export function WindowsView() {
const windows = useWindows();
return (<div>
{windows.map(({ id, app, size, position}) =>
<Window
id={id}
key={id}
app={app}
size={size}
position={position}
/>
)}
</div>);
}

View file

@ -0,0 +1,26 @@
import { createContext, useCallback, useContext, useState } from "react";
const WindowsContext = createContext();
/**
* @returns {React.Provider<any>}
*/
export function WindowsProvider({ children, windowsManager }) {
const [windows, setWindows] = useState([]);
const updateWindows = useCallback((updatedWindows) => {
setWindows(Object.values(updatedWindows));
}, []);
windowsManager.setUpdateWindows(updateWindows);
return (
<WindowsContext.Provider value={windows}>
{children}
</WindowsContext.Provider>
);
}
export function useWindows() {
return useContext(WindowsContext);
}

View file

@ -0,0 +1,27 @@
import { createContext, useContext } from "react";
import WindowsManager from "../modules/windows/windows.js";
import { WindowsProvider } from "./WindowsContext.js";
const WindowsManagerContext = createContext();
/**
* @returns {React.Provider<any>}
*/
export function WindowsManagerProvider({ children }) {
const windowsManager = new WindowsManager();
return (
<WindowsManagerContext.Provider value={windowsManager}>
<WindowsProvider windowsManager={windowsManager}>
{children}
</WindowsProvider>
</WindowsManagerContext.Provider>
);
}
/**
* @returns {WindowsManager}
*/
export function useWindowsManager() {
return useContext(WindowsManagerContext);
}

View file

@ -1,13 +1,5 @@
export default class Application {
constructor(name, id) {
Object.assign(this, { name, id });
}
start() {
}
stop() {
constructor(name, id, windowContent) {
Object.assign(this, { name, id, windowContent });
}
}

View file

@ -1,3 +1,4 @@
/* eslint-disable eqeqeq */
import Application from "./application.js";
export default class ApplicationsManager {
@ -9,7 +10,7 @@ export default class ApplicationsManager {
let application = null;
this.APPLICATIONS.forEach((app) => {
if (app.id === id) {
if (app.id == id) {
application = app;
return;
}

View file

@ -1,40 +1,61 @@
import { Window } from "../../components/Window.js";
import ApplicationsManager from "../applications/applications.js";
import Vector2 from "../math/vector2.js";
export default class WindowsManager {
windows = {};
constructor() {
this.windows = {};
this.updateWindows = () => {};
console.log("Windows manager init");
}
open(appId) {
const appData = ApplicationsManager.getApplication(appId);
const app = ApplicationsManager.getApplication(appId);
const size = new Vector2(800, 400);
const position = new Vector2(300, 200);
let id = 0;
while (Object.keys(this.windows).includes(id)) {
while (this.windowIds.includes(id.toString())) {
id++;
}
console.log(`Opening window ${id}:${appData.id}`);
console.log(`Opening window ${id}:${app.id}`);
this.windows[id] = <Window
id={id}
key={id}
app={appData}
size={size}
position={position}
/>;
this.windows[id.toString()] = {
id,
app,
size,
position
};
this.updateWindows(this.windows);
// console.log(this);
}
close(windowId) {
if (!Object.keys(this.windows).includes(windowId))
return;
windowId = windowId.toString();
if (!this.windowIds.includes(windowId)) {
console.log(`Failed to close window ${windowId}: window not found`);
return;
}
console.log(`Closing window ${windowId}`);
delete this.windows[windowId];
this.updateWindows(this.windows);
// console.log(this);
}
get windowsCount() {
return Object.keys(this.windows).length;
setUpdateWindows(updateWindows) {
this.updateWindows = updateWindows;
}
get windowIds() {
return Object.keys(this.windows);
}
get windowsData() {
return Object.values(this.windows);
}
}