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,87 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
|
|
3
|
+
// The padding sets the baseline as CSS does: on every wrapped line of rich text, on the first line of plain text.
|
|
4
|
+
Text {
|
|
5
|
+
id: root
|
|
6
|
+
|
|
7
|
+
// md_rendered: line-height 1.7 over the text's own pixel size.
|
|
8
|
+
readonly property real boxRatio: 1.7
|
|
9
|
+
readonly property bool rich: root.textFormat !== Text.PlainText
|
|
10
|
+
readonly property real box: Math.round(root.font.pixelSize * root.boxRatio)
|
|
11
|
+
// QTextLine rounds the font's height up, so the first line is ceil(height) tall.
|
|
12
|
+
readonly property real lead: Math.max(0, root.box - Math.ceil(metrics.height))
|
|
13
|
+
// Qt's FixedHeight line puts its baseline this share down the box whatever the font, so the padding moves it to the centred one.
|
|
14
|
+
readonly property real fixedBaselineShare: 0.8
|
|
15
|
+
readonly property int centredBaseline: Math.round((root.box - metrics.height) / 2 + metrics.ascent)
|
|
16
|
+
// The hosts set the Markdown here; a text with a picture draws it with the pictures wider than the text scaled to its width.
|
|
17
|
+
property string markdown: ""
|
|
18
|
+
// A text whose picture is taller than the box draws on proportional lines, which grow with it; the ratio keeps every other line at the box.
|
|
19
|
+
// Sample input: "Built with  here" holds one picture; the parser writes every local inline picture this way.
|
|
20
|
+
property bool growsForPictures: true
|
|
21
|
+
readonly property bool holdsPicture: root.growsForPictures && root.rich && /!\[[^\]]*\]\(file:/i.test(root.markdown)
|
|
22
|
+
// Built the first time a text holds a picture: a text without one owns no object for it, which the block cost gates count.
|
|
23
|
+
property Item pictures: null
|
|
24
|
+
function syncPictures() {
|
|
25
|
+
if (root.pictures === null && root.holdsPicture)
|
|
26
|
+
root.pictures = Qt.createComponent("MarkdownPictures.qml").createObject(root, { host: root })
|
|
27
|
+
}
|
|
28
|
+
onHoldsPictureChanged: root.syncPictures()
|
|
29
|
+
Component.onCompleted: root.syncPictures()
|
|
30
|
+
readonly property bool grown: root.pictures !== null && root.holdsPicture && root.pictures.tallest > root.box
|
|
31
|
+
readonly property real naturalLine: Math.ceil(metrics.height)
|
|
32
|
+
// Proportional lines keep the font's own ascent above the baseline and put the stretch below it.
|
|
33
|
+
readonly property int naturalBaseline: Math.round(metrics.ascent)
|
|
34
|
+
readonly property int restBaseline: root.grown ? root.naturalBaseline : Math.round(root.box * root.fixedBaselineShare)
|
|
35
|
+
// The tallest picture's line rests on its bottom edge at the baseline, so it is the picture plus the font's own descent.
|
|
36
|
+
readonly property real pictureLine: root.grown ? root.pictures.tallest + root.naturalLine - root.naturalBaseline : 0
|
|
37
|
+
// A one-line text takes back the stretch the ratio put under its picture; a second line would be half a box taller at least.
|
|
38
|
+
readonly property real stretch: root.grown && root.contentHeight < root.pictureLine * root.box / root.naturalLine + root.box / 2 ? root.contentHeight - root.pictureLine : 0
|
|
39
|
+
// Rich text shifts by the gap between the two baselines (negative when Qt sits it low); plain text sits at the top of its natural line.
|
|
40
|
+
readonly property int lift: root.rich ? root.centredBaseline - root.restBaseline : Math.floor(root.lead / 2)
|
|
41
|
+
// The first line's drawn baseline: Qt reports a FixedHeight line's baselineOffset at the ascent, short of where it draws.
|
|
42
|
+
readonly property real drawnBaseline: root.rich && !root.grown ? root.topPadding + root.restBaseline : root.baselineOffset
|
|
43
|
+
// The document's body size; the preview column scales it down from Quick Look's.
|
|
44
|
+
property int bodyPx: Theme.font.body
|
|
45
|
+
// Rows of a table add their own cell padding on top of the box.
|
|
46
|
+
property int cellPad: 0
|
|
47
|
+
|
|
48
|
+
// The parser pads a code chip with a no-break space in a span carrying this mark (MdEscape.CHIP_PAD_MARK), as Qt reads no em there.
|
|
49
|
+
readonly property string chipPadMark: '<span style="font-size:chippad">'
|
|
50
|
+
// The board pads a chip 4 px a side at body 14; the span's px is that over the face's space advance, so the pad's advance is those 4 px.
|
|
51
|
+
readonly property real chipPadBoardPx: 4
|
|
52
|
+
readonly property real boardBodyPx: 14
|
|
53
|
+
// advanceWidth is a call no binding tracks, so reading the metrics' font size and family measures the space again once the font settles.
|
|
54
|
+
readonly property int chipPadPx: {
|
|
55
|
+
metrics.font.pixelSize
|
|
56
|
+
metrics.font.family
|
|
57
|
+
return Math.max(1, Math.round(root.chipPadBoardPx * root.bodyPx / root.boardBodyPx * root.bodyPx / Math.max(1, metrics.advanceWidth(" "))))
|
|
58
|
+
}
|
|
59
|
+
function padSized(source) {
|
|
60
|
+
return source.indexOf(root.chipPadMark) < 0 ? source : source.split(root.chipPadMark).join('<span style="font-size:' + root.chipPadPx + 'px">')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// The host supplies the scheme gate (Markdown.isExternalLink), as no import of the parser fits the standalone probe copy.
|
|
64
|
+
property var linkGate: null
|
|
65
|
+
// One handler for every Markdown text: a link the gate passes opens in the default application, all else opens nothing.
|
|
66
|
+
onLinkActivated: function (link) {
|
|
67
|
+
if (root.linkGate !== null && root.linkGate(link))
|
|
68
|
+
Qt.openUrlExternally(link)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
text: root.padSized(root.pictures !== null ? root.pictures.shown : root.markdown)
|
|
72
|
+
textFormat: Text.MarkdownText
|
|
73
|
+
wrapMode: Text.Wrap
|
|
74
|
+
color: Theme.color.foreground
|
|
75
|
+
linkColor: Theme.color.foreground
|
|
76
|
+
font.family: Theme.font.family
|
|
77
|
+
font.pixelSize: root.bodyPx
|
|
78
|
+
lineHeight: root.grown ? root.box / root.naturalLine : root.rich ? root.box : 1
|
|
79
|
+
lineHeightMode: root.rich && !root.grown ? Text.FixedHeight : Text.ProportionalHeight
|
|
80
|
+
topPadding: root.cellPad + root.lift
|
|
81
|
+
bottomPadding: root.cellPad + root.lead - root.lift - root.stretch
|
|
82
|
+
|
|
83
|
+
FontMetrics {
|
|
84
|
+
id: metrics
|
|
85
|
+
font: root.font
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// MarkdownWorker.js: PreviewMarkdown's parser thread; WorkerScript binds no `.import` aliases, so Qt.include shares one scope with unique names.
|
|
2
|
+
Qt.include("js/Format.js");
|
|
3
|
+
Qt.include("js/MdUrl.js");
|
|
4
|
+
Qt.include("js/MdHtml.js");
|
|
5
|
+
Qt.include("js/MdHtmlImage.js");
|
|
6
|
+
Qt.include("js/MdHtmlBlock.js");
|
|
7
|
+
Qt.include("js/MdHtmlHeading.js");
|
|
8
|
+
Qt.include("js/MdEscape.js");
|
|
9
|
+
Qt.include("js/MdInline.js");
|
|
10
|
+
Qt.include("js/MdLink.js");
|
|
11
|
+
Qt.include("js/MdContainer.js");
|
|
12
|
+
Qt.include("js/MdRefs.js");
|
|
13
|
+
Qt.include("js/MdEntityTable.js");
|
|
14
|
+
Qt.include("js/MdEntity.js");
|
|
15
|
+
Qt.include("js/MdResolve.js");
|
|
16
|
+
Qt.include("js/MdEmph.js");
|
|
17
|
+
Qt.include("js/MdBreak.js");
|
|
18
|
+
Qt.include("js/MdHold.js");
|
|
19
|
+
Qt.include("js/MdRun.js");
|
|
20
|
+
Qt.include("js/MdParagraphs.js");
|
|
21
|
+
Qt.include("js/MdLeaf.js");
|
|
22
|
+
Qt.include("js/MdItems.js");
|
|
23
|
+
Qt.include("js/MarkdownLists.js");
|
|
24
|
+
Qt.include("js/MdChunks.js");
|
|
25
|
+
Qt.include("js/MdDocument.js");
|
|
26
|
+
Qt.include("js/MdMath.js");
|
|
27
|
+
Qt.include("js/MdFront.js");
|
|
28
|
+
Qt.include("js/MdBlocks.js");
|
|
29
|
+
|
|
30
|
+
var Format = { fileUri: fileUri };
|
|
31
|
+
var MdUrl = { canonicalUrl: canonicalUrl, classifyImage: classifyImage, placeholder: placeholder, srcsetPick: srcsetPick, strippedTarget: strippedTarget, targetAllowed: targetAllowed };
|
|
32
|
+
var MdHtml = { closeToken: closeToken, openToken: openToken, documentText: documentText, normalizedTarget: normalizedTarget, readTag: readTag, sanitizeTag: sanitizeTag, tagHead: tagHead, MAX_TAG_LENGTH: MAX_TAG_LENGTH };
|
|
33
|
+
var MdHtmlImage = { imageUnit: imageUnit, rawImage: rawImage, isCentred: isCentred, linkOf: linkOf, wrapperTail: wrapperTail, LEADING_BREAK: LEADING_BREAK, WRAPPER_OPEN: WRAPPER_OPEN };
|
|
34
|
+
var MdHtmlBlock = { splitHtmlImages: splitHtmlImages, separateBlocks: separateBlocks, htmlHeading: htmlHeading, NESTING_TAG: NESTING_TAG };
|
|
35
|
+
var MdHtmlHeading = { DRAWN_PICTURE: DRAWN_PICTURE, headingUnit: headingUnit, headingPicture: headingPicture, nestDepth: nestDepth };
|
|
36
|
+
var MdEscape = { chipPad: chipPad, escapeText: escapeText, isAsciiPunct: isAsciiPunct };
|
|
37
|
+
var MdInline = { INTERVAL_STRIDE: INTERVAL_STRIDE, MATH_SPAN: MATH_SPAN, isSpace: isSpace, codeHtml: codeHtml, escapeDecodedText: escapeDecodedText, escapeHtmlText: escapeHtmlText, isPunct: isPunct, linkHtml: linkHtml, linkInk: linkInk, spanIntervals: spanIntervals };
|
|
38
|
+
var MdLink = { angleClose: angleClose, normalizeLabel: normalizeLabel, readAutolink: readAutolink, readBarelink: readBarelink, readInlineTarget: readInlineTarget, readLabelRef: readLabelRef };
|
|
39
|
+
var MdRefs = { readDefinition: readDefinition, hideTitle: hideTitle, storeDefinition: storeDefinition, readDefinitionParts: readDefinitionParts, readFootnoteDefinition: readFootnoteDefinition, killDefinition: killDefinition, readFootnoteRef: readFootnoteRef, skipDropContent: skipDropContent, definitionAt: definitionAt, hideDefinition: hideDefinition };
|
|
40
|
+
var MdEntityTable = { namedValue: namedValue };
|
|
41
|
+
var MdEntity = { lineBlank: lineBlank, lineRestart: lineRestart, lineState: lineState, spaceRunAt: spaceRunAt, decodeReferences: decodeReferences, referenceAt: referenceAt };
|
|
42
|
+
var MdEmph = { literal: literal, process: process, runAt: runAt };
|
|
43
|
+
var MdBreak = { isRuleLine: isRuleLine, lineBreak: lineBreak, quoteMarkAt: quoteMarkAt };
|
|
44
|
+
var MdResolve = { bareAt: bareAt, parseAngle: parseAngle, plainText: plainText, readDestination: readDestination, resolvePair: resolvePair, styledSpan: styledSpan };
|
|
45
|
+
var MdHold = { hold: hold };
|
|
46
|
+
var MdRun = { parseInline: parseInline };
|
|
47
|
+
var MdParagraphs = { cutAfter: cutAfter };
|
|
48
|
+
var MdLeaf = { alertTitle: alertTitle, atxHeading: atxHeading, chunkTable: chunkTable, LIST_CHUNK_ITEMS: LIST_CHUNK_ITEMS, headingSafe: headingSafe, delimAligns: delimAligns, fenceOpen: fenceOpen, isThematic: isThematic, isSetext: isSetext, setextLevel: setextLevel, splitRow: splitRow, standaloneImage: standaloneImage, tableBlock: tableBlock, taskText: taskText, pinTaskBox: pinTaskBox };
|
|
49
|
+
var MdContainer = { readListMarker: readListMarker, indentationAt: indentationAt, takeIndent: takeIndent, quoteAt: quoteAt, takeQuote: takeQuote, listAt: listAt, takeList: takeList, startsBlock: startsBlock, textAt: textAt, unindent: unindent, expandLead: expandLead };
|
|
50
|
+
var MdItems = { builder: builder, isRaw: isRaw, listBlock: listBlock, quoteBlocks: quoteBlocks, visibleLines: visibleLines };
|
|
51
|
+
var MarkdownLists = { ORDERED_START: ORDERED_START, runStep: runStep };
|
|
52
|
+
var MdChunks = { chunkList: chunkList };
|
|
53
|
+
var MdMath = { displayAt: displayAt, inlineSources: inlineSources, splitDisplay: splitDisplay };
|
|
54
|
+
var MdFront = { closeAt: closeAt, sendFront: sendFront };
|
|
55
|
+
var MdDocument = { writer: writer, preparedText: preparedText };
|
|
56
|
+
var MdBlocks = { blocks: blocks, blockJob: blockJob, sliceDue: sliceDue, SLICE_MS: SLICE_MS };
|
|
57
|
+
// Short aliases the libraries use for each other, matching their `.import` names.
|
|
58
|
+
var Names = MdEntityTable;
|
|
59
|
+
var Md = MdInline;
|
|
60
|
+
var Link = MdLink;
|
|
61
|
+
var Esc = MdEscape;
|
|
62
|
+
var Run = MdRun;
|
|
63
|
+
var Hold = MdHold;
|
|
64
|
+
var Emph = MdEmph;
|
|
65
|
+
var Ent = MdEntity;
|
|
66
|
+
var Brk = MdBreak;
|
|
67
|
+
var Refs = MdRefs;
|
|
68
|
+
var Leaf = MdLeaf;
|
|
69
|
+
var Res = MdResolve;
|
|
70
|
+
var Container = MdContainer;
|
|
71
|
+
var Document = MdDocument;
|
|
72
|
+
var Front = MdFront;
|
|
73
|
+
var Items = MdItems;
|
|
74
|
+
var Chunks = MdChunks;
|
|
75
|
+
var Lists = MarkdownLists;
|
|
76
|
+
var Maths = MdMath;
|
|
77
|
+
var Html = MdHtml;
|
|
78
|
+
var HtmlImage = MdHtmlImage;
|
|
79
|
+
var HtmlBlock = MdHtmlBlock;
|
|
80
|
+
var HtmlHeading = MdHtmlHeading;
|
|
81
|
+
|
|
82
|
+
// The live request's parse, run one slice a message so a newer request or a cancel is read between two slices.
|
|
83
|
+
var held = null;
|
|
84
|
+
WorkerScript.onMessage = function (msg) {
|
|
85
|
+
if (msg.cancel === true) {
|
|
86
|
+
held = null;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
// Liveness is the pane's protocol: only a request carrying a head field is acked, sliced and beaten, other askers see full replies alone.
|
|
90
|
+
if (msg.cont === true) {
|
|
91
|
+
if (held === null || held.seq !== msg.seq)
|
|
92
|
+
return;
|
|
93
|
+
} else if (msg.head !== undefined) {
|
|
94
|
+
WorkerScript.sendMessage({ seq: msg.seq, ack: true });
|
|
95
|
+
try {
|
|
96
|
+
held = { seq: msg.seq, parse: MdBlocks.blockJob(msg.source, msg.dir, msg.chrome, msg.ink, msg.head, function (head) {
|
|
97
|
+
// A first parse of a file sends its head ahead, so the first screen draws while the rest is still parsing.
|
|
98
|
+
WorkerScript.sendMessage({ seq: msg.seq, blocks: head, error: '', partial: true });
|
|
99
|
+
}, function () {
|
|
100
|
+
WorkerScript.sendMessage({ seq: msg.seq, progress: true });
|
|
101
|
+
}) };
|
|
102
|
+
} catch (e) {
|
|
103
|
+
held = null;
|
|
104
|
+
WorkerScript.sendMessage({ seq: msg.seq, blocks: [], error: String(e) });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
var plain = [];
|
|
109
|
+
var failure = '';
|
|
110
|
+
try {
|
|
111
|
+
plain = MdBlocks.blocks(msg.source, msg.dir, msg.chrome, msg.ink, msg.head, undefined, undefined);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
failure = String(e);
|
|
114
|
+
}
|
|
115
|
+
WorkerScript.sendMessage({ seq: msg.seq, blocks: plain, error: failure });
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
var blocks = [];
|
|
119
|
+
var error = '';
|
|
120
|
+
try {
|
|
121
|
+
blocks = held.parse.run(MdBlocks.sliceDue(MdBlocks.SLICE_MS));
|
|
122
|
+
} catch (e) {
|
|
123
|
+
error = String(e);
|
|
124
|
+
blocks = [];
|
|
125
|
+
}
|
|
126
|
+
if (blocks === null) {
|
|
127
|
+
WorkerScript.sendMessage({ seq: msg.seq, yielded: true });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
held = null;
|
|
131
|
+
WorkerScript.sendMessage({ seq: msg.seq, blocks: blocks, error: error });
|
|
132
|
+
};
|
package/ui/MatchText.qml
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
|
|
3
|
+
// A name with the search or filter match run marked by an accent wash. Three PlainText runs laid
|
|
4
|
+
// out left to right, never StyledText: a filename is arbitrary text and StyledText would render any
|
|
5
|
+
// markup found inside it. SearchFilter rule 3: the run keeps the foreground ink and the accent goes
|
|
6
|
+
// behind it, because accent against foreground is under 1.5:1 on nine of the 22 installed palettes
|
|
7
|
+
// and exactly 1.00 on kanagawa, where inked matches were the dimmest part of the name.
|
|
8
|
+
Item {
|
|
9
|
+
id: root
|
|
10
|
+
|
|
11
|
+
property string text: ""
|
|
12
|
+
// Where the run starts inside text, -1 for no run; ui/js/Match.js computes both.
|
|
13
|
+
property int matchStart: -1
|
|
14
|
+
property int matchLength: 0
|
|
15
|
+
property color color: Theme.color.foreground
|
|
16
|
+
property color accent: Theme.color.accent
|
|
17
|
+
property int pixelSize: Theme.font.body
|
|
18
|
+
// True while the strip that explains the run is up, so the content builds with it and no keystroke pays for it.
|
|
19
|
+
property bool armed: false
|
|
20
|
+
// Opt-in middle elision, so the match run keeps its place.
|
|
21
|
+
property bool elideMiddle: false
|
|
22
|
+
|
|
23
|
+
readonly property bool marked: root.matchStart >= 0 && root.matchLength > 0
|
|
24
|
+
readonly property string before: root.marked ? root.text.substring(0, root.matchStart) : root.text
|
|
25
|
+
readonly property string run: root.marked ? root.text.substring(root.matchStart, root.matchStart + root.matchLength) : ""
|
|
26
|
+
readonly property string after: root.marked ? root.text.substring(root.matchStart + root.matchLength) : ""
|
|
27
|
+
|
|
28
|
+
implicitHeight: beforeText.implicitHeight
|
|
29
|
+
// The marked run and its tail exist only while a match is marked, so their widths are the loaded item's.
|
|
30
|
+
implicitWidth: beforeText.implicitWidth + (markLoader.item ? markLoader.item.runsImplicitWidth : 0)
|
|
31
|
+
|
|
32
|
+
Text {
|
|
33
|
+
id: beforeText
|
|
34
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
35
|
+
// Each run takes what is left of the slot, so the tail elides and nothing ever overflows.
|
|
36
|
+
width: Math.min(implicitWidth, root.width)
|
|
37
|
+
// A run clamped to zero paints nothing: an elided Text at width 0 still draws its full
|
|
38
|
+
// text on its first layout, so a late match (a head that fills the slot) overpaints
|
|
39
|
+
// whatever follows until any relayout. The accent wash below already gates the same way.
|
|
40
|
+
visible: width > 0
|
|
41
|
+
text: root.before
|
|
42
|
+
color: root.color
|
|
43
|
+
font.family: Theme.font.family
|
|
44
|
+
font.pixelSize: root.pixelSize
|
|
45
|
+
elide: root.elideMiddle && !root.marked ? Text.ElideMiddle : Text.ElideRight
|
|
46
|
+
textFormat: Text.PlainText
|
|
47
|
+
maximumLineCount: 1
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Built only while a match is marked: an unmarked name is the one run above, and most rows are unmarked.
|
|
51
|
+
Loader {
|
|
52
|
+
id: markLoader
|
|
53
|
+
active: root.marked || root.armed
|
|
54
|
+
anchors.left: beforeText.right
|
|
55
|
+
anchors.top: parent.top
|
|
56
|
+
anchors.bottom: parent.bottom
|
|
57
|
+
width: Math.max(0, root.width - beforeText.width)
|
|
58
|
+
sourceComponent: Item {
|
|
59
|
+
readonly property real runsImplicitWidth: runText.implicitWidth + afterText.implicitWidth
|
|
60
|
+
|
|
61
|
+
Rectangle {
|
|
62
|
+
anchors.fill: runText
|
|
63
|
+
visible: runText.width > 0
|
|
64
|
+
// The accent carries the row dim, so the wash multiplies it instead of replacing it.
|
|
65
|
+
color: Qt.rgba(root.accent.r, root.accent.g, root.accent.b, root.accent.a * Theme.washActive)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
Text {
|
|
69
|
+
id: runText
|
|
70
|
+
anchors.left: parent.left
|
|
71
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
72
|
+
width: Math.min(implicitWidth, parent.width)
|
|
73
|
+
visible: width > 0
|
|
74
|
+
text: root.run
|
|
75
|
+
color: root.color
|
|
76
|
+
font.family: Theme.font.family
|
|
77
|
+
font.pixelSize: root.pixelSize
|
|
78
|
+
elide: Text.ElideRight
|
|
79
|
+
textFormat: Text.PlainText
|
|
80
|
+
maximumLineCount: 1
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Text {
|
|
84
|
+
id: afterText
|
|
85
|
+
anchors.left: runText.right
|
|
86
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
87
|
+
width: Math.max(0, parent.width - runText.width)
|
|
88
|
+
visible: width > 0
|
|
89
|
+
text: root.after
|
|
90
|
+
color: root.color
|
|
91
|
+
font.family: Theme.font.family
|
|
92
|
+
font.pixelSize: root.pixelSize
|
|
93
|
+
elide: Text.ElideRight
|
|
94
|
+
textFormat: Text.PlainText
|
|
95
|
+
maximumLineCount: 1
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import Quickshell
|
|
3
|
+
import Quickshell.Io
|
|
4
|
+
|
|
5
|
+
// One preview's MPRIS player (tools/flea-mpris): the helper starts when `active` first turns true, off the first frame.
|
|
6
|
+
QtObject {
|
|
7
|
+
id: root
|
|
8
|
+
|
|
9
|
+
// The PreviewMedia this speaks for, which carries out the helper's commands.
|
|
10
|
+
required property var media
|
|
11
|
+
property bool active: false
|
|
12
|
+
property bool ready: false
|
|
13
|
+
// The newest state line, written when the helper starts if it was not up yet.
|
|
14
|
+
property string last: ""
|
|
15
|
+
|
|
16
|
+
onActiveChanged: if (root.active) helper.running = true
|
|
17
|
+
|
|
18
|
+
function send(state) {
|
|
19
|
+
root.last = JSON.stringify(state)
|
|
20
|
+
if (root.ready) helper.write(root.last + "\n")
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Destroying the preview destroys this Process, which kills the helper; a UI that died instead closes its stdin.
|
|
24
|
+
property Process helper: Process {
|
|
25
|
+
id: helper
|
|
26
|
+
command: [Quickshell.env("FLEA_MPRIS") || "/usr/lib/flea/flea-mpris"]
|
|
27
|
+
stdinEnabled: true
|
|
28
|
+
stdout: SplitParser {
|
|
29
|
+
splitMarker: "\n"
|
|
30
|
+
onRead: function (line) { root.media.remote(line) }
|
|
31
|
+
}
|
|
32
|
+
onStarted: {
|
|
33
|
+
root.ready = true
|
|
34
|
+
if (root.last.length > 0) helper.write(root.last + "\n")
|
|
35
|
+
}
|
|
36
|
+
onExited: root.ready = false
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
pragma Singleton
|
|
2
|
+
import QtQuick
|
|
3
|
+
|
|
4
|
+
// MediaMute rule 3: mute is one session flag both media surfaces read, never written to ui.json; the level beside it is stored as preview.volume.
|
|
5
|
+
QtObject {
|
|
6
|
+
id: root
|
|
7
|
+
|
|
8
|
+
property bool muted: false
|
|
9
|
+
|
|
10
|
+
// The level under a press, 0 to 100, or -1 with none down, when the stored level shows.
|
|
11
|
+
property int held: -1
|
|
12
|
+
// Every Flea player plays at this, mute or not: 100 is the full-scale output a player had before the level existed.
|
|
13
|
+
readonly property int volume: root.held >= 0 ? root.held : ViewState.mediaVolume
|
|
14
|
+
// What the player takes: QtAudio.convertVolume(volume / 100, Logarithmic, Linear), which QML does not expose, as qtaudio.cpp computes it.
|
|
15
|
+
readonly property real gain: root.volume > 99 ? 1 : -Math.log(1 - root.volume / 100) / Math.log(100)
|
|
16
|
+
|
|
17
|
+
function toggle() { root.muted = !root.muted }
|
|
18
|
+
|
|
19
|
+
// A press or drag sets the level live and writes nothing; the release stores it once.
|
|
20
|
+
function setVolume(level) { root.held = level }
|
|
21
|
+
|
|
22
|
+
function keepVolume() {
|
|
23
|
+
ViewState.setMediaVolume(root.volume)
|
|
24
|
+
root.held = -1
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
import "." as Flea
|
|
4
|
+
import "js/Format.js" as Format
|
|
5
|
+
|
|
6
|
+
// The transport the canvas draws under a media frame: a play/pause mark, a hairline seek with a square handle, a tabular clock and, under Quick Look, Media040's volume track. No filled chrome anywhere.
|
|
7
|
+
Item {
|
|
8
|
+
id: root
|
|
9
|
+
|
|
10
|
+
property bool playing: false
|
|
11
|
+
property real position: 0
|
|
12
|
+
property real duration: 0
|
|
13
|
+
// MediaMute rules 2 and 3: the state reads by glyph, off the one session flag both strips share.
|
|
14
|
+
readonly property bool muted: Flea.MediaSound.muted
|
|
15
|
+
|
|
16
|
+
// A tile borders four sides, which is the PreviewColumn artboard. Flush against the bottom of
|
|
17
|
+
// the Quick Look overlay that same border reads as a box, so there it is one top hairline.
|
|
18
|
+
property bool framed: true
|
|
19
|
+
|
|
20
|
+
signal toggled()
|
|
21
|
+
signal seeked(real ms)
|
|
22
|
+
// Any contact at all, so a host that hides this over a video can re-arm its own timer.
|
|
23
|
+
signal touched()
|
|
24
|
+
|
|
25
|
+
readonly property real fraction: root.duration > 0
|
|
26
|
+
? Math.max(0, Math.min(1, root.position / root.duration)) : 0
|
|
27
|
+
// One second a click, the step ui/Preview.qml set on the qs.Ui slider this replaced.
|
|
28
|
+
readonly property int wheelStepMs: 1000
|
|
29
|
+
|
|
30
|
+
// A drag in flight draws from the pointer, not from the player, whose own advance would fight it.
|
|
31
|
+
property bool scrubbing: false
|
|
32
|
+
property real scrubFraction: 0
|
|
33
|
+
readonly property real shown: root.scrubbing ? root.scrubFraction : root.fraction
|
|
34
|
+
|
|
35
|
+
implicitHeight: Theme.chromeHeight
|
|
36
|
+
|
|
37
|
+
Rectangle {
|
|
38
|
+
anchors.fill: parent
|
|
39
|
+
color: Theme.color.surface
|
|
40
|
+
border.width: root.framed ? Theme.spacing.hairline : 0
|
|
41
|
+
border.color: Theme.color.mutedFrame
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The unframed form's own divider, the same hairline ChromeBar draws under itself.
|
|
45
|
+
Rectangle {
|
|
46
|
+
anchors.top: parent.top
|
|
47
|
+
anchors.left: parent.left
|
|
48
|
+
anchors.right: parent.right
|
|
49
|
+
visible: !root.framed
|
|
50
|
+
height: Theme.spacing.hairline
|
|
51
|
+
color: Theme.color.foreground
|
|
52
|
+
opacity: 0.12
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// A test clicks each part itself rather than guess an offset; ui/shell.qml's previewSliderCentre reads seekItem, and volumeItem is null in the framed strip.
|
|
56
|
+
readonly property var playItem: playSlot
|
|
57
|
+
readonly property var seekItem: track
|
|
58
|
+
readonly property var muteItem: muteSlot
|
|
59
|
+
readonly property var volumeItem: volumeSlot.item
|
|
60
|
+
|
|
61
|
+
Item {
|
|
62
|
+
id: playSlot
|
|
63
|
+
anchors.left: parent.left
|
|
64
|
+
anchors.leftMargin: Theme.spacing.gap
|
|
65
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
66
|
+
width: Math.max(Theme.hitMin, Theme.font.bodySmall)
|
|
67
|
+
height: Math.max(Theme.hitMin, Theme.font.bodySmall)
|
|
68
|
+
|
|
69
|
+
Accessible.role: Accessible.Button
|
|
70
|
+
Accessible.name: root.playing ? "Pause" : "Play"
|
|
71
|
+
Accessible.onPressAction: { root.touched(); root.toggled() }
|
|
72
|
+
|
|
73
|
+
Flea.Glyph {
|
|
74
|
+
anchors.centerIn: parent
|
|
75
|
+
width: Theme.font.bodySmall
|
|
76
|
+
height: Theme.font.bodySmall
|
|
77
|
+
name: root.playing ? "pause" : "play"
|
|
78
|
+
color: Theme.color.foreground
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
TapHandler {
|
|
82
|
+
acceptedButtons: Qt.LeftButton
|
|
83
|
+
gesturePolicy: TapHandler.ReleaseWithinBounds
|
|
84
|
+
onTapped: {
|
|
85
|
+
root.touched()
|
|
86
|
+
root.toggled()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Flea.MediaTrack {
|
|
92
|
+
id: track
|
|
93
|
+
anchors.left: playSlot.right
|
|
94
|
+
anchors.leftMargin: Theme.spacing.gap
|
|
95
|
+
anchors.right: clock.left
|
|
96
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
97
|
+
anchors.top: parent.top
|
|
98
|
+
anchors.bottom: parent.bottom
|
|
99
|
+
fraction: root.shown
|
|
100
|
+
|
|
101
|
+
// Seeks once, on release: seeking on every dragged frame would fight the player's own
|
|
102
|
+
// advance. A press and release without moving is a click, so this covers both.
|
|
103
|
+
MouseArea {
|
|
104
|
+
anchors.fill: parent
|
|
105
|
+
hoverEnabled: true
|
|
106
|
+
cursorShape: Qt.PointingHandCursor
|
|
107
|
+
onPressed: function (mouse) {
|
|
108
|
+
root.scrubbing = true
|
|
109
|
+
root.scrubFraction = track.fractionAt(mouse.x)
|
|
110
|
+
root.touched()
|
|
111
|
+
}
|
|
112
|
+
onPositionChanged: function (mouse) {
|
|
113
|
+
if (root.scrubbing)
|
|
114
|
+
root.scrubFraction = track.fractionAt(mouse.x)
|
|
115
|
+
root.touched()
|
|
116
|
+
}
|
|
117
|
+
onReleased: {
|
|
118
|
+
root.scrubbing = false
|
|
119
|
+
root.touched()
|
|
120
|
+
if (root.duration > 0)
|
|
121
|
+
root.seeked(root.duration * root.scrubFraction)
|
|
122
|
+
}
|
|
123
|
+
// A wheel is not a position change, so this is the one interaction that has to re-arm a
|
|
124
|
+
// host's hide timer itself; the host clamps the absolute position this produces.
|
|
125
|
+
onWheel: function (wheel) {
|
|
126
|
+
root.touched()
|
|
127
|
+
if (root.duration > 0)
|
|
128
|
+
root.seeked(root.position + (wheel.angleDelta.y > 0 ? root.wheelStepMs : -root.wheelStepMs))
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// MediaMute rule 1: one mark after the clock in the chrome ink, drawn by the play mark's Glyph; the track gives up its width, and under Quick Look the mark sits one gap left of the volume track.
|
|
134
|
+
Item {
|
|
135
|
+
id: muteSlot
|
|
136
|
+
anchors.right: root.framed ? parent.right : volumeSlot.left
|
|
137
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
138
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
139
|
+
width: Math.max(Theme.hitMin, Theme.font.bodySmall)
|
|
140
|
+
height: Math.max(Theme.hitMin, Theme.font.bodySmall)
|
|
141
|
+
|
|
142
|
+
Accessible.role: Accessible.Button
|
|
143
|
+
Accessible.name: root.muted ? "Unmute" : "Mute"
|
|
144
|
+
Accessible.onPressAction: { root.touched(); Flea.MediaSound.toggle() }
|
|
145
|
+
|
|
146
|
+
Flea.Glyph {
|
|
147
|
+
anchors.centerIn: parent
|
|
148
|
+
width: Theme.font.bodySmall
|
|
149
|
+
height: Theme.font.bodySmall
|
|
150
|
+
// Rule 2: both states are foreground, because a muted player is a mode and not a
|
|
151
|
+
// control that cannot be pressed.
|
|
152
|
+
name: root.muted ? "volume-x" : "volume"
|
|
153
|
+
color: Theme.color.foreground
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
TapHandler {
|
|
157
|
+
acceptedButtons: Qt.LeftButton
|
|
158
|
+
gesturePolicy: TapHandler.ReleaseWithinBounds
|
|
159
|
+
onTapped: {
|
|
160
|
+
root.touched()
|
|
161
|
+
Flea.MediaSound.toggle()
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Media040's level, built with the strip so its first frame already draws the stored one.
|
|
167
|
+
Loader {
|
|
168
|
+
id: volumeSlot
|
|
169
|
+
active: !root.framed
|
|
170
|
+
anchors.right: parent.right
|
|
171
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
172
|
+
anchors.top: parent.top
|
|
173
|
+
anchors.bottom: parent.bottom
|
|
174
|
+
// Media040 draws a 60 px track at bodySmall 13, in resolved pixels, so space() would scale it twice.
|
|
175
|
+
width: Math.round(60 * Theme.font.bodySmall / 13)
|
|
176
|
+
sourceComponent: Flea.MediaVolume {}
|
|
177
|
+
onLoaded: item.touched.connect(root.touched)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
Text {
|
|
181
|
+
id: clock
|
|
182
|
+
anchors.right: muteSlot.left
|
|
183
|
+
anchors.rightMargin: Theme.spacing.gap
|
|
184
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
185
|
+
text: Format.duration(root.position) + " / " + Format.duration(root.duration)
|
|
186
|
+
color: Theme.color.muted
|
|
187
|
+
font.family: Theme.font.family
|
|
188
|
+
font.pixelSize: Theme.font.caption
|
|
189
|
+
textFormat: Text.PlainText
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
|
|
3
|
+
// The hairline track of the media strip, drawn for the seek and, under Quick Look, the volume: the played part and a square handle in the accent frame ink, the host adds its MouseArea.
|
|
4
|
+
Item {
|
|
5
|
+
id: root
|
|
6
|
+
|
|
7
|
+
property real fraction: 0
|
|
8
|
+
// A square handle, sized off the caption token so it scales with the text like everything else.
|
|
9
|
+
readonly property int handle: Math.round(Theme.font.caption * 0.5)
|
|
10
|
+
|
|
11
|
+
function fractionAt(x) {
|
|
12
|
+
return Math.max(0, Math.min(1, x / Math.max(1, root.width)))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
Rectangle {
|
|
16
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
17
|
+
width: parent.width
|
|
18
|
+
height: Theme.spacing.hairline * 2
|
|
19
|
+
color: Theme.color.mutedFrame
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
Rectangle {
|
|
23
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
24
|
+
width: parent.width * root.fraction
|
|
25
|
+
height: Theme.spacing.hairline * 2
|
|
26
|
+
color: Theme.color.accentFrame
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
Rectangle {
|
|
30
|
+
x: Math.round(parent.width * root.fraction) - root.handle / 2
|
|
31
|
+
anchors.verticalCenter: parent.verticalCenter
|
|
32
|
+
width: root.handle
|
|
33
|
+
height: root.handle
|
|
34
|
+
color: Theme.color.accentFrame
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import "." as Flea
|
|
3
|
+
|
|
4
|
+
// Media040's level on the Quick Look strip: a track that sets Flea.MediaSound's volume live and stores it on release; mute leaves it alone.
|
|
5
|
+
Flea.MediaTrack {
|
|
6
|
+
id: root
|
|
7
|
+
|
|
8
|
+
// Any contact at all, so a host that hides the strip over a video can re-arm its own timer.
|
|
9
|
+
signal touched()
|
|
10
|
+
|
|
11
|
+
// True while this track's own press holds the level, so closing Quick Look under a button still down lets it go.
|
|
12
|
+
property bool pressing: false
|
|
13
|
+
|
|
14
|
+
fraction: Flea.MediaSound.volume / 100
|
|
15
|
+
|
|
16
|
+
Component.onDestruction: if (root.pressing) Flea.MediaSound.held = -1
|
|
17
|
+
|
|
18
|
+
Accessible.role: Accessible.Slider
|
|
19
|
+
Accessible.name: "Volume"
|
|
20
|
+
// A screen reader steps the level by 5 and stores it as a release would.
|
|
21
|
+
Accessible.onIncreaseAction: root.nudge(5)
|
|
22
|
+
Accessible.onDecreaseAction: root.nudge(-5)
|
|
23
|
+
|
|
24
|
+
function nudge(delta) {
|
|
25
|
+
Flea.MediaSound.setVolume(Math.max(0, Math.min(100, Flea.MediaSound.volume + delta)))
|
|
26
|
+
Flea.MediaSound.keepVolume()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
MouseArea {
|
|
30
|
+
anchors.fill: parent
|
|
31
|
+
hoverEnabled: true
|
|
32
|
+
cursorShape: Qt.PointingHandCursor
|
|
33
|
+
onPressed: function (mouse) {
|
|
34
|
+
root.pressing = true
|
|
35
|
+
root.touched()
|
|
36
|
+
Flea.MediaSound.setVolume(Math.round(100 * root.fractionAt(mouse.x)))
|
|
37
|
+
}
|
|
38
|
+
onPositionChanged: function (mouse) {
|
|
39
|
+
root.touched()
|
|
40
|
+
if (pressed)
|
|
41
|
+
Flea.MediaSound.setVolume(Math.round(100 * root.fractionAt(mouse.x)))
|
|
42
|
+
}
|
|
43
|
+
onReleased: {
|
|
44
|
+
root.pressing = false
|
|
45
|
+
root.touched()
|
|
46
|
+
Flea.MediaSound.keepVolume()
|
|
47
|
+
}
|
|
48
|
+
// A stolen grab ends the drag like a release, so the level heard is the level kept.
|
|
49
|
+
onCanceled: {
|
|
50
|
+
root.pressing = false
|
|
51
|
+
Flea.MediaSound.keepVolume()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|