Skip to content

Commit

Permalink
Implement the Leaf toolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
Amphiluke committed Jun 5, 2024
1 parent 4b2ea55 commit 6287986
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 48 deletions.
59 changes: 31 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lindsvg-pwa",
"private": true,
"version": "2.4.4",
"version": "2.5.0",
"type": "module",
"scripts": {
"lint": "eslint",
Expand All @@ -17,10 +17,10 @@
"vue": "^3.4.27"
},
"devDependencies": {
"@eslint/js": "^9.3.0",
"@eslint/js": "^9.4.0",
"@stylistic/eslint-plugin-js": "^2.1.0",
"@vitejs/plugin-vue": "^5.0.5",
"eslint": "^9.3.0",
"eslint": "^9.4.0",
"eslint-plugin-vue": "^9.26.0",
"globals": "^15.3.0",
"vite": "^5.2.12"
Expand Down
2 changes: 2 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {onMounted} from "vue";
import {processLaunchOptions} from "./launchCtrl.mjs";
import PlotArea from "./components/PlotArea.vue";
import TheSidebar from "./components/TheSidebar.vue";
import LeafToolbar from "./components/LeafToolbar.vue";
import ThePopover from "./components/ThePopover.vue";
onMounted(() => processLaunchOptions());
Expand All @@ -11,6 +12,7 @@ onMounted(() => processLaunchOptions());
<template>
<div>
<PlotArea />
<LeafToolbar />
<TheSidebar />
<ThePopover />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/assets/icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
121 changes: 121 additions & 0 deletions src/components/LeafToolbar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<script setup>
import {computed} from "vue";
import {useCollectionsStore} from "../stores/collections.mjs";
import {useLSystemStore} from "../stores/lSystem.mjs";
import {useInterfaceStore} from "../stores/interface.mjs";
import interfaceStyles from "../styles/interface.module.css";
let collectionsStore = useCollectionsStore();
let lSystemStore = useLSystemStore();
let interfaceStore = useInterfaceStore();
let selectedLS = computed({
get: () => ({
cid: collectionsStore.selectedCID,
lid: collectionsStore.selectedLID,
}),
set: ({cid, lid}) => {
if (cid !== collectionsStore.selectedCID || lid !== collectionsStore.selectedLID) {
collectionsStore.selectedCID = cid;
collectionsStore.selectedLID = lid;
lSystemStore.setup(collectionsStore.selectedLSystem);
lSystemStore.buildSVG();
}
},
});
let lsList = computed(() => collectionsStore.collections
.map(({cid, items}) => items.map(({lid}) => ({cid, lid})))
.flat());
let selectedIndex = computed({
get: () => lsList.value.findIndex(({cid, lid}) => cid === selectedLS.value.cid && lid === selectedLS.value.lid),
set: (index) => {
selectedLS.value = lsList.value[index];
},
});
</script>

<template>
<form
v-show="interfaceStore.isLeafToolbarOpen"
action="#"
autocomplete="off"
:class="$style.leafToolbar"
@submit.prevent
>
<button
:class="[
$style.button,
interfaceStyles.iconButton,
interfaceStyles.iconButtonConfig,
{[$style.hidden]: !selectedLS.lid || interfaceStore.openedPanel === 'settings'}
]"
title="Edit this L-system’s parameters"
@click="interfaceStore.openedPanel = 'settings'"
/>
<select
v-model="selectedLS"
:class="$style.lSystems"
>
<template
v-for="({cid, items}) of collectionsStore.collections"
:key="cid"
>
<optgroup
v-if="!!items.length"
:label="cid"
>
<option
v-for="({lid}) of items"
:key="cid + lid"
:value="{cid, lid}"
>
{{ lid }}
</option>
</optgroup>
</template>
</select>
<button
type="button"
:class="[$style.button, interfaceStyles.iconButton, interfaceStyles.iconButtonUp]"
:disabled="selectedIndex <= 0"
title="Previous L-system"
@click="selectedIndex -= 1"
/>
<button
type="button"
:class="[$style.button, interfaceStyles.iconButton, interfaceStyles.iconButtonDown]"
:disabled="selectedIndex >= lsList.length - 1"
title="Next L-system"
@click="selectedIndex += 1"
/>
</form>
</template>

<style module>
.leafToolbar {
align-items: center;
display: flex;
gap: 5px;
justify-content: center;
min-width: 0;
padding-left: var(--size-sidebar-button);
padding-top: 0.6rem;
position: relative;
}
.lSystems {
flex: 1 1 0;
max-width: max-content;
min-width: 0;
}
.button[disabled] {
opacity: 0.5;
}
.hidden {
visibility: hidden;
}
</style>
2 changes: 1 addition & 1 deletion src/components/PanelCollections.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ let interfaceStore = useInterfaceStore();
let filter = ref("");
let debouncedFilter = refDebounced(filter, 300);
let filteredCollections = computed(() => {
let query = debouncedFilter.value.toLowerCase();
let query = debouncedFilter.value.trim().toLowerCase();
if (!query) {
return collectionsStore.collections;
}
Expand Down
49 changes: 36 additions & 13 deletions src/components/TheSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ let interfaceStore = useInterfaceStore();

<template>
<div :class="$style.sidebar">
<button
v-show="interfaceStore.openedPanel !== ''"
type="button"
:class="$style.collapse"
title="Hide sidebar"
@click="interfaceStore.openedPanel = ''"
/>
<div :class="$style.ctrlButtons">
<button
v-show="interfaceStore.openedPanel === 'collections'"
type="button"
:class="$style.toolbarButton"
title="Detach panel to a toolbar"
@click="interfaceStore.isLeafToolbarOpen = true"
/>
<button
v-show="interfaceStore.openedPanel !== ''"
type="button"
:class="$style.collapseButton"
title="Hide sidebar"
@click="interfaceStore.openedPanel = ''"
/>
</div>
<div :class="$style.buttons">
<button
v-for="name of ['collections', 'settings', 'attributes', 'sharing', 'about']"
Expand Down Expand Up @@ -49,16 +58,22 @@ let interfaceStore = useInterfaceStore();
top: 0;
}
.collapse {
.ctrlButtons {
display: flex;
gap: 10px;
position: absolute;
right: 10px;
top: 10px;
}
.toolbarButton,
.collapseButton {
background-color: var(--color-accent);
border: none;
height: 25px;
-webkit-mask: url(../assets/icons.svg) -150px 0 no-repeat;
mask: url(../assets/icons.svg) -150px 0 no-repeat;
-webkit-mask: url(../assets/icons.svg) var(--mask-pos) no-repeat;
mask: url(../assets/icons.svg) var(--mask-pos) no-repeat;
padding: 0;
position: absolute;
right: 10px;
top: 10px;
width: 25px;
@media (hover) {
Expand All @@ -68,6 +83,14 @@ let interfaceStore = useInterfaceStore();
}
}
.toolbarButton {
--mask-pos: -250px 0;
}
.collapseButton {
--mask-pos: -150px 0;
}
.buttons {
box-shadow: 0 -1px 0 0 var(--color-on-surface-mid);
display: flex;
Expand Down
11 changes: 11 additions & 0 deletions src/stores/bank.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ export default [
theta: 90,
iterations: 3,
step: 4,
attributes: {
fill: "peru",
stroke: "forestgreen",
"stroke-linejoin": "round",
"stroke-opacity": "0.8",
"stroke-width": "5",
},
},
{
lid: "Koch’s curve",
Expand Down Expand Up @@ -1200,6 +1207,10 @@ export default [
theta: 90,
iterations: 2,
step: 7,
attributes: {
stroke: "olive",
"stroke-width": "1.5",
},
},
{ // [AM]
lid: "napkin",
Expand Down
Loading

0 comments on commit 6287986

Please sign in to comment.