Added window opening and closing
This commit is contained in:
parent
0008d7dc4b
commit
30046b6f77
11 changed files with 133 additions and 49 deletions
|
|
@ -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.
|
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
|
## Features
|
||||||
|
|
||||||
|
|
|
||||||
22
src/App.js
22
src/App.js
|
|
@ -1,22 +1,16 @@
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import { TaskBar } from "./components/TaskBar.js";
|
import { TaskBar } from "./components/TaskBar.js";
|
||||||
import WindowsManager from "./modules/windows/windows.js";
|
import { WindowsManagerProvider } from "./hooks/WindowsManagerContext.js";
|
||||||
|
import { WindowsView } from "./components/WindowsView.js";
|
||||||
export const windowsManager = new WindowsManager();
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [windows, setWindows] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setWindows(Object.values(windowsManager.windows));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<WindowsManagerProvider>
|
||||||
<TaskBar/>
|
<div className="App">
|
||||||
{windows}
|
<TaskBar/>
|
||||||
</div>
|
<WindowsView/>
|
||||||
|
</div>
|
||||||
|
</WindowsManagerProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
transition: background-color 100ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Task-bar button:hover {
|
.Task-bar button:hover {
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faBatteryFull, faSearch, faVolumeHigh, faWifi } from "@fortawesome/free-solid-svg-icons";
|
import { faBatteryFull, faSearch, faVolumeHigh, faWifi } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { ReactSVG } from "react-svg";
|
import { ReactSVG } from "react-svg";
|
||||||
import ApplicationsManager from "../modules/applications/applications.js";
|
import ApplicationsManager from "../modules/applications/applications.js";
|
||||||
import { windowsManager } from "../App.js";
|
import { useWindowsManager } from "../hooks/WindowsManagerContext.js";
|
||||||
|
|
||||||
export function TaskBar() {
|
export function TaskBar() {
|
||||||
const [date, setDate] = useState(new Date());
|
const [date, setDate] = useState(new Date());
|
||||||
|
const windowsManager = useWindowsManager();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
|
@ -21,11 +22,11 @@ export function TaskBar() {
|
||||||
<button>
|
<button>
|
||||||
<FontAwesomeIcon icon={faSearch}/>
|
<FontAwesomeIcon icon={faSearch}/>
|
||||||
</button>
|
</button>
|
||||||
{ApplicationsManager.APPLICATIONS.forEach((app) =>
|
{ApplicationsManager.APPLICATIONS.map((app) => {
|
||||||
<button key={app.id} onClick={windowsManager.open(app.id)}>
|
return (<button key={app.id} onClick={() => { windowsManager.open(app.id); }}>
|
||||||
<ReactSVG src={process.env.PUBLIC_URL + `/media/applications/icons/${app.id}.svg`}/>
|
<ReactSVG src={process.env.PUBLIC_URL + `/media/applications/icons/${app.id}.svg`}/>
|
||||||
</button>
|
</button>);
|
||||||
)}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="Util-icons">
|
<div className="Util-icons">
|
||||||
<button>
|
<button>
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,14 @@ import "./Window.css";
|
||||||
import { faMinus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faMinus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faSquare } from "@fortawesome/free-regular-svg-icons";
|
import { faSquare } from "@fortawesome/free-regular-svg-icons";
|
||||||
import { ReactSVG } from "react-svg";
|
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 }) {
|
export function Window({ id, app, size, position, focused = false, minimized = false, maximized = false }) {
|
||||||
|
const windowsManager = useWindowsManager();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
key={id}
|
||||||
className="Window-container"
|
className="Window-container"
|
||||||
style={{
|
style={{
|
||||||
width: size.x,
|
width: size.x,
|
||||||
|
|
@ -25,7 +28,7 @@ export function Window({ id, app, size, position, focused = false, minimized = f
|
||||||
<button>
|
<button>
|
||||||
<FontAwesomeIcon icon={faSquare}/>
|
<FontAwesomeIcon icon={faSquare}/>
|
||||||
</button>
|
</button>
|
||||||
<button onClick={windowsManager.close(id)}>
|
<button onClick={() => { windowsManager.close(id); }}>
|
||||||
<FontAwesomeIcon icon={faXmark}/>
|
<FontAwesomeIcon icon={faXmark}/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
18
src/components/WindowsView.js
Normal file
18
src/components/WindowsView.js
Normal 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>);
|
||||||
|
}
|
||||||
26
src/hooks/WindowsContext.js
Normal file
26
src/hooks/WindowsContext.js
Normal 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);
|
||||||
|
}
|
||||||
27
src/hooks/WindowsManagerContext.js
Normal file
27
src/hooks/WindowsManagerContext.js
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,5 @@
|
||||||
export default class Application {
|
export default class Application {
|
||||||
constructor(name, id) {
|
constructor(name, id, windowContent) {
|
||||||
Object.assign(this, { name, id });
|
Object.assign(this, { name, id, windowContent });
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable eqeqeq */
|
||||||
import Application from "./application.js";
|
import Application from "./application.js";
|
||||||
|
|
||||||
export default class ApplicationsManager {
|
export default class ApplicationsManager {
|
||||||
|
|
@ -9,7 +10,7 @@ export default class ApplicationsManager {
|
||||||
let application = null;
|
let application = null;
|
||||||
|
|
||||||
this.APPLICATIONS.forEach((app) => {
|
this.APPLICATIONS.forEach((app) => {
|
||||||
if (app.id === id) {
|
if (app.id == id) {
|
||||||
application = app;
|
application = app;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,61 @@
|
||||||
import { Window } from "../../components/Window.js";
|
|
||||||
import ApplicationsManager from "../applications/applications.js";
|
import ApplicationsManager from "../applications/applications.js";
|
||||||
import Vector2 from "../math/vector2.js";
|
import Vector2 from "../math/vector2.js";
|
||||||
|
|
||||||
export default class WindowsManager {
|
export default class WindowsManager {
|
||||||
windows = {};
|
constructor() {
|
||||||
|
this.windows = {};
|
||||||
|
this.updateWindows = () => {};
|
||||||
|
console.log("Windows manager init");
|
||||||
|
}
|
||||||
|
|
||||||
open(appId) {
|
open(appId) {
|
||||||
const appData = ApplicationsManager.getApplication(appId);
|
const app = ApplicationsManager.getApplication(appId);
|
||||||
const size = new Vector2(800, 400);
|
const size = new Vector2(800, 400);
|
||||||
const position = new Vector2(300, 200);
|
const position = new Vector2(300, 200);
|
||||||
|
|
||||||
let id = 0;
|
let id = 0;
|
||||||
while (Object.keys(this.windows).includes(id)) {
|
while (this.windowIds.includes(id.toString())) {
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Opening window ${id}:${appData.id}`);
|
console.log(`Opening window ${id}:${app.id}`);
|
||||||
|
|
||||||
this.windows[id] = <Window
|
this.windows[id.toString()] = {
|
||||||
id={id}
|
id,
|
||||||
key={id}
|
app,
|
||||||
app={appData}
|
size,
|
||||||
size={size}
|
position
|
||||||
position={position}
|
};
|
||||||
/>;
|
|
||||||
|
this.updateWindows(this.windows);
|
||||||
|
|
||||||
|
// console.log(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(windowId) {
|
close(windowId) {
|
||||||
if (!Object.keys(this.windows).includes(windowId))
|
windowId = windowId.toString();
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (!this.windowIds.includes(windowId)) {
|
||||||
|
console.log(`Failed to close window ${windowId}: window not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Closing window ${windowId}`);
|
console.log(`Closing window ${windowId}`);
|
||||||
delete this.windows[windowId];
|
delete this.windows[windowId];
|
||||||
|
|
||||||
|
this.updateWindows(this.windows);
|
||||||
|
// console.log(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get windowsCount() {
|
setUpdateWindows(updateWindows) {
|
||||||
return Object.keys(this.windows).length;
|
this.updateWindows = updateWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
get windowIds() {
|
||||||
|
return Object.keys(this.windows);
|
||||||
|
}
|
||||||
|
|
||||||
|
get windowsData() {
|
||||||
|
return Object.values(this.windows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue