mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-23 16:25:22 +03:00
Added Windows and Mac icons files
Build native Mac and Windows apps. Shamelessly stolen from iNAV, thanks! NW.js requires us to disable pointer events on the inline images, otherwise the drag/drop events are generated for the images rather than for the html elements representing OSD items.
This commit is contained in:
parent
09bca92e9d
commit
805ec6063a
8 changed files with 4583 additions and 2 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -3,4 +3,8 @@ nbproject/
|
|||
.idea
|
||||
.project
|
||||
.settings/
|
||||
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
cache/
|
||||
apps/
|
||||
dist/
|
||||
|
|
18
README.md
18
README.md
|
@ -42,6 +42,24 @@ Please note - the application will automatically update itself when new versions
|
|||
|
||||
You can find the Betaflight Configurator icon in your application tab "Apps"
|
||||
|
||||
## Native app build via NW.js
|
||||
|
||||
Linux build is disabled currently because of unmet dependecies with some distros, it can be enabled in the `gulpfile.js`.
|
||||
|
||||
### Development
|
||||
|
||||
1. Install node.js
|
||||
2. Change to project folder and run `npm install`
|
||||
3. Run `npm start`
|
||||
|
||||
### App build and release
|
||||
|
||||
The tasks are defined in `gulpfile.js` and can be run either via `gulp task-name` (if the command is in PATH or via `../node_modules/gulp/bin/gulp.js task-name':
|
||||
|
||||
* **dist** copies all the JS and CSS files in the `./dist` folder
|
||||
* **apps** builds the apps in the `./apps` folder
|
||||
* **release** zips up the apps into individual archives in the `./apps` folder. Running this task on macOS or Linux requires Wine, since it's needed to set the icon for the Windows app.
|
||||
|
||||
## Notes
|
||||
|
||||
### WebGL
|
||||
|
|
242
gulpfile.js
Normal file
242
gulpfile.js
Normal file
|
@ -0,0 +1,242 @@
|
|||
'use strict';
|
||||
|
||||
var child_process = require('child_process');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var archiver = require('archiver');
|
||||
var del = require('del');
|
||||
var NwBuilder = require('nw-builder');
|
||||
|
||||
var gulp = require('gulp');
|
||||
var concat = require('gulp-concat');
|
||||
var runSequence = require('run-sequence');
|
||||
|
||||
var distDir = './dist/';
|
||||
var appsDir = './apps/';
|
||||
|
||||
function get_task_name(key) {
|
||||
return 'build-' + key.replace(/([A-Z])/g, function ($1) { return "-" + $1.toLowerCase(); });
|
||||
}
|
||||
|
||||
gulp.task('clean', function () { return del(['./dist/**'], { force: true }); });
|
||||
|
||||
// Real work for dist task. Done in another task to call it via
|
||||
// run-sequence.
|
||||
gulp.task('dist-build', [], function () {
|
||||
var distSources = [
|
||||
// CSS files
|
||||
'./main.css',
|
||||
'./tabs/power.css',
|
||||
'./tabs/firmware_flasher.css',
|
||||
'./tabs/onboard_logging.css',
|
||||
'./tabs/receiver.css',
|
||||
'./tabs/cli.css',
|
||||
'./tabs/servos.css',
|
||||
'./tabs/adjustments.css',
|
||||
'./tabs/configuration.css',
|
||||
'./tabs/auxiliary.css',
|
||||
'./tabs/pid_tuning.css',
|
||||
'./tabs/transponder.css',
|
||||
'./tabs/gps.css',
|
||||
'./tabs/led_strip.css',
|
||||
'./tabs/sensors.css',
|
||||
'./tabs/osd.css',
|
||||
'./tabs/motors.css',
|
||||
'./tabs/receiver_msp.css',
|
||||
'./tabs/logging.css',
|
||||
'./tabs/landing.css',
|
||||
'./tabs/setup_osd.css',
|
||||
'./tabs/help.css',
|
||||
'./tabs/failsafe.css',
|
||||
'./tabs/ports.css',
|
||||
'./tabs/setup.css',
|
||||
'./css/opensans_webfontkit/fonts.css',
|
||||
'./css/dropdown-lists/css/style_lists.css',
|
||||
'./css/font-awesome/css/font-awesome.min.css',
|
||||
'./js/libraries/flightindicators.css',
|
||||
'./js/libraries/jbox/jBox.css',
|
||||
'./js/libraries/jbox/themes/NoticeBorder.css',
|
||||
'./js/libraries/jbox/themes/ModalBorder.css',
|
||||
'./js/libraries/jbox/themes/TooltipDark.css',
|
||||
'./js/libraries/jbox/themes/TooltipBorder.css',
|
||||
'./js/libraries/jquery.nouislider.pips.min.css',
|
||||
'./js/libraries/switchery/switchery.css',
|
||||
'./js/libraries/jquery.nouislider.min.css',
|
||||
'./node_modules/jquery-ui-npm/jquery-ui.min.css',
|
||||
'./node_modules/jquery-ui-npm/jquery-ui.theme.min.css',
|
||||
'./node_modules/jquery-ui-npm/jquery-ui.structure.min.css',
|
||||
|
||||
// JavaScript
|
||||
'./js/libraries/q.js',
|
||||
'./js/libraries/jquery-2.1.4.min.js',
|
||||
'./js/libraries/jquery-ui-1.11.4.min.js',
|
||||
'./js/libraries/d3.min.js',
|
||||
'./js/libraries/jquery.nouislider.all.min.js',
|
||||
'./js/libraries/three/three.min.js',
|
||||
'./js/libraries/three/Projector.js',
|
||||
'./js/libraries/three/CanvasRenderer.js',
|
||||
'./js/libraries/jquery.flightindicators.js',
|
||||
'./js/libraries/semver.js',
|
||||
'./js/libraries/jbox/jBox.min.js',
|
||||
'./js/libraries/switchery/switchery.js',
|
||||
'./js/libraries/bluebird.min.js',
|
||||
'./js/libraries/jquery.ba-throttle-debounce.min.js',
|
||||
'./js/libraries/inflection.min.js',
|
||||
'./js/injected_methods.js',
|
||||
'./js/data_storage.js',
|
||||
'./js/workers/hex_parser.js',
|
||||
'./js/fc.js',
|
||||
'./js/port_handler.js',
|
||||
'./js/port_usage.js',
|
||||
'./js/serial.js',
|
||||
'./js/gui.js',
|
||||
'./js/huffman.js',
|
||||
'./js/default_huffman_tree.js',
|
||||
'./js/model.js',
|
||||
'./js/serial_backend.js',
|
||||
'./js/msp/MSPCodes.js',
|
||||
'./js/msp.js',
|
||||
'./js/msp/MSPHelper.js',
|
||||
'./js/backup_restore.js',
|
||||
'./js/peripherals.js',
|
||||
'./js/protocols/stm32.js',
|
||||
'./js/protocols/stm32usbdfu.js',
|
||||
'./js/localization.js',
|
||||
'./js/boards.js',
|
||||
'./js/RateCurve.js',
|
||||
'./js/Features.js',
|
||||
'./js/Beepers.js',
|
||||
'./tabs/adjustments.js',
|
||||
'./tabs/auxiliary.js',
|
||||
'./tabs/cli.js',
|
||||
'./tabs/configuration.js',
|
||||
'./tabs/failsafe.js',
|
||||
'./tabs/firmware_flasher.js',
|
||||
'./tabs/gps.js',
|
||||
'./tabs/help.js',
|
||||
'./tabs/landing.js',
|
||||
'./tabs/led_strip.js',
|
||||
'./tabs/logging.js',
|
||||
'./tabs/map.js',
|
||||
'./tabs/motors.js',
|
||||
'./tabs/onboard_logging.js',
|
||||
'./tabs/osd.js',
|
||||
'./tabs/pid_tuning.js',
|
||||
'./tabs/ports.js',
|
||||
'./tabs/power.js',
|
||||
'./tabs/receiver.js',
|
||||
'./tabs/receiver_msp.js',
|
||||
'./tabs/sensors.js',
|
||||
'./tabs/servos.js',
|
||||
'./tabs/setup.js',
|
||||
'./tabs/setup_osd.js',
|
||||
'./tabs/transponder.js',
|
||||
'./main.js',
|
||||
|
||||
// everything else
|
||||
'./package.json', // For NW.js
|
||||
'./manifest.json', // For Chrome app
|
||||
'./eventPage.js',
|
||||
'./*.html',
|
||||
'./tabs/*.html',
|
||||
'./images/**/*',
|
||||
'./_locales/**/*',
|
||||
'./css/font-awesome/fonts/*',
|
||||
'./css/opensans_webfontkit/*.{eot,svg,ttf,woff,woff2}',
|
||||
'./resources/*.json',
|
||||
'./resources/models/*',
|
||||
'./resources/osd/*.mcm',
|
||||
'./resources/motor_order/*.svg',
|
||||
];
|
||||
return gulp.src(distSources, { base: '.' })
|
||||
.pipe(gulp.dest(distDir));
|
||||
});
|
||||
|
||||
gulp.task('dist', function () {
|
||||
return runSequence('clean', 'dist-build');
|
||||
});
|
||||
|
||||
// Create app directories in ./apps
|
||||
gulp.task('apps', ['dist'], function (done) {
|
||||
var builder = new NwBuilder({
|
||||
files: './dist/**/*',
|
||||
buildDir: appsDir,
|
||||
platforms: ['osx64', 'win32'], // 'linux64' not working currently.
|
||||
flavor: 'normal',
|
||||
macIcns: './images/bf_icon.icns',
|
||||
macPlist: { 'CFBundleDisplayName': 'Betaflight Configurator'},
|
||||
winIco: './images/bf_icon.ico',
|
||||
});
|
||||
builder.on('log', console.log);
|
||||
builder.build(function (err) {
|
||||
if (err) {
|
||||
console.log("Error building NW apps:" + err);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
// Package apps as .zip files
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
function get_release_filename(platform, ext) {
|
||||
var pkg = require('./package.json');
|
||||
return 'Betaflight-Configurator_' + platform + '_' + pkg.version + '.' + ext;
|
||||
}
|
||||
|
||||
gulp.task('release-windows', function () {
|
||||
var pkg = require('./package.json');
|
||||
var src = path.join(appsDir, pkg.name, 'win32');
|
||||
var output = fs.createWriteStream(path.join(appsDir, get_release_filename('win32', 'zip')));
|
||||
var archive = archiver('zip', {
|
||||
zlib: { level: 9 }
|
||||
});
|
||||
archive.on('warning', function (err) { throw err; });
|
||||
archive.on('error', function (err) { throw err; });
|
||||
archive.pipe(output);
|
||||
archive.directory(src, 'Betaflight Configurator');
|
||||
return archive.finalize();
|
||||
});
|
||||
|
||||
gulp.task('release-linux', function () {
|
||||
var pkg = require('./package.json');
|
||||
var src = path.join(appsDir, pkg.name, 'linux64');
|
||||
var output = fs.createWriteStream(path.join(appsDir, get_release_filename('linux64', 'zip')));
|
||||
var archive = archiver('zip', {
|
||||
zlib: { level: 9 }
|
||||
});
|
||||
archive.on('warning', function (err) { throw err; });
|
||||
archive.on('error', function (err) { throw err; });
|
||||
archive.pipe(output);
|
||||
archive.directory(src, 'Betaflight Configurator');
|
||||
return archive.finalize();
|
||||
});
|
||||
|
||||
gulp.task('release-macos', function () {
|
||||
var pkg = require('./package.json');
|
||||
var src = path.join(appsDir, pkg.name, 'osx64', pkg.name + '.app');
|
||||
// Check if we want to sign the .app bundle
|
||||
if (process.env.CODESIGN_IDENTITY) {
|
||||
var sign_cmd = 'codesign --verbose --force --sign "' + process.env.CODESIGN_IDENTITY + '" ' + src;
|
||||
child_process.execSync(sign_cmd);
|
||||
}
|
||||
var output = fs.createWriteStream(path.join(appsDir, get_release_filename('macOS', 'zip')));
|
||||
var archive = archiver('zip', {
|
||||
zlib: { level: 9 }
|
||||
});
|
||||
archive.on('warning', function (err) { throw err; });
|
||||
archive.on('error', function (err) { throw err; });
|
||||
archive.pipe(output);
|
||||
console.log("Archiving MacOS app at " + src);
|
||||
archive.directory(src, 'Betaflight Configurator.app');
|
||||
return archive.finalize();
|
||||
});
|
||||
|
||||
// Create distributable .zip files in ./apps
|
||||
gulp.task('release', function () {
|
||||
// TODO: Linux
|
||||
return runSequence('apps', 'release-macos', 'release-windows');
|
||||
});
|
||||
|
||||
gulp.task('default', ['apps']);
|
BIN
images/bf_icon.icns
Normal file
BIN
images/bf_icon.icns
Normal file
Binary file not shown.
BIN
images/bf_icon.ico
Normal file
BIN
images/bf_icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
4273
package-lock.json
generated
Normal file
4273
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
38
package.json
Normal file
38
package.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "betaflight-configurator",
|
||||
"description": "Betaflight Configurator",
|
||||
"version": "3.2.2",
|
||||
"main": "main.html",
|
||||
"default_locale": "en",
|
||||
"scripts": {
|
||||
"start": "node_modules/gulp/bin/gulp.js dist && node_modules/nw/bin/nw ."
|
||||
},
|
||||
"window": {
|
||||
"title": "Betaflight Configurator",
|
||||
"icon": "images/inav_icon_128.png",
|
||||
"toolbar": true,
|
||||
"width": 1280,
|
||||
"height": 800
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "github.com/betaflight/betaflight-configurator"
|
||||
},
|
||||
"author": "iNavFlight",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"archiver": "^2.0.3",
|
||||
"bluebird": "3.4.1",
|
||||
"del": "^3.0.0",
|
||||
"gulp": "~3.9.1",
|
||||
"gulp-concat": "~2.6.1",
|
||||
"inflection": "1.12.0",
|
||||
"jquery": "2.1.4",
|
||||
"jquery-ui-npm": "1.12.0",
|
||||
"nw": "^0.25.4-sdk",
|
||||
"nw-builder": "^3.4.1",
|
||||
"run-sequence": "^2.2.0",
|
||||
"temp": "^0.8.3",
|
||||
"three": "0.72.0"
|
||||
}
|
||||
}
|
|
@ -1505,6 +1505,9 @@ TABS.osd.initialize = function (callback) {
|
|||
ctx.drawImage(img, i*12, 0);
|
||||
}
|
||||
field.preview_img.src = canvas.toDataURL('image/png');
|
||||
// Required for NW.js - Otherwise the <img /> will
|
||||
// consume drag/drop events.
|
||||
field.preview_img.style.pointerEvents = 'none';
|
||||
}
|
||||
var centerishPosition = 194;
|
||||
// artificial horizon
|
||||
|
@ -1548,6 +1551,9 @@ TABS.osd.initialize = function (callback) {
|
|||
.on('drop', OSD.GUI.preview.onDrop)
|
||||
.data('field', field)
|
||||
.data('position', i);
|
||||
// Required for NW.js - Otherwise the <img /> will
|
||||
// consume drag/drop events.
|
||||
$img.find('img').css('pointer-events', 'none');
|
||||
if (field && field.positionable) {
|
||||
$img
|
||||
.addClass('field-'+field.index)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue