-
-
Notifications
You must be signed in to change notification settings - Fork 865
Split label view data #1313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Split label view data #1313
Changes from all commits
7bf33b6
dac231f
c467f87
94b638f
689fef0
2379770
471e865
ca6d01f
3ab40ad
6ab2c03
861db87
0d56479
c22e6eb
32e7049
6d99d82
6fa3f78
e174056
ba0ce8e
fd32007
3927a76
fab495f
25824fe
5f35924
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1106,4 +1106,161 @@ export function resolveVersionConflicts(mapVersion) { | |
| } | ||
|
|
||
| } | ||
|
|
||
| if (isOlderThan("1.114.0")) { | ||
| // v1.114.0 moved labels data from SVG to data model | ||
| // Migrate old SVG labels to pack.labels structure | ||
| if (!pack.labels || !pack.labels.length) { | ||
| pack.labels = []; | ||
| let labelId = 0; | ||
|
|
||
| // Migrate state labels | ||
| const stateLabelsGroup = document.querySelector("#labels > #states"); | ||
| if (stateLabelsGroup) { | ||
| stateLabelsGroup.querySelectorAll("text").forEach(textElement => { | ||
| const id = textElement.getAttribute("id"); | ||
| if (!id || !id.startsWith("stateLabel")) return; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks redundant as the check is below |
||
|
|
||
| const stateIdMatch = id.match(/stateLabel(\d+)/); | ||
| if (!stateIdMatch) return; | ||
|
|
||
| const stateId = +stateIdMatch[1]; | ||
| const state = pack.states[stateId]; | ||
| if (!state || state.removed) return; | ||
|
|
||
| const textPath = textElement.querySelector("textPath"); | ||
| if (!textPath) return; | ||
|
|
||
| const text = textPath.textContent.trim(); | ||
| const fontSizeAttr = textPath.getAttribute("font-size"); | ||
| const fontSize = fontSizeAttr ? parseFloat(fontSizeAttr) : 100; | ||
|
|
||
| pack.labels.push({ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we need to save the custom path path as well? Currently it's not migrating manually changed labels. |
||
| i: pack.labels.length, | ||
| type: "state", | ||
| stateId: stateId, | ||
| text: text, | ||
| fontSize: fontSize | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please reduce the notation
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about other params like |
||
| }); | ||
| }); | ||
| } | ||
|
|
||
| // Migrate burg labels | ||
| const burgLabelsGroup = document.querySelector("#burgLabels"); | ||
| if (burgLabelsGroup) { | ||
| burgLabelsGroup.querySelectorAll("g").forEach(groupElement => { | ||
| const group = groupElement.getAttribute("id"); | ||
| if (!group) return; | ||
|
|
||
| const dxAttr = groupElement.getAttribute("data-dx"); | ||
| const dyAttr = groupElement.getAttribute("data-dy"); | ||
| const dx = dxAttr ? parseFloat(dxAttr) : 0; | ||
| const dy = dyAttr ? parseFloat(dyAttr) : 0; | ||
|
|
||
| groupElement.querySelectorAll("text").forEach(textElement => { | ||
| const burgId = +textElement.getAttribute("data-id"); | ||
| if (!burgId) return; | ||
|
|
||
| const burg = pack.burgs[burgId]; | ||
| if (!burg || burg.removed) return; | ||
|
|
||
| const text = textElement.textContent.trim(); | ||
| // Use burg coordinates, not SVG text coordinates | ||
| // SVG coordinates may be affected by viewbox transforms | ||
| const x = burg.x; | ||
| const y = burg.y; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if use has manually changed to label position? We need to parse |
||
|
|
||
| pack.labels.push({ | ||
| i: labelId++, | ||
| type: "burg", | ||
| burgId: burgId, | ||
| group: group, | ||
| text: text, | ||
| x: x, | ||
| y: y, | ||
| dx: dx, | ||
| dy: dy | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
| }); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| // Migrate custom labels | ||
| const customLabelsGroup = document.querySelector("#labels > #addedLabels"); | ||
| if (customLabelsGroup) { | ||
| customLabelsGroup.querySelectorAll("text").forEach(textElement => { | ||
| const id = textElement.getAttribute("id"); | ||
| if (!id) return; | ||
|
|
||
| const group = "custom"; | ||
| const textPath = textElement.querySelector("textPath"); | ||
| if (!textPath) return; | ||
|
|
||
| const text = textPath.textContent.trim(); | ||
| const fontSizeAttr = textPath.getAttribute("font-size"); | ||
| const fontSize = fontSizeAttr ? parseFloat(fontSizeAttr) : 100; | ||
| const letterSpacingAttr = textPath.getAttribute("letter-spacing"); | ||
| const letterSpacing = letterSpacingAttr ? parseFloat(letterSpacingAttr) : 0; | ||
| const startOffsetAttr = textPath.getAttribute("startOffset"); | ||
| const startOffset = startOffsetAttr ? parseFloat(startOffsetAttr) : 50; | ||
| const transform = textPath.getAttribute("transform"); | ||
|
|
||
| // Get path points from the referenced path | ||
| const href = textPath.getAttribute("xlink:href") || textPath.getAttribute("href"); | ||
| if (!href) return; | ||
|
|
||
| const pathId = href.replace("#", ""); | ||
| const pathElement = document.getElementById(pathId); | ||
| if (!pathElement) return; | ||
|
|
||
| const d = pathElement.getAttribute("d"); | ||
| if (!d) return; | ||
|
|
||
| // Parse path data to extract points(M, L and C commands) | ||
| const pathPoints = []; | ||
| const commands = d.match(/[MLC][^MLC]*/g); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a pretty weak approach, what if coords are lower case |
||
| if (commands) { | ||
| commands.forEach(cmd => { | ||
| const type = cmd[0]; | ||
| if (type === "M" || type === "L") { | ||
| const coords = cmd.slice(1).trim().split(/[\s,]+/).map(Number); | ||
| if (coords.length >= 2) { | ||
| pathPoints.push([coords[0], coords[1]]); | ||
| } | ||
| } else if (type === "C") { | ||
| const coords = cmd.slice(1).trim().split(/[\s,]+/).map(Number); | ||
| if (coords.length >= 6) { | ||
| pathPoints.push([coords[4], coords[5]]); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| if (pathPoints.length > 0) { | ||
| pack.labels.push({ | ||
| i: pack.labels.length, | ||
| type: "custom", | ||
| group: group, | ||
| text: text, | ||
| pathPoints: pathPoints, | ||
| startOffset: startOffset, | ||
| fontSize: fontSize, | ||
| letterSpacing: letterSpacing, | ||
| transform: transform || undefined | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| // Clear old SVG labels and redraw from data | ||
| if (stateLabelsGroup) stateLabelsGroup.querySelectorAll("*").forEach(el => el.remove()); | ||
| if (burgLabelsGroup) burgLabelsGroup.querySelectorAll("text").forEach(el => el.remove()); | ||
|
|
||
| // Regenerate labels from data | ||
| if (layerIsOn("toggleLabels")) { | ||
| drawStateLabels(); | ||
| drawBurgLabels(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -118,6 +118,9 @@ function editBurg(id) { | |
| const id = +elSelected.attr("data-id"); | ||
| pack.burgs[id].name = burgName.value; | ||
| elSelected.text(burgName.value); | ||
| // Sync to Labels data model | ||
StempunkDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const labelData = Labels.getBurgLabel(id); | ||
| if (labelData) Labels.updateLabel(labelData.i, {text: burgName.value}); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can |
||
| } | ||
|
|
||
| function generateNameRandom() { | ||
|
|
@@ -382,6 +385,10 @@ function editBurg(id) { | |
| burg.y = y; | ||
| if (burg.capital) pack.states[newState].center = burg.cell; | ||
|
|
||
| // Sync position to Labels data model | ||
| const labelData = Labels.getBurgLabel(id); | ||
| if (labelData) Labels.updateLabel(labelData.i, {x, y}); | ||
|
|
||
| if (d3.event.shiftKey === false) toggleRelocateBurg(); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should do the same on heightmap edit as well, at least in Erase mode.