End screen now works, much more pleasent
This commit is contained in:
parent
060de0df84
commit
1cdb570112
6 changed files with 90 additions and 22 deletions
|
@ -29,6 +29,9 @@ class Application:
|
|||
self.silent_exit = True
|
||||
if self.running():
|
||||
self.buffer.stats.signal_stop()
|
||||
except:
|
||||
if self.running():
|
||||
self.buffer.stats.signal_stop()
|
||||
|
||||
def summarize(self):
|
||||
if self.finished:
|
||||
|
|
|
@ -326,22 +326,50 @@ class TextBox(BufferDependentComponent):
|
|||
self.refresh()
|
||||
|
||||
|
||||
class StatsBox(BorderWithImprintedStats):
|
||||
class StatsBox(BorderedBox):
|
||||
"""
|
||||
Displays stats
|
||||
"""
|
||||
|
||||
def __init__(self, config):
|
||||
super().__init__(config)
|
||||
self.wpm_color = config.get("wpm_graph_color")
|
||||
self.raw_wpm_color = config.get("raw_wpm_graph_color")
|
||||
self.errors_color = config.get("errors_graph_color")
|
||||
self.logo = config.get("logo")
|
||||
self.logo_color = config.get("logo_color")
|
||||
self.resume_text = config.get("resume_text")
|
||||
self.resume_text_color = config.get("resume_text_color")
|
||||
self.template = config.get("end_template")
|
||||
self.color = config.get("end_color")
|
||||
|
||||
def paint_logo(self):
|
||||
if len(self.logo) <= self.width:
|
||||
self.paint_text(
|
||||
-1, (self.width - len(self.logo)) // 2, self.logo, self.logo_color
|
||||
)
|
||||
|
||||
def paint_resume_text(self):
|
||||
if len(self.resume_text) <= self.width:
|
||||
self.paint_text(
|
||||
self.height,
|
||||
(self.width - len(self.resume_text)) // 2,
|
||||
self.resume_text,
|
||||
self.resume_text_color,
|
||||
)
|
||||
|
||||
def paint_stats(self, application):
|
||||
record = application.buffer.stats.produce_record(for_csv=True)
|
||||
lines = [l.format_map(record) for l in self.template]
|
||||
max_l = max((len(l) for l in lines))
|
||||
|
||||
if max_l > self.width:
|
||||
return
|
||||
|
||||
for i, text in enumerate(lines):
|
||||
self.paint_text(i, 1, text, self.color)
|
||||
|
||||
def paint(self, screen, application):
|
||||
self.maxy, self.maxx = screen.getmaxyx()
|
||||
self.init(screen, application)
|
||||
self.paint_stats()
|
||||
self.paint_text(
|
||||
self.height // 2, self.width // 2 - 5, "FASTTYPER", self.errors_color
|
||||
)
|
||||
self.paint_logo()
|
||||
self.paint_resume_text()
|
||||
self.paint_stats(application)
|
||||
self.refresh()
|
||||
|
|
|
@ -10,9 +10,16 @@ class Config:
|
|||
"top_margin_percentage": 40,
|
||||
"left_margin_percentage": 35,
|
||||
"lines_on_screen": 3,
|
||||
"wpm_graph_color": 3,
|
||||
"raw_wpm_graph_color": 9,
|
||||
"errors_graph_color": 2,
|
||||
"logo": "~FastTyper~",
|
||||
"logo_color": 8,
|
||||
"resume_text": "press any key to continue, <Ctrl>C to exit",
|
||||
"resume_text_color": 9,
|
||||
"end_template": (
|
||||
"wpm: {wpm:.1f}/{peak_wpm:.1f} raw: {raw_wpm:.1f}/{peak_raw_wpm:.1f}",
|
||||
"acc: {accuracy:.1f} chars: {correct_chars}/{total_chars} words: {correct_words}/{total_words}",
|
||||
"time: {total_seconds:.1f}s",
|
||||
),
|
||||
"end_color": 9,
|
||||
}
|
||||
|
||||
def __init__(self, configmap):
|
||||
|
|
|
@ -60,7 +60,7 @@ class Stats:
|
|||
def total_seconds(self):
|
||||
stop_dtime = self.stop_dtime or datetime.now()
|
||||
start_dtime = self.start_dtime or datetime.now()
|
||||
return (stop_dtime - start_dtime).total_seconds() or 1
|
||||
return max(((stop_dtime - start_dtime).total_seconds(), 1))
|
||||
|
||||
@property
|
||||
def total_minutes(self):
|
||||
|
@ -90,16 +90,30 @@ class Stats:
|
|||
def raw_cpm(self):
|
||||
return self.total_chars / self.total_minutes
|
||||
|
||||
@property
|
||||
def peak_raw_cpm(self):
|
||||
return max([s["raw_cpm"] for s in self.snaps] + [0.0])
|
||||
|
||||
@property
|
||||
def peak_cpm(self):
|
||||
return max([s["raw_cpm"] for s in self.snaps] + [0.0])
|
||||
|
||||
@property
|
||||
def peak_raw_wpm(self):
|
||||
return self.peak_raw_cpm / 5
|
||||
|
||||
@property
|
||||
def peak_wpm(self):
|
||||
return self.peak_cpm / 5
|
||||
|
||||
@property
|
||||
def accuracy(self):
|
||||
if self.total_chars:
|
||||
return self.correct_chars / self.total_chars * 100
|
||||
return 100
|
||||
|
||||
def produce_record(self):
|
||||
return {
|
||||
"start_dtime": self.start_dtime.isoformat() if self.start_dtime else None,
|
||||
"stop_dtime": self.stop_dtime.isoformat() if self.stop_dtime else None,
|
||||
def produce_record(self, for_csv=False):
|
||||
result = {
|
||||
"total_seconds": self.total_seconds,
|
||||
"total_minutes": self.total_minutes,
|
||||
"total_chars": self.total_chars,
|
||||
|
@ -113,10 +127,26 @@ class Stats:
|
|||
"raw_wpm": self.raw_wpm,
|
||||
"raw_cpm": self.raw_cpm,
|
||||
"accuracy": self.accuracy,
|
||||
"mode": self.runtime_config.mode,
|
||||
"language": self.runtime_config.language,
|
||||
"words": self.runtime_config.words,
|
||||
}
|
||||
if for_csv:
|
||||
result.update(
|
||||
{
|
||||
"peak_cpm": self.peak_cpm,
|
||||
"peak_raw_cpm": self.peak_raw_cpm,
|
||||
"peak_wpm": self.peak_wpm,
|
||||
"peak_raw_wpm": self.peak_raw_wpm,
|
||||
"start_dtime": self.start_dtime.isoformat()
|
||||
if self.start_dtime
|
||||
else None,
|
||||
"stop_dtime": self.stop_dtime.isoformat()
|
||||
if self.stop_dtime
|
||||
else None,
|
||||
"mode": self.runtime_config.mode,
|
||||
"language": self.runtime_config.language,
|
||||
"words": self.runtime_config.words,
|
||||
}
|
||||
)
|
||||
return result
|
||||
|
||||
def export_to_datafile(self, datafile):
|
||||
if datafile is None:
|
||||
|
@ -128,7 +158,7 @@ class Stats:
|
|||
pathlib.Path(data_dir).mkdir(exist_ok=True, parents=True)
|
||||
exists = os.path.isfile(datafile)
|
||||
|
||||
record = self.produce_record()
|
||||
record = self.produce_record(for_csv=True)
|
||||
|
||||
if not exists:
|
||||
with open(datafile, "w") as f:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[bumpversion]
|
||||
current_version = 2.0.6
|
||||
current_version = 2.1.0
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
||||
|
|
2
setup.py
2
setup.py
|
@ -9,7 +9,7 @@ with open("requirements.txt", "r", encoding="utf-8") as fh:
|
|||
|
||||
setup(
|
||||
name="fasttyper",
|
||||
version="2.0.6",
|
||||
version="2.1.0",
|
||||
author="Piotr Domanski",
|
||||
author_email="pi.domanski@gmail.com",
|
||||
description="Minimalistic typing exercise",
|
||||
|
|
Loading…
Reference in a new issue