Major enhancements to VisualLog
The biggest change of v0.8.1 is the implementation of different kinds of cache references and bindings. Until now one had to access data being streamed from one LogBuilder cell to another with a classical, dictionary-like item access such as `my_value = self["my_value"]`
This had two major flaws: A typo can happen easily while typing a variable's name and the IDE did not know which kind of type could be assumed leading to further potential errors due to missing code analysis.
Second there was currently no clean way to access the cache's data from another thread, e.g. for time consuming workloads which should not be executed in the main thread.
For the first case there is now the new system of CacheLinks which works as follows: In the LogBuilder's __init__ function (like for a common object) you assign the class attribute a so called CLRef via self.clref(default_value), optionally you can also set the parameter create to false if you do not want to create the variable initially such as follows:
`self.my_value: int = self.clref(0)`
This tells the IDE the type and will initialize the value in the cache (if create isn't set to False). When ever you now access the variable's name "magic" in the LogBuilder's class will forward all read and write accesses from and to the cache this you can use a cache's data entry like every common class attribute.
For helper classes where this is no possibility, e.g. other threads, you can create a so called CacheRef via self.cache.create_ref. It will provide a thread-safe link to the LogBuilder's cache and most of all the possibility to (ex)change cache element's asynchronously, e.g. input data to output data.
VisualLog
* Disable automatically catching stdout in cells by default. Will be added to the options soon.
* Enhanced Cache functionality:
* Changes can now be staged via set_async and lpush_async. The staged changes can then be applied in the main thread by async_fetch. This way corrupting the cache in the middle of a building process can be avoided as now the main thread has full control over WHEN to apply these updates
* Test enhancements for Cache and CacheRef
* Implemented the LSelect widget (a combo box)
* Added the class CacheRef which can read and write one specific cache value and decide whether it will be written asap or via the new async methods.
* Added basic support for pages and tabs to LogBuilder. It is now possible to assign a page and/or a tab to a cell and use LogBuilder.page, LogBuilder.tab or LogBuilder.set_page to select which cells shall be visible.
* Added support for cell groups to LogBuilder. It is now possible to assign one or multiple groups to a cell and to filter the visible cells via LogBuilder.visible_groups and LogBuilder.hidden_groups
* Optimized the logging of simple tables
* Cells can not verify requirements by value via keyName==assumedValue
* Added the possibility to bind LogBuilder virtual attributes to element's in the cache for easier usage and better code insight support. Via `self.my_attribute = self.clref(default_value)`` a LogBuilder subclass attribute is bound to the corresponding name in the cache.
* Added tests for the LSelect class
* data, stream and once cells are now static to don't create waste within the html output
ImageStag
* Bugfix: Disable lazy loading for PIL images as they caused evil side effects in multi-threaded environments
DataStag
* It is now possible to transfer dictionaries, pandas dataframes and pandas time series via a remote DataStag connection
Bugfixes
* DataStagVault: It was not possible to pop the last element of a list via connection.pop(index=-1) because negative values were invalid in general. Now negative values are supported as for common Python lists.
* Editing an LSlider's value in the edit field directly did not trigger any change event
* An (empty) Image could not initialized as grayscale image