Added zoom UI
This commit is contained in:
parent
42ac51f1e9
commit
23ea9e77c4
@ -76,6 +76,29 @@
|
|||||||
</GhettoContextMenuOption>
|
</GhettoContextMenuOption>
|
||||||
</slot>
|
</slot>
|
||||||
</GhettoContextMenu>
|
</GhettoContextMenu>
|
||||||
|
<GhettoContextMenu alignment="right">
|
||||||
|
<template v-slot:activator>
|
||||||
|
Zoom
|
||||||
|
</template>
|
||||||
|
<slot>
|
||||||
|
<GhettoContextMenuOption
|
||||||
|
v-for="(command, index) of settings?.active.commands.zoom"
|
||||||
|
:key="index"
|
||||||
|
:label="command.label"
|
||||||
|
:shortcut="getKeyboardShortcutLabel(command)"
|
||||||
|
@click="execAction(command)"
|
||||||
|
>
|
||||||
|
</GhettoContextMenuOption>
|
||||||
|
<GhettoContextMenuItem
|
||||||
|
:disableHover="true"
|
||||||
|
>
|
||||||
|
<ZoomControl
|
||||||
|
:settings="settings"
|
||||||
|
:eventBus="eventBus"
|
||||||
|
/>
|
||||||
|
</GhettoContextMenuItem>
|
||||||
|
</slot>
|
||||||
|
</GhettoContextMenu>
|
||||||
<GhettoContextMenu alignment="right">
|
<GhettoContextMenu alignment="right">
|
||||||
<template v-slot:activator>
|
<template v-slot:activator>
|
||||||
<div class="context-item">
|
<div class="context-item">
|
||||||
@ -211,6 +234,7 @@ export default {
|
|||||||
AlignmentOptionsControlComponent,
|
AlignmentOptionsControlComponent,
|
||||||
SupportLevelIndicator,
|
SupportLevelIndicator,
|
||||||
TriggerZoneEditor,
|
TriggerZoneEditor,
|
||||||
|
ZoomControl,
|
||||||
},
|
},
|
||||||
mixins: [
|
mixins: [
|
||||||
UIProbeMixin,
|
UIProbeMixin,
|
||||||
|
112
src/csui/src/popup/player-menu/ZoomControl.vue
Normal file
112
src/csui/src/popup/player-menu/ZoomControl.vue
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Custom zoom
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="top-label">Zoom:</div>
|
||||||
|
<div class="input range-input">
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
class="slider"
|
||||||
|
min="0"
|
||||||
|
max="3"
|
||||||
|
step="0.01"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="true">
|
||||||
|
<div class="top-label">Vertical zoom:</div>
|
||||||
|
<div class="input range-input">
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
class="slider"
|
||||||
|
min="0"
|
||||||
|
max="3"
|
||||||
|
step="0.01"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div><input type="checkbox"/> Control vertical and horizontal zoom independently.</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
zoomAspectRatioLocked: true,
|
||||||
|
zoom: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: this should be mixin?
|
||||||
|
resizerConfig: {
|
||||||
|
crop: null,
|
||||||
|
stretch: null,
|
||||||
|
zoom: null,
|
||||||
|
pan: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mixins: [
|
||||||
|
|
||||||
|
],
|
||||||
|
props: [
|
||||||
|
'settings', // required for buttons and actions, which are global
|
||||||
|
'eventBus'
|
||||||
|
],
|
||||||
|
methods: {
|
||||||
|
getZoomForDisplay(axis) {
|
||||||
|
// zoom is internally handled logarithmically, because we want to have x0.5, x1, x2, x4 ... magnifications
|
||||||
|
// spaced out at regular intervals. When displaying, we need to convert that to non-logarithmic values.
|
||||||
|
|
||||||
|
return `${(Math.pow(2, this.zoom[axis]) * 100).toFixed()}%`
|
||||||
|
},
|
||||||
|
toggleZoomAr() {
|
||||||
|
this.zoomAspectRatioLocked = !this.zoomAspectRatioLocked;
|
||||||
|
},
|
||||||
|
|
||||||
|
resetZoom() {
|
||||||
|
// we store zoom logarithmically on this component
|
||||||
|
this.zoom = {x: 0, y: 0};
|
||||||
|
|
||||||
|
// we do not use logarithmic zoom elsewhere
|
||||||
|
// todo: replace eventBus with postMessage to parent
|
||||||
|
// this.eventBus.send('set-zoom', {zoom: 1, axis: 'y'});
|
||||||
|
// this.eventBus.send('set-zoom', {zoom: 1, axis: 'x'});
|
||||||
|
|
||||||
|
this.eventBus?.sendToTunnel('set-zoom', {zoom: 1, axis: 'y'});
|
||||||
|
this.eventBus?.sendToTunnel('set-zoom', {zoom: 1, axis: 'x'});
|
||||||
|
},
|
||||||
|
changeZoom(newZoom, axis) {
|
||||||
|
// we store zoom logarithmically on this compnent
|
||||||
|
if (!axis) {
|
||||||
|
this.zoom.x = newZoom;
|
||||||
|
} else {
|
||||||
|
this.zoom[axis] = newZoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we do not use logarithmic zoom elsewhere, therefore we need to convert
|
||||||
|
newZoom = Math.pow(2, newZoom);
|
||||||
|
|
||||||
|
if (this.zoomAspectRatioLocked) {
|
||||||
|
this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: 'y'});
|
||||||
|
this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: 'x'});
|
||||||
|
} else {
|
||||||
|
this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: axis ?? 'x'});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" src="@csui/res/css/flex.scss" scoped></style>
|
||||||
|
<style lang="scss" src="@csui/src/res-common/panels.scss" scoped module></style>
|
||||||
|
<style lang="scss" src="@csui/src/res-common/common.scss" scoped module></style>
|
@ -62,30 +62,7 @@ button, .button {
|
|||||||
padding: 0.5rem 2rem;
|
padding: 0.5rem 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&.l2 {
|
|
||||||
margin-left: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
flex: 0 0 25%;
|
|
||||||
text-align: right;
|
|
||||||
padding-right: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input, .range-input {
|
.input, .range-input {
|
||||||
flex: 0 0 70%;
|
|
||||||
max-width: 24rem;
|
|
||||||
background-color: rgba($blackBg, $normalTransparentOpacity);
|
background-color: rgba($blackBg, $normalTransparentOpacity);
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.5);
|
border-bottom: 1px solid rgba(255,255,255,0.5);
|
||||||
@ -135,6 +112,32 @@ button, .button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.l2 {
|
||||||
|
margin-left: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
flex: 0 0 25%;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input, .range-input {
|
||||||
|
flex: 0 0 70%;
|
||||||
|
max-width: 24rem;
|
||||||
|
}
|
||||||
|
|
||||||
.hint {
|
.hint {
|
||||||
padding-left: calc(25% + 1rem);
|
padding-left: calc(25% + 1rem);
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
Loading…
Reference in New Issue
Block a user