Skip to content

Commit 5774032

Browse files
committed
Merge branch 'master' into gh-pages
2 parents 8ba8772 + c153dd6 commit 5774032

37 files changed

+1987
-924
lines changed

.github/ISSUE_TEMPLATE/issue.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ body:
5353
id: os
5454
attributes:
5555
label: Operating System
56+
description: Your system, such as Windows or MacOS. When using Linux, please also specify the distro and installation method.
5657
validations:
5758
required: true
5859
- type: input

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ jobs:
1212
- name: "Linux"
1313
os: linux
1414
script:
15-
- npm run build-electron
1615
- sudo apt-get install rpm
17-
- electron-builder --publish=onTagOrDraft
16+
- npm run publish-linux
1817

1918
install:
2019
- npm install

build.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ function conditionalImportPlugin(name, config) {
2424
*/
2525
setup(build) {
2626
build.onResolve({ filter: config.filter }, args => {
27-
return { path: path.join(args.resolveDir, path.dirname(args.path), config.file) };
27+
if (config.library) {
28+
return { path: path.join( import.meta.dirname, 'node_modules', path.dirname(args.path), config.file) };
29+
} else {
30+
return { path: path.join(args.resolveDir, path.dirname(args.path), config.file) };
31+
}
2832
});
2933
}
3034
};
@@ -62,7 +66,7 @@ const dev_mode = options.watch || options.serve;
6266
const minify = !dev_mode;
6367

6468
/**
65-
* @typedef {esbuild.BuildOptions} BuildOptions
69+
* @type {esbuild.BuildOptions} BuildOptions
6670
*/
6771
const config = {
6872
entryPoints: ['./js/main.js'],
@@ -88,6 +92,11 @@ const config = {
8892
filter: /native_apis/,
8993
file: isApp ? 'native_apis.ts' : 'native_apis_web.ts'
9094
}),
95+
conditionalImportPlugin(3, {
96+
filter: /vue.js/,
97+
file: dev_mode ? 'vue.js' : 'vue.min.js',
98+
library: true,
99+
}),
91100
conditionalImportPlugin(1, {
92101
filter: /desktop/,
93102
file: isApp ? 'desktop.js' : 'web.js'

content/front_page_app.png

261 KB
Loading

css/dialogs.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@
242242
position: relative;
243243
margin: 0;
244244
margin-right: auto;
245+
padding-top: 2px;
245246
}
246247
.dialog_bar.form_bar .tool > .tooltip {
247248
display: none !important;

electron/main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import url from 'url'
44
import { createRequire } from 'node:module'
55
import { fileURLToPath } from 'node:url'
66
import fs from 'node:fs'
7-
import {getColorHexRGB} from 'electron-color-picker'
87

98
const require = createRequire(import.meta.url)
109
const __dirname = path.dirname(fileURLToPath(import.meta.url))
@@ -246,7 +245,8 @@ ipcMain.on('close-detached-project', async (event, window_id, uuid) => {
246245
if (window) window.send('close-detached-project', uuid);
247246
})
248247
ipcMain.on('request-color-picker', async (event, arg) => {
249-
const color = await getColorHexRGB().catch((error) => {
248+
const ColorPicker = await import('electron-color-picker');
249+
const color = await ColorPicker.getColorHexRGB().catch((error) => {
250250
console.warn('[Error] Failed to pick color', error)
251251
return ''
252252
})

js/animations/animation.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,10 +1666,11 @@ BARS.defineActions(function() {
16661666
if (!animator[channel]?.length) continue;
16671667
if (!animator.channels[channel].transform) continue;
16681668
let first = animator[channel][0];
1669+
let expected = +(channel === "scale");
16691670
// todo: add data points
16701671
if (animator[channel].length == 1 && first.data_points.length == 1 && (response.selection != 'selected_keyframes' || first.selected)) {
16711672
let value = first.getArray();
1672-
if (!value[0] && !value[1] && !value[2]) {
1673+
if (value.allAre(v => v === expected)) {
16731674
first.remove();
16741675
continue;
16751676
}
@@ -1733,7 +1734,7 @@ BARS.defineActions(function() {
17331734
}
17341735
}
17351736
} else if (!prev && !next) {
1736-
if (d_kf.allAre(val => !val)) {
1737+
if (d_kf.allAre(val => val === expected)) {
17371738
remove = true;
17381739
} else {
17391740
kf.time = 0;

js/animations/animation_mode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export const Animator = {
148148
let bone_stack = [];
149149
let iterate = g => {
150150
bone_stack.push(g);
151-
if (g.parent instanceof OutlinerElement && g.parent.constructor.animator) iterate(g.parent);
151+
if (g.parent instanceof OutlinerNode && g.parent.constructor.animator) iterate(g.parent);
152152
}
153153
iterate(target)
154154

js/copy_paste.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,12 @@ export const Clipbench = {
362362
let elements = [];
363363
let new_elements_by_old_id = {};
364364
for (let save of Clipbench.elements) {
365-
if (!OutlinerElement.isTypePermitted(save.type)) return;
366-
let copy = OutlinerElement.fromSave(save).addTo(target).markAsSelected();
365+
if (!OutlinerElement.isTypePermitted(save.type)) continue;
366+
let copy = new OutlinerElement.types[save.type](save);
367+
let target_parent = (target instanceof OutlinerNode && target.children) ? target : target.parent;
368+
if (!canAddOutlinerNodesTo([copy], target_parent)) continue;
369+
copy.init();
370+
copy.addTo(target).markAsSelected();
367371
copy.createUniqueName();
368372
Property.resetUniqueValues(copy.constructor, copy);
369373
if (typeof save.isOpen == 'boolean') copy.isOpen = save.isOpen;

js/desktop.js

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { electron, app, fs, PathModule, currentwindow, shell, ipcRenderer, process, nativeImage } from './native_apis';
1+
import { electron, app, fs, PathModule, currentwindow, shell, ipcRenderer, process, nativeImage, SystemInfo } from './native_apis';
22

33
export const recent_projects = (function() {
44
let array = [];
@@ -304,24 +304,84 @@ currentwindow.on('enter-full-screen', e => updateWindowState(e, 'screen'));
304304
currentwindow.on('leave-full-screen', e => updateWindowState(e, 'screen'));
305305
currentwindow.on('ready-to-show', e => updateWindowState(e, 'load'));
306306

307+
const ImageEditorPresets = {
308+
aseprite: {
309+
name: 'Aseprite',
310+
paths: {
311+
win32: 'C:\\Program Files\\Aseprite\\Aseprite.exe',
312+
darwin: '/Applications/Aseprite.app',
313+
linux: '/usr/share/applications//aseprite.desktop',
314+
}
315+
},
316+
pixieditor: {
317+
name: 'PixiEditor',
318+
paths: {
319+
win32: 'C:\\Program Files\\PixiEditor\\PixiEditor.exe',
320+
darwin: '/Applications/PixiEditor.app',
321+
linux: '/usr/share/applications//pixieditor.desktop',
322+
}
323+
},
324+
ps: {
325+
name: 'Photoshop',
326+
paths: {
327+
win32: 'C:\\Program Files\\Adobe\\Adobe Photoshop 2026\\Photoshop.exe',
328+
darwin: '/Applications/Adobe Photoshop 2026/Adobe Photoshop 2026.app',
329+
linux: '/usr/share/applications//photoshop.desktop'
330+
}
331+
},
332+
gimp: {
333+
name: 'GIMP',
334+
paths: {
335+
win32: 'C:\\Program Files\\GIMP 3\\bin\\gimp-3.exe',
336+
darwin: '/Applications/Gimp-3.app',
337+
linux: '/usr/share/applications//gimp.desktop',
338+
}
339+
},
340+
pdn: {
341+
name: 'Paint.NET',
342+
paths: {
343+
win32: 'C:\\Program Files\\paint.net\\PaintDotNet.exe'
344+
}
345+
},
346+
affinity: {
347+
name: 'Affinity',
348+
paths: {
349+
win32: () => PathModule.join(SystemInfo.appdata_directory, '..\\Local\\Microsoft\\WindowsApps\\Affinity.exe'),
350+
darwin: '/Applications/Affinity.app'
351+
}
352+
}
353+
};
354+
307355
//Image Editor
356+
export function isImageEditorValid(path) {
357+
if (!path) return false;
358+
try {
359+
fs.accessSync(path);
360+
return true;
361+
} catch (err) {
362+
return false;
363+
}
364+
}
308365
export function changeImageEditor(texture, not_found) {
309366
let app_file_extension = {
310367
'win32': ['exe'],
311368
'linux': [],
312369
'darwin': ['app'],
313370
};
371+
let options = {};
372+
for (let key in ImageEditorPresets) {
373+
let entry = ImageEditorPresets[key];
374+
if (!entry.paths[SystemInfo.platform]) continue;
375+
options[key] = entry.name;
376+
}
377+
options.other = 'message.image_editor.file';
378+
314379
new Dialog({
315380
title: tl('message.image_editor.title'),
316381
id: 'image_editor',
317382
form: {
318383
not_found_text: {type: 'info', text: 'message.image_editor.not_found', condition: not_found == true},
319-
editor: {type: 'select', full_width: true, options: {
320-
ps: Blockbench.platform == 'win32' ? 'Photoshop' : undefined,
321-
gimp: 'GIMP',
322-
pdn: Blockbench.platform == 'win32' ? 'Paint.NET' : undefined,
323-
other: 'message.image_editor.file'
324-
}},
384+
editor: {type: 'select', full_width: true, options},
325385
file: {
326386
label: 'message.image_editor.file',
327387
type: 'file',
@@ -337,27 +397,14 @@ export function changeImageEditor(texture, not_found) {
337397
let path;
338398
if (id == 'other') {
339399
path = result.file;
340-
341-
} else if (Blockbench.platform == 'darwin') {
342-
switch (id) {
343-
case 'ps': path = '/Applications/Adobe Photoshop 2024/Adobe Photoshop 2024.app'; break;
344-
case 'gimp':path = '/Applications/Gimp-2.10.app'; break;
345-
}
346-
} else if (Blockbench.platform == 'linux') {
347-
switch (id) {
348-
case 'ps': path = '/usr/share/applications//photoshop.desktop'; break;
349-
case 'gimp':path = '/usr/share/applications//gimp.desktop'; break;
350-
}
351400
} else {
352-
switch (id) {
353-
case 'ps': path = 'C:\\Program Files\\Adobe\\Adobe Photoshop 2024\\Photoshop.exe'; break;
354-
case 'gimp':path = 'C:\\Program Files\\GIMP 2\\bin\\gimp-2.10.exe'; break;
355-
case 'pdn': path = 'C:\\Program Files\\paint.net\\PaintDotNet.exe'; break;
356-
}
401+
path = ImageEditorPresets[result.editor].paths[SystemInfo.platform];
402+
if (typeof path == 'function') path = path();
357403
}
358-
if (path && fs.existsSync(path)) {
404+
if (isImageEditorValid(path)) {
359405
settings.image_editor.value = path
360406
ipcRenderer.send('edit-launch-setting', {key: 'image_editor', value: path});
407+
Settings.save();
361408
if (texture) {
362409
texture.openEditor()
363410
}

0 commit comments

Comments
 (0)