Skip to content

Commit

Permalink
refactor: Make layout_factory accept PhysicalLayout's
Browse files Browse the repository at this point in the history
  • Loading branch information
caksoylar committed Apr 16, 2024
1 parent f5b3848 commit f7aee90
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 31 deletions.
2 changes: 2 additions & 0 deletions keymap_drawer/keymap.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ def create_layout(cls, vals):
"""Create layout with type given by layout param."""
if vals["layout"] is None: # ignore for no-layout mode
return vals
if isinstance(vals["layout"], PhysicalLayout): # already provided a valid object
return vals
vals["layout"] = layout_factory(config=vals["config"], **vals["layout"])
return vals

Expand Down
65 changes: 34 additions & 31 deletions keymap_drawer/physical_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,12 @@ def layout_factory( # pylint: disable=too-many-arguments
)
layout = qmk_info["layouts"][qmk_layout]["layout"]

keys = QmkLayout(layout=layout).generate(config.key_h)
elif ortho_layout is not None:
keys = OrthoLayout(**ortho_layout).generate(config.key_w, config.key_h, config.split_gap)
else: # cols_thumbs_notation
assert cols_thumbs_notation is not None
keys = CPTLayout(spec=cols_thumbs_notation).generate(config.key_w, config.key_h, config.split_gap)
return PhysicalLayout(keys=keys)
return QmkLayout(layout=layout).generate(config.key_h)
if ortho_layout is not None:
return OrthoLayout(**ortho_layout).generate(config.key_w, config.key_h, config.split_gap)

assert cols_thumbs_notation is not None
return CPTLayout(spec=cols_thumbs_notation).generate(config.key_w, config.key_h, config.split_gap)


class OrthoLayout(BaseModel):
Expand Down Expand Up @@ -249,7 +248,7 @@ def check_drops(self):
assert self.split, '"drop_*" properties can only be used with split layouts'
return self

def generate(self, key_w: float, key_h: float, split_gap: float) -> list[PhysicalKey]:
def generate(self, key_w: float, key_h: float, split_gap: float) -> PhysicalLayout:
"""Generate a list of PhysicalKeys from given ortho specifications."""
nrows = self.rows
if not isinstance(self.thumbs, int):
Expand Down Expand Up @@ -285,7 +284,7 @@ def create_row(x: float, y: float, ncols: int = ncols) -> list[PhysicalKey]:
y += key_h

if not self.thumbs:
return keys
return PhysicalLayout(keys=keys)

match self.thumbs:
case int(): # implies split
Expand All @@ -307,7 +306,7 @@ def create_row(x: float, y: float, ncols: int = ncols) -> list[PhysicalKey]:
case _:
raise ValueError("Unknown thumbs value in ortho layout")

return keys
return PhysicalLayout(keys=keys)


class CPTLayout(BaseModel):
Expand Down Expand Up @@ -359,7 +358,7 @@ def _get_part_keys(cls, part_dict: dict[str, str | None], max_rows: int) -> tupl

return [key - min_pt for key in part_keys], max(p.x for p in part_keys) - min_pt.x

def generate(self, key_w: float, key_h: float, split_gap: float) -> list[PhysicalKey]:
def generate(self, key_w: float, key_h: float, split_gap: float) -> PhysicalLayout:
"""Generate a list of PhysicalKeys from given CPT specification."""
parts = [match.groupdict() for part in self.spec.split() if (match := self.part_pattern.match(part))]
max_rows = max(int(char) for part in parts for char in (part["a_l"] or part["a_r"]) if char.isdigit())
Expand All @@ -372,14 +371,16 @@ def generate(self, key_w: float, key_h: float, split_gap: float) -> list[Physica
x_offsets.append(x_offsets[-1] + max_x + 1)

sorted_keys = sorted(all_keys, key=lambda item: (int(item[0].y), item[1], int(item[0].x)))
return [
PhysicalKey(
Point((key.x + 0.5 + x_offsets[part_ind]) * key_w + part_ind * split_gap, (key.y + 0.5) * key_h),
key_w,
key_h,
)
for key, part_ind in sorted_keys
]
return PhysicalLayout(
keys=[
PhysicalKey(
Point((key.x + 0.5 + x_offsets[part_ind]) * key_w + part_ind * split_gap, (key.y + 0.5) * key_h),
key_w,
key_h,
)
for key, part_ind in sorted_keys
]
)


class QmkLayout(BaseModel):
Expand All @@ -398,20 +399,22 @@ class QmkKey(BaseModel):

layout: list[QmkKey]

def generate(self, key_size: float) -> list[PhysicalKey]:
def generate(self, key_size: float) -> PhysicalLayout:
"""Generate a sequence of PhysicalKeys from QmkKeys."""
min_pt = Point(min(k.x for k in self.layout), min(k.y for k in self.layout))
return [
PhysicalKey.from_qmk_spec(
scale=key_size,
pos=Point(k.x, k.y) - min_pt,
width=k.w,
height=k.h,
rotation=k.r,
rotation_pos=Point(k.x if k.rx is None else k.rx, k.y if k.ry is None else k.ry) - min_pt,
)
for k in self.layout
]
return PhysicalLayout(
keys=[
PhysicalKey.from_qmk_spec(
scale=key_size,
pos=Point(k.x, k.y) - min_pt,
width=k.w,
height=k.h,
rotation=k.r,
rotation_pos=Point(k.x if k.rx is None else k.rx, k.y if k.ry is None else k.ry) - min_pt,
)
for k in self.layout
]
)


def _map_qmk_keyboard(qmk_keyboard: str) -> str:
Expand Down

0 comments on commit f7aee90

Please sign in to comment.