Compare commits
4 Commits
11fa12001c
...
b2cd8197d4
| Author | SHA1 | Date | |
|---|---|---|---|
| b2cd8197d4 | |||
| 23ea9e77c4 | |||
| 42ac51f1e9 | |||
| d433878680 |
@ -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">
|
||||
@ -186,20 +209,21 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PlayerUIWindow from './src/PlayerUIWindow.vue';
|
||||
import GhettoContextMenu from './src/components/GhettoContextMenu.vue';
|
||||
import GhettoContextMenuItem from './src/components/GhettoContextMenuItem.vue';
|
||||
import GhettoContextMenuOption from './src/components/GhettoContextMenuOption.vue';
|
||||
import AlignmentOptionsControlComponent from './src/PlayerUiPanels/AlignmentOptionsControlComponent.vue';
|
||||
import BrowserDetect from '../ext/conf/BrowserDetect';
|
||||
import Logger from '../ext/lib/Logger';
|
||||
import Settings from '../ext/lib/Settings';
|
||||
import EventBus from '../ext/lib/EventBus';
|
||||
import UIProbeMixin from './src/utils/UIProbeMixin';
|
||||
import KeyboardShortcutParserMixin from './src/utils/KeyboardShortcutParserMixin';
|
||||
import CommsMixin from './src/utils/CommsMixin';
|
||||
import SupportLevelIndicator from './src/components/SupportLevelIndicator.vue';
|
||||
import TriggerZoneEditor from './src/components/TriggerZoneEditor.vue';
|
||||
import PlayerUIWindow from '@csui/src/PlayerUIWindow.vue';
|
||||
import GhettoContextMenu from '@csui/src/components/GhettoContextMenu.vue';
|
||||
import GhettoContextMenuItem from '@csui/src/components/GhettoContextMenuItem.vue';
|
||||
import GhettoContextMenuOption from '@csui/src/components/GhettoContextMenuOption.vue';
|
||||
import AlignmentOptionsControlComponent from '@csui/src/PlayerUiPanels/AlignmentOptionsControlComponent.vue';
|
||||
import BrowserDetect from '@src/ext/conf/BrowserDetect';
|
||||
import Logger from '@src/ext/lib/Logger';
|
||||
import Settings from '@src/ext/lib/Settings';
|
||||
import EventBus from '@src/ext/lib/EventBus';
|
||||
import UIProbeMixin from '@csui/src/utils/UIProbeMixin';
|
||||
import KeyboardShortcutParserMixin from '@csui/src/utils/KeyboardShortcutParserMixin';
|
||||
import CommsMixin from '@csui/src/utils/CommsMixin';
|
||||
import SupportLevelIndicator from '@csui/src/components/SupportLevelIndicator.vue';
|
||||
import TriggerZoneEditor from '@csui/src/components/TriggerZoneEditor.vue';
|
||||
import ZoomControl from '@csui/src/popup/player-menu/ZoomControl.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -210,6 +234,7 @@ export default {
|
||||
AlignmentOptionsControlComponent,
|
||||
SupportLevelIndicator,
|
||||
TriggerZoneEditor,
|
||||
ZoomControl,
|
||||
},
|
||||
mixins: [
|
||||
UIProbeMixin,
|
||||
@ -570,9 +595,8 @@ export default {
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="./src/res-common/panels.scss" scoped module></style>
|
||||
<style lang="scss" src="./src/res-common/common.scss" scoped module></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>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.uw-hover {
|
||||
|
||||
@ -63,7 +63,7 @@
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Do not show in-player UI when video player is narrower than (% of screen width)
|
||||
Do not show in-player UI when video player is narrower than
|
||||
</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
@ -77,16 +77,18 @@
|
||||
@change="(event) => saveSettings()"
|
||||
>
|
||||
<input
|
||||
style="margin-right: 0.6rem;"
|
||||
:value="ghettoComputed.minEnabledWidth"
|
||||
@input="(event) => setPlayerRestrictions('minEnabledWidth', event.target.value, true)"
|
||||
@change="(event) => saveSettings(true)"
|
||||
>
|
||||
<div class="unit">% of screen</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Do not show in-player UI when video player is shorter than (% of screen width)
|
||||
Do not show in-player UI when video player is shorter than
|
||||
</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
@ -100,10 +102,12 @@
|
||||
@change="(event) => saveSettings()"
|
||||
>
|
||||
<input
|
||||
style="margin-right: 0.6rem;"
|
||||
:value="ghettoComputed.minEnabledHeight"
|
||||
@input="(event) => setPlayerRestrictions('minEnabledHeight', event.target.value, true)"
|
||||
@change="(event) => saveSettings(true)"
|
||||
>
|
||||
<div class="unit">% of screen</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -242,8 +246,6 @@ export default {
|
||||
max-width: 24rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.trigger-zone-editor {
|
||||
background-color: rgba(0,0,0,0.25);
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
@ -112,9 +112,16 @@ export default {
|
||||
if (! this.uwWindowVisible) {
|
||||
this.uwTriggerZoneVisible = true;
|
||||
clearTimeout(this.uwTriggerZoneTimeout);
|
||||
|
||||
const windowParent = window.parent;
|
||||
this.uwTriggerZoneTimeout = setTimeout(
|
||||
() => {
|
||||
this.uwTriggerZoneVisible = false;
|
||||
|
||||
windowParent.postMessage(
|
||||
{action: 'uwui-hidden', opacity: false},
|
||||
origin
|
||||
);
|
||||
},
|
||||
500
|
||||
);
|
||||
@ -134,6 +141,7 @@ export default {
|
||||
{
|
||||
action: 'uwui-clickable',
|
||||
clickable: isClickable,
|
||||
opacity: isClickable || this.contextMenuActive || this.uwTriggerZoneVisible,
|
||||
hoverStats: {
|
||||
isOverTriggerZone: isOverTriggerZone,
|
||||
isOverMenuTrigger: isOverMenuTrigger,
|
||||
|
||||
@ -95,6 +95,7 @@ class UI {
|
||||
iframe.style.zIndex = this.isGlobal ? '90009' : '90000';
|
||||
iframe.style.border = 0;
|
||||
iframe.style.pointerEvents = 'none';
|
||||
iframe.style.opacity = 0;
|
||||
iframe.style.backgroundColor = 'transparent !important';
|
||||
|
||||
/* so we have a problem: we want iframe to be clickthrough everywhere except
|
||||
@ -323,7 +324,7 @@ class UI {
|
||||
}
|
||||
|
||||
this.uiIframe.style.pointerEvents = event.data.clickable ? 'auto' : 'none';
|
||||
this.uiIframe.style.display = event.data.opacity ? '100' : '0';
|
||||
this.uiIframe.style.opacity = event.data.opacity ? '100' : '0';
|
||||
break;
|
||||
case 'uw-bus-tunnel':
|
||||
const busCommand = event.data.payload;
|
||||
@ -335,6 +336,9 @@ class UI {
|
||||
case 'uwui-interface-ready':
|
||||
this.setUiVisibility(!this.isGlobal);
|
||||
break;
|
||||
case 'uwui-hidden':
|
||||
this.uiIframe.style.opacity = event.data.opacity ? '100' : '0';
|
||||
break;
|
||||
case 'uwui-global-window-hidden':
|
||||
if (!this.isGlobal) {
|
||||
return; // This shouldn't even happen in non-global windows
|
||||
|
||||
Loading…
Reference in New Issue
Block a user