Skip to content

Commit

Permalink
feat: make windows draggable and resizable
Browse files Browse the repository at this point in the history
  • Loading branch information
Renovamen committed Apr 29, 2021
1 parent ef40204 commit 68a5244
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 55 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"react-dom": "^17.0.2",
"react-feather": "2.0.9",
"react-rangeslider": "2.2.0",
"react-rnd": "^10.2.4",
"react-scripts": "4.0.3",
"react-webcam": "5.2.2",
"sort-package-json": "^1.49.0",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Desktop.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import Notepad from "../apps/Notepad";

export default function Desktop() {
const [showControlCenter, setShowControlCenter] = useState(false);
const [currentTitle, setCurrentTitle] = useState("Playground");

const [bioShow, setBioShow] = useState(true);
const [faceTimeShow, setFaceTimeShow] = useState(false);
const [safariShow, setSafariShow] = useState(false);
const [cmdShow, setCmdShow] = useState(false);
const [currentTitle, setCurrentTitle] = useState("Playground");

const [bioZ, setBioZ] = useState(2);
const [faceTimeZ, setFaceTimeZ] = useState(2);
Expand Down
156 changes: 104 additions & 52 deletions src/components/Window.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,114 @@
import React from "react";
import React, { Component } from "react";
import { Rnd } from "react-rnd";

function TrafficLights({ setShow, max, setMax }) {
const closeWindow = (e) => {
class TrafficLights extends Component {
closeWindow = (e) => {
e.stopPropagation();
setShow(false);
this.props.setShow(false);
};

return (
<div className="flex flex-row absolute left-0 space-x-2 pl-2 mt-1.5">
<button
className="w-3 h-3 rounded-full bg-red-500 outline-none focus:outline-none"
onClick={closeWindow}
/>
<button
className="w-3 h-3 rounded-full bg-yellow-500 outline-none focus:outline-none"
onClick={() => setMax(false)}
/>
<button
className="w-3 h-3 rounded-full bg-green-500 outline-none focus:outline-none"
onClick={() => setMax(!max)}
/>
</div>
);
render() {
return (
<div className="flex flex-row absolute left-0 space-x-2 pl-2 mt-1.5">
<button
className="w-3 h-3 rounded-full bg-red-500 outline-none focus:outline-none"
onClick={this.closeWindow}
/>
<button
className="w-3 h-3 rounded-full bg-yellow-500 outline-none focus:outline-none"
onClick={() => this.props.setMax(false)}
/>
<button
className="w-3 h-3 rounded-full bg-green-500 outline-none focus:outline-none"
onClick={() => this.props.setMax(!this.props.max)}
/>
</div>
);
}
}

export default function Window({
content,
title,
show,
setShow,
max,
setMax,
active,
z,
size
}) {
const minSize = size ? `${size} mt-16 mb-24` : "h-3/4 w-1/2 mt-16 mb-24";
const windowSize = max ? "w-full h-full" : minSize;
const round = max ? "rounded-none" : "rounded-lg";

if (!show) {
return <div />;
export default class Window extends Component {
constructor(props) {
super(props);
const width = props.width ? props.width : "640";
const height = props.height ? props.height : "400";
const maxW = document.body.offsetWidth;
const maxH = document.body.offsetHeight;
this.state = {
width: width,
height: height,
maxW: maxW,
maxH: maxH,
x: Math.random() * (maxW - width),
y: Math.random() * (maxH - height - 100)
};
this.resize.bind(this);
}

componentDidMount() {
window.addEventListener("resize", this.resize);
}

componentWillUnmount() {
window.removeEventListener("resize", this.resize);
}

return (
<div
onClick={() => active(title)}
className={`absolute transition-hw ${round} overflow-y-hidden bg-white ${windowSize} shadow-md`}
style={{ zIndex: z }}
>
<div
className="relative h-6 text-center bg-gray-300"
onDoubleClick={() => setMax(!max)}
resize = () => {
this.setState({
maxW: document.body.offsetWidth,
maxH: document.body.offsetHeight
});
};

render() {
const round = this.props.max ? "rounded-none" : "rounded-lg";

if (!this.props.show) {
return <div />;
}

return (
<Rnd
size={{
width: this.props.max ? this.state.maxW : this.state.width,
height: this.props.max ? this.state.maxH : this.state.height
}}
position={{
x: this.props.max ? 0 : this.state.x,
y: this.props.max ? 0 : this.state.y
}}
onDragStop={(e, d) => {
this.setState({ x: d.x, y: d.y });
}}
onResizeStop={(e, direction, ref, delta, position) => {
this.setState({
width: ref.style.width,
height: ref.style.height,
...position
});
}}
disableDragging={this.props.max}
style={{ zIndex: this.props.z }}
onMouseDown={() => this.props.active(this.props.title)}
className={`absolute transition-hw ${round} overflow-y-hidden bg-white w-full h-full shadow-md`}
>
<TrafficLights setShow={setShow} max={max} setMax={setMax} />
<span className="font-semibold text-gray-700">{title}</span>
</div>
<div className="innner-window w-full overflow-y-hidden">{content}</div>
</div>
);
<div
className="relative h-6 text-center bg-gray-300"
onDoubleClick={() => this.props.setMax(!this.props.max)}
>
<TrafficLights
setShow={this.props.setShow}
max={this.props.max}
setMax={this.props.setMax}
/>
<span className="font-semibold text-gray-700">
{this.props.title}
</span>
</div>
<div className="innner-window w-full overflow-y-hidden">
{this.props.content}
</div>
</Rnd>
);
}
}
1 change: 1 addition & 0 deletions src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

html, body {
height: 100%;
overflow: hidden;
}

.ccm {
Expand Down
38 changes: 36 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3221,7 +3221,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"

classnames@^2.2.3:
classnames@^2.2.3, classnames@^2.2.5:
version "2.3.1"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
Expand Down Expand Up @@ -4910,6 +4910,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=

fast-memoize@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.2.tgz#79e3bb6a4ec867ea40ba0e7146816f6cdce9b57e"
integrity sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==

fastq@^1.6.0:
version "1.10.1"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.10.1.tgz#8b8f2ac8bf3632d67afcd65dac248d5fdc45385e"
Expand Down Expand Up @@ -8969,7 +8974,7 @@ [email protected], prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"

prop-types@^15.7.2:
prop-types@^15.6.0, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
Expand Down Expand Up @@ -9133,6 +9138,13 @@ [email protected]:
iconv-lite "0.4.24"
unpipe "1.0.0"

[email protected]:
version "6.9.0"
resolved "https://registry.yarnpkg.com/re-resizable/-/re-resizable-6.9.0.tgz#9c3059b389ced6ade602234cc5bb1e12d231cd47"
integrity sha512-3cUDG81ylyqI0Pdgle/RHwwRYq0ORZzsUaySOCO8IbEtNyaRtrIHYm/jMQ5pjcNiKCxR3vsSymIQZHwJq4gg2Q==
dependencies:
fast-memoize "^2.5.1"

react-app-polyfill@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz#a0bea50f078b8a082970a9d853dc34b6dcc6a3cf"
Expand Down Expand Up @@ -9184,6 +9196,14 @@ react-dom@^17.0.2:
object-assign "^4.1.1"
scheduler "^0.20.2"

[email protected]:
version "4.4.3"
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.3.tgz#0727f2cae5813e36b0e4962bf11b2f9ef2b406f3"
integrity sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==
dependencies:
classnames "^2.2.5"
prop-types "^15.6.0"

react-error-overlay@^6.0.9:
version "6.0.9"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
Expand Down Expand Up @@ -9219,6 +9239,15 @@ react-refresh@^0.8.3:
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==

react-rnd@^10.2.4:
version "10.2.4"
resolved "https://registry.yarnpkg.com/react-rnd/-/react-rnd-10.2.4.tgz#542c28fa9cfcb3ad1521694dfa2799217832818f"
integrity sha512-wseACIsxa1wuZz9XatO3/JAZR748Sddehh0NtJz1Yj3X5BQm5pwRShiadfnWrUajJATurHbN0NVTUn+jEkHkPw==
dependencies:
re-resizable "6.9.0"
react-draggable "4.4.3"
tslib "2.0.3"

[email protected]:
version "4.0.3"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345"
Expand Down Expand Up @@ -10845,6 +10874,11 @@ tsconfig-paths@^3.9.0:
minimist "^1.2.0"
strip-bom "^3.0.0"

[email protected]:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c"
integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==

tslib@^1.8.1, tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
Expand Down

0 comments on commit 68a5244

Please sign in to comment.