zui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. checksums.yaml +7 -0
  2. data/Components/Builtins/Accordion.qml +208 -0
  3. data/Components/Builtins/Action.qml +43 -0
  4. data/Components/Builtins/ActionButton.qml +19 -0
  5. data/Components/Builtins/ActionGroup.qml +81 -0
  6. data/Components/Builtins/AlertDialog.qml +398 -0
  7. data/Components/Builtins/AnchorAnimation.qml +3 -0
  8. data/Components/Builtins/AnchorChanges.qml +11 -0
  9. data/Components/Builtins/AnimatedImage.qml +39 -0
  10. data/Components/Builtins/Animation.qml +3 -0
  11. data/Components/Builtins/AnimationController.qml +11 -0
  12. data/Components/Builtins/ApplicationWindow.qml +103 -0
  13. data/Components/Builtins/AreaChart.qml +70 -0
  14. data/Components/Builtins/AspectRatio.qml +30 -0
  15. data/Components/Builtins/Audio.qml +85 -0
  16. data/Components/Builtins/AudioInput.qml +10 -0
  17. data/Components/Builtins/AudioOutput.qml +10 -0
  18. data/Components/Builtins/Avatar.qml +46 -0
  19. data/Components/Builtins/Badge.qml +38 -0
  20. data/Components/Builtins/Banner.qml +133 -0
  21. data/Components/Builtins/BarChart.qml +67 -0
  22. data/Components/Builtins/BarIconButton.qml +30 -0
  23. data/Components/Builtins/BarIndicator.qml +26 -0
  24. data/Components/Builtins/Behavior.qml +13 -0
  25. data/Components/Builtins/Blur.qml +14 -0
  26. data/Components/Builtins/BorderImage.qml +38 -0
  27. data/Components/Builtins/BorderOverlay.qml +25 -0
  28. data/Components/Builtins/BottomSheet.qml +211 -0
  29. data/Components/Builtins/Breadcrumb.qml +169 -0
  30. data/Components/Builtins/BubbleChart.qml +3 -0
  31. data/Components/Builtins/BusyIndicator.qml +24 -0
  32. data/Components/Builtins/Button.qml +55 -0
  33. data/Components/Builtins/ButtonGroup.qml +18 -0
  34. data/Components/Builtins/Calendar.qml +55 -0
  35. data/Components/Builtins/Camera.qml +18 -0
  36. data/Components/Builtins/CandlestickChart.qml +3 -0
  37. data/Components/Builtins/Canvas.qml +159 -0
  38. data/Components/Builtins/CaptureSession.qml +19 -0
  39. data/Components/Builtins/Card.qml +23 -0
  40. data/Components/Builtins/Carousel.qml +72 -0
  41. data/Components/Builtins/Center.qml +20 -0
  42. data/Components/Builtins/CheckDelegate.qml +132 -0
  43. data/Components/Builtins/Checkbox.qml +62 -0
  44. data/Components/Builtins/Chip.qml +65 -0
  45. data/Components/Builtins/Circle.qml +35 -0
  46. data/Components/Builtins/Clipboard.qml +29 -0
  47. data/Components/Builtins/ColorAnimation.qml +3 -0
  48. data/Components/Builtins/ColorPicker.qml +70 -0
  49. data/Components/Builtins/Colorize.qml +14 -0
  50. data/Components/Builtins/Column.qml +17 -0
  51. data/Components/Builtins/ColumnLayout.qml +13 -0
  52. data/Components/Builtins/ConfirmDialog.qml +20 -0
  53. data/Components/Builtins/ConstrainedBox.qml +28 -0
  54. data/Components/Builtins/Container.qml +30 -0
  55. data/Components/Builtins/ContextMenu.qml +140 -0
  56. data/Components/Builtins/CursorSurface.qml +18 -0
  57. data/Components/Builtins/DataTable.qml +69 -0
  58. data/Components/Builtins/DatePicker.qml +180 -0
  59. data/Components/Builtins/DayOfWeekRow.qml +11 -0
  60. data/Components/Builtins/DelayButton.qml +47 -0
  61. data/Components/Builtins/DelegateModel.qml +10 -0
  62. data/Components/Builtins/DelegateModelGroup.qml +10 -0
  63. data/Components/Builtins/Dial.qml +42 -0
  64. data/Components/Builtins/Dialog.qml +128 -0
  65. data/Components/Builtins/DialogButtonBox.qml +137 -0
  66. data/Components/Builtins/Divider.qml +26 -0
  67. data/Components/Builtins/DonutChart.qml +3 -0
  68. data/Components/Builtins/DoubleSpinBox.qml +58 -0
  69. data/Components/Builtins/DragArea.qml +43 -0
  70. data/Components/Builtins/Drawer.qml +107 -0
  71. data/Components/Builtins/DropArea.qml +19 -0
  72. data/Components/Builtins/DropShadow.qml +16 -0
  73. data/Components/Builtins/Dropdown.qml +19 -0
  74. data/Components/Builtins/ExpansionPanel.qml +157 -0
  75. data/Components/Builtins/FilePicker.qml +140 -0
  76. data/Components/Builtins/FittedBox.qml +40 -0
  77. data/Components/Builtins/Flickable.qml +40 -0
  78. data/Components/Builtins/Flipable.qml +45 -0
  79. data/Components/Builtins/Flow.qml +16 -0
  80. data/Components/Builtins/FocusScope.qml +29 -0
  81. data/Components/Builtins/FolderListModel.qml +9 -0
  82. data/Components/Builtins/FolderPicker.qml +93 -0
  83. data/Components/Builtins/FontLoader.qml +21 -0
  84. data/Components/Builtins/FontPicker.qml +91 -0
  85. data/Components/Builtins/Frame.qml +71 -0
  86. data/Components/Builtins/FrameAnimation.qml +13 -0
  87. data/Components/Builtins/Gauge.qml +3 -0
  88. data/Components/Builtins/Glow.qml +15 -0
  89. data/Components/Builtins/Gradient.qml +93 -0
  90. data/Components/Builtins/Grid.qml +16 -0
  91. data/Components/Builtins/GridLayout.qml +16 -0
  92. data/Components/Builtins/GridView.qml +226 -0
  93. data/Components/Builtins/GroupBox.qml +95 -0
  94. data/Components/Builtins/Heatmap.qml +3 -0
  95. data/Components/Builtins/Histogram.qml +3 -0
  96. data/Components/Builtins/HorizontalHeader.qml +23 -0
  97. data/Components/Builtins/HorizontalHeaderDelegate.qml +39 -0
  98. data/Components/Builtins/HoverArea.qml +19 -0
  99. data/Components/Builtins/Icon.qml +16 -0
  100. data/Components/Builtins/Image.qml +110 -0
  101. data/Components/Builtins/ImageCapture.qml +14 -0
  102. data/Components/Builtins/ItemDelegate.qml +152 -0
  103. data/Components/Builtins/KeyCatcher.qml +25 -0
  104. data/Components/Builtins/Label.qml +43 -0
  105. data/Components/Builtins/LayoutItemProxy.qml +51 -0
  106. data/Components/Builtins/Legend.qml +86 -0
  107. data/Components/Builtins/Line.qml +28 -0
  108. data/Components/Builtins/LineChart.qml +87 -0
  109. data/Components/Builtins/ListModel.qml +8 -0
  110. data/Components/Builtins/ListView.qml +65 -0
  111. data/Components/Builtins/Loader.qml +33 -0
  112. data/Components/Builtins/Markdown.qml +23 -0
  113. data/Components/Builtins/MediaDevices.qml +10 -0
  114. data/Components/Builtins/MediaPlayer.qml +27 -0
  115. data/Components/Builtins/MediaRecorder.qml +16 -0
  116. data/Components/Builtins/Menu.qml +119 -0
  117. data/Components/Builtins/MenuBar.qml +128 -0
  118. data/Components/Builtins/MenuItem.qml +77 -0
  119. data/Components/Builtins/MenuSeparator.qml +30 -0
  120. data/Components/Builtins/MessageDialog.qml +104 -0
  121. data/Components/Builtins/ModalSheet.qml +222 -0
  122. data/Components/Builtins/ModelView3d.qml +50 -0
  123. data/Components/Builtins/MonthGrid.qml +23 -0
  124. data/Components/Builtins/MultiEffect.qml +48 -0
  125. data/Components/Builtins/MultiSelect.qml +23 -0
  126. data/Components/Builtins/NavigationRail.qml +154 -0
  127. data/Components/Builtins/NumberAnimation.qml +3 -0
  128. data/Components/Builtins/NumberField.qml +18 -0
  129. data/Components/Builtins/OpacityAnimator.qml +3 -0
  130. data/Components/Builtins/OpacityMask.qml +21 -0
  131. data/Components/Builtins/OpticalGlyph.qml +16 -0
  132. data/Components/Builtins/Page.qml +111 -0
  133. data/Components/Builtins/PageIndicator.qml +63 -0
  134. data/Components/Builtins/Pagination.qml +158 -0
  135. data/Components/Builtins/Pane.qml +72 -0
  136. data/Components/Builtins/PanelHero.qml +15 -0
  137. data/Components/Builtins/ParallelAnimation.qml +3 -0
  138. data/Components/Builtins/ParentAnimation.qml +3 -0
  139. data/Components/Builtins/ParentChange.qml +10 -0
  140. data/Components/Builtins/ParticleSystem.qml +81 -0
  141. data/Components/Builtins/PasswordField.qml +58 -0
  142. data/Components/Builtins/Path.qml +35 -0
  143. data/Components/Builtins/PathAnimation.qml +3 -0
  144. data/Components/Builtins/PauseAnimation.qml +3 -0
  145. data/Components/Builtins/PieChart.qml +3 -0
  146. data/Components/Builtins/PinchArea.qml +23 -0
  147. data/Components/Builtins/Popup.qml +130 -0
  148. data/Components/Builtins/Progress.qml +15 -0
  149. data/Components/Builtins/ProgressRing.qml +120 -0
  150. data/Components/Builtins/PropertyAction.qml +11 -0
  151. data/Components/Builtins/PropertyAnimation.qml +3 -0
  152. data/Components/Builtins/PropertyChanges.qml +10 -0
  153. data/Components/Builtins/RadarChart.qml +3 -0
  154. data/Components/Builtins/RadialGauge.qml +3 -0
  155. data/Components/Builtins/RadioButton.qml +46 -0
  156. data/Components/Builtins/RadioDelegate.qml +115 -0
  157. data/Components/Builtins/RadioGroup.qml +58 -0
  158. data/Components/Builtins/RangeSlider.qml +39 -0
  159. data/Components/Builtins/Rectangle.qml +23 -0
  160. data/Components/Builtins/RectangularShadow.qml +23 -0
  161. data/Components/Builtins/ReorderableList.qml +204 -0
  162. data/Components/Builtins/RichText.qml +23 -0
  163. data/Components/Builtins/RotationAnimation.qml +3 -0
  164. data/Components/Builtins/RotationAnimator.qml +3 -0
  165. data/Components/Builtins/RoundButton.qml +42 -0
  166. data/Components/Builtins/Row.qml +17 -0
  167. data/Components/Builtins/RowLayout.qml +13 -0
  168. data/Components/Builtins/ScaleAnimator.qml +3 -0
  169. data/Components/Builtins/ScatterChart.qml +3 -0
  170. data/Components/Builtins/ScreenCapture.qml +78 -0
  171. data/Components/Builtins/ScriptAction.qml +15 -0
  172. data/Components/Builtins/Scroll.qml +18 -0
  173. data/Components/Builtins/ScrollBar.qml +18 -0
  174. data/Components/Builtins/ScrollIndicator.qml +15 -0
  175. data/Components/Builtins/SearchField.qml +178 -0
  176. data/Components/Builtins/SearchableDropdown.qml +21 -0
  177. data/Components/Builtins/SectionHeader.qml +14 -0
  178. data/Components/Builtins/SelectableText.qml +33 -0
  179. data/Components/Builtins/SelectionRectangle.qml +17 -0
  180. data/Components/Builtins/Separator.qml +13 -0
  181. data/Components/Builtins/SequentialAnimation.qml +3 -0
  182. data/Components/Builtins/Settings.qml +10 -0
  183. data/Components/Builtins/ShaderEffect.qml +115 -0
  184. data/Components/Builtins/ShaderEffectSource.qml +61 -0
  185. data/Components/Builtins/Shaders/grayscale.frag +14 -0
  186. data/Components/Builtins/Shaders/grayscale.frag.qsb +0 -0
  187. data/Components/Builtins/Shaders/passthrough.frag +11 -0
  188. data/Components/Builtins/Shaders/passthrough.frag.qsb +0 -0
  189. data/Components/Builtins/Shaders/pixelate.frag +16 -0
  190. data/Components/Builtins/Shaders/pixelate.frag.qsb +0 -0
  191. data/Components/Builtins/Shaders/vignette.frag +18 -0
  192. data/Components/Builtins/Shaders/vignette.frag.qsb +0 -0
  193. data/Components/Builtins/Shaders/wave.frag +18 -0
  194. data/Components/Builtins/Shaders/wave.frag.qsb +0 -0
  195. data/Components/Builtins/Shape.qml +53 -0
  196. data/Components/Builtins/Skeleton.qml +78 -0
  197. data/Components/Builtins/Slider.qml +21 -0
  198. data/Components/Builtins/SmoothedAnimation.qml +3 -0
  199. data/Components/Builtins/Snackbar.qml +181 -0
  200. data/Components/Builtins/SortFilterProxyModel.qml +16 -0
  201. data/Components/Builtins/SoundEffect.qml +10 -0
  202. data/Components/Builtins/Spacer.qml +13 -0
  203. data/Components/Builtins/Sparkline.qml +3 -0
  204. data/Components/Builtins/SpinBox.qml +44 -0
  205. data/Components/Builtins/SplitView.qml +31 -0
  206. data/Components/Builtins/SpringAnimation.qml +3 -0
  207. data/Components/Builtins/Stack.qml +14 -0
  208. data/Components/Builtins/StackLayout.qml +19 -0
  209. data/Components/Builtins/StackView.qml +122 -0
  210. data/Components/Builtins/StackedBarChart.qml +3 -0
  211. data/Components/Builtins/StandardPaths.qml +9 -0
  212. data/Components/Builtins/State.qml +13 -0
  213. data/Components/Builtins/StateGroup.qml +11 -0
  214. data/Components/Builtins/Support/AnimationDriver.qml +79 -0
  215. data/Components/Builtins/Support/AnimationGroupDriver.qml +32 -0
  216. data/Components/Builtins/Support/ChartCanvas.qml +629 -0
  217. data/Components/Builtins/Support/ModelView3dScene.qml +292 -0
  218. data/Components/Builtins/Support/OptionalModuleState.js +5 -0
  219. data/Components/Builtins/SwipeDelegate.qml +231 -0
  220. data/Components/Builtins/SwipeView.qml +69 -0
  221. data/Components/Builtins/SwitchDelegate.qml +140 -0
  222. data/Components/Builtins/TabBar.qml +117 -0
  223. data/Components/Builtins/TabButton.qml +105 -0
  224. data/Components/Builtins/TableView.qml +388 -0
  225. data/Components/Builtins/TableViewDelegate.qml +17 -0
  226. data/Components/Builtins/Tabs.qml +138 -0
  227. data/Components/Builtins/Text.qml +24 -0
  228. data/Components/Builtins/TextArea.qml +59 -0
  229. data/Components/Builtins/TextField.qml +21 -0
  230. data/Components/Builtins/TextMetrics.qml +39 -0
  231. data/Components/Builtins/TimePicker.qml +213 -0
  232. data/Components/Builtins/Timer.qml +13 -0
  233. data/Components/Builtins/Toast.qml +213 -0
  234. data/Components/Builtins/Toggle.qml +19 -0
  235. data/Components/Builtins/ToggleSwitch.qml +22 -0
  236. data/Components/Builtins/ToolBar.qml +61 -0
  237. data/Components/Builtins/ToolButton.qml +41 -0
  238. data/Components/Builtins/ToolSeparator.qml +36 -0
  239. data/Components/Builtins/Tooltip.qml +20 -0
  240. data/Components/Builtins/Transition.qml +3 -0
  241. data/Components/Builtins/TreeView.qml +423 -0
  242. data/Components/Builtins/TreeViewDelegate.qml +46 -0
  243. data/Components/Builtins/Tumbler.qml +18 -0
  244. data/Components/Builtins/UniformAnimator.qml +3 -0
  245. data/Components/Builtins/VectorAnimation.qml +3 -0
  246. data/Components/Builtins/VectorImage.qml +62 -0
  247. data/Components/Builtins/VerticalHeader.qml +21 -0
  248. data/Components/Builtins/VerticalHeaderDelegate.qml +35 -0
  249. data/Components/Builtins/Video.qml +54 -0
  250. data/Components/Builtins/VideoOutput.qml +54 -0
  251. data/Components/Builtins/WebView.qml +57 -0
  252. data/Components/Builtins/WeekNumberColumn.qml +13 -0
  253. data/Components/Builtins/WidgetButton.qml +26 -0
  254. data/Components/Builtins/Window.qml +90 -0
  255. data/Components/Builtins/WindowCapture.qml +11 -0
  256. data/Components/Builtins/Wrap.qml +18 -0
  257. data/Components/Builtins/XAnimator.qml +3 -0
  258. data/Components/Builtins/YAnimator.qml +3 -0
  259. data/Components/README.md +45 -0
  260. data/ControlNode.qml +1369 -0
  261. data/Controls/BarIconButton.qml +27 -0
  262. data/Controls/BarIndicator.qml +22 -0
  263. data/Controls/BorderOverlay.qml +10 -0
  264. data/Controls/BorderSurface.qml +10 -0
  265. data/Controls/Button.qml +78 -0
  266. data/Controls/ButtonGroup.qml +19 -0
  267. data/Controls/ConfirmDialog.qml +37 -0
  268. data/Controls/CursorSurface.qml +29 -0
  269. data/Controls/Dropdown.qml +59 -0
  270. data/Controls/MultiSelect.qml +32 -0
  271. data/Controls/NumberField.qml +24 -0
  272. data/Controls/OpticalGlyph.qml +14 -0
  273. data/Controls/PanelActionButton.qml +10 -0
  274. data/Controls/PanelHero.qml +18 -0
  275. data/Controls/PanelKeyCatcher.qml +25 -0
  276. data/Controls/PanelSectionHeader.qml +11 -0
  277. data/Controls/PanelSeparator.qml +10 -0
  278. data/Controls/PanelSlider.qml +36 -0
  279. data/Controls/PanelToolTip.qml +13 -0
  280. data/Controls/SearchableDropdown.qml +11 -0
  281. data/Controls/TextField.qml +25 -0
  282. data/Controls/Toggle.qml +22 -0
  283. data/Controls/ToggleSwitch.qml +26 -0
  284. data/Controls/WidgetButton.qml +35 -0
  285. data/Controls/qmldir +25 -0
  286. data/Desktop.qml +76 -0
  287. data/LICENSE +22 -0
  288. data/README.md +112 -0
  289. data/Service.qml +430 -0
  290. data/Theme/Border.qml +22 -0
  291. data/Theme/Color.qml +22 -0
  292. data/Theme/Style.qml +47 -0
  293. data/Theme/Util.qml +6 -0
  294. data/Theme/qmldir +5 -0
  295. data/bin/zui +7 -0
  296. data/lib/zui/animation.rb +24 -0
  297. data/lib/zui/application.rb +327 -0
  298. data/lib/zui/builder.rb +725 -0
  299. data/lib/zui/cli.rb +91 -0
  300. data/lib/zui/command.rb +101 -0
  301. data/lib/zui/component_registry.rb +91 -0
  302. data/lib/zui/components.rb +262 -0
  303. data/lib/zui/distribution.rb +200 -0
  304. data/lib/zui/generator.rb +84 -0
  305. data/lib/zui/host.rb +123 -0
  306. data/lib/zui/node.rb +30 -0
  307. data/lib/zui/platform.rb +40 -0
  308. data/lib/zui/protocol.rb +29 -0
  309. data/lib/zui/runner.rb +37 -0
  310. data/lib/zui/runtime.rb +23 -0
  311. data/lib/zui/scheduler.rb +136 -0
  312. data/lib/zui/source_bundle.rb +63 -0
  313. data/lib/zui/state_store.rb +100 -0
  314. data/lib/zui/value.rb +44 -0
  315. data/lib/zui.rb +33 -0
  316. data/native/CMakeLists.txt +45 -0
  317. data/native/ZuiClipboard.cpp +16 -0
  318. data/native/ZuiClipboard.h +16 -0
  319. data/native/ZuiProcess.cpp +84 -0
  320. data/native/ZuiProcess.h +34 -0
  321. data/native/main.cpp +64 -0
  322. data/vendor/host/linux-x86_64/PROVENANCE.md +15 -0
  323. data/vendor/host/linux-x86_64/zui-host +0 -0
  324. data/vendor/host/linux-x86_64/zui-host.sha256 +1 -0
  325. metadata +365 -0
@@ -0,0 +1,398 @@
1
+ import QtQuick
2
+ import QtQuick.Controls as QQC
3
+ import "../../Theme"
4
+ import "../../Controls" as ZuiControls
5
+
6
+ QQC.Dialog {
7
+ id: alertRoot
8
+
9
+ required property var renderer
10
+ readonly property bool requestedOpen: renderer.prop("opened", false) === true && renderer.prop("visible", true) !== false
11
+ readonly property string severity: String(renderer.prop("severity", "info"))
12
+ readonly property string imageSource: String(renderer.prop("image", renderer.prop("image_source", "")))
13
+ readonly property var buttonNames: normalizedButtonNames()
14
+ readonly property bool centered: renderer.prop("centered", true) !== false
15
+ readonly property bool hasExplicitX: renderer.node && renderer.node.props && renderer.node.props.x !== undefined
16
+ readonly property bool hasExplicitY: renderer.node && renderer.node.props && renderer.node.props.y !== undefined
17
+
18
+ function severityIcon() {
19
+ var requested = String(renderer.prop("icon", ""));
20
+ if (requested !== "")
21
+ return requested;
22
+
23
+ if (severity === "success")
24
+ return "check";
25
+
26
+ if (severity === "warning")
27
+ return "warning";
28
+
29
+ if (severity === "error" || severity === "critical")
30
+ return "xmark";
31
+
32
+ return "info";
33
+ }
34
+
35
+ function severityColor() {
36
+ if (severity === "success")
37
+ return renderer.prop("success_color", renderer.prop("accent", Color.accent));
38
+
39
+ if (severity === "warning")
40
+ return renderer.prop("warning_color", "#d8a657");
41
+
42
+ if (severity === "error" || severity === "critical")
43
+ return renderer.prop("error_color", Color.urgent);
44
+
45
+ return renderer.prop("accent", Color.accent);
46
+ }
47
+
48
+ function normalizedButtonNames() {
49
+ var requested = renderer.prop("standard_buttons", ["ok"]);
50
+ var values = Array.isArray(requested) ? requested : [requested];
51
+ return values.map(function(value) {
52
+ return String(value || "").toLowerCase();
53
+ }).filter(function(value) {
54
+ return value !== "";
55
+ });
56
+ }
57
+
58
+ function buttonText(name) {
59
+ var labels = renderer.prop("button_labels", {
60
+ });
61
+ if (labels && labels[name] !== undefined)
62
+ return String(labels[name]);
63
+
64
+ var names = {
65
+ "ok": "OK",
66
+ "save": "Save",
67
+ "save_all": "Save All",
68
+ "open": "Open",
69
+ "yes": "Yes",
70
+ "yes_to_all": "Yes to All",
71
+ "no": "No",
72
+ "no_to_all": "No to All",
73
+ "abort": "Abort",
74
+ "retry": "Retry",
75
+ "ignore": "Ignore",
76
+ "close": "Close",
77
+ "cancel": "Cancel",
78
+ "discard": "Discard",
79
+ "help": "Help",
80
+ "apply": "Apply",
81
+ "reset": "Reset",
82
+ "restore_defaults": "Restore Defaults"
83
+ };
84
+ return names[name] || name;
85
+ }
86
+
87
+ function isPrimaryButton(name) {
88
+ return ["ok", "save", "save_all", "open", "yes", "yes_to_all", "retry", "apply"].indexOf(name) >= 0;
89
+ }
90
+
91
+ function activateButton(name) {
92
+ if (name === "apply") {
93
+ renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "apply", {
94
+ });
95
+ } else if (name === "reset" || name === "restore_defaults") {
96
+ renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "reset", {
97
+ });
98
+ } else if (name === "help") {
99
+ renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "help", {
100
+ });
101
+ } else if (name === "discard") {
102
+ renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "discard", {
103
+ });
104
+ close();
105
+ } else if (["no", "no_to_all", "abort", "close", "cancel"].indexOf(name) >= 0) {
106
+ reject();
107
+ } else {
108
+ accept();
109
+ }
110
+ }
111
+
112
+ function fillModeValue(value) {
113
+ var mode = String(value || "preserve_aspect_fit");
114
+ if (mode === "stretch")
115
+ return Image.Stretch;
116
+
117
+ if (mode === "preserve_aspect_crop" || mode === "crop" || mode === "cover")
118
+ return Image.PreserveAspectCrop;
119
+
120
+ if (mode === "tile")
121
+ return Image.Tile;
122
+
123
+ if (mode === "tile_vertically" || mode === "tile_vertical")
124
+ return Image.TileVertically;
125
+
126
+ if (mode === "tile_horizontally" || mode === "tile_horizontal")
127
+ return Image.TileHorizontally;
128
+
129
+ if (mode === "pad")
130
+ return Image.Pad;
131
+
132
+ return Image.PreserveAspectFit;
133
+ }
134
+
135
+ function closePolicyValue(value) {
136
+ var names = Array.isArray(value) ? value : [value || "escape"];
137
+ var result = 0;
138
+ for (var index = 0; index < names.length; index++) {
139
+ var name = String(names[index]);
140
+ if (name === "escape")
141
+ result |= QQC.Popup.CloseOnEscape;
142
+
143
+ if (name === "outside")
144
+ result |= QQC.Popup.CloseOnPressOutside;
145
+
146
+ if (name === "outside_parent")
147
+ result |= QQC.Popup.CloseOnPressOutsideParent;
148
+
149
+ }
150
+ return result;
151
+ }
152
+
153
+ function syncOpenState() {
154
+ if (requestedOpen === opened)
155
+ return ;
156
+
157
+ if (requestedOpen)
158
+ open();
159
+ else
160
+ close();
161
+ }
162
+
163
+ title: String(renderer.prop("title", ""))
164
+ standardButtons: QQC.Dialog.NoButton
165
+ parent: QQC.Overlay.overlay
166
+ x: hasExplicitX ? Number(renderer.prop("x", 0)) : (centered && parent ? Math.round((parent.width - width) / 2) : 0)
167
+ y: hasExplicitY ? Number(renderer.prop("y", 0)) : (centered && parent ? Math.round((parent.height - height) / 2) : 0)
168
+ width: Number(renderer.prop("width", 500))
169
+ height: Number(renderer.prop("height", 360))
170
+ modal: renderer.prop("modal", true) !== false
171
+ dim: renderer.prop("dim", modal) !== false
172
+ focus: renderer.prop("focus", true) !== false
173
+ closePolicy: closePolicyValue(renderer.prop("close_policy", "escape"))
174
+ enabled: renderer.prop("enabled", true) !== false
175
+ padding: Number(renderer.prop("padding", Style.spacing.lg))
176
+ font.family: String(renderer.prop("font_family", renderer.fontFamily))
177
+ font.pixelSize: Number(renderer.prop("font_size", Style.font.body))
178
+ Component.onCompleted: syncOpenState()
179
+ onRequestedOpenChanged: syncOpenState()
180
+ onAccepted: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "accept", {
181
+ })
182
+ onRejected: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "reject", {
183
+ })
184
+ onOpened: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "open", {
185
+ })
186
+ onClosed: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "close", {
187
+ })
188
+ onAboutToShow: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "about_to_show", {
189
+ })
190
+ onAboutToHide: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "about_to_hide", {
191
+ })
192
+ onVisibleChanged: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, visible ? "show" : "hide", {
193
+ })
194
+ onActiveFocusChanged: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, activeFocus ? "focus" : "blur", {
195
+ })
196
+
197
+ background: Rectangle {
198
+ color: renderer.prop("background", Color.background)
199
+ radius: Number(renderer.prop("radius", Style.cornerRadius))
200
+ border.width: String(renderer.prop("border_color", "")).length > 0 ? Style.normalBorderWidth : 0
201
+ border.color: renderer.prop("border_color", "transparent")
202
+ }
203
+
204
+ header: Rectangle {
205
+ implicitHeight: alertRoot.title.length > 0 ? Number(renderer.prop("header_height", 48)) : 0
206
+ color: renderer.prop("header_background", renderer.prop("background", Color.background))
207
+ radius: Number(renderer.prop("radius", Style.cornerRadius))
208
+
209
+ Text {
210
+ anchors.left: parent.left
211
+ anchors.right: parent.right
212
+ anchors.leftMargin: Number(renderer.prop("padding", Style.spacing.lg))
213
+ anchors.rightMargin: Number(renderer.prop("padding", Style.spacing.lg))
214
+ anchors.verticalCenter: parent.verticalCenter
215
+ text: alertRoot.title
216
+ color: renderer.prop("foreground", renderer.foreground)
217
+ font.family: String(renderer.prop("font_family", renderer.fontFamily))
218
+ font.pixelSize: Number(renderer.prop("title_size", Style.font.body))
219
+ font.bold: true
220
+ elide: Text.ElideRight
221
+ }
222
+
223
+ Rectangle {
224
+ anchors.left: parent.left
225
+ anchors.right: parent.right
226
+ anchors.bottom: parent.bottom
227
+ height: Style.normalBorderWidth
228
+ color: renderer.prop("border_color", Qt.rgba(renderer.foreground.r, renderer.foreground.g, renderer.foreground.b, 0.2))
229
+ }
230
+
231
+ }
232
+
233
+ contentItem: Column {
234
+ spacing: Number(renderer.prop("spacing", Style.spacing.md))
235
+
236
+ Row {
237
+ id: messageRow
238
+
239
+ width: parent.width
240
+ height: Math.max(iconFrame.visible ? iconFrame.height : 0, messageText.implicitHeight)
241
+ spacing: Number(renderer.prop("spacing", Style.spacing.md))
242
+
243
+ Item {
244
+ id: iconFrame
245
+
246
+ width: Number(renderer.prop("icon_size", 32))
247
+ height: width
248
+ visible: renderer.prop("show_icon", true) !== false
249
+ anchors.verticalCenter: parent.verticalCenter
250
+
251
+ Rectangle {
252
+ anchors.fill: parent
253
+ radius: width / 2
254
+ color: alertRoot.severityColor()
255
+ }
256
+
257
+ Text {
258
+ anchors.centerIn: parent
259
+ text: renderer.iconGlyph(alertRoot.severityIcon())
260
+ color: renderer.prop("icon_foreground", Color.background)
261
+ font.family: renderer.fontFamily
262
+ font.pixelSize: Math.max(10, parent.width * 0.5)
263
+ horizontalAlignment: Text.AlignHCenter
264
+ verticalAlignment: Text.AlignVCenter
265
+ }
266
+
267
+ }
268
+
269
+ Text {
270
+ id: messageText
271
+
272
+ width: Math.max(0, parent.width - (iconFrame.visible ? iconFrame.width + parent.spacing : 0))
273
+ anchors.verticalCenter: parent.verticalCenter
274
+ text: String(renderer.prop("message", ""))
275
+ color: renderer.prop("foreground", renderer.foreground)
276
+ font.family: String(renderer.prop("font_family", renderer.fontFamily))
277
+ font.pixelSize: Number(renderer.prop("message_size", Style.font.heading))
278
+ font.bold: true
279
+ wrapMode: Text.Wrap
280
+ }
281
+
282
+ }
283
+
284
+ Rectangle {
285
+ id: imageFrame
286
+
287
+ width: {
288
+ var requested = Number(renderer.prop("image_width", 0));
289
+ return requested > 0 ? Math.min(parent.width, requested) : parent.width;
290
+ }
291
+ height: Number(renderer.prop("image_height", 160))
292
+ anchors.horizontalCenter: parent.horizontalCenter
293
+ visible: alertRoot.imageSource !== ""
294
+ color: "transparent"
295
+ radius: Number(renderer.prop("image_radius", renderer.prop("radius", Style.cornerRadius)))
296
+ clip: true
297
+
298
+ Image {
299
+ anchors.fill: parent
300
+ source: renderer.assetUrl(alertRoot.imageSource)
301
+ fillMode: alertRoot.fillModeValue(renderer.prop("image_fill_mode", "preserve_aspect_fit"))
302
+ asynchronous: renderer.prop("image_asynchronous", true) !== false
303
+ cache: renderer.prop("image_cache", true) !== false
304
+ smooth: true
305
+ onStatusChanged: {
306
+ if (status === Image.Error)
307
+ renderer.componentError("alert_dialog_image_failed", "Unable to load the declared alert dialog image", {
308
+ "source": String(source)
309
+ });
310
+ }
311
+ }
312
+
313
+ }
314
+
315
+ Text {
316
+ width: parent.width
317
+ visible: text.length > 0
318
+ text: String(renderer.prop("informative_text", ""))
319
+ color: renderer.prop("muted", Color.muted)
320
+ font.family: String(renderer.prop("font_family", renderer.fontFamily))
321
+ font.pixelSize: Number(renderer.prop("font_size", Style.font.body))
322
+ wrapMode: Text.Wrap
323
+ }
324
+
325
+ QQC.ScrollView {
326
+ width: parent.width
327
+ height: Number(renderer.prop("details_height", 120))
328
+ visible: String(renderer.prop("detailed_text", "")).length > 0
329
+ clip: true
330
+
331
+ QQC.TextArea {
332
+ text: String(renderer.prop("detailed_text", ""))
333
+ readOnly: true
334
+ selectByMouse: true
335
+ wrapMode: TextEdit.Wrap
336
+ color: renderer.prop("foreground", renderer.foreground)
337
+ font.family: String(renderer.prop("font_family", renderer.fontFamily))
338
+ font.pixelSize: Number(renderer.prop("details_size", Style.font.caption))
339
+ }
340
+
341
+ }
342
+
343
+ }
344
+
345
+ footer: Rectangle {
346
+ implicitHeight: alertRoot.buttonNames.length > 0 ? Number(renderer.prop("footer_height", 62)) : 0
347
+ color: renderer.prop("footer_background", renderer.prop("background", Color.background))
348
+
349
+ Rectangle {
350
+ anchors.left: parent.left
351
+ anchors.right: parent.right
352
+ anchors.top: parent.top
353
+ height: Style.normalBorderWidth
354
+ color: renderer.prop("border_color", Qt.rgba(renderer.foreground.r, renderer.foreground.g, renderer.foreground.b, 0.2))
355
+ }
356
+
357
+ Row {
358
+ id: buttonRow
359
+
360
+ readonly property string alignment: String(renderer.prop("button_alignment", "right"))
361
+
362
+ anchors.left: alignment === "left" || alignment === "start" ? parent.left : undefined
363
+ anchors.right: alignment === "right" || alignment === "end" ? parent.right : undefined
364
+ anchors.horizontalCenter: alignment === "center" ? parent.horizontalCenter : undefined
365
+ anchors.leftMargin: Number(renderer.prop("padding", Style.spacing.lg))
366
+ anchors.rightMargin: Number(renderer.prop("padding", Style.spacing.lg))
367
+ anchors.verticalCenter: parent.verticalCenter
368
+ spacing: Number(renderer.prop("button_spacing", Style.spacing.sm))
369
+
370
+ Repeater {
371
+ model: alertRoot.buttonNames
372
+
373
+ delegate: ZuiControls.Button {
374
+ required property string modelData
375
+ readonly property bool primary: alertRoot.isPrimaryButton(modelData)
376
+
377
+ text: alertRoot.buttonText(modelData)
378
+ iconText: primary && modelData === "ok" ? renderer.iconGlyph("check") : ""
379
+ foreground: renderer.prop("button_foreground", renderer.prop("foreground", renderer.foreground))
380
+ background: primary ? renderer.prop("button_background", "transparent") : "transparent"
381
+ accent: renderer.prop("button_accent", renderer.prop("accent", Color.accent))
382
+ fontFamily: String(renderer.prop("font_family", renderer.fontFamily))
383
+ fontSize: Number(renderer.prop("font_size", Style.font.body))
384
+ focusable: true
385
+ bordered: !primary
386
+ active: primary
387
+ horizontalPadding: Number(renderer.prop("button_horizontal_padding", Style.spacing.controlPaddingX))
388
+ verticalPadding: Number(renderer.prop("button_vertical_padding", Style.spacing.controlPaddingY))
389
+ onClicked: alertRoot.activateButton(modelData)
390
+ }
391
+
392
+ }
393
+
394
+ }
395
+
396
+ }
397
+
398
+ }
@@ -0,0 +1,3 @@
1
+ import QtQuick
2
+ import "Support" as Support
3
+ Support.AnimationDriver { renderer: null; animationType: "anchor" }
@@ -0,0 +1,11 @@
1
+ import QtQuick
2
+
3
+ Item {
4
+ id: changesRoot
5
+ property var renderer: null
6
+ property int handledRevision: -1
7
+ function line(target,key){var value=renderer.prop("anchors",{})[key];if(value===undefined||value===null||String(value)==="")return undefined;var item=renderer.findRenderedItem(value);if(!item)return undefined;if(key==="left"||key==="right"||key==="horizontal_center")return key==="left"?item.left:(key==="right"?item.right:item.horizontalCenter);return key==="top"?item.top:(key==="bottom"?item.bottom:item.verticalCenter)}
8
+ function apply(){if(!renderer)return;var revision=Number(renderer.prop("revision",0));if(revision===handledRevision)return;var target=renderer.findRenderedItem(renderer.prop("target",""));if(!target)return;handledRevision=revision;var anchors=renderer.prop("anchors",{});if(anchors.left!==undefined)target.anchors.left=line(target,"left");if(anchors.right!==undefined)target.anchors.right=line(target,"right");if(anchors.top!==undefined)target.anchors.top=line(target,"top");if(anchors.bottom!==undefined)target.anchors.bottom=line(target,"bottom");if(anchors.horizontal_center!==undefined)target.anchors.horizontalCenter=line(target,"horizontal_center");if(anchors.vertical_center!==undefined)target.anchors.verticalCenter=line(target,"vertical_center");var margins=renderer.prop("margins",{});for(var key in margins){var property=key.replace(/_([a-z])/g,function(_,letter){return letter.toUpperCase()});if(target.anchors.hasOwnProperty(property))target.anchors[property]=margins[key]}renderer.bridge.sendEvent(renderer.surfaceName,renderer.controlId,"apply",{revision:revision})}
9
+ Connections{target:renderer;function onNodeChanged(){changesRoot.apply()}}
10
+ Component.onCompleted:apply()
11
+ }
@@ -0,0 +1,39 @@
1
+ import QtQuick
2
+ import QtQuick.Controls as QQC
3
+ import QtQuick.Layouts
4
+ import QtMultimedia
5
+ import QtQuick.VectorImage
6
+ import "../../Theme"
7
+ import "../../Controls" as ZuiControls
8
+
9
+ AnimatedImage {
10
+ required property var renderer
11
+ source: String(renderer.prop("source", ""))
12
+ width: Number(renderer.prop("width", sourceSize.width > 0 ? sourceSize.width : 120))
13
+ height: Number(renderer.prop("height", sourceSize.height > 0 ? sourceSize.height : 120))
14
+ fillMode: {
15
+ var mode = String(renderer.prop("fill_mode", "contain"))
16
+ if (mode === "cover") return Image.PreserveAspectCrop
17
+ if (mode === "stretch") return Image.Stretch
18
+ if (mode === "tile") return Image.Tile
19
+ if (mode === "tile_horizontal") return Image.TileHorizontally
20
+ if (mode === "tile_vertical") return Image.TileVertically
21
+ if (mode === "pad") return Image.Pad
22
+ return Image.PreserveAspectFit
23
+ }
24
+ playing: renderer.prop("playing", true) !== false
25
+ paused: renderer.prop("paused", false) === true
26
+ speed: Number(renderer.prop("speed", 1))
27
+ asynchronous: renderer.prop("asynchronous", true) !== false
28
+ cache: renderer.prop("cache", true) !== false
29
+ mirror: renderer.prop("mirror", false) === true
30
+ smooth: renderer.prop("smooth", true) !== false
31
+ onCurrentFrameChanged: {
32
+ if (renderer.subscribed("frame")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "frame", { value: currentFrame, count: frameCount })
33
+ }
34
+ onStatusChanged: {
35
+ if (renderer.subscribed("status")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "status", { value: status })
36
+ if (status === AnimatedImage.Ready && renderer.subscribed("loaded")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "loaded", { width: sourceSize.width, height: sourceSize.height, frames: frameCount })
37
+ if (status === AnimatedImage.Error) renderer.componentError("animated_image_load_failed", "Unable to load the declared animated image", { source: String(source) })
38
+ }
39
+ }
@@ -0,0 +1,3 @@
1
+ import QtQuick
2
+ import "Support" as Support
3
+ Support.AnimationDriver { renderer: null; animationType: "property" }
@@ -0,0 +1,11 @@
1
+ import QtQuick
2
+
3
+ Item {
4
+ id: controllerRoot
5
+ property var renderer: null
6
+ function option(name,fallback){var specification=renderer?renderer.prop("animation",{}):{};return specification&&specification[name]!==undefined?specification[name]:(renderer?renderer.prop(name,fallback):fallback)}
7
+ readonly property var targetItem: renderer ? renderer.findRenderedItem(option("target", "")) : null
8
+ NumberAnimation { id: controlledAnimation; target: controllerRoot.targetItem; property: String(controllerRoot.option("property", "opacity")); from: Number(controllerRoot.option("from", 0)); to: Number(controllerRoot.option("to", 1)); duration: Number(controllerRoot.option("duration", 1000)) }
9
+ AnimationController { id: nativeController; animation: controlledAnimation; progress: Number(renderer ? renderer.prop("progress", 0) : 0); onProgressChanged: { renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "progress_change", { value: progress }); if(progress>=1)renderer.bridge.sendEvent(renderer.surfaceName,renderer.controlId,"finish",{}) } }
10
+ Connections { target: renderer; function onNodeChanged(){nativeController.progress=Number(renderer.prop("progress",0));if(renderer.prop("reload",false)===true)nativeController.reload()} }
11
+ }
@@ -0,0 +1,103 @@
1
+ import QtQuick
2
+ import QtQuick.Controls as QQC
3
+ import QtQuick.Window
4
+
5
+ QQC.ApplicationWindow {
6
+ id: nativeWindow
7
+
8
+ required property var renderer
9
+
10
+ function visibilityValue(value) {
11
+ var name = String(value || "automatic")
12
+ if (name === "hidden") return Window.Hidden
13
+ if (name === "minimized") return Window.Minimized
14
+ if (name === "maximized") return Window.Maximized
15
+ if (name === "fullscreen" || name === "full_screen") return Window.FullScreen
16
+ if (name === "windowed") return Window.Windowed
17
+ return Window.AutomaticVisibility
18
+ }
19
+
20
+ function modalityValue(value) {
21
+ var name = String(value || "none")
22
+ if (name === "window" || name === "window_modal") return Qt.WindowModal
23
+ if (name === "application" || name === "application_modal") return Qt.ApplicationModal
24
+ return Qt.NonModal
25
+ }
26
+
27
+ function flagsValue(value) {
28
+ if (typeof value === "number") return value
29
+ var names = Array.isArray(value) ? value : [value || "window"]
30
+ var result = 0
31
+ for (var index = 0; index < names.length; index++) {
32
+ var name = String(names[index])
33
+ if (name === "dialog") result |= Qt.Dialog
34
+ else if (name === "sheet") result |= Qt.Sheet
35
+ else if (name === "drawer") result |= Qt.Drawer
36
+ else if (name === "popup") result |= Qt.Popup
37
+ else if (name === "tool") result |= Qt.Tool
38
+ else if (name === "tooltip") result |= Qt.ToolTip
39
+ else if (name === "splash") result |= Qt.SplashScreen
40
+ else if (name === "frameless") result |= Qt.FramelessWindowHint
41
+ else if (name === "stay_on_top") result |= Qt.WindowStaysOnTopHint
42
+ else if (name === "stay_on_bottom") result |= Qt.WindowStaysOnBottomHint
43
+ else result |= Qt.Window
44
+ }
45
+ return result || Qt.Window
46
+ }
47
+
48
+ function orientationValue(value) {
49
+ var name = String(value || "primary")
50
+ if (name === "portrait") return Qt.PortraitOrientation
51
+ if (name === "landscape") return Qt.LandscapeOrientation
52
+ if (name === "inverted_portrait") return Qt.InvertedPortraitOrientation
53
+ if (name === "inverted_landscape") return Qt.InvertedLandscapeOrientation
54
+ return Qt.PrimaryOrientation
55
+ }
56
+
57
+ title: String(renderer.prop("title", ""))
58
+ x: Number(renderer.prop("x", 0))
59
+ y: Number(renderer.prop("y", 0))
60
+ width: Number(renderer.prop("width", 800))
61
+ height: Number(renderer.prop("height", 600))
62
+ minimumWidth: Number(renderer.prop("minimum_width", 0))
63
+ minimumHeight: Number(renderer.prop("minimum_height", 0))
64
+ maximumWidth: Number(renderer.prop("maximum_width", 16777215))
65
+ maximumHeight: Number(renderer.prop("maximum_height", 16777215))
66
+ color: renderer.prop("color", "transparent")
67
+ visible: renderer.prop("visible", false) === true
68
+ visibility: visibilityValue(renderer.prop("visibility", "automatic"))
69
+ modality: modalityValue(renderer.prop("modality", "none"))
70
+ flags: flagsValue(renderer.prop("flags", "window"))
71
+ opacity: Number(renderer.prop("opacity", 1))
72
+ contentOrientation: orientationValue(renderer.prop("content_orientation", "primary"))
73
+ font.family: String(renderer.prop("font_family", renderer.fontFamily))
74
+ font.pixelSize: Number(renderer.prop("font_size", 14))
75
+ background: Rectangle { color: renderer.prop("background", "transparent") }
76
+
77
+ onClosing: function(close) {
78
+ renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "close", {
79
+ accepted: close.accepted
80
+ })
81
+ }
82
+ onVisibleChanged: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "visible_change", { value: visible })
83
+ onActiveChanged: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "active_change", { value: active })
84
+ onVisibilityChanged: renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "visibility_change", { value: visibility })
85
+ onActiveFocusControlChanged: if (renderer.subscribed("focus_change")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "focus_change", {
86
+ active: activeFocusControl !== null,
87
+ object_name: activeFocusControl ? String(activeFocusControl.objectName || "") : ""
88
+ })
89
+ onXChanged: if (renderer.subscribed("move")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "move", { x: x, y: y })
90
+ onYChanged: if (renderer.subscribed("move")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "move", { x: x, y: y })
91
+ onWidthChanged: if (renderer.subscribed("resize")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "resize", { width: width, height: height })
92
+ onHeightChanged: if (renderer.subscribed("resize")) renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "resize", { width: width, height: height })
93
+
94
+ Item {
95
+ anchors.fill: parent
96
+ LayoutMirroring.enabled: String(renderer.prop("layout_direction", "left_to_right")) === "right_to_left"
97
+ LayoutMirroring.childrenInherit: true
98
+ Repeater {
99
+ model: renderer.node.children || []
100
+ delegate: renderer.childDelegateComponent
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,70 @@
1
+ import QtQuick
2
+ import QtQuick.Controls as QQC
3
+ import QtQuick.Layouts
4
+ import QtMultimedia
5
+ import QtQuick.VectorImage
6
+ import "../../Theme"
7
+ import "../../Controls" as ZuiControls
8
+
9
+ Item {
10
+ required property var renderer
11
+ implicitWidth: Number(renderer.prop("width", 420))
12
+ implicitHeight: Number(renderer.prop("height", 220))
13
+ Canvas {
14
+ id: areaCanvas
15
+ anchors.fill: parent
16
+ antialiasing: true
17
+ onPaint: {
18
+ var ctx = getContext("2d")
19
+ ctx.clearRect(0, 0, width, height)
20
+ var raw = renderer.prop("values", [])
21
+ if (!Array.isArray(raw) || raw.length === 0) return
22
+ var values = raw.map(function(value) { return Number(value) })
23
+ var low = renderer.prop("minimum", null)
24
+ var high = renderer.prop("maximum", null)
25
+ if (low === null) low = Math.min.apply(Math, values)
26
+ if (high === null) high = Math.max.apply(Math, values)
27
+ low = Number(low); high = Number(high)
28
+ if (high === low) { high += 1; low -= 1 }
29
+ var pad = 10
30
+ var chartWidth = Math.max(1, width - pad * 2)
31
+ var chartHeight = Math.max(1, height - pad * 2)
32
+ if (renderer.prop("show_grid", true) !== false) {
33
+ ctx.strokeStyle = renderer.prop("grid_color", Color.muted); ctx.lineWidth = 1
34
+ for (var grid = 0; grid <= 4; grid++) {
35
+ var gy = pad + chartHeight * grid / 4
36
+ ctx.beginPath(); ctx.moveTo(pad, gy); ctx.lineTo(width - pad, gy); ctx.stroke()
37
+ }
38
+ }
39
+ var points = []
40
+ for (var index = 0; index < values.length; index++) {
41
+ points.push({
42
+ x: pad + (values.length === 1 ? chartWidth / 2 : chartWidth * index / (values.length - 1)),
43
+ y: pad + chartHeight * (1 - (values[index] - low) / (high - low))
44
+ })
45
+ }
46
+ ctx.beginPath(); ctx.moveTo(points[0].x, height - pad)
47
+ for (var fillIndex = 0; fillIndex < points.length; fillIndex++) ctx.lineTo(points[fillIndex].x, points[fillIndex].y)
48
+ ctx.lineTo(points[points.length - 1].x, height - pad); ctx.closePath()
49
+ ctx.fillStyle = renderer.prop("fill_color", renderer.prop("color", Color.accent)); ctx.fill()
50
+ ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y)
51
+ for (var lineIndex = 1; lineIndex < points.length; lineIndex++) ctx.lineTo(points[lineIndex].x, points[lineIndex].y)
52
+ ctx.strokeStyle = renderer.prop("color", Color.accent)
53
+ ctx.lineWidth = Number(renderer.prop("line_width", 2)); ctx.stroke()
54
+ }
55
+ }
56
+ Connections { target: root; function onNodeChanged() { areaCanvas.requestPaint() } }
57
+ MouseArea {
58
+ anchors.fill: parent
59
+ hoverEnabled: renderer.subscribed("hover")
60
+ function payload(mouse) {
61
+ var values = renderer.prop("values", [])
62
+ if (!Array.isArray(values) || values.length === 0) return ({ index: -1 })
63
+ var index = Math.max(0, Math.min(values.length - 1, Math.round(mouse.x / Math.max(1, width) * (values.length - 1))))
64
+ var labels = renderer.prop("labels", [])
65
+ return { index: index, value: values[index], label: Array.isArray(labels) ? labels[index] : null }
66
+ }
67
+ onClicked: function(mouse) { renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "select", payload(mouse)) }
68
+ onPositionChanged: function(mouse) { renderer.bridge.sendEvent(renderer.surfaceName, renderer.controlId, "hover", payload(mouse)) }
69
+ }
70
+ }