flea-qml 0.0.0-stage → 0.1.0

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 (625) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +478 -2
  3. package/THIRD-PARTY-NOTICES.md +29 -0
  4. package/demos/App.java +5 -0
  5. package/demos/Dockerfile +4 -0
  6. package/demos/Main.kt +3 -0
  7. package/demos/Program.cs +1 -0
  8. package/demos/README.md +12 -0
  9. package/demos/app.dart +3 -0
  10. package/demos/app.deb +0 -0
  11. package/demos/app.js +1 -0
  12. package/demos/backup.tar +0 -0
  13. package/demos/budget.xlsx +0 -0
  14. package/demos/build.sh +2 -0
  15. package/demos/bundle.zip +0 -0
  16. package/demos/clip.mp4 +0 -0
  17. package/demos/data.sqlite +0 -0
  18. package/demos/disk.iso +0 -0
  19. package/demos/engine.cpp +5 -0
  20. package/demos/firmware.bin +0 -0
  21. package/demos/flake.nix +4 -0
  22. package/demos/folder/inside.txt +1 -0
  23. package/demos/font.ttf +0 -0
  24. package/demos/index.html +5 -0
  25. package/demos/index.php +2 -0
  26. package/demos/init.lua +1 -0
  27. package/demos/letter.docx +0 -0
  28. package/demos/lib.rs +3 -0
  29. package/demos/main.c +6 -0
  30. package/demos/main.h +3 -0
  31. package/demos/math-and-diagrams.md +200 -0
  32. package/demos/notes.tar.gz +0 -0
  33. package/demos/notes.txt +3 -0
  34. package/demos/photo.png +0 -0
  35. package/demos/program +2 -0
  36. package/demos/report.pdf +32 -0
  37. package/demos/script.py +1 -0
  38. package/demos/server.go +7 -0
  39. package/demos/settings.json +4 -0
  40. package/demos/slides.pptx +0 -0
  41. package/demos/song.mp3 +0 -0
  42. package/demos/style.css +4 -0
  43. package/demos/tool.rb +1 -0
  44. package/demos/types.ts +2 -0
  45. package/docs/pele.md +23 -0
  46. package/docs/protocol.md +3420 -0
  47. package/docs/temml.md +63 -0
  48. package/index.js +107 -0
  49. package/package.json +34 -4
  50. package/src/archive.js +402 -0
  51. package/src/archiveops.js +697 -0
  52. package/src/backend.js +369 -0
  53. package/src/bulkrename.js +95 -0
  54. package/src/clip-host.js +76 -0
  55. package/src/clip.js +462 -0
  56. package/src/code.js +168 -0
  57. package/src/compare.js +74 -0
  58. package/src/create.js +128 -0
  59. package/src/dirsize.js +147 -0
  60. package/src/figure-svg.js +530 -0
  61. package/src/figure-thread.js +23 -0
  62. package/src/figure.js +132 -0
  63. package/src/find.js +55 -0
  64. package/src/flea.js +39 -0
  65. package/src/fsinfo.js +39 -0
  66. package/src/highlight.js +141 -0
  67. package/src/html.js +52 -0
  68. package/src/kinds.js +89 -0
  69. package/src/listing.js +130 -0
  70. package/src/markdown-html.js +317 -0
  71. package/src/mathml.js +186 -0
  72. package/src/menu.js +180 -0
  73. package/src/meta.js +129 -0
  74. package/src/office.js +810 -0
  75. package/src/order.js +100 -0
  76. package/src/peek.js +49 -0
  77. package/src/pele-wrapper.js +695 -0
  78. package/src/permissions.js +180 -0
  79. package/src/places.js +313 -0
  80. package/src/preview-language.js +10 -0
  81. package/src/transfer.js +669 -0
  82. package/src/trash-record.js +41 -0
  83. package/src/trash.js +210 -0
  84. package/src/trashbrowse.js +326 -0
  85. package/src/uistate.js +393 -0
  86. package/src/uistore.js +168 -0
  87. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  88. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  89. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  90. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  91. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  92. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  93. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  94. package/src/vendor/pele.js +145 -0
  95. package/src/vendor/temml.mjs +14708 -0
  96. package/src/watch.js +98 -0
  97. package/src/wayland/client.js +109 -0
  98. package/src/wayland/protocol.js +55 -0
  99. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  100. package/src/wayland/protocols/wayland.xml +3248 -0
  101. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  102. package/src/wayland/resource-io.js +6 -0
  103. package/src/wayland/socket-discovery.js +26 -0
  104. package/src/wayland/transport-posix.js +120 -0
  105. package/src/wayland/transport-win32.js +11 -0
  106. package/src/wayland/transport.js +3 -0
  107. package/src/wayland/win32-resources.js +80 -0
  108. package/src/wayland/win32-wire.js +62 -0
  109. package/test/archive.test.js +80 -0
  110. package/test/bench-markdown-scroll.mjs +190 -0
  111. package/test/clip-host.test.js +113 -0
  112. package/test/code-preview.test.js +35 -0
  113. package/test/compare-ui-paths.test.js +24 -0
  114. package/test/compare.test.js +54 -0
  115. package/test/delete-trash.test.js +67 -0
  116. package/test/dirsize.test.js +138 -0
  117. package/test/file-ops.test.js +241 -0
  118. package/test/find-contents.test.js +161 -0
  119. package/test/find-input.test.js +66 -0
  120. package/test/fixtures/pele-parity.json +1006 -0
  121. package/test/highlight-launcher.test.js +35 -0
  122. package/test/html-preview.test.js +22 -0
  123. package/test/input.test.js +15 -0
  124. package/test/keymap.test.js +26 -0
  125. package/test/language-icons.test.js +36 -0
  126. package/test/launcher.test.js +51 -0
  127. package/test/manual-code-scroll.mjs +28 -0
  128. package/test/manual-column-scroll.mjs +24 -0
  129. package/test/manual-compare-ui.mjs +20 -0
  130. package/test/manual-find-status.mjs +37 -0
  131. package/test/manual-html-security.mjs +23 -0
  132. package/test/manual-html-ui.mjs +30 -0
  133. package/test/manual-syntax-preview.mjs +26 -0
  134. package/test/manual-trash-ui.mjs +86 -0
  135. package/test/markdown-diagrams.test.js +93 -0
  136. package/test/markdown-html.test.js +105 -0
  137. package/test/mathml.test.js +92 -0
  138. package/test/menu-transfer.test.js +57 -0
  139. package/test/office-preview.test.js +154 -0
  140. package/test/pele-parity.test.js +28 -0
  141. package/test/places.test.js +134 -0
  142. package/test/preview-keys.test.js +60 -0
  143. package/test/preview-language.test.js +22 -0
  144. package/test/status-filename.test.js +20 -0
  145. package/test/transfer-replace-merge.test.js +187 -0
  146. package/test/trash-address.test.js +23 -0
  147. package/test/trash-view.test.js +37 -0
  148. package/test/trashbrowse.test.js +135 -0
  149. package/ui/AboutFacts.qml +78 -0
  150. package/ui/ArchiveCards.qml +68 -0
  151. package/ui/ArchiveCompressDialog.qml +378 -0
  152. package/ui/ArchivePasswordDialog.qml +257 -0
  153. package/ui/Backend.qml +771 -0
  154. package/ui/BulkOldNames.qml +47 -0
  155. package/ui/BulkRenameDialog.qml +380 -0
  156. package/ui/CardFrame.qml +67 -0
  157. package/ui/CardScroll.qml +79 -0
  158. package/ui/CheckBox.qml +73 -0
  159. package/ui/ChromeBar.qml +360 -0
  160. package/ui/ChromeButton.qml +131 -0
  161. package/ui/ChromeModes.qml +43 -0
  162. package/ui/CodeLines.qml +256 -0
  163. package/ui/CodeRefusal.qml +52 -0
  164. package/ui/CollideConfirm.qml +147 -0
  165. package/ui/CollideHost.qml +167 -0
  166. package/ui/ColumnPane.qml +523 -0
  167. package/ui/ColumnRow.qml +380 -0
  168. package/ui/ColumnsArea.qml +594 -0
  169. package/ui/ColumnsLanding.qml +147 -0
  170. package/ui/CompareView.qml +321 -0
  171. package/ui/ContextMenu.qml +743 -0
  172. package/ui/ConvertDialog.qml +456 -0
  173. package/ui/CountedWorker.qml +7 -0
  174. package/ui/Crumb.qml +64 -0
  175. package/ui/CrumbDrop.qml +25 -0
  176. package/ui/CsvTable.qml +394 -0
  177. package/ui/CursorMark.qml +41 -0
  178. package/ui/DefaultClaim.qml +130 -0
  179. package/ui/DeviceLock.qml +47 -0
  180. package/ui/DeviceMounts.qml +540 -0
  181. package/ui/DialogButton.qml +150 -0
  182. package/ui/DialogField.qml +147 -0
  183. package/ui/DialogHeader.qml +31 -0
  184. package/ui/DialogScrim.qml +20 -0
  185. package/ui/DialogTitle.qml +37 -0
  186. package/ui/Divider.qml +9 -0
  187. package/ui/DropInto.qml +126 -0
  188. package/ui/DropTarget.qml +35 -0
  189. package/ui/DropboxMark.qml +60 -0
  190. package/ui/EmptyState.qml +150 -0
  191. package/ui/EscapeHint.qml +11 -0
  192. package/ui/FactsTable.qml +54 -0
  193. package/ui/FastScrollHandler.qml +476 -0
  194. package/ui/FatNamesConfirm.qml +157 -0
  195. package/ui/Favourites.qml +143 -0
  196. package/ui/FigureService.qml +120 -0
  197. package/ui/FileDrag.qml +267 -0
  198. package/ui/FilterStrip.qml +133 -0
  199. package/ui/FitMetrics.qml +22 -0
  200. package/ui/FlashDriveRows.qml +137 -0
  201. package/ui/FlashHost.qml +72 -0
  202. package/ui/FlashImageRow.qml +104 -0
  203. package/ui/FlashRunner.qml +119 -0
  204. package/ui/FlashStepRow.qml +172 -0
  205. package/ui/FlashStrip.qml +38 -0
  206. package/ui/FlashView.qml +397 -0
  207. package/ui/FleaMark.qml +88 -0
  208. package/ui/FlyoutFade.qml +23 -0
  209. package/ui/FontPane.qml +170 -0
  210. package/ui/Glass.qml +114 -0
  211. package/ui/GlassTagger.qml +59 -0
  212. package/ui/Glyph.qml +64 -0
  213. package/ui/GlyphSolid.qml +22 -0
  214. package/ui/GridArea.qml +664 -0
  215. package/ui/GridTile.qml +325 -0
  216. package/ui/GvfsBridge.qml +164 -0
  217. package/ui/Header.qml +433 -0
  218. package/ui/HoverTimers.qml +39 -0
  219. package/ui/HtmlClip.qml +30 -0
  220. package/ui/HtmlPane.qml +63 -0
  221. package/ui/HyprlandMark.qml +45 -0
  222. package/ui/Ipc.qml +1005 -0
  223. package/ui/IpcControls.qml +7 -0
  224. package/ui/IpcMenuState.qml +48 -0
  225. package/ui/IpcPreviewState.qml +185 -0
  226. package/ui/JumpPath.qml +51 -0
  227. package/ui/KeymapSheet.qml +561 -0
  228. package/ui/KeymapSheetResult.qml +89 -0
  229. package/ui/KindStack.qml +40 -0
  230. package/ui/LangMark.qml +51 -0
  231. package/ui/LangMarkLoader.qml +26 -0
  232. package/ui/List.qml +480 -0
  233. package/ui/LoadingState.qml +54 -0
  234. package/ui/LocalSend.qml +56 -0
  235. package/ui/LocalSendMark.qml +73 -0
  236. package/ui/MarkdownBlockView.qml +311 -0
  237. package/ui/MarkdownBlocks.qml +35 -0
  238. package/ui/MarkdownFigure.qml +254 -0
  239. package/ui/MarkdownImages.qml +72 -0
  240. package/ui/MarkdownList.qml +81 -0
  241. package/ui/MarkdownMathsText.qml +97 -0
  242. package/ui/MarkdownPane.qml +83 -0
  243. package/ui/MarkdownPictures.qml +41 -0
  244. package/ui/MarkdownQuote.qml +52 -0
  245. package/ui/MarkdownRemote.qml +82 -0
  246. package/ui/MarkdownSource.qml +155 -0
  247. package/ui/MarkdownTable.qml +222 -0
  248. package/ui/MarkdownTableScroll.qml +64 -0
  249. package/ui/MarkdownTableWheel.qml +126 -0
  250. package/ui/MarkdownText.qml +87 -0
  251. package/ui/MarkdownWorker.js +132 -0
  252. package/ui/MatchText.qml +99 -0
  253. package/ui/MediaSession.qml +38 -0
  254. package/ui/MediaSound.qml +26 -0
  255. package/ui/MediaStrip.qml +191 -0
  256. package/ui/MediaTrack.qml +36 -0
  257. package/ui/MediaVolume.qml +54 -0
  258. package/ui/MenuActionDialog.qml +396 -0
  259. package/ui/MenuEdgeFade.qml +24 -0
  260. package/ui/MenuHost.qml +227 -0
  261. package/ui/MenuRow.qml +351 -0
  262. package/ui/MountListing.qml +100 -0
  263. package/ui/NetworkDialog.qml +435 -0
  264. package/ui/NetworkForm.qml +426 -0
  265. package/ui/NetworkMounts.qml +913 -0
  266. package/ui/NetworkPlaces.qml +127 -0
  267. package/ui/OpenWithDialog.qml +613 -0
  268. package/ui/Opener.qml +115 -0
  269. package/ui/Pane.qml +1296 -0
  270. package/ui/PaneMenuActions.qml +527 -0
  271. package/ui/PanePath.qml +90 -0
  272. package/ui/PaneRail.qml +239 -0
  273. package/ui/PaneStates.qml +88 -0
  274. package/ui/PaneSwap.qml +339 -0
  275. package/ui/PaneWire.qml +605 -0
  276. package/ui/ParkedWait.qml +9 -0
  277. package/ui/PathEntry.qml +186 -0
  278. package/ui/PathJump.qml +400 -0
  279. package/ui/PdfViewer.qml +297 -0
  280. package/ui/PermissionsDialog.qml +658 -0
  281. package/ui/PermissionsHeadings.qml +31 -0
  282. package/ui/PhoneMounts.qml +67 -0
  283. package/ui/PickerAnswers.qml +75 -0
  284. package/ui/PickerBox.qml +26 -0
  285. package/ui/PickerChrome.qml +295 -0
  286. package/ui/PickerFilter.qml +97 -0
  287. package/ui/PickerGrid.qml +308 -0
  288. package/ui/PickerHeader.qml +28 -0
  289. package/ui/PickerLifecycle.qml +27 -0
  290. package/ui/PickerList.qml +218 -0
  291. package/ui/PickerListing.qml +149 -0
  292. package/ui/PickerPathBar.qml +127 -0
  293. package/ui/PickerPlaces.qml +189 -0
  294. package/ui/PickerRecent.qml +92 -0
  295. package/ui/PickerSave.qml +101 -0
  296. package/ui/PickerSelection.qml +155 -0
  297. package/ui/PickerWindow.qml +846 -0
  298. package/ui/PowerSectorsReader.qml +10 -0
  299. package/ui/PrebuildDriver.qml +146 -0
  300. package/ui/Preview.qml +1004 -0
  301. package/ui/PreviewAnimation.qml +24 -0
  302. package/ui/PreviewArchive.qml +66 -0
  303. package/ui/PreviewColumn.qml +551 -0
  304. package/ui/PreviewEdge.qml +63 -0
  305. package/ui/PreviewFacts.qml +30 -0
  306. package/ui/PreviewFactsLine.qml +34 -0
  307. package/ui/PreviewHtml.qml +233 -0
  308. package/ui/PreviewImage.qml +253 -0
  309. package/ui/PreviewImagePan.qml +13 -0
  310. package/ui/PreviewImageSharp.qml +32 -0
  311. package/ui/PreviewLines.qml +106 -0
  312. package/ui/PreviewMarkdown.qml +706 -0
  313. package/ui/PreviewMedia.qml +250 -0
  314. package/ui/PreviewPdf.qml +482 -0
  315. package/ui/PreviewScroll.qml +201 -0
  316. package/ui/PreviewSwap.qml +335 -0
  317. package/ui/PreviewText.qml +149 -0
  318. package/ui/ProtocolChip.qml +18 -0
  319. package/ui/QuickLookArchive.qml +38 -0
  320. package/ui/QuickLookBar.qml +103 -0
  321. package/ui/QuickLookPrepare.qml +355 -0
  322. package/ui/QuickLookSwap.qml +10 -0
  323. package/ui/QuickLookWarm.qml +65 -0
  324. package/ui/RailDrop.qml +155 -0
  325. package/ui/RailHeading.qml +19 -0
  326. package/ui/RailPlaces.qml +38 -0
  327. package/ui/RailTrashRow.qml +67 -0
  328. package/ui/RenameField.qml +353 -0
  329. package/ui/RendererRetry.qml +11 -0
  330. package/ui/ResizeHandle.qml +52 -0
  331. package/ui/Reveal.qml +54 -0
  332. package/ui/Row.qml +476 -0
  333. package/ui/RowDrag.qml +213 -0
  334. package/ui/RowDropTarget.qml +27 -0
  335. package/ui/RunCard.qml +286 -0
  336. package/ui/Scripts.qml +65 -0
  337. package/ui/SearchStrip.qml +232 -0
  338. package/ui/SelectionBand.qml +140 -0
  339. package/ui/SelectionPreview.qml +370 -0
  340. package/ui/SettingsFavourite.qml +122 -0
  341. package/ui/SettingsGroup.qml +96 -0
  342. package/ui/SettingsHint.qml +12 -0
  343. package/ui/SettingsMetrics.qml +29 -0
  344. package/ui/SettingsPane.qml +178 -0
  345. package/ui/SettingsPanel.qml +547 -0
  346. package/ui/SettingsRail.qml +128 -0
  347. package/ui/SettingsRow.qml +409 -0
  348. package/ui/SettingsRuler.qml +85 -0
  349. package/ui/SettingsSegment.qml +85 -0
  350. package/ui/ShareBrowser.qml +113 -0
  351. package/ui/ShareLink.qml +67 -0
  352. package/ui/ShelfPins.qml +101 -0
  353. package/ui/Sidebar.qml +732 -0
  354. package/ui/SidebarRow.qml +358 -0
  355. package/ui/Spinner.qml +60 -0
  356. package/ui/StableModel.qml +89 -0
  357. package/ui/StateMessage.qml +84 -0
  358. package/ui/StatusBar.qml +512 -0
  359. package/ui/StatusFileName.qml +27 -0
  360. package/ui/TabBar.qml +673 -0
  361. package/ui/TabDragGeometry.qml +60 -0
  362. package/ui/TagMenuMark.qml +52 -0
  363. package/ui/TagRailSection.qml +53 -0
  364. package/ui/TagSlot.qml +40 -0
  365. package/ui/TagState.qml +150 -0
  366. package/ui/TagSwatch.qml +28 -0
  367. package/ui/Taildrop.qml +86 -0
  368. package/ui/TailscaleMark.qml +50 -0
  369. package/ui/Theme.qml +460 -0
  370. package/ui/ThemeColors.qml +43 -0
  371. package/ui/TransferCard.qml +239 -0
  372. package/ui/TrashConfirm.qml +129 -0
  373. package/ui/TrashDropHandler.qml +11 -0
  374. package/ui/TrashHost.qml +202 -0
  375. package/ui/TrashMonitor.qml +30 -0
  376. package/ui/TrashToolbar.qml +19 -0
  377. package/ui/TrashView.qml +492 -0
  378. package/ui/UnlockDialog.qml +450 -0
  379. package/ui/UnlockHost.qml +206 -0
  380. package/ui/UpdateCheck.qml +97 -0
  381. package/ui/UserDirs.qml +25 -0
  382. package/ui/ViewState.qml +565 -0
  383. package/ui/ViewportScrollBar.qml +195 -0
  384. package/ui/ViewportScrollBars.qml +25 -0
  385. package/ui/WebPreview.qml +33 -0
  386. package/ui/WebPreviewView.qml +26 -0
  387. package/ui/WindowBody.qml +827 -0
  388. package/ui/WindowDrag.qml +35 -0
  389. package/ui/boot/Commons/AudioNodes.qml +50 -0
  390. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  391. package/ui/boot/Commons/Border.qml +243 -0
  392. package/ui/boot/Commons/BorderGeometry.js +373 -0
  393. package/ui/boot/Commons/Color.qml +258 -0
  394. package/ui/boot/Commons/I18n.qml +118 -0
  395. package/ui/boot/Commons/InputDevices.qml +112 -0
  396. package/ui/boot/Commons/InputMethodState.qml +38 -0
  397. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  398. package/ui/boot/Commons/Numbers.js +19 -0
  399. package/ui/boot/Commons/Plural.js +91 -0
  400. package/ui/boot/Commons/ShellIpc.qml +12 -0
  401. package/ui/boot/Commons/Style.qml +561 -0
  402. package/ui/boot/Commons/Translations.qml +100 -0
  403. package/ui/boot/Commons/UntypedInput.qml +152 -0
  404. package/ui/boot/Commons/Util.qml +188 -0
  405. package/ui/boot/Commons/qmldir +13 -0
  406. package/ui/boot/LICENSE-omarchy +20 -0
  407. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  408. package/ui/boot/Ui/BarIconButton.qml +106 -0
  409. package/ui/boot/Ui/BarIconContent.qml +38 -0
  410. package/ui/boot/Ui/BarIndicator.qml +53 -0
  411. package/ui/boot/Ui/BarWidget.qml +50 -0
  412. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  413. package/ui/boot/Ui/BorderSurface.qml +40 -0
  414. package/ui/boot/Ui/Button.qml +224 -0
  415. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  416. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  417. package/ui/boot/Ui/CursorSurface.qml +42 -0
  418. package/ui/boot/Ui/Dropdown.qml +245 -0
  419. package/ui/boot/Ui/FilterInput.qml +26 -0
  420. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  421. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  422. package/ui/boot/Ui/MultiSelect.qml +624 -0
  423. package/ui/boot/Ui/NumberField.qml +86 -0
  424. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  425. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  426. package/ui/boot/Ui/Panel.qml +60 -0
  427. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  428. package/ui/boot/Ui/PanelController.qml +16 -0
  429. package/ui/boot/Ui/PanelHero.qml +112 -0
  430. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  431. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  432. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  433. package/ui/boot/Ui/PanelSlider.qml +156 -0
  434. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  435. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  436. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  437. package/ui/boot/Ui/PopupCard.qml +181 -0
  438. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  439. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  440. package/ui/boot/Ui/SizedImage.qml +125 -0
  441. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  442. package/ui/boot/Ui/TextField.qml +58 -0
  443. package/ui/boot/Ui/Toggle.qml +118 -0
  444. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  445. package/ui/boot/Ui/WidgetButton.qml +172 -0
  446. package/ui/boot/Ui/qmldir +41 -0
  447. package/ui/boot/fleatab.qml +50 -0
  448. package/ui/boot/picker.qml +39 -0
  449. package/ui/boot/shell.qml +122 -0
  450. package/ui/boot/tabtearoff.qml +51 -0
  451. package/ui/js/Anchor.js +379 -0
  452. package/ui/js/AnchorHold.js +162 -0
  453. package/ui/js/Archive.js +157 -0
  454. package/ui/js/ArchiveCard.js +44 -0
  455. package/ui/js/ArchiveOps.js +44 -0
  456. package/ui/js/BackReturn.js +118 -0
  457. package/ui/js/BulkRename.js +100 -0
  458. package/ui/js/Buttons.js +54 -0
  459. package/ui/js/ChromeKeys.js +116 -0
  460. package/ui/js/ClipMarks.js +73 -0
  461. package/ui/js/ClipSelection.js +67 -0
  462. package/ui/js/Clipboard.js +179 -0
  463. package/ui/js/Cloud.js +97 -0
  464. package/ui/js/CodeRuns.js +72 -0
  465. package/ui/js/Collide.js +212 -0
  466. package/ui/js/ColumnFit.js +28 -0
  467. package/ui/js/ColumnMenu.js +111 -0
  468. package/ui/js/Columns.js +298 -0
  469. package/ui/js/ColumnsCarry.js +103 -0
  470. package/ui/js/Compare.js +74 -0
  471. package/ui/js/Contrast.js +157 -0
  472. package/ui/js/ControlReader.js +42 -0
  473. package/ui/js/Convert.js +52 -0
  474. package/ui/js/CopyAs.js +52 -0
  475. package/ui/js/Crumbs.js +178 -0
  476. package/ui/js/Csv.js +231 -0
  477. package/ui/js/Density.js +44 -0
  478. package/ui/js/Devices.js +440 -0
  479. package/ui/js/DirSizes.js +180 -0
  480. package/ui/js/Drag.js +364 -0
  481. package/ui/js/DragOut.js +166 -0
  482. package/ui/js/DropDev.js +52 -0
  483. package/ui/js/Dropbox.js +41 -0
  484. package/ui/js/Eject.js +217 -0
  485. package/ui/js/Errors.js +188 -0
  486. package/ui/js/ExtThumbs.js +115 -0
  487. package/ui/js/Facts.js +402 -0
  488. package/ui/js/FigureDate.js +14 -0
  489. package/ui/js/Filter.js +285 -0
  490. package/ui/js/Find.js +46 -0
  491. package/ui/js/Flash.js +184 -0
  492. package/ui/js/FlashCard.js +79 -0
  493. package/ui/js/FlashEndings.js +125 -0
  494. package/ui/js/FlashPane.js +116 -0
  495. package/ui/js/FleaBin.js +12 -0
  496. package/ui/js/Focus.js +502 -0
  497. package/ui/js/FolderSorts.js +108 -0
  498. package/ui/js/FolderViews.js +44 -0
  499. package/ui/js/Format.js +305 -0
  500. package/ui/js/Fuzzy.js +141 -0
  501. package/ui/js/GlassTag.js +72 -0
  502. package/ui/js/Grid.js +33 -0
  503. package/ui/js/GridGeometry.js +90 -0
  504. package/ui/js/GridNames.js +153 -0
  505. package/ui/js/GvfsBridge.js +200 -0
  506. package/ui/js/HostClipboard.js +29 -0
  507. package/ui/js/Icons.js +218 -0
  508. package/ui/js/Input.js +50 -0
  509. package/ui/js/Jump.js +200 -0
  510. package/ui/js/KeyName.js +64 -0
  511. package/ui/js/Keymap.js +401 -0
  512. package/ui/js/Kinds.js +164 -0
  513. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  514. package/ui/js/LangMarkPaths.js +47 -0
  515. package/ui/js/LangMarks.js +120 -0
  516. package/ui/js/Lists.js +11 -0
  517. package/ui/js/LocalSend.js +39 -0
  518. package/ui/js/LockedMenu.js +63 -0
  519. package/ui/js/MakeDefault.js +186 -0
  520. package/ui/js/MarkBox.js +7 -0
  521. package/ui/js/Markdown.js +119 -0
  522. package/ui/js/MarkdownLists.js +86 -0
  523. package/ui/js/MarkdownMaths.js +58 -0
  524. package/ui/js/MarkdownPictures.js +32 -0
  525. package/ui/js/MarkdownPrepared.js +139 -0
  526. package/ui/js/MarkdownTableFit.js +34 -0
  527. package/ui/js/Marks.js +148 -0
  528. package/ui/js/Marquee.js +96 -0
  529. package/ui/js/Match.js +93 -0
  530. package/ui/js/Material.js +109 -0
  531. package/ui/js/MdBlocks.js +437 -0
  532. package/ui/js/MdBreak.js +71 -0
  533. package/ui/js/MdChunks.js +70 -0
  534. package/ui/js/MdContainer.js +137 -0
  535. package/ui/js/MdDocument.js +337 -0
  536. package/ui/js/MdEmph.js +97 -0
  537. package/ui/js/MdEntity.js +108 -0
  538. package/ui/js/MdEntityTable.js +223 -0
  539. package/ui/js/MdEscape.js +59 -0
  540. package/ui/js/MdFront.js +37 -0
  541. package/ui/js/MdHold.js +32 -0
  542. package/ui/js/MdHtml.js +307 -0
  543. package/ui/js/MdHtmlBlock.js +290 -0
  544. package/ui/js/MdHtmlHeading.js +53 -0
  545. package/ui/js/MdHtmlImage.js +179 -0
  546. package/ui/js/MdInline.js +154 -0
  547. package/ui/js/MdItems.js +212 -0
  548. package/ui/js/MdLeaf.js +309 -0
  549. package/ui/js/MdLink.js +196 -0
  550. package/ui/js/MdMath.js +67 -0
  551. package/ui/js/MdParagraphs.js +138 -0
  552. package/ui/js/MdRefs.js +232 -0
  553. package/ui/js/MdResolve.js +226 -0
  554. package/ui/js/MdRun.js +300 -0
  555. package/ui/js/MdUrl.js +226 -0
  556. package/ui/js/Menu.js +514 -0
  557. package/ui/js/MenuContext.js +85 -0
  558. package/ui/js/MenuFit.js +13 -0
  559. package/ui/js/MenuRefresh.js +74 -0
  560. package/ui/js/MenuWheel.js +35 -0
  561. package/ui/js/Messages.js +186 -0
  562. package/ui/js/Motion.js +16 -0
  563. package/ui/js/Mounts.js +320 -0
  564. package/ui/js/MouseNav.js +13 -0
  565. package/ui/js/Nav.js +329 -0
  566. package/ui/js/NetFs.js +26 -0
  567. package/ui/js/OpenWith.js +83 -0
  568. package/ui/js/Ops.js +585 -0
  569. package/ui/js/Palette.js +33 -0
  570. package/ui/js/PathBar.js +260 -0
  571. package/ui/js/Permissions.js +179 -0
  572. package/ui/js/Phones.js +112 -0
  573. package/ui/js/Picker.js +353 -0
  574. package/ui/js/PlaceMenu.js +96 -0
  575. package/ui/js/Places.js +265 -0
  576. package/ui/js/PreviewAsk.js +21 -0
  577. package/ui/js/PreviewKeys.js +155 -0
  578. package/ui/js/PreviewSettle.js +29 -0
  579. package/ui/js/PreviewSwap.js +101 -0
  580. package/ui/js/PropertyFacts.js +144 -0
  581. package/ui/js/Protocols.js +296 -0
  582. package/ui/js/QuickLookKinds.js +27 -0
  583. package/ui/js/QuickLookRect.js +24 -0
  584. package/ui/js/RailDrop.js +51 -0
  585. package/ui/js/RailKeys.js +87 -0
  586. package/ui/js/RailMenu.js +133 -0
  587. package/ui/js/Recent.js +135 -0
  588. package/ui/js/RecentMode.js +156 -0
  589. package/ui/js/Reload.js +60 -0
  590. package/ui/js/Renderer.js +9 -0
  591. package/ui/js/RunFile.js +143 -0
  592. package/ui/js/Scripts.js +28 -0
  593. package/ui/js/Scroll.js +304 -0
  594. package/ui/js/ScrollOff.js +69 -0
  595. package/ui/js/Search.js +478 -0
  596. package/ui/js/Selection.js +97 -0
  597. package/ui/js/Settings.js +476 -0
  598. package/ui/js/SettingsAbout.js +97 -0
  599. package/ui/js/SettingsShelf.js +52 -0
  600. package/ui/js/SheetKeys.js +42 -0
  601. package/ui/js/SheetQuery.js +281 -0
  602. package/ui/js/ShelfPile.js +27 -0
  603. package/ui/js/SlowClick.js +53 -0
  604. package/ui/js/SlowOp.js +6 -0
  605. package/ui/js/Sort.js +134 -0
  606. package/ui/js/Startup.js +63 -0
  607. package/ui/js/StateWords.js +17 -0
  608. package/ui/js/Status.js +238 -0
  609. package/ui/js/Swap.js +166 -0
  610. package/ui/js/TabMove.js +39 -0
  611. package/ui/js/Tabs.js +736 -0
  612. package/ui/js/Tags.js +134 -0
  613. package/ui/js/Taildrop.js +128 -0
  614. package/ui/js/Tap.js +174 -0
  615. package/ui/js/TextSize.js +107 -0
  616. package/ui/js/Thumbs.js +158 -0
  617. package/ui/js/Transfer.js +172 -0
  618. package/ui/js/Trash.js +81 -0
  619. package/ui/js/TrashDates.js +47 -0
  620. package/ui/js/TrashDrop.js +64 -0
  621. package/ui/js/UiState.js +438 -0
  622. package/ui/js/Unlock.js +152 -0
  623. package/ui/js/Update.js +130 -0
  624. package/ui/js/UserDirs.js +56 -0
  625. package/ui/qmldir +228 -0
@@ -0,0 +1,360 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Crumbs.js" as Crumbs
5
+ import "js/PathBar.js" as PathBar
6
+
7
+ // The window's top chrome, per the canvas: where you are on the left, how you are looking at it on
8
+ // the right. The path lives here rather than in the status bar, which the design gives to counts.
9
+ Item {
10
+ id: root
11
+
12
+ property string path: ""
13
+ // True only when the drawn path's listing failed, so retyping it retries and all else is a no-op.
14
+ property bool pathFailed: false
15
+ property string home: ""
16
+ property var pathAlias: null
17
+ property bool canGoBack: false
18
+ property bool canGoUp: false
19
+ // "list", "columns" or "grid"; the button naming the current one takes the accent.
20
+ property string viewMode: "list"
21
+ property bool showPath: true
22
+ // Read by the path bar alone, so a Tab on a dotted leaf peeks the way the listing is set to look.
23
+ property bool showHidden: false
24
+ property bool canFilter: false
25
+ // flea-qml: whether each toggle stands on now, drawn sunk while it does.
26
+ property bool filterOn: false
27
+ property bool searchOn: false
28
+ property bool canSort: false
29
+ // False while Quick Look is open: Qt 6 still hands a press beneath an accepted shield, so only handlers stop, never Item.enabled.
30
+ property bool inputLive: true
31
+ // Tab's chrome stop: the keyboard is on the control named by glyph, which draws its own frame; ui/js/ChromeKeys.js moves it.
32
+ property bool stopFocused: false
33
+ property string focusedGlyph: ""
34
+ // Drops callout 4: the pane whose collide sends a drop on a crumb.
35
+ property var dropPane: null
36
+
37
+ signal backRequested()
38
+ signal upRequested()
39
+ signal searchRequested()
40
+ signal filterRequested()
41
+ signal sortRequested()
42
+ signal viewChosen(string mode)
43
+ // The path bar's four. ui/shell.qml navigates, hands the keyboard back, runs the peek behind Tab
44
+ // and carries what the bar says to the status line, because this file draws the chrome and knows
45
+ // nothing about the backend, the pane or the bar below it.
46
+ signal pathEntered(string path)
47
+ signal editClosed()
48
+ signal completeRequested(string dir, bool hidden)
49
+ signal said(string text)
50
+ // The folder jump's one read per open, carried to the pane's backend like Tab's peek; see ui/PathJump.qml.
51
+ signal jumpRequested(int id, int ranking, var favourites, var recent)
52
+ // Built by the first edit and kept for the window's life, so a bar never opened compiles none of it.
53
+ property bool entryBuilt: false
54
+ readonly property var jump: entryLoader.item !== null ? entryLoader.item.jump : null
55
+ readonly property bool jumpShown: entryLoader.item !== null && entryLoader.item.jumpShown
56
+ // Its dropdown hangs below the strip, so the strip rises over the tab bar and the listing while it shows.
57
+ z: root.jumpShown ? 1 : 0
58
+ // The settings panel's pointer door, beside the comma key; see ui/shell.qml for the third.
59
+ signal settingsRequested()
60
+
61
+ // The path bar, typed instead of drawn; the typed half is ui/PathEntry.qml, shared with the picker, and this bar answers its commit and jump.
62
+ readonly property bool editing: entryLoader.item !== null && entryLoader.item.editing
63
+ // What the seam reads: the line as it stands, and the box a test double-clicks to open the bar.
64
+ readonly property string editText: entryLoader.item !== null ? entryLoader.item.editText : ""
65
+ readonly property alias pathArea: pathArea
66
+ // The open field and its frame, null until the bar is first opened, so a test measures where they lie in the strip once it is.
67
+ readonly property var pathFrame: entryLoader.item !== null ? entryLoader.item.pathFrame : null
68
+ readonly property var pathField: entryLoader.item !== null ? entryLoader.item.pathField : null
69
+ // The collapsed middle's own crumb, so a test can press the one segment that names no directory. Its index moves with the room, because the crumbs nearest the root are put back before it.
70
+ readonly property int elisionIndex: {
71
+ for (var i = 0; i < crumbs.model.length; i++)
72
+ if (crumbs.model[i].elided)
73
+ return i
74
+ return -1
75
+ }
76
+ // itemAt is a call and not a property, so the model is named here too: without it a width that keeps the same index hands back the item the model before it built, which is by then destroyed.
77
+ readonly property var elisionMarker: root.elisionIndex >= 0 && crumbs.model ? crumbs.itemAt(root.elisionIndex) : null
78
+ // Issue 45's segments as items, so tests/ui.sh can press one the way it presses a tab.
79
+ readonly property alias crumbItems: crumbs
80
+ function startEdit() { root.entryBuilt = true; entryLoader.item.startEdit() }
81
+
82
+ function closeEdit() { if (entryLoader.item !== null) entryLoader.item.closeEdit() }
83
+
84
+ function commitEdit() {
85
+ var typed = root.editText
86
+ var target = PathBar.addressTarget(typed, root.path, root.home)
87
+ root.closeEdit()
88
+ // An empty line closes the bar, and a settled path stays a no-op to keep the selection, while a failed or locked one retries.
89
+ if (PathBar.shouldNavigate(target, root.path, root.pathFailed)) {
90
+ root.pathEntered(target)
91
+ return
92
+ }
93
+ // A line that named something and still resolved to nothing is a file:// URI on another
94
+ // host. Silence there would read as a broken Enter, so it gets the sentence the rest of
95
+ // this application gives a key that cannot do what was asked.
96
+ if (PathBar.refused(typed)) {
97
+ root.said(PathBar.REFUSED_SENTENCE)
98
+ }
99
+ }
100
+
101
+ // Tab. The rows come from the backend's peek, which is the read the columns view already makes of
102
+ // a directory that is not the pane's, so completing costs no new request type.
103
+ function completeEdit() { if (entryLoader.item !== null) entryLoader.item.completeEdit() }
104
+
105
+ // A peek came back. The columns view peeks the pane's ancestors on the same wire, and a Tab that
106
+ // gained a dot asks the same directory again with the other hidden flag, so the reply is matched
107
+ // on the pair the backend echoes rather than on the path alone: a line completing ".conf" was
108
+ // otherwise free to answer off rows that carried no dotfiles at all. Only directories are kept:
109
+ // this bar goes to a directory, and a name that cannot be opened is not a completion.
110
+ function completeWith(dir, hidden, rows) { if (entryLoader.item !== null) entryLoader.item.completeWith(dir, hidden, rows) }
111
+
112
+ function applyCompletion(dir, names) { if (entryLoader.item !== null) entryLoader.item.applyCompletion(dir, names) }
113
+
114
+ // A chrome strip, not a data row; see Theme.qml's chromeHeight comment.
115
+ implicitHeight: Theme.chromeHeight
116
+
117
+ Rectangle {
118
+ anchors.fill: parent
119
+ color: Glass.surface
120
+ }
121
+
122
+ // A test drives these by coordinate, because a glyph button carries no text to find on screen.
123
+ function buttonFor(glyph) {
124
+ var groups = [nav, views, modes]
125
+ for (var g = 0; g < groups.length; g++) {
126
+ var kids = groups[g].children
127
+ for (var i = 0; i < kids.length; i++) {
128
+ if (kids[i].glyph === glyph)
129
+ return kids[i]
130
+ }
131
+ }
132
+ return null
133
+ }
134
+
135
+ Row {
136
+ id: nav
137
+ anchors.left: parent.left
138
+ anchors.leftMargin: Theme.spacing.rowPaddingX
139
+ anchors.verticalCenter: parent.verticalCenter
140
+ spacing: Theme.spacing.gap
141
+
142
+ Flea.ChromeButton {
143
+ inputLive: root.inputLive
144
+ ruleRows: Theme.spacing.hairline
145
+ glyph: "arrow-left"
146
+ keyboardFocused: root.stopFocused && root.focusedGlyph === glyph
147
+ enabled: root.canGoBack
148
+ onActivated: root.backRequested()
149
+ }
150
+
151
+ Flea.ChromeButton {
152
+ inputLive: root.inputLive
153
+ ruleRows: Theme.spacing.hairline
154
+ glyph: "arrow-up"
155
+ keyboardFocused: root.stopFocused && root.focusedGlyph === glyph
156
+ enabled: root.canGoUp
157
+ onActivated: root.upRequested()
158
+ }
159
+ }
160
+
161
+ // Where the path is drawn is where it is typed. A double click opens the bar, which is the
162
+ // pointer's half of ":" and Ctrl+L. Issue 45 made the segments above the leaf a control as well
163
+ // as a label: one tap on any of them opens that directory, and the leaf is where the pane
164
+ // already is, so it stays a label and only the bar answers a click on it.
165
+ Item {
166
+ id: pathArea
167
+ anchors.left: nav.right
168
+ anchors.leftMargin: Theme.spacing.gap
169
+ anchors.right: views.left
170
+ anchors.rightMargin: Theme.spacing.gap
171
+ anchors.top: parent.top
172
+ anchors.bottom: parent.bottom
173
+ // The strip draws its own rule along that bottom edge, so the content stops above it: without
174
+ // this the rename editor's frame sat two pixels clear of the strip's top and one of its rule,
175
+ // which is the same unequal margin the Trash chrome's control had.
176
+ anchors.bottomMargin: Theme.spacing.hairline
177
+
178
+ // The tail identifies the directory, so a path too long for the bar loses its head: the row
179
+ // slides left inside a clipped slot, which is the left elision the single Text drew, made of
180
+ // pieces a click can land on.
181
+ Text {
182
+ anchors.fill: parent
183
+ visible: !root.editing && root.showPath && ViewState.addressBar === "path"
184
+ text: root.home && (root.path === root.home || root.path.indexOf(root.home + "/") === 0)
185
+ ? "~" + root.path.substring(root.home.length) : root.path
186
+ color: Theme.color.foreground
187
+ font.family: Theme.font.family
188
+ font.pixelSize: Theme.font.caption
189
+ verticalAlignment: Text.AlignVCenter
190
+ elide: Text.ElideLeft
191
+ textFormat: Text.PlainText
192
+ TapHandler { enabled: root.inputLive; onDoubleTapped: root.startEdit() }
193
+ }
194
+
195
+ // One glyph's advance is every glyph's advance in this face, so the crumbs are fitted by
196
+ // character count rather than by a layout pass that would feed its own width back in.
197
+ TextMetrics {
198
+ id: crumbMetrics
199
+ font.family: Theme.font.family
200
+ font.pixelSize: Theme.font.caption
201
+ text: "0"
202
+ }
203
+
204
+ Item {
205
+ id: crumbSlot
206
+ visible: !root.editing && root.showPath && ViewState.addressBar === "breadcrumb"
207
+ anchors.fill: parent
208
+ clip: true
209
+
210
+ Row {
211
+ id: crumbRow
212
+ anchors.verticalCenter: parent.verticalCenter
213
+
214
+ Repeater {
215
+ id: crumbs
216
+ model: Crumbs.fitCrumbs(Crumbs.crumbs(root.path, root.home, root.pathAlias),
217
+ Math.floor(crumbSlot.width / crumbMetrics.advanceWidth))
218
+
219
+ delegate: Flea.Crumb {
220
+ inputLive: root.inputLive
221
+ dropPane: root.dropPane
222
+ // The strip's height with the glyphs centred, because the crumb's handlers are the path area's
223
+ // whole gesture and a text-tall box left 11 of the strip's 27 px dead, measured at the window.
224
+ height: crumbSlot.height
225
+ onChosen: function (path) { root.pathEntered(path) }
226
+ onEditRequested: root.startEdit()
227
+ }
228
+ }
229
+ }
230
+
231
+ // The rest of the line, which names no directory and so keeps the plain caret and the
232
+ // one gesture the whole strip used to carry. It is empty once the path fills the bar.
233
+ Item {
234
+ id: typeArea
235
+ anchors.left: crumbRow.right
236
+ anchors.right: parent.right
237
+ anchors.top: parent.top
238
+ anchors.bottom: parent.bottom
239
+
240
+ HoverHandler {
241
+ enabled: root.inputLive
242
+ cursorShape: Qt.IBeamCursor
243
+ }
244
+
245
+ TapHandler {
246
+ enabled: root.inputLive
247
+ acceptedButtons: Qt.LeftButton
248
+ onDoubleTapped: root.startEdit()
249
+ }
250
+ }
251
+
252
+ }
253
+
254
+ // The typed half, shared with the file picker; the bar answers its commit and its jump choice, which differ by host.
255
+ Loader {
256
+ id: entryLoader
257
+ anchors.fill: parent
258
+ active: root.entryBuilt
259
+ asynchronous: false
260
+ source: "PathEntry.qml"
261
+ onLoaded: {
262
+ item.path = Qt.binding(function () { return root.path })
263
+ item.home = Qt.binding(function () { return root.home })
264
+ item.showHidden = Qt.binding(function () { return root.showHidden })
265
+ }
266
+ }
267
+ Connections {
268
+ target: entryLoader.item
269
+ function onCommitLine() { root.commitEdit() }
270
+ function onJumpChosen(path) { root.closeEdit(); if (PathBar.shouldNavigate(path, root.path, root.pathFailed)) root.pathEntered(path) }
271
+ function onEditClosed() { root.editClosed() }
272
+ function onCompleteRequested(dir, hidden) { root.completeRequested(dir, hidden) }
273
+ function onSaid(text) { root.said(text) }
274
+ function onJumpRequested(id, ranking, favourites, recent) { root.jumpRequested(id, ranking, favourites, recent) }
275
+ }
276
+ }
277
+
278
+ Row {
279
+ id: views
280
+ anchors.right: parent.right
281
+ anchors.rightMargin: Theme.spacing.rowPaddingX
282
+ anchors.verticalCenter: parent.verticalCenter
283
+ spacing: Theme.spacing.gap
284
+
285
+ // flea-qml: Filter and Find side by side in every view, each a toggle of its own: the funnel
286
+ // narrows what is listed by name, the magnifier runs find; both may stand at once.
287
+ Flea.ChromeButton {
288
+ inputLive: root.inputLive
289
+ ruleRows: Theme.spacing.hairline
290
+ enabled: root.canFilter
291
+ glyph: "filter"
292
+ checkable: true
293
+ checked: root.filterOn
294
+ keyboardFocused: root.stopFocused && root.focusedGlyph === glyph
295
+ accessName: "Filter"
296
+ onActivated: root.filterRequested()
297
+ }
298
+
299
+ Flea.ChromeButton {
300
+ inputLive: root.inputLive
301
+ ruleRows: Theme.spacing.hairline
302
+ glyph: "search"
303
+ checkable: true
304
+ checked: root.searchOn
305
+ keyboardFocused: root.stopFocused && root.focusedGlyph === glyph
306
+ accessName: "Find"
307
+ onActivated: root.searchRequested()
308
+ }
309
+
310
+ Flea.ChromeButton {
311
+ inputLive: root.inputLive
312
+ ruleRows: Theme.spacing.hairline
313
+ visible: root.viewMode === "grid"
314
+ enabled: root.canSort
315
+ glyph: "sort"
316
+ keyboardFocused: root.stopFocused && root.focusedGlyph === glyph
317
+ accessName: "Sort"
318
+ onActivated: root.sortRequested()
319
+ }
320
+
321
+ Flea.ChromeModes {
322
+ id: modes
323
+ inputLive: root.inputLive
324
+ viewMode: root.viewMode
325
+ focusedGlyph: root.stopFocused ? root.focusedGlyph : ""
326
+ onChosen: function (mode) { root.viewChosen(mode) }
327
+ }
328
+
329
+ // Row owns horizontal placement; the short Settings divider stays vertically centered.
330
+ Rectangle {
331
+ width: Theme.spacing.hairline
332
+ height: Theme.chromeMarkSize - Theme.spacing.hairline
333
+ y: (parent.height - height) / 2
334
+ color: Theme.color.foreground
335
+ opacity: 0.12
336
+ }
337
+
338
+ Flea.ChromeButton {
339
+ inputLive: root.inputLive
340
+ ruleRows: Theme.spacing.hairline
341
+ glyph: "sliders"
342
+ keyboardFocused: root.stopFocused && root.focusedGlyph === glyph
343
+ onActivated: root.settingsRequested()
344
+ }
345
+ }
346
+
347
+ // The strip's own bottom edge, declared last so it draws over the path area: the elided head's
348
+ // opaque fill reaches the same row and used to leave a seven pixel gap in it.
349
+ Rectangle {
350
+ anchors.bottom: parent.bottom
351
+ anchors.left: parent.left
352
+ anchors.right: parent.right
353
+ height: Theme.spacing.hairline
354
+ color: Theme.color.foreground
355
+ opacity: 0.12
356
+ }
357
+
358
+ // The pointer's title bar over the whole strip; the controls under it keep their own taps.
359
+ Flea.WindowDrag { anchors.fill: parent; editing: root.editing; inputLive: root.inputLive }
360
+ }
@@ -0,0 +1,131 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Buttons.js" as Buttons
5
+
6
+ // A live chrome control inks in foreground; an active one uses the accent and the keyboard draws its own foreground frame.
7
+ Item {
8
+ id: root
9
+
10
+ property string glyph: "file"
11
+ property bool active: false
12
+ // flea-qml: a toggle that is on draws sunk into the bar, as a pressed key stays down; off is the
13
+ // ordinary raised mark. Filter and Find use it.
14
+ property bool checkable: false
15
+ property bool checked: false
16
+ property bool keyboardFocused: false
17
+ // False while something the chrome sits under takes the pointer; the handlers stop, the drawing does not.
18
+ property bool inputLive: true
19
+ property color restingColor: Theme.color.foreground
20
+ // DragThreshold lets a drag that starts on a chrome bar button move the window; an overlay's instance passes ReleaseWithinBounds.
21
+ property int gesturePolicy: TapHandler.DragThreshold
22
+ property real glyphSize: Theme.chromeMarkSize
23
+ // Rows at the bottom of the hit box that a strip's own rule takes; the frame and the glyph centre in the rows above them.
24
+ property int ruleRows: 0
25
+
26
+ signal activated()
27
+
28
+ property string accessName: {
29
+ if (root.glyph === "arrow-left")
30
+ return "Back"
31
+ if (root.glyph === "arrow-up")
32
+ return "Parent folder"
33
+ if (root.glyph === "search")
34
+ return "Search"
35
+ if (root.glyph === "list")
36
+ return "List view"
37
+ if (root.glyph === "columns")
38
+ return "Columns view"
39
+ if (root.glyph === "grid")
40
+ return "Grid view"
41
+ return root.glyph
42
+ }
43
+
44
+ // The pointer's own state, read by Quick Look's IPC and by the native capture harness to prove a driven hover or press landed.
45
+ readonly property bool hovered: hover.hovered
46
+ readonly property bool pressed: tap.pressed
47
+ // The keyboard frame and the glyph, read by tests/chromering.sh.
48
+ readonly property Item ringItem: ring
49
+ readonly property Item markItem: mark
50
+
51
+ // The mark stays the chrome token; the hit box is at least 24 px wide and the strip's height.
52
+ implicitWidth: Math.max(Theme.hitMin, Theme.chromeMarkSize)
53
+ implicitHeight: Theme.chromeHeight
54
+ scale: tap.pressed && root.enabled && !Theme.reducedMotion ? Buttons.PRESS_SCALE : 1
55
+
56
+ Accessible.role: Accessible.Button
57
+ Accessible.name: root.accessName
58
+ Accessible.checkable: root.checkable
59
+ Accessible.checked: root.checked
60
+ Accessible.onPressAction: if (root.enabled) root.activated()
61
+
62
+ Behavior on scale {
63
+ enabled: !Theme.reducedMotion
64
+ NumberAnimation { duration: Buttons.PRESS_MS; easing.type: Easing.OutCubic }
65
+ }
66
+
67
+ // ButtonSystem040 A: the keyboard frames the mark in the foreground, centred in the rows above a strip's rule and trimmed to the control inset clear and the glyph's parity.
68
+ Item {
69
+ id: ringBand
70
+ width: root.width
71
+ height: root.height - root.ruleRows
72
+ // flea-qml: the well a checked toggle sits in, darker than the bar with a frame round it.
73
+ Rectangle {
74
+ id: well
75
+ anchors.centerIn: parent
76
+ width: ring.width + 2 * Theme.spacing.hairline
77
+ height: width
78
+ radius: Theme.spacing.hairline * 3
79
+ visible: root.checkable && root.checked
80
+ color: Theme.color.background
81
+ border.width: Theme.spacing.hairline
82
+ border.color: Theme.color.mutedFrame
83
+ }
84
+ Rectangle {
85
+ id: ring
86
+ readonly property int room: Math.min(Math.max(Theme.hitMin, root.glyphSize), ringBand.height - 2 * Theme.chromeControlInset)
87
+ anchors.centerIn: parent
88
+ width: ring.room - (ring.room - root.glyphSize) % 2
89
+ height: width
90
+ color: "transparent"
91
+ border.width: Theme.spacing.hairline
92
+ border.color: Theme.color.foreground
93
+ visible: root.keyboardFocused && root.enabled
94
+ }
95
+ }
96
+
97
+ Flea.Glyph {
98
+ id: mark
99
+ anchors.centerIn: ringBand
100
+ // Pressed in by a hairline while its toggle is on.
101
+ anchors.verticalCenterOffset: root.checkable && root.checked ? Theme.spacing.hairline : 0
102
+ width: root.glyphSize
103
+ height: root.glyphSize
104
+ name: root.glyph
105
+ color: !root.enabled ? Theme.color.mutedFrame
106
+ : root.active || (root.checkable && root.checked) ? Theme.color.accent
107
+ : root.keyboardFocused ? Theme.color.foreground : root.restingColor
108
+ // A control with nowhere to go keeps its slot so the bar never reflows, and says so by dimming.
109
+ opacity: root.enabled ? 1 : Theme.disabledOpacity
110
+ }
111
+
112
+ // A focused mark answers Return, keypad Enter and Space as a press does; its host owns Tab.
113
+ Keys.onReturnPressed: function(event) { if (root.enabled) root.activated(); else event.accepted = false }
114
+ Keys.onEnterPressed: function(event) { if (root.enabled) root.activated(); else event.accepted = false }
115
+ Keys.onSpacePressed: function(event) { if (root.enabled) root.activated(); else event.accepted = false }
116
+
117
+ HoverHandler {
118
+ id: hover
119
+ enabled: root.inputLive
120
+ cursorShape: Qt.PointingHandCursor
121
+ }
122
+
123
+ // overlay-tap-exempt: the instance chooses, and tests/shellload.sh holds every overlay's instance to ReleaseWithinBounds.
124
+ TapHandler {
125
+ id: tap
126
+ enabled: root.inputLive
127
+ acceptedButtons: Qt.LeftButton
128
+ gesturePolicy: root.gesturePolicy
129
+ onTapped: root.activated()
130
+ }
131
+ }
@@ -0,0 +1,43 @@
1
+ import QtQuick
2
+ import "." as Flea
3
+
4
+ // The chrome's four view modes, one choice hairline-separated from the contextual actions beside it.
5
+ // The chosen one is foreground and its three neighbours are muted, which is brightness and survives
6
+ // every palette: an accent-inked current mode is invisible on kanagawa, where accent equals
7
+ // foreground exactly, and measures under 1.5:1 against muted on three more.
8
+ Row {
9
+ id: root
10
+
11
+ property string viewMode: ""
12
+ property bool inputLive: true
13
+ // The glyph the keyboard is on while Tab's chrome stop holds it, "" otherwise.
14
+ property string focusedGlyph: ""
15
+
16
+ signal chosen(string mode)
17
+
18
+ spacing: Theme.spacing.gap
19
+
20
+ // The group's own left edge; ui/ChromeBar.qml draws the matching one before Settings.
21
+ Rectangle {
22
+ width: Theme.spacing.hairline
23
+ height: Theme.chromeMarkSize - Theme.spacing.hairline
24
+ y: (parent.height - height) / 2
25
+ color: Theme.color.foreground
26
+ opacity: 0.12
27
+ }
28
+
29
+ Repeater {
30
+ model: ["list", "columns", "grid", "dual"]
31
+
32
+ // No box and no plate: four glyphs in a strip are Tier A, where a box would be furniture.
33
+ delegate: Flea.ChromeButton {
34
+ required property string modelData
35
+ ruleRows: Theme.spacing.hairline
36
+ glyph: modelData
37
+ keyboardFocused: root.focusedGlyph === modelData
38
+ inputLive: root.inputLive
39
+ restingColor: root.viewMode === modelData ? Theme.color.foreground : Theme.color.mutedFrame
40
+ onActivated: root.chosen(modelData)
41
+ }
42
+ }
43
+ }