Progress on Tabletop CRPG-style design
This commit is contained in:
@@ -241,7 +241,6 @@ export default {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
// @ts-ignore
|
||||
meteor: {
|
||||
children() {
|
||||
const indicesOfTerminatingProps = [];
|
||||
|
||||
@@ -72,37 +72,23 @@
|
||||
<v-footer
|
||||
inset
|
||||
class="pa-0"
|
||||
style="background: none;
|
||||
box-shadow: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom:0;
|
||||
right: 0;"
|
||||
style="
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom:0;
|
||||
right: 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
"
|
||||
>
|
||||
<v-container fluid>
|
||||
<v-row
|
||||
dense
|
||||
class="action-row overflow-x-auto align-end"
|
||||
style="flex-wrap: nowrap; padding-top: 100px;"
|
||||
@wheel="transformScroll($event)"
|
||||
>
|
||||
<mini-character-sheet
|
||||
v-if="activeCreatureId"
|
||||
data-id="mini-character-sheet"
|
||||
:creature-id="activeCreatureId"
|
||||
@click="openCharacterSheetDialog"
|
||||
/>
|
||||
<action-card
|
||||
v-for="action in actions"
|
||||
:key="action._id"
|
||||
:model="action"
|
||||
:active="activeActionId === action._id"
|
||||
:targets="targets"
|
||||
@activate="activeActionId = action._id"
|
||||
@deactivate="activeActionId = undefined; targets = [];"
|
||||
/>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<v-slide-y-reverse-transition mode="out-in">
|
||||
<selected-creature-bar
|
||||
:key="activeCreatureId"
|
||||
:creature-id="activeCreatureId"
|
||||
/>
|
||||
</v-slide-y-reverse-transition>
|
||||
</v-footer>
|
||||
</div>
|
||||
</template>
|
||||
@@ -117,6 +103,7 @@ import { snackbar } from '/imports/client/ui/components/snackbars/SnackbarQueue.
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
|
||||
import ActionCard from '/imports/client/ui/tabletop/TabletopActionCard.vue';
|
||||
import SelectedCreatureBar from '/imports/client/ui/tabletop/selectedCreatureBar/SelectedCreatureBar.vue';
|
||||
|
||||
const getProperties = function (creatureId, selector = {}) {
|
||||
return CreatureProperties.find({
|
||||
@@ -142,6 +129,7 @@ export default {
|
||||
TabletopMap,
|
||||
ActionCard,
|
||||
MiniCharacterSheet,
|
||||
SelectedCreatureBar,
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<template lang="html">
|
||||
<v-btn
|
||||
icon
|
||||
plain
|
||||
large
|
||||
@click="$emit('click')"
|
||||
@mouseover="$emit('hover', $event)"
|
||||
>
|
||||
<property-icon
|
||||
v-if="prop"
|
||||
:model="prop"
|
||||
/>
|
||||
<v-icon v-else-if="icon">
|
||||
{{ icon }}
|
||||
</v-icon>
|
||||
<v-icon v-else>
|
||||
mdi-help
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import PropertyIcon from '/imports/client/ui/properties/shared/PropertyIcon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PropertyIcon,
|
||||
},
|
||||
props: {
|
||||
propId: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
}
|
||||
},
|
||||
meteor: {
|
||||
prop() {
|
||||
if (!this.propId) return;
|
||||
return CreatureProperties.findOne(this.propId);
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,8 +1,10 @@
|
||||
<template lang="html">
|
||||
<div
|
||||
v-if="creatureId"
|
||||
class="selected-creature-bar d-flex"
|
||||
class="selected-creature-bar d-flex pa-4"
|
||||
style="gap: 8px;"
|
||||
>
|
||||
<!--
|
||||
<tabletop-buff-icons
|
||||
creature-id="creatureId"
|
||||
@select-icon="selectIcon"
|
||||
@@ -11,75 +13,124 @@
|
||||
creature-id="creatureId"
|
||||
@select-icon="selectIcon"
|
||||
/>
|
||||
<tabletop-actions
|
||||
creature-id="creatureId"
|
||||
@select-icon="selectIcon"
|
||||
/>
|
||||
<tabletop-grouped-folders
|
||||
creature-id="creatureId"
|
||||
@select-icon="selectIcon"
|
||||
/>
|
||||
<tabletop-resources
|
||||
creature-id="creatureId"
|
||||
@select-icon="selectIcon"
|
||||
/>
|
||||
<tabletop-creature-sheet-tabs
|
||||
-->
|
||||
<v-menu
|
||||
v-model="selectedProp"
|
||||
:position-x="menuX"
|
||||
:position-y="menuY"
|
||||
absolute
|
||||
offset-y
|
||||
:close-on-content-click="false"
|
||||
>
|
||||
<tabletop-action-card
|
||||
v-if="selectedProp && selectedProp.type === 'action'"
|
||||
:model="selectedProp"
|
||||
/>
|
||||
</v-menu>
|
||||
<v-card
|
||||
v-for="group in iconGroups"
|
||||
:key="group.name"
|
||||
>
|
||||
<div
|
||||
v-for="(row, rowIndex) in group.rows"
|
||||
:key="rowIndex"
|
||||
class="d-flex"
|
||||
>
|
||||
<template
|
||||
v-for="(icon, iconIndex) in row"
|
||||
>
|
||||
<creature-bar-icon
|
||||
:key="icon.propId || iconIndex"
|
||||
:prop-id="icon.propId"
|
||||
:icon="icon.icon"
|
||||
@click="selectedIcon = icon"
|
||||
@hover="e => {selectedIcon = icon; menuX = e.clientX; menuY = e.clientY; log(e)}"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</v-card>
|
||||
<!--<tabletop-actions
|
||||
creature-id="creatureId"
|
||||
@select-icon="selectIcon"
|
||||
/>
|
||||
<tabletop-detail-popover />
|
||||
-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="js">
|
||||
import Creatures from '/imports/api/creature/creatures/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import TabletopActionCard from '/imports/client/ui/tabletop/TabletopActionCard.vue';
|
||||
import CreatureBarIcon from '/imports/client/ui/tabletop/selectedCreatureBar/CreatureBarIcon.vue';
|
||||
|
||||
import TabletopPortrait from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopPortrait.vue';
|
||||
import TabletopBuffIcons from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopBuffIcons.vue';
|
||||
import TabletopActions from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopActions.vue';
|
||||
import TabletopGroupedFolders from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopGroupedFolders.vue';
|
||||
import TabletopResources from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopResources.vue';
|
||||
import TabletopCreatureSheetTabs from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopCreatureSheetTabs.vue';
|
||||
import TabletopDetailPopover from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopDetailPopover.vue';
|
||||
//import TabletopPortrait from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopPortrait.vue';
|
||||
//import TabletopBuffIcons from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopBuffIcons.vue';
|
||||
//import TabletopActions from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopActions.vue';
|
||||
//import TabletopGroupedFolders from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopGroupedFolders.vue';
|
||||
//import TabletopResources from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopResources.vue';
|
||||
//import TabletopCreatureSheetTabs from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopCreatureSheetTabs.vue';
|
||||
//import TabletopDetailPopover from '/imports/client/ui/tabletop/selectedCreatureBar/TabletopDetailPopover.vue';
|
||||
|
||||
function splitToNChunks(inputArray, n) {
|
||||
let result = [];
|
||||
const array = [...inputArray] // Create shallow copy, because splice mutates array
|
||||
for (let i = n; i > 0; i--) {
|
||||
result.push(array.splice(0, Math.ceil(array.length / i)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TabletopPortrait,
|
||||
TabletopBuffIcons,
|
||||
TabletopActions,
|
||||
TabletopGroupedFolders,
|
||||
TabletopResources,
|
||||
TabletopCreatureSheetTabs,
|
||||
},
|
||||
//TabletopPortrait,
|
||||
//TabletopBuffIcons,
|
||||
//TabletopActions,
|
||||
//TabletopGroupedFolders,
|
||||
//TabletopResources,
|
||||
//TabletopCreatureSheetTabs,
|
||||
CreatureBarIcon,
|
||||
TabletopActionCard,
|
||||
},
|
||||
props: {
|
||||
creatureId: {
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
},.
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rows: 2,
|
||||
selectedIcon: undefined,
|
||||
menuX: 200,
|
||||
menuY: 200,
|
||||
};
|
||||
},
|
||||
meteor: {
|
||||
creature() {
|
||||
if (!this.creatureId) return;
|
||||
return Creatures.findOne(this.creatureId)
|
||||
},
|
||||
selectedProp() {
|
||||
if (!this.selectedIcon?.propId) return;
|
||||
return CreatureProperties.findOne(this.selectedIcon.propId);
|
||||
},
|
||||
iconGroups() {
|
||||
if (!this.creature) return;
|
||||
const iconGroups = [];
|
||||
|
||||
// Get the standard icons
|
||||
const standardIconsById = {
|
||||
'cast-spell': { groupName: 'standardActions' },
|
||||
'make-check': { groupName: 'standardActions' },
|
||||
'roll-dice': { groupName: 'standardActions' },
|
||||
'tab-stats': { groupName: 'tabs' },
|
||||
'tab-actions': { groupName: 'tabs' },
|
||||
'tab-spells': { groupName: 'tabs' },
|
||||
'tab-inventory': { groupName: 'tabs' },
|
||||
'tab-features': { groupName: 'tabs' },
|
||||
'tab-journal': { groupName: 'tabs' },
|
||||
'tab-build': { groupName: 'tabs' },
|
||||
'cast-spell': { groupName: 'Standard Actions', icon: 'mdi-fire' },
|
||||
'make-check': { groupName: 'Standard Actions', icon: 'mdi-radiobox-marked' },
|
||||
'roll-dice': { groupName: 'Standard Actions', icon: 'mdi-dice-d20' },
|
||||
'tab-stats': { groupName: 'Tabs', icon: 'mdi-chart-box' },
|
||||
'tab-actions': { groupName: 'Tabs', icon: 'mdi-lightning-bolt' },
|
||||
'tab-spells': { groupName: 'Tabs', icon: 'mdi-fire' },
|
||||
'tab-inventory': { groupName: 'Tabs', icon: 'mdi-cube' },
|
||||
'tab-features': { groupName: 'Tabs', icon: 'mdi-text' },
|
||||
'tab-journal': { groupName: 'Tabs', icon: 'mdi-book-open-variant' },
|
||||
'tab-build': { groupName: 'Tabs', icon: 'mdi-wrench' },
|
||||
};
|
||||
|
||||
// Get the folders that could hide a property
|
||||
@@ -125,7 +176,7 @@ export default {
|
||||
const props = [];
|
||||
CreatureProperties.find(filter, {
|
||||
sort: { order: -1 },
|
||||
fields: { _id: 1 },
|
||||
fields: { _id: 1, type: 1 },
|
||||
}).forEach(prop => {
|
||||
props.push(prop);
|
||||
propsById[prop._id] = prop;
|
||||
@@ -164,6 +215,7 @@ export default {
|
||||
case 'resource': groupName = 'Resources'; break;
|
||||
case 'folder': groupName = 'Folders'; break;
|
||||
}
|
||||
if (!groupName) return;
|
||||
if (!groupsByName[groupName]) {
|
||||
groupsByName[groupName] = { name: groupName, iconList: [] };
|
||||
defaultGroups.push(groupsByName[groupName]);
|
||||
@@ -176,14 +228,22 @@ export default {
|
||||
const standardIcon = standardIconsById[key];
|
||||
if (standardIcon._placedInGroup) return;
|
||||
|
||||
const groupName = standardIcon.groupName;
|
||||
const groupName = standardIcon.groupName || 'no';
|
||||
if (!groupsByName[groupName]) {
|
||||
groupsByName[groupName] = { name: groupName, iconList: [] };
|
||||
defaultGroups.push(groupsByName[groupName]);
|
||||
}
|
||||
|
||||
groupsByName[groupName].iconList.push({ standardId: key });
|
||||
groupsByName[groupName].iconList.push({ standardId: key, icon: standardIcon.icon });
|
||||
}
|
||||
|
||||
iconGroups.push(...defaultGroups);
|
||||
|
||||
// Divide the icons into rows
|
||||
iconGroups.forEach(group => {
|
||||
group.rows = splitToNChunks(group.iconList, this.rows);
|
||||
});
|
||||
|
||||
return iconGroups;
|
||||
}
|
||||
},
|
||||
@@ -191,16 +251,12 @@ export default {
|
||||
selectIcon(e) {
|
||||
this.$emit('select-icon', e);
|
||||
},
|
||||
log(e) {
|
||||
console.log(e);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.selected-creature-bar {
|
||||
height: 140px;
|
||||
max-height: 30%;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: visible;
|
||||
}
|
||||
</style>
|
||||
2
app/package-lock.json
generated
2
app/package-lock.json
generated
@@ -1917,7 +1917,7 @@
|
||||
"lodash.omit": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||
"integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
|
||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
||||
},
|
||||
"lodash.template": {
|
||||
"version": "4.5.0",
|
||||
|
||||
Reference in New Issue
Block a user