Get manual zoom to work

This commit is contained in:
Tamius Han 2021-10-31 23:19:32 +01:00
parent 78da45d468
commit 829047585a
5 changed files with 145 additions and 119 deletions

View File

@ -1,37 +1,6 @@
export default { export default {
computed: { // computed: {
scopeActions: function() { // aspectRatioActions: this.settings?.active.commands.crop,
return this.settings?.active.actions?.filter(x => { // stretchActions: this.settings?.active.commands.stretch
if (! x.scopes) { // }
console.error('This action does not have a scope.', x); }
return false;
}
return x.scopes[this.scope] && x.scopes[this.scope].show
}) || [];
},
extensionActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-ExtensionMode') || [];
},
aardActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-autoar-mode') || [];
},
aspectRatioActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-ar') || [];
},
cropModePersistenceActions: function() {
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-ar-persistence') || [];
},
stretchActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-stretch') || [];
},
keyboardActions: function() {
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-keyboard') || [];
},
alignmentActions: function() {
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-alignment') || [];
},
otherActions: function() {
return this.scopeActions.filter(x => x.cmd.length > 1) || [];
}
}
}

View File

@ -0,0 +1,37 @@
export default {
computed: {
scopeActions: function() {
return this.settings?.active.actions?.filter(x => {
if (! x.scopes) {
console.error('This action does not have a scope.', x);
return false;
}
return x.scopes[this.scope] && x.scopes[this.scope].show
}) || [];
},
extensionActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-ExtensionMode') || [];
},
aardActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-autoar-mode') || [];
},
aspectRatioActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-ar') || [];
},
cropModePersistenceActions: function() {
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-ar-persistence') || [];
},
stretchActions: function(){
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-stretch') || [];
},
keyboardActions: function() {
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-keyboard') || [];
},
alignmentActions: function() {
return this.scopeActions.filter(x => x.cmd.length === 1 && x.cmd[0].action === 'set-alignment') || [];
},
otherActions: function() {
return this.scopeActions.filter(x => x.cmd.length > 1) || [];
}
}
}

View File

@ -1,33 +1,33 @@
<template> <template>
<div class="flex flex-row flex-wrap" style="padding-bottom: 20px"> <div class="flex flex-row flex-wrap" style="padding-bottom: 20px">
<div class="sub-panel"> <div v-if="settings" class="sub-panel">
<div class="flex flex-row"> <div class="flex flex-row">
<mdicon name="crop" :size="32" /> <mdicon name="crop" :size="32" />
<h1>Crop video:</h1> <h1>Crop video:</h1>
</div> </div>
<div class="sub-panel-content flex flex-row flex-wrap"> <div class="sub-panel-content flex flex-row flex-wrap">
<ShortcutButton v-for="(action, index) of aspectRatioActions" <ShortcutButton v-for="(command, index) of settings?.active.commands.crop"
class="flex b3 flex-grow button" class="flex b3 flex-grow button"
:key="index" :key="index"
:label="(action.scopes.page && action.scopes.page.label) ? action.scopes.page.label : action.label" :label="command.label"
:shortcut="parseShortcut(action)" :shortcut="parseShortcut(command)"
@click="execAction(action)" @click="execAction(command)"
> >
</ShortcutButton> </ShortcutButton>
</div> </div>
</div> </div>
<div class="sub-panel"> <div v-if="settings" class="sub-panel">
<div class="flex flex-row"> <div class="flex flex-row">
<mdicon name="stretch-to-page-outline" :size="32" /> <mdicon name="stretch-to-page-outline" :size="32" />
<h1>Stretch video:</h1> <h1>Stretch video:</h1>
</div> </div>
<div class="flex flex-row flex-wrap"> <div class="flex flex-row flex-wrap">
<ShortcutButton v-for="(action, index) of stretchActions" <ShortcutButton v-for="(command, index) of settings?.active.commands.stretch"
class="flex b3 flex-grow button" class="flex b3 flex-grow button"
:key="index" :key="index"
:label="(action.scopes.page && action.scopes.page.label) ? action.scopes.page.label : action.label" :label="command.label"
:shortcut="parseShortcut(action)" :shortcut="parseShortcut(command)"
@click="execAction(action)" @click="execAction(command)"
> >
</ShortcutButton> </ShortcutButton>
</div> </div>
@ -61,7 +61,7 @@
</Button> </Button>
</div> </div>
<template v-if="zoomAspectRatioLocked"> <template v-if="zoomAspectRatioLocked">
<div class="flex flex-row"> <!-- <div class="flex flex-row">
<ShortcutButton <ShortcutButton
class="flex b3 flex-grow button" class="flex b3 flex-grow button"
label="-5 %" label="-5 %"
@ -83,7 +83,7 @@
label="+5 %" label="+5 %"
> >
</ShortcutButton> </ShortcutButton>
</div> </div> -->
<input id="_input_zoom_slider" <input id="_input_zoom_slider"
class="input-slider" class="input-slider"
type="range" type="range"
@ -104,7 +104,7 @@
</template> </template>
<template v-else> <template v-else>
<div>Horizontal zoom</div> <div>Horizontal zoom</div>
<div class="flex flex-row"> <!-- <div class="flex flex-row">
<ShortcutButton <ShortcutButton
class="flex b3 flex-grow button" class="flex b3 flex-grow button"
label="-5 %" label="-5 %"
@ -126,7 +126,7 @@
label="+5 %" label="+5 %"
> >
</ShortcutButton> </ShortcutButton>
</div> </div> -->
<input id="_input_zoom_slider" <input id="_input_zoom_slider"
class="input-slider" class="input-slider"
type="range" type="range"
@ -134,12 +134,12 @@
min="-1" min="-1"
max="4" max="4"
:value="logarithmicZoom" :value="logarithmicZoom"
@input="changeZoom($event.target.value)" @input="changeZoom($event.target.value, 'x')"
/> />
<div>Vertical zoom</div> <div>Vertical zoom</div>
<div class="flex flex-row"> <div class="flex flex-row">
<ShortcutButton <!-- <ShortcutButton
class="flex b3 flex-grow button" class="flex b3 flex-grow button"
label="-5 %" label="-5 %"
> >
@ -159,7 +159,7 @@
class="flex b3 flex-grow button" class="flex b3 flex-grow button"
label="+5 %" label="+5 %"
> >
</ShortcutButton> </ShortcutButton> -->
</div> </div>
<input id="_input_zoom_slider" <input id="_input_zoom_slider"
class="input-slider" class="input-slider"
@ -168,7 +168,7 @@
min="-1" min="-1"
max="4" max="4"
:value="logarithmicZoom" :value="logarithmicZoom"
@input="changeZoom($event.target.value)" @input="changeZoom($event.target.value, 'y')"
/> />
<div style="overflow: auto" class="flex flex-row"> <div style="overflow: auto" class="flex flex-row">
@ -231,7 +231,6 @@ export default {
props: [ props: [
'settings', 'settings',
'frame', 'frame',
'zoom',
'cropModePersistence', 'cropModePersistence',
'eventBus' 'eventBus'
], ],
@ -252,31 +251,14 @@ export default {
async openOptionsPage() { async openOptionsPage() {
BrowserDetect.runtime.openOptionsPage(); BrowserDetect.runtime.openOptionsPage();
}, },
execAction(action) { execAction(command) {
this.eventBus?.send(command.action, command.arguments);
// TODO: migrate all actions to the new way of doing things
if (action.cmd[0].action === 'set-ar') {
this.eventBus?.send('set-ar', {
type: action.cmd[0].arg,
ratio: action.cmd[0].customArg
});
return;
}
console.log('execing action:', action, window.ultrawidify);
try {
this.exec.exec(action, 'page', this.frame, true);
} catch (error) {
console.error('[uw:VideoSettings.vue::execAction] failed to execute action. Error:', error);
}
}, },
parseShortcut(action) { parseShortcut(command) {
if (! action.scopes.page.shortcut) { if (! command.shortcut) {
return ''; return '';
} }
return KeyboardShortcutParser.parseShortcut(action.scopes.page.shortcut[0]); return KeyboardShortcutParser.parseShortcut(command.shortcut);
}, },
toggleZoomAr() { toggleZoomAr() {
@ -285,18 +267,16 @@ export default {
resetZoom() { resetZoom() {
this.zoom = 1; this.zoom = 1;
this.eventBus.send('set-zoom', {zoom: 1});
console.log('resetting zoom!');
}, },
changeZoom(newZoom, axis) { changeZoom(newZoom, axis) {
newZoom = Math.pow(2, newZoom); newZoom = Math.pow(2, newZoom);
console.log('new zoom:', newZoom);
this.exec.exec( this.eventBus.send('set-zoom', {zoom: newZoom, axis: axis});
{
cmd: [{action: 'set-zoom', arg: newZoom}]
},
'page',
this.frame,
true
);
}, },
} }
} }

View File

@ -22,6 +22,7 @@ class Resizer {
//#region flags //#region flags
canPan: boolean = false; canPan: boolean = false;
destroyed: boolean = false; destroyed: boolean = false;
manualZoom: boolean = false;
//#endregion //#endregion
//#region helper objects //#region helper objects
@ -56,7 +57,10 @@ class Resizer {
//#region event bus configuration //#region event bus configuration
private eventBusCommands = { private eventBusCommands = {
'set-ar': [{ 'set-ar': [{
function: (config: any) => this.setAr(config) function: (config: any) => {
this.manualZoom = false; // this only gets called from UI or keyboard shortcuts, making this action safe.
this.setAr(config);
}
}], }],
'set-alignment': [{ 'set-alignment': [{
function: (config: any) => { function: (config: any) => {
@ -64,10 +68,13 @@ class Resizer {
} }
}], }],
'set-stretch': [{ 'set-stretch': [{
function: (config: any) => this.setStretchMode(config.stretchMode, config.fixedAspectRatio) function: (config: any) => {
this.manualZoom = false; // we also need to unset manual aspect ratio when doing this
this.setStretchMode(config.stretchMode, config.fixedAspectRatio)
}
}], }],
'set-zoom': [{ 'set-zoom': [{
function: (config: any) => this.setZoom(config.zoomLevel) function: (config: any) => this.setZoom(config.zoom, config.axis)
}], }],
'change-zoom': [{ 'change-zoom': [{
function: (config: any) => this.zoomStep(config.step) function: (config: any) => this.zoomStep(config.step)
@ -138,8 +145,6 @@ class Resizer {
if (ar.type !== AspectRatioType.FitWidth && ar.type !== AspectRatioType.FitHeight && ar.ratio) { if (ar.type !== AspectRatioType.FitWidth && ar.type !== AspectRatioType.FitHeight && ar.ratio) {
return ar; return ar;
} }
// Skrbi za "stare" možnosti, kot na primer "na širino zaslona", "na višino zaslona" in "ponastavi".
// Približevanje opuščeno.
// handles "legacy" options, such as 'fit to widht', 'fit to height' and AspectRatioType.Reset. No zoom tho // handles "legacy" options, such as 'fit to widht', 'fit to height' and AspectRatioType.Reset. No zoom tho
let ratioOut; let ratioOut;
@ -157,9 +162,6 @@ class Resizer {
ratioOut = this.conf.player.dimensions.width / this.conf.player.dimensions.height; ratioOut = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
} }
// POMEMBNO: lastAr je potrebno nastaviti šele po tem, ko kličemo _res_setAr(). _res_setAr() predvideva,
// da želimo nastaviti statično (type: 'static') razmerje stranic — tudi, če funkcijo kličemo tu oz. v ArDetect.
//
// IMPORTANT NOTE: lastAr needs to be set after _res_setAr() is called, as _res_setAr() assumes we're // IMPORTANT NOTE: lastAr needs to be set after _res_setAr() is called, as _res_setAr() assumes we're
// setting a static aspect ratio (even if the function is called from here or ArDetect). // setting a static aspect ratio (even if the function is called from here or ArDetect).
@ -205,6 +207,10 @@ class Resizer {
return; return;
} }
if (ar.type !== AspectRatioType.Automatic) {
this.manualZoom = false;
}
if (!this.video.videoWidth || !this.video.videoHeight) { if (!this.video.videoWidth || !this.video.videoHeight) {
this.logger.log('warning', 'debug', '[Resizer::setAr] <rid:'+this.resizerId+'> Video has no width or no height. This is not allowed. Aspect ratio will not be set, and videoData will be uninitialized.'); this.logger.log('warning', 'debug', '[Resizer::setAr] <rid:'+this.resizerId+'> Video has no width or no height. This is not allowed. Aspect ratio will not be set, and videoData will be uninitialized.');
this.conf.videoUnloaded(); this.conf.videoUnloaded();
@ -322,7 +328,12 @@ class Resizer {
this.logger.log('error', 'debug', '[Resizer::setAr] Okay wtf happened? If you see this, something has gone wrong', stretchFactors,"\n------[ i n f o d u m p ]------\nstretcher:", this.stretcher); this.logger.log('error', 'debug', '[Resizer::setAr] Okay wtf happened? If you see this, something has gone wrong', stretchFactors,"\n------[ i n f o d u m p ]------\nstretcher:", this.stretcher);
} }
this.zoom.applyZoom(stretchFactors); this.applyScaling(stretchFactors);
}
private applyScaling(stretchFactors) {
console.log('applying scaling factors:', stretchFactors);
this.stretcher.chromeBugMitigation(stretchFactors); this.stretcher.chromeBugMitigation(stretchFactors);
let translate = this.computeOffsets(stretchFactors); let translate = this.computeOffsets(stretchFactors);
@ -410,20 +421,25 @@ class Resizer {
} }
restore() { restore() {
this.logger.log('info', 'debug', "[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio", {'lastAr': this.lastAr} ); if (!this.manualZoom) {
this.logger.log('info', 'debug', "[Resizer::restore] <rid:"+this.resizerId+"> attempting to restore aspect ratio", {'lastAr': this.lastAr} );
// this is true until we verify that css has actually been applied // this is true until we verify that css has actually been applied
if(this.lastAr.type === AspectRatioType.Initial){ if(this.lastAr.type === AspectRatioType.Initial){
this.setAr({type: AspectRatioType.Reset}); this.setAr({type: AspectRatioType.Reset});
}
else {
if (this.lastAr?.ratio === null) {
// if this is the case, we do nothing as we have the correct aspect ratio
// throw "Last ar is null!"
return;
} }
this.setAr(this.lastAr, this.lastAr) else {
if (this.lastAr?.ratio === null) {
// if this is the case, we do nothing as we have the correct aspect ratio
// throw "Last ar is null!"
return;
}
this.setAr(this.lastAr, this.lastAr)
}
} else {
this.applyScaling({xFactor: this.zoom.scale, yFactor: this.zoom.scaleY});
} }
} }
reset(){ reset(){
@ -443,16 +459,20 @@ class Resizer {
} }
} }
setZoom(zoomLevel, no_announce?) { setZoom(zoomLevel: number, axis?: 'x' | 'y', no_announce?) {
this.zoom.setZoom(zoomLevel, no_announce); this.manualZoom = true;
console.log('setting zoom:', zoomLevel);
this.zoom.setZoom(zoomLevel, axis, no_announce);
} }
zoomStep(step){ zoomStep(step){
this.manualZoom = true;
this.zoom.zoomStep(step); this.zoom.zoomStep(step);
} }
resetZoom(){ resetZoom(){
this.zoom.setZoom(1); this.zoom.setZoom(1);
this.manualZoom = false;
this.restore(); this.restore();
} }

View File

@ -17,8 +17,10 @@ class Zoom {
//#region misc data //#region misc data
scale: number = 1; scale: number = 1;
scaleY: number = 1;
logScale: number = 0; logScale: number = 0;
scaleStep: number = 0.1; logScaleY: number = 0;
scaleStep: number = 0.1;
minScale: number = -1; // 50% (log2(0.5) = -1) minScale: number = -1; // 50% (log2(0.5) = -1)
maxScale: number = 3; // 800% (log2(8) = 3) maxScale: number = 3; // 800% (log2(8) = 3)
//#endregion //#endregion
@ -34,6 +36,11 @@ class Zoom {
this.logScale = 0; this.logScale = 0;
} }
/**
* Increases zoom by a given amount. Does not allow per-axis zoom.
* Will set zoom level to x axis (+ given amount) if x and y zooms differ.
* @param amount
*/
zoomStep(amount){ zoomStep(amount){
this.logScale += amount; this.logScale += amount;
@ -43,18 +50,16 @@ class Zoom {
if (this.logScale >= this.maxScale) { if (this.logScale >= this.maxScale) {
this.logScale = this.maxScale; this.logScale = this.maxScale;
} }
this.logScaleY = this.logScale;
this.scale = Math.pow(2, this.logScale); this.scale = Math.pow(2, this.logScale);
this.logger.log('info', 'debug', "[Zoom::zoomStep] changing zoom by", amount, ". New zoom level:", this.scale); this.logger.log('info', 'debug', "[Zoom::zoomStep] changing zoom by", amount, ". New zoom level:", this.scale);
this.processZoom();
this.conf.resizer.toFixedAr();
this.conf.restoreAr();
this.conf.announceZoom(this.scale);
} }
setZoom(scale: number, no_announce?){ setZoom(scale: number, axis?: 'x' |'y', no_announce?){
this.logger.log('info', 'debug', "[Zoom::setZoom] Setting zoom to", scale, "!"); this.logger.log('info', 'debug', "[Zoom::setZoom] Setting zoom to", scale, "!");
// NOTE: SCALE IS NOT LOGARITHMIC // NOTE: SCALE IS NOT LOGARITHMIC
@ -64,12 +69,27 @@ class Zoom {
scale = this.maxScale; scale = this.maxScale;
} }
this.scale = scale; switch (axis) {
case 'x':
this.scale = scale;
break;
case 'y':
this.scaleY = scale;
break;
default:
this.scale = scale;
this.scaleY = scale;
}
this.processZoom();
}
processZoom() {
// this.conf.resizer.toFixedAr();
this.conf.restoreAr(); this.conf.restoreAr();
if (!no_announce) { this.conf.announceZoom(this.scale);
this.conf.announceZoom(this.scale);
}
} }
applyZoom(stretchFactors){ applyZoom(stretchFactors){