Added: Layout Switcher

This commit is contained in:
DerGrumpf 2025-01-05 01:01:39 +01:00
parent 59e00cb812
commit 7635df42b4
14 changed files with 582 additions and 250 deletions

36
class_editor.py Normal file
View File

@ -0,0 +1,36 @@
import imgui
from model import *
class ClassEditor:
def __init__(self):
super().__init__()
self.add_name = str()
self.select = 0
def __call__(self):
classes = Class.select()
with imgui.begin("Class Editor", False, imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
imgui.text("Add Class")
_, self.add_name = imgui.input_text(" ", self.add_name)
if imgui.button("Add"):
if self.add_name:
Class.create(name=self.add_name)
self.add_name = str()
imgui.separator()
if not classes:
imgui.text("No Dataset could be queried")
return
for n, c in enumerate(classes, start=1):
display = f"{n}. {c.name}"
opened, _ = imgui.selectable(display, self.select == n-1)
if opened:
self.select = n-1
return classes[self.select]

15
datatypes.py Normal file
View File

@ -0,0 +1,15 @@
from PIL import ImageColor
from enum import IntEnum
# Global Color Pallet
COLOR_BACKGROUND = tuple([e/255 for e in ImageColor.getcolor("#29132E","RGBA")])
COLOR_1 = tuple([e/255 for e in ImageColor.getcolor("#321450","RGBA")])
COLOR_2 = tuple([e/255 for e in ImageColor.getcolor("#860029","RGBA")])
COLOR_3 = tuple([e/255 for e in ImageColor.getcolor("#DE004E","RGBA")])
COLOR_TEXT = tuple([e/255 for e in ImageColor.getcolor("#F887FF","RGBA")])
COLOR_TEXT_PASSED = tuple([e/255 for e in ImageColor.getcolor("#1AFE49","RGBA")])
COLOR_TEXT_FAILED = tuple([e/255 for e in ImageColor.getcolor("#FF124F","RGBA")])
class LayoutOptions(IntEnum):
EDITOR = 1
GRAPHER = 2

89
gui.py Normal file
View File

@ -0,0 +1,89 @@
import imgui
import glfw
import OpenGL.GL as gl
from imgui.integrations.glfw import GlfwRenderer
from datatypes import *
from view import View
def impl_glfw_init(window_name="Grapher Tool", width=1280, height=720):
if not glfw.init():
print("Could not initialize OpenGL context")
exit(1)
# OS X supports only forward-compatible core profiles from 3.2
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)
# Create a windowed mode window and its OpenGL context
window = glfw.create_window(int(width), int(height), window_name, None, None)
glfw.make_context_current(window)
if not window:
glfw.terminate()
print("Could not initialize Window")
exit(1)
return window
class GUI(object):
def __init__(self):
super().__init__()
# Window States
self.window = impl_glfw_init()
gl.glClearColor(*COLOR_BACKGROUND)
imgui.create_context()
self.impl = GlfwRenderer(self.window)
self.io = imgui.get_io()
# Global GUI Setting
win_w, win_h = glfw.get_window_size(self.window)
fb_w, fb_h = glfw.get_framebuffer_size(self.window)
font_scaling_factor = max(float(fb_w) / win_w, float(fb_h) / win_h)
font_size_in_pixels = 30
self.io.fonts.add_font_from_file_ttf("assets/MPLUSRounded1c-Regular.ttf", font_size_in_pixels * font_scaling_factor)
self.io.font_global_scale /= font_scaling_factor
self.view = View()
self.loop()
def header(self):
imgui.set_next_window_size(io.display_size.x, io.display_size.y*0.03)
imgui.set_next_window_position(0, io.display_size.y*0.02)
with imgui.begin("HEADER", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE | imgui.WINDOW_NO_TITLE_BAR):
imgui.set_window_font_scale(1.3)
text = "Student Analyzer"
ww = imgui.get_window_size().x
tw = imgui.calc_text_size(text).x
imgui.set_cursor_pos_x((ww - tw) * 0.5)
imgui.text("Student Analyzer")
def loop(self):
while not glfw.window_should_close(self.window):
glfw.poll_events()
self.impl.process_inputs()
imgui.new_frame()
self.view()
#imgui.show_test_window()
imgui.render()
gl.glClearColor(*COLOR_BACKGROUND)
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
self.impl.render(imgui.get_draw_data())
glfw.swap_buffers(self.window)
self.impl.shutdown()
glfw.terminate()
if __name__ == "__main__":
gui = GUI()

45
lecture_editor.py Normal file
View File

@ -0,0 +1,45 @@
import imgui
from datatypes import *
from model import *
class LectureEditor:
def __init__(self):
super().__init__()
self.select = 0
self.add_lecture_text = str()
self.add_lecture_points = 0
def __call__(self, clas: Class):
id = clas.id if clas else None
lectures = Lecture.select().where(Lecture.class_id == id) if id else None
with imgui.begin("Lecture Editor", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
imgui.text("Add Lecture")
_, self.add_lecture_text = imgui.input_text("Title", self.add_lecture_text)
if self.add_lecture_points < 0:
self.add_lecture_points = 0
_, self.add_lecture_points = imgui.input_int("Points", self.add_lecture_points)
if imgui.button("Add"):
Lecture.create(
title=self.add_lecture_text,
points=self.add_lecture_points,
class_id=id
)
imgui.separator()
if not lectures:
imgui.text("No Lectures could be queried")
return
for n, lecture in enumerate(lectures, start=1):
display = f"{n}. {lecture.title}"
opened, _ = imgui.selectable(display, self.select == n-1)
if opened:
self.select = n-1
return lectures[self.select]

250
main.py
View File

@ -1,24 +1,6 @@
import imgui
import glfw
import OpenGL.GL as gl
from imgui.integrations.glfw import GlfwRenderer
from PIL import ImageColor
from dataclasses import dataclass
import numpy
@dataclass
class Lecture:
name: str
points: float
max_points: int
@dataclass
class Student:
name: str
jupyter_id: str
project: str
lectures: list
phil = Student(
"Phil Keier", "772fb04b24caa68fd38a05ec2a22e62b", "Geomapping",
[Lecture("1. Tutorial 1", 28.5, 31), Lecture("2. Tutorial 2", 4.5, 15), Lecture("3. Extended Application", 18, 18)]
@ -33,239 +15,7 @@ kathi = Student(
)
students = [phil, nova, kathi]
# Global Color Pallet
COLOR_BACKGROUND = tuple([e/255 for e in ImageColor.getcolor("#29132E","RGBA")])
COLOR_1 = tuple([e/255 for e in ImageColor.getcolor("#321450","RGBA")])
COLOR_2 = tuple([e/255 for e in ImageColor.getcolor("#860029","RGBA")])
COLOR_3 = tuple([e/255 for e in ImageColor.getcolor("#DE004E","RGBA")])
COLOR_TEXT = tuple([e/255 for e in ImageColor.getcolor("#F887FF","RGBA")])
COLOR_TEXT_PASSED = tuple([e/255 for e in ImageColor.getcolor("#1AFE49","RGBA")])
COLOR_TEXT_FAILED = tuple([e/255 for e in ImageColor.getcolor("#FF124F","RGBA")])
def impl_glfw_init(window_name="Grapher Tool", width=1280, height=720):
if not glfw.init():
print("Could not initialize OpenGL context")
exit(1)
# OS X supports only forward-compatible core profiles from 3.2
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)
# Create a windowed mode window and its OpenGL context
window = glfw.create_window(int(width), int(height), window_name, None, None)
glfw.make_context_current(window)
if not window:
glfw.terminate()
print("Could not initialize Window")
exit(1)
return window
class GUI(object):
def __init__(self):
super().__init__()
self.backgroundColor = COLOR_BACKGROUND
self.window = impl_glfw_init()
gl.glClearColor(*self.backgroundColor)
imgui.create_context()
self.impl = GlfwRenderer(self.window)
# App states
self.select_student: int = 0
self.select_lecture: int = 0
self.lectures: list = list()
self.add_lecture_text = str()
self.add_lecture_points = 0
self.edit_lecture_title = str()
self.edit_lecture_points = 0
# Global GUI Setting
win_w, win_h = glfw.get_window_size(self.window)
fb_w, fb_h = glfw.get_framebuffer_size(self.window)
font_scaling_factor = max(float(fb_w) / win_w, float(fb_h) / win_h)
font_size_in_pixels = 30
io = imgui.get_io()
io.fonts.add_font_from_file_ttf("assets/MPLUSRounded1c-Regular.ttf", font_size_in_pixels * font_scaling_factor)
io.font_global_scale /= font_scaling_factor
self.loop()
def student_info(self, student: Student):
# Window Position and Sizing
io = imgui.get_io()
imgui.set_next_window_size(io.display_size.x*0.3, io.display_size.y*0.4)
imgui.set_next_window_position(io.display_size.x*0.7, io.display_size.y*0.05)
# Student accumulated Info
overall_points = sum([lecture.points for lecture in student.lectures])
if overall_points.is_integer():
overall_points = int(overall_points)
overall_max = sum([lecture.max_points for lecture in student.lectures])
with imgui.begin("Student Info", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
if not student:
imgui.text("No Student selected")
return
s = f"{overall_points}/{overall_max} | {round(overall_points/overall_max*100, 1)}%"
imgui.text_colored(student.name, *COLOR_TEXT)
w, h = imgui.get_window_size()
imgui.progress_bar(overall_points/overall_max, (w*0.5, h*0.1), s)
imgui.text("Jupyter ID:")
imgui.text_colored(student.jupyter_id.rjust(4+len(student.jupyter_id), " "), *COLOR_TEXT)
imgui.separator()
imgui.text("Project:")
imgui.text_colored(student.project.rjust(4+len(student.project), " "), *COLOR_TEXT)
imgui.text("Lectures:")
for lecture in student.lectures:
COLOR = COLOR_TEXT_PASSED if lecture.points >= lecture.max_points/3 else COLOR_TEXT_FAILED
s = f"{lecture.name}: {lecture.points}/{lecture.max_points}"
imgui.text_colored(s.rjust(4+len(s), " "), *COLOR)
def table(self, students: list):
# Window Position and Sizing
io = imgui.get_io()
imgui.set_next_window_size(io.display_size.x*0.15, io.display_size.y*0.95)
imgui.set_next_window_position(0, io.display_size.y*0.05)
with imgui.begin("Student Table", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
if not students:
imgui.text("No Dataset selected")
return
for n, student in enumerate(students):
opened, _ = imgui.selectable(student.name, self.select_student == n)
if opened:
self.select_student = n
def student_graph(self, student: Student):
# Window Position and Sizing
io = imgui.get_io()
imgui.set_next_window_size(io.display_size.x*0.55, io.display_size.y*0.4)
imgui.set_next_window_position(io.display_size.x*0.15, io.display_size.y*0.05)
# Setup Data
data = numpy.array([float(lecture.points) / float(lecture.max_points) * 100 for lecture in student.lectures], dtype=numpy.float32)
with imgui.begin("Student Graph", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
if not students:
imgui.text("No Dataset selected")
return
imgui.plot_histogram(
"##Data", data, overlay_text="Performance per Lecture (in %)",
scale_min=0.0, scale_max=100,
graph_size=imgui.get_content_region_available()
)
def header(self):
# Window Position and Sizing
io = imgui.get_io()
imgui.set_next_window_size(io.display_size.x, io.display_size.y*0.03)
imgui.set_next_window_position(0, io.display_size.y*0.02)
with imgui.begin("HEADER", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE | imgui.WINDOW_NO_TITLE_BAR):
imgui.set_window_font_scale(1.3)
text = "Student Analyzer"
ww = imgui.get_window_size().x
tw = imgui.calc_text_size(text).x
imgui.set_cursor_pos_x((ww - tw) * 0.5)
imgui.text("Student Analyzer")
def editor(self):
# Window Position and Sizing
io = imgui.get_io()
imgui.set_next_window_size(io.display_size.x*0.3, io.display_size.y*0.3)
imgui.set_next_window_position(io.display_size.x*0.7, io.display_size.y*0.45)
lecture = None
with imgui.begin("Lecture Editor", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
with imgui.begin_group():
if not self.lectures:
imgui.text("No Lecture Added")
else:
for n, lecture in enumerate(self.lectures):
opened, _ = imgui.selectable(lecture.name, self.select_lecture == n, width=imgui.get_window_size().x*0.3)
if opened:
self.select_lecture = n
lecture = self.lectures[self.select_lecture]
self.edit_lecture_title = lecture.name
self.edit_lecture_points = lecture.max_points
imgui.same_line(spacing=int(imgui.get_window_size().x * 0.05))
with imgui.begin_group():
imgui.push_item_width(imgui.get_window_size().x * 0.2)
imgui.text("Add Lecture")
_, self.add_lecture_text = imgui.input_text(" ", self.add_lecture_text)
_, self.add_lecture_points = imgui.input_int("", self.add_lecture_points)
if self.add_lecture_points < 0:
self.add_lecture_points = 0
clicked = imgui.button("Confirm")
if clicked:
self.lectures.append(Lecture(self.add_lecture_text, 0, self.add_lecture_points))
self.add_lecture_points = 0
self.add_lecture_text = str()
imgui.pop_item_width()
if lecture:
imgui.same_line(spacing=int(imgui.get_window_size().x * 0.05))
with imgui.begin_group():
_, self.edit_lecture_title = imgui.input_text(" ", self.edit_lecture_title)
_, self.edit_lecture_points = imgui.input_int("", self.edit_lecture_points)
if self.edit_lecture_points < 0:
self.edit_lecture_points = 0
def main_menu(self):
with imgui.begin_main_menu_bar() as main_menu_bar:
if main_menu_bar:
with imgui.begin_menu("File", True) as file_menu:
if file_menu.opened:
imgui.menu_item("New", " ", False, True)
imgui.menu_item("Open", " ", False, True)
imgui.menu_item("Save", " ", False, True)
imgui.menu_item("Save as", " ", False, True)
def loop(self):
while not glfw.window_should_close(self.window):
glfw.poll_events()
self.impl.process_inputs()
imgui.new_frame()
self.main_menu()
self.header()
self.table(students)
self.student_info(students[self.select_student])
self.student_graph(students[self.select_student])
self.editor()
#imgui.show_test_window()
imgui.render()
gl.glClearColor(*self.backgroundColor)
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
self.impl.render(imgui.get_draw_data())
glfw.swap_buffers(self.window)
self.impl.shutdown()
glfw.terminate()
if __name__ == "__main__":
gui = GUI()

26
main_menu.py Normal file
View File

@ -0,0 +1,26 @@
import imgui
from datatypes import *
class MainMenu:
def __init__(self):
super().__init__()
def __call__(self):
with imgui.begin_main_menu_bar() as main_menu_bar:
if main_menu_bar:
with imgui.begin_menu("File", True) as file_menu:
if file_menu.opened:
imgui.menu_item("New", " ", False, True)
imgui.menu_item("Open", " ", False, True)
imgui.menu_item("Save", " ", False, True)
imgui.menu_item("Save as", " ", False, True)
with imgui.begin_menu("View", True) as view_menu:
if view_menu.opened:
with imgui.begin_menu("Change Layout", True) as open_layout_menu:
if open_layout_menu.opened:
layout_options = list(LayoutOptions)
for n, l in enumerate(layout_options):
clicked, _ = imgui.menu_item(l.name.title(), None, False, True)
if clicked:
return l

61
model.py Normal file
View File

@ -0,0 +1,61 @@
from peewee import *
from datetime import datetime
db = SqliteDatabase('test.db')
class BaseModel(Model):
class Meta:
database = db
class Class(BaseModel):
name = CharField()
created_at = DateTimeField(default=datetime.now)
class Student(BaseModel):
prename = CharField()
surname = CharField()
sex = CharField()
class_id = ForeignKeyField(Class, backref='class')
created_at = DateTimeField(default=datetime.now)
class Lecture(BaseModel):
title = CharField()
points = IntegerField()
class_id = ForeignKeyField(Class, backref='class')
created_at = DateTimeField(default=datetime.now)
class Submission(BaseModel):
student_id = ForeignKeyField(Student, backref='student')
lecture_id = ForeignKeyField(Lecture, backref='lecture')
points = FloatField()
created_at = DateTimeField(default=datetime.now)
db.connect()
db.create_tables([Class, Student, Lecture, Submission])
if __name__ == "__main__":
import random
# Generate Test Data
class1 = Class.create(name="WiSe 22/23")
class2 = Class.create(name="WiSe 23/24")
class3 = Class.create(name="WiSe 24/25")
phil = Student.create(prename="Phil", surname="Keier", sex="Male", class_id=class1.id)
calvin = Student.create(prename="Calvin", surname="Brandt", sex="Male", class_id=class2.id)
nova = Student.create(prename="Nova", surname="Eib", sex="Female", class_id=class1.id)
kathi = Student.create(prename="Katharina", surname="Walz", sex="Female", class_id=class3.id)
victoria = Student.create(prename="Victoria", surname="Möller", sex="Female", class_id=class3.id)
lec1 = Lecture.create(title="Tutorial 1", points=30, class_id=class1.id)
lec2 = Lecture.create(title="Tutorial 1", points=30, class_id=class3.id)
lec3 = Lecture.create(title="Tutorial 2", points=20, class_id=class1.id)
lec4 = Lecture.create(title="Tutorial 2", points=20, class_id=class2.id)
lec5 = Lecture.create(title="Extended Applications", points=44, class_id=class1.id)
sub1_phil = Submission.create(student_id=phil.id, lecture_id=lec1.id, points=random.randint(0, lec1.points))
sub2_phil = Submission.create(student_id=phil.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub3_phil = Submission.create(student_id=phil.id, lecture_id=lec5.id, points=random.randint(0, lec5.points))
sub1_nova = Submission.create(student_id=nova.id, lecture_id=lec1.id, points=random.randint(0, lec1.points))
sub2_nova = Submission.create(student_id=nova.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub1_kathi = Submission.create(student_id=kathi.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub1_vici = Submission.create(student_id=victoria.id, lecture_id=lec2.id, points=random.randint(0, lec2.points))

42
student_editor.py Normal file
View File

@ -0,0 +1,42 @@
import imgui
from model import *
class StudentEditor:
def __init__(self):
super().__init__()
self.prename = str()
self.surname = str()
self.sex = True
self.current = 0
def __call__(self):
with imgui.begin("Student Editor", False, imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
imgui.text("Add Student")
_, self.prename = imgui.input_text("First Name", self.prename)
_, self.surname = imgui.input_text("Last Name", self.surname)
with imgui.begin_group():
if imgui.radio_button("Male", self.sex):
self.sex = True
imgui.same_line()
if imgui.radio_button("Female", not self.sex):
self.sex = False
classes = Class.select()
if classes:
_, self.current = imgui.combo("Classes", self.current, [c.name for c in classes])
if imgui.button("Confirm") and classes:
Student.create(
prename=self.prename,
surname=self.surname,
sex='Male' if self.sex else 'Female',
class_id = classes[self.current]
)
self.prename = str()
self.surname = str()

27
student_graph.py Normal file
View File

@ -0,0 +1,27 @@
import imgui
import numpy as np
import random
from model import *
class StudentGraph:
def __init__(self):
super().__init__()
def __call__(self):
# Setup Data
submissions = Submission.select().where(Submission.student_id == 1)
data = np.array([submission.points/Lecture.get_by_id(submission.lecture_id).points*100 for submission in submissions], dtype=np.float32)
with imgui.begin("Student Graph", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
w, h = imgui.get_content_region_available()
imgui.plot_histogram(
"##Data", data, overlay_text="Performance per Lecture (in %)",
scale_min=0.0, scale_max=100,
graph_size=(w, h*0.9)
)
imgui.button("Text")

60
student_info.py Normal file
View File

@ -0,0 +1,60 @@
import imgui
from datatypes import *
from model import *
class StudentInfo:
def __init__(self):
super().__init__()
def __call__(self, student: Student):
submissions = Submission.select().where(Submission.student_id == student.id) if student else None
with imgui.begin("Student Info", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
if not student:
imgui.text("No Student selected")
return
w, h = imgui.get_window_size()
imgui.text_colored(f"{student.prename} {student.surname}", *COLOR_TEXT)
content = Class.get_by_id(student.class_id).name
text_size = imgui.calc_text_size(content)
imgui.same_line(position=w-1.5*text_size.x)
imgui.text(content)
if submissions:
overall_points = sum([s.points for s in submissions])
if overall_points.is_integer():
overall_points = int(overall_points)
overall_max = sum([lectures.points for lectures in [Lecture.get_by_id(s.lecture_id) for s in submissions]])
percentile = overall_points / overall_max
imgui.progress_bar(percentile, (w*0.5, h*0.05), f"{overall_points}/{overall_max} {percentile:.1%}")
content = "Delete"
if submissions:
text_size = imgui.calc_text_size(content)
imgui.same_line(position=w-2*text_size.x)
if imgui.button(content):
# Delete all Submissions related to that Student
#for submission in submissions:
# submission.delete().execute()
# Delete Student
#student.delete().execute()
return
imgui.separator()
if not submissions:
imgui.text("No Submission for this Student")
for n, submission in enumerate(submissions, start=1):
lecture = Lecture.get_by_id(submission.lecture_id)
points = submission.points
if points.is_integer():
points = int(points)
display = f"{n}. {lecture.title} {points}/{lecture.points}"
COLOR = COLOR_TEXT_PASSED if points > lecture.points*0.3 else COLOR_TEXT_FAILED
imgui.text_colored(display, *COLOR)

28
student_list.py Normal file
View File

@ -0,0 +1,28 @@
import imgui
from model import *
class StudentList:
def __init__(self):
super().__init__()
self.select: int = 0
def __call__(self, clas: Class):
id = clas.id if clas else None
students = Student.select().where(Student.class_id == id) if id else None
with imgui.begin("Student Table", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
if not students:
imgui.text("No Dataset could be queried")
return
for n, student in enumerate(students, start=1):
display = f"{n}. {student.prename} {student.surname}"
opened, _ = imgui.selectable(display, self.select == n-1)
if opened:
self.select = n-1
return students[self.select]

67
submission_editor.py Normal file
View File

@ -0,0 +1,67 @@
import imgui
from model import *
class SubmissionEditor:
def __init__(self):
super().__init__()
self.current_lecture = 0
self.current_student = 0
self.points = 0
def __call__(self, clas: Class):
id = clas.id if clas else None
lectures = Lecture.select().where(Lecture.class_id == id) if id else None
students = Student.select().where(Student.class_id == id) if id else None
with imgui.begin("Submission Editor", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
imgui.text("Add Submission")
if not lectures:
imgui.text("No Lectures queried")
return
if not students:
imgui.text("No Students queried")
return
_, self.current_lecture = imgui.combo("Lecture", self.current_lecture, [f"{l.title} ({l.points})" for l in lectures])
_, self.current_student = imgui.combo("Student", self.current_student, [f"{s.prename} {s.surname}" for s in students])
if self.points < 0:
self.points = 0
max = lectures[self.current_lecture].points
if self.points > max:
self.points = max
_, self.points = imgui.input_float("Points", self.points, format='%.1f', step=0.5, step_fast=1.0)
if imgui.button("Add"):
if not Submission.select().where(
Submission.student_id == students[self.current_student].id and
Submission.lecture_id == lectures[self.current_lecture].id
):
Submission.create(
student_id=students[self.current_student].id,
lecture_id=lectures[self.current_lecture].id,
points=self.points
)
imgui.same_line()
if imgui.button("Update"):
submission = Submission.select().where(
Submission.student_id == students[self.current_student].id and
Submission.lecture_id == lectures[self.current_lecture].id
).get()
submission.points = self.points
submission.save()
imgui.same_line()
if imgui.button("Delete"):
Submission.delete().where(
Submission.student_id == students[self.current_student].id and
Submission.lecture_id == lectures[self.current_lecture].id
).execute()

BIN
test.db Normal file

Binary file not shown.

86
view.py Normal file
View File

@ -0,0 +1,86 @@
import imgui
from datatypes import *
from main_menu import MainMenu
from student_editor import StudentEditor
from student_list import StudentList
from student_info import StudentInfo
from class_editor import ClassEditor
from lecture_editor import LectureEditor
from submission_editor import SubmissionEditor
from student_graph import StudentGraph
def set_layout(size: tuple, pos: tuple) -> None:
io = imgui.get_io()
imgui.set_next_window_size(
io.display_size.x*size[0],
io.display_size.y*size[1]
)
imgui.set_next_window_position(
io.display_size.x*pos[0],
io.display_size.y*pos[1]
)
class GrapherLayout:
def __init__(self):
super().__init__()
self.student_graph = StudentGraph()
def __call__(self):
set_layout((0.7, 0.4), (0.1, 0.1))
self.student_graph()
class EditorLayout:
def __init__(self):
super().__init__()
self.io = imgui.get_io()
self.student_editor = StudentEditor()
self.student_list = StudentList()
self.student_info = StudentInfo()
self.class_editor = ClassEditor()
self.lecture_editor = LectureEditor()
self.submission_editor = SubmissionEditor()
def __call__(self):
set_layout((0.3, 0.3), (0.7, 0.4))
clas = self.class_editor()
set_layout((0.5, 0.3), (0.2, 0.4))
self.student_editor()
set_layout((0.2, 0.98), (0, 0.02))
student = self.student_list(clas)
set_layout((0.3, 0.38), (0.7, 0.02))
self.student_info(student)
set_layout((0.5, 0.3), (0.2, 0.7))
self.lecture_editor(clas)
set_layout((0.5, 0.3), (0.2, 0.1))
self.submission_editor(clas)
class View:
def __init__(self):
super().__init__()
self.io = imgui.get_io()
self.current = LayoutOptions.GRAPHER
self.main_menu = MainMenu()
self.editor = EditorLayout()
self.grapher = GrapherLayout()
def __call__(self):
option = self.main_menu()
if option:
self.current = option
if self.current == LayoutOptions.EDITOR:
self.editor()
if self.current == LayoutOptions.GRAPHER:
self.grapher()