269 lines
14 KiB
Plaintext
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()
|