Added zoom UI
This commit is contained in:
parent
42ac51f1e9
commit
23ea9e77c4
@ -76,6 +76,29 @@
|
||||
</GhettoContextMenuOption>
|
||||
</slot>
|
||||
</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">
|
||||
<template v-slot:activator>
|
||||
<div class="context-item">
|
||||
@ -211,6 +234,7 @@ export default {
|
||||
AlignmentOptionsControlComponent,
|
||||
SupportLevelIndicator,
|
||||
TriggerZoneEditor,
|
||||
ZoomControl,
|
||||
},
|
||||
mixins: [
|
||||
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,6 +62,56 @@ button, .button {
|
||||
padding: 0.5rem 2rem;
|
||||
}
|
||||
|
||||
.input, .range-input {
|
||||
background-color: rgba($blackBg, $normalTransparentOpacity);
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.5);
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
position: relative;
|
||||
|
||||
&:active, &:focus, &:focus-within {
|
||||
border-bottom: 1px solid rgba($primary, 0.5);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
outline: none;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.unit {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
pointer-events: none;
|
||||
opacity: 0.69;
|
||||
font-size: 0.8rem;
|
||||
top: 0;
|
||||
transform: translateY(69%);
|
||||
}
|
||||
}
|
||||
|
||||
.range-input {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
* {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
input {
|
||||
max-width: 5rem;
|
||||
}
|
||||
|
||||
input[type=range] {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -86,53 +136,6 @@ button, .button {
|
||||
.input, .range-input {
|
||||
flex: 0 0 70%;
|
||||
max-width: 24rem;
|
||||
background-color: rgba($blackBg, $normalTransparentOpacity);
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.5);
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
position: relative;
|
||||
|
||||
&:active, &:focus, &:focus-within {
|
||||
border-bottom: 1px solid rgba($primary, 0.5);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
outline: none;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.unit {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
pointer-events: none;
|
||||
opacity: 0.69;
|
||||
font-size: 0.8rem;
|
||||
top: 0;
|
||||
transform: translateY(69%);
|
||||
}
|
||||
}
|
||||
|
||||
.range-input {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
* {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
input {
|
||||
max-width: 5rem;
|
||||
}
|
||||
|
||||
input[type=range] {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
.hint {
|
||||
|
Loading…
Reference in New Issue
Block a user