1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-23 16:25:22 +03:00

Add support for OSD type variants

This commit is contained in:
Miguel Angel Mulero Martinez 2021-04-06 09:21:53 +02:00
parent 9ece824971
commit e6c2e67c5b
3 changed files with 182 additions and 10 deletions

View file

@ -4636,6 +4636,14 @@
"osdDescElementAltitude": { "osdDescElementAltitude": {
"message": "Current altitude (flashes when above alarm threshold)" "message": "Current altitude (flashes when above alarm threshold)"
}, },
"osdTextElementAltitudeVariant1Decimal": {
"message": "With 1 decimal",
"description": "One of the variants of the altitude element of the OSD"
},
"osdTextElementAltitudeVariantNoDecimal": {
"message": "Without decimals",
"description": "One of the variants of the altitude element of the OSD"
},
"osdTextElementOnTime": { "osdTextElementOnTime": {
"message": "On time", "message": "On time",
"description": "One of the elements of the OSD" "description": "One of the elements of the OSD"
@ -4685,6 +4693,22 @@
"osdDescElementGPSLat": { "osdDescElementGPSLat": {
"message": "GPS latitude coordinate" "message": "GPS latitude coordinate"
}, },
"osdTextElementGPSVariant7Decimals": {
"message": "With 7 decimals",
"description": "One of the variants for the GPS element of the OSD"
},
"osdTextElementGPSVariant4Decimals": {
"message": "With 4 decimals",
"description": "One of the variants for the GPS element of the OSD"
},
"osdTextElementGPSVariantDegMinSec": {
"message": "Using degrees, minutes and seconds",
"description": "One of the variants for the GPS element of the OSD"
},
"osdTextElementGPSVariantOpenLocation": {
"message": "Using Open Location Code",
"description": "One of the variants for the GPS element of the OSD"
},
"osdTextElementDebug": { "osdTextElementDebug": {
"message": "Debug", "message": "Debug",
"description": "One of the elements of the OSD" "description": "One of the elements of the OSD"
@ -4762,6 +4786,22 @@
"osdDescElementMainBattUsage": { "osdDescElementMainBattUsage": {
"message": "Graphical representation of battery capacity usage" "message": "Graphical representation of battery capacity usage"
}, },
"osdTextElementMainBattUsageVariantGraphrRemain": {
"message": "Graphical remaining",
"description": "One of the variants for the Main Battery Usage element of the OSD"
},
"osdTextElementMainBattUsageVariantGraphUsage": {
"message": "Graphical used",
"description": "One of the variants for the Main Battery Usage element of the OSD"
},
"osdTextElementMainBattUsageVariantValueRemain": {
"message": "Percentage remaining",
"description": "One of the variants for the Main Battery Usage element of the OSD"
},
"osdTextElementMainBattUsageVariantValueUsage": {
"message": "Percentage used",
"description": "One of the variants for the Main Battery Usage element of the OSD"
},
"osdTextElementArmedTime": { "osdTextElementArmedTime": {
"message": "Timer: armed time", "message": "Timer: armed time",
"description": "One of the elements of the OSD" "description": "One of the elements of the OSD"

View file

@ -449,6 +449,10 @@ button {
border-radius: 3px; border-radius: 3px;
} }
.tab-osd select.osd-variant {
max-width: 100%;
}
.tab-osd .preview { .tab-osd .preview {
width: 360px; width: 360px;
float: left; float: left;

View file

@ -296,6 +296,73 @@ OSD.initData = function() {
}; };
OSD.initData(); OSD.initData();
OSD.getVariantForPreview = function(osdData, elementName) {
return osdData.displayItems.find(element => element.name === elementName).variant;
};
OSD.generateAltitudePreview = function(osdData) {
const unit = FONT.symbol(osdData.unit_mode === 0 ? SYM.FEET : SYM.METRE);
const variantSelected = OSD.getVariantForPreview(osdData, 'ALTITUDE');
return `${FONT.symbol(SYM.ALTITUDE)}399${variantSelected === 0? '.7' : ''}${unit}`;
};
OSD.generateBatteryUsagePreview = function(osdData) {
const variantSelected = OSD.getVariantForPreview(osdData, 'MAIN_BATT_USAGE');
let value;
switch (variantSelected) {
case 0:
value = FONT.symbol(SYM.PB_START) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL)
+ FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL)
+ FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_END) + FONT.symbol(SYM.PB_EMPTY)
+ FONT.symbol(SYM.PB_CLOSE);
break;
case 1:
value = FONT.symbol(SYM.PB_START) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL)
+ FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_END) + FONT.symbol(SYM.PB_EMPTY)
+ FONT.symbol(SYM.PB_EMPTY) + FONT.symbol(SYM.PB_EMPTY) + FONT.symbol(SYM.PB_EMPTY) + FONT.symbol(SYM.PB_EMPTY)
+ FONT.symbol(SYM.PB_CLOSE);
break;
case 2:
value = `${FONT.symbol(SYM.MAH)}67%`;
break;
case 3:
value = `${FONT.symbol(SYM.MAH)}33%`;
break;
}
return value;
};
OSD.generateGpsLatLongPreview = function(osdData, elementName) {
const variantSelected = OSD.getVariantForPreview(osdData, elementName);
let value;
switch (variantSelected) {
case 0:
value = elementName === 'GPS_LON' ? `${FONT.symbol(SYM.GPS_LON)}-000.0000000` : `${FONT.symbol(SYM.GPS_LAT)}-00.0000000 `;
break;
case 1:
value = elementName === 'GPS_LON' ? `${FONT.symbol(SYM.GPS_LON)}-000.0000` : `${FONT.symbol(SYM.GPS_LAT)}-00.0000 `;
break;
case 2:
const degreesSymbol = FONT.symbol(SYM.STICK_OVERLAY_SPRITE_HIGH);
value = elementName === 'GPS_LON' ? `${FONT.symbol(SYM.GPS_LON)}00${degreesSymbol}000'00.0"N` : `${FONT.symbol(SYM.GPS_LAT)}00${degreesSymbol}00'00.0"E `;
break;
case 3:
value = `${FONT.symbol(SYM.GPS_SAT_L)}${FONT.symbol(SYM.GPS_SAT_R)}000000AA+BBB`;
break;
}
return value;
};
OSD.generateTimerPreview = function(osdData, timerIndex) { OSD.generateTimerPreview = function(osdData, timerIndex) {
let preview = ''; let preview = '';
switch (osdData.timers[timerIndex].src) { switch (osdData.timers[timerIndex].src) {
@ -675,9 +742,12 @@ OSD.loadDisplayFields = function() {
defaultPosition: 62, defaultPosition: 62,
draw_order: 160, draw_order: 160,
positionable: true, positionable: true,
variants: [
'osdTextElementAltitudeVariant1Decimal',
'osdTextElementAltitudeVariantNoDecimal',
],
preview(osdData) { preview(osdData) {
const unit = FONT.symbol(osdData.unit_mode === 0 ? SYM.FEET : SYM.METRE); return OSD.generateAltitudePreview(osdData);
return `${FONT.symbol(SYM.ALTITUDE)}399.7${unit}`;
}, },
}, },
ONTIME: { ONTIME: {
@ -733,7 +803,15 @@ OSD.loadDisplayFields = function() {
defaultPosition: -1, defaultPosition: -1,
draw_order: 830, draw_order: 830,
positionable: true, positionable: true,
preview: `${FONT.symbol(SYM.GPS_LON)}-000.0000000`, variants: [
'osdTextElementGPSVariant7Decimals',
'osdTextElementGPSVariant4Decimals',
'osdTextElementGPSVariantDegMinSec',
'osdTextElementGPSVariantOpenLocation',
],
preview(osdData) {
return OSD.generateGpsLatLongPreview(osdData, 'GPS_LON');
},
}, },
GPS_LAT: { GPS_LAT: {
name: 'GPS_LAT', name: 'GPS_LAT',
@ -742,7 +820,15 @@ OSD.loadDisplayFields = function() {
defaultPosition: -1, defaultPosition: -1,
draw_order: 820, draw_order: 820,
positionable: true, positionable: true,
preview: `${FONT.symbol(SYM.GPS_LAT)}-00.0000000 `, variants: [
'osdTextElementGPSVariant7Decimals',
'osdTextElementGPSVariant4Decimals',
'osdTextElementGPSVariantDegMinSec',
'osdTextElementGPSVariantOpenLocation',
],
preview(osdData) {
return OSD.generateGpsLatLongPreview(osdData, 'GPS_LAT');
},
}, },
DEBUG: { DEBUG: {
name: 'DEBUG', name: 'DEBUG',
@ -842,10 +928,15 @@ OSD.loadDisplayFields = function() {
defaultPosition: -17, defaultPosition: -17,
draw_order: 270, draw_order: 270,
positionable: true, positionable: true,
preview: FONT.symbol(SYM.PB_START) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) variants: [
+ FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) 'osdTextElementMainBattUsageVariantGraphrRemain',
+ FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_FULL) + FONT.symbol(SYM.PB_END) + FONT.symbol(SYM.PB_EMPTY) 'osdTextElementMainBattUsageVariantGraphUsage',
+ FONT.symbol(SYM.PB_CLOSE), 'osdTextElementMainBattUsageVariantValueRemain',
'osdTextElementMainBattUsageVariantValueUsage',
],
preview(osdData) {
return OSD.generateBatteryUsagePreview(osdData);
},
}, },
ARMED_TIME: { ARMED_TIME: {
name: 'ARMED_TIME', name: 'ARMED_TIME',
@ -1195,6 +1286,7 @@ OSD.loadDisplayFields = function() {
OSD.constants = { OSD.constants = {
VISIBLE: 0x0800, VISIBLE: 0x0800,
VARIANTS: 0xC000,
VIDEO_TYPES: [ VIDEO_TYPES: [
'AUTO', 'AUTO',
'PAL', 'PAL',
@ -1801,7 +1893,9 @@ OSD.msp = {
* b: blink flag * b: blink flag
* y: y coordinate * y: y coordinate
* x: x coordinate * x: x coordinate
* 0000 vbyy yyyx xxxx * p: profile
* t: variant type
* ttpp vbyy yyyx xxxx
*/ */
helpers: { helpers: {
unpack: { unpack: {
@ -1820,6 +1914,9 @@ OSD.msp = {
for (let osd_profile = 0; osd_profile < OSD.getNumberOfProfiles(); osd_profile++) { for (let osd_profile = 0; osd_profile < OSD.getNumberOfProfiles(); osd_profile++) {
displayItem.isVisible[osd_profile] = (bits & (OSD.constants.VISIBLE << osd_profile)) !== 0; displayItem.isVisible[osd_profile] = (bits & (OSD.constants.VISIBLE << osd_profile)) !== 0;
} }
displayItem.variant = (bits & OSD.constants.VARIANTS) >> 14;
} else { } else {
displayItem.position = (bits === -1) ? defaultPosition : bits; displayItem.position = (bits === -1) ? defaultPosition : bits;
displayItem.isVisible = [bits !== -1]; displayItem.isVisible = [bits !== -1];
@ -1839,13 +1936,17 @@ OSD.msp = {
position(displayItem) { position(displayItem) {
const isVisible = displayItem.isVisible; const isVisible = displayItem.isVisible;
const position = displayItem.position; const position = displayItem.position;
const variant = displayItem.variant;
if (semver.gte(FC.CONFIG.apiVersion, "1.21.0")) { if (semver.gte(FC.CONFIG.apiVersion, "1.21.0")) {
let packed_visible = 0; let packed_visible = 0;
for (let osd_profile = 0; osd_profile < OSD.getNumberOfProfiles(); osd_profile++) { for (let osd_profile = 0; osd_profile < OSD.getNumberOfProfiles(); osd_profile++) {
packed_visible |= isVisible[osd_profile] ? OSD.constants.VISIBLE << osd_profile : 0; packed_visible |= isVisible[osd_profile] ? OSD.constants.VISIBLE << osd_profile : 0;
} }
return packed_visible | (((position / FONT.constants.SIZES.LINE) & 0x001F) << 5) | (position % FONT.constants.SIZES.LINE); const variantSelected = (variant << 14);
return packed_visible | variantSelected | (((position / FONT.constants.SIZES.LINE) & 0x001F) << 5) | (position % FONT.constants.SIZES.LINE);
} else { } else {
const realPosition = position === -1 ? 0 : position; const realPosition = position === -1 ? 0 : position;
return isVisible[0] ? realPosition : -1; return isVisible[0] ? realPosition : -1;
@ -1954,6 +2055,7 @@ OSD.msp = {
index: j, index: j,
draw_order: c.draw_order, draw_order: c.draw_order,
preview: suffix ? c.preview + suffix : c.preview, preview: suffix ? c.preview + suffix : c.preview,
variants: c.variants,
ignoreSize, ignoreSize,
}, this.helpers.unpack.position(item, c))); }, this.helpers.unpack.position(item, c)));
} }
@ -2810,6 +2912,32 @@ TABS.osd.initialize = function(callback) {
const finalFieldName = titleizeField(field); const finalFieldName = titleizeField(field);
$field.append(`<label for="${field.name}" class="char-label">${finalFieldName}</label>`); $field.append(`<label for="${field.name}" class="char-label">${finalFieldName}</label>`);
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44) && field.variants && field.variants.length > 0) {
const selectVariant = $('<select class="osd-variant" />')
.data('field', field)
.on("change", function() {
const fieldChanged = $(this).data('field');
fieldChanged.variant = parseInt($(this).val());
MSP.promise(MSPCodes.MSP_SET_OSD_CONFIG, OSD.msp.encodeLayout(fieldChanged))
.then(function() {
updateOsdView();
});
});
for (const [variantIndex, variantText] of field.variants.entries()) {
selectVariant.append($('<option/>')
.val(variantIndex)
.html(i18n.getMessage(variantText)));
}
selectVariant.val(field.variant);
$field.append(selectVariant);
}
if (field.positionable && field.isVisible[OSD.getCurrentPreviewProfile()]) { if (field.positionable && field.isVisible[OSD.getCurrentPreviewProfile()]) {
$field.append( $field.append(
$(`<input type="number" class="${field.index} position"></input>`) $(`<input type="number" class="${field.index} position"></input>`)