@vcmap/ui 5.0.0-rc.8 → 5.0.0-rc.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -22
- package/build/build.js +0 -3
- package/build/buildHelpers.js +0 -1
- package/build/commonViteConfig.js +1 -1
- package/config/dev.config.json +4 -4
- package/dist/assets/{cesium.6b5bb6.js → cesium.4e40f4.js} +0 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/core.edcf5e.js +4 -0
- package/dist/assets/core.js +1 -1
- package/dist/assets/{index.0be2842f.js → index.889d0f3a.js} +1 -1
- package/dist/assets/{ol.0561aa.js → ol.246fd4.js} +0 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.df4f6d.css +1 -0
- package/dist/assets/ui.df4f6d.js +43 -0
- package/dist/assets/ui.js +1 -1
- package/dist/assets/{vue-composition-api.f926fa.js → vue-composition-api.a520f3.js} +1 -1
- package/dist/assets/vue-composition-api.js +2 -2
- package/dist/assets/{vue.ddcb6b.js → vue.2cee44.js} +0 -0
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify.d21163.css → vuetify.cc817b.css} +0 -0
- package/dist/assets/{vuetify.d21163.js → vuetify.cc817b.js} +1 -1
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.js +39 -1
- package/package.json +2 -3
- package/plugins/@vcmap/pluginExample/index.js +5 -5
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +1 -1
- package/plugins/@vcmap/project-selector/ContextsListComponent.vue +1 -1
- package/plugins/@vcmap/project-selector/index.js +5 -5
- package/plugins/@vcmap/project-selector/package.json +1 -2
- package/plugins/@vcmap/theme-changer/index.js +6 -6
- package/plugins/buttonExamples/ButtonExamples.vue +1 -1
- package/plugins/buttonExamples/index.js +5 -4
- package/plugins/categoryTest/Categories.vue +1 -1
- package/plugins/categoryTest/Category.vue +1 -1
- package/plugins/categoryTest/index.js +5 -5
- package/plugins/example/index.js +33 -14
- package/plugins/test/allIconsComponent.vue +34 -0
- package/plugins/test/editor.vue +1 -1
- package/plugins/test/index.js +40 -17
- package/plugins/test/toolbox-data.js +106 -26
- package/plugins/test/windowManagerExample.vue +1 -2
- package/src/actions/actionHelper.js +2 -1
- package/src/actions/styleSelector.vue +1 -1
- package/src/application/Navbar.vue +18 -6
- package/src/application/VcsApp.vue +34 -28
- package/src/assets/logo-mobile.svg +9 -0
- package/src/assets/logo.svg +23 -23
- package/src/components/buttons/VcsActionButtonList.vue +99 -0
- package/src/components/buttons/VcsButton.vue +201 -0
- package/src/components/form-inputs-controls/VcsCheckbox.vue +73 -0
- package/src/components/form-inputs-controls/VcsColorPicker.vue +81 -0
- package/src/components/form-inputs-controls/VcsFormSection.vue +46 -0
- package/src/components/form-inputs-controls/VcsLabel.vue +38 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +97 -0
- package/src/components/form-inputs-controls/VcsTextArea.vue +130 -0
- package/src/components/form-inputs-controls/VcsTextField.vue +129 -0
- package/src/components/form-output/VcsFormattedNumber.vue +103 -0
- package/src/components/lists/VcsActionList.vue +100 -0
- package/src/components/lists/VcsTreeview.vue +109 -0
- package/src/components/lists/VcsTreeviewLeaf.vue +105 -0
- package/src/components/lists/VcsTreeviewSearchbar.vue +156 -0
- package/src/components/notification/VcsBadge.vue +27 -0
- package/src/components/notification/VcsTooltip.vue +154 -0
- package/src/components/notification/validation.js +19 -0
- package/src/contentTree/LayerTree.vue +1 -1
- package/src/contentTree/contentTreeCollection.js +6 -2
- package/src/icons/+all.js +359 -0
- package/src/icons/2DAreaIcon.vue +21 -0
- package/src/icons/2DDistanceIcon.vue +18 -0
- package/src/icons/3DAreaIcon.vue +21 -0
- package/src/icons/3DDistanceIcon.vue +18 -0
- package/src/icons/3DHeightIcon.vue +18 -0
- package/src/icons/AngleIcon.vue +8 -0
- package/src/icons/AssociationsIcon.vue +34 -0
- package/src/icons/AxisIcon.vue +10 -0
- package/src/icons/BoundingBoxIcon.vue +15 -0
- package/src/icons/CheckboxCheckedIcon.vue +16 -0
- package/src/icons/CheckboxIcon.vue +23 -0
- package/src/icons/CheckboxIndeterminateIcon.vue +24 -0
- package/src/icons/CircleIcon.vue +10 -0
- package/src/icons/ColorSwatchIcon.vue +17 -0
- package/src/icons/CommentIcon.vue +19 -0
- package/src/icons/CompassIcon.vue +8 -0
- package/src/icons/ComponentsIcon.vue +7 -0
- package/src/icons/ConeIcon.vue +11 -0
- package/src/icons/DimensionsHouseIcon.vue +14 -0
- package/src/icons/ElevationProfileIcon.vue +111 -0
- package/src/icons/ExportAreaIcon.vue +7 -0
- package/src/icons/ExportFlightIcon.vue +7 -0
- package/src/icons/ExportIcon.vue +8 -0
- package/src/icons/ExternalLinkIcon.vue +10 -0
- package/src/icons/EyeIcon.vue +7 -0
- package/src/icons/FastForwardIcon.vue +7 -0
- package/src/icons/FilterIcon.vue +8 -0
- package/src/icons/GlobeNatureIcon.vue +14 -0
- package/src/icons/HealthCareIndustriesIcon.vue +118 -0
- package/src/icons/HelpIcon.vue +7 -0
- package/src/icons/HomePointIcon.vue +8 -0
- package/src/icons/HospitalsIcon.vue +237 -0
- package/src/icons/HouseIcon.vue +25 -0
- package/src/icons/ImportIcon.vue +8 -0
- package/src/icons/InfoIcon.vue +10 -0
- package/src/icons/KebabIcon.vue +36 -0
- package/src/icons/LabelIcon.vue +7 -0
- package/src/icons/LayersIcon.vue +26 -0
- package/src/icons/LegendIcon.vue +65 -0
- package/src/icons/LineIcon.vue +7 -0
- package/src/icons/LinkIcon.vue +7 -0
- package/src/icons/MapIcon.vue +8 -0
- package/src/icons/MenuIcon.vue +34 -0
- package/src/icons/MinusIcon.vue +8 -0
- package/src/icons/ObjectAttributeIcon.vue +18 -0
- package/src/icons/ObjectSelectIcon.vue +8 -0
- package/src/icons/ObliqueViewIcon.vue +13 -0
- package/src/icons/PdfIcon.vue +10 -0
- package/src/icons/PedestrianIcon.vue +8 -0
- package/src/icons/PenIcon.vue +14 -0
- package/src/icons/PlayCircleIcon.vue +10 -0
- package/src/icons/PlusIcon.vue +9 -0
- package/src/icons/PoiIcon.vue +7 -0
- package/src/icons/PointSelectIcon.vue +7 -0
- package/src/icons/PolygonIcon.vue +38 -0
- package/src/icons/PresentationModeIcon.vue +7 -0
- package/src/icons/ProgressIcon.vue +24 -0
- package/src/icons/QueryIcon.vue +15 -0
- package/src/icons/RectangleIcon.vue +9 -0
- package/src/icons/ReturnIcon.vue +7 -0
- package/src/icons/RewindIcon.vue +6 -0
- package/src/icons/SearchIcon.vue +8 -0
- package/src/icons/ShadowIcon.vue +9 -0
- package/src/icons/ShapesIcon.vue +28 -0
- package/src/icons/ShareIcon.vue +22 -0
- package/src/icons/SimpleCircleFilledIcon.vue +15 -0
- package/src/icons/SimpleCircleHalfFilledIcon.vue +12 -0
- package/src/icons/SimpleCircleOutlinedIcon.vue +15 -0
- package/src/icons/SkipNextIcon.vue +7 -0
- package/src/icons/SkipPreviousIcon.vue +9 -0
- package/src/icons/SplitViewIcon.vue +19 -0
- package/src/icons/TextStyleIcon.vue +14 -0
- package/src/icons/ThreeDimensionsIcon.vue +7 -0
- package/src/icons/ToolsIcon.vue +35 -0
- package/src/icons/TouchIcon.vue +8 -0
- package/src/icons/TrashCanIcon.vue +7 -0
- package/src/icons/TriangleIcon.vue +15 -0
- package/src/icons/TwoDimensionsIcon.vue +8 -0
- package/src/icons/UploadIcon.vue +14 -0
- package/src/icons/VideoRecorderIcon.vue +14 -0
- package/src/icons/WalkingIcon.vue +7 -0
- package/src/icons/WallIcon.vue +14 -0
- package/src/manager/buttonManager.js +5 -53
- package/src/manager/navbarManager.js +81 -0
- package/src/manager/toolbox/ToolboxGroupComponent.vue +128 -0
- package/src/manager/toolbox/ToolboxManager.vue +119 -76
- package/src/manager/toolbox/toolboxManager.js +204 -0
- package/src/manager/window/WindowComponentHeader.vue +1 -1
- package/src/manager/window/WindowManager.vue +18 -1
- package/src/manager/window/windowManager.js +3 -5
- package/src/navigation/mapNavigation.vue +9 -5
- package/src/navigation/orientationToolsButton.vue +1 -1
- package/src/navigation/tiltSlider.vue +1 -1
- package/src/styles/_theming.scss +10 -0
- package/src/styles/main.scss +3 -0
- package/src/styles/variables.scss +70 -0
- package/src/styles/vcsFont.scss +5 -0
- package/src/styles/vcsGrid.scss +4 -0
- package/src/vcsUiApp.js +4 -3
- package/src/vuePlugins/vuetify.js +1 -1
- package/dist/assets/core.98f9bb.js +0 -4
- package/dist/assets/ui.b7c1e3.css +0 -1
- package/dist/assets/ui.b7c1e3.js +0 -39
- package/dist/assets/uicomponents.682c5f.css +0 -1
- package/dist/assets/uicomponents.682c5f.js +0 -32
- package/dist/assets/uicomponents.js +0 -1
- package/lib/uicomponents.js +0 -1
- package/src/manager/toolbox/ToolboxMultiSelectButton.vue +0 -96
- package/src/manager/toolbox/ToolboxSingleSelectButton.vue +0 -98
- package/src/manager/toolbox/toolbox-manager.js +0 -203
@@ -0,0 +1,128 @@
|
|
1
|
+
<template>
|
2
|
+
<div v-if="actions.length > 0">
|
3
|
+
<VcsButton
|
4
|
+
v-if="singleActionButton"
|
5
|
+
:key="singleActionButton.name"
|
6
|
+
:tooltip="singleActionButton.title"
|
7
|
+
:icon="singleActionButton.icon"
|
8
|
+
:active="singleActionButton.active"
|
9
|
+
@click.stop="singleActionButton.callback($event)"
|
10
|
+
v-bind="{...$attrs}"
|
11
|
+
/>
|
12
|
+
<VcsButton
|
13
|
+
v-else-if="groupButtons.length > 0"
|
14
|
+
v-bind="{...$attrs}"
|
15
|
+
width="48"
|
16
|
+
:icon="groupIcon"
|
17
|
+
:tooltip="groupTitle"
|
18
|
+
:active="active"
|
19
|
+
@click="$emit('click')"
|
20
|
+
>
|
21
|
+
<v-icon v-text="active ? 'mdi-chevron-up' : 'mdi-chevron-down'" color="accent" class="text--darken-3" />
|
22
|
+
</VcsButton>
|
23
|
+
<v-toolbar
|
24
|
+
v-if="active"
|
25
|
+
dense
|
26
|
+
absolute
|
27
|
+
:width="width"
|
28
|
+
class="toolbar__secondary rounded-b mx-auto v-sheet mt-12 px-4"
|
29
|
+
:style="{left: `${nudgeLeft}px` }"
|
30
|
+
>
|
31
|
+
<v-toolbar-items class="w-full">
|
32
|
+
<div class="d-flex align-center justify-space-between w-full action-btn-wrap">
|
33
|
+
<VcsButton
|
34
|
+
v-for="(button, index) in groupButtons"
|
35
|
+
:key="`${button.name}-${index}`"
|
36
|
+
:tooltip="button.title"
|
37
|
+
:icon="button.icon"
|
38
|
+
:active="button.active"
|
39
|
+
@click.stop="button.callback($event)"
|
40
|
+
small
|
41
|
+
:width="buttonSize"
|
42
|
+
v-bind="{...$attrs}"
|
43
|
+
/>
|
44
|
+
</div>
|
45
|
+
</v-toolbar-items>
|
46
|
+
</v-toolbar>
|
47
|
+
</div>
|
48
|
+
</template>
|
49
|
+
<style lang="scss" scoped>
|
50
|
+
.action-btn-wrap{
|
51
|
+
gap: 8px;
|
52
|
+
}
|
53
|
+
.v-toolbar.v-sheet {
|
54
|
+
background-color: #ffffffda;
|
55
|
+
}
|
56
|
+
</style>
|
57
|
+
<script>
|
58
|
+
|
59
|
+
import VcsButton from '../../components/buttons/VcsButton.vue';
|
60
|
+
import { validateActions } from '../../components/lists/VcsActionList.vue';
|
61
|
+
|
62
|
+
/**
|
63
|
+
* @description
|
64
|
+
* A component rendering a single action or a group of actions in a dropdown toolbox using {@link VcsButton} and {@link ToolboxButton}.
|
65
|
+
* @vue-prop {Array<VcsAction>} actions - Array of actions
|
66
|
+
* @vue-prop {string} [groupIcon=''] - optional icon for group dropdown button
|
67
|
+
* @vue-prop {string} [groupTitle=''] - optional title for group dropdown button
|
68
|
+
* @vue-prop {boolean} active - boolean flag, whether group is active
|
69
|
+
* @vue-prop {boolean} position - relative x-position of the button within the toolbar
|
70
|
+
* @vue-computed {Array<VcsAction>} singleActionButton - single button without dropdown
|
71
|
+
* @vue-computed {Array<VcsAction>} groupButtons - buttons rendered below group dropdown button
|
72
|
+
* @vue-computed {number} nudgeLeft - offset depending on buttonSize and buttonPadding to render toolbox centered below dropdown button
|
73
|
+
*/
|
74
|
+
export default {
|
75
|
+
name: 'ToolboxGroupComponent',
|
76
|
+
components: { VcsButton },
|
77
|
+
props: {
|
78
|
+
actions: {
|
79
|
+
type: Array,
|
80
|
+
required: true,
|
81
|
+
validator: validateActions,
|
82
|
+
},
|
83
|
+
groupIcon: {
|
84
|
+
type: String,
|
85
|
+
required: true,
|
86
|
+
},
|
87
|
+
groupTitle: {
|
88
|
+
type: String,
|
89
|
+
default: '',
|
90
|
+
},
|
91
|
+
active: {
|
92
|
+
type: Boolean,
|
93
|
+
required: true,
|
94
|
+
},
|
95
|
+
position: {
|
96
|
+
type: Number,
|
97
|
+
required: true,
|
98
|
+
},
|
99
|
+
},
|
100
|
+
data() {
|
101
|
+
return {
|
102
|
+
buttonSize: 34,
|
103
|
+
buttonPadding: 8,
|
104
|
+
};
|
105
|
+
},
|
106
|
+
computed: {
|
107
|
+
singleActionButton() {
|
108
|
+
if (this.actions.length === 1) {
|
109
|
+
return this.actions[0];
|
110
|
+
}
|
111
|
+
return undefined;
|
112
|
+
},
|
113
|
+
groupButtons() {
|
114
|
+
if (this.singleActionButton) {
|
115
|
+
return [];
|
116
|
+
}
|
117
|
+
return this.actions;
|
118
|
+
},
|
119
|
+
width() {
|
120
|
+
// XXX can this be solved by CSS to get rid of hardcoded size and padding?
|
121
|
+
return this.groupButtons.length * (this.buttonSize + 2 * this.buttonPadding);
|
122
|
+
},
|
123
|
+
nudgeLeft() {
|
124
|
+
return this.position - this.width / 2;
|
125
|
+
},
|
126
|
+
},
|
127
|
+
};
|
128
|
+
</script>
|
@@ -1,43 +1,24 @@
|
|
1
|
+
<script src="../../vcsUiApp.js"></script>
|
1
2
|
<template>
|
2
3
|
<v-toolbar
|
4
|
+
v-if="toolboxOpen && actionGroups.length > 0 && $vuetify.breakpoint.mdAndUp"
|
3
5
|
dense
|
4
|
-
class="vcs-toolbox toolbar__secondary rounded-b mx-auto v-sheet"
|
5
|
-
:
|
6
|
+
class="vcs-toolbox toolbar__secondary rounded-b mx-auto v-sheet marginToTop"
|
7
|
+
:width="width"
|
6
8
|
>
|
7
9
|
<v-toolbar-items class="w-full">
|
8
10
|
<div class="d-flex align-center justify-space-between w-full">
|
9
|
-
<
|
10
|
-
v-for="group
|
11
|
+
<ToolboxGroupComponent
|
12
|
+
v-for="(group, idx) in actionGroups"
|
11
13
|
:key="group.id"
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
/>
|
21
|
-
<Button
|
22
|
-
v-if="group.type === 'toggleButton'"
|
23
|
-
:group="group"
|
24
|
-
:icon="'$vcsObjectAttribute'"
|
25
|
-
:value="group.active"
|
26
|
-
@click.native="group.active = !group.active"
|
27
|
-
/>
|
28
|
-
<ToolboxSingleSelectButton
|
29
|
-
v-if="toolboxGroupVisible(group) && group.type === 'singleSelectButton'"
|
30
|
-
:group="group"
|
31
|
-
@selected="id => selectSingleSelectOption(id)"
|
32
|
-
@set-open="({ id, open }) => setGroupOpen({ id, open })"
|
33
|
-
/>
|
34
|
-
<ToolboxMultiSelectButton
|
35
|
-
v-if="toolboxGroupVisible(group) && group.type === 'multiSelectButton'"
|
36
|
-
:group="group"
|
37
|
-
@selected="id => selectMultiSlectOption(id)"
|
38
|
-
@set-open="({ id, open }) => setGroupOpen({ id, open })"
|
39
|
-
/>
|
40
|
-
</span>
|
14
|
+
:group-icon="group.icon"
|
15
|
+
:group-title="group.title"
|
16
|
+
:actions="group.actions"
|
17
|
+
class="px-2"
|
18
|
+
:active="groupId === group.id"
|
19
|
+
:position="getPosition(idx)"
|
20
|
+
@click="toggleGroup(group.id)"
|
21
|
+
/>
|
41
22
|
</div>
|
42
23
|
</v-toolbar-items>
|
43
24
|
</v-toolbar>
|
@@ -60,55 +41,117 @@
|
|
60
41
|
background-color: #ffffffda;
|
61
42
|
}
|
62
43
|
}
|
44
|
+
|
45
|
+
.marginToTop {
|
46
|
+
margin-top: 2px;
|
47
|
+
}
|
63
48
|
</style>
|
64
49
|
|
65
50
|
<script>
|
66
51
|
|
67
|
-
|
68
|
-
|
52
|
+
import { inject, ref, computed, watch, onUnmounted } from '@vue/composition-api';
|
53
|
+
import ToolboxGroupComponent from './ToolboxGroupComponent.vue';
|
54
|
+
import {ButtonLocation, vcsAppSymbol} from '@vcmap/ui';
|
55
|
+
|
56
|
+
/**
|
57
|
+
* @typedef {Object} ActionGroup
|
58
|
+
* @property {string} id
|
59
|
+
* @property {string} icon
|
60
|
+
* @property {string} title
|
61
|
+
* @property {Array<VcsAction>} actions
|
62
|
+
*/
|
69
63
|
|
70
|
-
|
71
|
-
|
64
|
+
/**
|
65
|
+
* @description ToolboxManager component rendering toolbox using {@link ToolboxGroupComponent}.
|
66
|
+
* @vue-computed {Array<ActionGroup>} actionGroups - Array of group components
|
67
|
+
* @vue-computed {number} width - width of toolbox depending on number of groups
|
68
|
+
*/
|
69
|
+
export default {
|
70
|
+
name: 'VcsToolboxManager',
|
71
|
+
components: {
|
72
|
+
ToolboxGroupComponent,
|
73
|
+
},
|
74
|
+
setup() {
|
75
|
+
const app = inject('vcsApp');
|
72
76
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
77
|
+
const toolboxComponentIds = ref(app.toolboxManager.componentIds);
|
78
|
+
const actionGroups = computed(() => {
|
79
|
+
const groups = toolboxComponentIds.value.map(id => app.toolboxManager.get(id));
|
80
|
+
return groups
|
81
|
+
.map((g) => {
|
82
|
+
const buttonIds = ref(g.buttonManager.componentIds);
|
83
|
+
return {
|
84
|
+
id: g.id,
|
85
|
+
icon: g.icon,
|
86
|
+
title: g.title,
|
87
|
+
actions: buttonIds.value.map(id => g.buttonManager.get(id).action),
|
88
|
+
};
|
89
|
+
})
|
90
|
+
.filter(g => g.actions.length > 0);
|
91
|
+
});
|
92
|
+
|
93
|
+
const toolboxOpen = ref(true);
|
94
|
+
const toolboxToggleAction = {
|
95
|
+
name: 'toolboxToggleAction',
|
96
|
+
icon: '$vcsTools',
|
97
|
+
title: 'Toolbox',
|
98
|
+
active: true,
|
99
|
+
callback() {
|
100
|
+
this.active = !this.active;
|
101
|
+
toolboxOpen.value = this.active;
|
79
102
|
},
|
80
|
-
}
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
103
|
+
};
|
104
|
+
|
105
|
+
const stopWatching = watch([actionGroups],
|
106
|
+
([actionGroups]) => {
|
107
|
+
if (actionGroups.length > 0) {
|
108
|
+
if (!app.navbarManager.has('toolbox')) {
|
109
|
+
app.navbarManager.add(
|
110
|
+
{
|
111
|
+
id: 'toolbox',
|
112
|
+
action: toolboxToggleAction,
|
113
|
+
},
|
114
|
+
vcsAppSymbol,
|
115
|
+
ButtonLocation.TOOL,
|
116
|
+
);
|
117
|
+
}
|
118
|
+
} else {
|
119
|
+
app.navbarManager.remove('toolbox');
|
120
|
+
}
|
121
|
+
}
|
122
|
+
);
|
123
|
+
|
124
|
+
onUnmounted(() => {
|
125
|
+
stopWatching();
|
126
|
+
});
|
127
|
+
|
128
|
+
// XXX can this solved by CSS to get rid of the hardcoded size and padding?
|
129
|
+
const buttonSize = 54;
|
130
|
+
const buttonPadding = 8;
|
131
|
+
const size = buttonSize + (2 * buttonPadding);
|
132
|
+
const width = computed(() => actionGroups.value.length * size);
|
98
133
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
134
|
+
/**
|
135
|
+
* calculates relative x-position of a button from the left edge of toolbar
|
136
|
+
* @param {number} idx
|
137
|
+
* @returns {number}
|
138
|
+
*/
|
139
|
+
const getPosition = (idx) => (size * (idx + 1)) - (size / 2);
|
140
|
+
|
141
|
+
return {
|
142
|
+
toolboxOpen,
|
143
|
+
actionGroups,
|
144
|
+
width,
|
145
|
+
getPosition,
|
146
|
+
groupId: null,
|
147
|
+
toggleGroup(groupId) {
|
148
|
+
if (this.groupId === groupId) {
|
149
|
+
this.groupId = null;
|
150
|
+
} else {
|
151
|
+
this.groupId = groupId;
|
152
|
+
}
|
153
|
+
},
|
154
|
+
};
|
155
|
+
},
|
156
|
+
};
|
114
157
|
</script>
|
@@ -0,0 +1,204 @@
|
|
1
|
+
/* eslint-disable import/prefer-default-export */
|
2
|
+
import { VcsEvent } from '@vcmap/core';
|
3
|
+
import { reactive } from '@vue/composition-api';
|
4
|
+
import { check, checkMaybe } from '@vcsuite/check';
|
5
|
+
import { v4 as uuidv4 } from 'uuid';
|
6
|
+
import { ButtonManager } from '../buttonManager.js';
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @typedef ToolboxGroupComponentOptions
|
10
|
+
* @property {string} [id] Optional ID, If not provided an uuid will be generated.
|
11
|
+
* @property {string} [icon] Optional group icon, for dropdowns
|
12
|
+
* @property {string} [title] Optional group title, for dropdowns
|
13
|
+
*/
|
14
|
+
|
15
|
+
/**
|
16
|
+
* @typedef ToolboxGroupComponent
|
17
|
+
* @property {string} id
|
18
|
+
* @property {string} title
|
19
|
+
* @property {ButtonManager} buttonManager
|
20
|
+
*/
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Default groups predefining icon and title of the group
|
24
|
+
* @type {Array<ToolboxGroupComponentOptions>}
|
25
|
+
*/
|
26
|
+
const defaultGroups = [
|
27
|
+
{
|
28
|
+
id: 'select',
|
29
|
+
icon: '$vcsPen',
|
30
|
+
title: 'select',
|
31
|
+
},
|
32
|
+
{
|
33
|
+
id: 'measurement',
|
34
|
+
icon: '$vcsDimensionsHouse',
|
35
|
+
title: 'measurement',
|
36
|
+
},
|
37
|
+
{
|
38
|
+
id: 'flight',
|
39
|
+
icon: '$vcsVideoRecorder',
|
40
|
+
title: 'flight',
|
41
|
+
},
|
42
|
+
];
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Requests default groups for a toolboxManager.
|
46
|
+
* Once requested, group id, icon and title are defined and cannot be changed or overwritten.
|
47
|
+
* @param {ToolboxManager} toolboxManager
|
48
|
+
* @param {Array<ToolboxGroupComponentOptions>} groups
|
49
|
+
*/
|
50
|
+
export function setupDefaultGroups(toolboxManager, groups = defaultGroups) {
|
51
|
+
groups.forEach(({ id, icon, title }) => toolboxManager.requestGroup(id, icon, title));
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @class ToolboxManager
|
56
|
+
* @description Manages a set of Toolbox Groups
|
57
|
+
* @implements VcsComponentManager<ToolboxGroupComponent,ToolboxGroupComponentOptions>
|
58
|
+
*/
|
59
|
+
export class ToolboxManager {
|
60
|
+
constructor() {
|
61
|
+
/**
|
62
|
+
* @type {import("@vcmap/core").VcsEvent<ToolboxGroupComponent>}
|
63
|
+
*/
|
64
|
+
this.added = new VcsEvent();
|
65
|
+
/**
|
66
|
+
* @type {import("@vcmap/core").VcsEvent<ToolboxGroupComponent>}
|
67
|
+
*/
|
68
|
+
this.removed = new VcsEvent();
|
69
|
+
/**
|
70
|
+
* reactive ordered array of ids,
|
71
|
+
* @type {Array<string>}
|
72
|
+
*/
|
73
|
+
this.componentIds = reactive([]);
|
74
|
+
|
75
|
+
/**
|
76
|
+
* @type {Map<string, ToolboxGroupComponent>}
|
77
|
+
* @private
|
78
|
+
*/
|
79
|
+
this._toolboxGroups = new Map();
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* @param {string} id
|
84
|
+
* @returns {ToolboxGroupComponent}
|
85
|
+
*/
|
86
|
+
get(id) {
|
87
|
+
return this._toolboxGroups.get(id);
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* @param {string} id
|
92
|
+
* @returns {boolean}
|
93
|
+
*/
|
94
|
+
has(id) {
|
95
|
+
return this._toolboxGroups.has(id);
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Toolbox groups should be static. Removing them can lead to undefined behavior.
|
100
|
+
* @param {string} id
|
101
|
+
*/
|
102
|
+
remove(id) {
|
103
|
+
check(id, String);
|
104
|
+
const toolboxGroupComponent = this._toolboxGroups.get(id);
|
105
|
+
if (toolboxGroupComponent) {
|
106
|
+
const index = this.componentIds.indexOf(id);
|
107
|
+
this.componentIds.splice(index, 1);
|
108
|
+
this._toolboxGroups.delete(id);
|
109
|
+
this.removed.raiseEvent(toolboxGroupComponent);
|
110
|
+
toolboxGroupComponent.buttonManager.destroy();
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Do not call add directly. Use requestGroup for adding toolbox groups.
|
116
|
+
* @param {ToolboxGroupComponentOptions} toolboxGroupComponentOptions
|
117
|
+
* @throws {Error} if a buttonComponent with the same ID has already been added
|
118
|
+
* @returns {ToolboxGroupComponent}
|
119
|
+
*/
|
120
|
+
add(toolboxGroupComponentOptions) {
|
121
|
+
checkMaybe(toolboxGroupComponentOptions.id, String);
|
122
|
+
checkMaybe(toolboxGroupComponentOptions.icon, String);
|
123
|
+
checkMaybe(toolboxGroupComponentOptions.title, String);
|
124
|
+
|
125
|
+
if (toolboxGroupComponentOptions.id && this.has(toolboxGroupComponentOptions.id)) {
|
126
|
+
throw new Error(`A toolGroup with id ${toolboxGroupComponentOptions.id} has already been registered.`);
|
127
|
+
}
|
128
|
+
const id = toolboxGroupComponentOptions.id || uuidv4();
|
129
|
+
const icon = toolboxGroupComponentOptions.icon || undefined;
|
130
|
+
const title = toolboxGroupComponentOptions.title || undefined;
|
131
|
+
const buttonManager = new ButtonManager();
|
132
|
+
|
133
|
+
/**
|
134
|
+
* @type {ToolboxGroupComponent}
|
135
|
+
*/
|
136
|
+
const toolboxGroupComponent = {
|
137
|
+
get id() {
|
138
|
+
return id;
|
139
|
+
},
|
140
|
+
get icon() {
|
141
|
+
return icon;
|
142
|
+
},
|
143
|
+
get title() {
|
144
|
+
return title;
|
145
|
+
},
|
146
|
+
get buttonManager() {
|
147
|
+
return buttonManager;
|
148
|
+
},
|
149
|
+
};
|
150
|
+
|
151
|
+
this._toolboxGroups.set(id, toolboxGroupComponent);
|
152
|
+
this.componentIds.push(id);
|
153
|
+
this.added.raiseEvent(toolboxGroupComponent);
|
154
|
+
return toolboxGroupComponent;
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Returns an existing group or creates a new group. Add toolbox groups with this API.
|
159
|
+
* @param {string} id
|
160
|
+
* @param {string} [icon='mdi-select-group']
|
161
|
+
* @param {string} [title='defaultGroup']
|
162
|
+
* @returns {ToolboxGroupComponent}
|
163
|
+
*/
|
164
|
+
requestGroup(id, icon = 'mdi-select-group', title = 'defaultGroup') {
|
165
|
+
check(id, String);
|
166
|
+
checkMaybe(icon, String);
|
167
|
+
checkMaybe(title, String);
|
168
|
+
|
169
|
+
if (this.has(id)) {
|
170
|
+
return this.get(id);
|
171
|
+
} else {
|
172
|
+
return this.add({ id, icon, title });
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
/**
|
177
|
+
* removes all {@link ButtonComponent}s of a specific owner and fires removed Events
|
178
|
+
* @param {string|vcsAppSymbol} owner
|
179
|
+
*/
|
180
|
+
removeOwner(owner) {
|
181
|
+
this.componentIds.forEach((id) => {
|
182
|
+
this.get(id).buttonManager.removeOwner(owner);
|
183
|
+
});
|
184
|
+
}
|
185
|
+
|
186
|
+
/**
|
187
|
+
* removes all buttonComponents and fires removed Events
|
188
|
+
*/
|
189
|
+
clear() {
|
190
|
+
const componentIds = [...this.componentIds];
|
191
|
+
componentIds.forEach((id) => { this.remove(id); });
|
192
|
+
}
|
193
|
+
|
194
|
+
/**
|
195
|
+
* destroys the ButtonManager;
|
196
|
+
*/
|
197
|
+
destroy() {
|
198
|
+
this.added.destroy();
|
199
|
+
this.removed.destroy();
|
200
|
+
this.clear();
|
201
|
+
this.componentIds.splice(0);
|
202
|
+
this._toolboxGroups.clear();
|
203
|
+
}
|
204
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<div>
|
2
|
+
<div :class="$vuetify.breakpoint.xs ? 'win-container-mobile' : 'unset'">
|
3
3
|
<WindowComponent
|
4
4
|
v-for="(id, zIndex) in componentIds"
|
5
5
|
:key="id"
|
@@ -28,6 +28,23 @@
|
|
28
28
|
</div>
|
29
29
|
</template>
|
30
30
|
|
31
|
+
<style scoped lang="scss">
|
32
|
+
.win-container-mobile {
|
33
|
+
position: absolute;
|
34
|
+
z-index: 2;
|
35
|
+
width: 100%;
|
36
|
+
height: 100%;
|
37
|
+
}
|
38
|
+
.win-container-mobile > {
|
39
|
+
div{
|
40
|
+
width: 100% !important;
|
41
|
+
inset: unset !important;
|
42
|
+
border-radius: 0 !important;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
</style>
|
47
|
+
|
31
48
|
<script>
|
32
49
|
import { inject } from '@vue/composition-api';
|
33
50
|
|
@@ -71,7 +71,7 @@ export const WindowPositions = {
|
|
71
71
|
|
72
72
|
/**
|
73
73
|
* @typedef WindowComponentOptions
|
74
|
-
* @property {string} [id] Optional ID, If not provided
|
74
|
+
* @property {string} [id] Optional ID, If not provided an uuid will be generated.
|
75
75
|
* @property {VueComponent} component Main Component which is shown below the header.
|
76
76
|
* @property {VueComponent} [headerComponent] Replaces the Header Component.
|
77
77
|
* @property {WindowPositionOptions} [position] Will be ignored if WindowSlot !== DETACHED, can be given otherwise or default will be used
|
@@ -199,10 +199,7 @@ export class WindowManager {
|
|
199
199
|
* @returns {WindowComponent}
|
200
200
|
*/
|
201
201
|
get(id) {
|
202
|
-
|
203
|
-
return this._windowComponents.get(id);
|
204
|
-
}
|
205
|
-
return undefined;
|
202
|
+
return this._windowComponents.get(id);
|
206
203
|
}
|
207
204
|
|
208
205
|
/**
|
@@ -219,6 +216,7 @@ export class WindowManager {
|
|
219
216
|
* @param {string} id
|
220
217
|
*/
|
221
218
|
remove(id) {
|
219
|
+
check(id, String);
|
222
220
|
const windowComponent = this._windowComponents.get(id);
|
223
221
|
if (windowComponent) {
|
224
222
|
const index = this.componentIds.indexOf(id);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<v-container class="nav-container">
|
2
|
+
<v-container :class="$vuetify.breakpoint.xs ? 'nav-container mobile' : 'nav-container'">
|
3
3
|
<v-row>
|
4
4
|
<VcsCompass
|
5
5
|
:view-mode="viewMode"
|
@@ -13,16 +13,16 @@
|
|
13
13
|
v-model="heading"
|
14
14
|
/>
|
15
15
|
</v-row>
|
16
|
-
<v-row justify="center">
|
16
|
+
<v-row justify="center" v-if="$vuetify.breakpoint.mdAndUp">
|
17
17
|
<VcsZoomButton
|
18
18
|
@zoom-out="zoomOut()"
|
19
19
|
@zoom-in="zoomIn()"
|
20
20
|
/>
|
21
21
|
</v-row>
|
22
|
-
<v-row v-if="is3D
|
22
|
+
<v-row justify="center" v-if="is3D && $vuetify.breakpoint.mdAndUp">
|
23
23
|
<TiltSlider v-model="tilt" />
|
24
24
|
</v-row>
|
25
|
-
<v-row justify="center">
|
25
|
+
<v-row justify="center" v-if="$vuetify.breakpoint.mdAndUp">
|
26
26
|
<OrientationToolsButton
|
27
27
|
:icon="overviewAction.icon"
|
28
28
|
:tooltip="overviewAction.title"
|
@@ -191,8 +191,12 @@
|
|
191
191
|
right: 2rem;
|
192
192
|
bottom: 2rem;
|
193
193
|
width: unset;
|
194
|
+
&.mobile{
|
195
|
+
top: 1rem;
|
196
|
+
right: 1rem;
|
197
|
+
bottom: auto;
|
198
|
+
}
|
194
199
|
}
|
195
|
-
|
196
200
|
.nav-container > {
|
197
201
|
.row {
|
198
202
|
margin-bottom: 15px;
|
@@ -23,7 +23,7 @@
|
|
23
23
|
}
|
24
24
|
</style>
|
25
25
|
<script>
|
26
|
-
import
|
26
|
+
import VcsTooltip from '../components/notification/VcsTooltip.vue';
|
27
27
|
|
28
28
|
/**
|
29
29
|
* A v-card with h & w 8. Requires an icon and binds all attributes & listeners to the v-card
|
@@ -47,7 +47,7 @@
|
|
47
47
|
</style>
|
48
48
|
<script>
|
49
49
|
import { clamp } from 'ol/math.js';
|
50
|
-
import
|
50
|
+
import VcsTooltip from '../components/notification/VcsTooltip.vue';
|
51
51
|
|
52
52
|
/**
|
53
53
|
* A vertical slider from 0 to -90. pass value with v-model
|