From 1168ae02f16a69bc8d7f423bfbce3ea936e11931 Mon Sep 17 00:00:00 2001 From: postsolar <120750161+postsolar@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:58:47 +0200 Subject: [PATCH] Update examples --- examples/app-launcher/spago.lock | 4 +- examples/app-launcher/spago.yaml | 3 +- examples/app-launcher/src/Main.purs | 20 ++-- examples/simple-bar/spago.lock | 25 ++++- examples/simple-bar/spago.yaml | 4 +- examples/simple-bar/src/Main.purs | 148 +++++++++++++++------------- 6 files changed, 115 insertions(+), 89 deletions(-) diff --git a/examples/app-launcher/spago.lock b/examples/app-launcher/spago.lock index 1185993..4c27c33 100644 --- a/examples/app-launcher/spago.lock +++ b/examples/app-launcher/spago.lock @@ -552,7 +552,7 @@ workspace: extra_packages: ags-bindings: git: https://github.com/postsolar/purescript-ags-bindings.git - ref: 52185fac7caae70d5483fb2d33408ac365bfd2d5 + ref: a9d2ef3bda754374f1aef96a862678b0dec32ece packages: aff: type: registry @@ -579,7 +579,7 @@ packages: ags-bindings: type: git url: https://github.com/postsolar/purescript-ags-bindings.git - rev: 52185fac7caae70d5483fb2d33408ac365bfd2d5 + rev: a9d2ef3bda754374f1aef96a862678b0dec32ece dependencies: - aff - console diff --git a/examples/app-launcher/spago.yaml b/examples/app-launcher/spago.yaml index 33b3364..644a019 100644 --- a/examples/app-launcher/spago.yaml +++ b/examples/app-launcher/spago.yaml @@ -14,4 +14,5 @@ workspace: extra_packages: ags-bindings: git: https://github.com/postsolar/purescript-ags-bindings.git - ref: 52185fac7caae70d5483fb2d33408ac365bfd2d5 + ref: a9d2ef3bda754374f1aef96a862678b0dec32ece + diff --git a/examples/app-launcher/src/Main.purs b/examples/app-launcher/src/Main.purs index 68bee29..65521ad 100644 --- a/examples/app-launcher/src/Main.purs +++ b/examples/app-launcher/src/Main.purs @@ -64,14 +64,12 @@ appList = do apps ∷ Widget apps = Widget.scrollable - -- Since many widget properties accept either a "raw" value or a binding for - -- that value, it's necessary to wrap them usin `Untagged.Union.asOneOf`. - { child: asOneOf $ + { child: Widget.box -- We use the function `appEntry` declared below and pass it the binding to -- the search query to construct an array of widgets each representing -- a particular application. - { children: asOneOf $ + { children: let appWidgets ∷ Array Widget appWidgets = appEntry currQuery <$> allApps @@ -85,7 +83,7 @@ appList = do } entryBox = Widget.entry - { hexpand: asOneOf true + { hexpand: true , css: "margin-bottom: 5px;" -- When the search query is accepted with the Enter key, -- we get the value of the variable of the applications, @@ -111,7 +109,7 @@ appList = do pure $ Widget.box { vertical: true , css: "margin: 10px;" - , children: asOneOf [ entryBox, apps ] + , children: [ entryBox, apps ] } appEntry ∷ Binding String → Applications.Application → Widget @@ -128,15 +126,15 @@ appEntry currQuery app = } label = Widget.label - { className: asOneOf "appTitle" - , label: asOneOf name + { className: "appTitle" + , label: name , xalign: 0.0 , vpack: "center" , truncate: "end" } buttonChild = Widget.box - { children: asOneOf [ icon, label ] + { children: [ icon, label ] , spacing: 5.0 } @@ -158,10 +156,10 @@ appEntry currQuery app = in Widget.button - { child: asOneOf buttonChild + { child: buttonChild , onClicked: do Applications.launchApp app App.quit - , visible: asOneOf visible + , visible } diff --git a/examples/simple-bar/spago.lock b/examples/simple-bar/spago.lock index 5d031fb..5830323 100644 --- a/examples/simple-bar/spago.lock +++ b/examples/simple-bar/spago.lock @@ -1,6 +1,6 @@ workspace: packages: - ags-config: + ags-bindings-example-simple-bar: path: ./ dependencies: - ags-bindings @@ -10,12 +10,12 @@ workspace: - formatters - now - prelude - - record-studio - yoga-json test_dependencies: [] build_plan: - aff - ags-bindings + - arraybuffer-types - arrays - assert - bifunctors @@ -82,6 +82,7 @@ workspace: - unsafe-coerce - untagged-union - variant + - web-encoding - yoga-json - yoga-tree package_set: @@ -567,7 +568,7 @@ workspace: extra_packages: ags-bindings: git: https://github.com/postsolar/purescript-ags-bindings.git - ref: 05ecdd265dd95441faaf963f9ac815daf616c4de + ref: a9d2ef3bda754374f1aef96a862678b0dec32ece yoga-json: git: https://github.com/rowtype-yoga/purescript-yoga-json.git ref: da7fd729964a9aafa65ec81918bddc1dec12d692 @@ -629,7 +630,7 @@ packages: ags-bindings: type: git url: https://github.com/postsolar/purescript-ags-bindings.git - rev: 05ecdd265dd95441faaf963f9ac815daf616c4de + rev: a9d2ef3bda754374f1aef96a862678b0dec32ece dependencies: - aff - console @@ -640,7 +641,14 @@ packages: - nullable - prelude - record + - record-studio - untagged-union + - web-encoding + arraybuffer-types: + type: registry + version: 3.0.2 + integrity: sha256-mQKokysYVkooS4uXbO+yovmV/s8b138Ws3zQvOwIHRA= + dependencies: [] arrays: type: registry version: 7.3.0 @@ -1356,6 +1364,15 @@ packages: - record - tuples - unsafe-coerce + web-encoding: + type: registry + version: 3.0.0 + integrity: sha256-lqvbj4Rw9mqgSnKx5vSdeNz4vTGxuRQI/PdSK9+kmk0= + dependencies: + - arraybuffer-types + - effect + - newtype + - prelude yoga-json: type: git url: https://github.com/rowtype-yoga/purescript-yoga-json.git diff --git a/examples/simple-bar/spago.yaml b/examples/simple-bar/spago.yaml index 49373dc..339ed9e 100644 --- a/examples/simple-bar/spago.yaml +++ b/examples/simple-bar/spago.yaml @@ -1,5 +1,5 @@ package: - name: ags-bindings-example-simple-bar + name: simple-bar dependencies: - ags-bindings - console @@ -18,7 +18,7 @@ workspace: extra_packages: ags-bindings: git: https://github.com/postsolar/purescript-ags-bindings.git - ref: 05ecdd265dd95441faaf963f9ac815daf616c4de + ref: a9d2ef3bda754374f1aef96a862678b0dec32ece yoga-json: git: https://github.com/rowtype-yoga/purescript-yoga-json.git ref: da7fd729964a9aafa65ec81918bddc1dec12d692 diff --git a/examples/simple-bar/src/Main.purs b/examples/simple-bar/src/Main.purs index 1049020..fdd3f9d 100644 --- a/examples/simple-bar/src/Main.purs +++ b/examples/simple-bar/src/Main.purs @@ -12,10 +12,7 @@ import AGS.Service.Hyprland as H import AGS.Utils.Exec as Exec import AGS.Variable as Var import AGS.Widget (Widget) -import AGS.Widget.Box as Box -import AGS.Widget.Button as Button -import AGS.Widget.CenterBox as CenterBox -import AGS.Widget.Label as Label +import AGS.Widget as Widget import AGS.Widget.Window (Window, window) as Window import AGS.Widget.Window.Anchor (left, right, top) as Window import AGS.Widget.Window.Exclusivity (exclusive) as Window @@ -51,9 +48,12 @@ main = ado -- This is the window we're going to use. -- It uses one child widget `barCenterBox`, which is declared just below. --- A widget's child could be of type `Widget` (a static widget) or --- `Binding Widget` (a dynamically updated wrapping over a `Widget`). --- This is an untagged union so it has to be wrapped with `Union.Untagged.asOneOf`. +-- A widget's child (and, in fact, all other properties) could be +-- of type `Widget` (a static widget) or `Binding Widget`, +-- a dynamically updated wrapping over a `Widget`. +-- Although it's an untagged union, for all widgets it's not needed +-- to wrap them with `Untagged.Union.asOneOf`. But windows are special +-- and require explicit wrapping of child widgets. barWindow ∷ Effect Window.Window barWindow = do @@ -71,13 +71,13 @@ barCenterBox = ado center ← barCenter right ← barRight in - CenterBox.centerBox - { startWidget: asOneOf left - , centerWidget: asOneOf center - , endWidget: asOneOf right + Widget.centerBox + { startWidget: left + , centerWidget: center + , endWidget: right } --- The widget created by `AGS.Widget.Box.box` can have +-- The widget created by `AGS.Widget.box` can have -- multiple children. As before, it can be either `Array Widget` -- or `Binding (Array Widget)`. @@ -85,16 +85,16 @@ barLeft ∷ Effect Widget barLeft = ado wss ← workspaces in - Box.box - { children: asOneOf wss + Widget.box + { children: wss } barCenter ∷ Effect Widget barCenter = ado dtButton ← dateTimeButton in - Box.box - { children: asOneOf [ dtButton ] + Widget.box + { children: [ dtButton ] } barRight ∷ Effect Widget @@ -102,8 +102,8 @@ barRight = ado sysStats ← sysStatsToggleable volume ← volumeToggleable in - Box.box - { children: asOneOf [ sysStats, volume ] + Widget.box + { children: [ sysStats, volume ] , hpack: "end" } @@ -113,25 +113,28 @@ barRight = ado -- synchronously or asynchronously. In the former case, the function -- `exec` takes a single string as the command. In the latter case, -- it takes an array of strings to separate the command and its arguments. +-- NOTE: Commands are not wrapped in a shell, this has to be done explicitly. -- `AGS.Variable` exports multiple functions to work with mutable data. -- A `Variable` is an opaque type with methods for getting and setting current value. -- It can be obtained either by storing a pure value (`Variable.store`), or -- by listening to the output of an external command (`Variable.listen`), or -- by polling (executing periodically with `Variable.poll`) an external command. --- Finally, a variable can be created by polling a value of type `Effect a`. +-- Finally, a variable can be created by polling a value of type `Effect a` with `Variable.serve`. -- After a variable is obtained, it can be made into a `Binding` -- with `Variable.bindValue` to be used with widgets. volumeToggleable ∷ Effect Widget volumeToggleable = do initValue ← Exec.exec $ "pamixer --get-volume-human" - lvl ← - Var.listen - { command: [ "sh", "-c", volumeCommand ] - , initValue - , transform: const identity - } <#> Var.bindValue + lvlBinding ← + Var.bindValue + <$> + Var.listen + { command: [ "sh", "-c", volumeCommand ] + , initValue + , transform: const identity + } let display = Var.store false @@ -142,17 +145,19 @@ volumeToggleable = do -- Via `Applicative` instance bindings also have `Semigroup` and `Monoid` instances. -- When multiple bindings are composed together, the resulting binding -- will be updated whenever any of its components get updated. - -- See the next widgets for more examples of how to utilize bindings. - - label = Label.label - { label: asOneOf ado - display' ← Var.bindValue display - lvl' ← lvl - in if display' then "volume: " <> lvl' else "  " - } - - pure $ Button.button - { child: asOneOf label + -- See the next widgets for more examples of how to utilize variables and bindings. + + label = + Widget.label + { label: + ado + display' ← Var.bindValue display + lvl' ← lvlBinding + in if display' then "volume: " <> lvl' else "  " + } + + pure $ Widget.button + { child: label , onClicked: Var.set not display } @@ -176,22 +181,23 @@ sysStatsToggleable = ado let display = Var.store false - label = Label.label - { label: asOneOf ado - cpu' ← cpu - ram' ← ram - display' ← Var.bindValue display - in - case display', cpu', ram' of - false, _, _ → "  " - _, Nothing, _ → "Error retrieving CPU data" - _, _, Nothing → "Error retrieving RAM data" - _, Just c, Just r → printStats c r + label = Widget.label + { label: + ado + cpu' ← cpu + ram' ← ram + display' ← Var.bindValue display + in + case display', cpu', ram' of + false, _, _ → "  " + _, Nothing, _ → "Error retrieving CPU data" + _, _, Nothing → "Error retrieving RAM data" + _, Just c, Just r → printStats c r } in - Button.button - { child: asOneOf label + Widget.button + { child: label , onClicked: Var.set not display } @@ -244,30 +250,29 @@ dateTimeButton ∷ Effect Widget dateTimeButton = do now ← Now.nowDateTime offset ← Now.getTimezoneOffset - dt ← Var.serve + dtVar ← Var.serve { initValue: now , command: Now.nowDateTime , interval: 1000 } let - ft = Var.store dtFormatLong + ftVar = Var.store dtFormatLong formatDT ft' = DT.adjust (negateDuration offset) >>> maybe "Can't adjust datetime for timezone" (FDT.format ft') - label = Label.label - { label: asOneOf $ - lift2 formatDT (Var.bindValue ft) (Var.bindValue dt) + label = Widget.label + { label: lift2 formatDT (Var.bindValue ftVar) (Var.bindValue dtVar) } flipFt curr | curr == dtFormatLong = dtFormatShort | otherwise = dtFormatLong - pure $ Button.button - { child: asOneOf label + pure $ Widget.button + { child: label , onClicked: Var.set flipFt ft } @@ -306,9 +311,10 @@ dateTimeButton = do workspaces ∷ Effect (Binding (Array Widget)) workspaces = ado - wss ← + workspacesBinding ← Service.bindServiceProp @H.Hyprland @"workspaces" - activeWsId ← + + activeWorkspaceIdBinding ← map _.id <$> Service.bindServiceProp @H.HyprlandActive @"workspace" let @@ -318,17 +324,21 @@ workspaces = ado -- the value of the underlying binding changes. wssWidgets = - wss <#> A.sort >>> map \{ id } → - Button.button - { child: - asOneOf $ Label.label { label: asOneOf $ show id } - , onClicked: - Aff.launchAff_ do - void $ H.messageAsync $ "dispatch workspace " <> show id - , className: - asOneOf $ activeWsId <#> \actId → - guard (actId == id) "focused" - } + workspacesBinding + <#> A.sort >>> map \{ id } → + Widget.button + { child: + Widget.label + { label: show id + } + , onClicked: + Aff.launchAff_ do + void $ H.messageAsync $ "dispatch workspace " <> show id + , className: + activeWorkspaceIdBinding + <#> \actId → + guard (actId == id) "focused" + } in wssWidgets