Texmacs/Mogan Note 2
23_15
1(get-init-tree "text-at-halign")
这个与缓存有关。缓存位置在~/.Texmacs/
。如果不更改缓存,更改源代码不会生效。
23_7
1(tm-define (graphics-release-left x y)
2 ;;(display* "Graphics] Release-left " x ", " y "\n")
3 (if (inside-graphical-text?)
4 (with-innermost t graphical-text-context?
5 (let* ((ps (select-first (s2f x) (s2f y)))
6 (p (and ps (car ps))))
7 (if (and p (list-starts? p (tree->path t)))
8 (go-to p)
9 (tree-go-to t :start))))
10 (edit_left-button (car (graphics-mode)) x y)))
1(tm-define (get-keyboard-modifiers)
2 the-keyboard-modifiers)
3
4(tm-define (set-keyboard-modifiers mods)
5 (set! the-keyboard-modifiers mods))
结论:https://github.com/XmacsLabs/mogan/pull/796
问题
- .ts文件怎么使用
- C++代码中有很多字符串类型的东西可以用枚举类型来替代,可以重构一下?
- 绘图模式有没有给座标系标注1、2、3的模式
编译时候出现问题
1generating scheme glueA glue_font ... ok
2generating scheme glueA glue_analyze ... ok
3generating scheme glueA glue_drd ... ok
4installing libmogan ..
5error: install failed, method 'trim' is not callable (a nil value)
看起来是lua语言中的trim方法无法调用。 结论:有一个环境变量字符串被设置为nil,之后在他的上面调用trim方法则报错。
23_14
edit_interface_rep::handle_mouse
处理鼠标事件。
1edit_interface_rep::handle_mouse (string kind, SI x, SI y, int m, time_t t,
2 array<double> data)
kind的类型可以有move, press-left, release-left, press-right 等。
1else {
2 string rew= kind;
3 SI dist= (SI) (5 * PIXEL / magf);
4 rew= detect_left_drag ((void*) this, rew, x, y, t, m, dist);
5 if (rew == "start-drag-left") {
6 call_mouse_event (rew, left_x, left_y, m, t, data);
7 delayed_call_mouse_event ("dragging-left", x, y, m, t, data);
8 }
9 else {
10 rew= detect_right_drag ((void*) this, rew, x, y, t, m, dist);
11 if (rew == "start-drag-right") {
12 call_mouse_event (rew, right_x, right_y, m, t, data);
13 delayed_call_mouse_event ("dragging-right", x, y, m, t, data);
14 }
15 else call_mouse_event (rew, x, y, m, t, data);
16 }
17 }
这段检测了是否有拖动发生,如果没有,最终会执行call_mouse_event (rew, x, y, m, t, data);
1static void
2call_mouse_event (string kind, SI x, SI y, SI m, time_t t, array<double> d) {
3 array<object> args;
4 args << object (kind) << object (x) << object (y)
5 << object (m) << object ((double) t) << object (d);
6 call ("mouse-event", args);
7}
然后转发给scheme来处理。
1(tm-define (mouse-event key x y mods time data)
2 ;;(display* "mouse-event " key ", " x ", " y ", " mods ", " time ", " data "\n")
3 (mouse-any key x y mods (+ time 0.0) data))
转到mouse-any
mouse-any
再转回C++
1{
2 scm_name = "mouse-any",
3 cpp_name = "mouse_any",
4 ret_type = "void",
5 arg_list = {
6 "string",
7 "int",
8 "int",
9 "int",
10 "double",
11 "array_double"
12 }
13 },
在mouse_any
中进行dispatch.
1 if (type == "press-left" || type == "start-drag-left") {
2 if (mods > 1) {
3 mouse_adjusting = mods;
4 mouse_adjust_selection(x, y, mods);
5 } else
6 mouse_click (x, y);
7 }
在这里进入mouse_click函数
1void
2edit_interface_rep::mouse_click (SI x, SI y) {
3 if (mouse_message ("click", x, y)) return;
4 start_x= x;
5 start_y= y;
6 send_mouse_grab (this, true);
7}
思路改为倒着找,从绘图的移动功能出发。因为只需要在绘图上进行改变鼠标样式的操作,而改变鼠标样式(setCursor
)是依赖于具体的widget来执行的。
1(tm-define (edit_move mode x y)
1(tm-define (graphics-move x y)
2 ;;(display* "Graphics] Move " x ", " y "\n")
3 (when (not (inside-graphical-text?))
4 (edit_move (car (graphics-mode)) x y)))
根据("Move objects" (graphics-set-mode '(group-edit move)))
, 应该重载到group-edit版本。
测试发现正确:
1(tm-define (edit_move mode x y)
2 (:require (eq? mode 'group-edit))
3 (:state graphics-state)
4 (display* "HERE\n")
5 (cond (sticky-point
6 (set! x (s2f x))
7 (set! y (s2f y))
8 (with mode (graphics-mode)
9 (cond ((== (cadr mode) 'move)
10 (sketch-transform
11 (group-translate (- x group-old-x)
12 (- y group-old-y))))
13 ((== (cadr mode) 'zoom)
14 (sketch-set! group-first-go)
15 (sketch-transform (group-zoom x y)))
16 ((== (cadr mode) 'rotate)
17 (sketch-set! group-first-go)
18 (sketch-transform (group-rotate x y)))))
19 (set! group-old-x x)
20 (set! group-old-y y))
21 (multiselecting
22 (graphical-object!
23 (append
24 (create-graphical-props 'default #f)
25 `((with color red
26 (cline (point ,selecting-x0 ,selecting-y0)
27 (point ,x ,selecting-y0)
28 (point ,x ,y)
29 (point ,selecting-x0 ,y)))))))
30 (else
31 (cond (current-path
32 (set-message (string-append "Left click: operate; "
33 "Shift+Left click or Right click: select/unselect")
34 "Group of objects"))
35 ((nnull? (sketch-get))
36 (set-message "Left click: operate"
37 "Group of objects"))
38 (else
39 (set-message "Move over object on which to operate"
40 "Edit groups of objects")))
41 (graphics-decorations-update))))
之后倒到edit_graphics.cpp
中的:
1bool
2edit_graphics_rep::mouse_graphics (string type, SI x, SI y, int mods, time_t t,
3 array<double> data) {
倒退到
1bool
2edit_graphics_rep::mouse_graphics (string type, SI x, SI y, int mods, time_t t,
3 array<double> data) {
然后倒退到scheme中。没找到可以利用的。
换思路,搜索: public QWidget
,看都有谁继承了。因为setCursor是它的成员函数。QtMainWindow也是Qt库中的,它也继承了QWidget.
看不出。直接看主界面怎么生成的吧。
qt_tm_widget.hpp
中写了:
1 QMainWindow* mainwindow () {
2 return qobject_cast<QMainWindow*> (qwid);
3 }
这个函数可以获取主页面的QWidget. 但它仍然是一个成员函数所以可能不太对。
在qt_dialogues.cpp
中,发现了
1 QWidget* mainwindow = QApplication::activeWindow ();
这个可能是Qt自带的找到当前活跃窗口的函数。
23_14 Bug
1(tm-define (graphics-get-property var)
2 (with val (graphics-get-raw-property var)
3 (tm->stree val)))
4
5(define (graphics-get-raw-property var)
6 (with val (get-upwards-tree-property (graphics-graphics-path) var)
7 (if (eq? val nothing)
8 (get-default-tree-val var)
9 (if (eq? (tm-car val) 'quote)
10 (tree-ref val 0)
11 val))))
研究 get-env-tree
1tree
2edit_typeset_rep::get_env_value (string var, path p) {
3 typeset_exec_until (p);
4 tree t= cur[p][var];
5 return is_func (t, BACKUP, 2)? t[0]: t;
6}
鼠标点击研究
1 if (type == "press-left" || type == "start-drag-left") {
2 if (mods > 1) {
3 mouse_adjusting = mods;
4 mouse_adjust_selection(x, y, mods);
5 } else
6 mouse_click (x, y);
7 }
之后进入
1void
2edit_interface_rep::mouse_click (SI x, SI y) {
3 cout << "DEBUG: ";
4 if (mouse_message ("click", x, y)) return;
5 start_x= x;
6 start_y= y;
7 send_mouse_grab (this, true);
8}
之后
1inline void
2send_mouse_grab (widget w, bool get_grab) {
3 // request a mouse grab for the widget
4 send<bool> (w, SLOT_MOUSE_GRAB, get_grab);
5}
在这里似乎捕获了
1void
2qt_tm_widget_rep::send (slot s, blackbox val) {
3 switch (s) {
4 case SLOT_INVALIDATE:
5 case SLOT_INVALIDATE_ALL:
6 case SLOT_EXTENTS:
7 case SLOT_SCROLL_POSITION:
8 case SLOT_ZOOM_FACTOR:
9 case SLOT_MOUSE_GRAB:
10 main_widget->send(s, val);
11 return;
似乎会跑到这里
1 case SLOT_MOUSE_GRAB:
2 {
3 check_type<bool> (val, s);
4 bool grab = open_box<bool>(val);
5 if (grab && canvas() && !canvas()->hasFocus())
6 canvas()->setFocus (Qt::MouseFocusReason);
7 }
8 break;