Skip to content

Commit

Permalink
feat: make core Tree be able to accept config on init
Browse files Browse the repository at this point in the history
  • Loading branch information
aravinda0 committed Dec 16, 2023
1 parent b816901 commit cc32f4f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
16 changes: 14 additions & 2 deletions src/qtile_bonsai/core/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,30 @@ class InvalidTreeStructureError(Exception):

class Tree:
TreeEventCallback = Callable[[list[Node]], None]
MultiLevelConfig = collections.defaultdict[int, dict[str, Any]]

_recency_seq = 0

# Tab levels of trees begin from 1 for the topmost level. Use 'level 0' to store
# defaults.
_default_config_level_key = 0

def __init__(self, width: int, height: int):
def __init__(
self,
width: int,
height: int,
config: MultiLevelConfig | None = None,
):
self._width: int = width
self._height: int = height
self._config: collections.defaultdict[int, dict] = self.make_default_config()
self._root: TabContainer | None = None

self._config: Tree.MultiLevelConfig = self.make_default_config()
if config is not None:
for level, lconfig in config.items():
for k, v in lconfig.items():
self._config[level][k] = v

self._event_subscribers: collections.defaultdict[
TreeEvent, dict[str, Tree.TreeEventCallback]
] = collections.defaultdict(dict)
Expand Down
18 changes: 11 additions & 7 deletions src/qtile_bonsai/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# SPDX-License-Identifier: MIT


import collections
import itertools
import re
from typing import Callable, ClassVar
Expand Down Expand Up @@ -510,8 +511,7 @@ def _handle_default_next_window(self) -> BonsaiPane:
def _reset(self):
# We initialize the tree with arbitrary dimensions. These get reset soon as this
# layout's group is assigned to a screen.
self._tree = BonsaiTree(100, 100)
self._parse_config()
self._tree = BonsaiTree(100, 100, config=self.get_multi_level_config())

self._tree.subscribe(
TreeEvent.node_added, lambda nodes: self._handle_added_tree_nodes(nodes)
Expand All @@ -527,18 +527,22 @@ def _handle_next_window():

self._on_next_window = _handle_next_window

def _parse_config(self):
config = itertools.chain(
def get_multi_level_config(self) -> BonsaiTree.MultiLevelConfig:
merged_user_config = itertools.chain(
((c[0], c[1]) for c in self.defaults),
((k, v) for k, v in self._user_config.items()),
)
for [key, value] in config:

multi_level_config: BonsaiTree.MultiLevelConfig = collections.defaultdict(dict)
for key, value in merged_user_config:
level_specific_key = self.level_specific_config_format.match(key)
level = None
level = 0
if level_specific_key is not None:
level = int(level_specific_key.group(1))
key = level_specific_key.group(2)
self._tree.set_config(key, value, level=level)
multi_level_config[level][key] = value

return multi_level_config

def _handle_added_tree_nodes(self, nodes: list[BonsaiNodeMixin]):
for node in nodes:
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/core/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -3698,6 +3698,22 @@ def test_when_the_provided_tabs_are_nested_under_one_another_then_an_error_is_ra


class TestConfig:
def test_when_config_is_passed_on_init_then_it_overrides_default_config(self):
# Default window.margin is 0
config = {
0: {
"window.margin": 12,
}
}

tree = Tree(400, 300, config)

p1 = tree.tab()
p2 = tree.split(p1, "x")

assert p1.box.margin == 12
assert p2.box.margin == 12

def test_fall_back_to_default(self, tree: Tree):
tree.set_config("window.margin", 10)

Expand Down

0 comments on commit cc32f4f

Please sign in to comment.