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,354 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import QtQuick.Controls as QQC
|
|
3
|
+
import qs.Commons
|
|
4
|
+
import qs.Commons as Commons
|
|
5
|
+
|
|
6
|
+
// Searchable single-select dropdown. Same trigger shape as Dropdown, but
|
|
7
|
+
// the popup leads with an embedded TextField that filters the option
|
|
8
|
+
// list in real time. Use for pickers with enough options that scanning
|
|
9
|
+
// is friction.
|
|
10
|
+
//
|
|
11
|
+
// Filtering is case-insensitive substring against each option's label.
|
|
12
|
+
// Options can be string[] or [{ value, label, description? }] — the same
|
|
13
|
+
// shape Dropdown accepts. The filter clears whenever the popup closes.
|
|
14
|
+
//
|
|
15
|
+
// Keyboard: Tab to focus the trigger, Enter/Space opens (search focused
|
|
16
|
+
// immediately). Down arrow from the search jumps to the first match;
|
|
17
|
+
// Up from the first match returns to the search. Enter selects, Esc
|
|
18
|
+
// closes (and clears the filter).
|
|
19
|
+
Item {
|
|
20
|
+
id: root
|
|
21
|
+
|
|
22
|
+
property string label: ""
|
|
23
|
+
property string value: ""
|
|
24
|
+
property var options: []
|
|
25
|
+
property string placeholderText: Commons.I18n.t("common.search")
|
|
26
|
+
property string emptyText: Commons.I18n.t("common.noMatches")
|
|
27
|
+
property string triggerLabel: ""
|
|
28
|
+
|
|
29
|
+
property color foreground: Commons.Color.popups.text
|
|
30
|
+
property color background: Commons.Color.popups.background
|
|
31
|
+
property color popupBorder: Commons.Color.popups.border
|
|
32
|
+
property color accent: Commons.Color.accent
|
|
33
|
+
readonly property var popupBorderSpec: Border.localOrSurfaceSpec("popups", "border", popupBorder, Commons.Color.popups.border, Style.normalBorderWidth)
|
|
34
|
+
property string fontFamily: Style.font.family
|
|
35
|
+
property int rowHeight: Style.spacing.controlHeight
|
|
36
|
+
property int popupRowHeight: Style.spacing.popupRowHeight
|
|
37
|
+
property int popupMinHeight: Style.spacing.searchablePopupMinHeight
|
|
38
|
+
property bool showLabel: true
|
|
39
|
+
|
|
40
|
+
// Panel-cursor flag. When true, the trigger renders the shared
|
|
41
|
+
// hover-cursor state. Active Qt focus defaults to the same visuals.
|
|
42
|
+
// Emits `hovered(bool)` on pointer enter/leave so the panel can keep
|
|
43
|
+
// its cursor state in sync with the mouse.
|
|
44
|
+
property bool hasCursor: false
|
|
45
|
+
|
|
46
|
+
// popupOpen + open()/close()/toggle() let a parent panel know when the
|
|
47
|
+
// dropdown owns keys (search field + result list are active) and
|
|
48
|
+
// suspend its own keyCatcher so typing into the filter doesn't drive
|
|
49
|
+
// the panel cursor.
|
|
50
|
+
readonly property bool popupOpen: popup.opened
|
|
51
|
+
function open() { popup.open() }
|
|
52
|
+
function close() { popup.close() }
|
|
53
|
+
function toggle() { popup.opened ? popup.close() : popup.open() }
|
|
54
|
+
|
|
55
|
+
signal changed(string value)
|
|
56
|
+
signal hovered(bool isHovered)
|
|
57
|
+
|
|
58
|
+
function optionValue(o) {
|
|
59
|
+
return (o && typeof o === "object") ? String(o.value) : String(o)
|
|
60
|
+
}
|
|
61
|
+
function optionLabel(o) {
|
|
62
|
+
return (o && typeof o === "object") ? String(o.label) : String(o)
|
|
63
|
+
}
|
|
64
|
+
function optionDescription(o) {
|
|
65
|
+
return (o && typeof o === "object" && o.description) ? String(o.description) : ""
|
|
66
|
+
}
|
|
67
|
+
function currentLabel() {
|
|
68
|
+
for (var i = 0; i < options.length; i++) {
|
|
69
|
+
if (optionValue(options[i]) === value) return optionLabel(options[i])
|
|
70
|
+
}
|
|
71
|
+
return value
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
property var filtered: options
|
|
75
|
+
function recomputeFiltered() {
|
|
76
|
+
var q = searchField.text.toLowerCase()
|
|
77
|
+
if (!q) { filtered = options; return }
|
|
78
|
+
var out = []
|
|
79
|
+
for (var i = 0; i < options.length; i++) {
|
|
80
|
+
var lbl = optionLabel(options[i]).toLowerCase()
|
|
81
|
+
var desc = optionDescription(options[i]).toLowerCase()
|
|
82
|
+
if (lbl.indexOf(q) !== -1 || desc.indexOf(q) !== -1) out.push(options[i])
|
|
83
|
+
}
|
|
84
|
+
filtered = out
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onOptionsChanged: recomputeFiltered()
|
|
88
|
+
|
|
89
|
+
implicitWidth: Style.spacing.searchableDropdownWidth
|
|
90
|
+
implicitHeight: showLabel && label !== "" ? rowHeight + Style.spacing.huge : rowHeight
|
|
91
|
+
|
|
92
|
+
Column {
|
|
93
|
+
anchors.fill: parent
|
|
94
|
+
spacing: Style.spacing.labelGap
|
|
95
|
+
|
|
96
|
+
Text {
|
|
97
|
+
textFormat: Text.PlainText
|
|
98
|
+
visible: root.showLabel && root.label !== ""
|
|
99
|
+
text: root.label
|
|
100
|
+
color: Qt.darker(root.foreground, 1.4)
|
|
101
|
+
font.family: root.fontFamily
|
|
102
|
+
font.pixelSize: Style.font.caption
|
|
103
|
+
font.bold: true
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
BorderSurface {
|
|
107
|
+
id: trigger
|
|
108
|
+
width: parent.width
|
|
109
|
+
height: root.rowHeight
|
|
110
|
+
radius: Style.cornerRadius
|
|
111
|
+
|
|
112
|
+
readonly property bool _focused: trigger.activeFocus
|
|
113
|
+
readonly property bool _hot: triggerHover.hovered || root.hasCursor
|
|
114
|
+
readonly property var _borderSpec: Border.controlSpec(trigger._focused ? "focus" : (trigger._hot ? "hover-cursor" : "normal"), root.foreground, root.accent)
|
|
115
|
+
|
|
116
|
+
color: Style.controlFill(trigger._focused, trigger._hot, root.foreground, root.accent)
|
|
117
|
+
borderSpec: _borderSpec
|
|
118
|
+
|
|
119
|
+
activeFocusOnTab: true
|
|
120
|
+
|
|
121
|
+
HoverHandler {
|
|
122
|
+
id: triggerHover
|
|
123
|
+
onHoveredChanged: root.hovered(hovered)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Keys.onPressed: function(event) {
|
|
127
|
+
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter
|
|
128
|
+
|| event.key === Qt.Key_Space || event.key === Qt.Key_Down) {
|
|
129
|
+
popup.opened ? popup.close() : popup.open()
|
|
130
|
+
event.accepted = true
|
|
131
|
+
} else if (event.key === Qt.Key_Escape && popup.opened) {
|
|
132
|
+
popup.close(); event.accepted = true
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
Text {
|
|
137
|
+
textFormat: Text.PlainText
|
|
138
|
+
anchors.left: parent.left
|
|
139
|
+
anchors.right: chevron.left
|
|
140
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
141
|
+
anchors.leftMargin: trigger.borderLeft + Style.spacing.controlPaddingX
|
|
142
|
+
anchors.rightMargin: trigger.borderRight + Style.spacing.md
|
|
143
|
+
text: root.currentLabel() || root.triggerLabel || root.placeholderText
|
|
144
|
+
color: (root.currentLabel() || root.triggerLabel) ? root.foreground : Qt.darker(root.foreground, 1.5)
|
|
145
|
+
font.family: root.fontFamily
|
|
146
|
+
font.pixelSize: Style.font.body
|
|
147
|
+
elide: Text.ElideRight
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
Text {
|
|
151
|
+
id: chevron
|
|
152
|
+
anchors.right: parent.right
|
|
153
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
154
|
+
anchors.rightMargin: trigger.borderRight + Style.spacing.controlGap
|
|
155
|
+
text: ""
|
|
156
|
+
color: Qt.darker(root.foreground, 1.2)
|
|
157
|
+
font.family: root.fontFamily
|
|
158
|
+
font.pixelSize: Style.font.body
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
MouseArea {
|
|
162
|
+
anchors.fill: parent
|
|
163
|
+
cursorShape: Qt.PointingHandCursor
|
|
164
|
+
onClicked: {
|
|
165
|
+
trigger.forceActiveFocus()
|
|
166
|
+
popup.opened ? popup.close() : popup.open()
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
QQC.Popup {
|
|
171
|
+
id: popup
|
|
172
|
+
x: 0
|
|
173
|
+
y: trigger.height + Style.spacing.xxs
|
|
174
|
+
width: trigger.width
|
|
175
|
+
implicitHeight: Math.max(root.popupMinHeight,
|
|
176
|
+
Math.min(resultList.contentHeight + Style.space(50),
|
|
177
|
+
root.popupRowHeight * 6 + 5 * Style.spacing.labelGap + Style.space(50)))
|
|
178
|
+
padding: Style.spacing.hairline
|
|
179
|
+
leftPadding: Border.left(root.popupBorderSpec) + Style.spacing.hairline
|
|
180
|
+
rightPadding: Border.right(root.popupBorderSpec) + Style.spacing.hairline
|
|
181
|
+
topPadding: Border.top(root.popupBorderSpec) + Style.spacing.hairline
|
|
182
|
+
bottomPadding: Border.bottom(root.popupBorderSpec) + Style.spacing.hairline
|
|
183
|
+
focus: true
|
|
184
|
+
|
|
185
|
+
background: BorderSurface {
|
|
186
|
+
color: root.background
|
|
187
|
+
borderSpec: root.popupBorderSpec
|
|
188
|
+
radius: Style.cornerRadius
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
onOpened: {
|
|
192
|
+
searchField.text = ""
|
|
193
|
+
root.recomputeFiltered()
|
|
194
|
+
Qt.callLater(function() { searchField.forceActiveFocus() })
|
|
195
|
+
}
|
|
196
|
+
onClosed: searchField.text = ""
|
|
197
|
+
|
|
198
|
+
contentItem: Column {
|
|
199
|
+
spacing: 0
|
|
200
|
+
|
|
201
|
+
Item {
|
|
202
|
+
id: searchHeader
|
|
203
|
+
width: parent.width
|
|
204
|
+
height: root.popupRowHeight + Style.spacing.controlPaddingX
|
|
205
|
+
|
|
206
|
+
TextField {
|
|
207
|
+
id: searchField
|
|
208
|
+
anchors.fill: parent
|
|
209
|
+
anchors.margins: Style.spacing.md
|
|
210
|
+
placeholderText: root.placeholderText
|
|
211
|
+
foreground: root.foreground
|
|
212
|
+
accent: root.accent
|
|
213
|
+
font.family: root.fontFamily
|
|
214
|
+
font.pixelSize: Style.font.body
|
|
215
|
+
|
|
216
|
+
onTextChanged: {
|
|
217
|
+
root.recomputeFiltered()
|
|
218
|
+
if (resultList.count > 0) resultList.currentIndex = 0
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
Keys.onPressed: function(event) {
|
|
222
|
+
if (event.key === Qt.Key_Escape) {
|
|
223
|
+
popup.close(); event.accepted = true
|
|
224
|
+
} else if (event.key === Qt.Key_Down) {
|
|
225
|
+
if (resultList.count > 0) {
|
|
226
|
+
resultList.currentIndex = 0
|
|
227
|
+
resultList.forceActiveFocus()
|
|
228
|
+
}
|
|
229
|
+
event.accepted = true
|
|
230
|
+
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
|
231
|
+
if (resultList.count > 0) {
|
|
232
|
+
resultList.currentIndex = 0
|
|
233
|
+
resultList.selectCurrent()
|
|
234
|
+
}
|
|
235
|
+
event.accepted = true
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
Rectangle {
|
|
242
|
+
width: parent.width
|
|
243
|
+
height: 1
|
|
244
|
+
color: Util.alpha(root.foreground, 0.10)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
Item {
|
|
248
|
+
width: parent.width
|
|
249
|
+
height: popup.height - searchHeader.height - Style.spacing.xxs - 1
|
|
250
|
+
|
|
251
|
+
Text {
|
|
252
|
+
textFormat: Text.PlainText
|
|
253
|
+
anchors.centerIn: parent
|
|
254
|
+
visible: resultList.count === 0
|
|
255
|
+
text: root.emptyText
|
|
256
|
+
color: Qt.darker(root.foreground, 1.6)
|
|
257
|
+
font.family: root.fontFamily
|
|
258
|
+
font.pixelSize: Style.font.body
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
ListView {
|
|
262
|
+
id: resultList
|
|
263
|
+
anchors.fill: parent
|
|
264
|
+
spacing: Style.spacing.labelGap
|
|
265
|
+
clip: true
|
|
266
|
+
boundsBehavior: Flickable.StopAtBounds
|
|
267
|
+
model: root.filtered
|
|
268
|
+
currentIndex: -1
|
|
269
|
+
keyNavigationEnabled: false
|
|
270
|
+
|
|
271
|
+
function selectCurrent() {
|
|
272
|
+
if (currentIndex < 0 || currentIndex >= root.filtered.length) return
|
|
273
|
+
var v = root.optionValue(root.filtered[currentIndex])
|
|
274
|
+
root.value = v
|
|
275
|
+
root.changed(v)
|
|
276
|
+
popup.close()
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
Keys.priority: Keys.BeforeItem
|
|
280
|
+
Keys.onPressed: function(event) {
|
|
281
|
+
if (event.key === Qt.Key_Escape) {
|
|
282
|
+
popup.close(); event.accepted = true
|
|
283
|
+
} else if (event.key === Qt.Key_Down || event.text === "j") {
|
|
284
|
+
if (resultList.currentIndex >= resultList.count - 1) {
|
|
285
|
+
event.accepted = true; return
|
|
286
|
+
}
|
|
287
|
+
resultList.currentIndex = resultList.currentIndex + 1
|
|
288
|
+
event.accepted = true
|
|
289
|
+
} else if (event.key === Qt.Key_Up || event.text === "k") {
|
|
290
|
+
if (resultList.currentIndex <= 0) {
|
|
291
|
+
searchField.forceActiveFocus()
|
|
292
|
+
event.accepted = true; return
|
|
293
|
+
}
|
|
294
|
+
resultList.currentIndex = resultList.currentIndex - 1
|
|
295
|
+
event.accepted = true
|
|
296
|
+
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
|
297
|
+
resultList.selectCurrent(); event.accepted = true
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
delegate: Rectangle {
|
|
302
|
+
required property var modelData
|
|
303
|
+
required property int index
|
|
304
|
+
width: resultList.width
|
|
305
|
+
height: Math.max(root.popupRowHeight, rowContent.implicitHeight + Style.spacing.rowPaddingX)
|
|
306
|
+
color: index === resultList.currentIndex
|
|
307
|
+
? Style.hoverFillFor(root.foreground, root.accent)
|
|
308
|
+
: "transparent"
|
|
309
|
+
|
|
310
|
+
Column {
|
|
311
|
+
id: rowContent
|
|
312
|
+
anchors.left: parent.left
|
|
313
|
+
anchors.right: parent.right
|
|
314
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
315
|
+
anchors.leftMargin: Style.spacing.controlPaddingX
|
|
316
|
+
anchors.rightMargin: Style.spacing.controlPaddingX
|
|
317
|
+
spacing: Style.spacing.xxs
|
|
318
|
+
|
|
319
|
+
Text {
|
|
320
|
+
textFormat: Text.PlainText
|
|
321
|
+
text: root.optionLabel(modelData)
|
|
322
|
+
color: index === resultList.currentIndex ? Style.hoverStateColor(root.foreground, root.accent) : root.foreground
|
|
323
|
+
font.family: root.fontFamily
|
|
324
|
+
font.pixelSize: Style.font.body
|
|
325
|
+
elide: Text.ElideRight
|
|
326
|
+
width: parent.width
|
|
327
|
+
}
|
|
328
|
+
Text {
|
|
329
|
+
textFormat: Text.PlainText
|
|
330
|
+
visible: text !== ""
|
|
331
|
+
text: root.optionDescription(modelData)
|
|
332
|
+
color: Qt.darker(root.foreground, 1.5)
|
|
333
|
+
font.family: root.fontFamily
|
|
334
|
+
font.pixelSize: Style.font.caption
|
|
335
|
+
elide: Text.ElideRight
|
|
336
|
+
width: parent.width
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
MouseArea {
|
|
341
|
+
anchors.fill: parent
|
|
342
|
+
hoverEnabled: true
|
|
343
|
+
cursorShape: Qt.PointingHandCursor
|
|
344
|
+
onPositionChanged: resultList.currentIndex = parent.index
|
|
345
|
+
onClicked: resultList.selectCurrent()
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
|
|
3
|
+
// An image fitted inside this item, or with `crop` covering it, preserving
|
|
4
|
+
// its aspect ratio, and decoded at about the size it is drawn, in physical
|
|
5
|
+
// pixels, instead of at the file's own size. A 2560x1440 screenshot shown as
|
|
6
|
+
// a 40px thumbnail would otherwise hold a 14 MB bitmap for as long as the
|
|
7
|
+
// thumbnail exists.
|
|
8
|
+
//
|
|
9
|
+
// The inner Image is not PreserveAspectFit or PreserveAspectCrop on purpose.
|
|
10
|
+
// With either, Qt scales the decode to cover sourceSize, which upscales an
|
|
11
|
+
// image narrower than the box: a 400x10 strip in a 400x400 box would decode at
|
|
12
|
+
// 16000x400. Without them, sourceSize is a bound Qt only ever shrinks the
|
|
13
|
+
// image to fit, so the bitmap is never larger than the bound or the file.
|
|
14
|
+
// This item then places the decoded image the way the fill mode would. A crop
|
|
15
|
+
// bounds the decode at twice the box, so images up to 2:1 still cover it at
|
|
16
|
+
// full resolution.
|
|
17
|
+
//
|
|
18
|
+
// That only holds for raster images. Qt renders an SVG at exactly sourceSize
|
|
19
|
+
// when the fill mode is not a preserving one, which would stretch it, and with
|
|
20
|
+
// a preserving one it covers the box like any other image. An SVG therefore
|
|
21
|
+
// keeps Qt's own handling: rendered at its intrinsic size and fitted or
|
|
22
|
+
// cropped on draw.
|
|
23
|
+
//
|
|
24
|
+
// The image waits until the item has been laid out, so nothing is decoded at
|
|
25
|
+
// native size first.
|
|
26
|
+
Item {
|
|
27
|
+
id: root
|
|
28
|
+
|
|
29
|
+
property url url: ""
|
|
30
|
+
property bool crop: false
|
|
31
|
+
property int horizontalAlignment: Image.AlignHCenter
|
|
32
|
+
property int verticalAlignment: Image.AlignVCenter
|
|
33
|
+
// Left and right swap in a mirrored (right-to-left) layout, as they do for
|
|
34
|
+
// a plain Image.
|
|
35
|
+
readonly property int effectiveHorizontalAlignment: !LayoutMirroring.enabled ? horizontalAlignment
|
|
36
|
+
: horizontalAlignment === Image.AlignLeft ? Image.AlignRight
|
|
37
|
+
: horizontalAlignment === Image.AlignRight ? Image.AlignLeft
|
|
38
|
+
: horizontalAlignment
|
|
39
|
+
property bool asynchronous: true
|
|
40
|
+
readonly property alias status: image.status
|
|
41
|
+
readonly property bool sized: width > 0 && height > 0
|
|
42
|
+
// Clipboard captures name the file after the MIME subtype, as in .svg+xml,
|
|
43
|
+
// and Util.fileUrl percent-encodes the plus.
|
|
44
|
+
readonly property bool scalable: /(\.svgz?|\.svg(\+|%2B)xml)([?#].*)?$|^data:image\/svg/i.test(String(url))
|
|
45
|
+
readonly property real reach: crop ? 2 : 1
|
|
46
|
+
// A strip thin enough that fitting it in the bound rounds its short side
|
|
47
|
+
// to nothing decodes empty. It is decoded again covering a single pixel
|
|
48
|
+
// instead: one pixel across and its aspect ratio long, still a sliver of
|
|
49
|
+
// the file however large that is.
|
|
50
|
+
// Remembered by URL rather than as a flag to reset, so switching to another
|
|
51
|
+
// image can't carry the fallback over to it.
|
|
52
|
+
property string thinUrl: ""
|
|
53
|
+
readonly property bool thinDecode: thinUrl !== "" && thinUrl === String(url)
|
|
54
|
+
property string failedUrl: ""
|
|
55
|
+
property string recheckedUrl: ""
|
|
56
|
+
onUrlChanged: {
|
|
57
|
+
failedUrl = ""
|
|
58
|
+
recheckedUrl = ""
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
clip: crop
|
|
62
|
+
|
|
63
|
+
Image {
|
|
64
|
+
id: image
|
|
65
|
+
|
|
66
|
+
readonly property real placedScale: implicitWidth > 0 && implicitHeight > 0
|
|
67
|
+
? (root.crop ? Math.max(root.width / implicitWidth, root.height / implicitHeight)
|
|
68
|
+
: Math.min(root.width / implicitWidth, root.height / implicitHeight))
|
|
69
|
+
: 0
|
|
70
|
+
|
|
71
|
+
width: root.scalable ? root.width : implicitWidth * placedScale
|
|
72
|
+
height: root.scalable ? root.height : implicitHeight * placedScale
|
|
73
|
+
x: root.scalable || root.effectiveHorizontalAlignment === Image.AlignLeft ? 0
|
|
74
|
+
: root.effectiveHorizontalAlignment === Image.AlignRight ? root.width - width
|
|
75
|
+
: (root.width - width) / 2
|
|
76
|
+
y: root.scalable || root.verticalAlignment === Image.AlignTop ? 0
|
|
77
|
+
: root.verticalAlignment === Image.AlignBottom ? root.height - height
|
|
78
|
+
: (root.height - height) / 2
|
|
79
|
+
|
|
80
|
+
source: root.sized ? root.url : ""
|
|
81
|
+
readonly property bool bounded: root.sized && !root.scalable && !root.thinDecode
|
|
82
|
+
sourceSize.width: bounded ? Math.ceil(root.width * root.reach * Screen.devicePixelRatio) : root.thinDecode ? 1 : 0
|
|
83
|
+
sourceSize.height: bounded ? Math.ceil(root.height * root.reach * Screen.devicePixelRatio) : root.thinDecode ? 1 : 0
|
|
84
|
+
onStatusChanged: {
|
|
85
|
+
var loaded = String(source)
|
|
86
|
+
if (root.thinDecode) {
|
|
87
|
+
if (status === Image.Error) {
|
|
88
|
+
root.thinUrl = ""
|
|
89
|
+
} else if (status === Image.Ready && root.recheckedUrl !== loaded) {
|
|
90
|
+
// The fallback's bitmap has the image's aspect ratio. If fitting
|
|
91
|
+
// that in the bound keeps at least a pixel across, the bounded load
|
|
92
|
+
// failed for another reason, such as art that only appeared later,
|
|
93
|
+
// so load it bounded again. Only once per URL, so a disagreement
|
|
94
|
+
// about rounding can't flip back and forth.
|
|
95
|
+
var boundWidth = Math.ceil(root.width * root.reach * Screen.devicePixelRatio)
|
|
96
|
+
var boundHeight = Math.ceil(root.height * root.reach * Screen.devicePixelRatio)
|
|
97
|
+
var across = Math.min(boundWidth / implicitWidth, boundHeight / implicitHeight) * Math.min(implicitWidth, implicitHeight)
|
|
98
|
+
if (across >= 1) {
|
|
99
|
+
root.recheckedUrl = loaded
|
|
100
|
+
root.thinUrl = ""
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
if (!bounded) return
|
|
106
|
+
if (status === Image.Ready && (implicitWidth === 0 || implicitHeight === 0)) {
|
|
107
|
+
root.thinUrl = loaded
|
|
108
|
+
} else if (status === Image.Error && root.failedUrl !== loaded) {
|
|
109
|
+
// Some decoders fail outright where a thin PNG comes back empty. Try
|
|
110
|
+
// the fallback once per URL, so a file that is simply missing does
|
|
111
|
+
// not keep reloading.
|
|
112
|
+
root.failedUrl = loaded
|
|
113
|
+
root.thinUrl = loaded
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// A thin decode covers its 1x1 bound, so its short side is one pixel.
|
|
117
|
+
fillMode: root.scalable || root.thinDecode
|
|
118
|
+
? (root.crop || root.thinDecode ? Image.PreserveAspectCrop : Image.PreserveAspectFit)
|
|
119
|
+
: Image.Stretch
|
|
120
|
+
horizontalAlignment: root.horizontalAlignment
|
|
121
|
+
verticalAlignment: root.verticalAlignment
|
|
122
|
+
asynchronous: root.asynchronous
|
|
123
|
+
smooth: root.smooth
|
|
124
|
+
}
|
|
125
|
+
}
|