mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-26 01:35:28 +03:00
feat & fix : made this actually work with advanced elements and now it should account the height
This commit is contained in:
parent
94b7d301a0
commit
09477e1dec
2 changed files with 111 additions and 86 deletions
|
@ -512,6 +512,10 @@
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
|
button.osd-menu-trigger {
|
||||||
|
all: unset;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.osd-context-menu {
|
.osd-context-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -26,7 +26,7 @@ let globalMenuClickHandler = null;
|
||||||
const positionConfigs = {
|
const positionConfigs = {
|
||||||
TL: {
|
TL: {
|
||||||
label: "Top Left",
|
label: "Top Left",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: 1,
|
x: 1,
|
||||||
y: 1,
|
y: 1,
|
||||||
}),
|
}),
|
||||||
|
@ -38,7 +38,7 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
TC: {
|
TC: {
|
||||||
label: "Top Center",
|
label: "Top Center",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
||||||
y: 1,
|
y: 1,
|
||||||
}),
|
}),
|
||||||
|
@ -50,7 +50,7 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
TR: {
|
TR: {
|
||||||
label: "Top Right",
|
label: "Top Right",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
||||||
y: 1,
|
y: 1,
|
||||||
}),
|
}),
|
||||||
|
@ -60,12 +60,12 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
gridPos: [2, 0],
|
gridPos: [2, 0],
|
||||||
},
|
},
|
||||||
// Top‑middle row
|
// Top-middle row
|
||||||
TML: {
|
TML: {
|
||||||
label: "Top Middle Left",
|
label: "Top Middle Left",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: 1,
|
x: 1,
|
||||||
y: Math.floor(OSD.data.displaySize.y / 3),
|
y: Math.floor(OSD.data.displaySize.y / 3) - Math.floor(h / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -75,9 +75,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
TMC: {
|
TMC: {
|
||||||
label: "Top Mid Center",
|
label: "Top Mid Center",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
||||||
y: Math.floor(OSD.data.displaySize.y / 3),
|
y: Math.floor(OSD.data.displaySize.y / 3) - Math.floor(h / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -87,9 +87,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
TMR: {
|
TMR: {
|
||||||
label: "Top Middle Right",
|
label: "Top Middle Right",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
||||||
y: Math.floor(OSD.data.displaySize.y / 3),
|
y: Math.floor(OSD.data.displaySize.y / 3) - Math.floor(h / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -100,9 +100,9 @@ const positionConfigs = {
|
||||||
// Exact middle row
|
// Exact middle row
|
||||||
LMC: {
|
LMC: {
|
||||||
label: "Left Middle",
|
label: "Left Middle",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.floor(OSD.data.displaySize.x / 3),
|
x: 1,
|
||||||
y: Math.floor(OSD.data.displaySize.y / 2),
|
y: Math.floor((OSD.data.displaySize.y - h) / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -112,9 +112,11 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
CTR: {
|
CTR: {
|
||||||
label: "Center",
|
label: "Center",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
x: Math.floor(OSD.data.displaySize.x / 2 - w / 2),
|
||||||
y: Math.floor(OSD.data.displaySize.y / 2),
|
y: Math.floor(OSD.data.displaySize.y / 2 - h / 2),
|
||||||
|
// x: 1,
|
||||||
|
// y: 1,
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -124,9 +126,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
RMC: {
|
RMC: {
|
||||||
label: "Right Middle",
|
label: "Right Middle",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.max(1, Math.floor((OSD.data.displaySize.x * 2) / 3) - Math.floor(w / 2)),
|
x: OSD.data.displaySize.x - 1 - w,
|
||||||
y: Math.floor(OSD.data.displaySize.y / 2),
|
y: Math.floor((OSD.data.displaySize.y - h) / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -134,12 +136,12 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
gridPos: [2, 2],
|
gridPos: [2, 2],
|
||||||
},
|
},
|
||||||
// Bottom‑middle row
|
// Bottom-middle row
|
||||||
BML: {
|
BML: {
|
||||||
label: "Bottom Middle Left",
|
label: "Bottom Middle Left",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: 1,
|
x: 1,
|
||||||
y: Math.floor((OSD.data.displaySize.y * 2) / 3),
|
y: Math.floor((OSD.data.displaySize.y * 2) / 3) - Math.floor(h / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -149,9 +151,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
BMC: {
|
BMC: {
|
||||||
label: "Bottom Mid Center",
|
label: "Bottom Mid Center",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
||||||
y: Math.floor((OSD.data.displaySize.y * 2) / 3),
|
y: Math.floor((OSD.data.displaySize.y * 2) / 3) - Math.floor(h / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -161,9 +163,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
BMR: {
|
BMR: {
|
||||||
label: "Bottom Middle Right",
|
label: "Bottom Middle Right",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
||||||
y: Math.floor((OSD.data.displaySize.y * 2) / 3),
|
y: Math.floor((OSD.data.displaySize.y * 2) / 3) - Math.floor(h / 2),
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -173,9 +175,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
BL: {
|
BL: {
|
||||||
label: "Bottom Left",
|
label: "Bottom Left",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: 1,
|
x: 1,
|
||||||
y: OSD.data.displaySize.y - 2,
|
y: OSD.data.displaySize.y - h - 1,
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -185,9 +187,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
BC: {
|
BC: {
|
||||||
label: "Bottom Center",
|
label: "Bottom Center",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
x: Math.floor((OSD.data.displaySize.x - w) / 2),
|
||||||
y: OSD.data.displaySize.y - 2,
|
y: OSD.data.displaySize.y - h - 1,
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -197,9 +199,9 @@ const positionConfigs = {
|
||||||
},
|
},
|
||||||
BR: {
|
BR: {
|
||||||
label: "Bottom Right",
|
label: "Bottom Right",
|
||||||
coords: (w) => ({
|
coords: (w, h) => ({
|
||||||
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
x: Math.max(1, OSD.data.displaySize.x - w - 1),
|
||||||
y: OSD.data.displaySize.y - 2,
|
y: OSD.data.displaySize.y - h - 1,
|
||||||
}),
|
}),
|
||||||
grow: {
|
grow: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -2105,12 +2107,14 @@ OSD.searchLimitsElement = function (arrayElements) {
|
||||||
limits.maxX = Math.max(valor.length, limits.maxX);
|
limits.maxX = Math.max(valor.length, limits.maxX);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
arrayElements.forEach(function (valor) {
|
for (let i = 0; i < arrayElements.length; i++) {
|
||||||
limits.minX = Math.min(valor.x, limits.minX);
|
const { x, y } = arrayElements[i];
|
||||||
limits.maxX = Math.max(valor.x, limits.maxX);
|
// Update axis limits.
|
||||||
limits.minY = Math.min(valor.y, limits.minY);
|
if (x < limits.minX) limits.minX = x;
|
||||||
limits.maxY = Math.max(valor.y, limits.maxY);
|
if (x > limits.maxX) limits.maxX = x;
|
||||||
});
|
if (y < limits.minY) limits.minY = y;
|
||||||
|
if (y > limits.maxY) limits.maxY = y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return limits;
|
return limits;
|
||||||
|
@ -3478,13 +3482,13 @@ osd.initialize = function (callback) {
|
||||||
|
|
||||||
// Create the context menu trigger button
|
// Create the context menu trigger button
|
||||||
const $menuTrigger = $(`
|
const $menuTrigger = $(`
|
||||||
<div class="osd-menu-trigger grey" title="Position Options">
|
<button type="button" class="osd-menu-trigger grey" aria-label="OSD position options">
|
||||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
|
||||||
<circle cx="12" cy="5" r="2"/>
|
<circle cx="12" cy="5" r="2"/>
|
||||||
<circle cx="12" cy="12" r="2"/>
|
<circle cx="12" cy="12" r="2"/>
|
||||||
<circle cx="12" cy="19" r="2"/>
|
<circle cx="12" cy="19" r="2"/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>`);
|
</button>`);
|
||||||
// Create the context menu
|
// Create the context menu
|
||||||
const $contextMenu = $(`
|
const $contextMenu = $(`
|
||||||
<div class="osd-context-menu">
|
<div class="osd-context-menu">
|
||||||
|
@ -3537,54 +3541,37 @@ osd.initialize = function (callback) {
|
||||||
const applyPosition = (fieldChanged, positionKey) => {
|
const applyPosition = (fieldChanged, positionKey) => {
|
||||||
const config = positionConfigs[positionKey];
|
const config = positionConfigs[positionKey];
|
||||||
if (!config) return;
|
if (!config) return;
|
||||||
// Get element width estimation (same logic as before)
|
|
||||||
let elementWidth = 1;
|
let elementWidth = fieldChanged.preview.constructor == String ? fieldChanged.preview.length : 1;
|
||||||
if (fieldChanged.preview && fieldChanged.preview.length) {
|
// TODO : Are there any multi-lined String (simple) elements?Hardcoding this to one for now.
|
||||||
elementWidth = fieldChanged.preview.length;
|
let elementHeight = 1;
|
||||||
} else if (fieldChanged.preview_length) {
|
|
||||||
elementWidth = fieldChanged.preview_length;
|
let adjustOffsetX = 0;
|
||||||
} else if (fieldChanged.length) {
|
let adjustOffsetY = 0;
|
||||||
elementWidth = fieldChanged.length;
|
|
||||||
} else if (fieldChanged.max_length) {
|
// Advanced elements
|
||||||
elementWidth = fieldChanged.max_length;
|
if (fieldChanged.preview.constructor == Array) {
|
||||||
} else if (fieldChanged.name) {
|
const limits = OSD.searchLimitsElement(fieldChanged.preview);
|
||||||
const fieldEstimates = {
|
|
||||||
ALTITUDE: 6,
|
elementWidth = limits.maxX - limits.minX;
|
||||||
THROTTLE_POS: 4,
|
elementHeight = limits.maxY - limits.minY;
|
||||||
BATTERY_VOLTAGE: 5,
|
|
||||||
RSSI_VALUE: 4,
|
// I'n
|
||||||
TIMER: 8,
|
adjustOffsetX = limits.minX + 1;
|
||||||
FLYMODE: 4,
|
adjustOffsetY = limits.minY + 1;
|
||||||
CRAFT_NAME: 12,
|
|
||||||
PILOT_NAME: 12,
|
|
||||||
HOME_DIST: 8,
|
|
||||||
GPS_SPEED: 6,
|
|
||||||
GPS_SATS: 3,
|
|
||||||
CURRENT_DRAW: 6,
|
|
||||||
MAH_DRAWN: 6,
|
|
||||||
WH_DRAWN: 6,
|
|
||||||
BATTERY_AVERAGE_CELL_VOLTAGE: 5,
|
|
||||||
GPS_LON: 12,
|
|
||||||
GPS_LAT: 12,
|
|
||||||
DEBUG: 8,
|
|
||||||
PID_ROLL: 8,
|
|
||||||
PID_PITCH: 8,
|
|
||||||
PID_YAW: 8,
|
|
||||||
POWER: 4,
|
|
||||||
PIDRATE_PROFILE: 3,
|
|
||||||
PID_PROFILE: 3,
|
|
||||||
RC_CHANNELS: 4,
|
|
||||||
CAMERA_FRAME: 10,
|
|
||||||
};
|
|
||||||
elementWidth = fieldEstimates[fieldChanged.name] || 6;
|
|
||||||
}
|
}
|
||||||
const target = config.coords(elementWidth);
|
|
||||||
|
const target = config.coords(elementWidth, elementHeight);
|
||||||
let finalPosition = null;
|
let finalPosition = null;
|
||||||
// Ensure target position is within bounds
|
// Ensure target position is within bounds
|
||||||
if (target.x < 1) target.x = 1;
|
if (target.x < 1) target.x = 1;
|
||||||
|
if (target.y < 1) target.y = 1;
|
||||||
if (target.x + elementWidth > OSD.data.displaySize.x - 1) {
|
if (target.x + elementWidth > OSD.data.displaySize.x - 1) {
|
||||||
target.x = Math.max(1, OSD.data.displaySize.x - elementWidth - 1);
|
target.x = Math.max(1, OSD.data.displaySize.x - elementWidth - 1);
|
||||||
}
|
}
|
||||||
|
if (target.y + elementHeight > OSD.data.displaySize.y - 1) {
|
||||||
|
target.y = Math.max(1, OSD.data.displaySize.y - elementHeight - 1);
|
||||||
|
}
|
||||||
// Find available position with growth logic
|
// Find available position with growth logic
|
||||||
for (
|
for (
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
|
@ -3601,15 +3588,49 @@ osd.initialize = function (callback) {
|
||||||
)
|
)
|
||||||
break;
|
break;
|
||||||
let canPlace = true;
|
let canPlace = true;
|
||||||
for (let i = 0; i < elementWidth && canPlace; i++) {
|
for (let row = 0; row < elementHeight && canPlace; row++) {
|
||||||
const checkPos = testY * OSD.data.displaySize.x + testX + i;
|
for (let col = 0; col < elementWidth && canPlace; col++) {
|
||||||
const cell = OSD.data.preview[checkPos];
|
const checkPos = (testY + row) * OSD.data.displaySize.x + testX + col;
|
||||||
if (cell && cell[0] && cell[0].index !== fieldChanged.index) {
|
const cell = OSD.data.preview[checkPos];
|
||||||
canPlace = false;
|
|
||||||
|
if (
|
||||||
|
cell &&
|
||||||
|
cell[0] &&
|
||||||
|
cell[0].index !== fieldChanged.index &&
|
||||||
|
// Lets skip over the advanced elements and just let any elements overlap these advanced elements and let it be overlapped by any element.
|
||||||
|
// Since they don't actually use up the full space of their bounds and we can overlap with them while our elements still being fully visible.
|
||||||
|
!(
|
||||||
|
cell[0].preview.constructor === Array ||
|
||||||
|
fieldChanged.preview.constructor === Array
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
canPlace = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (canPlace) {
|
if (canPlace) {
|
||||||
finalPosition = testY * OSD.data.displaySize.x + testX;
|
finalPosition = testY * OSD.data.displaySize.x + testX;
|
||||||
|
{
|
||||||
|
// I'm just copying this block here but I actually don't fully understand why this is needed
|
||||||
|
// and why we can't just put it at that position and need these offsets/adjustments:
|
||||||
|
|
||||||
|
// if (displayItem.preview.constructor === Array) {
|
||||||
|
// console.log(`Initial Drop Position: ${position}`);
|
||||||
|
// const x = parseInt(ev.dataTransfer.getData("x"));
|
||||||
|
// const y = parseInt(ev.dataTransfer.getData("y"));
|
||||||
|
// console.log(`XY Co-ords: ${x}-${y}`);
|
||||||
|
// position -= x; // <-- Here
|
||||||
|
// position -= y * OSD.data.displaySize.x; // <-- Here
|
||||||
|
// console.log(`Calculated Position: ${position}`);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// This just imitates the code above^
|
||||||
|
// If this doesn't exist then advanced elements can't be properly
|
||||||
|
// placed/positioned to the preset positions
|
||||||
|
finalPosition -= adjustOffsetX;
|
||||||
|
finalPosition -= adjustOffsetY * OSD.data.displaySize.x;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue