MapPreview.qml 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import QtQuick 2.15
  2. import QtQuick.Controls 2.15
  3. import QtQuick.Layouts 1.15
  4. import StandardOfIron 1.0
  5. Rectangle {
  6. id: root
  7. property var mapPath: ""
  8. property var playerConfigs: []
  9. property bool loading: false
  10. property string previewId: ""
  11. function refreshPreview() {
  12. if (!mapPath || mapPath === "" || !playerConfigs || playerConfigs.length === 0) {
  13. previewImage.source = "";
  14. previewId = "";
  15. return ;
  16. }
  17. if (typeof game === "undefined" || !game.generate_map_preview)
  18. return ;
  19. loading = true;
  20. try {
  21. var configStr = JSON.stringify(playerConfigs);
  22. var hash = 0;
  23. for (var i = 0; i < configStr.length; i++) {
  24. var codePoint = configStr.charCodeAt(i);
  25. hash = ((hash << 5) - hash) + codePoint;
  26. hash = hash & hash;
  27. }
  28. var newId = mapPath + "_" + hash + "_" + Date.now();
  29. var preview = game.generate_map_preview(mapPath, playerConfigs);
  30. if (typeof mapPreviewProvider !== "undefined") {
  31. mapPreviewProvider.set_preview_image(newId, preview);
  32. previewId = newId;
  33. previewImage.source = "image://mappreview/" + newId;
  34. }
  35. loading = false;
  36. } catch (e) {
  37. console.error("MapPreview: Failed to generate preview:", e);
  38. loading = false;
  39. }
  40. }
  41. radius: Theme.radiusLarge
  42. color: Theme.cardBase
  43. border.color: Theme.panelBr
  44. border.width: 1
  45. clip: true
  46. onMapPathChanged: refreshPreview()
  47. onPlayerConfigsChanged: refreshPreview()
  48. Text {
  49. id: titleText
  50. text: qsTr("Map Preview")
  51. color: Theme.textMain
  52. font.pixelSize: 16
  53. font.bold: true
  54. anchors {
  55. top: parent.top
  56. left: parent.left
  57. margins: Theme.spacingMedium
  58. }
  59. }
  60. Rectangle {
  61. id: previewContainer
  62. color: Theme.cardBaseB
  63. radius: Theme.radiusMedium
  64. border.color: Theme.thumbBr
  65. border.width: 1
  66. anchors {
  67. top: titleText.bottom
  68. left: parent.left
  69. right: parent.right
  70. bottom: parent.bottom
  71. margins: Theme.spacingMedium
  72. }
  73. RowLayout {
  74. id: previewRow
  75. anchors.fill: parent
  76. anchors.margins: Theme.spacingSmall
  77. spacing: Theme.spacingMedium
  78. visible: !loading
  79. Item {
  80. id: imageWrapper
  81. Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
  82. Layout.preferredWidth: Math.min(previewContainer.width * 0.6, previewContainer.height - Theme.spacingLarge)
  83. Layout.preferredHeight: Layout.preferredWidth
  84. Image {
  85. id: previewImage
  86. anchors.fill: parent
  87. fillMode: Image.PreserveAspectFit
  88. smooth: true
  89. cache: false
  90. visible: status === Image.Ready
  91. }
  92. }
  93. Text {
  94. id: legendText
  95. text: qsTr("Player bases shown as colored circles")
  96. color: Theme.textSubLite
  97. font.pixelSize: 12
  98. font.italic: true
  99. wrapMode: Text.WordWrap
  100. horizontalAlignment: Text.AlignLeft
  101. verticalAlignment: Text.AlignVCenter
  102. Layout.fillWidth: true
  103. Layout.alignment: Qt.AlignVCenter
  104. visible: mapPath !== ""
  105. }
  106. }
  107. Text {
  108. anchors.centerIn: parent
  109. text: qsTr("Select a map\nto see preview")
  110. color: Theme.textHint
  111. font.pixelSize: 13
  112. horizontalAlignment: Text.AlignHCenter
  113. visible: !loading && previewImage.status !== Image.Ready && mapPath === ""
  114. }
  115. Text {
  116. anchors.centerIn: parent
  117. text: qsTr("No preview available")
  118. color: Theme.textHint
  119. font.pixelSize: 13
  120. horizontalAlignment: Text.AlignHCenter
  121. visible: !loading && previewImage.status !== Image.Ready && mapPath !== ""
  122. }
  123. Item {
  124. anchors.centerIn: parent
  125. visible: loading
  126. width: 60
  127. height: 60
  128. Text {
  129. anchors.centerIn: parent
  130. text: "⟳"
  131. font.pixelSize: 36
  132. color: Theme.accent
  133. RotationAnimator on rotation {
  134. from: 0
  135. to: 360
  136. duration: 1500
  137. loops: Animation.Infinite
  138. running: loading
  139. }
  140. }
  141. }
  142. }
  143. }