mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-02 11:11:04 +02:00
Merge branch 'master' into feat/networkmanager
This commit is contained in:
commit
b860f5b603
57 changed files with 2450 additions and 858 deletions
|
@ -49,8 +49,8 @@ dnf install libpulseaudio-devel
|
|||
By default, all features are enabled for convenience. This can result in a significant compile time.
|
||||
If you know you are not going to need all the features, you can compile with only the features you need.
|
||||
|
||||
As of `v0.10.0`, compiling with no features is about 33% faster.
|
||||
On a 3800X, it takes about 60 seconds for no features and 90 seconds for all.
|
||||
As of `v0.15.0`, compiling with no features is about 50% faster.
|
||||
On a 3800X, it takes about 45 seconds for no features and 90 seconds for all.
|
||||
This difference is expected to increase as the bar develops.
|
||||
|
||||
Features containing a `+` can be stacked, for example `config+json` and `config+yaml` could both be enabled.
|
||||
|
@ -77,6 +77,7 @@ cargo build --release --no-default-features \
|
|||
| config+corn | Enables configuration support for [Corn](https://github.com/jakestanger/corn). |
|
||||
| config+ron | Enables configuration support for [Ron](https://github.com/ron-rs/ron). |
|
||||
| **Modules** | |
|
||||
| cairo | Enables the `cairo` module |
|
||||
| clipboard | Enables the `clipboard` module. |
|
||||
| clock | Enables the `clock` module. |
|
||||
| focused | Enables the `focused` module. |
|
||||
|
@ -84,6 +85,7 @@ cargo build --release --no-default-features \
|
|||
| music+all | Enables the `music` module with support for all player types. |
|
||||
| music+mpris | Enables the `music` module with MPRIS support. |
|
||||
| music+mpd | Enables the `music` module with MPD support. |
|
||||
| notifications | Enables the `notiications` module. |
|
||||
| sys_info | Enables the `sys_info` module. |
|
||||
| tray | Enables the `tray` module. |
|
||||
| upower | Enables the `upower` module. |
|
||||
|
|
|
@ -332,6 +332,7 @@ For information on the `Script` type, and embedding scripts in strings, see [her
|
|||
| `show_if` | [Dynamic Boolean](dynamic-values#dynamic-boolean) | `null` | Polls the script to check its exit code. If exit code is zero, the module is shown. For other codes, it is hidden. |
|
||||
| `transition_type` | `slide_start` or `slide_end` or `crossfade` or `none` | `slide_start` | The transition animation to use when showing/hiding the widget. |
|
||||
| `transition_duration` | `integer` | `250` | The length of the transition animation to use when showing/hiding the widget. |
|
||||
| `disable_popup` | `boolean` | `false` | Prevents the popup from opening on-click for this widget. |
|
||||
|
||||
#### Appearance
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ Responds with `ok`.
|
|||
|
||||
### `get`
|
||||
|
||||
Gets an [ironvar](ironvars) value.
|
||||
Gets an [ironvar](ironvars) value.
|
||||
|
||||
Responds with `ok_value` if the value exists, otherwise `error`.
|
||||
|
||||
|
@ -104,6 +104,20 @@ Responds with `ok`.
|
|||
}
|
||||
```
|
||||
|
||||
### list
|
||||
|
||||
Gets a list of all [ironvar](ironvars) values.
|
||||
|
||||
Responds with `ok_value`.
|
||||
|
||||
Each key/value pair is on its own `\n` separated newline. The key and value are separated by a colon and space `: `.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "list"
|
||||
}
|
||||
```
|
||||
|
||||
### `load_css`
|
||||
|
||||
Loads an additional CSS stylesheet, with hot-reloading enabled.
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
## Custom
|
||||
|
||||
- [Power Menu](power-menu)
|
||||
- [Weather](weather)
|
||||
|
||||
# Modules
|
||||
|
||||
- [Cairo](cairo)
|
||||
- [Clipboard](clipboard)
|
||||
- [Clock](clock)
|
||||
- [Custom](custom)
|
||||
|
|
468
docs/examples/custom/Weather.md
Normal file
468
docs/examples/custom/Weather.md
Normal file
|
@ -0,0 +1,468 @@
|
|||
Creates a button on the bar which displays the current weather condition and temperature.
|
||||
Clicking the button opens a popup with forecast information for the next few days.
|
||||
|
||||
Weather information is fetched from [wttr.in](https://wttr.in) via an external script.
|
||||
You will need to set up the script to be run as a service.
|
||||
|
||||

|
||||
|
||||
## Configuration
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"end": [
|
||||
{
|
||||
"type": "custom",
|
||||
"class": "weather",
|
||||
"bar": [
|
||||
{
|
||||
"type": "button",
|
||||
"label": "#weather_current",
|
||||
"on_click": "popup:toggle"
|
||||
}
|
||||
],
|
||||
"popup": [
|
||||
{
|
||||
"type": "box",
|
||||
"orientation": "vertical",
|
||||
"widgets": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "header",
|
||||
"label": "Forecast"
|
||||
},
|
||||
{
|
||||
"type": "box",
|
||||
"widgets": [
|
||||
{
|
||||
"type": "box",
|
||||
"name": "dates",
|
||||
"orientation": "vertical",
|
||||
"widgets": [
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-date",
|
||||
"label": "#weather_date_0"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-date",
|
||||
"label": "#weather_date_1"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-date",
|
||||
"label": "#weather_date_2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "box",
|
||||
"name": "temps",
|
||||
"orientation": "vertical",
|
||||
"widgets": [
|
||||
{
|
||||
"type": "box",
|
||||
"widgets": [
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-high",
|
||||
"label": " #weather_high_0"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-avg",
|
||||
"label": " #weather_avg_0"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-low",
|
||||
"label": " #weather_low_0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "box",
|
||||
"widgets": [
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-high",
|
||||
"label": " #weather_high_1"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-avg",
|
||||
"label": " #weather_avg_1"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-low",
|
||||
"label": " #weather_low_1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "box",
|
||||
"widgets": [
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-high",
|
||||
"label": " #weather_high_2"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-avg",
|
||||
"label": " #weather_avg_2"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"class": "weather-low",
|
||||
"label": " #weather_low_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>TOML</summary>
|
||||
|
||||
```toml
|
||||
[[end]]
|
||||
type = "custom"
|
||||
class = "weather"
|
||||
|
||||
[[end.bar]]
|
||||
type = "button"
|
||||
label = "#weather_current"
|
||||
on_click = "popup:toggle"
|
||||
|
||||
[[end.popup]]
|
||||
type = "box"
|
||||
orientation = "vertical"
|
||||
|
||||
[[end.popup.widgets]]
|
||||
type = "label"
|
||||
name = "header"
|
||||
label = "Forecast"
|
||||
|
||||
[[end.popup.widgets]]
|
||||
type = "box"
|
||||
|
||||
[[end.popup.widgets.widgets]]
|
||||
type = "box"
|
||||
name = "dates"
|
||||
orientation = "vertical"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-date"
|
||||
label = "#weather_date_0"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-date"
|
||||
label = "#weather_date_1"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-date"
|
||||
label = "#weather_date_2"
|
||||
|
||||
[[end.popup.widgets.widgets]]
|
||||
type = "box"
|
||||
name = "temps"
|
||||
orientation = "vertical"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets]]
|
||||
type = "box"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-high"
|
||||
label = " #weather_high_0"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-avg"
|
||||
label = " #weather_avg_0"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-low"
|
||||
label = " #weather_low_0"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets]]
|
||||
type = "box"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-high"
|
||||
label = " #weather_high_1"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-avg"
|
||||
label = " #weather_avg_1"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-low"
|
||||
label = " #weather_low_1"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets]]
|
||||
type = "box"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-high"
|
||||
label = " #weather_high_2"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-avg"
|
||||
label = " #weather_avg_2"
|
||||
|
||||
[[end.popup.widgets.widgets.widgets.widgets]]
|
||||
type = "label"
|
||||
class = "weather-low"
|
||||
label = " #weather_low_2"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>YAML</summary>
|
||||
|
||||
```yaml
|
||||
end:
|
||||
- type: custom
|
||||
class: weather
|
||||
bar:
|
||||
- type: button
|
||||
label: '#weather_current'
|
||||
on_click: popup:toggle
|
||||
popup:
|
||||
- type: box
|
||||
orientation: vertical
|
||||
widgets:
|
||||
- type: label
|
||||
name: header
|
||||
label: Forecast
|
||||
- type: box
|
||||
widgets:
|
||||
- type: box
|
||||
name: dates
|
||||
orientation: vertical
|
||||
widgets:
|
||||
- type: label
|
||||
class: weather-date
|
||||
label: '#weather_date_0'
|
||||
- type: label
|
||||
class: weather-date
|
||||
label: '#weather_date_1'
|
||||
- type: label
|
||||
class: weather-date
|
||||
label: '#weather_date_2'
|
||||
- type: box
|
||||
name: temps
|
||||
orientation: vertical
|
||||
widgets:
|
||||
- type: box
|
||||
widgets:
|
||||
- type: label
|
||||
class: weather-high
|
||||
label: ' #weather_high_0'
|
||||
- type: label
|
||||
class: weather-avg
|
||||
label: ' #weather_avg_0'
|
||||
- type: label
|
||||
class: weather-low
|
||||
label: ' #weather_low_0'
|
||||
- type: box
|
||||
widgets:
|
||||
- type: label
|
||||
class: weather-high
|
||||
label: ' #weather_high_1'
|
||||
- type: label
|
||||
class: weather-avg
|
||||
label: ' #weather_avg_1'
|
||||
- type: label
|
||||
class: weather-low
|
||||
label: ' #weather_low_1'
|
||||
- type: box
|
||||
widgets:
|
||||
- type: label
|
||||
class: weather-high
|
||||
label: ' #weather_high_2'
|
||||
- type: label
|
||||
class: weather-avg
|
||||
label: ' #weather_avg_2'
|
||||
- type: label
|
||||
class: weather-low
|
||||
label: ' #weather_low_2'
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Corn</summary>
|
||||
|
||||
|
||||
```corn
|
||||
let {
|
||||
$weather = {
|
||||
type = "custom"
|
||||
class = "weather"
|
||||
|
||||
bar = [ { type = "button" label = "#weather_current" on_click = "popup:toggle" } ]
|
||||
popup = [ {
|
||||
type = "box"
|
||||
orientation = "vertical"
|
||||
|
||||
widgets = [
|
||||
{ type = "label" name = "header" label = "Forecast" }
|
||||
{
|
||||
type = "box"
|
||||
widgets = [
|
||||
{ type = "box" name="dates" orientation = "vertical" widgets = [
|
||||
{ type = "label" class="weather-date" label = "#weather_date_0" }
|
||||
{ type = "label" class="weather-date" label = "#weather_date_1" }
|
||||
{ type = "label" class="weather-date" label = "#weather_date_2" }
|
||||
]}
|
||||
{ type = "box" name="temps" orientation = "vertical" widgets = [
|
||||
{
|
||||
type = "box"
|
||||
widgets = [
|
||||
{ type = "label" class="weather-high" label = " #weather_high_0" }
|
||||
{ type = "label" class="weather-avg" label = " #weather_avg_0" }
|
||||
{ type = "label" class="weather-low" label = " #weather_low_0" }
|
||||
]
|
||||
}
|
||||
{
|
||||
type = "box"
|
||||
widgets = [
|
||||
{ type = "label" class="weather-high" label = " #weather_high_1" }
|
||||
{ type = "label" class="weather-avg" label = " #weather_avg_1" }
|
||||
{ type = "label" class="weather-low" label = " #weather_low_1" }
|
||||
]
|
||||
}
|
||||
{
|
||||
type = "box"
|
||||
widgets = [
|
||||
{ type = "label" class="weather-high" label = " #weather_high_2" }
|
||||
{ type = "label" class="weather-avg" label = " #weather_avg_2" }
|
||||
{ type = "label" class="weather-low" label = " #weather_low_2" }
|
||||
]
|
||||
}
|
||||
] }
|
||||
]
|
||||
}
|
||||
]
|
||||
} ]
|
||||
}
|
||||
} in {
|
||||
end = [ $weather ]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Script
|
||||
|
||||
Run the following script on a timer. Ensure to fill out your city name.
|
||||
|
||||
```js
|
||||
#!/usr/bin/env zx
|
||||
|
||||
const location = "Canterbury";
|
||||
|
||||
// JS uses Sunday as first day
|
||||
const weekday = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
|
||||
|
||||
// bar logic
|
||||
|
||||
|
||||
const data = await fetch(`https://wttr.in/${location}?format=%c %t|%m %t|%S|%s`)
|
||||
.then(r => r.text());
|
||||
|
||||
const [day, night, sunrise, sunset] = data.replaceAll("+", "").split("|");
|
||||
const [sunriseH, sunriseM, sunriseS] = sunrise.split(":");
|
||||
const [sunsetH, sunsetM, sunsetS] = sunset.split(":");
|
||||
|
||||
const currentTime = new Date();
|
||||
|
||||
const sunriseTime = new Date(currentTime);
|
||||
sunriseTime.setHours(sunriseH);
|
||||
sunriseTime.setMinutes(sunriseM);
|
||||
sunriseTime.setSeconds(sunriseS);
|
||||
|
||||
const sunsetTime = new Date(currentTime);
|
||||
sunsetTime.setHours(sunsetH);
|
||||
sunsetTime.setMinutes(sunsetM);
|
||||
sunsetTime.setSeconds(sunsetS);
|
||||
|
||||
let value = day;
|
||||
if(currentTime < sunriseTime || currentTime > sunsetTime) value = night;
|
||||
|
||||
await $`ironbar set weather_current ${value}`;
|
||||
|
||||
// popup logic
|
||||
|
||||
const forecast = await fetch(`https://wttr.in/${location}?format=j1`).then(r => r.json());
|
||||
|
||||
for (const i in forecast.weather) {
|
||||
const report = forecast.weather[i];
|
||||
|
||||
const day = weekday[new Date(report.date).getDay()];
|
||||
|
||||
await $`ironbar set weather_date_${i} ${day}`;
|
||||
await $`ironbar set weather_avg_${i} ${report.avgtempC.padStart(2, "0")}`;
|
||||
await $`ironbar set weather_high_${i} ${report.maxtempC.padStart(2, "0")}`;
|
||||
await $`ironbar set weather_low_${i} ${report.mintempC.padStart(2, "0")}`;
|
||||
}
|
||||
```
|
||||
|
||||
## Styling
|
||||
|
||||
```css
|
||||
.popup-weather #header {
|
||||
font-size: 1.8em;
|
||||
padding-bottom: 0.4em;
|
||||
margin-bottom: 0.6em;
|
||||
border-bottom: 1px solid @color-border;
|
||||
}
|
||||
|
||||
.popup-weather .weather-date {
|
||||
font-size: 1.5em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.popup-weather .weather-avg {
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
/*
|
||||
this is a hack to align the different font sizes on left/right
|
||||
you may need to adjust for different fonts
|
||||
*/
|
||||
.popup-weather #temps label {
|
||||
padding-top: 0.2em;
|
||||
margin-bottom: 0.7em;
|
||||
}
|
||||
```
|
215
docs/modules/Cairo.md
Normal file
215
docs/modules/Cairo.md
Normal file
|
@ -0,0 +1,215 @@
|
|||
Allows you to render custom content using the Lua and the Cairo drawing library.
|
||||
This is an advanced feature which provides a powerful escape hatch, allowing you to fetch data and render anything
|
||||
using an embedded scripting environment.
|
||||
|
||||
Scripts are automatically hot-reloaded.
|
||||
|
||||
> [!NOTE]
|
||||
> The Lua engine uses LuaJIT 5.1, and requires the use of a library called `lgi`.
|
||||
> Ensure you have the correct lua-lgi package installed.
|
||||
|
||||

|
||||
|
||||
## Configuration
|
||||
|
||||
> Type: `cairo`
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|--------------------|-----------|---------|----------------------------------------------------|
|
||||
| `path` | `string` | `null` | The path to the Lua script to load. |
|
||||
| `frequency` | `float` | `200` | The number of milliseconds between each draw call. |
|
||||
| `width` | `integer` | `42` | The canvas width in pixels. |
|
||||
| `height` | `integer` | `42` | The canvas height in pixels. |
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"center": [
|
||||
{
|
||||
"type": "cairo",
|
||||
"path": ".config/ironbar/clock.lua",
|
||||
"frequency": 100,
|
||||
"width": 300,
|
||||
"height": 300
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>TOML</summary>
|
||||
|
||||
```toml
|
||||
[[center]]
|
||||
type = "cairo"
|
||||
path = ".config/ironbar/clock.lua"
|
||||
frequency = 100
|
||||
width = 300
|
||||
height = 300
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>YAML</summary>
|
||||
|
||||
```yaml
|
||||
center:
|
||||
- type: cairo
|
||||
path: .config/ironbar/clock.lua
|
||||
frequency: 100
|
||||
width: 300
|
||||
height: 300
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Corn</summary>
|
||||
|
||||
```corn
|
||||
let {
|
||||
$config_dir = ".config/ironbar"
|
||||
$cairo = {
|
||||
type = "cairo"
|
||||
path = "$config_dir/clock.lua"
|
||||
frequency = 100
|
||||
width = 300
|
||||
height = 300
|
||||
}
|
||||
} in {
|
||||
center = [ $cairo ]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Script
|
||||
|
||||
Every script must contain a function called `draw`.
|
||||
This takes a single parameter, which is the Cairo context.
|
||||
|
||||
Outside of this, you can do whatever you like.
|
||||
The full lua `stdlib` is available, and you can load in additional system packages as desired.
|
||||
|
||||
The most basic example, which draws a red square, can be seen below:
|
||||
|
||||
```lua
|
||||
function draw(cr)
|
||||
cr:set_source_rgb(1.0, 0.0, 0.0)
|
||||
cr:paint()
|
||||
end
|
||||
```
|
||||
|
||||
A longer example, used to create the clock in the image at the top of the page, is shown below:
|
||||
|
||||
<details>
|
||||
<summary>Circle clock</summary>
|
||||
|
||||
```lua
|
||||
function get_ms()
|
||||
local ms = tostring(io.popen('date +%s%3N'):read('a')):sub(-4, 9999)
|
||||
return tonumber(ms) / 1000
|
||||
end
|
||||
|
||||
function draw(cr)
|
||||
local center_x = 150
|
||||
local center_y = 150
|
||||
local radius = 130
|
||||
|
||||
local date_table = os.date("*t")
|
||||
|
||||
local hours = date_table["hour"]
|
||||
local minutes = date_table["min"]
|
||||
local seconds = date_table["sec"]
|
||||
local ms = get_ms()
|
||||
|
||||
|
||||
local label_seconds = seconds
|
||||
seconds = seconds + ms
|
||||
|
||||
local hours_str = tostring(hours)
|
||||
if string.len(hours_str) == 1 then
|
||||
hours_str = "0" .. hours_str
|
||||
end
|
||||
|
||||
local minutes_str = tostring(minutes)
|
||||
if string.len(minutes_str) == 1 then
|
||||
minutes_str = "0" .. minutes_str
|
||||
end
|
||||
|
||||
local seconds_str = tostring(label_seconds)
|
||||
if string.len(seconds_str) == 1 then
|
||||
seconds_str = "0" .. seconds_str
|
||||
end
|
||||
|
||||
local font_size = radius / 5.5
|
||||
|
||||
cr:set_source_rgb(1.0, 1.0, 1.0)
|
||||
|
||||
cr:move_to(center_x - font_size * 2.5 + 10, center_y + font_size / 2.5)
|
||||
cr:set_font_size(font_size)
|
||||
cr:show_text(hours_str .. ':' .. minutes_str .. ':' .. seconds_str)
|
||||
cr:stroke()
|
||||
|
||||
if hours > 12 then
|
||||
hours = hours - 12
|
||||
end
|
||||
|
||||
local line_width = radius / 8
|
||||
local start_angle = -math.pi / 2
|
||||
|
||||
local end_angle = start_angle + ((hours + minutes / 60 + seconds / 3600) / 12) * 2 * math.pi
|
||||
cr:set_line_width(line_width)
|
||||
cr:arc(center_x, center_y, radius, start_angle, end_angle)
|
||||
cr:stroke()
|
||||
|
||||
end_angle = start_angle + ((minutes + seconds / 60) / 60) * 2 * math.pi
|
||||
cr:set_line_width(line_width)
|
||||
cr:arc(center_x, center_y, radius * 0.8, start_angle, end_angle)
|
||||
cr:stroke()
|
||||
|
||||
if seconds == 0 then
|
||||
seconds = 60
|
||||
end
|
||||
|
||||
end_angle = start_angle + (seconds / 60) * 2 * math.pi
|
||||
cr:set_line_width(line_width)
|
||||
cr:arc(center_x, center_y, radius * 0.6, start_angle, end_angle)
|
||||
cr:stroke()
|
||||
|
||||
return 0
|
||||
end
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
> [!TIP]
|
||||
> The C documentation for the Cairo context interface can be found [here](https://www.cairographics.org/manual/cairo-cairo-t.html).
|
||||
> The Lua interface provides a slightly friendlier API which restructures things slightly.
|
||||
> The `cairo_` prefix is dropped, and the `cairo_t *cr` parameters are replaced with a namespaced call.
|
||||
> For example, `cairo_paint (cairo_t *cr)` becomes `cr:paint()`
|
||||
|
||||
> [!TIP]
|
||||
> Ironbar's Cairo module has similar functionality to the popular Conky program.
|
||||
> You can often re-use scripts with little work.
|
||||
|
||||
### Initialization
|
||||
|
||||
You can optionally create an `init.lua` file in your config directory.
|
||||
Any code in here will be executed once, on bar startup.
|
||||
|
||||
As variables and functions are global by default in Lua,
|
||||
this provides a mechanism for sharing code between multiple modules.
|
||||
|
||||
## Styling
|
||||
|
||||
| Selector | Description |
|
||||
|----------|-------------------------|
|
||||
| `.cairo` | Cairo widget container. |
|
||||
|
||||
For more information on styling, please see the [styling guide](styling-guide).
|
|
@ -13,6 +13,7 @@ Clicking on the widget opens a popup with the time and a calendar.
|
|||
| `format` | `string` | `%d/%m/%Y %H:%M` | Date/time format string. Pango markup is supported. |
|
||||
| `format_popup` | `string` | `%H:%M:%S` | Date/time format string to display in the popup header. Pango markup is supported. |
|
||||
| `locale` | `string` | `$LC_TIME` or `$LANG` or `'POSIX'` | Locale to use (eg `en_GB`). Defaults to the system language (reading from env var). |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the time on the clock button. |
|
||||
|
||||
> Detail on available tokens can be found here: <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
Allows you to compose custom modules consisting of multiple widgets, including popups.
|
||||
Allows you to compose custom modules consisting of multiple modules and widgets, including popups.
|
||||
Labels can display dynamic content from scripts, and buttons can interact with the bar or execute commands on click.
|
||||
|
||||
The module provides a set of utility widgets, such as containers, labels and buttons.
|
||||
In addition to these, you can also add any native module.
|
||||
Paired with the other custom modules such as Cairo,
|
||||
this provides a powerful declarative interface for constructing your own interfaces.
|
||||
|
||||
If you only intend to run a single script, prefer the [script](script) module,
|
||||
or [label](label) if you only need a single text label.
|
||||
|
||||
|
@ -13,6 +18,11 @@ or [label](label) if you only need a single text label.
|
|||
This module can be quite fiddly to configure as you effectively have to build a tree of widgets by hand.
|
||||
It is well worth looking at the examples.
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|---------|------------------------|------------|------------------------------------------|
|
||||
| `bar` | `(Module or Widget)[]` | `[]` | Modules and widgets to add to the bar. |
|
||||
| `popup` | `(Module or Widget)[]` | `null` | Modules and widgets to add to the popup. |
|
||||
|
||||
### `Widget`
|
||||
|
||||
There are many widget types, each with their own config options.
|
||||
|
@ -36,7 +46,7 @@ A container to place nested widgets inside.
|
|||
| Name | Type | Default | Description |
|
||||
|---------------|------------------------------------------------------------|----------------|-------------------------------------------------------------------|
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Whether child widgets should be horizontally or vertically added. |
|
||||
| `widgets` | `Widget[]` | `[]` | List of widgets to add to this box. |
|
||||
| `widgets` | `(Module or Widget)[]` | `[]` | List of modules/widgets to add to this box. |
|
||||
|
||||
#### Label
|
||||
|
||||
|
@ -47,6 +57,7 @@ A text label. Pango markup is supported.
|
|||
| Name | Type | Default | Description |
|
||||
|---------|-------------------------------------------------|---------|---------------------------------------------------------------------|
|
||||
| `label` | [Dynamic String](dynamic-values#dynamic-string) | `null` | Widget text label. Pango markup and embedded scripts are supported. |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the label. |
|
||||
|
||||
#### Button
|
||||
|
||||
|
@ -54,10 +65,12 @@ A clickable button, which can run a command when clicked.
|
|||
|
||||
> Type `button`
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|------------|-------------------------------------------------|---------|---------------------------------------------------------------------|
|
||||
| `label` | [Dynamic String](dynamic-values#dynamic-string) | `null` | Widget text label. Pango markup and embedded scripts are supported. |
|
||||
| `on_click` | `string [command]` | `null` | Command to execute. More on this [below](#commands). |
|
||||
| Name | Type | Default | Description |
|
||||
|------------|-------------------------------------------------|---------|--------------------------------------------------------------------------------------------------|
|
||||
| `label` | [Dynamic String](dynamic-values#dynamic-string) | `null` | Widget text label. Pango markup and embedded scripts are supported. Ignored if `widgets` is set. |
|
||||
| `widgets` | `(Module or Widget)[]` | `[]` | List of modules/widgets to add to this button. |
|
||||
| `on_click` | `string [command]` | `null` | Command to execute. More on this [below](#commands). |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the button. |
|
||||
|
||||
#### Image
|
||||
|
||||
|
@ -197,6 +210,7 @@ to help get your head around what's going on:
|
|||
<button class="power-btn" label="" on_click="!reboot" />
|
||||
</box>
|
||||
<label name="uptime" label="Uptime: {{30000:uptime -p | cut -d ' ' -f2-}}" />
|
||||
<clock disable_popup="true" />
|
||||
</box>
|
||||
</popup>
|
||||
</custom>
|
||||
|
@ -252,6 +266,10 @@ to help get your head around what's going on:
|
|||
"label": "Uptime: {{30000:uptime -p | cut -d ' ' -f2-}}",
|
||||
"name": "uptime",
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"type": "clock",
|
||||
"disable_popup": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -309,6 +327,10 @@ type = 'button'
|
|||
label = '''Uptime: {{30000:uptime -p | cut -d ' ' -f2-}}'''
|
||||
name = 'uptime'
|
||||
type = 'label'
|
||||
|
||||
[[end.popup.widgets]]
|
||||
type = 'clock'
|
||||
disable_popup = true
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -345,6 +367,8 @@ end:
|
|||
- label: 'Uptime: {{30000:uptime -p | cut -d '' '' -f2-}}'
|
||||
name: uptime
|
||||
type: label
|
||||
- type: clock
|
||||
disable_popup: true
|
||||
type: custom
|
||||
```
|
||||
|
||||
|
@ -370,6 +394,7 @@ let {
|
|||
]
|
||||
}
|
||||
{ type = "label" name = "uptime" label = "Uptime: {{30000:uptime -p | cut -d ' ' -f2-}}" }
|
||||
{ type = "clock" disable_popup = true }
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ Pango markup is supported.
|
|||
| `interval.temps` | `integer` | `5` | Seconds between refreshing temperature data |
|
||||
| `interval.disks` | `integer` | `5` | Seconds between refreshing disk data |
|
||||
| `interval.network` | `integer` | `5` | Seconds between refreshing network data |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the labels. |
|
||||
| `direction` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | How the labels are laid out (not the rotation of an individual label). |
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue