Add a fullscreen button and the keyboard lock API (#266)

Closes #249
This commit is contained in:
Keavon Chambers
2021-07-14 18:56:22 -07:00
parent 2aff782e70
commit ca50e8f37d
14 changed files with 151 additions and 17 deletions
@@ -15,7 +15,8 @@
<Icon :icon="entry.icon" v-if="entry.icon && drawIcon" />
<div class="no-icon" v-else-if="drawIcon" />
<span class="entry-label">{{ entry.label }}</span>
<UserInputLabel v-if="entry.shortcut && entry.shortcut.length" :inputKeys="[entry.shortcut]" />
<Icon :icon="'Info'" v-if="entry.shortcutRequiresLock && !fullscreen.keyboardLocked" :title="keyboardLockInfoMessage" />
<UserInputLabel v-else-if="entry.shortcut && entry.shortcut.length" :inputKeys="[entry.shortcut]" />
<div class="submenu-arrow" v-if="entry.children && entry.children.length"></div>
<div class="no-submenu-arrow" v-else></div>
<MenuList
@@ -121,6 +122,7 @@
<script lang="ts">
import { defineComponent, PropType } from "vue";
import { keyboardLockApiSupported } from "@/utilities/fullscreen";
import FloatingMenu, { MenuDirection, MenuType } from "./FloatingMenu.vue";
import Separator, { SeparatorDirection, SeparatorType } from "../Separator.vue";
import Icon from "../labels/Icon.vue";
@@ -134,13 +136,18 @@ interface MenuListEntryData {
icon?: string;
// TODO: Add `checkbox` (which overrides any `icon`)
shortcut?: Array<string>;
shortcutRequiresLock?: boolean;
action?: Function;
children?: SectionsOfMenuListEntries;
}
export type MenuListEntry = MenuListEntryData & { ref?: typeof FloatingMenu | typeof MenuList };
const KEYBOARD_LOCK_USE_FULLSCREEN = "This hotkey is reserved by the browser, but becomes available in fullscreen mode";
const KEYBOARD_LOCK_SWITCH_BROWSER = "This hotkey is reserved by the browser, but becomes available in Chrome, Edge, and Opera which support the Keyboard.lock() API";
const MenuList = defineComponent({
inject: ["fullscreen"],
props: {
direction: { type: String as PropType<MenuDirection>, default: MenuDirection.Bottom },
menuEntries: { type: Array as PropType<SectionsOfMenuListEntries>, required: true },
@@ -242,6 +249,7 @@ const MenuList = defineComponent({
data() {
return {
currentEntry: this.activeEntry,
keyboardLockInfoMessage: keyboardLockApiSupported() ? KEYBOARD_LOCK_USE_FULLSCREEN : KEYBOARD_LOCK_SWITCH_BROWSER,
SeparatorDirection,
SeparatorType,
MenuDirection,
@@ -65,13 +65,13 @@ const menuEntries: MenuListEntries = [
ref: undefined,
children: [
[
{ label: "New", icon: "File", shortcut: ["Ctrl", "N"], action: async () => (await wasm).new_document() },
{ label: "New", icon: "File", shortcut: ["Ctrl", "N"], shortcutRequiresLock: true, action: async () => (await wasm).new_document() },
{ label: "Open…", shortcut: ["Ctrl", "O"] },
{
label: "Open Recent",
shortcut: ["Ctrl", "⇧", "O"],
children: [
[{ label: "Reopen Last Closed", shortcut: ["Ctrl", "⇧", "T"] }, { label: "Clear Recently Opened" }],
[{ label: "Reopen Last Closed", shortcut: ["Ctrl", "⇧", "T"], shortcutRequiresLock: true }, { label: "Clear Recently Opened" }],
[
{ label: "Some Recent File.gdd" },
{ label: "Another Recent File.gdd" },
@@ -83,7 +83,7 @@ const menuEntries: MenuListEntries = [
},
],
[
{ label: "Close", shortcut: ["Ctrl", "W"], action: async () => (await wasm).close_active_document_with_confirmation() },
{ label: "Close", shortcut: ["Ctrl", "W"], shortcutRequiresLock: true, action: async () => (await wasm).close_active_document_with_confirmation() },
{ label: "Close All", shortcut: ["Ctrl", "Alt", "W"], action: async () => (await wasm).close_all_documents_with_confirmation() },
],
[
@@ -86,11 +86,14 @@ import Link from "../../../../assets/12px-solid/link.svg";
import Grid from "../../../../assets/12px-solid/grid.svg";
import Overlays from "../../../../assets/12px-solid/overlays.svg";
import Snapping from "../../../../assets/12px-solid/snapping.svg";
import Info from "../../../../assets/12px-solid/info.svg";
import Swap from "../../../../assets/12px-solid/swap.svg";
import ResetColors from "../../../../assets/12px-solid/reset-colors.svg";
import DropdownArrow from "../../../../assets/12px-solid/dropdown-arrow.svg";
import VerticalEllipsis from "../../../../assets/12px-solid/vertical-ellipsis.svg";
import CloseX from "../../../../assets/12px-solid/close-x.svg";
import FullscreenEnter from "../../../../assets/12px-solid/fullscreen-enter.svg";
import FullscreenExit from "../../../../assets/12px-solid/fullscreen-exit.svg";
import WindowButtonWinMinimize from "../../../../assets/12px-solid/window-button-win-minimize.svg";
import WindowButtonWinMaximize from "../../../../assets/12px-solid/window-button-win-maximize.svg";
import WindowButtonWinRestoreDown from "../../../../assets/12px-solid/window-button-win-restore-down.svg";
@@ -164,11 +167,14 @@ const icons = {
Grid: { component: Grid, size: 12 },
Overlays: { component: Overlays, size: 12 },
Snapping: { component: Snapping, size: 12 },
Info: { component: Info, size: 12 },
Swap: { component: Swap, size: 12 },
ResetColors: { component: ResetColors, size: 12 },
DropdownArrow: { component: DropdownArrow, size: 12 },
VerticalEllipsis: { component: VerticalEllipsis, size: 12 },
CloseX: { component: CloseX, size: 12 },
FullscreenEnter: { component: FullscreenEnter, size: 12 },
FullscreenExit: { component: FullscreenExit, size: 12 },
WindowButtonWinMinimize: { component: WindowButtonWinMinimize, size: 12 },
WindowButtonWinMaximize: { component: WindowButtonWinMaximize, size: 12 },
WindowButtonWinRestoreDown: { component: WindowButtonWinRestoreDown, size: 12 },