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 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
+ }