Revision control

Copy as Markdown

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Shapes
Item {
id: map
implicitWidth: mapShape.implicitWidth
implicitHeight: mapShape.implicitHeight
Europe_generated {
id: mapShape
}
property int containsMode: Shape.FillContains
property bool zoomedIn: false
signal zoomTo(Item child, string name, var childRect, var textRect)
property var lookupTable: {
"fi" : "Finland"
,"se" : "Sweden"
,"dk" : "Denmark"
,"gb-nir" : "Northern Ireland"
,"gb-main" : "Great Britain"
,"ie" : "Ireland"
,"nl" : "The Netherlands"
,"be" : "Belgium"
,"lu" : "Luxembourg"
,"de" : "Germany"
,"fr" : "France"
,"es" : "Spain"
,"pt" : "Portugal"
,"at" : "Austria"
,"it" : "Italy"
,"gr" : "Greece"
,"ee" : "Estonia"
,"lv" : "Latvia"
,"lt" : "Lithuania"
,"pl" : "Poland"
,"cz" : "Czechia"
,"sk" : "Slovakia"
,"si" : "Slovenia"
,"hu" : "Hungary"
,"ro" : "Romania"
,"bg" : "Bulgaria"
,"cy" : "Cyprus"
,"mt" : "Malta"
,"hr" : "Croatia"
,"ba" : "Bosnia and Herzegovina"
,"me" : "Montenegro"
,"rs" : "Serbia"
,"rs-km" : "Kosovo"
,"mk" : "North Makedonia"
,"al" : "Albania"
,"is" : "Iceland"
,"by" : "Belarus"
,"no" : "Norway"
,"ua" : "Ukraine"
,"ch" : "Switzerland"
,"md" : "Moldova"
,"ad" : "Andorra"
,"mc" : "Monaco"
,"li" : "Liechtenstein"
,"ru-kgd" : "Kaliningrad"
,"im" : "Isle of Man"
,"fo" : "Faroe Islands"
}
property var overrideRects: {
"fi": {x: 6616, y: 1996, width: 1920, height: 800, rotation: 65},
"no": {x: 4794, y: 1967, width: 3360, height: 680, rotation: -65},
"se": {x: 5739, y: 2560, width: 1920, height: 800, rotation: -80},
"it": {x: 5734, y: 6483, width: 1680, height: 440, rotation: 45},
"pt": {x: 3105, y: 6783, width: 960, height: 320, rotation: -70},
"md": {x: 8294, y: 5472, width: 480, height: 200, rotation: 45},
"rs": {x: 7233, y: 6168, width: 840, height: 320, rotation: 45},
"gb-main": {x: 3943, y: 3998, width: 1800, height: 800, rotation: 75},
"ba": {x: 6570, y: 6289, width: 1440, height: 200, rotation: 0},
"al": {x: 7312, y: 6830, width: 600, height: 200, rotation: 75},
"be": {x: 5237, y: 5126, width: 600, height: 200, rotation: 40},
"hr": {x: 6705, y: 6053, width: 840, height: 200, rotation: 0},
"at": {x: 6191, y: 5556, width: 1080, height: 440, rotation: -25},
"cy": {x: 9509, y: 7497, width: 480, height: 200, rotation: -35},
}
MouseArea {
id: mouseArea
anchors.fill: parent
property Item currentChild: null
property color prevColor
property color selectedColor: "#dbd6c8"
acceptedButtons: Qt.LeftButton
function traverseChildren(item, x, y) {
let p = item.mapFromItem(mouseArea, x, y)
if (item.objectName) {
if (item.contains(p))
return item;
}
for (var i = 0; i < item.children.length; i++) {
let r = traverseChildren(item.children[i], x, y)
if (r)
return r;
}
return null;
}
function findChild(x, y) {
return traverseChildren(map, x, y)
}
function findMatchingPath(node) {
if (!node)
return null
let pathName = "svg_path:" + node.objectName
for (var i = 0; i < node.data.length; i++) {
let child = node.data[i]
if (child.objectName === pathName)
return child
}
return null
}
onPressed: (mouse)=> {
if (!map.zoomedIn) {
currentChild = findChild(mouse.x, mouse.y)
let path = findMatchingPath(currentChild)
if (path) {
prevColor = path.fillColor
path.fillColor = selectedColor
currentChild.z = 1
}
}
}
onPositionChanged: (mouse)=> {
if (currentChild) {
let localPos = currentChild.mapFromItem(mouseArea, mouse.x, mouse.y)
let path = findMatchingPath(currentChild)
if (path) {
if (currentChild.contains(localPos)) {
path.fillColor = selectedColor
} else {
path.fillColor = prevColor
}
}
}
}
onReleased: (mouse) => {
if (map.zoomedIn) {
zoomTo(null, null, null, null)
zoomedIn = false
if (currentChild) {
let path = findMatchingPath(currentChild)
if (path)
path.fillColor = prevColor
currentChild.z = 0
currentChild = null
}
} else if (currentChild) {
let localPos = currentChild.mapFromItem(mouseArea, mouse.x, mouse.y)
if (currentChild.contains(localPos)) {
let br = currentChild.boundingRect
let rot = 0
let or = overrideRects[currentChild.objectName]
if (or) {
rot = or.rotation
let r = currentChild.mapToItem(map, or.x, or.y, or.width, or.height)
or = {x: r.x, y: r.y, width: r.width, height: r.height, rotation: rot}
}
let rect = currentChild.mapToItem(map, br)
zoomTo(currentChild, lookupTable[currentChild.objectName], rect, or )
zoomedIn = true
}
}
}
}
}