omarchy-ui 0.0.1-x86_64-linux
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.
- checksums.yaml +7 -0
- data/App.qml +112 -0
- data/BarWidget.qml +47 -0
- data/Components/README.md +40 -0
- data/Components/Sparkline.qml +36 -0
- data/ControlNode.qml +745 -0
- data/LICENSE +22 -0
- data/Panel.qml +106 -0
- data/README.md +362 -0
- data/Service.qml +422 -0
- data/bin/omarchy_ui +7 -0
- data/lib/omarchy_ui/animation.rb +24 -0
- data/lib/omarchy_ui/application.rb +282 -0
- data/lib/omarchy_ui/builder.rb +230 -0
- data/lib/omarchy_ui/cli.rb +199 -0
- data/lib/omarchy_ui/command.rb +67 -0
- data/lib/omarchy_ui/component_registry.rb +87 -0
- data/lib/omarchy_ui/components.rb +43 -0
- data/lib/omarchy_ui/node.rb +30 -0
- data/lib/omarchy_ui/project.rb +127 -0
- data/lib/omarchy_ui/protocol.rb +29 -0
- data/lib/omarchy_ui/runtime.rb +31 -0
- data/lib/omarchy_ui/scheduler.rb +136 -0
- data/lib/omarchy_ui/state_store.rb +100 -0
- data/lib/omarchy_ui/value.rb +44 -0
- data/lib/omarchy_ui.rb +29 -0
- data/manifest.json +27 -0
- data/vendor/runtime/x86_64-linux/omarchy-ui-runtime +0 -0
- metadata +71 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: d11e68e81c3b65cc3b41b2dae80f301e7ffb3e29f44cfdde1495a92a6a562e8d
|
|
4
|
+
data.tar.gz: c7baff4c2f09d68dad37f3b0742c00d3abca2a661fa71f425443db9ae1850b85
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3f256ebcdcc59f1c4bf984900e8f0f1f51896c719f5b956677bb734be45139349d56ee6a05ee6d117c7d79fa325ca13348f0e9088317a49d8ac03829d9d3d3c6
|
|
7
|
+
data.tar.gz: dc8c3e1df89667cc9204218cb39b9c80ef50599cb78858041650202135a80a98424b08cdfe7932a6854f2e39de3e40a76e0e7466e8d0e8f35a73e7012830a994
|
data/App.qml
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import Quickshell
|
|
3
|
+
import qs.Commons
|
|
4
|
+
import qs.Ui as OmarchyUi
|
|
5
|
+
|
|
6
|
+
ShellRoot {
|
|
7
|
+
id: root
|
|
8
|
+
|
|
9
|
+
readonly property string configuredProjectDir: String(Quickshell.env("OMARCHY_UI_PROJECT_DIR") || "")
|
|
10
|
+
readonly property string projectDir: configuredProjectDir !== "" ? configuredProjectDir : Quickshell.shellDir
|
|
11
|
+
readonly property string requestedProgram: Quickshell.env("OMARCHY_UI_RUBY_PROGRAM")
|
|
12
|
+
readonly property var appManifest: ({
|
|
13
|
+
id: "omarchy-ui-application",
|
|
14
|
+
name: "Omarchy UI",
|
|
15
|
+
__sourceDir: projectDir
|
|
16
|
+
})
|
|
17
|
+
property bool wasMapped: false
|
|
18
|
+
readonly property string activeSurface: applicationSurface()
|
|
19
|
+
readonly property var windowOptions: service.optionsFor(activeSurface)
|
|
20
|
+
|
|
21
|
+
function option(name, fallback) {
|
|
22
|
+
var value = windowOptions ? windowOptions[name] : undefined
|
|
23
|
+
return value === undefined || value === null ? fallback : value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function applicationSurface() {
|
|
27
|
+
if (!service || !service.surfaces) return ""
|
|
28
|
+
if (service.rootId("main") !== "") return "main"
|
|
29
|
+
var names = Object.keys(service.surfaces)
|
|
30
|
+
for (var i = 0; i < names.length; i++)
|
|
31
|
+
if (names[i] !== "bar") return names[i]
|
|
32
|
+
return names.length > 0 ? names[0] : ""
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Service {
|
|
36
|
+
id: service
|
|
37
|
+
manifest: root.appManifest
|
|
38
|
+
program: root.requestedProgram
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
FloatingWindow {
|
|
42
|
+
id: window
|
|
43
|
+
visible: root.option("visible", true) !== false
|
|
44
|
+
title: String(root.option("title", root.appManifest.name))
|
|
45
|
+
implicitWidth: Number(root.option("width", 760))
|
|
46
|
+
implicitHeight: Number(root.option("height", 520))
|
|
47
|
+
minimumSize: Qt.size(Number(root.option("min_width", 320)), Number(root.option("min_height", 220)))
|
|
48
|
+
maximumSize: Qt.size(Number(root.option("max_width", 16777215)), Number(root.option("max_height", 16777215)))
|
|
49
|
+
maximized: root.option("maximized", false) === true
|
|
50
|
+
fullscreen: root.option("fullscreen", false) === true
|
|
51
|
+
color: root.option("color", Color.popups.background)
|
|
52
|
+
|
|
53
|
+
onBackingWindowVisibleChanged: {
|
|
54
|
+
if (backingWindowVisible) root.wasMapped = true
|
|
55
|
+
else if (root.wasMapped) Qt.quit()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
Rectangle {
|
|
59
|
+
anchors.fill: parent
|
|
60
|
+
color: window.color
|
|
61
|
+
|
|
62
|
+
Rectangle {
|
|
63
|
+
id: titleBar
|
|
64
|
+
anchors { left: parent.left; right: parent.right; top: parent.top }
|
|
65
|
+
height: Style.space(44)
|
|
66
|
+
color: Color.popups.background
|
|
67
|
+
|
|
68
|
+
Text {
|
|
69
|
+
anchors { left: parent.left; leftMargin: Style.space(16); verticalCenter: parent.verticalCenter }
|
|
70
|
+
text: window.title
|
|
71
|
+
color: Color.foreground
|
|
72
|
+
font.family: Style.font.family
|
|
73
|
+
font.pixelSize: Style.font.body
|
|
74
|
+
font.bold: true
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
MouseArea {
|
|
78
|
+
anchors.fill: parent
|
|
79
|
+
acceptedButtons: Qt.LeftButton
|
|
80
|
+
onPressed: window.startSystemMove()
|
|
81
|
+
onDoubleClicked: window.maximized = !window.maximized
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
ControlNode {
|
|
86
|
+
id: renderer
|
|
87
|
+
anchors {
|
|
88
|
+
left: parent.left
|
|
89
|
+
right: parent.right
|
|
90
|
+
top: titleBar.bottom
|
|
91
|
+
bottom: parent.bottom
|
|
92
|
+
margins: Style.space(24)
|
|
93
|
+
}
|
|
94
|
+
visible: root.activeSurface !== "" && service.rootId(root.activeSurface) !== ""
|
|
95
|
+
bridge: service
|
|
96
|
+
surfaceName: root.activeSurface
|
|
97
|
+
controlId: service.rootId(surfaceName)
|
|
98
|
+
foreground: Color.foreground
|
|
99
|
+
fontFamily: Style.font.family
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
Text {
|
|
103
|
+
anchors.centerIn: parent
|
|
104
|
+
visible: !renderer.visible
|
|
105
|
+
text: service.lastError !== "" ? service.lastError : "Starting Ruby UI…"
|
|
106
|
+
color: Color.foreground
|
|
107
|
+
font.family: Style.font.family
|
|
108
|
+
font.pixelSize: Style.font.body
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
data/BarWidget.qml
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
import qs.Commons
|
|
3
|
+
import qs.Ui
|
|
4
|
+
|
|
5
|
+
BarWidget {
|
|
6
|
+
id: root
|
|
7
|
+
property var manifest: null
|
|
8
|
+
moduleName: manifest ? String(manifest.id) : ""
|
|
9
|
+
|
|
10
|
+
readonly property var rubyService: bar && bar.shell
|
|
11
|
+
? bar.shell.serviceFor(moduleName)
|
|
12
|
+
: null
|
|
13
|
+
readonly property string surfaceName: "bar"
|
|
14
|
+
readonly property string rootControlId: rubyService ? rubyService.rootId(surfaceName) : ""
|
|
15
|
+
|
|
16
|
+
implicitWidth: Math.max(Style.bar.iconSlot, renderer.implicitWidth + Style.space(12))
|
|
17
|
+
implicitHeight: barSize
|
|
18
|
+
|
|
19
|
+
ControlNode {
|
|
20
|
+
id: renderer
|
|
21
|
+
anchors.centerIn: parent
|
|
22
|
+
visible: root.rubyService && root.rootControlId !== ""
|
|
23
|
+
bridge: root.rubyService
|
|
24
|
+
surfaceName: root.surfaceName
|
|
25
|
+
controlId: root.rootControlId
|
|
26
|
+
foreground: root.bar ? root.bar.barForeground : Color.foreground
|
|
27
|
+
fontFamily: root.bar ? root.bar.fontFamily : Style.font.family
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Text {
|
|
31
|
+
anchors.centerIn: parent
|
|
32
|
+
visible: !renderer.visible
|
|
33
|
+
text: root.rubyService && root.rubyService.lastError !== "" ? "!rb" : "rb"
|
|
34
|
+
color: root.bar ? root.bar.barForeground : Color.foreground
|
|
35
|
+
font.family: root.bar ? root.bar.fontFamily : Style.font.family
|
|
36
|
+
font.pixelSize: Style.font.bodySmall
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
MouseArea {
|
|
40
|
+
anchors.fill: parent
|
|
41
|
+
cursorShape: Qt.PointingHandCursor
|
|
42
|
+
onClicked: {
|
|
43
|
+
if (root.rubyService && root.rootControlId !== "")
|
|
44
|
+
root.rubyService.sendEvent(root.surfaceName, root.rootControlId, "click", {})
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# QML component adapters
|
|
2
|
+
|
|
3
|
+
Applications can extend the framework without modifying `ControlNode.qml` or `Service.qml`.
|
|
4
|
+
Register an adapter before declaring surfaces:
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
register_component :sparkline,
|
|
8
|
+
qml: "Sparkline.qml",
|
|
9
|
+
properties: %i[values color],
|
|
10
|
+
events: %i[click]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then place `Sparkline.qml` in this directory and render it with:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
component :sparkline, values: [2, 8, 5, 12], color: "#f44"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
An adapter is a QML `Item` with any of these framework-injected properties it needs:
|
|
20
|
+
`bridge`, `surfaceName`, `controlId`, and `node`. Events are sent with
|
|
21
|
+
`bridge.sendEvent(surfaceName, controlId, "click", payload)`.
|
|
22
|
+
|
|
23
|
+
The registry only accepts local adapter basenames and declares every allowed property and
|
|
24
|
+
event. QML source is never accepted from the runtime JSON stream as executable text.
|
|
25
|
+
|
|
26
|
+
## Animation
|
|
27
|
+
|
|
28
|
+
Reactive patches can carry native QML transitions:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
bind(chart, :opacity, animation: animation(duration: 240, easing: :out_cubic)) do
|
|
32
|
+
state.visible ? 1.0 : 0.0
|
|
33
|
+
end
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The bridge validates the transition, preserves the previous value, and runs a QML
|
|
37
|
+
`PropertyAnimation` against the adapter property. For an animatable custom property, expose
|
|
38
|
+
a QML property with the same name as the registered Ruby property. Adapters remain free to
|
|
39
|
+
use QML `Behavior`, `Transition`, `SequentialAnimation`, `ParallelAnimation`, states,
|
|
40
|
+
shaders, particles, and any other native QML animation internally.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import QtQuick
|
|
2
|
+
|
|
3
|
+
Canvas {
|
|
4
|
+
property var values: []
|
|
5
|
+
property color strokeColor: "white"
|
|
6
|
+
property real lineWidth: 2
|
|
7
|
+
signal click(var payload)
|
|
8
|
+
implicitWidth: 160
|
|
9
|
+
implicitHeight: 48
|
|
10
|
+
|
|
11
|
+
onValuesChanged: requestPaint()
|
|
12
|
+
onStrokeColorChanged: requestPaint()
|
|
13
|
+
onPaint: {
|
|
14
|
+
var context = getContext("2d")
|
|
15
|
+
context.reset()
|
|
16
|
+
if (values.length < 2) return
|
|
17
|
+
var minimum = Math.min.apply(Math, values)
|
|
18
|
+
var maximum = Math.max.apply(Math, values)
|
|
19
|
+
var span = Math.max(0.000001, maximum - minimum)
|
|
20
|
+
context.strokeStyle = strokeColor
|
|
21
|
+
context.lineWidth = lineWidth
|
|
22
|
+
context.beginPath()
|
|
23
|
+
for (var i = 0; i < values.length; i++) {
|
|
24
|
+
var x = i * width / (values.length - 1)
|
|
25
|
+
var y = height - ((Number(values[i]) - minimum) / span) * height
|
|
26
|
+
if (i === 0) context.moveTo(x, y)
|
|
27
|
+
else context.lineTo(x, y)
|
|
28
|
+
}
|
|
29
|
+
context.stroke()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
MouseArea {
|
|
33
|
+
anchors.fill: parent
|
|
34
|
+
onClicked: parent.click({ button: button })
|
|
35
|
+
}
|
|
36
|
+
}
|