bear_hug.bear_hug module

An object-oriented bearlibterminal wrapper with the support for complex ASCII art and widget-like behaviour.

class bear_hug.bear_hug.WidgetLocation(pos, layer)

Bases: tuple

layer

Alias for field number 1

pos

Alias for field number 0

class bear_hug.bear_hug.BearTerminal(font_path='../demo_assets/cp437_12x12.png', **kwargs)

Bases: object

A main terminal class.

This class corresponds to a single window and is responsible for drawing whatever widgets get added to this window, as well as processing any input.

Accepts bearlibterminal library configuration options as kwargs to self.__init__. Currently only library settings are supported and there is no support for changing them on the fly.

start()

Open a terminal and place it on the screen.

Library settings that were passed as kwargs to self.__init__() get actually applied during when this method is executed.

clear()

Remove all widgets from this terminal, but do not close it.

refresh()

Refresh a terminal.

Actually draws whatever changes were made by *_widget methods.

close()

Close a terminal.

Does not destroy Widget objects or call any other cleanup routine.

add_widget(widget, pos=(0, 0), layer=0, refresh=False)

Add a widget to the terminal and set widget.terminal to self.

No two widgets are allowed to overlap within a layer and no widget can be added twice.

Parameters:
  • widget – a Widget instance
  • pos – top left corner of the widget
  • layer – layer to place the widget on
  • refresh – whether to refresh terminal after adding the widget. If False, the widget will not be actually shown until the next terminal.refresh() call
remove_widget(widget, refresh=False)

Remove widget from the terminal.

This method does not cause or imply the destruction of Widget object; it merely removes it from the terminal.

Parameters:
  • widget – A widget to be removed
  • refresh – whether to refresh the terminal after removing a widget. If False, the widget will be visible until the next terminal.refresh() call
move_widget(widget, pos, refresh=False)

Move widget to a new position.

Widgets can only be moved within the layer. If it is necessary to move a widget from one layer to another, it should be removed and added anew.

Parameters:
  • widget – A widget to be moved
  • pos
    param refresh:whether to refresh the terminal after removing a widget. If False, the widget won’t move on screen until the next terminal.refresh() call
update_widget(widget, refresh=False)

Actually draw widget chars on screen.

If widget.chars or widget.colors have changed, this method will make these changes visible. It is also called by self.add_widget() and other methods that have a refresh argument.

Parameters:widget – A widget to be updated.
get_widget_by_pos(pos, layer=None)

Return the widget currently placed at the given position.

Parameters:
  • pos – Position (a 2-tuple of ints)
  • layer – A layer to look at. If this is set to valid layer number, returns the widget (if any) from that layer. If not set, return the widget from highest layer where a given cell is non-empty.
check_input()

Check if terminal has input. If so, yield corresponding BearEvent.

This method returns an iterator because it’s possible there would be more than one event in a single tick, eg when two buttons are pressed simultaneously.

This method mostly just wraps bearlibterminal’s input behaviour in `events<foo.wyrd.name/en:bearlibterminal:reference:input>`_, with a single exception: in bearlibterminal, when a key is pressed and held for more than a single tick, it first emits key_down, then waits for 0.5 seconds. Then, if the key is not released, it assumes the key is indeed held and starts spamming events every tick. This makes sense to avoid messing up the typing (where a slow typist would get char sequences like tthiisss).

Bearlibterminal, on the other hand, is meant mostly for games that require more precise input timing. Therefore, it starts spamming key_down events immediately after the button is pressed and expects widgets and listeners to mind their input cooldowns themselves.

Yields:BearEvent instances with event_type set to misc_input, key_up or key_down.
check_state(query)

Wrap BLT state

Accepts any of the TK_* strings and returns whatever terminal.state has to say about it.

Parameters:query – query string
class bear_hug.bear_hug.BearLoop(terminal, queue, fps=30, profile=False)

Bases: object

A loop that passes events around every 1/fps seconds.

Every tick, the loop calls its run_iteration() method, adding tick-related and input-related events to the queue, and then forcing it to start passing all events to the correct subscribers.

There are two tick-related events. In the beginning of the tick it’s tick-type event whose value is time since the last similar event (in seconds). This is guaranteed to be emitted before any other events from this tick, since the queue wouldn’t finish the previous one until it was empty.

In the end of the tick it’s a service-type event with the value ‘tick_over’, which is emitted after the entire queue has been processed. It is meant to let subscribers know that the tick is over and nothing is going to happen until the next one. This is, for example, a perfect moment for a Layout to redraw itself, or for a logger to write everything down.

If any events are emitted in response to this event, they will be passed around before the next tick. This is a great source of bugs, so it is not advised to respond to tick_over unless absolutely necessary.

The loop cannot be started until it has a valid terminal. When the loop is stopped, this terminal is shut down.

Parameters:
  • terminal – a BearTerminal instance to collect input from.
  • queue – a bear_hug.event.BearEventDispatcher instance to send events to.
  • fps – a number of times per second this loop should process events.
run()

Start a loop.

It would run until stopped with self.stop()

stop()

Order the loop to stop.

It would not actually do it until the current tick is processed.