[doc] minor restructuring
This commit is contained in:
parent
3c2ed218cf
commit
e612ec11ac
5 changed files with 0 additions and 10 deletions
130
doc/development/WRITING-A-MODULE.md
Normal file
130
doc/development/WRITING-A-MODULE.md
Normal file
|
@ -0,0 +1,130 @@
|
|||
# Writing a bumblebee-status module
|
||||
|
||||
## Introduction
|
||||
Adding a new module to `bumblebee-status` is straight-forward:
|
||||
|
||||
- Add a new Python module in `modules/contrib/`. The name of the
|
||||
module will be the name that the user needs to specify when
|
||||
invoking `bumblebee-status` (i.e. a module called `modules/contrib/test.py`
|
||||
will be loaded using `bumblebee-status -m test`)
|
||||
- See below for how to actually write the module
|
||||
- Test (run `bumblebee-status` in the CLI)
|
||||
- Make sure your changes don't break anything: `./coverage.sh`
|
||||
- If you want to do me favour, run your module through `black -t py34` before submitting
|
||||
|
||||
## Pull requests
|
||||
The project **gladly** accepts PRs for bugfixes, new functionality, new
|
||||
modules, etc.
|
||||
When you feel comfortable with what you've developed, please just open
|
||||
a PR, somebody will look at it eventually :) Thanks!
|
||||
|
||||
## Coding guidelines
|
||||
I'm pretty open to whatever style you use, but if it's all the same to you
|
||||
(and yes, I know that the current codebase is only slowly adapting to this):
|
||||
- Please favour single quotes for strings (except for docstrings, which are always """)
|
||||
- For private methods/variables, please use a leading `__` (e.g. `__output` rather than `_output`)
|
||||
|
||||
## Hello world
|
||||
This example will show "hello world" in the status bar:
|
||||
|
||||
```python
|
||||
"""Short description"""
|
||||
|
||||
import core.module
|
||||
import core.widget
|
||||
|
||||
class Module(core.module.Module):
|
||||
def __init__(self, config):
|
||||
super().__init__(config, core.widget.Widget(self.full_text))
|
||||
|
||||
def full_text(self, widgets):
|
||||
return 'hello world'
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
```
|
||||
|
||||
## Of modules and widgets
|
||||
There are two important concepts for module writers:
|
||||
- A module is something that offers a single set of coherent functionality
|
||||
- A module has 1 to n "widgets", which translates to individual blocks in the i3bar
|
||||
|
||||
Very often, this is a 1:1 relationship, and a single module has a single widget. If that's the
|
||||
case for you, you can stop reading now :)
|
||||
|
||||
Otherwise, you have a number of ways to handle widgets:
|
||||
- During the `super().init__(...)` inside the module's constructor, you can specify a **list**
|
||||
of widgets, and those will comprise the widgets (in ordered fashion)
|
||||
- During runtime, you can set a new list of widgets by using the `self.widgets(<new list>)`
|
||||
method of the module
|
||||
|
||||
## Adding widgets at runtime
|
||||
If you want to add widgets during runtime, please use the `add_widget()` method of the module:
|
||||
|
||||
```
|
||||
def do_something(self):
|
||||
self.add_widget(full_text="my sample text", name="<optional name>")
|
||||
```
|
||||
|
||||
TODO: expand on this
|
||||
|
||||
## Periodic updates
|
||||
`bumblebee-status` modules have two different ways to update their data:
|
||||
1. Each interval, the callback registered when the widget was created is called. You can do arbitrarily complex things there
|
||||
2. Each interval, **before** the widget's callback is invoked, a generic `update(self, widgets)` method is called on the **module**
|
||||
|
||||
Largely, where you want to put your update code is up to you. My observations:
|
||||
- If you want to change the widgets a module has, you **have** to stick with `update()`
|
||||
- For simple modules, doing the data update in the widget callback is simplest (see `kernel`, for example)
|
||||
|
||||
## Advanced topics
|
||||
### Event handlers
|
||||
The `core.input` module can be used to execute callbacks during mouse events:
|
||||
```python
|
||||
import core.module
|
||||
import core.widget
|
||||
import core.input
|
||||
|
||||
class Module(core.module.Module):
|
||||
@core.decorators.every(minutes=60, seconds=20)
|
||||
def __init__(self, config):
|
||||
super().__init__(config=config, widgets=<widgets>)
|
||||
|
||||
core.input.register(widget, button=core.input.LEFT_MOUSE, cmd=<cmd>)
|
||||
```
|
||||
|
||||
The command can be either a CLI tool that will be directly executed (e.g. `cmd='shutdown -h now'`)
|
||||
or a method that will be executed. The method's signature needs to be: `def <name>(self, event)`,
|
||||
where "event" is the event data provided by i3wm.
|
||||
|
||||
The full list of possible bindings:
|
||||
- LEFT_MOUSE
|
||||
- RIGHT_MOUSE
|
||||
- MIDDLE_MOUSE
|
||||
- WHEEL_UP
|
||||
- WHEEL_UP
|
||||
|
||||
### Setting a default update interval
|
||||
To change the default update interval, you can use a simple decorator:
|
||||
```python
|
||||
import core.module
|
||||
import core.widget
|
||||
import core.decorators
|
||||
|
||||
class Module(core.module.Module):
|
||||
@core.decorators.every(minutes=60, seconds=20)
|
||||
def __init__(self, config):
|
||||
super().__init__(config=config, widgets=<widgets>)
|
||||
```
|
||||
|
||||
**NOTE**: This makes the update interval of the module independent of what the
|
||||
user configures via `-i <interval>`! It is still possible to override the module's
|
||||
interval using `-p <module>.interval=<value>`, however.
|
||||
|
||||
## TODOs
|
||||
- default update interval
|
||||
- scrolling
|
||||
- theme.minwidth
|
||||
- scrolling decorator
|
||||
- theme.exclude
|
||||
- per module update interval -> nice string format
|
||||
- update via events
|
111
doc/development/WRITING-A-THEME.md
Normal file
111
doc/development/WRITING-A-THEME.md
Normal file
|
@ -0,0 +1,111 @@
|
|||
# How to write themes
|
||||
|
||||
## Introduction
|
||||
`bumblebee-status` themes are simply JSON files that describe various attributes (foreground color,
|
||||
background color, etc.) of the blocks that make up a status bar.
|
||||
|
||||
It is possible to specify each attribute at various levels:
|
||||
- For a specific state of a specific module
|
||||
- For a specific module
|
||||
- A cycle of attributes (those are cycled through widget-by-widget)
|
||||
- Default values
|
||||
|
||||
Looking up a value follows the "more specific rather than more generic" approach. In other words,
|
||||
if a foreground color exists for the "warning" state of module "a", any less specific foreground
|
||||
color value that **would** match will be ignored.
|
||||
|
||||
Themes are loaded from the following locations:
|
||||
- `$(BUMBLEBEE_STATUS_BASE_DIR)/themes/`
|
||||
- `~/.config/bumblebee-status/themes/`
|
||||
|
||||
## Basic structure
|
||||
A very simple theme file looks like this:
|
||||
```json
|
||||
{
|
||||
"icons": [ "awesome-fonts" ],
|
||||
"defaults": {
|
||||
"fg": "#000000",
|
||||
"bg": "#ffffff",
|
||||
"warning": {
|
||||
"fg": "#ff0000",
|
||||
"bg": "#ffffff"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Icons
|
||||
Using the `icons` directive, it's possible to reuse icon definitions for multiple themes.
|
||||
The value of the field is the **basename** of a JSON file located in `$(THEME_DIRECTORY)/icons/`.
|
||||
The format of the icon file is identical to the theme itself (as the two are essentially just
|
||||
merged into a single JSON.
|
||||
|
||||
## Color definitions and pyWAL support
|
||||
`bumblebee-status` supports [github:dylanaraps/pywal](https://github.com/dylanaraps/pywal) definitions.
|
||||
|
||||
To make use of them, simply generate a colorset using pyWAL and reference it in the theme like
|
||||
this:
|
||||
|
||||
```json
|
||||
{
|
||||
"icons": [ ... ],
|
||||
"colors": [ "wal" ],
|
||||
"defaults": {
|
||||
"critical": {
|
||||
"fg": "cursor",
|
||||
"bg": "color5"
|
||||
},
|
||||
"warning": {
|
||||
"fg": "cursor",
|
||||
"bg": "color6"
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Additionally, you can use the `colors` directive to set up named colors for your scheme:
|
||||
|
||||
```json
|
||||
{
|
||||
"icons": [ ... ],
|
||||
"colors": [ { "red": "#ff0000", "green": "#00ff00", "black": "#000000" } ],
|
||||
"defaults": {
|
||||
"critical": {
|
||||
"fg": "red",
|
||||
"bg": "black"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Pango support
|
||||
All values that accept a full text (i.e. the base level, `prefix` and `suffix`) accept a special
|
||||
attribute `pango` **instead** of all other attributes. In other words, if you specify `pango`,
|
||||
any other attribute on that level (foreground color, etc.) will be ignored!
|
||||
|
||||
Inside `pango`, you can just specify arbitrary Pango attributes, and those will be applied to a
|
||||
`<span></span>` that's automatically enclosing the actual text.
|
||||
|
||||
## Full list of attributes
|
||||
|
||||
(TODO: Add explanation)
|
||||
|
||||
- defaults
|
||||
- cycle
|
||||
- icons
|
||||
- warning
|
||||
- critical
|
||||
- fg
|
||||
- bg
|
||||
- separator
|
||||
- padding
|
||||
- pango
|
||||
- prefix
|
||||
- suffix
|
||||
- default-separators
|
||||
- separator-block-width
|
||||
- <module name>
|
||||
- <state>
|
||||
|
||||
## Examples
|
||||
|
||||
see [github:tobi-wan-kenobi/bumblebee-status/themes](https://github.com/tobi-wan-kenobi/bumblebee-status/tree/master/themes)
|
Loading…
Add table
Add a link
Reference in a new issue