Files
endorphin-tessera-gui/examples/campus-lms.endor
codex-bot e54264f23b
Verify Tessera GUI / verify (push) Failing after 1m32s
example: add multi-page Endor campus learning environment
2026-10-25 00:13:22 +08:00

269 lines
14 KiB
Plaintext

// Endor Campus — a multi-page learning environment inspired by Canvas LMS.
// Fictional student/course data. Paste the complete source into Console and Enter.
// All seven tabs are ordinary managed Pages. There is no server or Canvas login.
class CampusPanel: Column {
function paint(self: CampusPanel, mount: Mount, geometry: Bounds): DisplayList {
fill = PaintCommand()
fill.kind = "roundedRect"
fill.x = geometry.x
fill.y = geometry.y
fill.width = geometry.width
fill.height = geometry.height
fill.radius = 10
fill.color = "#FFFFFF"
return DisplayList(ObjectList(fill))
}
}
class CampusCell: Column {
width: Number
function measure(self: CampusCell, mount: Mount, constraints: Constraints): MeasureResult {
result = Column.measure(self, mount, constraints)
result.width = self.width
return result
}
}
class CampusSidebar: Column {
function measure(self: CampusSidebar, mount: Mount, constraints: Constraints): MeasureResult {
return MeasureResult(168, 620)
}
function paint(self: CampusSidebar, mount: Mount, geometry: Bounds): DisplayList {
fill = PaintCommand()
fill.kind = "roundedRect"
fill.x = geometry.x
fill.y = geometry.y
fill.width = geometry.width
fill.height = geometry.height
fill.radius = 10
fill.color = "#852B38"
return DisplayList(ObjectList(fill))
}
}
class CampusNav: Button {
background: String
function measure(self: CampusNav, mount: Mount, constraints: Constraints): MeasureResult {
return MeasureResult(144, 40)
}
function paint(self: CampusNav, mount: Mount, geometry: Bounds): DisplayList {
fill = Button.paint(self, mount, geometry).commands.at(0)
fill.color = self.background
fill.radius = 7
return DisplayList(ObjectList(fill))
}
}
class CampusCourse {
title: String
code: String
teacher: String
grade: String
progress: String
}
class CampusWork {
status: String
score: String
feedback: String
submission: String
todo: String
result: String
course: CampusCourse
function submit(self: CampusWork, event: Event): Unit {
self.status = "已提交 · 等待评分"
self.submission = "lab01.endor · 已提交示例内容"
self.todo = "已完成本次实验提交"
self.result = "示例提交成功,可以切到作业中心查看同一条记录。"
}
function assess(self: CampusWork, event: Event): Unit {
self.status = "已评分"
self.score = "92 / 100"
self.feedback = "结构清晰,边界情况处理完整。建议补充函数说明。"
self.submission = "lab01.endor · 已提交示例内容"
self.todo = "本次实验已评分"
self.course.grade = "88.5%"
self.course.progress = "已完成 4 / 6 个学习单元"
self.result = "已应用预设评分;仪表盘、课程主页和成绩总览同步更新。"
}
function reset(self: CampusWork, event: Event): Unit {
self.status = "未提交"
self.score = "— / 100"
self.feedback = "提交后可在此查看教师反馈。"
self.submission = "尚无提交内容"
self.todo = "1 项实验待提交"
self.course.grade = "86.0%"
self.course.progress = "已完成 3 / 6 个学习单元"
self.result = "已恢复实验、课程成绩和学习进度的示例状态。"
}
}
function campusCell(content: Block, width: Number): Block {
return CampusCell(0, 0, content, width)
}
class CampusTarget {
page: Page
// Consume the click Event here; Page.open's optional argument is a Window.
function open(self: CampusTarget, event: Event): Unit { self.page.open() }
}
function campusLink(label: String, target: Page): Button {
button = Button(label)
action = CampusTarget(target)
button.on("click", action.open)
return button
}
function campusNav(label: String, target: Page, background: String): Button {
button = CampusNav(label, background)
button.replace(0, TextBlock(label, 1, "#FFFFFF"))
action = CampusTarget(target)
button.on("click", action.open)
return button
}
function campusNavigation(home: Page, course: Page, assignments: Page, grades: Page, homeTone: String, courseTone: String, workTone: String, gradeTone: String): Block {
return CampusSidebar(12, 10,
TextBlock("Endor", 2, "#FFFFFF"),
TextBlock("Campus", 1, "#E7BAC0"), Spacer(16),
campusNav("仪表盘", home, homeTone),
campusNav("课程", course, courseTone),
campusNav("作业中心", assignments, workTone),
campusNav("成绩总览", grades, gradeTone), Spacer(100),
TextBlock("林沐", 1, "#FFFFFF"),
TextBlock("2026 秋季学期", 1, "#E7BAC0"),
TextBlock("本地演示", 1, "#E7BAC0"))
}
function campusShell(navigation: Block, title: String, subtitle: String, body: Block): Block {
scroll = ScrollBlock(1120, 680,
Row(24, 28, navigation,
Column(0, 16,
TextBlock(title, 2, "#263444"),
TextBlock(subtitle, 1, "#7C8793"),
RectBlock(800, 1, 0, "#E0E5EB"), body)))
scroll.axis = "both"
return scroll
}
function campusCourseCard(course: CampusCourse, page: Page, color: String): Block {
return CampusPanel(0, 0,
RectBlock(248, 44, 8, color),
Column(16, 8,
TextBlock(course.code, 1, "#7C8793"),
TextBlock(course.title, 1, "#263444"),
TextBlock(course.teacher, 1, "#7C8793"),
ui.textOf(course, "grade", 2, color),
campusLink("进入课程", page)))
}
function campusGradeRow(course: CampusCourse, target: Page): Block {
return Column(0, 12,
Row(0, 0,
campusCell(TextBlock(course.title), 240),
campusCell(TextBlock(course.code, 1, "#7C8793"), 140),
campusCell(ui.textOf(course, "grade", 1, "#315E86"), 140),
campusLink("课程详情", target)),
RectBlock(752, 1, 0, "#EDF0F3"))
}
function campusCourseBody(course: CampusCourse, intro: String, moduleOne: String, moduleTwo: String, moduleThree: String, assignments: Page, grades: Page): Block {
return Column(0, 20,
Row(0, 16, campusLink("作业与提交", assignments), campusLink("查看成绩", grades)),
CampusPanel(20, 12,
TextBlock("课程概况", 1, "#263444"),
TextBlock(intro, 1, "#6D7987"),
TextBlock(course.teacher, 1, "#6D7987"),
Row(0, 24, TextBlock("当前成绩", 1, "#7C8793"), ui.textOf(course, "grade", 2, "#315E86")),
ui.textOf(course, "progress", 1, "#6D7987")),
CampusPanel(20, 14,
TextBlock("学习单元", 1, "#263444"),
TextBlock(moduleOne, 1, "#526372"),
RectBlock(752, 1, 0, "#EDF0F3"),
TextBlock(moduleTwo, 1, "#526372"),
RectBlock(752, 1, 0, "#EDF0F3"),
TextBlock(moduleThree, 1, "#526372")))
}
// The shared object graph is created once; each Page projects those same objects.
campusProgramming = CampusCourse("计算机程序设计", "CS 101", "陈老师 · 周二 / 周四", "86.0%", "已完成 3 / 6 个学习单元")
campusMathematics = CampusCourse("高等数学 I", "MATH 101", "周老师 · 周一 / 周三", "91.0%", "已完成 4 / 6 个学习单元")
campusEnglish = CampusCourse("学术英语", "ENG 102", "许老师 · 周五", "89.0%", "已完成 3 / 5 个学习单元")
campusWork = CampusWork("未提交", "— / 100", "提交后可在此查看教师反馈。", "尚无提交内容", "1 项实验待提交", "这是一个本地提交与评分演示。", campusProgramming)
campusDashboard = Page()
campusDashboard.title = "Campus · 仪表盘"
campusProgrammingPage = Page()
campusProgrammingPage.title = "CS 101 · 程序设计"
campusMathPage = Page()
campusMathPage.title = "MATH 101 · 高等数学"
campusEnglishPage = Page()
campusEnglishPage.title = "ENG 102 · 学术英语"
campusAssignments = Page()
campusAssignments.title = "Campus · 作业中心"
campusGrades = Page()
campusGrades.title = "Campus · 成绩总览"
campusWorkPage = Page()
campusWorkPage.title = "实验 01 · 提交详情"
campusHomeNav = campusNavigation(campusDashboard, campusProgrammingPage, campusAssignments, campusGrades, "#A64350", "#852B38", "#852B38", "#852B38")
campusCourseNav = campusNavigation(campusDashboard, campusProgrammingPage, campusAssignments, campusGrades, "#852B38", "#A64350", "#852B38", "#852B38")
campusAssignmentNav = campusNavigation(campusDashboard, campusProgrammingPage, campusAssignments, campusGrades, "#852B38", "#852B38", "#A64350", "#852B38")
campusGradeNav = campusNavigation(campusDashboard, campusProgrammingPage, campusAssignments, campusGrades, "#852B38", "#852B38", "#852B38", "#A64350")
campusDashboard.render(campusShell(campusHomeNav, "仪表盘", "林沐,欢迎回来。这里是你的课程与近期学习安排。",
Column(0, 20,
Row(0, 16,
campusCourseCard(campusProgramming, campusProgrammingPage, "#326A8F"),
campusCourseCard(campusMathematics, campusMathPage, "#547C67"),
campusCourseCard(campusEnglish, campusEnglishPage, "#88647D")),
CampusPanel(20, 12,
TextBlock("近期作业", 1, "#263444"),
Row(0, 24, TextBlock("CS 101 · 实验 01:对象与函数"), ui.textOf(campusWork, "status", 1, "#315E86")),
ui.textOf(campusWork, "todo", 1, "#7C8793"),
campusLink("打开作业详情", campusWorkPage)),
TextBlock("虚构课程与学生数据 · Endor 本地多页面演示", 1, "#8C959F"))))
campusProgrammingPage.render(campusShell(campusCourseNav, "计算机程序设计", "课程 / CS 101 / 主页",
Column(0, 16,
campusCourseBody(campusProgramming, "通过实际编程理解对象、函数与交互。", "01 对象与字段 · 已完成", "02 函数与方法 · 已完成", "03 事件与可视界面 · 进行中", campusAssignments, campusGrades),
campusLink("实验 01:对象与函数", campusWorkPage))))
campusMathPage.render(campusShell(campusCourseNav, "高等数学 I", "课程 / MATH 101 / 主页",
campusCourseBody(campusMathematics, "学习极限、微分与积分的基本方法。", "01 函数与极限 · 已完成", "02 导数及其应用 · 已完成", "03 积分方法 · 进行中", campusAssignments, campusGrades)))
campusEnglishPage.render(campusShell(campusCourseNav, "学术英语", "课程 / ENG 102 / 主页",
campusCourseBody(campusEnglish, "阅读学术文本,练习清晰的论证与表达。", "01 Academic reading · 已完成", "02 Evidence and arguments · 已完成", "03 Research writing · 进行中", campusAssignments, campusGrades)))
campusAssignments.render(campusShell(campusAssignmentNav, "作业中心", "本学期 / 全部课程 / 作业与提交",
Column(0, 20,
CampusPanel(20, 12,
TextBlock("实验 01:对象与函数", 1, "#263444"),
TextBlock("CS 101 · 10 月 30 日 23:59 截止 · 满分 100", 1, "#7C8793"),
Row(0, 24, ui.textOf(campusWork, "status", 1, "#315E86"), ui.textOf(campusWork, "score")),
campusLink("查看提交详情", campusWorkPage)),
CampusPanel(20, 12,
TextBlock("习题 04:微分与应用", 1, "#263444"),
TextBlock("MATH 101 · 已提交 · 90 / 100", 1, "#7C8793")),
CampusPanel(20, 12,
TextBlock("Reading response", 1, "#263444"),
TextBlock("ENG 102 · 已评分 · 88 / 100", 1, "#7C8793")))))
campusGrades.render(campusShell(campusGradeNav, "成绩总览", "2026 秋季学期 / 当前课程成绩",
Column(0, 20,
CampusPanel(20, 16,
Row(0, 0,
campusCell(TextBlock("课程", 1, "#7C8793"), 240),
campusCell(TextBlock("课程编号", 1, "#7C8793"), 140),
campusCell(TextBlock("当前成绩", 1, "#7C8793"), 140)),
campusGradeRow(campusProgramming, campusProgrammingPage),
campusGradeRow(campusMathematics, campusMathPage),
campusGradeRow(campusEnglish, campusEnglishPage)),
CampusPanel(20, 12,
TextBlock("CS 101 · 作业评分与反馈", 1, "#263444"),
Row(0, 24, TextBlock("实验 01:对象与函数"), ui.textOf(campusWork, "score", 1, "#315E86")),
ui.textOf(campusWork, "feedback", 1, "#6D7987"),
campusLink("打开作业与反馈", campusWorkPage)))))
campusSubmitButton = Button("模拟提交实验")
campusSubmitButton.on("click", campusWork.submit)
campusAssessButton = Button("应用示例评分")
campusAssessButton.on("click", campusWork.assess)
campusResetButton = Button("恢复演示数据")
campusResetButton.on("click", campusWork.reset)
campusWorkPage.render(campusShell(campusAssignmentNav, "实验 01:对象与函数", "CS 101 / 作业 / 提交详情",
Column(0, 20,
Row(0, 16, campusLink("返回课程", campusProgrammingPage), campusLink("全部作业", campusAssignments), campusLink("成绩总览", campusGrades)),
CampusPanel(20, 12,
TextBlock("实验要求", 1, "#263444"),
TextBlock("使用 Endor 定义一个对象,并通过方法更新其字段。", 1, "#6D7987"),
TextBlock("为同一个对象建立两个可视展示,验证修改后同时更新。", 1, "#6D7987"),
TextBlock("截止:10 月 30 日 23:59 满分:100", 1, "#7C8793")),
CampusPanel(20, 12,
TextBlock("提交记录", 1, "#263444"),
ui.textOf(campusWork, "submission"),
ui.textOf(campusWork, "status", 1, "#315E86"),
Row(0, 12, campusSubmitButton, campusAssessButton, campusResetButton)),
CampusPanel(20, 12,
Row(0, 24, TextBlock("成绩与反馈"), ui.textOf(campusWork, "score", 2, "#315E86")),
ui.textOf(campusWork, "feedback", 1, "#6D7987")),
ui.textOf(campusWork, "result", 1, "#7C8793"))))
campusDashboard.activate()