| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- // Copyright (C) 2025 The Qt Company Ltd.
- // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
- import QtQuick
- import QtQuick.Controls
- import QtQuick.Layouts
- import QtQuick.Window
- import QtQuick.Dialogs
- import LightmapFile 1.0
- ApplicationWindow {
- width: 640
- height: 480
- visible: true
- title: qsTr("Lightmap Viewer")
- id: window
- property string selectedKey: listView.model[0]
- property real imageZoom: 1
- property real imageCenterX: 0
- property real imageCenterY: 0
- function clampImagePosition() {
- // If the image is smaller than the scroll view, center it
- if (image.width <= scrollView.width) {
- imageCenterX = 0
- } else {
- const maxOffsetX = (image.width - scrollView.width) / 2
- imageCenterX = Math.max(-maxOffsetX, Math.min(imageCenterX,
- maxOffsetX))
- }
- if (image.height <= scrollView.height) {
- imageCenterY = 0
- } else {
- const maxOffsetY = (image.height - scrollView.height) / 2
- imageCenterY = Math.max(-maxOffsetY, Math.min(imageCenterY,
- maxOffsetY))
- }
- }
- header: ToolBar {
- RowLayout {
- Button {
- text: qsTr("Open Lightmap")
- onClicked: fileDialog.open()
- }
- Rectangle {
- width: 1
- color: "darkgray"
- Layout.fillHeight: true
- Layout.alignment: Qt.AlignVCenter
- }
- Label {
- text: "Zoom: " + window.imageZoom.toFixed(1)
- }
- Rectangle {
- width: 1
- color: "darkgray"
- Layout.fillHeight: true
- Layout.alignment: Qt.AlignVCenter
- }
- Switch {
- id: alphaSwitch
- padding: 0
- checked: true
- text: "Alpha"
- }
- Rectangle {
- width: 1
- color: "darkgray"
- Layout.fillHeight: true
- Layout.alignment: Qt.AlignVCenter
- }
- Text {
- text: "Path: " + LightmapFile.source
- }
- }
- }
- FileDialog {
- id: fileDialog
- onAccepted: {
- LightmapFile.source = selectedFile
- LightmapFile.loadData()
- }
- }
- Shortcut {
- sequences: [StandardKey.Open]
- onActivated: {
- fileDialog.open()
- }
- }
- SplitView {
- anchors.fill: parent
- orientation: Qt.Horizontal
- focus: true
- Keys.onPressed: event => {
- if (event.key === Qt.Key_Up) {
- listView.currentIndex = Math.max(
- 0, listView.currentIndex - 1)
- selectedKey = listView.model[listView.currentIndex]
- } else if (event.key === Qt.Key_Down) {
- listView.currentIndex = Math.min(
- listView.model.length - 1,
- listView.currentIndex + 1)
- selectedKey = listView.model[listView.currentIndex]
- }
- clampImagePosition()
- }
- ListView {
- id: listView
- SplitView.preferredWidth: 100
- SplitView.minimumWidth: 50
- model: LightmapFile.dataList
- delegate: Text {
- text: modelData
- MouseArea {
- anchors.fill: parent
- onClicked: {
- listView.currentIndex = index
- selectedKey = modelData // Select this item
- }
- }
- }
- highlight: Rectangle {
- color: "lightsteelblue"
- radius: 1
- }
- }
- Rectangle {
- id: scrollView
- clip: true
- color: "black"
- property real lastMouseX: 0
- property real lastMouseY: 0
- onWidthChanged: {
- clampImagePosition()
- }
- onHeightChanged: {
- clampImagePosition()
- }
- MouseArea {
- id: mouseArea
- property bool dragging: false
- anchors.fill: parent
- onPressed: mouse => {
- scrollView.lastMouseX = mouse.x
- scrollView.lastMouseY = mouse.y
- dragging = true
- }
- onReleased: mouse => {
- dragging = false
- }
- onPositionChanged: mouse => {
- var dx = mouse.x - scrollView.lastMouseX
- var dy = mouse.y - scrollView.lastMouseY
- scrollView.lastMouseX = mouse.x
- scrollView.lastMouseY = mouse.y
- imageCenterX += dx
- imageCenterY += dy
- clampImagePosition()
- }
- cursorShape: mouseArea.dragging ? Qt.ClosedHandCursor : Qt.ArrowCursor
- onWheel: event => {
- const oldZoom = imageZoom
- const zoomDelta = event.angleDelta.y / 256
- const newZoom = Math.max(
- 1, Math.min(32, oldZoom + zoomDelta))
- if (newZoom === oldZoom)
- return
- // Adjust center offset so the same point remains at the center
- const scaleFactor = newZoom / oldZoom
- imageCenterX *= scaleFactor
- imageCenterY *= scaleFactor
- imageZoom = newZoom
- clampImagePosition()
- event.accepted = true
- }
- }
- Image {
- id: baseGrid
- anchors.fill: scrollView
- source: "grid.png"
- fillMode: Image.Tile
- opacity: 0.75
- }
- Rectangle {
- width: image.width + (border.width * 2)
- height: image.height + (border.width * 2)
- x: image.x - border.width
- y: image.y - border.width
- color: "white" // This is the border color
- border.width: 0
- border.color: "white"
- opacity: 0.25
- }
- Image {
- id: image
- x: Math.round(parent.width / 2 - width / 2) + imageCenterX
- y: Math.round(parent.height / 2 - height / 2) + imageCenterY
- source: `image://lightmaps/key=${selectedKey}&file=${LightmapFile.source}&alpha=${alphaSwitch.checked}`
- onWidthChanged: clampImagePosition()
- onHeightChanged: clampImagePosition()
- fillMode: Image.PreserveAspectFit
- smooth: false
- antialiasing: false
- // Let the image scale visibly
- width: sourceSize.width * imageZoom
- height: sourceSize.height * imageZoom
- }
- }
- }
- DropArea {
- id: dropArea
- anchors.fill: parent
- onEntered: (drag) => {
- drag.accept(Qt.LinkAction)
- }
- // Just take first url if several
- onDropped: (drop) => {
- if (drop.hasUrls) {
- LightmapFile.source = drop.urls[0]
- LightmapFile.loadData()
- }
- }
- }
- }
|