mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Support direct EvColumn adds to EvTable. Resolves #2762
This commit is contained in:
parent
7d8c6f2a26
commit
9438e5856a
4 changed files with 102 additions and 20 deletions
|
|
@ -217,6 +217,7 @@ Up requirements to Django 4.0+, Twisted 22+, Python 3.9 or 3.10
|
|||
(mainly for custom align/valign). `EvCells` now makes use of `utils.justify`.
|
||||
- `utils.justify` now supports `align="a"` (absolute alignments. This keeps
|
||||
the given left indent but crops/fills to the width. Used in EvCells.
|
||||
- `EvTable` now supports passing `EvColumn`s as a list directly, (`EvTable(table=[colA,colB])`)
|
||||
|
||||
## Evennia 0.9.5
|
||||
|
||||
|
|
|
|||
|
|
@ -471,9 +471,6 @@ class EvCell:
|
|||
else:
|
||||
self.height = self.raw_height
|
||||
|
||||
# prepare data
|
||||
# self.formatted = self._reformat()
|
||||
|
||||
def _crop(self, text, width):
|
||||
"""
|
||||
Apply cropping of text.
|
||||
|
|
@ -853,16 +850,19 @@ class EvCell:
|
|||
Get data, padded and aligned in the form of a list of lines.
|
||||
|
||||
"""
|
||||
self.formatted = self._reformat()
|
||||
if not self.formatted:
|
||||
self.formatted = self._reformat()
|
||||
return self.formatted
|
||||
|
||||
def __repr__(self):
|
||||
self.formatted = self._reformat()
|
||||
if not self.formatted:
|
||||
self.formatted = self._reformat()
|
||||
return str(ANSIString("<EvCel %s>" % self.formatted))
|
||||
|
||||
def __str__(self):
|
||||
"returns cell contents on string form"
|
||||
self.formatted = self._reformat()
|
||||
if not self.formatted:
|
||||
self.formatted = self._reformat()
|
||||
return str(ANSIString("\n").join(self.formatted))
|
||||
|
||||
|
||||
|
|
@ -1146,7 +1146,19 @@ class EvTable:
|
|||
self.options = kwargs
|
||||
|
||||
# use the temporary table to generate the table on the fly, as a list of EvColumns
|
||||
self.table = [EvColumn(*col, **kwargs) for col in table]
|
||||
self.table = []
|
||||
for col in table:
|
||||
if isinstance(col, EvColumn):
|
||||
self.add_column(col, **kwargs)
|
||||
elif isinstance(col, (list, tuple)):
|
||||
self.table.append(EvColumn(*col, **kwargs))
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"EvTable 'table' kwarg must be a list of EvColumns or a list-of-lists of"
|
||||
f" strings. Found {type(col)}."
|
||||
)
|
||||
|
||||
# self.table = [EvColumn(*col, **kwargs) for col in table]
|
||||
|
||||
# this is the actual working table
|
||||
self.worktable = None
|
||||
|
|
@ -1508,7 +1520,12 @@ class EvTable:
|
|||
options = dict(list(self.options.items()) + list(kwargs.items()))
|
||||
|
||||
xpos = kwargs.get("xpos", None)
|
||||
column = EvColumn(*args, **options)
|
||||
|
||||
if args and isinstance(args[0], EvColumn):
|
||||
column = args[0]
|
||||
column.reformat(**kwargs)
|
||||
else:
|
||||
column = EvColumn(*args, **options)
|
||||
wtable = self.ncols
|
||||
htable = self.nrows
|
||||
|
||||
|
|
@ -1546,7 +1563,6 @@ class EvTable:
|
|||
xpos = min(wtable - 1, max(0, int(xpos)))
|
||||
self.table.insert(xpos, column)
|
||||
self.ncols += 1
|
||||
# self._balance()
|
||||
|
||||
def add_row(self, *args, **kwargs):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -196,7 +196,8 @@ class TestEvTable(EvenniaTestCase):
|
|||
|
||||
def test_multiple_rows(self):
|
||||
"""
|
||||
adding a lot of rows with `.add_row`.
|
||||
Adding a lot of rows with `.add_row`.
|
||||
|
||||
"""
|
||||
table = evtable.EvTable("|yHeading1|n", "|B|[GHeading2|n", "Heading3")
|
||||
nlines = 12
|
||||
|
|
@ -222,3 +223,56 @@ class TestEvTable(EvenniaTestCase):
|
|||
expected = "\n".join(expected)
|
||||
|
||||
self._validate(expected, str(table))
|
||||
|
||||
def test_2762(self):
|
||||
"""
|
||||
Testing https://github.com/evennia/evennia/issues/2762
|
||||
|
||||
Extra spaces getting added to cell content
|
||||
|
||||
Also testing out adding EvColumns directly to the table kwarg.
|
||||
|
||||
"""
|
||||
# direct table add
|
||||
table = evtable.EvTable(table=[["another"]], fill_char=".", pad_char="#", width=8)
|
||||
|
||||
expected = """
|
||||
+------+
|
||||
|#anot#|
|
||||
|#her.#|
|
||||
+------+
|
||||
"""
|
||||
self._validate(expected, str(table))
|
||||
|
||||
# add with .add_column
|
||||
table = evtable.EvTable(fill_char=".", pad_char="#")
|
||||
table.add_column("another", width=8)
|
||||
|
||||
self._validate(expected, str(table))
|
||||
|
||||
# add by passing a column to constructor directly
|
||||
|
||||
colB = evtable.EvColumn("another", width=8)
|
||||
|
||||
table = evtable.EvTable(table=[colB], fill_char=".", pad_char="#")
|
||||
|
||||
self._validate(expected, str(table))
|
||||
|
||||
# more complex table
|
||||
|
||||
colA = evtable.EvColumn("this", "is", "a", "column") # no width
|
||||
colB = evtable.EvColumn("and", "another", "one", "here", width=8)
|
||||
|
||||
table = evtable.EvTable(table=[colA, colB], fill_char=".", pad_char="#")
|
||||
|
||||
expected = """
|
||||
+--------+-------+
|
||||
|#this..#|#and..#|
|
||||
|#is....#|#anoth#|
|
||||
|#......#|#er...#|
|
||||
|#a.....#|#one..#|
|
||||
|#column#|#here.#|
|
||||
+--------+-------+
|
||||
"""
|
||||
|
||||
self._validate(expected, str(table))
|
||||
|
|
|
|||
|
|
@ -2193,23 +2193,34 @@ def calledby(callerdepth=1):
|
|||
another function; it will print which function called it.
|
||||
|
||||
Args:
|
||||
callerdepth (int): Must be larger than 0. When > 1, it will
|
||||
print the caller of the caller etc.
|
||||
callerdepth (int or None): If None, show entire stack. If int, must be larger than 0.
|
||||
When > 1, it will print the sequence to that depth.
|
||||
|
||||
Returns:
|
||||
calledby (str): A debug string detailing which routine called
|
||||
us.
|
||||
calledby (str): A debug string detailing the code that called us.
|
||||
|
||||
"""
|
||||
import inspect
|
||||
|
||||
def _stack_display(frame):
|
||||
path = os.path.sep.join(frame[1].rsplit(os.path.sep, 2)[-2:])
|
||||
return (
|
||||
f"> called by '{frame[3]}': {path}:{frame[2]} >>>"
|
||||
f" {frame[4][0].strip() if frame[4] else ''}"
|
||||
)
|
||||
|
||||
stack = inspect.stack()
|
||||
# we must step one extra level back in stack since we don't want
|
||||
# to include the call of this function itself.
|
||||
callerdepth = min(max(2, callerdepth + 1), len(stack) - 1)
|
||||
frame = inspect.stack()[callerdepth]
|
||||
path = os.path.sep.join(frame[1].rsplit(os.path.sep, 2)[-2:])
|
||||
return "[called by '%s': %s:%s %s]" % (frame[3], path, frame[2], frame[4])
|
||||
|
||||
out = []
|
||||
if callerdepth is None:
|
||||
callerdepth = len(stack) - 1
|
||||
|
||||
# show range
|
||||
for idepth in range(1, max(1, callerdepth + 1)):
|
||||
# we must step one extra level back in stack since we don't want
|
||||
# to include the call of this function itself.
|
||||
out.append(_stack_display(stack[min(idepth + 1, len(stack) - 1)]))
|
||||
return "\n".join(out[::-1])
|
||||
|
||||
|
||||
def m_len(target):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue