Fix issues with UV editor on touch devices

Fix right clicking keyframe
Fix #1093 Gizmo position not correct with rescaled elements
Fix cubes without faces causing errors
Add setting to change default Display UV value, closes #1097
right clicking UV face now selects it
This commit is contained in:
JannisX11 2021-10-15 15:14:32 +02:00
parent 4c646d4e69
commit 7b0c3d2aee
7 changed files with 40 additions and 27 deletions

View File

@ -27,9 +27,10 @@
z-index: 250;
}
#work_screen {
--toolbar-height: 30px;
display: grid;
grid-template-columns: 332px auto 314px;
grid-template-rows: 30px minmax(200px, 5000px) 26px;
grid-template-rows: var(--toolbar-height) minmax(200px, 5000px) 26px;
grid-template-areas:
"left_bar toolbar toolbar"
"left_bar center right_bar"
@ -286,7 +287,7 @@
}
#work_screen {
display: grid;
grid-template-rows: auto minmax(200px, 5000px) 26px 36px;
grid-template-rows: auto minmax(200px, 5000px) 26px 36px !important;
grid-template-areas:
"toolbar"
"center"

View File

@ -1009,7 +1009,7 @@ onVueSetup(function() {
v-on:dblclick="keyframe.callPlayhead()"
:title="tl('timeline.'+keyframe.channel)"
@mousedown="dragKeyframes(keyframe, $event)" @touchstart="dragKeyframes(keyframe, $event)"
@contextmenu.prevent="keyframe.showContextMenu($event)"
@contextmenu.prevent.stop="keyframe.showContextMenu($event)"
>
<i class="material-icons keyframe_icon_smaller" v-if="keyframe.interpolation == 'catmullrom'">lens</i>
<i :class="keyframe.data_points.length == 1 ? 'icon-keyframe' : 'icon-keyframe_discontinuous'" v-else></i>

View File

@ -276,10 +276,11 @@ const Settings = {
new Setting('image_editor', {category: 'paint', value: false, type: 'click', condition: isApp, icon: 'fas.fa-pen-square', click: function() {changeImageEditor(null, true) }});
//Defaults
new Setting('autouv', {category: 'defaults', value: true});
new Setting('create_rename', {category: 'defaults', value: false});
new Setting('default_path', {category: 'defaults', value: false, type: 'click', condition: isApp, icon: 'burst_mode', click: function() { openDefaultTexturePath() }});
new Setting('animation_snap',{category: 'defaults', value: 24, type: 'number'});
new Setting('autouv', {category: 'defaults', value: true});
new Setting('create_rename', {category: 'defaults', value: false});
new Setting('show_only_selected_uv', {category: 'defaults', value: false});
new Setting('default_path', {category: 'defaults', value: false, type: 'click', condition: isApp, icon: 'burst_mode', click: function() { openDefaultTexturePath() }});
new Setting('animation_snap', {category: 'defaults', value: 24, type: 'number'});
//Dialogs
new Setting('dialog_larger_cubes', {category: 'dialogs', value: true, name: tl('message.model_clipping.title'), description: tl('settings.dialog.desc', [tl('message.model_clipping.title')])});

View File

@ -23,7 +23,7 @@ class ModelProject {
this.format = options.format instanceof ModelFormat ? options.format : Formats.free;
this.mode = 'edit';
this.view_mode = 'textured';
this.display_uv = 'selected_elements';
this.display_uv = settings.show_only_selected_uv.value ? 'selected_faces' :'selected_elements';
this.previews = {};
this.EditSession = null;

View File

@ -466,9 +466,9 @@ class Cube extends OutlinerElement {
this.from[1] + this.size(1)/2,
this.from[2] + this.size(2)/2
)
pos.x -= this.origin[0]
pos.y -= this.origin[1]
pos.z -= this.origin[2]
pos.x = (pos.x - this.origin[0]) * m.scale.x;
pos.y = (pos.y - this.origin[1]) * m.scale.y;
pos.z = (pos.z - this.origin[2]) * m.scale.z;
if (m) {
var r = m.getWorldQuaternion(Reusable.quat1)
@ -916,6 +916,7 @@ new NodePreviewController(Cube, {
if (materials.allEqual(materials[0])) materials = materials[0];
mesh.material = materials
}
if (!mesh.material) mesh.material = Canvas.transparentMaterial;
},
updateUV(cube, animation = true) {
if (Project.view_mode !== 'textured') return;

View File

@ -513,7 +513,7 @@ const UVEditor = {
slider.node.style.setProperty('display', BARS.condition(slider.condition)?'block':'none');
slider.update();
}
var face = Cube.selected[0].faces[this.selected_faces[0]]
var face = Cube.selected[0] && this.selected_faces[0] && Cube.selected[0].faces[this.selected_faces[0]]
if (face) {
BarItems.uv_rotation.set((face && face.rotation)||0);
BarItems.cullface.set(face.cullface||'off')
@ -1904,7 +1904,7 @@ Interface.definePanels(function() {
},
contextMenu(event) {
setActivePanel('uv');
if (!UVEditor.getReferenceFace()) return;
if (!UVEditor.getReferenceFace() && !Project.box_uv) return;
UVEditor.menu.open(event);
},
selectFace(key, event, keep_selection, support_dragging) {
@ -1961,11 +1961,13 @@ Interface.definePanels(function() {
},
drag({event, onDrag, onEnd, onAbort, snap}) {
if (event.which == 2 || event.which == 3) return;
convertTouchEvent(event);
let scope = this;
let pos = [0, 0];
let last_pos = [0, 0];
function drag(e1) {
convertTouchEvent(e1);
if (snap == undefined) {
let snap = UVEditor.grid / canvasGridSize(e1.shiftKey || Pressing.overrides.shift, e1.ctrlOrCmd || Pressing.overrides.ctrl);
@ -2129,6 +2131,7 @@ Interface.definePanels(function() {
rotateFace(face_key, event) {
if (event.which == 2 || event.which == 3) return;
event.stopPropagation();
convertTouchEvent(event);
let scope = this;
let elements = this.mappable_elements;
Undo.initEdit({elements, uv_only: true})
@ -2169,6 +2172,7 @@ Interface.definePanels(function() {
let straight_angle;
let snap = elements[0] instanceof Cube ? 90 : 1;
function drag(e1) {
convertTouchEvent(e1);
angle = Math.atan2(
(e1.clientY - center_on_screen[1]),
@ -2436,6 +2440,8 @@ Interface.definePanels(function() {
:title="face_names[key]"
:class="{selected: selected_faces.includes(key), unselected: display_uv === 'all_elements' && !mappable_elements.includes(element)}"
@mousedown.prevent="dragFace(key, $event)"
@touchstart.prevent="dragFace(key, $event)"
@contextmenu="selectFace(key, $event, true, false)"
:style="{
left: toPixels(Math.min(face.uv[0], face.uv[2]), -1),
top: toPixels(Math.min(face.uv[1], face.uv[3]), -1),
@ -2445,21 +2451,21 @@ Interface.definePanels(function() {
>
<template v-if="selected_faces.includes(key) && !(display_uv === 'all_elements' && !mappable_elements.includes(element))">
{{ face_names[key] || '' }}
<div class="uv_resize_side horizontal" @mousedown="resizeFace(key, $event, 0, -1)" style="width: var(--width)"></div>
<div class="uv_resize_side horizontal" @mousedown="resizeFace(key, $event, 0, 1)" style="top: var(--height); width: var(--width)"></div>
<div class="uv_resize_side vertical" @mousedown="resizeFace(key, $event, -1, 0)" style="height: var(--height)"></div>
<div class="uv_resize_side vertical" @mousedown="resizeFace(key, $event, 1, 0)" style="left: var(--width); height: var(--height)"></div>
<div class="uv_resize_corner uv_c_nw" :class="{main_corner: !face.rotation}" @mousedown="resizeFace(key, $event, -1, -1)" style="left: 0; top: 0">
<div class="uv_rotate_field" v-if="!face.rotation" @mousedown.stop="rotateFace(key, $event)"></div>
<div class="uv_resize_side horizontal" @mousedown="resizeFace(key, $event, 0, -1)" @touchstart.prevent="resizeFace(key, $event, 0, -1)" style="width: var(--width)"></div>
<div class="uv_resize_side horizontal" @mousedown="resizeFace(key, $event, 0, 1)" @touchstart.prevent="resizeFace(key, $event, 0, 1)" style="top: var(--height); width: var(--width)"></div>
<div class="uv_resize_side vertical" @mousedown="resizeFace(key, $event, -1, 0)" @touchstart.prevent="resizeFace(key, $event, -1, 0)" style="height: var(--height)"></div>
<div class="uv_resize_side vertical" @mousedown="resizeFace(key, $event, 1, 0)" @touchstart.prevent="resizeFace(key, $event, 1, 0)" style="left: var(--width); height: var(--height)"></div>
<div class="uv_resize_corner uv_c_nw" :class="{main_corner: !face.rotation}" @mousedown="resizeFace(key, $event, -1, -1)" @touchstart.prevent="resizeFace(key, $event, -1, -1)" style="left: 0; top: 0">
<div class="uv_rotate_field" v-if="!face.rotation" @mousedown.stop="rotateFace(key, $event)" @touchstart.prevent.stop="rotateFace(key, $event)"></div>
</div>
<div class="uv_resize_corner uv_c_ne" :class="{main_corner: face.rotation == 270}" @mousedown="resizeFace(key, $event, 1, -1)" style="left: var(--width); top: 0">
<div class="uv_rotate_field" v-if="face.rotation == 270" @mousedown.stop="rotateFace(key, $event)"></div>
<div class="uv_resize_corner uv_c_ne" :class="{main_corner: face.rotation == 270}" @mousedown="resizeFace(key, $event, 1, -1)" @touchstart.prevent="resizeFace(key, $event, 1, -1)" style="left: var(--width); top: 0">
<div class="uv_rotate_field" v-if="face.rotation == 270" @mousedown.stop="rotateFace(key, $event)" @touchstart.prevent.stop="rotateFace(key, $event)"></div>
</div>
<div class="uv_resize_corner uv_c_sw" :class="{main_corner: face.rotation == 90}" @mousedown="resizeFace(key, $event, -1, 1)" style="left: 0; top: var(--height)">
<div class="uv_rotate_field" v-if="face.rotation == 90" @mousedown.stop="rotateFace(key, $event)"></div>
<div class="uv_resize_corner uv_c_sw" :class="{main_corner: face.rotation == 90}" @mousedown="resizeFace(key, $event, -1, 1)" @touchstart.prevent="resizeFace(key, $event, -1, 1)" style="left: 0; top: var(--height)">
<div class="uv_rotate_field" v-if="face.rotation == 90" @mousedown.stop="rotateFace(key, $event)" @touchstart.prevent.stop="rotateFace(key, $event)"></div>
</div>
<div class="uv_resize_corner uv_c_se" :class="{main_corner: face.rotation == 180}" @mousedown="resizeFace(key, $event, 1, 1)" style="left: var(--width); top: var(--height)">
<div class="uv_rotate_field" v-if="face.rotation == 180" @mousedown.stop="rotateFace(key, $event)"></div>
<div class="uv_resize_corner uv_c_se" :class="{main_corner: face.rotation == 180}" @mousedown="resizeFace(key, $event, 1, 1)" @touchstart.prevent="resizeFace(key, $event, 1, 1)" style="left: var(--width); top: var(--height)">
<div class="uv_rotate_field" v-if="face.rotation == 180" @mousedown.stop="rotateFace(key, $event)" @touchstart.prevent.stop="rotateFace(key, $event)"></div>
</div>
</template>
</div>
@ -2468,6 +2474,7 @@ Interface.definePanels(function() {
<div v-else-if="element.type == 'cube'" class="cube_box_uv"
:key="element.uuid"
@mousedown.prevent="dragFace(null, $event)"
@touchstart.prevent="dragFace(null, $event)"
@click.prevent="selectCube(element, $event)"
:class="{unselected: display_uv === 'all_elements' && !mappable_elements.includes(element)}"
:style="{left: toPixels(element.uv_offset[0]), top: toPixels(element.uv_offset[1])}"
@ -2484,6 +2491,7 @@ Interface.definePanels(function() {
v-if="face.vertices.length > 2 && (display_uv !== 'selected_faces' || selected_faces.includes(key)) && face.getTexture() == texture"
:class="{selected: selected_faces.includes(key)}"
@mousedown.prevent="dragFace(key, $event)"
@touchstart.prevent="dragFace(key, $event)"
:style="{
left: toPixels(getMeshFaceCorner(face, 0), -1),
top: toPixels(getMeshFaceCorner(face, 1), -1),
@ -2497,10 +2505,10 @@ Interface.definePanels(function() {
<template v-if="selected_faces.includes(key)">
<div class="uv_mesh_vertex" v-for="(key, index) in face.vertices"
:class="{main_corner: index == 0, selected: selected_vertices[element.uuid] && selected_vertices[element.uuid].includes(key)}"
@mousedown.prevent.stop="dragVertices(element, key, $event)"
@mousedown.prevent.stop="dragVertices(element, key, $event)" @touchstart.prevent.stop="dragVertices(element, key, $event)"
:style="{left: toPixels( face.uv[key][0] - getMeshFaceCorner(face, 0) ), top: toPixels( face.uv[key][1] - getMeshFaceCorner(face, 1) )}"
>
<div class="uv_rotate_field" @mousedown.stop="rotateFace(key, $event)" v-if="index == 0"></div>
<div class="uv_rotate_field" @mousedown.stop="rotateFace(key, $event)" @touchstart.prevent.stop="rotateFace(key, $event)" v-if="index == 0"></div>
</div>
</template>
</div>

View File

@ -644,6 +644,8 @@
"settings.autouv.desc": "Enable Auto UV by default",
"settings.create_rename": "Rename New Cube",
"settings.create_rename.desc": "Focus name field when creating new element or group",
"settings.show_only_selected_uv": "Show Only Selected UV",
"settings.show_only_selected_uv.desc": "Only display the selected UV faces in the UV editor by default",
"settings.animation_snap": "Animation Snap",
"settings.animation_snap.desc": "Default snap interval for keyframes in the animation timeline in steps per second. This can also be changed per animation. The default value is 24.",