# Xfbp python bindings

Author: | Klaus Koepernik

## General

The python binding of xfbp is hard coded into the program. There is no source code you can look at. Because of this tight connection pyxfbp can only be used from within xfbp. For convenience we have decided to setup the python environment in the following way:

The pyxfbp module is already imported as:

    from pyxfbp import *

which injects all classes into the namespace. We also created an instance of the class `pyxfbp.Xfbp` called xfbp. From this some methods/properties are loaded into the namespace

> - `G` represents all Graphs
> - `killall` clean slate
> - `printto` guess what
> - `paper` setup paper dimensions
> - `arrange` arranges graphs
> - `setMouseHook` set a mini-script to be executed on left mouse click
> - `cursor` the cursor position on mouse click

All other properties/classes can be accessed hierarchically from `G`. Many classes can be used standalone, whatever is more convenient. E.g.:

    Title(1).text='some text'
    #and
    G[1].title.text='some text '

both change the text of the graph with id 1. However, indexing only works via the corresponding properties as in:

    # copy set 1 into set 1
    G[1].Gr[1].S[2]=G[1].Gr[1].S[1]

For a better understanding of the indexing read the doc for `Graphs`. Some simple classes like `FontStyle` behave differently in that they either represent the fontstyle of some object or can be created for assignment reasons:

    # Here font returns a FontStyle object representing
    # the title's font
    Title(1).font.color=0xff

    # Here we create a free stranding FontStyle
    fst=FontStyle(color=0xff)

    # and assign it to all textboxes (assuming some exist)
    for t in G[1].textboxes:
        t.font=fst

In the first case .font returns a FontStyle object representing the titles font and in the second the textboxes font is hard copied from fst.

Note, that many data are implemented as properties and some as functions/methods. Properties can be gotten and set, functions must be called:

    G[1].title.text='some text' # set the property text

    ti=G[1].title.text # get the property text

    G[1].title.off() # call the method `off`.

## Examples

There are examples of `.xpy` scripts scattered through out the pyfplo examples in `FPLO.../DOC/pyfplo/Examples` and in `FPLO.../DOC/Xfbp/Examples`.

## Editor

The code editor has two modes, the native xfbp script mode with (file extension `.cmd`) which is still available but not as versatile and the python mode (file extension `.xpy` or `.py`). The `.xpy` extension is usefull for easy file association e.g. in midnight-commander or desktop tools. It also signals that these python scripts need xfbp to run. They cannot run standalone (yet).

A new script will have a file type marker at the beginning. This is only ment to tell you , which mode you are in. It is not used for identification. The file extensions decide how the script is parsed.

Python uses indentation to mark blocks. The editor supports python style, where you use the tab key to indent by 4 spaces. You can select a bunch of lines and indent or unindent them via editing menu commands. If for some reasons tab-characters find their way into the script they are highlighted to find them easier. You should use block unindent and indent to convert them into space. Otherwise, python might consider wrong indentation, which can change the meaning of the code. It might run but does not do what you expect.

Note, that if you copy text from some other source (help) the indentation might be wrong. If this happens select the block, indented/unindent it with the edit commands as needed.

There is quite some code insertion available. The fastest is to adjust you textboxes, shapes and world and view and then to insert the corresponding code into the script via the editors insert menu. Code insertion often uses direct object access in contrast to hierarchical access for brevity. You will get the hang of it. After insertion select the whole block and use the edit->indent functionality for proper python indentation, if needed.

## Help

There are two versions of inbuilt help. The first is called when a python help command is written into the editor and the script is executed while the editor is open. This will either display the content from the python help system if the item does not belong to `pyxfbp` or display the `pyxfbp` help. The other version is just pressing F1 in the editor, which displays `pyxfbp` help. The help browser has a search function (Ctrl-F). Type the search string. Hit Ctrl-F or ENTER to continue searching. If the search reaches the end of the file hit Ctrl-F/ENTER again to start from the beginning. Hit ESCAPE to leave the search. Hit Ctrl-F twice to redo the previous search.

How to use it: if you don’t know what comes next do the following:

    g=G[1] # g represents graph with id 1
    help(g)

will tell you that g is a `Graph` instance and from there you can pick a property, say Gr and write instead:

    help(g.Gr[1])

Yet another way is to type in help for a class member:

    help(Graph.active)    # help on property active in class Graph

which is not the same as:

    help(G[1].active)     # G[1] is a Graph instance and G[1].active an int
                          # so you get help for the int class of python

You get the idea. If you know your way around just hit F1 and use the search function.

If you want help on python keywords like `for` type:

    help('for') # yes as string!

On last note … the functions which where loaded into the namespace from xfbp will be treated like python internal help. If you type:

    help(Xfbp.killall)

you get the expected result.

# Commmand line parameters

In order to write generic scripts, command line parameters are implemented the following way. On the command line you give something like:

    xfbp -a filename:+band -a col:0xff -a unit:0.529177 -a i:3

where the part before the colon is the variable name and the part after the colon is the value. There shoudn’t be a space before and after the colon! You can us quotes for longer `str` values. If the `str` value contains $-formating use single quotes! The program will determine the easiest type of all values by trying to cast it in the following order: hex(`int`), `int`, `float` and `str`. If any of the casts succeeds the parameter in python will have this type, e.g. `-a i:42` will be an `int`. If inside the script you want it to be a `str` use `str(i)`. Please note, that these parameters become normal variables in the script. You should be carefull with the names. Simple example script called t.py:

    killall()
    G[1].read("band",filename)
    G[1].Gr[1].line.color=col
    G[1].title.text=title
    G[1].yaxislabel.text='Energy [{}]'.format(sunit)
    for s in G[1].Gr[1].S:
        s.y/=unit
    G[1].world.ymin/=unit
    G[1].world.ymax/=unit

is called e.g. like this:

    xfbp t.py -a filename:+band -a col:0xff -a title:'This works: FeO$_2$.' \
       -a unit:13.60569193 -a sunit:Ry

More command line parameters are found under Command line options.

# Text Formating

The various properties which can hold text can be formated in the following way.

- `$~`

    next character is from the symbol font (greek) (hopefully works on your system)

- `$i`

    switch to italic font

- `$n`

    switch to regular font

- `$_`

    switch to next subscript level

- `$^`

    switch to next superscript level

- `$.`

    switch to normal level

- `$x{real-number}`

    shift the current position (for the following characters) to the right (positive number) or left (negative number). Note that the shift scale is different before or after a sub/super script marker (`$^`, `$_`). Try:

        X$_ij$.$x{-0.5}$^ab$.

    or:

        X$_a$_i$.$x{-0.8}$^$~m$.

    versus:

        X$_ij$.$^ab$.

    or:

        X$_a$_i$.$^$~m$.

- `$y{real-number}`

    vertical shift (see `$x{}` above)

- `$arrowup`, `$arrowdown`, `$arrowleft`, `$arrowright`, `$angstroem`, `$infinity`, `$nabla`

    some special characters (hopefully works)

- `$$`

    a $ sign

Note, that some special characters (e.g. `$arrowup`) switch the font to regular after they were printed (bug). To continue with italic, use another `$i`. On some systems the display of symbol characters is wrong.

# Colors

There are several classes which have colors. A color is given as a hex(int) constant. A color is coded as rgb (red/green/blue) value. The format is as follows: There are three bytes (value 0..255) in a color the first byte represents the red value, the second green and the third blue. Using hex notation the bytes are forming two digit hex numbers. Hence a color contains 6 hex digits. The brightest colors are the highest value (ff). If red is zero it does not have to be written explicitly. A hex constant starts with `0x` The bytes are in the order left to right: r g b. If a color is returned by `pyxfbp` it is returend as `int` (base 10) .To print it in hex form use `print hex(c)`. Examples:

> hex color | red | green | blue | color
> `0xff00aa` | `ff/255` | `0` | `aa/170` | pink
> `0xffffff` | `ff/255` | `ff/255` | `ff/255` | white
> `0xff` | `0` | `0` | `ff/255` | blue
> `0xff0000` | `ff/255` | `0` | `0` | red
> `0xff00` | `0` | `ff/255` | `0` | green
> `0xaa00` | `0` | `aa/170` | `0` | darker green
> `0x0` | `0` | `0` | `0` | black

Usefull defaults

> hex | amount (1==100%)
> 00 | 0
> 33 | 0.2
> 40 | 1/4
> 55 | 1/3
> 66 | 0.4
> 80 | 1/2
> 99 | 0.6
> aa | 2/3
> c0 | 3/4
> cc | 0.8
> ff | 1