Skip to content

Commit 3ca9b0a

Browse files
authored
[0114] 页面边白输入框改为原生 QSpinBox 数字调节框 (#3338)
1 parent 23dd4c7 commit 3ca9b0a

13 files changed

Lines changed: 292 additions & 14 deletions

File tree

TeXmacs/progs/generic/document-widgets.scm

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,19 @@
324324
;; Document -> Page / Margins
325325
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
326326

327+
(define (page-margin-get-mm-initial u var)
328+
(let ((val (initial-get u var)))
329+
(cond ((or (not val) (== val "") (== val "auto")) 30)
330+
((tm-length? val)
331+
(with decoded (length-decode val)
332+
(if decoded
333+
(inexact->exact (round (/ decoded 6047.0)))
334+
30)))
335+
(else 30))))
336+
337+
(define (page-margin-set-mm-initial u var val)
338+
(initial-set u var (string-append (number->string val) "mm")))
339+
327340
(tm-widget (page-formatter-margins u quit)
328341
(padded
329342
(refreshable "page-margin-toggles"
@@ -349,14 +362,17 @@
349362
(if (!= (initial-get u "page-width-margin") "true")
350363
(aligned
351364
(item (text "(Odd page) Left:")
352-
(input (initial-set u "page-odd" answer) "string"
353-
(list (initial-get u "page-odd")) "6em"))
365+
(hlist
366+
(numeric-input (page-margin-set-mm-initial u "page-odd" answer) "4em" "mm"
367+
0 500 1 (page-margin-get-mm-initial u "page-odd"))))
354368
(item (text "(Even page) Left:")
355-
(input (initial-set u "page-even" answer) "string"
356-
(list (initial-get u "page-odd")) "6em"))
369+
(hlist
370+
(numeric-input (page-margin-set-mm-initial u "page-even" answer) "4em" "mm"
371+
0 500 1 (page-margin-get-mm-initial u "page-even"))))
357372
(item (text "(Odd page) Right:")
358-
(input (initial-set u "page-right" answer) "string"
359-
(list (initial-get u "page-right")) "6em"))
373+
(hlist
374+
(numeric-input (page-margin-set-mm-initial u "page-right" answer) "4em" "mm"
375+
0 500 1 (page-margin-get-mm-initial u "page-right"))))
360376
(item (text "Top:")
361377
(input (initial-set u "page-top" answer) "string"
362378
(list (initial-get u "page-top")) "6em"))

TeXmacs/progs/generic/format-tools.scm

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,19 @@
322322
;; Global page margins
323323
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
324324

325+
(define (page-margin-get-mm win var)
326+
(let ((val (window-get-init win var)))
327+
(cond ((or (not val) (== val "") (== val "auto")) 30)
328+
((tm-length? val)
329+
(with decoded (length-decode val)
330+
(if decoded
331+
(inexact->exact (round (/ decoded 6047.0)))
332+
30)))
333+
(else 30))))
334+
335+
(define (page-margin-set-mm win var val)
336+
(window-set-init win var (string-append (number->string val) "mm")))
337+
325338
(tm-widget (page-margins-tool win)
326339
(padded
327340
(aligned
@@ -346,18 +359,18 @@
346359
(aligned
347360
(item (text "Left:")
348361
(hlist
349-
(input (window-set-init win "page-odd" answer) "string"
350-
(list (window-get-init win "page-odd")) "6em")
362+
(numeric-input (page-margin-set-mm win "page-odd" answer) "4em" "mm"
363+
0 500 1 (page-margin-get-mm win "page-odd"))
351364
// // (text "(odd pages)") // >>>))
352365
(item (text "")
353366
(hlist
354-
(input (window-set-init win "page-even" answer) "string"
355-
(list (window-get-init win "page-odd")) "6em")
367+
(numeric-input (page-margin-set-mm win "page-even" answer) "4em" "mm"
368+
0 500 1 (page-margin-get-mm win "page-even"))
356369
// // (text "(even pages)") >>>))
357370
(item (text "Right:")
358371
(hlist
359-
(input (window-set-init win "page-right" answer) "string"
360-
(list (window-get-init win "page-right")) "6em")
372+
(numeric-input (page-margin-set-mm win "page-right" answer) "4em" "mm"
373+
0 500 1 (page-margin-get-mm win "page-right"))
361374
// // (text "(odd pages)") // >>>))
362375
(item (text "Top:")
363376
(input (window-set-init win "page-top" answer) "string"

TeXmacs/progs/kernel/gui/gui-markup.scm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@
335335
(:synopsis "Make input field")
336336
`(list 'input (lambda (answer) ,cmd) ,type (lambda () ,proposals) ,width))
337337

338+
(tm-define-macro ($numeric-input cmd width unit min max step def)
339+
(:synopsis "Make numeric input field")
340+
`(list 'numeric-input (lambda (answer) ,cmd) ,width ,unit ,min ,max ,step ,def))
341+
338342
(tm-define-macro ($toggle cmd on)
339343
(:synopsis "Make input toggle")
340344
`(list 'toggle (lambda (answer) ,cmd) (lambda () ,on)))

TeXmacs/progs/kernel/gui/menu-convert.scm

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@
195195
`(input-popup ,type ,cmd ,width ,(car props)
196196
(choice-list ,cmd ,(car props) ,@props))))))
197197

198+
(tm-define (markup-numeric-input cmd* width unit min max step def)
199+
(with cmd (unary-mangled cmd*)
200+
`(numeric-input ,cmd ,width ,unit ,min ,max ,step ,def)))
201+
198202
(tm-define (markup-enum cmd* props val style width)
199203
;; TODO: handle inert style
200204
(with cmd (unary-mangled cmd*)
@@ -448,10 +452,16 @@
448452

449453
(define (build-menu-input p style)
450454
"Make @(input :%1 :string? :%1 :string?) menu item."
451-
(with (tag cmd type props width) p
455+
(with (tag cmd type props width) p
452456
(markup-input (object->command (menu-protect cmd)) type (props)
453457
style width)))
454458

459+
(define (build-numeric-input p style)
460+
"Make @(numeric-input :%7) menu item."
461+
(with (tag cmd width unit min max step def) p
462+
(markup-numeric-input (object->command (menu-protect cmd)) width unit min max
463+
step def)))
464+
455465
(define (build-enum p style)
456466
"Make @(enum :%3 :string?) item."
457467
(with (tag cmd vals val width) p
@@ -943,6 +953,8 @@
943953
,(lambda (p style bar?) (list (build-texmacs-input p style))))
944954
(input (:%1 :string? :%1 :string?)
945955
,(lambda (p style bar?) (list (build-menu-input p style))))
956+
(numeric-input (:%1 :string? :string? :integer? :integer? :integer? :integer?)
957+
,(lambda (p style bar?) (list (build-numeric-input p style))))
946958
(enum (:%3 :string?)
947959
,(lambda (p style bar?) (list (build-enum p style))))
948960
(choice (:%3)

TeXmacs/progs/kernel/gui/menu-define.scm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@
117117
(require-format x '(input :%4))
118118
`($input ,@(cdr x)))
119119

120+
(define (gui-make-numeric-input x)
121+
(require-format x '(numeric-input :%7))
122+
`($numeric-input ,@(cdr x)))
123+
120124
(define (gui-make-enum x)
121125
(require-format x '(enum :%4))
122126
`($enum ,@(cdr x)))
@@ -412,6 +416,7 @@
412416
(texmacs-output ,gui-make-texmacs-output)
413417
(texmacs-input ,gui-make-texmacs-input)
414418
(input ,gui-make-input)
419+
(numeric-input ,gui-make-numeric-input)
415420
(enum ,gui-make-enum)
416421
(choice ,gui-make-choice)
417422
(choices ,gui-make-choices)

TeXmacs/progs/kernel/gui/menu-widget.scm

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,16 @@
293293

294294
(define (make-menu-input p style)
295295
"Make @(input :%1 :string? :%1 :string?) menu item."
296-
(with (tag cmd type props width) p
296+
(with (tag cmd type props width) p
297297
(widget-input (object->command (menu-protect cmd)) type (props)
298298
style width)))
299299

300+
(define (make-numeric-input p style)
301+
"Make @(numeric-input :%7) menu item."
302+
(with (tag cmd width unit min max step def) p
303+
(widget-numeric-input (object->command (menu-protect cmd)) width unit min max
304+
step def)))
305+
300306
(define (make-enum p style)
301307
"Make @(enum :%3 :string?) item."
302308
(with (tag cmd vals val width) p
@@ -862,6 +868,8 @@
862868
,(lambda (p style bar?) (list (make-texmacs-input p style))))
863869
(input (:%1 :string? :%1 :string?)
864870
,(lambda (p style bar?) (list (make-menu-input p style))))
871+
(numeric-input (:%1 :string? :string? :integer? :integer? :integer? :integer?)
872+
,(lambda (p style bar?) (list (make-numeric-input p style))))
865873
(enum (:%3 :string?)
866874
,(lambda (p style bar?) (list (make-enum p style))))
867875
(choice (:%3)

TeXmacs/progs/prog/glue-symbols.scm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@
639639
"widget-empty"
640640
"widget-text"
641641
"widget-input"
642+
"widget-numeric-input"
642643
"widget-enum"
643644
"widget-choice"
644645
"widget-choices"

devel/0114.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# [0114] 页面边白输入框改为数字调节框
2+
3+
## 相关文档
4+
- [dddd.md](dddd.md) - 任务文档模板
5+
6+
## 任务相关的代码文件
7+
8+
### C++ 层(新增 QSpinBox widget 支持)
9+
- `src/Graphics/Gui/widget.hpp`
10+
- `src/Plugins/Qt/qt_dialogues.hpp`
11+
- `src/Plugins/Qt/qt_dialogues.cpp`
12+
- `src/Plugins/Qt/qt_widget.cpp`
13+
- `src/Scheme/L5/glue_widget.lua`
14+
- `build/glue/glue_widget.cpp`(构建时自动生成,但需重新生成)
15+
16+
### Scheme 层(新增 `numeric-input` GUI 原语)
17+
- `TeXmacs/progs/kernel/gui/gui-markup.scm`
18+
- `TeXmacs/progs/kernel/gui/menu-define.scm`
19+
- `TeXmacs/progs/kernel/gui/menu-convert.scm`
20+
- `TeXmacs/progs/kernel/gui/menu-widget.scm`
21+
- `TeXmacs/progs/prog/glue-symbols.scm`
22+
23+
### 业务层(使用 `numeric-input`
24+
- `TeXmacs/progs/generic/format-tools.scm` - 侧边栏页面边白工具
25+
- `TeXmacs/progs/generic/document-widgets.scm` - 文档页面设置弹窗
26+
27+
## 如何测试
28+
29+
### 编译
30+
由于新增了 C++ 代码,需要重新编译:
31+
```bash
32+
xmake build
33+
```
34+
35+
xmake 会自动根据 `glue_widget.lua` 重新生成 `build/glue/glue_widget.cpp`
36+
37+
### 非确定性测试(文档验证)
38+
1. 启动 Mogan,新建文档
39+
2. 打开右侧工具栏 -> Document -> Page -> Margins
40+
3. 观察 Left(odd pages)、Left(even pages)、Right(odd pages)三个输入框:
41+
- 默认值应显示为数字(如 `30`
42+
- 应为原生 Qt 数字调节框(QSpinBox),带上下箭头按钮
43+
- 旁边应有 `mm` 单位标签
44+
- 点击上下箭头或输入数字,数值实时变化并写入环境变量
45+
4. 当值为 `auto` 时,默认显示 `30`
46+
5. 同样测试 Document -> Page -> Margins 弹窗中的三个输入框
47+
48+
## 如何提交
49+
50+
```bash
51+
# 编译前检查
52+
xmake build
53+
54+
# 提交(注意 build/glue/glue_widget.cpp 是生成文件,不应提交)
55+
```
56+
57+
## What
58+
59+
将页面边白(Margins)设置中的三个左右边距输入框,从自由文本输入改为原生 Qt 数字调节框(QSpinBox),并固定单位为 mm。
60+
61+
本次 PR 仅修改以下三个输入框:
62+
1. **Left (odd pages)** — 对应环境变量 `page-odd`
63+
2. **Left (even pages)** — 对应环境变量 `page-even`
64+
3. **Right (odd pages)** — 对应环境变量 `page-right`
65+
66+
具体改动:
67+
1. 当当前值为 `auto` 时,默认显示 `30`(对应 `30mm`
68+
2. 输入框为原生 QSpinBox,只显示纯数字
69+
3. 单位 `mm` 以标签形式固定显示在旁边
70+
4. 通过 QSpinBox 的上下箭头每次增减 `1mm`
71+
5. 直接输入数字后自动追加 `mm` 单位并写入环境变量
72+
73+
## Why
74+
75+
当前边白输入框为自由文本(`string` 类型),默认值显示 `auto`,用户需要手动输入带单位的长度值(如 `30mm`),不够直观。改为原生数字调节框后:
76+
- 降低用户理解成本,无需记忆单位格式
77+
- 通过原生 QSpinBox 的上下箭头快速微调边距,体验更精致
78+
- 与大多数排版/设计软件的操作习惯保持一致
79+
80+
## How
81+
82+
### C++ 层:新增 `qt_numeric_input_widget_rep`
83+
84+
`src/Plugins/Qt/qt_dialogues.hpp/cpp` 中新增 `qt_numeric_input_widget_rep` 类:
85+
86+
- `as_qwidget()` 创建 `QSpinBox`,设置范围、步长、默认值
87+
- `commit()` 将数值通过 command 传递给 Scheme 层
88+
- `setValue()` 前通过 `blockSignals(true/false)` 避免刷新 widget 时触发不必要的 commit
89+
90+
`src/Graphics/Gui/widget.hpp``src/Plugins/Qt/qt_widget.cpp` 中新增工厂函数:
91+
```cpp
92+
widget numeric_input_widget (command call_back, string width, int min_val,
93+
int max_val, int step, int def);
94+
```
95+
96+
### Glue 层:新增 `widget-numeric-input`
97+
98+
在 `src/Scheme/L5/glue_widget.lua` 中添加 `widget-numeric-input` 绑定:
99+
```lua
100+
{
101+
scm_name = "widget-numeric-input",
102+
cpp_name = "numeric_input_widget",
103+
ret_type = "widget",
104+
arg_list = { "command", "string", "int", "int", "int", "int" }
105+
}
106+
```
107+
108+
并在 `TeXmacs/progs/prog/glue-symbols.scm` 中注册符号。
109+
110+
### Scheme 层:新增 `numeric-input` GUI 原语
111+
112+
`gui-markup.scm``menu-define.scm``menu-convert.scm``menu-widget.scm` 中依次添加 `numeric-input` 的支持,使其可以在 Scheme 菜单/widget 中直接使用:
113+
114+
```scheme
115+
(numeric-input cmd width min max step def)
116+
```
117+
118+
### 业务层:使用 `numeric-input`
119+
120+
`format-tools.scm``document-widgets.scm` 中,将三个左右边距输入框改为:
121+
122+
```scheme
123+
(numeric-input (page-margin-set-mm win "page-odd" answer) "4em"
124+
0 500 1 (page-margin-get-mm win "page-odd"))
125+
```
126+
127+
辅助函数保留:
128+
- `page-margin-get-mm` / `page-margin-get-mm-initial`:将环境变量值(含 `auto`、各种单位)转换为 mm 整数
129+
- `page-margin-set-mm` / `page-margin-set-mm-initial`:将整数转换为 `"<val>mm"` 写入环境变量

src/Graphics/Gui/widget.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ widget input_text_widget (command call_back, string type, array<string> def,
182182
// default inputs (the first one should be displayed, if there is one)
183183
// an optional width may be specified for the input field
184184
// the width is specified in TeXmacs length format with units em, px or w
185+
widget numeric_input_widget (command call_back, string width, string unit,
186+
int min_val, int max_val, int step, int def);
187+
// a numeric input widget with a spin box for integer values
188+
// an optional width may be specified for the input field
189+
// an optional unit suffix (e.g. "mm") may be displayed after the value
185190
widget enum_widget (command cb, array<string> vals, string val, int st= 0,
186191
string w= "1w");
187192
// select a value from a list of possible values

src/Plugins/Qt/qt_dialogues.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <QLineEdit>
3333
#include <QMessageBox>
3434
#include <QPushButton>
35+
#include <QSpinBox>
3536
#include <QVBoxLayout>
3637
#include <QVector>
3738

@@ -433,3 +434,46 @@ qt_input_text_widget_rep::commit (bool flag) {
433434
: list_object (object (false)));
434435
}
435436
}
437+
438+
/******************************************************************************
439+
* qt_numeric_input_widget_rep
440+
******************************************************************************/
441+
442+
qt_numeric_input_widget_rep::qt_numeric_input_widget_rep (
443+
command _cmd, string _width, string _unit, int _min_val, int _max_val,
444+
int _step, int _def)
445+
: qt_widget_rep (input_widget), cmd (_cmd), width (_width), unit (_unit),
446+
min_val (_min_val), max_val (_max_val), step (_step), value (_def) {}
447+
448+
QWidget*
449+
qt_numeric_input_widget_rep::as_qwidget () {
450+
QSpinBox* spin= new QSpinBox ();
451+
qwid = spin;
452+
spin->setRange (min_val, max_val);
453+
spin->setSingleStep (step);
454+
spin->blockSignals (true);
455+
spin->setValue (value);
456+
spin->blockSignals (false);
457+
spin->setObjectName ("numeric-input");
458+
459+
if (unit != "") {
460+
spin->setSuffix (to_qstring (unit));
461+
}
462+
463+
if (width != "") {
464+
spin->setMinimumWidth (50);
465+
}
466+
467+
QObject::connect (spin, QOverload<int>::of (&QSpinBox::valueChanged),
468+
[this] (int new_val) {
469+
value= new_val;
470+
commit ();
471+
});
472+
473+
return qwid;
474+
}
475+
476+
void
477+
qt_numeric_input_widget_rep::commit () {
478+
the_gui->process_command (cmd, list_object (object (value)));
479+
}

0 commit comments

Comments
 (0)