+
+
{{ displayText(formTitle) }}
─ ☐ ✕
@@ -707,6 +728,10 @@ const noop = () => {}
box-shadow: 0 2px 10px rgb(0 0 0 / 0.15);
}
+.window.borderless {
+ border-color: transparent;
+}
+
.window.selected {
outline: 1px dashed #2563eb;
outline-offset: 2px;
diff --git a/web/src/designer/PropertyGrid.vue b/web/src/designer/PropertyGrid.vue
index 209c998..5865b1f 100644
--- a/web/src/designer/PropertyGrid.vue
+++ b/web/src/designer/PropertyGrid.vue
@@ -7,7 +7,7 @@ import ChartDialog from './ChartDialog.vue'
import type { DesignerDocument } from './document'
import { checkName, getEventHandler, getItems, getPropText, typeOf } from './edit'
import { resourceNameOf } from './resources'
-import { NAMED_COLORS, hexToRgb, parseValue, rgb, type Value } from './values'
+import { COLOR_LABELS, NAMED_COLORS, hexToRgb, parseValue, rgb, type Value } from './values'
const props = defineProps<{
doc: DesignerDocument
@@ -289,7 +289,7 @@ function renameHandler(event: string, value: string) {
{
const code = 'namespace A\n{\n public partial class F : Form\n {\n }\n}\n'
const { code: next, line } = ensureHandler(code, 'F', 'F_Load', 'EventArgs')
expect(next).toBe(
- 'namespace A\n{\n public partial class F : Form\n {\n private void F_Load(object sender, EventArgs e)\n {\n\n }\n }\n}\n',
+ 'namespace A\n{\n public partial class F : Form\n {\n private void F_Load(object sender, EventArgs e)\n {\n \n }\n }\n}\n',
)
expect(line).toBe(7)
})
@@ -33,5 +33,5 @@ test('类里还没有成员时不留多余空行', () => {
test('字符串和注释里的大括号不影响查找类的结尾', () => {
const code = 'class F\n{\n string s = "}{";\n // }\n char c = \'}\';\n}\n'
const { code: next } = ensureHandler(code, 'F', 'F_Load', 'EventArgs')
- expect(next.endsWith(" char c = '}';\n\n private void F_Load(object sender, EventArgs e)\n {\n\n }\n}\n")).toBe(true)
+ expect(next.endsWith(" char c = '}';\n\n private void F_Load(object sender, EventArgs e)\n {\n \n }\n}\n")).toBe(true)
})
diff --git a/web/src/designer/code.ts b/web/src/designer/code.ts
index 4201c54..584d69a 100644
--- a/web/src/designer/code.ts
+++ b/web/src/designer/code.ts
@@ -20,7 +20,9 @@ export function ensureHandler(code: string, className: string, handler: string,
// 类里已有成员时,与上一个成员之间空一行
const before = code.slice(0, lineStart)
const hasMembers = !/\{\s*$/.test(before)
- const method = [...(hasMembers ? [''] : []), `${indent}private void ${handler}(object sender, ${args} e)`, `${indent}{`, '', `${indent}}`].join(eol)
+ // 方法体的空行带好缩进(和 VS 一样),光标跳过去就在缩进后面,学生的代码不会顶格写
+ const body = `${indent} `
+ const method = [...(hasMembers ? [''] : []), `${indent}private void ${handler}(object sender, ${args} e)`, `${indent}{`, body, `${indent}}`].join(eol)
const next = `${before}${method}${eol}${code.slice(lineStart)}`
return { code: next, line: lineOf(next, before.length) + (hasMembers ? 3 : 2) }
}
diff --git a/web/src/designer/values.ts b/web/src/designer/values.ts
index 083ebd4..74bd65b 100644
--- a/web/src/designer/values.ts
+++ b/web/src/designer/values.ts
@@ -134,6 +134,30 @@ export const NAMED_COLORS: Record
= {
Cyan: '#00ffff',
}
+/** 属性窗口里颜色的中文名,英文名放在悬停提示里 */
+export const COLOR_LABELS: Record = {
+ Transparent: '透明',
+ Black: '黑色',
+ White: '白色',
+ Red: '红色',
+ Green: '绿色',
+ Blue: '蓝色',
+ Yellow: '黄色',
+ Orange: '橙色',
+ Gray: '灰色',
+ DimGray: '暗灰色',
+ Silver: '银色',
+ LightGray: '浅灰色',
+ DarkBlue: '深蓝色',
+ SkyBlue: '天蓝色',
+ LightGreen: '浅绿色',
+ Lime: '亮绿色',
+ Purple: '紫色',
+ Brown: '棕色',
+ Pink: '粉红色',
+ Cyan: '青色',
+}
+
/** 系统颜色(System.Drawing.SystemColors),按 Windows 10 默认主题取值 */
const SYSTEM_COLORS: Record = {
Control: '#f0f0f0',
diff --git a/web/src/editor/CodeEditor.vue b/web/src/editor/CodeEditor.vue
index 00841ab..474b812 100644
--- a/web/src/editor/CodeEditor.vue
+++ b/web/src/editor/CodeEditor.vue
@@ -124,6 +124,8 @@ onMounted(() => {
tabSize: 4,
insertSpaces: true,
minimap: { enabled: false },
+ // 顶部不固定显示所在的类和方法:点报错跳到文件开头附近的行时,那一行会被它挡住
+ stickyScroll: { enabled: false },
scrollBeyondLastLine: false,
renderWhitespace: 'selection',
unicodeHighlight: { ambiguousCharacters: false },
diff --git a/web/src/editor/monaco.ts b/web/src/editor/monaco.ts
index 6f95597..5b2fa7f 100644
--- a/web/src/editor/monaco.ts
+++ b/web/src/editor/monaco.ts
@@ -1,5 +1,7 @@
// 按需加载 Monaco(0.57 的模块布局):编辑器 API + 全部编辑功能(查找、折叠、括号匹配等)+ C# 和 SQL 语法高亮,
// 不加载其他几十种语言和 JS/TS/CSS 语言服务,体积小很多。
+// 中文界面(查找替换、右键菜单、提示文字):必须在编辑器模块之前加载,编辑器模块加载时就会取界面文字
+import 'monaco-editor/nls/lang/zh-cn'
import * as monaco from 'monaco-editor/editor/editor.api'
import 'monaco-editor/features/register.all'
import 'monaco-editor/languages/definitions/csharp/register'
diff --git a/web/src/grading/TaskPanel.vue b/web/src/grading/TaskPanel.vue
index be1ab5b..b50a34c 100644
--- a/web/src/grading/TaskPanel.vue
+++ b/web/src/grading/TaskPanel.vue
@@ -77,6 +77,7 @@ const formatTime = (ms: number) => new Date(ms).toLocaleTimeString('zh-CN', { ho
:show-mask="false"
:trap-focus="false"
:block-scroll="false"
+ class="task-drawer"
@update:show="emit('update:show', $event)"
>
@@ -117,6 +118,13 @@ const formatTime = (ms: number) => new Date(ms).toLocaleTimeString('zh-CN', { ho
+
+