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.
- package/LICENSE +22 -0
- package/README.md +478 -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 +402 -0
- package/src/archiveops.js +697 -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 +129 -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/transfer.js +669 -0
- package/src/trash-record.js +41 -0
- package/src/trash.js +210 -0
- package/src/trashbrowse.js +326 -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 +241 -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-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-html-security.mjs +23 -0
- package/test/manual-html-ui.mjs +30 -0
- package/test/manual-syntax-preview.mjs +26 -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 +68 -0
- package/ui/ArchiveCompressDialog.qml +378 -0
- package/ui/ArchivePasswordDialog.qml +257 -0
- package/ui/Backend.qml +771 -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 +523 -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 +115 -0
- package/ui/Pane.qml +1296 -0
- package/ui/PaneMenuActions.qml +527 -0
- package/ui/PanePath.qml +90 -0
- package/ui/PaneRail.qml +239 -0
- package/ui/PaneStates.qml +88 -0
- package/ui/PaneSwap.qml +339 -0
- package/ui/PaneWire.qml +605 -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 +1004 -0
- package/ui/PreviewAnimation.qml +24 -0
- package/ui/PreviewArchive.qml +66 -0
- package/ui/PreviewColumn.qml +551 -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 +38 -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 +732 -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/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 +827 -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 +122 -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 +364 -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 +502 -0
- package/ui/js/FolderSorts.js +108 -0
- package/ui/js/FolderViews.js +44 -0
- package/ui/js/Format.js +305 -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 +736 -0
- package/ui/js/Tags.js +134 -0
- package/ui/js/Taildrop.js +128 -0
- package/ui/js/Tap.js +174 -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 +81 -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 +228 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "js/Drag.js" as DragOps
|
|
3
|
+
|
|
4
|
+
// The rail's Trash SidebarRow trashes rows dragged from this window through ui/js/TrashDrop.js; it lives outside the group-indexed ui/Sidebar.qml, which sits at its recorded ceiling.
|
|
5
|
+
SidebarRow {
|
|
6
|
+
id: root
|
|
7
|
+
|
|
8
|
+
required property var rail
|
|
9
|
+
readonly property int railIndex: root.index + root.rail.homeLead.length + root.rail.recentEntries.length + root.rail.homeRest.length
|
|
10
|
+
readonly property var pane: root.rail.navigationPane
|
|
11
|
+
// Exposed so ui/PaneRail.qml keeps an overlay rail up while a drag rests on this row.
|
|
12
|
+
readonly property bool dragOver: target.containsDrag
|
|
13
|
+
|
|
14
|
+
// The drop cue is separate from the rail's own location and keyboard cursor.
|
|
15
|
+
lit: root.railIndex === root.rail.litIndex
|
|
16
|
+
highlighted: root.railIndex === root.rail.highlightedIndex
|
|
17
|
+
cursor: root.rail.cursorDrawn && root.railIndex === root.rail.cursorIndex
|
|
18
|
+
focused: root.rail.focused
|
|
19
|
+
trailingLabel: dropLoader.item ? dropLoader.item.label : null
|
|
20
|
+
onActivated: root.rail.activate(root.railIndex)
|
|
21
|
+
onMenuRequested: function (idx, pos) { root.rail.openRailMenu(root.railIndex, pos) }
|
|
22
|
+
|
|
23
|
+
function dropDecisions() {
|
|
24
|
+
if (feedback.item) return feedback.item
|
|
25
|
+
feedback.setSource(Qt.resolvedUrl("TrashDropHandler.qml"), { pane: Qt.binding(function () { return root.pane }) })
|
|
26
|
+
feedback.active = true
|
|
27
|
+
return feedback.item
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Loader {
|
|
31
|
+
id: feedback
|
|
32
|
+
active: false
|
|
33
|
+
onStatusChanged: if (status === Loader.Error) console.warn("TrashDropHandler.qml did not load: Loader status " + status)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Loader {
|
|
37
|
+
id: dropLoader
|
|
38
|
+
active: root.dragOver
|
|
39
|
+
anchors.fill: parent
|
|
40
|
+
// TrashDrop always moves to Trash, regardless of the drag's copy or link modifiers.
|
|
41
|
+
onActiveChanged: dropLoader.setSource(dropLoader.active ? Qt.resolvedUrl("DropTarget.qml") : "", { text: DragOps.label(false, false) })
|
|
42
|
+
onStatusChanged: if (status === Loader.Error) throw new Error("DropTarget.qml did not load: Loader status " + status)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
DropArea {
|
|
46
|
+
id: target
|
|
47
|
+
anchors.fill: parent
|
|
48
|
+
keys: [DragOps.ROWS_MIME]
|
|
49
|
+
onEntered: function (drag) {
|
|
50
|
+
var marker = drag.getDataAsString(DragOps.ROWS_MIME)
|
|
51
|
+
var decisions = root.dropDecisions()
|
|
52
|
+
if (!root.pane || !decisions || !decisions.accepts(marker, drag.urls, root.pane.path)) {
|
|
53
|
+
drag.accepted = false
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
decisions.feedback = DragOps.feedbackFor(marker, drag.urls, "")
|
|
57
|
+
decisions.say(decisions.line(marker, drag.urls, root.pane.path))
|
|
58
|
+
}
|
|
59
|
+
onExited: if (feedback.item) feedback.item.leaveTarget()
|
|
60
|
+
onDropped: function (drop) {
|
|
61
|
+
var decisions = root.dropDecisions()
|
|
62
|
+
if (decisions && decisions.drop(root.pane, drop.getDataAsString(DragOps.ROWS_MIME), drop.urls))
|
|
63
|
+
drop.accept(Qt.CopyAction)
|
|
64
|
+
if (decisions) decisions.leaveTarget()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
|
|
4
|
+
// The row becoming its own editor, per the States artboard: an accent frame around the name, the
|
|
5
|
+
// extension muted inside that frame, enter commits and escape abandons.
|
|
6
|
+
//
|
|
7
|
+
// A TextInput cannot colour part of its own text, and splitting the extension into a second,
|
|
8
|
+
// non-editable Text would stop the operator renaming a.txt to a.md. So the whole name stays editable
|
|
9
|
+
// and the extension is painted over it: positionToRectangle gives the exact x of the boundary, an
|
|
10
|
+
// opaque patch covers what the field drew there, and the muted copy goes on top. The patch yields
|
|
11
|
+
// whenever there is a selection to render, so selection is never hidden by it.
|
|
12
|
+
Item {
|
|
13
|
+
id: root
|
|
14
|
+
|
|
15
|
+
property string name: ""
|
|
16
|
+
property var pane: null
|
|
17
|
+
property var viewport: null
|
|
18
|
+
property Item editorHost: null
|
|
19
|
+
property bool containOnBegin: false
|
|
20
|
+
// GridTile supplies the first measurement later; zero would collapse an expanded predecessor.
|
|
21
|
+
property real extraHeight: -1
|
|
22
|
+
readonly property string errorText: pane ? pane.renameError : ""
|
|
23
|
+
readonly property bool pending: pane ? pane.renamePending : false
|
|
24
|
+
readonly property real errorHeight: errorText.length > 0 ? errorLabel.implicitHeight + Theme.spacing.gap : 0
|
|
25
|
+
readonly property real fieldHeight: height - errorHeight
|
|
26
|
+
readonly property alias inputItem: field
|
|
27
|
+
// The editor's frame and the extension's patch, so a test measures the patch against the frame's four sides.
|
|
28
|
+
readonly property alias frame: editFrame
|
|
29
|
+
readonly property alias extensionPatch: mutedExtension
|
|
30
|
+
// The selection drawn as one box that fills the frame's interior, so a test measures it against the frame.
|
|
31
|
+
readonly property alias selectionBox: selectionFill
|
|
32
|
+
// The error line's width where the host gives it more than the field, or -1 for the field's own.
|
|
33
|
+
property real errorSpan: -1
|
|
34
|
+
// The one height every host draws: the row's line box, or the typed line and two hairlines where a small stop's is shorter.
|
|
35
|
+
readonly property real lineBox: Math.max(Theme.rowHeight - 2 * Theme.spacing.rowPaddingY,
|
|
36
|
+
Math.ceil(typedLine.height) + 2 * Theme.spacing.hairline)
|
|
37
|
+
implicitHeight: root.lineBox + errorHeight
|
|
38
|
+
|
|
39
|
+
signal committed(string newName)
|
|
40
|
+
signal abandoned()
|
|
41
|
+
|
|
42
|
+
// Read off what is in the field right now, not off the name it opened with, so the muted run
|
|
43
|
+
// follows an edit that changes where the extension starts.
|
|
44
|
+
readonly property string current: field.text
|
|
45
|
+
readonly property int dot: root.current.lastIndexOf(".")
|
|
46
|
+
readonly property int stemEnd: root.dot > 0 ? root.dot : root.current.length
|
|
47
|
+
readonly property string extension: root.current.substring(root.stemEnd)
|
|
48
|
+
|
|
49
|
+
// Set by begin(), so a hide can only abandon an edit that began; see onVisibleChanged below.
|
|
50
|
+
property bool begun: false
|
|
51
|
+
property bool beginning: false
|
|
52
|
+
property int editIndex: -1
|
|
53
|
+
property string editName: ""
|
|
54
|
+
property var editPane: null
|
|
55
|
+
property var editViewport: null
|
|
56
|
+
property bool containmentQueued: false
|
|
57
|
+
property bool containing: false
|
|
58
|
+
onExtraHeightChanged: if (root.containOnBegin && root.viewport && root.viewport.queueRenameLayout)
|
|
59
|
+
root.viewport.queueRenameLayout()
|
|
60
|
+
|
|
61
|
+
function ownsEdit() {
|
|
62
|
+
return root.begun && root.name === root.editName
|
|
63
|
+
&& root.pane === root.editPane && root.viewport === root.editViewport
|
|
64
|
+
&& (!root.pane || root.pane.renamingIndex === root.editIndex)
|
|
65
|
+
&& (!root.containOnBegin || !root.viewport || root.viewport.renameEditor === root)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function viewportOwnsFocus() {
|
|
69
|
+
return root.containOnBegin && root.viewport && root.viewport.activeFocus
|
|
70
|
+
&& root.viewport.visible && !root.viewport.hiddenHeld
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// A retained delegate can be visible yet culled from Grid's scene graph. Resolve its live slot.
|
|
74
|
+
function layoutHost() {
|
|
75
|
+
if (!root.containOnBegin || !root.viewport || !root.editorHost) return root.editorHost
|
|
76
|
+
var current = root.viewport.currentItem
|
|
77
|
+
var slot = current && current.renaming ? current : root.editorHost
|
|
78
|
+
var host = root.viewport.itemAt(slot.x + slot.width / 2, slot.y + slot.height / 2)
|
|
79
|
+
var editor = host ? host.editorField : null
|
|
80
|
+
return editor && host.renaming && editor.pane === root.pane && editor.viewport === root.viewport
|
|
81
|
+
&& editor.name === root.name ? host : null
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function begin(fromLayout) {
|
|
85
|
+
if (root.beginning) return
|
|
86
|
+
if (root.begun && root.containOnBegin && root.viewport && root.viewport.renameEditor
|
|
87
|
+
&& root.viewport.renameEditor !== root
|
|
88
|
+
&& !(fromLayout && root.layoutHost() === root.editorHost)) return
|
|
89
|
+
var continuing = root.ownsEdit()
|
|
90
|
+
var handoff = null
|
|
91
|
+
var previous = root.containOnBegin && root.viewport ? root.viewport.renameEditor : null
|
|
92
|
+
var retirement = root.containOnBegin && root.viewport ? root.viewport.renameRetirement : null
|
|
93
|
+
if (!continuing && previous && previous !== root
|
|
94
|
+
&& root.pane && previous.editPane === root.pane && previous.editViewport === root.viewport
|
|
95
|
+
&& previous.editIndex === root.pane.renamingIndex && previous.editName === root.name
|
|
96
|
+
&& previous.ownsEdit()) {
|
|
97
|
+
var input = previous.inputItem
|
|
98
|
+
handoff = {text: input.text, cursor: input.cursorPosition,
|
|
99
|
+
anchor: input.cursorPosition === input.selectionStart ? input.selectionEnd : input.selectionStart,
|
|
100
|
+
focused: input.activeFocus || root.viewportOwnsFocus()}
|
|
101
|
+
}
|
|
102
|
+
if (!continuing && !previous && retirement && root.pane === retirement.pane
|
|
103
|
+
&& root.viewport === retirement.viewport && root.pane.renamingIndex === retirement.index
|
|
104
|
+
&& root.name === retirement.name && root.pane.renameRequest === retirement.request) handoff = retirement
|
|
105
|
+
root.beginning = true
|
|
106
|
+
lifecycle.stop()
|
|
107
|
+
root.editIndex = root.pane ? root.pane.renamingIndex : -1
|
|
108
|
+
root.editName = root.name
|
|
109
|
+
root.editPane = root.pane
|
|
110
|
+
root.editViewport = root.viewport
|
|
111
|
+
root.containmentQueued = false
|
|
112
|
+
root.begun = true
|
|
113
|
+
// A recycled same-row delegate can begin before its predecessor has lost focus or died.
|
|
114
|
+
if (root.containOnBegin && root.viewport) root.viewport.renameEditor = root
|
|
115
|
+
if (!continuing) field.text = handoff ? handoff.text : root.name
|
|
116
|
+
// A menu or rail that already took focus keeps it; the lifecycle timer judges that departure.
|
|
117
|
+
if (!handoff || (handoff.focused && root.viewportOwnsFocus())) field.forceActiveFocus()
|
|
118
|
+
// The stem alone, which is the part a rename usually changes.
|
|
119
|
+
var cut = root.name.lastIndexOf(".")
|
|
120
|
+
if (handoff) field.select(handoff.anchor, handoff.cursor)
|
|
121
|
+
else if (!continuing) field.select(0, cut > 0 ? cut : root.name.length)
|
|
122
|
+
if (root.containOnBegin || root.errorText.length > 0) root.queueContainment()
|
|
123
|
+
root.beginning = false
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// File validation belongs to the pane; rail labels retain their existing empty-submit behavior.
|
|
127
|
+
function commit() {
|
|
128
|
+
if (!root.ownsEdit() || !root.visible || root.pending) return false
|
|
129
|
+
var next = field.text.trim()
|
|
130
|
+
if ((!root.pane && next.length === 0) || field.text === root.name || next === root.name) {
|
|
131
|
+
root.abandon()
|
|
132
|
+
return false
|
|
133
|
+
}
|
|
134
|
+
root.committed(next)
|
|
135
|
+
return true
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function queueContainment() {
|
|
139
|
+
if (!root.begun || root.containmentQueued) return
|
|
140
|
+
root.containmentQueued = true
|
|
141
|
+
lifecycle.restart()
|
|
142
|
+
}
|
|
143
|
+
function revealEditor() {
|
|
144
|
+
if (!root.ownsEdit() || !root.visible || !root.pane || !field.activeFocus) return
|
|
145
|
+
if (root.viewport && (!root.viewport.visible || root.viewport.hiddenHeld)) return
|
|
146
|
+
root.containing = true
|
|
147
|
+
// Grid height changes reposition every tile. Contain its final position, not the old layout.
|
|
148
|
+
if (root.containOnBegin && root.viewport) root.viewport.forceLayout()
|
|
149
|
+
if (root.ownsEdit() && root.visible && field.activeFocus) root.pane.setCursor(root.editIndex, 0)
|
|
150
|
+
root.containing = false
|
|
151
|
+
}
|
|
152
|
+
// Let the expanded row and Grid cell height settle before containing the complete error editor.
|
|
153
|
+
onErrorTextChanged: if (root.visible && root.errorText.length > 0) root.queueContainment()
|
|
154
|
+
|
|
155
|
+
// The editor arms itself rather than leaving it to each row that draws one: an Item built with
|
|
156
|
+
// visible already true writes true over true and emits no visibleChanged, so a delegate
|
|
157
|
+
// constructed mid-rename came up empty with nothing holding the caret.
|
|
158
|
+
Component.onCompleted: if (root.visible && !root.begun) root.begin()
|
|
159
|
+
Component.onDestruction: {
|
|
160
|
+
lifecycle.stop()
|
|
161
|
+
if (root.containOnBegin && root.editViewport && root.editViewport.retireRenameEditor) {
|
|
162
|
+
// The viewport retains values only, never a method or context belonging to this field.
|
|
163
|
+
var retirement = root.ownsEdit() ? {pane: root.editPane, viewport: root.editViewport,
|
|
164
|
+
index: root.editIndex, name: root.editName, text: field.text, cursor: field.cursorPosition,
|
|
165
|
+
anchor: field.cursorPosition === field.selectionStart ? field.selectionEnd : field.selectionStart,
|
|
166
|
+
focused: field.activeFocus || root.viewportOwnsFocus(),
|
|
167
|
+
request: root.editPane ? root.editPane.renameRequest : null} : null
|
|
168
|
+
root.begun = false
|
|
169
|
+
root.editViewport.retireRenameEditor(root, retirement)
|
|
170
|
+
} else {
|
|
171
|
+
root.abandon()
|
|
172
|
+
if (root.containOnBegin && root.editViewport && root.editViewport.renameEditor === root)
|
|
173
|
+
root.editViewport.renameEditor = null
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Hiding is abandoning. Qt drops effective visibility before it emits this, so the focus handler
|
|
178
|
+
// below can never see the case, and a hidden editor left renamingIndex set with nothing alive to
|
|
179
|
+
// clear it, which killed the whole window's keyboard, escape included.
|
|
180
|
+
onVisibleChanged: {
|
|
181
|
+
if (root.visible) {
|
|
182
|
+
root.begin()
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
if (root.begun) lifecycle.restart()
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function abandon() {
|
|
189
|
+
if (!root.ownsEdit() || root.pending) return
|
|
190
|
+
root.begun = false
|
|
191
|
+
// The enclosing ListView is a focus scope and remembers this field as its focused child, so
|
|
192
|
+
// giving up what begin() took is what lets the scope itself take the keys again.
|
|
193
|
+
field.focus = false
|
|
194
|
+
root.abandoned()
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Child timers recheck ownership after layout and die with the field, so stale editors cannot cancel or refocus replacements.
|
|
198
|
+
Timer {
|
|
199
|
+
id: lifecycle
|
|
200
|
+
interval: 0
|
|
201
|
+
onTriggered: {
|
|
202
|
+
var contain = root.containmentQueued
|
|
203
|
+
root.containmentQueued = false
|
|
204
|
+
if (!root.ownsEdit()) return
|
|
205
|
+
if (root.containOnBegin && root.editorHost && root.viewport
|
|
206
|
+
&& root.viewport.visible && !root.viewport.hiddenHeld) {
|
|
207
|
+
var host = root.layoutHost()
|
|
208
|
+
if (host && host !== root.editorHost) {
|
|
209
|
+
host.editorField.begin(true)
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (!root.visible || !field.activeFocus) {
|
|
214
|
+
if (!root.visible) field.focus = false
|
|
215
|
+
root.abandon()
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
if (contain) root.revealEditor()
|
|
219
|
+
if (!root.ownsEdit() || root.pending || !root.viewport || !root.viewport.visible
|
|
220
|
+
|| root.viewport.hiddenHeld) return
|
|
221
|
+
var top = root.mapToItem(root.viewport, 0, 0).y
|
|
222
|
+
if (top + root.height > 0 && top < root.viewport.height) return
|
|
223
|
+
root.abandon()
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function queueDeparture() {
|
|
227
|
+
if (!root.ownsEdit() || root.pending || !root.viewport || !root.viewport.visible
|
|
228
|
+
|| root.viewport.hiddenHeld || root.containing) return
|
|
229
|
+
lifecycle.restart()
|
|
230
|
+
}
|
|
231
|
+
Connections {
|
|
232
|
+
target: root.viewport
|
|
233
|
+
function onContentYChanged() { root.queueDeparture() }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
Rectangle {
|
|
237
|
+
id: editFrame
|
|
238
|
+
width: parent.width
|
|
239
|
+
height: root.fieldHeight
|
|
240
|
+
color: Theme.color.background
|
|
241
|
+
border.width: Theme.spacing.hairline
|
|
242
|
+
border.color: root.errorText.length > 0 ? Theme.color.error : Theme.color.accent
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
FontMetrics {
|
|
246
|
+
id: typedLine
|
|
247
|
+
font: field.font
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// The extra arguments are read only so a layout or a scroll re-runs the binding, as mutedExtension's x does.
|
|
251
|
+
function edgeX(position, laidOut, scrolled) { return field.x + field.positionToRectangle(position).x }
|
|
252
|
+
Item {
|
|
253
|
+
id: selectionFill
|
|
254
|
+
visible: field.selectionEnd > field.selectionStart && (field.activeFocus || field.persistentSelection)
|
|
255
|
+
readonly property real fromX: Math.max(field.x, root.edgeX(field.selectionStart, field.contentWidth, field.cursorRectangle.x))
|
|
256
|
+
readonly property real toX: Math.min(field.x + field.width, root.edgeX(field.selectionEnd, field.contentWidth, field.cursorRectangle.x))
|
|
257
|
+
x: fromX
|
|
258
|
+
y: Theme.spacing.hairline
|
|
259
|
+
width: Math.max(0, toX - fromX)
|
|
260
|
+
height: root.fieldHeight - 2 * Theme.spacing.hairline
|
|
261
|
+
|
|
262
|
+
Rectangle {
|
|
263
|
+
anchors.fill: parent
|
|
264
|
+
color: Theme.color.accent
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
TextInput {
|
|
269
|
+
id: field
|
|
270
|
+
anchors { left: parent.left; right: parent.right; top: parent.top }
|
|
271
|
+
height: root.fieldHeight
|
|
272
|
+
anchors.leftMargin: Theme.spacing.gap
|
|
273
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
274
|
+
verticalAlignment: TextInput.AlignVCenter
|
|
275
|
+
color: Theme.color.foreground
|
|
276
|
+
// The selection is painted by selectionFill, which fills the interior where the field's own stops at its line.
|
|
277
|
+
selectionColor: "transparent"
|
|
278
|
+
selectedTextColor: Theme.color.background
|
|
279
|
+
font.family: Theme.font.family
|
|
280
|
+
font.pixelSize: Theme.font.body
|
|
281
|
+
clip: true
|
|
282
|
+
readOnly: root.pending
|
|
283
|
+
// Grid can drop child focus before pooling; preserve the selection its replacement inherits.
|
|
284
|
+
persistentSelection: root.containOnBegin
|
|
285
|
+
|
|
286
|
+
// Both keys are handled and accepted here rather than through onAccepted, because an
|
|
287
|
+
// unaccepted Return goes on to the list's own Keys handler, which reads it as "open" and
|
|
288
|
+
// tries to open the row under a name the rename has just taken away.
|
|
289
|
+
Keys.onPressed: function (event) {
|
|
290
|
+
if (event.key === Qt.Key_Escape) {
|
|
291
|
+
root.abandon()
|
|
292
|
+
event.accepted = true
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
|
296
|
+
root.commit()
|
|
297
|
+
event.accepted = true
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Losing Qt focus while the editor is up abandons, which is the rail's own field and the
|
|
302
|
+
// context menu, which takes focus as it opens. A click on another row never lands here,
|
|
303
|
+
// because a TapHandler moves no focus; ui/js/Tap.js commits that case explicitly.
|
|
304
|
+
onActiveFocusChanged: if (!activeFocus && root.begun) lifecycle.restart()
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Text {
|
|
308
|
+
id: errorLabel
|
|
309
|
+
anchors { top: field.bottom; left: parent.left }
|
|
310
|
+
anchors.topMargin: Theme.spacing.gap
|
|
311
|
+
width: root.errorSpan >= 0 ? root.errorSpan : root.width
|
|
312
|
+
visible: root.errorText.length > 0
|
|
313
|
+
text: root.errorText
|
|
314
|
+
color: Theme.color.error
|
|
315
|
+
font.family: Theme.font.family
|
|
316
|
+
font.pixelSize: Theme.font.caption
|
|
317
|
+
textFormat: Text.PlainText
|
|
318
|
+
wrapMode: Text.Wrap
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// The extension, painted over the field's own copy of it. It stands down only when a selection
|
|
322
|
+
// actually reaches into the extension, because a patch over selected text would hide the
|
|
323
|
+
// selection; the usual case, the stem selected and the extension not, keeps the muted run.
|
|
324
|
+
Item {
|
|
325
|
+
id: mutedExtension
|
|
326
|
+
visible: root.extension.length > 0 && field.selectionEnd <= root.stemEnd
|
|
327
|
+
// contentWidth is read so this re-evaluates once the field has laid the new text out.
|
|
328
|
+
// positionToRectangle is a method, so nothing re-runs it on its own, and begin() assigns the
|
|
329
|
+
// text and selects the stem in one go: the boundary was measured against the layout before
|
|
330
|
+
// that text existed, came back 0, and the patch covered the stem instead of the extension.
|
|
331
|
+
// Every view drew a rename as a bare ".txt" until the first keystroke moved the selection.
|
|
332
|
+
x: field.contentWidth >= 0 ? field.x + field.positionToRectangle(root.stemEnd).x : field.x
|
|
333
|
+
// One hairline in from the frame's top and bottom, so the patch never covers the frame's sides.
|
|
334
|
+
y: field.y + Theme.spacing.hairline
|
|
335
|
+
width: Math.max(0, field.width - (x - field.x))
|
|
336
|
+
height: field.height - 2 * Theme.spacing.hairline
|
|
337
|
+
clip: true
|
|
338
|
+
|
|
339
|
+
Rectangle {
|
|
340
|
+
anchors.fill: parent
|
|
341
|
+
color: Theme.color.background
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
Text {
|
|
345
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
346
|
+
text: root.extension
|
|
347
|
+
color: Theme.color.muted
|
|
348
|
+
font.family: field.font.family
|
|
349
|
+
font.pixelSize: field.font.pixelSize
|
|
350
|
+
textFormat: Text.PlainText
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import Quickshell
|
|
3
|
+
import "js/Renderer.js" as Renderer
|
|
4
|
+
|
|
5
|
+
// Loaded by file: URL when the scene graph fails, because the boot directory cannot import
|
|
6
|
+
// ui/js/Renderer.js through qs: and the startup path must not compile it.
|
|
7
|
+
QtObject {
|
|
8
|
+
function fallbackCommand(backendName) {
|
|
9
|
+
return Renderer.fallbackCommand(backendName, Quickshell.env("FLEA_RENDERER_AUTOMATIC"), Quickshell.env("FLEA_BIN"))
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import Quickshell
|
|
3
|
+
|
|
4
|
+
// ListColumns040 board: one grab zone over a column hairline; the caller centres it on a whole pixel, the drag lives in ui/Header.qml.
|
|
5
|
+
Item {
|
|
6
|
+
id: root
|
|
7
|
+
|
|
8
|
+
property string columnKey: ""
|
|
9
|
+
// True while this column's drag is in flight, held by the caller, not the press.
|
|
10
|
+
property bool hot: false
|
|
11
|
+
// The accent line's x inside the zone: the centre for a column edge, the zone's first pixel for the Dual divider.
|
|
12
|
+
property real lineX: (width - Theme.spacing.hairline) / 2
|
|
13
|
+
signal pressed(var mouse)
|
|
14
|
+
signal moved(var mouse)
|
|
15
|
+
signal released()
|
|
16
|
+
// Before released() when the grab is taken away, so a caller can tell an aborted drag from a release.
|
|
17
|
+
signal canceled()
|
|
18
|
+
signal doubleClicked()
|
|
19
|
+
|
|
20
|
+
// FLEA_TRACE_RESIZE=1 logs each press, held move, release and cancel the zone hears.
|
|
21
|
+
readonly property bool trace: Quickshell.env("FLEA_TRACE_RESIZE") === "1"
|
|
22
|
+
function note(what) { if (root.trace) console.log("RESIZE " + (root.columnKey || "divider") + " " + what) }
|
|
23
|
+
|
|
24
|
+
width: 9 // ui/Header.qml offsets each zone by floor(width / 2), so this is the only number.
|
|
25
|
+
|
|
26
|
+
MouseArea {
|
|
27
|
+
id: zone
|
|
28
|
+
anchors.fill: parent
|
|
29
|
+
hoverEnabled: true
|
|
30
|
+
acceptedButtons: Qt.LeftButton
|
|
31
|
+
cursorShape: Qt.SplitHCursor
|
|
32
|
+
// A row's DragHandler under the Dual divider would otherwise take the grab on its first move.
|
|
33
|
+
preventStealing: true
|
|
34
|
+
onPressed: function (mouse) { root.note("press"); root.pressed(mouse) }
|
|
35
|
+
onPositionChanged: function (mouse) { if (zone.pressed) root.note("move"); root.moved(mouse) }
|
|
36
|
+
onReleased: { root.note("release"); root.released() }
|
|
37
|
+
onCanceled: { root.note("cancel"); root.canceled(); root.released() }
|
|
38
|
+
onDoubleClicked: root.doubleClicked()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// The accent line shows only while hovered or dragged, so it builds only then; the zone stays live at rest.
|
|
42
|
+
Loader {
|
|
43
|
+
x: root.lineX
|
|
44
|
+
width: Theme.spacing.hairline
|
|
45
|
+
height: parent.height
|
|
46
|
+
active: zone.containsMouse || root.hot
|
|
47
|
+
sourceComponent: Rectangle {
|
|
48
|
+
anchors.fill: parent
|
|
49
|
+
color: Theme.color.accent
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/ui/Reveal.qml
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "js/Motion.js" as Motion
|
|
3
|
+
|
|
4
|
+
// The one fade every dialog and menu shares: OutCubic, Motion.durMs.open in and .close out, snapped under reduced motion.
|
|
5
|
+
QtObject {
|
|
6
|
+
id: root
|
|
7
|
+
|
|
8
|
+
// The item that fades; it declares a plain `opacity: 0` and never binds it.
|
|
9
|
+
property Item target: null
|
|
10
|
+
property bool shown: false
|
|
11
|
+
// A dialog's card: it rises Motion.translateUpPx into place on a fresh open only, and never moves while it fades out.
|
|
12
|
+
property Item lift: null
|
|
13
|
+
|
|
14
|
+
// Drives target.opacity from where it stands, so a reopen during a close fades up from there and never replays the old frame.
|
|
15
|
+
function drive() {
|
|
16
|
+
if (root.target === null) return
|
|
17
|
+
fade.stop()
|
|
18
|
+
risen.stop()
|
|
19
|
+
if (Theme.reducedMotion) {
|
|
20
|
+
root.target.opacity = root.shown ? 1 : 0
|
|
21
|
+
rise.y = 0
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
if (root.shown && root.lift !== null) {
|
|
25
|
+
if (root.target.opacity === 0) rise.y = Motion.translateUpPx
|
|
26
|
+
if (rise.y !== 0) risen.start()
|
|
27
|
+
}
|
|
28
|
+
fade.to = root.shown ? 1 : 0
|
|
29
|
+
fade.duration = root.shown ? Motion.durMs.open : Motion.durMs.close
|
|
30
|
+
fade.start()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
onShownChanged: root.drive()
|
|
34
|
+
Component.onCompleted: {
|
|
35
|
+
if (root.lift !== null) root.lift.transform = rise
|
|
36
|
+
if (root.shown) root.drive()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
property Translate rise: Translate {}
|
|
40
|
+
property NumberAnimation fade: NumberAnimation {
|
|
41
|
+
target: root.target
|
|
42
|
+
property: "opacity"
|
|
43
|
+
easing.type: Easing.OutCubic
|
|
44
|
+
// A close cut inside the rise leaves the card where it stood until it is gone, then rests it.
|
|
45
|
+
onFinished: if (!root.shown) root.rise.y = 0
|
|
46
|
+
}
|
|
47
|
+
property NumberAnimation risen: NumberAnimation {
|
|
48
|
+
target: root.rise
|
|
49
|
+
property: "y"
|
|
50
|
+
to: 0
|
|
51
|
+
duration: Motion.durMs.open
|
|
52
|
+
easing.type: Easing.OutCubic
|
|
53
|
+
}
|
|
54
|
+
}
|