Mercurial > gemma
changeset 3016:083cd270bdfd
client: splitview: implemented rotation mechanism
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Thu, 11 Apr 2019 16:44:27 +0200 |
parents | fe88a9b151ca |
children | 9a408a8b74b8 |
files | client/src/components/Main.vue client/src/components/map/Map.vue |
diffstat | 2 files changed, 99 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/Main.vue Thu Apr 11 16:43:14 2019 +0200 +++ b/client/src/components/Main.vue Thu Apr 11 16:44:27 2019 +0200 @@ -6,6 +6,19 @@ { 'flex-column': ['left', 'right'].includes(paneMode) } ]" > + <div + v-if="panes.length !== 1" + id="pane-controls" + class="position-absolute wh-100 d-flex justify-content-center align-items-center" + > + <div + class="box-control bg-white ui-element small shadow-sm" + @click="togglePaneMode" + > + <font-awesome-icon icon="redo" fixed-width /> + </div> + </div> + <template v-if="panes.length === 1"> <div id="pane1" class="pane wh-100"><component :is="panes[0]" /></div> </template> @@ -34,34 +47,34 @@ <div id="pane1" class="pane w-100 h-50"> <component :is="panes[0]" /> </div> + <div id="pane3" class="pane w-50 h-50"> + <component :is="panes[2]" /> + </div> + <div id="pane2" class="pane w-50 h-50"> + <component :is="panes[1]" /> + </div> + </template> + <template v-if="paneMode === 'right'"> + <div id="pane3" class="pane w-50 h-50"> + <component :is="panes[2]" /> + </div> + <div id="pane2" class="pane w-50 h-50"> + <component :is="panes[1]" /> + </div> + <div id="pane1" class="pane w-50 h-100"> + <component :is="panes[0]" /> + </div> + </template> + <template v-if="paneMode === 'bottom'"> <div id="pane2" class="pane w-50 h-50"> <component :is="panes[1]" /> </div> <div id="pane3" class="pane w-50 h-50"> <component :is="panes[2]" /> </div> - </template> - <template v-if="paneMode === 'right'"> - <div id="pane1" class="pane w-50 h-50"> + <div id="pane1" class="pane w-100 h-50"> <component :is="panes[0]" /> </div> - <div id="pane2" class="pane w-50 h-50"> - <component :is="panes[1]" /> - </div> - <div id="pane3" class="pane w-50 h-100"> - <component :is="panes[2]" /> - </div> - </template> - <template v-if="paneMode === 'bottom'"> - <div id="pane1" class="pane w-50 h-50"> - <component :is="panes[0]" /> - </div> - <div id="pane2" class="pane w-50 h-50"> - <component :is="panes[1]" /> - </div> - <div id="pane3" class="pane w-100 h-50"> - <component :is="panes[2]" /> - </div> </template> <template v-if="paneMode === 'left'"> <div id="pane1" class="pane w-50 h-100"> @@ -79,8 +92,8 @@ <template v-if="panes.length === 4"> <div id="pane1" class="pane w-50 h-50"><component :is="panes[0]" /></div> <div id="pane2" class="pane w-50 h-50"><component :is="panes[1]" /></div> + <div id="pane4" class="pane w-50 h-50"><component :is="panes[3]" /></div> <div id="pane3" class="pane w-50 h-50"><component :is="panes[2]" /></div> - <div id="pane4" class="pane w-50 h-50"><component :is="panes[3]" /></div> </template> </div> </template> @@ -92,6 +105,9 @@ bottom: -1.5px left: -1.5px z-index: 1 + #pane-controls + z-index: 1 + pointer-events: none .pane border: solid 1.5px #fff background-color: #eee @@ -123,8 +139,57 @@ // all components that are supposed to be displayed in a pane must be registered here Map: () => import("./map/Map") }, + data() { + return { + // This is needed to accomplish a true rotation of components/panes with + // two panes. On every second "rotation" the components are fliped. This way + // toggling between horizontal and vertical mode feels like the components + // are actually rotating. See: togglePaneMode() + rotations: 0 + }; + }, computed: { ...mapState("application", ["panes", "paneMode"]) + }, + watch: { + panes(panes) { + if (panes.length !== 2) this.rotations = 0; + } + }, + methods: { + rotateComponents() { + this.panes.unshift(this.panes.pop()); + }, + togglePaneMode() { + if (this.panes.length === 2) { + this.$store.commit( + "application/paneMode", + this.paneMode === "horizontal" ? "vertical" : "horizontal" + ); + if (++this.rotations % 2) { + this.rotateComponents(); + } + } + if (this.panes.length === 3) { + let next; + if (this.paneMode === "top") { + next = "right"; + } + if (this.paneMode === "right") { + next = "bottom"; + } + if (this.paneMode === "bottom") { + next = "left"; + } + if (this.paneMode === "left") { + next = "top"; + } + this.$store.commit("application/paneMode", next); + } + if (this.panes.length === 4) { + this.rotateComponents(); + } + } } }; </script>
--- a/client/src/components/map/Map.vue Thu Apr 11 16:43:14 2019 +0200 +++ b/client/src/components/map/Map.vue Thu Apr 11 16:44:27 2019 +0200 @@ -53,6 +53,7 @@ mixins: [uuid], data() { return { + map: null, splitscreen: false }; }, @@ -66,7 +67,7 @@ "cutTool" ]), ...mapState("bottlenecks", ["selectedSurvey"]), - ...mapState("application", ["showSplitscreen"]), + ...mapState("application", ["showSplitscreen", "panes", "paneMode"]), ...mapState("imports", ["selectedStretchId"]), hasActiveInteractions() { return ( @@ -101,11 +102,14 @@ this.splitscreen = false; } }, + panes() { + this.$nextTick(() => this.map.updateSize()); + }, + paneMode() { + this.$nextTick(() => this.map.updateSize()); + }, splitscreen() { - const map = this.openLayersMap; - this.$nextTick(() => { - map && map.updateSize(); - }); + this.$nextTick(() => this.map.updateSize()); }, selectedSurvey(newSelectedSurvey) { if (newSelectedSurvey) { @@ -131,7 +135,7 @@ } }, mounted() { - const map = new Map({ + this.map = new Map({ layers: layers.config, target: "map-" + this.uuid, controls: [], @@ -142,11 +146,11 @@ projection: "EPSG:3857" }) }); - map.getLayer = id => layers.get(id); + this.map.getLayer = id => layers.get(id); // store map position on every move // will be obsolete once we abandoned the separated admin context - map.on("moveend", event => { + this.map.on("moveend", event => { const center = event.map.getView().getCenter(); this.$store.commit("map/extent", { lat: center[1], @@ -154,7 +158,7 @@ zoom: event.map.getView().getZoom() }); }); - this.$store.dispatch("map/openLayersMap", map); + this.$store.dispatch("map/openLayersMap", this.map); // move to user specific default extent if map loads for the first timeout // checking initialLoad will be obsolete once we abandoned the separated admin context