flea-qml 0.0.0-stage → 0.2.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.
- package/LICENSE +22 -0
- package/README.md +511 -2
- package/THIRD-PARTY-NOTICES.md +29 -0
- package/demos/App.java +5 -0
- package/demos/Dockerfile +4 -0
- package/demos/Main.kt +3 -0
- package/demos/Program.cs +1 -0
- package/demos/README.md +12 -0
- package/demos/app.dart +3 -0
- package/demos/app.deb +0 -0
- package/demos/app.js +1 -0
- package/demos/backup.tar +0 -0
- package/demos/budget.xlsx +0 -0
- package/demos/build.sh +2 -0
- package/demos/bundle.zip +0 -0
- package/demos/clip.mp4 +0 -0
- package/demos/data.sqlite +0 -0
- package/demos/disk.iso +0 -0
- package/demos/engine.cpp +5 -0
- package/demos/firmware.bin +0 -0
- package/demos/flake.nix +4 -0
- package/demos/folder/inside.txt +1 -0
- package/demos/font.ttf +0 -0
- package/demos/index.html +5 -0
- package/demos/index.php +2 -0
- package/demos/init.lua +1 -0
- package/demos/letter.docx +0 -0
- package/demos/lib.rs +3 -0
- package/demos/main.c +6 -0
- package/demos/main.h +3 -0
- package/demos/math-and-diagrams.md +200 -0
- package/demos/notes.tar.gz +0 -0
- package/demos/notes.txt +3 -0
- package/demos/photo.png +0 -0
- package/demos/program +2 -0
- package/demos/report.pdf +32 -0
- package/demos/script.py +1 -0
- package/demos/server.go +7 -0
- package/demos/settings.json +4 -0
- package/demos/slides.pptx +0 -0
- package/demos/song.mp3 +0 -0
- package/demos/style.css +4 -0
- package/demos/tool.rb +1 -0
- package/demos/types.ts +2 -0
- package/docs/pele.md +23 -0
- package/docs/protocol.md +3420 -0
- package/docs/temml.md +63 -0
- package/index.js +107 -0
- package/package.json +34 -4
- package/src/archive.js +407 -0
- package/src/archiveops.js +728 -0
- package/src/backend.js +369 -0
- package/src/bulkrename.js +95 -0
- package/src/clip-host.js +76 -0
- package/src/clip.js +462 -0
- package/src/code.js +168 -0
- package/src/compare.js +74 -0
- package/src/create.js +128 -0
- package/src/dirsize.js +147 -0
- package/src/figure-svg.js +530 -0
- package/src/figure-thread.js +23 -0
- package/src/figure.js +132 -0
- package/src/find.js +55 -0
- package/src/flea.js +39 -0
- package/src/fsinfo.js +39 -0
- package/src/highlight.js +141 -0
- package/src/html.js +52 -0
- package/src/kinds.js +89 -0
- package/src/listing.js +130 -0
- package/src/markdown-html.js +317 -0
- package/src/mathml.js +186 -0
- package/src/menu.js +180 -0
- package/src/meta.js +135 -0
- package/src/office.js +810 -0
- package/src/order.js +100 -0
- package/src/peek.js +49 -0
- package/src/pele-wrapper.js +695 -0
- package/src/permissions.js +180 -0
- package/src/places.js +313 -0
- package/src/preview-language.js +10 -0
- package/src/terminal-server.js +95 -0
- package/src/terminal-shell.js +26 -0
- package/src/transfer.js +669 -0
- package/src/trash-record.js +41 -0
- package/src/trash.js +210 -0
- package/src/trashbrowse.js +327 -0
- package/src/uistate.js +393 -0
- package/src/uistore.js +168 -0
- package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
- package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
- package/src/vendor/LICENSES/MIT-katex.txt +21 -0
- package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
- package/src/vendor/LICENSES/MIT-pele.txt +40 -0
- package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
- package/src/vendor/LICENSES/MIT-temml.txt +21 -0
- package/src/vendor/pele.js +145 -0
- package/src/vendor/temml.mjs +14708 -0
- package/src/watch.js +98 -0
- package/src/wayland/client.js +109 -0
- package/src/wayland/protocol.js +55 -0
- package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
- package/src/wayland/protocols/wayland.xml +3248 -0
- package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
- package/src/wayland/resource-io.js +6 -0
- package/src/wayland/socket-discovery.js +26 -0
- package/src/wayland/transport-posix.js +120 -0
- package/src/wayland/transport-win32.js +11 -0
- package/src/wayland/transport.js +3 -0
- package/src/wayland/win32-resources.js +80 -0
- package/src/wayland/win32-wire.js +62 -0
- package/test/archive.test.js +80 -0
- package/test/bench-markdown-scroll.mjs +190 -0
- package/test/clip-host.test.js +113 -0
- package/test/code-preview.test.js +35 -0
- package/test/compare-ui-paths.test.js +24 -0
- package/test/compare.test.js +54 -0
- package/test/delete-trash.test.js +67 -0
- package/test/dirsize.test.js +138 -0
- package/test/file-ops.test.js +307 -0
- package/test/file-url.test.js +24 -0
- package/test/find-contents.test.js +161 -0
- package/test/find-input.test.js +66 -0
- package/test/fixtures/pele-parity.json +1006 -0
- package/test/highlight-launcher.test.js +35 -0
- package/test/html-preview.test.js +22 -0
- package/test/input.test.js +15 -0
- package/test/keymap.test.js +26 -0
- package/test/language-icons.test.js +36 -0
- package/test/launcher.test.js +51 -0
- package/test/manual-archive-here-ui.mjs +47 -0
- package/test/manual-code-scroll.mjs +28 -0
- package/test/manual-column-scroll.mjs +24 -0
- package/test/manual-compare-ui.mjs +20 -0
- package/test/manual-find-status.mjs +37 -0
- package/test/manual-folder-focus.mjs +63 -0
- package/test/manual-html-security.mjs +23 -0
- package/test/manual-html-ui.mjs +30 -0
- package/test/manual-syntax-preview.mjs +26 -0
- package/test/manual-terminal-lifecycle.mjs +42 -0
- package/test/manual-terminal-navigation.mjs +48 -0
- package/test/manual-terminal-ui.mjs +47 -0
- package/test/manual-trash-ui.mjs +86 -0
- package/test/markdown-diagrams.test.js +93 -0
- package/test/markdown-html.test.js +105 -0
- package/test/mathml.test.js +92 -0
- package/test/menu-transfer.test.js +57 -0
- package/test/office-preview.test.js +154 -0
- package/test/pele-parity.test.js +28 -0
- package/test/places.test.js +134 -0
- package/test/preview-keys.test.js +60 -0
- package/test/preview-language.test.js +22 -0
- package/test/status-filename.test.js +20 -0
- package/test/transfer-replace-merge.test.js +187 -0
- package/test/trash-address.test.js +23 -0
- package/test/trash-view.test.js +37 -0
- package/test/trashbrowse.test.js +135 -0
- package/ui/AboutFacts.qml +78 -0
- package/ui/ArchiveCards.qml +95 -0
- package/ui/ArchiveCompressDialog.qml +378 -0
- package/ui/ArchiveHereConfirm.qml +127 -0
- package/ui/ArchivePasswordDialog.qml +257 -0
- package/ui/Backend.qml +775 -0
- package/ui/BulkOldNames.qml +47 -0
- package/ui/BulkRenameDialog.qml +380 -0
- package/ui/CardFrame.qml +67 -0
- package/ui/CardScroll.qml +79 -0
- package/ui/CheckBox.qml +73 -0
- package/ui/ChromeBar.qml +360 -0
- package/ui/ChromeButton.qml +131 -0
- package/ui/ChromeModes.qml +43 -0
- package/ui/CodeLines.qml +256 -0
- package/ui/CodeRefusal.qml +52 -0
- package/ui/CollideConfirm.qml +147 -0
- package/ui/CollideHost.qml +167 -0
- package/ui/ColumnPane.qml +525 -0
- package/ui/ColumnRow.qml +380 -0
- package/ui/ColumnsArea.qml +594 -0
- package/ui/ColumnsLanding.qml +147 -0
- package/ui/CompareView.qml +321 -0
- package/ui/ContextMenu.qml +743 -0
- package/ui/ConvertDialog.qml +456 -0
- package/ui/CountedWorker.qml +7 -0
- package/ui/Crumb.qml +64 -0
- package/ui/CrumbDrop.qml +25 -0
- package/ui/CsvTable.qml +394 -0
- package/ui/CursorMark.qml +41 -0
- package/ui/DefaultClaim.qml +130 -0
- package/ui/DeviceLock.qml +47 -0
- package/ui/DeviceMounts.qml +540 -0
- package/ui/DialogButton.qml +150 -0
- package/ui/DialogField.qml +147 -0
- package/ui/DialogHeader.qml +31 -0
- package/ui/DialogScrim.qml +20 -0
- package/ui/DialogTitle.qml +37 -0
- package/ui/Divider.qml +9 -0
- package/ui/DropInto.qml +126 -0
- package/ui/DropTarget.qml +35 -0
- package/ui/DropboxMark.qml +60 -0
- package/ui/EmptyState.qml +150 -0
- package/ui/EscapeHint.qml +11 -0
- package/ui/FactsTable.qml +54 -0
- package/ui/FastScrollHandler.qml +476 -0
- package/ui/FatNamesConfirm.qml +157 -0
- package/ui/Favourites.qml +143 -0
- package/ui/FigureService.qml +120 -0
- package/ui/FileDrag.qml +267 -0
- package/ui/FilterStrip.qml +133 -0
- package/ui/FitMetrics.qml +22 -0
- package/ui/FlashDriveRows.qml +137 -0
- package/ui/FlashHost.qml +72 -0
- package/ui/FlashImageRow.qml +104 -0
- package/ui/FlashRunner.qml +119 -0
- package/ui/FlashStepRow.qml +172 -0
- package/ui/FlashStrip.qml +38 -0
- package/ui/FlashView.qml +397 -0
- package/ui/FleaMark.qml +88 -0
- package/ui/FlyoutFade.qml +23 -0
- package/ui/FontPane.qml +170 -0
- package/ui/Glass.qml +114 -0
- package/ui/GlassTagger.qml +59 -0
- package/ui/Glyph.qml +64 -0
- package/ui/GlyphSolid.qml +22 -0
- package/ui/GridArea.qml +664 -0
- package/ui/GridTile.qml +325 -0
- package/ui/GvfsBridge.qml +164 -0
- package/ui/Header.qml +433 -0
- package/ui/HoverTimers.qml +39 -0
- package/ui/HtmlClip.qml +30 -0
- package/ui/HtmlPane.qml +63 -0
- package/ui/HyprlandMark.qml +45 -0
- package/ui/Ipc.qml +1005 -0
- package/ui/IpcControls.qml +7 -0
- package/ui/IpcMenuState.qml +48 -0
- package/ui/IpcPreviewState.qml +185 -0
- package/ui/JumpPath.qml +51 -0
- package/ui/KeymapSheet.qml +561 -0
- package/ui/KeymapSheetResult.qml +89 -0
- package/ui/KindStack.qml +40 -0
- package/ui/LangMark.qml +51 -0
- package/ui/LangMarkLoader.qml +26 -0
- package/ui/List.qml +480 -0
- package/ui/LoadingState.qml +54 -0
- package/ui/LocalSend.qml +56 -0
- package/ui/LocalSendMark.qml +73 -0
- package/ui/MarkdownBlockView.qml +311 -0
- package/ui/MarkdownBlocks.qml +35 -0
- package/ui/MarkdownFigure.qml +254 -0
- package/ui/MarkdownImages.qml +72 -0
- package/ui/MarkdownList.qml +81 -0
- package/ui/MarkdownMathsText.qml +97 -0
- package/ui/MarkdownPane.qml +83 -0
- package/ui/MarkdownPictures.qml +41 -0
- package/ui/MarkdownQuote.qml +52 -0
- package/ui/MarkdownRemote.qml +82 -0
- package/ui/MarkdownSource.qml +155 -0
- package/ui/MarkdownTable.qml +222 -0
- package/ui/MarkdownTableScroll.qml +64 -0
- package/ui/MarkdownTableWheel.qml +126 -0
- package/ui/MarkdownText.qml +87 -0
- package/ui/MarkdownWorker.js +132 -0
- package/ui/MatchText.qml +99 -0
- package/ui/MediaSession.qml +38 -0
- package/ui/MediaSound.qml +26 -0
- package/ui/MediaStrip.qml +191 -0
- package/ui/MediaTrack.qml +36 -0
- package/ui/MediaVolume.qml +54 -0
- package/ui/MenuActionDialog.qml +396 -0
- package/ui/MenuEdgeFade.qml +24 -0
- package/ui/MenuHost.qml +227 -0
- package/ui/MenuRow.qml +351 -0
- package/ui/MountListing.qml +100 -0
- package/ui/NetworkDialog.qml +435 -0
- package/ui/NetworkForm.qml +426 -0
- package/ui/NetworkMounts.qml +913 -0
- package/ui/NetworkPlaces.qml +127 -0
- package/ui/OpenWithDialog.qml +613 -0
- package/ui/Opener.qml +95 -0
- package/ui/Pane.qml +1320 -0
- package/ui/PaneMenuActions.qml +527 -0
- package/ui/PanePath.qml +90 -0
- package/ui/PaneRail.qml +268 -0
- package/ui/PaneStates.qml +88 -0
- package/ui/PaneSwap.qml +339 -0
- package/ui/PaneWire.qml +601 -0
- package/ui/ParkedWait.qml +9 -0
- package/ui/PathEntry.qml +186 -0
- package/ui/PathJump.qml +400 -0
- package/ui/PdfViewer.qml +297 -0
- package/ui/PermissionsDialog.qml +658 -0
- package/ui/PermissionsHeadings.qml +31 -0
- package/ui/PhoneMounts.qml +67 -0
- package/ui/PickerAnswers.qml +75 -0
- package/ui/PickerBox.qml +26 -0
- package/ui/PickerChrome.qml +295 -0
- package/ui/PickerFilter.qml +97 -0
- package/ui/PickerGrid.qml +308 -0
- package/ui/PickerHeader.qml +28 -0
- package/ui/PickerLifecycle.qml +27 -0
- package/ui/PickerList.qml +218 -0
- package/ui/PickerListing.qml +149 -0
- package/ui/PickerPathBar.qml +127 -0
- package/ui/PickerPlaces.qml +189 -0
- package/ui/PickerRecent.qml +92 -0
- package/ui/PickerSave.qml +101 -0
- package/ui/PickerSelection.qml +155 -0
- package/ui/PickerWindow.qml +846 -0
- package/ui/PowerSectorsReader.qml +10 -0
- package/ui/PrebuildDriver.qml +146 -0
- package/ui/Preview.qml +1005 -0
- package/ui/PreviewAnimation.qml +24 -0
- package/ui/PreviewArchive.qml +91 -0
- package/ui/PreviewColumn.qml +553 -0
- package/ui/PreviewEdge.qml +63 -0
- package/ui/PreviewFacts.qml +30 -0
- package/ui/PreviewFactsLine.qml +34 -0
- package/ui/PreviewHtml.qml +233 -0
- package/ui/PreviewImage.qml +253 -0
- package/ui/PreviewImagePan.qml +13 -0
- package/ui/PreviewImageSharp.qml +32 -0
- package/ui/PreviewLines.qml +106 -0
- package/ui/PreviewMarkdown.qml +706 -0
- package/ui/PreviewMedia.qml +250 -0
- package/ui/PreviewPdf.qml +482 -0
- package/ui/PreviewScroll.qml +201 -0
- package/ui/PreviewSwap.qml +335 -0
- package/ui/PreviewText.qml +149 -0
- package/ui/ProtocolChip.qml +18 -0
- package/ui/QuickLookArchive.qml +41 -0
- package/ui/QuickLookBar.qml +103 -0
- package/ui/QuickLookPrepare.qml +355 -0
- package/ui/QuickLookSwap.qml +10 -0
- package/ui/QuickLookWarm.qml +65 -0
- package/ui/RailDrop.qml +155 -0
- package/ui/RailHeading.qml +19 -0
- package/ui/RailPlaces.qml +38 -0
- package/ui/RailTrashRow.qml +67 -0
- package/ui/RenameField.qml +353 -0
- package/ui/RendererRetry.qml +11 -0
- package/ui/ResizeHandle.qml +52 -0
- package/ui/Reveal.qml +54 -0
- package/ui/Row.qml +476 -0
- package/ui/RowDrag.qml +213 -0
- package/ui/RowDropTarget.qml +27 -0
- package/ui/RunCard.qml +286 -0
- package/ui/Scripts.qml +65 -0
- package/ui/SearchStrip.qml +232 -0
- package/ui/SelectionBand.qml +140 -0
- package/ui/SelectionPreview.qml +370 -0
- package/ui/SettingsFavourite.qml +122 -0
- package/ui/SettingsGroup.qml +96 -0
- package/ui/SettingsHint.qml +12 -0
- package/ui/SettingsMetrics.qml +29 -0
- package/ui/SettingsPane.qml +178 -0
- package/ui/SettingsPanel.qml +547 -0
- package/ui/SettingsRail.qml +128 -0
- package/ui/SettingsRow.qml +409 -0
- package/ui/SettingsRuler.qml +85 -0
- package/ui/SettingsSegment.qml +85 -0
- package/ui/ShareBrowser.qml +113 -0
- package/ui/ShareLink.qml +67 -0
- package/ui/ShelfPins.qml +101 -0
- package/ui/Sidebar.qml +728 -0
- package/ui/SidebarRow.qml +358 -0
- package/ui/Spinner.qml +60 -0
- package/ui/StableModel.qml +89 -0
- package/ui/StateMessage.qml +84 -0
- package/ui/StatusBar.qml +512 -0
- package/ui/StatusFileName.qml +27 -0
- package/ui/TabBar.qml +673 -0
- package/ui/TabDragGeometry.qml +60 -0
- package/ui/TagMenuMark.qml +52 -0
- package/ui/TagRailSection.qml +53 -0
- package/ui/TagSlot.qml +40 -0
- package/ui/TagState.qml +150 -0
- package/ui/TagSwatch.qml +28 -0
- package/ui/Taildrop.qml +86 -0
- package/ui/TailscaleMark.qml +50 -0
- package/ui/TerminalService.qml +69 -0
- package/ui/TerminalTab.qml +48 -0
- package/ui/TerminalTabs.qml +27 -0
- package/ui/Theme.qml +460 -0
- package/ui/ThemeColors.qml +43 -0
- package/ui/TransferCard.qml +239 -0
- package/ui/TrashConfirm.qml +129 -0
- package/ui/TrashDropHandler.qml +11 -0
- package/ui/TrashHost.qml +202 -0
- package/ui/TrashMonitor.qml +30 -0
- package/ui/TrashToolbar.qml +19 -0
- package/ui/TrashView.qml +492 -0
- package/ui/UnlockDialog.qml +450 -0
- package/ui/UnlockHost.qml +206 -0
- package/ui/UpdateCheck.qml +97 -0
- package/ui/UserDirs.qml +25 -0
- package/ui/ViewState.qml +565 -0
- package/ui/ViewportScrollBar.qml +195 -0
- package/ui/ViewportScrollBars.qml +25 -0
- package/ui/WebPreview.qml +33 -0
- package/ui/WebPreviewView.qml +26 -0
- package/ui/WindowBody.qml +829 -0
- package/ui/WindowDrag.qml +35 -0
- package/ui/boot/Commons/AudioNodes.qml +50 -0
- package/ui/boot/Commons/AudioNodesModel.js +96 -0
- package/ui/boot/Commons/Border.qml +243 -0
- package/ui/boot/Commons/BorderGeometry.js +373 -0
- package/ui/boot/Commons/Color.qml +258 -0
- package/ui/boot/Commons/I18n.qml +118 -0
- package/ui/boot/Commons/InputDevices.qml +112 -0
- package/ui/boot/Commons/InputMethodState.qml +38 -0
- package/ui/boot/Commons/IpcRegistry.qml +77 -0
- package/ui/boot/Commons/Numbers.js +19 -0
- package/ui/boot/Commons/Plural.js +91 -0
- package/ui/boot/Commons/ShellIpc.qml +12 -0
- package/ui/boot/Commons/Style.qml +561 -0
- package/ui/boot/Commons/Translations.qml +100 -0
- package/ui/boot/Commons/UntypedInput.qml +152 -0
- package/ui/boot/Commons/Util.qml +188 -0
- package/ui/boot/Commons/qmldir +13 -0
- package/ui/boot/LICENSE-omarchy +20 -0
- package/ui/boot/Ui/BackgroundMedia.qml +49 -0
- package/ui/boot/Ui/BarIconButton.qml +106 -0
- package/ui/boot/Ui/BarIconContent.qml +38 -0
- package/ui/boot/Ui/BarIndicator.qml +53 -0
- package/ui/boot/Ui/BarWidget.qml +50 -0
- package/ui/boot/Ui/BorderOverlay.qml +54 -0
- package/ui/boot/Ui/BorderSurface.qml +40 -0
- package/ui/boot/Ui/Button.qml +224 -0
- package/ui/boot/Ui/ButtonGroup.qml +131 -0
- package/ui/boot/Ui/ConfirmDialog.qml +134 -0
- package/ui/boot/Ui/CursorSurface.qml +42 -0
- package/ui/boot/Ui/Dropdown.qml +245 -0
- package/ui/boot/Ui/FilterInput.qml +26 -0
- package/ui/boot/Ui/IconContentBounds.qml +141 -0
- package/ui/boot/Ui/KeyboardPanel.qml +453 -0
- package/ui/boot/Ui/MultiSelect.qml +624 -0
- package/ui/boot/Ui/NumberField.qml +86 -0
- package/ui/boot/Ui/OpticalGlyph.qml +68 -0
- package/ui/boot/Ui/OverlayWindow.qml +102 -0
- package/ui/boot/Ui/Panel.qml +60 -0
- package/ui/boot/Ui/PanelActionButton.qml +105 -0
- package/ui/boot/Ui/PanelController.qml +16 -0
- package/ui/boot/Ui/PanelHero.qml +112 -0
- package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
- package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
- package/ui/boot/Ui/PanelSeparator.qml +19 -0
- package/ui/boot/Ui/PanelSlider.qml +156 -0
- package/ui/boot/Ui/PanelToolTip.qml +50 -0
- package/ui/boot/Ui/PluginBarApi.qml +89 -0
- package/ui/boot/Ui/PointerMoveGate.qml +54 -0
- package/ui/boot/Ui/PopupCard.qml +181 -0
- package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
- package/ui/boot/Ui/SearchableDropdown.qml +354 -0
- package/ui/boot/Ui/SizedImage.qml +125 -0
- package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
- package/ui/boot/Ui/TextField.qml +58 -0
- package/ui/boot/Ui/Toggle.qml +118 -0
- package/ui/boot/Ui/ToggleSwitch.qml +115 -0
- package/ui/boot/Ui/WidgetButton.qml +172 -0
- package/ui/boot/Ui/qmldir +41 -0
- package/ui/boot/fleatab.qml +50 -0
- package/ui/boot/picker.qml +39 -0
- package/ui/boot/shell.qml +131 -0
- package/ui/boot/tabtearoff.qml +51 -0
- package/ui/js/Anchor.js +379 -0
- package/ui/js/AnchorHold.js +162 -0
- package/ui/js/Archive.js +157 -0
- package/ui/js/ArchiveCard.js +44 -0
- package/ui/js/ArchiveOps.js +44 -0
- package/ui/js/BackReturn.js +118 -0
- package/ui/js/BulkRename.js +100 -0
- package/ui/js/Buttons.js +54 -0
- package/ui/js/ChromeKeys.js +116 -0
- package/ui/js/ClipMarks.js +73 -0
- package/ui/js/ClipSelection.js +67 -0
- package/ui/js/Clipboard.js +179 -0
- package/ui/js/Cloud.js +97 -0
- package/ui/js/CodeRuns.js +72 -0
- package/ui/js/Collide.js +212 -0
- package/ui/js/ColumnFit.js +28 -0
- package/ui/js/ColumnMenu.js +111 -0
- package/ui/js/Columns.js +298 -0
- package/ui/js/ColumnsCarry.js +103 -0
- package/ui/js/Compare.js +74 -0
- package/ui/js/Contrast.js +157 -0
- package/ui/js/ControlReader.js +42 -0
- package/ui/js/Convert.js +52 -0
- package/ui/js/CopyAs.js +52 -0
- package/ui/js/Crumbs.js +178 -0
- package/ui/js/Csv.js +231 -0
- package/ui/js/Density.js +44 -0
- package/ui/js/Devices.js +440 -0
- package/ui/js/DirSizes.js +180 -0
- package/ui/js/Drag.js +360 -0
- package/ui/js/DragOut.js +166 -0
- package/ui/js/DropDev.js +52 -0
- package/ui/js/Dropbox.js +41 -0
- package/ui/js/Eject.js +217 -0
- package/ui/js/Errors.js +188 -0
- package/ui/js/ExtThumbs.js +115 -0
- package/ui/js/Facts.js +402 -0
- package/ui/js/FigureDate.js +14 -0
- package/ui/js/Filter.js +285 -0
- package/ui/js/Find.js +46 -0
- package/ui/js/Flash.js +184 -0
- package/ui/js/FlashCard.js +79 -0
- package/ui/js/FlashEndings.js +125 -0
- package/ui/js/FlashPane.js +116 -0
- package/ui/js/FleaBin.js +12 -0
- package/ui/js/Focus.js +504 -0
- package/ui/js/FolderSorts.js +108 -0
- package/ui/js/FolderViews.js +44 -0
- package/ui/js/Format.js +314 -0
- package/ui/js/Fuzzy.js +141 -0
- package/ui/js/GlassTag.js +72 -0
- package/ui/js/Grid.js +33 -0
- package/ui/js/GridGeometry.js +90 -0
- package/ui/js/GridNames.js +153 -0
- package/ui/js/GvfsBridge.js +200 -0
- package/ui/js/HostClipboard.js +29 -0
- package/ui/js/Icons.js +218 -0
- package/ui/js/Input.js +50 -0
- package/ui/js/Jump.js +200 -0
- package/ui/js/KeyName.js +64 -0
- package/ui/js/Keymap.js +401 -0
- package/ui/js/Kinds.js +164 -0
- package/ui/js/LICENSES/ISC-lucide.txt +43 -0
- package/ui/js/LangMarkPaths.js +47 -0
- package/ui/js/LangMarks.js +120 -0
- package/ui/js/Lists.js +11 -0
- package/ui/js/LocalSend.js +39 -0
- package/ui/js/LockedMenu.js +63 -0
- package/ui/js/MakeDefault.js +186 -0
- package/ui/js/MarkBox.js +7 -0
- package/ui/js/Markdown.js +119 -0
- package/ui/js/MarkdownLists.js +86 -0
- package/ui/js/MarkdownMaths.js +58 -0
- package/ui/js/MarkdownPictures.js +32 -0
- package/ui/js/MarkdownPrepared.js +139 -0
- package/ui/js/MarkdownTableFit.js +34 -0
- package/ui/js/Marks.js +148 -0
- package/ui/js/Marquee.js +96 -0
- package/ui/js/Match.js +93 -0
- package/ui/js/Material.js +109 -0
- package/ui/js/MdBlocks.js +437 -0
- package/ui/js/MdBreak.js +71 -0
- package/ui/js/MdChunks.js +70 -0
- package/ui/js/MdContainer.js +137 -0
- package/ui/js/MdDocument.js +337 -0
- package/ui/js/MdEmph.js +97 -0
- package/ui/js/MdEntity.js +108 -0
- package/ui/js/MdEntityTable.js +223 -0
- package/ui/js/MdEscape.js +59 -0
- package/ui/js/MdFront.js +37 -0
- package/ui/js/MdHold.js +32 -0
- package/ui/js/MdHtml.js +307 -0
- package/ui/js/MdHtmlBlock.js +290 -0
- package/ui/js/MdHtmlHeading.js +53 -0
- package/ui/js/MdHtmlImage.js +179 -0
- package/ui/js/MdInline.js +154 -0
- package/ui/js/MdItems.js +212 -0
- package/ui/js/MdLeaf.js +309 -0
- package/ui/js/MdLink.js +196 -0
- package/ui/js/MdMath.js +67 -0
- package/ui/js/MdParagraphs.js +138 -0
- package/ui/js/MdRefs.js +232 -0
- package/ui/js/MdResolve.js +226 -0
- package/ui/js/MdRun.js +300 -0
- package/ui/js/MdUrl.js +226 -0
- package/ui/js/Menu.js +514 -0
- package/ui/js/MenuContext.js +85 -0
- package/ui/js/MenuFit.js +13 -0
- package/ui/js/MenuRefresh.js +74 -0
- package/ui/js/MenuWheel.js +35 -0
- package/ui/js/Messages.js +186 -0
- package/ui/js/Motion.js +16 -0
- package/ui/js/Mounts.js +320 -0
- package/ui/js/MouseNav.js +13 -0
- package/ui/js/Nav.js +329 -0
- package/ui/js/NetFs.js +26 -0
- package/ui/js/OpenWith.js +83 -0
- package/ui/js/Ops.js +585 -0
- package/ui/js/Palette.js +33 -0
- package/ui/js/PathBar.js +260 -0
- package/ui/js/Permissions.js +179 -0
- package/ui/js/Phones.js +112 -0
- package/ui/js/Picker.js +353 -0
- package/ui/js/PlaceMenu.js +96 -0
- package/ui/js/Places.js +265 -0
- package/ui/js/PreviewAsk.js +21 -0
- package/ui/js/PreviewKeys.js +155 -0
- package/ui/js/PreviewSettle.js +29 -0
- package/ui/js/PreviewSwap.js +101 -0
- package/ui/js/PropertyFacts.js +144 -0
- package/ui/js/Protocols.js +296 -0
- package/ui/js/QuickLookKinds.js +27 -0
- package/ui/js/QuickLookRect.js +24 -0
- package/ui/js/RailDrop.js +51 -0
- package/ui/js/RailKeys.js +87 -0
- package/ui/js/RailMenu.js +133 -0
- package/ui/js/Recent.js +135 -0
- package/ui/js/RecentMode.js +156 -0
- package/ui/js/Reload.js +60 -0
- package/ui/js/Renderer.js +9 -0
- package/ui/js/RunFile.js +143 -0
- package/ui/js/Scripts.js +28 -0
- package/ui/js/Scroll.js +304 -0
- package/ui/js/ScrollOff.js +69 -0
- package/ui/js/Search.js +478 -0
- package/ui/js/Selection.js +97 -0
- package/ui/js/Settings.js +476 -0
- package/ui/js/SettingsAbout.js +97 -0
- package/ui/js/SettingsShelf.js +52 -0
- package/ui/js/SheetKeys.js +42 -0
- package/ui/js/SheetQuery.js +281 -0
- package/ui/js/ShelfPile.js +27 -0
- package/ui/js/SlowClick.js +53 -0
- package/ui/js/SlowOp.js +6 -0
- package/ui/js/Sort.js +134 -0
- package/ui/js/Startup.js +63 -0
- package/ui/js/StateWords.js +17 -0
- package/ui/js/Status.js +238 -0
- package/ui/js/Swap.js +166 -0
- package/ui/js/TabMove.js +39 -0
- package/ui/js/Tabs.js +751 -0
- package/ui/js/Tags.js +134 -0
- package/ui/js/Taildrop.js +128 -0
- package/ui/js/Tap.js +180 -0
- package/ui/js/TextSize.js +107 -0
- package/ui/js/Thumbs.js +158 -0
- package/ui/js/Transfer.js +172 -0
- package/ui/js/Trash.js +84 -0
- package/ui/js/TrashDates.js +47 -0
- package/ui/js/TrashDrop.js +64 -0
- package/ui/js/UiState.js +438 -0
- package/ui/js/Unlock.js +152 -0
- package/ui/js/Update.js +130 -0
- package/ui/js/UserDirs.js +56 -0
- package/ui/qmldir +230 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Shapes
|
|
3
|
+
import "." as Flea
|
|
4
|
+
import "js/Icons.js" as Icons
|
|
5
|
+
import "js/Markdown.js" as Markdown
|
|
6
|
+
|
|
7
|
+
// The board's placeholder spans the content with a dashed muted box around a left-aligned muted image glyph and sentence on one line.
|
|
8
|
+
Item {
|
|
9
|
+
id: root
|
|
10
|
+
|
|
11
|
+
// The blocked image's host, which the sentence names.
|
|
12
|
+
property string host: ""
|
|
13
|
+
// RenderedPreviews' remote box is a 1 px CSS dashed border: 3 px dashes with 3 px gaps.
|
|
14
|
+
readonly property int dashPx: 3
|
|
15
|
+
readonly property int dashPitch: 2 * root.dashPx
|
|
16
|
+
// The delegate sets the width; the dashes and the sentence follow it.
|
|
17
|
+
height: remoteRow.implicitHeight + 2 * Theme.spacing.gap
|
|
18
|
+
|
|
19
|
+
// The dashes a side of this length holds, laid from its corner: the last one ends at the returned offset.
|
|
20
|
+
// Sample input: 20 answers 15, three dashes at 0, 6 and 12 ending at 15.
|
|
21
|
+
function dashEnd(length) {
|
|
22
|
+
return (Math.max(1, Math.floor((length + root.dashPx) / root.dashPitch)) - 1) * root.dashPitch + root.dashPx
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// The four sides as SVG subpaths, each dashing from its own corner and running half a stroke inside the box.
|
|
26
|
+
// Sample input: (20, 10) with a 1 px hairline answers "M0 0.5 L15 0.5 M0 9.5 L15 9.5 M0.5 0 L0.5 9 M19.5 0 L19.5 9".
|
|
27
|
+
function borderPath(w, h) {
|
|
28
|
+
var half = Theme.spacing.hairline / 2
|
|
29
|
+
var across = root.dashEnd(w)
|
|
30
|
+
var down = root.dashEnd(h)
|
|
31
|
+
return "M0 " + half + " L" + across + " " + half + " M0 " + (h - half) + " L" + across + " " + (h - half)
|
|
32
|
+
+ " M" + half + " 0 L" + half + " " + down + " M" + (w - half) + " 0 L" + (w - half) + " " + down
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// One Shape draws all four sides, so a wide card builds a handful of objects instead of a Rectangle per dash.
|
|
36
|
+
Shape {
|
|
37
|
+
id: dashes
|
|
38
|
+
anchors.fill: parent
|
|
39
|
+
|
|
40
|
+
ShapePath {
|
|
41
|
+
strokeColor: Theme.color.mutedFrame
|
|
42
|
+
strokeWidth: Theme.spacing.hairline
|
|
43
|
+
fillColor: "transparent"
|
|
44
|
+
strokeStyle: ShapePath.DashLine
|
|
45
|
+
// A dash is dashPx long in units of the stroke width, which the hairline sets.
|
|
46
|
+
dashPattern: [root.dashPx / Theme.spacing.hairline, root.dashPx / Theme.spacing.hairline]
|
|
47
|
+
capStyle: ShapePath.FlatCap
|
|
48
|
+
PathSvg { path: root.borderPath(root.width, root.height) }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Row {
|
|
53
|
+
id: remoteRow
|
|
54
|
+
anchors.left: parent.left
|
|
55
|
+
anchors.leftMargin: Theme.spacing.gap
|
|
56
|
+
anchors.right: parent.right
|
|
57
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
58
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
59
|
+
spacing: Theme.spacing.gap
|
|
60
|
+
|
|
61
|
+
Flea.Glyph {
|
|
62
|
+
id: remoteMark
|
|
63
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
64
|
+
width: Theme.chromeMarkSize
|
|
65
|
+
height: Theme.chromeMarkSize
|
|
66
|
+
maxSize: Theme.chromeMarkSize
|
|
67
|
+
name: Icons.glyphFor("image-x-generic")
|
|
68
|
+
color: Theme.color.mutedFrame
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Text {
|
|
72
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
73
|
+
width: parent.width - remoteMark.width - parent.spacing
|
|
74
|
+
text: Markdown.placeholder(root.host)
|
|
75
|
+
color: Theme.color.muted
|
|
76
|
+
font.family: Theme.font.family
|
|
77
|
+
font.pixelSize: Theme.font.caption
|
|
78
|
+
textFormat: Text.PlainText
|
|
79
|
+
elide: Text.ElideRight
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "." as Flea
|
|
3
|
+
import "js/CodeRuns.js" as CodeRuns
|
|
4
|
+
|
|
5
|
+
// The Source view: the file's lines coloured by the backend's code engine and numbered, asked a screen at a time through CodeLines.
|
|
6
|
+
Item {
|
|
7
|
+
id: root
|
|
8
|
+
|
|
9
|
+
// The whole text, empty while Rendered shows; a save changes it, so the lines are asked again.
|
|
10
|
+
property string text: ""
|
|
11
|
+
property string path: ""
|
|
12
|
+
// True on network and phone storage, where the backend is never given the path.
|
|
13
|
+
property bool truncate: false
|
|
14
|
+
property var backend: null
|
|
15
|
+
// The backend's name for this pane's Source ask, so a sibling pane's ask never ends it.
|
|
16
|
+
property string slot: "look"
|
|
17
|
+
property bool active: false
|
|
18
|
+
// The document's read or listing-size refusal also applies when no code request can be made.
|
|
19
|
+
property bool tooLarge: false
|
|
20
|
+
property bool readFailed: false
|
|
21
|
+
// The wrap the code view uses: a long line ends in an ellipsis until w wraps it.
|
|
22
|
+
property bool wrap: false
|
|
23
|
+
property int insetX: 0
|
|
24
|
+
property int insetY: 0
|
|
25
|
+
// The notice drawn above the first line, empty for none, and the gap between it and the text.
|
|
26
|
+
property string notice: ""
|
|
27
|
+
property int blockGap: 0
|
|
28
|
+
property int bodyPx: Theme.font.body
|
|
29
|
+
// The lines are built on the first Source view and kept after it, so a Rendered file builds no CodeLines.
|
|
30
|
+
property bool built: false
|
|
31
|
+
Component.onCompleted: root.built = root.active
|
|
32
|
+
onActiveChanged: if (root.active) root.built = true
|
|
33
|
+
readonly property bool engine: root.backend !== null && typeof root.backend.askCode === "function"
|
|
34
|
+
// The CodeLines once built, null before.
|
|
35
|
+
readonly property var lines: frame.item !== null ? frame.item.lines : null
|
|
36
|
+
// CodeLines' scrolling view, which the scroll bar and the wheel read.
|
|
37
|
+
readonly property var list: frame.item !== null ? frame.item.list : null
|
|
38
|
+
readonly property bool binary: root.lines !== null && root.lines.answer === "binary"
|
|
39
|
+
readonly property bool large: root.tooLarge || (root.lines !== null && root.lines.answer === "large")
|
|
40
|
+
readonly property bool failed: root.readFailed || (root.lines !== null && root.lines.answer === "failed")
|
|
41
|
+
readonly property bool refused: root.binary || root.large || root.failed
|
|
42
|
+
readonly property string status: root.large ? "This file is too large to preview." : root.failed ? "This file could not be read." : root.firstScreen ? "ready" : "loading"
|
|
43
|
+
// Characters of the rows the list lays out, re-read as it scrolls or an answer lands.
|
|
44
|
+
readonly property int laidChars: root.list === null ? 0 : root.laidOf(root.list.contentY, root.lines.stamp)
|
|
45
|
+
// Lines in view are answered; a file the backend refused (binary, large, failed) has no lines, so it is no screen to wait for.
|
|
46
|
+
readonly property bool firstScreen: root.refused || (root.lines !== null && root.lines.firstScreen)
|
|
47
|
+
readonly property Item noticeItem: root.list !== null && root.list.headerItem !== null ? root.list.headerItem.notice : null
|
|
48
|
+
|
|
49
|
+
function laidOf(top, stamp) {
|
|
50
|
+
var n = 0
|
|
51
|
+
var rows = root.list.contentItem.children
|
|
52
|
+
for (var i = 0; i < rows.length; i++)
|
|
53
|
+
if (rows[i].index !== undefined && rows[i].children.length === 2) {
|
|
54
|
+
var runs = root.lines.rowAt(rows[i].index + 1)
|
|
55
|
+
if (runs) n += CodeRuns.plain(runs).length
|
|
56
|
+
}
|
|
57
|
+
return n
|
|
58
|
+
}
|
|
59
|
+
function keepTop(top) {
|
|
60
|
+
root.list.forceLayout()
|
|
61
|
+
root.list.positionViewAtIndex(top, ListView.Beginning)
|
|
62
|
+
}
|
|
63
|
+
// The line at the top of the view stays at the top while the rows change width.
|
|
64
|
+
onWrapChanged: if (root.list !== null) Qt.callLater(root.keepTop, Math.max(0, root.list.indexAt(0, root.list.contentY + 1)))
|
|
65
|
+
|
|
66
|
+
// The notice sits above the first line and scrolls with the rows, so the list never moves under a change to it.
|
|
67
|
+
Component {
|
|
68
|
+
id: noticeHeader
|
|
69
|
+
|
|
70
|
+
Item {
|
|
71
|
+
id: noticeRow
|
|
72
|
+
// The notice's Text, which the pane and the suites read for its place.
|
|
73
|
+
readonly property Item notice: deepNotice
|
|
74
|
+
width: ListView.view.width
|
|
75
|
+
height: root.notice !== "" ? deepNotice.height + root.blockGap : 0
|
|
76
|
+
visible: root.notice !== ""
|
|
77
|
+
onHeightChanged: if (root.list !== null && root.notice !== "") Qt.callLater(root.list.positionViewAtBeginning)
|
|
78
|
+
|
|
79
|
+
Text {
|
|
80
|
+
id: deepNotice
|
|
81
|
+
width: noticeRow.width
|
|
82
|
+
visible: root.notice !== ""
|
|
83
|
+
text: root.notice
|
|
84
|
+
textFormat: Text.PlainText
|
|
85
|
+
elide: Text.ElideRight
|
|
86
|
+
color: Theme.color.muted
|
|
87
|
+
font.family: Theme.font.family
|
|
88
|
+
font.pixelSize: Theme.font.caption
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Without an engine the backend cannot colour a line, so the text the caller holds is drawn plain.
|
|
94
|
+
Loader {
|
|
95
|
+
id: frame
|
|
96
|
+
anchors.fill: parent
|
|
97
|
+
active: root.built
|
|
98
|
+
|
|
99
|
+
sourceComponent: Item {
|
|
100
|
+
id: frameItem
|
|
101
|
+
anchors.fill: parent
|
|
102
|
+
property alias lines: codeLines
|
|
103
|
+
Component.onCompleted: Qt.callLater(frameItem.list.positionViewAtBeginning)
|
|
104
|
+
// CodeLines' scrolling view, its one Flickable child.
|
|
105
|
+
readonly property var list: {
|
|
106
|
+
var kids = codeLines.children
|
|
107
|
+
for (var i = 0; i < kids.length; i++)
|
|
108
|
+
if (kids[i].contentY !== undefined) return kids[i]
|
|
109
|
+
return null
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Flea.CodeLines {
|
|
113
|
+
id: codeLines
|
|
114
|
+
anchors.fill: parent
|
|
115
|
+
anchors.leftMargin: root.insetX
|
|
116
|
+
anchors.rightMargin: root.insetX
|
|
117
|
+
anchors.topMargin: root.insetY
|
|
118
|
+
anchors.bottomMargin: root.insetY
|
|
119
|
+
visible: !root.refused
|
|
120
|
+
backend: root.backend
|
|
121
|
+
slot: root.slot
|
|
122
|
+
path: root.path
|
|
123
|
+
fromText: root.truncate || !root.engine
|
|
124
|
+
text: root.text
|
|
125
|
+
active: root.active && !root.tooLarge
|
|
126
|
+
numbered: true
|
|
127
|
+
wrap: root.wrap
|
|
128
|
+
scrolls: true
|
|
129
|
+
pixelSize: root.bodyPx
|
|
130
|
+
header: noticeHeader
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The wheel and the bar belong to the frame, as in Rendered: the bar sits on the frame edge beside the list's top.
|
|
134
|
+
Flea.FastScrollHandler {
|
|
135
|
+
flickable: frameItem.list
|
|
136
|
+
visible: !root.refused
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
Flea.ViewportScrollBar {
|
|
140
|
+
anchors { top: parent.top; topMargin: root.insetY; right: parent.right }
|
|
141
|
+
flickable: frameItem.list
|
|
142
|
+
visible: !root.refused
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Flea.CodeRefusal {
|
|
148
|
+
anchors.fill: parent
|
|
149
|
+
visible: root.refused
|
|
150
|
+
binary: root.binary
|
|
151
|
+
tooLarge: root.large
|
|
152
|
+
failed: root.failed
|
|
153
|
+
markName: "markdown"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "." as Flea
|
|
3
|
+
import "js/Markdown.js" as Markdown
|
|
4
|
+
import "js/MarkdownTableFit.js" as Fit
|
|
5
|
+
import "js/Scroll.js" as Scroll
|
|
6
|
+
|
|
7
|
+
// A table hugs its cells with Grid, Column and Row, never QtQuick.Layouts, so the preview never loads it.
|
|
8
|
+
Column {
|
|
9
|
+
id: root
|
|
10
|
+
objectName: "tableGrid"
|
|
11
|
+
|
|
12
|
+
// The parsed table chunk, and the preview that sets the document's size and gap.
|
|
13
|
+
property var block: ({ head: [], aligns: [], rows: [], measure: [], pictures: [], weights: [], words: [], cols: 0 })
|
|
14
|
+
property Item preview: null
|
|
15
|
+
// The width the block column gives the table; columns wrap inside it, and 0 means no limit.
|
|
16
|
+
property real availableWidth: 0
|
|
17
|
+
readonly property int bodyPx: root.preview.bodyPx
|
|
18
|
+
// A chunk after the first sits flush under its predecessor, across the gap the list puts between blocks.
|
|
19
|
+
y: root.block.joined === true ? -root.preview.blockGap : 0
|
|
20
|
+
// A table wider than its block clips to the block and scrolls sideways; the bar's lane is reserved under it, once under a chunked table's last chunk, and under no fitting table.
|
|
21
|
+
width: root.overflows ? root.availableWidth : root.tableWidth
|
|
22
|
+
clip: root.overflows
|
|
23
|
+
readonly property bool lane: root.overflows && root.block.last !== false
|
|
24
|
+
bottomPadding: root.lane ? Theme.spacing.rowPaddingX : 0
|
|
25
|
+
spacing: 0
|
|
26
|
+
|
|
27
|
+
// The sideways scroll, built when the table overflows and dropped when it stops: a table that fits owns no object for it, which the block cost gates count.
|
|
28
|
+
property Item scroller: null
|
|
29
|
+
function syncScroller() {
|
|
30
|
+
if (root.scroller === null && root.overflows) {
|
|
31
|
+
root.scroller = Qt.createComponent("MarkdownTableScroll.qml").createObject(root, { table: root })
|
|
32
|
+
} else if (root.scroller !== null && !root.overflows) {
|
|
33
|
+
root.scroller.destroy()
|
|
34
|
+
root.scroller = null
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
onOverflowsChanged: root.syncScroller()
|
|
38
|
+
Component.onCompleted: root.syncScroller()
|
|
39
|
+
// Every row slides by the scroll position under the clip, so a table that fits sits at zero.
|
|
40
|
+
readonly property real shift: root.overflows && root.scroller !== null ? -root.scroller.contentX : 0
|
|
41
|
+
|
|
42
|
+
Row {
|
|
43
|
+
id: headerRow
|
|
44
|
+
x: root.shift
|
|
45
|
+
spacing: root.cellGap
|
|
46
|
+
|
|
47
|
+
Repeater {
|
|
48
|
+
model: root.block.head.length
|
|
49
|
+
delegate: Flea.MarkdownText {
|
|
50
|
+
linkGate: Markdown.isExternalLink
|
|
51
|
+
width: root.textWidth(index)
|
|
52
|
+
bodyPx: root.bodyPx
|
|
53
|
+
cellPad: 2
|
|
54
|
+
markdown: root.block.head[index]
|
|
55
|
+
horizontalAlignment: root.alignAt(index)
|
|
56
|
+
font.bold: true
|
|
57
|
+
color: Theme.color.foregroundBright
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Rectangle {
|
|
63
|
+
visible: root.block.head.length > 0
|
|
64
|
+
x: root.shift
|
|
65
|
+
width: root.tableWidth
|
|
66
|
+
height: Theme.spacing.hairline
|
|
67
|
+
color: Theme.color.foreground
|
|
68
|
+
opacity: root.preview.ruleOpacity
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Repeater {
|
|
72
|
+
id: bodyRows
|
|
73
|
+
model: root.block.rows.length
|
|
74
|
+
delegate: Column {
|
|
75
|
+
readonly property int row: index
|
|
76
|
+
x: root.shift
|
|
77
|
+
width: root.tableWidth
|
|
78
|
+
spacing: 0
|
|
79
|
+
|
|
80
|
+
Row {
|
|
81
|
+
spacing: root.cellGap
|
|
82
|
+
|
|
83
|
+
Repeater {
|
|
84
|
+
model: root.columns
|
|
85
|
+
delegate: Flea.MarkdownText {
|
|
86
|
+
linkGate: Markdown.isExternalLink
|
|
87
|
+
width: root.textWidth(index)
|
|
88
|
+
bodyPx: root.bodyPx
|
|
89
|
+
cellPad: 2
|
|
90
|
+
markdown: root.cellAt(row, index)
|
|
91
|
+
horizontalAlignment: root.alignAt(index)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Rectangle {
|
|
97
|
+
width: root.tableWidth
|
|
98
|
+
height: Theme.spacing.hairline
|
|
99
|
+
color: Theme.color.foreground
|
|
100
|
+
opacity: root.preview.ruleOpacity
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Invisible measurers carry each column's widest cell plus a second for an image cell, since the parser cannot know the image's width.
|
|
106
|
+
Repeater {
|
|
107
|
+
id: measurers
|
|
108
|
+
model: root.measureTexts
|
|
109
|
+
delegate: Text {
|
|
110
|
+
objectName: "measurer"
|
|
111
|
+
visible: false
|
|
112
|
+
text: modelData
|
|
113
|
+
textFormat: Text.MarkdownText
|
|
114
|
+
font.family: Theme.font.family
|
|
115
|
+
font.pixelSize: root.bodyPx
|
|
116
|
+
// A header cell may set the width and is bold, so every measurer is: chunks without the header must agree.
|
|
117
|
+
font.bold: true
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// The measure of each column, then the picture cell of every column that has one, in the order the measurers are built.
|
|
122
|
+
readonly property var measureTexts: {
|
|
123
|
+
var texts = []
|
|
124
|
+
var pictures = root.block.pictures || []
|
|
125
|
+
for (var c = 0; c < root.columns; c++)
|
|
126
|
+
texts.push(c < root.block.measure.length ? root.block.measure[c] : "")
|
|
127
|
+
for (var p = 0; p < root.columns; p++) {
|
|
128
|
+
if (p < pictures.length && pictures[p] !== "")
|
|
129
|
+
texts.push(pictures[p])
|
|
130
|
+
}
|
|
131
|
+
return texts
|
|
132
|
+
}
|
|
133
|
+
// The empty gap each column keeps beside its text, and the width of one glyph when the parser measured no text.
|
|
134
|
+
readonly property int cellGap: 14
|
|
135
|
+
readonly property real fallbackGlyphEm: 0.6
|
|
136
|
+
// A column's text width: the wider of its measure and its picture cell, once the measurers have laid out.
|
|
137
|
+
readonly property var columnPx: {
|
|
138
|
+
// Count and implicitWidth notify when a measurer arrives and lays out; itemAt alone notifies nothing.
|
|
139
|
+
var widths = []
|
|
140
|
+
var pictures = root.block.pictures || []
|
|
141
|
+
var next = root.columns
|
|
142
|
+
for (var c = 0; c < root.columns; c++) {
|
|
143
|
+
var own = measurers.count > c ? measurers.itemAt(c) : null
|
|
144
|
+
var px = own ? own.implicitWidth : 0
|
|
145
|
+
if (c < pictures.length && pictures[c] !== "") {
|
|
146
|
+
var extra = measurers.count > next ? measurers.itemAt(next) : null
|
|
147
|
+
px = Math.max(px, extra ? extra.implicitWidth : 0)
|
|
148
|
+
next++
|
|
149
|
+
}
|
|
150
|
+
widths.push(px)
|
|
151
|
+
}
|
|
152
|
+
return widths
|
|
153
|
+
}
|
|
154
|
+
// A column's text width beside its picture width: the parser weighs text alone, so the glyph price divides text by text.
|
|
155
|
+
readonly property var textPx: {
|
|
156
|
+
// Count and implicitWidth notify when a measurer arrives and lays out; itemAt alone notifies nothing.
|
|
157
|
+
var widths = []
|
|
158
|
+
for (var c = 0; c < root.columns; c++) {
|
|
159
|
+
var own = measurers.count > c ? measurers.itemAt(c) : null
|
|
160
|
+
widths.push(own ? own.implicitWidth : 0)
|
|
161
|
+
}
|
|
162
|
+
return widths
|
|
163
|
+
}
|
|
164
|
+
// Pixels a column of the parser's width weight draws: the table's measured text over its weight, so the longest word converts to pixels.
|
|
165
|
+
readonly property real glyphPx: {
|
|
166
|
+
var px = 0
|
|
167
|
+
var weight = 0
|
|
168
|
+
var weights = root.block.weights || []
|
|
169
|
+
for (var c = 0; c < root.columns; c++) {
|
|
170
|
+
if (c < weights.length && weights[c] > 0) {
|
|
171
|
+
px += root.textPx[c]
|
|
172
|
+
weight += weights[c]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return weight > 0 ? px / weight : root.bodyPx * root.fallbackGlyphEm
|
|
176
|
+
}
|
|
177
|
+
// Each column's width: natural when the table fits the block, else shared by Fit with every column keeping its longest word first.
|
|
178
|
+
readonly property var widths: {
|
|
179
|
+
var natural = []
|
|
180
|
+
var minimum = []
|
|
181
|
+
var words = root.block.words || []
|
|
182
|
+
for (var c = 0; c < root.columns; c++) {
|
|
183
|
+
// Whole pixels up: Fit floors its shares, and a text box a fraction short of its word breaks the word.
|
|
184
|
+
natural.push(Math.ceil(root.columnPx[c]) + root.cellGap)
|
|
185
|
+
minimum.push(Math.ceil((c < words.length ? words[c] : 0) * root.glyphPx) + root.cellGap)
|
|
186
|
+
}
|
|
187
|
+
// A wide glyph takes two, so no column goes under two glyphs of text.
|
|
188
|
+
var least = root.cellGap + Math.ceil(2 * root.glyphPx)
|
|
189
|
+
return root.availableWidth > 0 ? Fit.fit(natural, minimum, root.availableWidth, least) : natural
|
|
190
|
+
}
|
|
191
|
+
readonly property real tableWidth: {
|
|
192
|
+
var total = 0
|
|
193
|
+
for (var c = 0; c < root.widths.length; c++)
|
|
194
|
+
total += root.widths[c]
|
|
195
|
+
return total
|
|
196
|
+
}
|
|
197
|
+
// Wider than its block once every column holds its longest word whole; the block's width then bounds the table.
|
|
198
|
+
readonly property bool overflows: root.availableWidth > 0 && root.tableWidth - root.availableWidth > Scroll.OVERFLOW_PX
|
|
199
|
+
|
|
200
|
+
// The first body row, which the capture's IPC aims its wheel at.
|
|
201
|
+
function firstRow() { return bodyRows.itemAt(0) }
|
|
202
|
+
|
|
203
|
+
// Helpers over the block, so delegates read cells and alignment by place.
|
|
204
|
+
readonly property int columns: Math.max(1, root.block.cols)
|
|
205
|
+
function alignName(i) {
|
|
206
|
+
return i < root.block.aligns.length ? root.block.aligns[i] : "left"
|
|
207
|
+
}
|
|
208
|
+
function alignAt(i) {
|
|
209
|
+
var name = root.alignName(i)
|
|
210
|
+
return name === "center" ? Text.AlignHCenter : name === "right" ? Text.AlignRight : Text.AlignLeft
|
|
211
|
+
}
|
|
212
|
+
function cellAt(r, c) {
|
|
213
|
+
return r < root.block.rows.length && c < root.block.rows[r].length ? root.block.rows[r][c] : ""
|
|
214
|
+
}
|
|
215
|
+
function colWidth(col) {
|
|
216
|
+
return col < root.widths.length ? root.widths[col] : 0
|
|
217
|
+
}
|
|
218
|
+
// A cell's text stays inside its column's share minus the gap the next cell starts after, so the gap never holds ink.
|
|
219
|
+
function textWidth(col) {
|
|
220
|
+
return Math.max(0, root.colWidth(col) - root.cellGap)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "." as Flea
|
|
3
|
+
import "js/Scroll.js" as Scroll
|
|
4
|
+
|
|
5
|
+
// The sideways scroll of a table wider than its block: the position and extent the table's rows slide by, the bar under the table, and the wheel's arithmetic.
|
|
6
|
+
Flickable {
|
|
7
|
+
id: root
|
|
8
|
+
objectName: "tableScroll"
|
|
9
|
+
|
|
10
|
+
required property Item table
|
|
11
|
+
|
|
12
|
+
// A sibling of the table in the block, laid over it. A positioner would stack it as a row, so under one it takes the positioner's parent and offset.
|
|
13
|
+
readonly property Item flow: root.table.parent !== null && root.table.parent.move !== undefined ? root.table.parent : null
|
|
14
|
+
// The key every chunk of one table shares, undefined for a table in one piece.
|
|
15
|
+
readonly property var group: root.table.block.tableKey
|
|
16
|
+
parent: root.flow !== null ? root.flow.parent : root.table.parent
|
|
17
|
+
x: root.table.x + (root.flow !== null ? root.flow.x : 0)
|
|
18
|
+
y: root.table.y + (root.flow !== null ? root.flow.y : 0)
|
|
19
|
+
z: 1
|
|
20
|
+
width: root.table.width
|
|
21
|
+
height: root.table.height
|
|
22
|
+
contentWidth: root.table.tableWidth
|
|
23
|
+
contentHeight: root.height
|
|
24
|
+
// Only the wheel and the bar move it: a disabled item takes none of the presses the table's links and cells need.
|
|
25
|
+
enabled: false
|
|
26
|
+
// The chunks of one table follow one position, whichever of them the wheel is over.
|
|
27
|
+
onContentXChanged: if (root.route !== null) root.route.follow(root)
|
|
28
|
+
onWidthChanged: root.returnToBounds()
|
|
29
|
+
onContentWidthChanged: root.returnToBounds()
|
|
30
|
+
|
|
31
|
+
// The router calls this for a stroke it gave the table, since the disabled handler below gets no event of its own.
|
|
32
|
+
function wheel(event) {
|
|
33
|
+
return wheelHandler.handleWheel(event)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Kept from the start, since the table is already going when this is destroyed with it.
|
|
37
|
+
property Item route: null
|
|
38
|
+
Component.onCompleted: {
|
|
39
|
+
root.route = root.table.preview !== null && root.table.preview.tableWheel ? root.table.preview.tableWheel : null
|
|
40
|
+
if (root.route !== null)
|
|
41
|
+
root.route.add(root)
|
|
42
|
+
}
|
|
43
|
+
Component.onDestruction: {
|
|
44
|
+
if (root.route !== null)
|
|
45
|
+
root.route.remove(root)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
Flea.FastScrollHandler {
|
|
49
|
+
id: wheelHandler
|
|
50
|
+
parent: root
|
|
51
|
+
flickable: root
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The bar draws under the table, in the lane the table reserved; the lane shows it only while moving, hovered or dragged.
|
|
55
|
+
Flea.ViewportScrollBar {
|
|
56
|
+
parent: root.parent
|
|
57
|
+
// Only the last chunk of a table holds the lane, so a joined chunk stays flush under the one above.
|
|
58
|
+
visible: root.table.lane && root.contentWidth - root.width > Scroll.OVERFLOW_PX
|
|
59
|
+
x: root.x
|
|
60
|
+
y: root.y + root.height - height
|
|
61
|
+
flickable: root
|
|
62
|
+
orientation: Qt.Horizontal
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "js/Scroll.js" as Scroll
|
|
3
|
+
|
|
4
|
+
// A wheel or swipe that goes sideways over a table wider than its block scrolls that table; a vertical one is left for the document's handler beneath.
|
|
5
|
+
MouseArea {
|
|
6
|
+
id: root
|
|
7
|
+
objectName: "tableWheel"
|
|
8
|
+
|
|
9
|
+
// The sideways scrolls alive in the document, which each adds itself to and drops itself from.
|
|
10
|
+
property var scrollers: []
|
|
11
|
+
// The table a touchpad stroke went to until it ends, and whether the stroke went to the document instead.
|
|
12
|
+
property var held: null
|
|
13
|
+
property bool documentStroke: false
|
|
14
|
+
// The sideways position each chunked table was last left at, by key, so a chunk built later joins it.
|
|
15
|
+
property var positions: ({})
|
|
16
|
+
|
|
17
|
+
anchors.fill: parent
|
|
18
|
+
// A press is never taken: the table's links and the document's own handler need them.
|
|
19
|
+
acceptedButtons: Qt.NoButton
|
|
20
|
+
// Over the document's FastScrollHandler (z 1000), so a sideways stroke reaches the table first.
|
|
21
|
+
z: 1001
|
|
22
|
+
|
|
23
|
+
function add(scroller) {
|
|
24
|
+
root.scrollers = root.scrollers.concat([scroller])
|
|
25
|
+
if (scroller.group !== undefined && root.positions[scroller.group] !== undefined)
|
|
26
|
+
scroller.contentX = root.positions[scroller.group]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// The other chunks of this scroller's table move to its position.
|
|
30
|
+
function follow(scroller) {
|
|
31
|
+
if (scroller.group === undefined)
|
|
32
|
+
return
|
|
33
|
+
root.positions[scroller.group] = scroller.contentX
|
|
34
|
+
for (var i = 0; i < root.scrollers.length; i++) {
|
|
35
|
+
var other = root.scrollers[i]
|
|
36
|
+
if (other && other !== scroller && other.group === scroller.group && other.contentX !== scroller.contentX)
|
|
37
|
+
other.contentX = scroller.contentX
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function remove(scroller) {
|
|
42
|
+
root.scrollers = root.scrollers.filter(function (s) { return s && s !== scroller })
|
|
43
|
+
if (root.held === scroller)
|
|
44
|
+
root.held = null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// A new document forgets the old one's sideways places; chunks of the live one still join.
|
|
48
|
+
function reset() {
|
|
49
|
+
root.positions = {}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The overflowing table under a point of this item, else null.
|
|
53
|
+
function scrollerAt(x, y) {
|
|
54
|
+
for (var i = 0; i < root.scrollers.length; i++) {
|
|
55
|
+
var s = root.scrollers[i]
|
|
56
|
+
if (!s || !s.visible || !s.table || !s.table.overflows)
|
|
57
|
+
continue
|
|
58
|
+
var at = s.mapFromItem(root, x, y)
|
|
59
|
+
if (at.x >= 0 && at.y >= 0 && at.x < s.width && at.y < s.height)
|
|
60
|
+
return s
|
|
61
|
+
}
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// The sideways distance of an event: Shift turns a vertical wheel notch sideways, as it does in a browser.
|
|
66
|
+
function across(event, axis) {
|
|
67
|
+
var pixel = Number(event.pixelDelta.x) || 0
|
|
68
|
+
var angle = Number(event.angleDelta.x) || 0
|
|
69
|
+
if ((event.modifiers & Qt.ShiftModifier) && pixel === 0 && angle === 0)
|
|
70
|
+
return axis === "pixel" ? Number(event.pixelDelta.y) || 0 : Number(event.angleDelta.y) || 0
|
|
71
|
+
return axis === "pixel" ? pixel : angle
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Sideways when its sideways travel beats its vertical in the unit the event carries, or Shift holds a notch; Shift on a vertical notch is sideways.
|
|
75
|
+
function sideways(event) {
|
|
76
|
+
var pixel = (Number(event.pixelDelta.x) || 0) !== 0 || (Number(event.pixelDelta.y) || 0) !== 0
|
|
77
|
+
var x = Math.abs(root.across(event, pixel ? "pixel" : "angle"))
|
|
78
|
+
var y = Math.abs(Number(pixel ? event.pixelDelta.y : event.angleDelta.y) || 0)
|
|
79
|
+
return (event.modifiers & Qt.ShiftModifier) ? x !== 0 : x > y
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// A table's wheel takes sideways deltas only; the vertical ones stay with the document.
|
|
83
|
+
function sidewaysEvent(event) {
|
|
84
|
+
return { pixelDelta: { x: root.across(event, "pixel"), y: 0 }, angleDelta: { x: root.across(event, "angle"), y: 0 },
|
|
85
|
+
modifiers: event.modifiers & ~Qt.ShiftModifier, phase: event.phase !== undefined ? event.phase : Qt.NoScrollPhase, accepted: false }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// True when the table took the event; a false answer leaves it to the document's handler under this one.
|
|
89
|
+
function route(event) {
|
|
90
|
+
if (event.modifiers & Qt.ControlModifier)
|
|
91
|
+
return false
|
|
92
|
+
var phase = event.phase !== undefined ? event.phase : Qt.NoScrollPhase
|
|
93
|
+
var at = root.scrollerAt(event.x, event.y)
|
|
94
|
+
if (!Scroll.isTouchpad(phase)) {
|
|
95
|
+
if (at === null || !root.sideways(event))
|
|
96
|
+
return false
|
|
97
|
+
at.wheel(root.sidewaysEvent(event))
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
100
|
+
if (phase === Qt.ScrollBegin) {
|
|
101
|
+
root.held = null
|
|
102
|
+
root.documentStroke = false
|
|
103
|
+
// The table stops its own coasting on a new touch, and the document hears the Begin as well.
|
|
104
|
+
if (at !== null)
|
|
105
|
+
at.wheel(root.sidewaysEvent(event))
|
|
106
|
+
return false
|
|
107
|
+
}
|
|
108
|
+
if (root.held === null && !root.documentStroke && phase !== Qt.ScrollEnd) {
|
|
109
|
+
if (at !== null && root.sideways(event))
|
|
110
|
+
root.held = at
|
|
111
|
+
else if ((Number(event.pixelDelta.x) || 0) !== 0 || (Number(event.pixelDelta.y) || 0) !== 0)
|
|
112
|
+
root.documentStroke = true
|
|
113
|
+
}
|
|
114
|
+
var taker = root.held
|
|
115
|
+
if (phase === Qt.ScrollEnd) {
|
|
116
|
+
root.held = null
|
|
117
|
+
root.documentStroke = false
|
|
118
|
+
}
|
|
119
|
+
if (taker === null)
|
|
120
|
+
return false
|
|
121
|
+
taker.wheel(root.sidewaysEvent(event))
|
|
122
|
+
return true
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
onWheel: function (wheel) { wheel.accepted = root.route(wheel) }
|
|
126
|
+
}
|