diff --git a/assets/network.svg b/assets/network.svg new file mode 100755 index 0000000..10ed58a --- /dev/null +++ b/assets/network.svg @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/assets/no-network.svg b/assets/no-network.svg new file mode 100755 index 0000000..5b9b7f9 --- /dev/null +++ b/assets/no-network.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + diff --git a/assets/question.svg b/assets/question.svg new file mode 100755 index 0000000..43d6ac8 --- /dev/null +++ b/assets/question.svg @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/src/renderer/App.css b/src/renderer/App.css index 587ed26..b23aa02 100644 --- a/src/renderer/App.css +++ b/src/renderer/App.css @@ -3,7 +3,7 @@ body { } .App { - --window-head-color: blue; + --window-head-color: navy; --window-head-text-color: white; --window-accent-color: grey; --body-color: white; @@ -32,7 +32,7 @@ body { z-index: 20; backdrop-filter: blur(2px); } -.App-modal-container:has(.modal-active) { +.App-modal-container:has(.Modal-active) { display: block; } .App-confirm-dialog-text { diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 671929f..95f3e7f 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -17,6 +17,7 @@ import ConfirmModal from './modals/ConfirmModal'; import ConnectionConfigModal, { ConnectionConfigChangeEvent, } from './modals/ConnectionConfigModal'; +import HelpModal from './modals/HelpModal'; import GamepadInfoModal from './modals/GamepadInfoModal'; import ResizeBar from './ResizeBar'; import { @@ -403,6 +404,7 @@ export default function App() { onConnectionConfigModalOpen={() => changeActiveModal('ConnectionConfig') } + onHelpModalOpen={() => changeActiveModal('Help')} dawnVersion={dawnVersion} robotLatencyMs={robotLatencyMs} robotBatteryVoltage={robotBatteryVoltage} @@ -471,6 +473,7 @@ export default function App() { FieldIPAddress={FieldIPAddress} FieldStationNum={FieldStationNum} /> + void; -}) { - return ( -
- -
- ); -} diff --git a/src/renderer/Editor.css b/src/renderer/Editor.css index e904e43..1545e40 100644 --- a/src/renderer/Editor.css +++ b/src/renderer/Editor.css @@ -95,6 +95,7 @@ transition: filter 0.25s; /* Fix other filter variables so transition is directly from black to blue: */ filter: invert(0%) sepia(100%) hue-rotate(180deg) saturate(0); + pointer-events: none; } .Editor-tbbtn-toggled img { /* CSS filter witchcraft producing #0088ff */ diff --git a/src/renderer/Topbar.css b/src/renderer/Topbar.css index 0b57aea..4a747c0 100644 --- a/src/renderer/Topbar.css +++ b/src/renderer/Topbar.css @@ -16,9 +16,6 @@ .Topbar-right-group { float: right; } -.Topbar-tail { - clear: both; -} .Topbar-dawn-version { font-size: 25px; margin-right: 40px; @@ -32,6 +29,7 @@ font-weight: bold; font-size: 15px; } + .Topbar-robot-disconnected { background-color: indianred; } diff --git a/src/renderer/Topbar.tsx b/src/renderer/Topbar.tsx index d76ef20..8734ed3 100644 --- a/src/renderer/Topbar.tsx +++ b/src/renderer/Topbar.tsx @@ -1,4 +1,7 @@ -import ConnectionConfigButton from './ConnectionConfigButton'; +import TopbarButton from './TopbarButton'; +import questionSvg from '../../assets/question.svg'; +import connectionSvg from '../../assets/network.svg'; +import noConnectionSvg from '../../assets/no-network.svg'; import './Topbar.css'; const GOOD_BATTERY_VOLTAGE = 11; @@ -11,6 +14,7 @@ const FAIR_LATENCY_MS = 200; * @param props - props * @param props.onConnectionConfigModalOpen - handler called when the ConnectionConfigModal should * be opened + * @param props.onHelpModalOpen - handler called when the HelpModal should be opened * @param props.robotLatencyMs - latency in milliseconds of the connection to the currently * connected robot, or -1 if there is no robot connected * @param props.robotBatteryVoltage - battery voltage in volts of the currently connected robot. The @@ -19,11 +23,13 @@ const FAIR_LATENCY_MS = 200; */ export default function Topbar({ onConnectionConfigModalOpen, + onHelpModalOpen, robotBatteryVoltage, robotLatencyMs, dawnVersion, }: { onConnectionConfigModalOpen: () => void; + onHelpModalOpen: () => void; robotBatteryVoltage: number; robotLatencyMs: number; dawnVersion: string; @@ -66,9 +72,17 @@ export default function Topbar({ {robotInfo}
- + +
-
); } diff --git a/src/renderer/TopbarButton.css b/src/renderer/TopbarButton.css new file mode 100644 index 0000000..4700fb0 --- /dev/null +++ b/src/renderer/TopbarButton.css @@ -0,0 +1,18 @@ +.TopbarButton { + height: 100%; +} +.TopbarButton button { + background-color: transparent; + border: none; + outline: none; + cursor: pointer; +} +.TopbarButton img { + height: 25px; + border: 3px solid lightgray; + border-radius: 6px; + pointer-events: none; +} +.TopbarButton button:active img { + border-color: gray; +} diff --git a/src/renderer/TopbarButton.tsx b/src/renderer/TopbarButton.tsx new file mode 100644 index 0000000..5e6c651 --- /dev/null +++ b/src/renderer/TopbarButton.tsx @@ -0,0 +1,26 @@ +import './TopbarButton.css'; + +/** + * Image button component in the Topbar that opens a modal. + * @param props - props + * @param props.onModalOpen - click handler for the button that opens the ConnectionConfigModal + * @param props.src - source of the image + * @param props.alt - string to use as the image alt text and button hover text + */ +export default function TopbarButton({ + onModalOpen, + src, + alt, +}: { + onModalOpen: () => void; + src: string; + alt: string; +}) { + return ( +
+ +
+ ); +} diff --git a/src/renderer/modals/HelpModal.tsx b/src/renderer/modals/HelpModal.tsx new file mode 100644 index 0000000..d11e76c --- /dev/null +++ b/src/renderer/modals/HelpModal.tsx @@ -0,0 +1,23 @@ +import Modal from './Modal'; + +/** + * Modal component displaying help for Dawn and the robot API. + * @param props - props + * @param props.onClose - handler called when the modal is closed by any means + * @param props.isActive - whether to display the modal + */ +export default function GamepadInfoModal({ + onClose, + isActive, +}: { + onClose: () => void; + isActive: boolean; +}) { + return ( + + This is a very helpful message. So helpful, in fact, that it's too + helpful to even write here. Its helpfulness would blind your eyes with its + brilliance. + + ); +} diff --git a/src/renderer/modals/Modal.css b/src/renderer/modals/Modal.css index d3ec1a3..5ce64e5 100644 --- a/src/renderer/modals/Modal.css +++ b/src/renderer/modals/Modal.css @@ -6,8 +6,9 @@ transform: translate(-50%, -50%); background-color: var(--body-color); border-radius: 10px; + font-family: Arial, sans-serif; } -.modal-active { +.Modal-active { display: block; } .Modal-title-bar { diff --git a/src/renderer/modals/Modal.tsx b/src/renderer/modals/Modal.tsx index bef6869..df52b46 100644 --- a/src/renderer/modals/Modal.tsx +++ b/src/renderer/modals/Modal.tsx @@ -23,7 +23,7 @@ export default function Modal({ className?: string; }) { return ( -
+
{modalTitle}