ModernPatternCard.qml 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import QtQuick 2.15
  2. import QtQuick.Controls 2.15
  3. import QtQuick.Effects
  4. Rectangle {
  5. property string name: ""
  6. property string preview: "" // Changed from alias to regular property
  7. // Clean up the pattern name for display
  8. property string cleanName: {
  9. var cleanedName = name
  10. // Remove path (get everything after the last slash)
  11. var parts = cleanedName.split('/')
  12. cleanedName = parts[parts.length - 1]
  13. // Remove .thr extension
  14. cleanedName = cleanedName.replace('.thr', '')
  15. return cleanedName
  16. }
  17. signal clicked()
  18. // Watch for preview changes and update image source
  19. onPreviewChanged: {
  20. if (preview) {
  21. previewImage.source = "file://" + preview
  22. } else {
  23. previewImage.source = ""
  24. }
  25. }
  26. color: "white"
  27. radius: 12
  28. border.width: 1
  29. border.color: "#e5e7eb"
  30. // Drop shadow effect - DISABLED for linuxfb compatibility
  31. // linuxfb doesn't support layer effects properly
  32. // layer.enabled: true
  33. // layer.effect: MultiEffect {
  34. // shadowEnabled: true
  35. // shadowColor: "#20000000"
  36. // shadowBlur: 0.8
  37. // shadowVerticalOffset: 2
  38. // shadowHorizontalOffset: 0
  39. // }
  40. // Hover/press animation
  41. scale: mouseArea.pressed ? 0.95 : (mouseArea.containsMouse ? 1.02 : 1.0)
  42. Behavior on scale {
  43. NumberAnimation { duration: 150; easing.type: Easing.OutQuad }
  44. }
  45. Column {
  46. anchors.fill: parent
  47. anchors.margins: 8
  48. spacing: 6
  49. // Preview image container
  50. Rectangle {
  51. width: parent.width
  52. height: parent.height - nameLabel.height - 12
  53. radius: 8
  54. color: "#f8f8f8"
  55. clip: true
  56. Image {
  57. id: previewImage
  58. anchors.fill: parent
  59. fillMode: Image.PreserveAspectFit
  60. source: "" // Set via onPreviewChanged handler
  61. smooth: true
  62. cache: false // Disable caching to ensure images load properly with linuxfb
  63. asynchronous: true // Load images asynchronously
  64. // Loading animation
  65. opacity: status === Image.Ready ? 1 : 0
  66. Behavior on opacity {
  67. NumberAnimation { duration: 200 }
  68. }
  69. }
  70. // Placeholder when no preview
  71. Rectangle {
  72. anchors.fill: parent
  73. color: "#f0f0f0"
  74. visible: previewImage.status === Image.Error || previewImage.source == ""
  75. radius: 8
  76. Column {
  77. anchors.centerIn: parent
  78. spacing: 8
  79. Text {
  80. text: "◻"
  81. font.pixelSize: 32
  82. anchors.horizontalCenter: parent.horizontalCenter
  83. color: "#ddd"
  84. }
  85. Text {
  86. text: "No Preview"
  87. anchors.horizontalCenter: parent.horizontalCenter
  88. color: "#999"
  89. font.pixelSize: 12
  90. }
  91. }
  92. }
  93. }
  94. // Pattern name
  95. Label {
  96. id: nameLabel
  97. text: cleanName
  98. width: parent.width
  99. elide: Label.ElideRight
  100. horizontalAlignment: Label.AlignHCenter
  101. font.pixelSize: 13
  102. font.weight: Font.Medium
  103. color: "#333"
  104. wrapMode: Text.Wrap
  105. maximumLineCount: 2
  106. }
  107. }
  108. // Click area
  109. MouseArea {
  110. id: mouseArea
  111. anchors.fill: parent
  112. hoverEnabled: true
  113. onClicked: parent.clicked()
  114. // Ripple effect on click
  115. Rectangle {
  116. id: ripple
  117. width: 0
  118. height: 0
  119. radius: width / 2
  120. color: "#20000000"
  121. anchors.centerIn: parent
  122. NumberAnimation {
  123. id: rippleAnimation
  124. target: ripple
  125. property: "width"
  126. from: 0
  127. to: mouseArea.width * 1.5
  128. duration: 300
  129. easing.type: Easing.OutQuad
  130. onFinished: {
  131. ripple.width = 0
  132. ripple.height = 0
  133. }
  134. }
  135. Connections {
  136. target: mouseArea
  137. function onPressed() {
  138. ripple.height = ripple.width
  139. rippleAnimation.start()
  140. }
  141. }
  142. }
  143. }
  144. }