cleaner coupling

This commit is contained in:
2020-04-04 15:35:17 +02:00
parent 01caa47fd1
commit a4bc0c8cf1
3 changed files with 98 additions and 43 deletions

View File

@@ -1,7 +1,11 @@
# -*- coding:utf-8 -*-
from .gui import App
from .gui import NoteViewer
from .data import Notes
app = App()
app.run()
# Load notes
notes = Notes("testdata")
# View them
viewer = NoteViewer(notes)
viewer.run()

View File

@@ -1,4 +1,6 @@
# -*- coding:utf-8 -*-
import random
from collections import namedtuple
def test_data():
return { "Henri" :
@@ -37,30 +39,63 @@ def test_data():
},
}
def extract_from_file(path):
""" Extract and yields notes from the file at path """
pass
NoteInfo = namedtuple("NoteInfo", ("person", "category", "date", "time", "author", "text"))
def extract_test():
for person in ["Henri", "Étienne", "Julia"]:
for category in ["Santé", "Comportement", "Quotidien", "Infos", "Activités"]:
for day in range(2, 18):
for time in ("Matin", "Soir", "Nuit"):
text = random.choice(("Tout va bien", "A l'air un peu triste aujourd'hui", "Bien mangé au repas"))
author = random.choice(("Éric", "Mélanie", "Thibault"))
date = f"{day} mars 2020"
yield NoteInfo(person, category, date, time, author, text)
class Notes(dict):
""" Store of notes grouped by subject and category """
def __init__(self, source):
self._categories = None
super().__init__([data for data in test_data().items()])
super().__init__()
self.categories = []
self.load(source)
def subjects(self):
def load(self, source):
if source is "testdata":
for note in extract_test():
self.insert(note.person, note.category, note.date, (note.time, note.text))
def insert(self, person, category, date, note):
""" Inserts a new note """
# Track existing categories
if not category in self.categories:
self.categories.append(category)
# Checks
if not person in self:
self[person] = { cat: {} for cat in self.categories }
if not category in self[person]:
self[person][category] = {}
# Insertion
if not date in self[person][category]:
self[person][category][date] = [note]
else:
self[person][category][date].append(note)
def persons(self):
""" Returns list of subjects """
return list(self.keys())
def categories(self):
""" Returns list of categories """
if not self._categories:
self._categories = ["Santé", "Comportement", "Quotidien", "Infos", "Activité"]
return self._categories
def get(self, subject_idx, category_idx, date_range=None):
def get(self, person_idx, category_idx, date_range=None):
""" Filter notes by subject, category and date """
subject = list(self.subjects())[subject_idx]
person = list(self.persons())[person_idx]
# TODO: deduplicate categories by using a tuple
category = list(self.categories())[category_idx]
notes = self[subject][category]
category = self.categories[category_idx]
notes = self[person][category]
if date_range is not None:
# TODO: filter by date
pass

View File

@@ -10,9 +10,7 @@ def new_frame_horiz(parent):
frame.pack(fill=tk.X, expand=True)
return frame
def render_notes(notes, text_area):
# Text
for date, notes in notes.items():
text_area.insert(tk.INSERT, f"{date}\n\n", "d")
for note in notes:
@@ -21,39 +19,51 @@ def render_notes(notes, text_area):
text_area.insert(tk.INSERT, "\n")
class NoteViewer(tk.Frame):
class App(tk.Frame):
__notes = None
def __init__(self, master=None):
def __init__(self, notes, master=None):
super().__init__(master)
self.pack(fill=tk.BOTH, expand=True)
self.__create_widgets()
self.notes = notes
def run(self):
self.notes = Notes(None)
self._create_widgets()
""" Launch the viewer """
self.mainloop()
def _set_subject(self):
pass
@property
def notes(self):
return self.__notes
def _set_category(self):
pass
@notes.setter
def notes(self, new_notes):
""" Replace loaded notes """
self.__notes = new_notes
# Reset widgets state
self.person_choice.configure(values=new_notes.persons())
self.person_choice.current(0)
self.category_choice.configure(values=new_notes.categories)
self.category_choice.current(0)
self.refresh_text(None)
def _set_date_range(self):
pass
def _refresh_text(self, event):
def refresh_text(self, event):
self.text.config(state=tk.NORMAL)
self.text.delete(1.0, tk.END)
render_notes( self.notes.get(self.subjectChoice.current(), self.categoryChoice.current())
, self.text)
try:
render_notes( self.notes.get(self.person_choice.current(), self.category_choice.current())
, self.text)
except IndexError:
self.text.insert(tk.INSERT, "Veuillez sélectionner une personne et une catégorie")
self.text.config(state=tk.DISABLED)
def _create_widgets(self):
def __create_widgets(self):
def combo_with_buttons(label, values):
""" Builds a combo with cycling buttons, and returns the combobox """
""" Builds a combo with cycling buttons, and returns the combobox.
"""
def cycle_choice(cbox, reversed=False):
def do_it():
def on_click():
idx = cbox.current()
max_idx = len(cbox["values"]) - 1
if reversed:
@@ -61,8 +71,8 @@ class App(tk.Frame):
else:
idx = idx + 1 if idx < max_idx else 0
cbox.current(idx)
self._refresh_text(None)
return do_it
self.refresh_text(None)
return on_click
# Build
frame = new_frame_horiz(self.header)
label = tk.Label(frame, text=label + " : ")
@@ -70,19 +80,26 @@ class App(tk.Frame):
cbox = ttk.Combobox(frame, values=values, state="readonly")
prev_button = tk.Button(frame, text="<", command=cycle_choice(cbox, reversed=True))
next_button = tk.Button(frame, text=">", command=cycle_choice(cbox))
# Pack
prev_button.pack(side=tk.LEFT)
cbox.pack(side=tk.LEFT, fill=tk.X, expand=True)
next_button.pack(side=tk.LEFT)
# Configure
cbox.current(0)
cbox.bind("<<ComboboxSelected>>", self._refresh_text)
cbox.bind("<<ComboboxSelected>>", self.refresh_text)
return cbox
# Subject and Category selection
self.header = tk.Frame(self)
self.header.pack(side=tk.TOP, fill=tk.X)
self.subjectChoice = combo_with_buttons("Résident", values=self.notes.subjects())
self.categoryChoice = combo_with_buttons("Catégorie", values=self.notes.categories())
try:
persons = self.notes.persons()
categories = self.notes.categories
except AttributeError: # Init case
persons = []
categories = []
self.person_choice = combo_with_buttons("Résident", values=persons)
self.category_choice = combo_with_buttons("Catégorie", values=categories)
# Text view
textView = tk.Frame(self)
textView.pack(fill=tk.BOTH, expand=True)
@@ -94,7 +111,6 @@ class App(tk.Frame):
self.text.pack(fill=tk.BOTH, expand=True)
scrollbar.config(command=self.text.yview)
self._refresh_text(None)