From 1946632990b43c6c2726b0001eb47a059485e6ce Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Thu, 22 Jan 2026 14:36:45 +0800 Subject: [PATCH 01/27] =?UTF-8?q?=E7=AA=97=E5=8F=A3=E6=82=AC=E6=B5=AE?= =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/images/images.qrc | 22 ++ .../text-toolbar/align-center-white.svg | 8 + .../misc/images/text-toolbar/align-center.svg | 8 + .../text-toolbar/align-justify-white.svg | 8 + .../images/text-toolbar/align-justify.svg | 8 + .../images/text-toolbar/align-left-white.svg | 8 + .../misc/images/text-toolbar/align-left.svg | 8 + .../images/text-toolbar/align-right-white.svg | 8 + .../misc/images/text-toolbar/align-right.svg | 8 + .../misc/images/text-toolbar/bold-white.svg | 4 + TeXmacs/misc/images/text-toolbar/bold.svg | 4 + .../misc/images/text-toolbar/color-white.svg | 5 + TeXmacs/misc/images/text-toolbar/color.svg | 5 + .../images/text-toolbar/highlight-white.svg | 5 + .../misc/images/text-toolbar/highlight.svg | 5 + .../misc/images/text-toolbar/italic-white.svg | 4 + TeXmacs/misc/images/text-toolbar/italic.svg | 4 + .../images/text-toolbar/underline-white.svg | 4 + .../misc/images/text-toolbar/underline.svg | 4 + TeXmacs/misc/themes/liii-night.css | 62 ++++ TeXmacs/misc/themes/liii.css | 64 ++++ src/Edit/Interface/edit_interface.hpp | 6 + src/Edit/Interface/edit_mouse.cpp | 60 ++++ src/Plugins/Qt/QTMTextToolbar.cpp | 282 ++++++++++++++++++ src/Plugins/Qt/QTMTextToolbar.hpp | 71 +++++ src/Plugins/Qt/qt_simple_widget.cpp | 46 +++ src/Plugins/Qt/qt_simple_widget.hpp | 10 + 27 files changed, 731 insertions(+) create mode 100644 TeXmacs/misc/images/text-toolbar/align-center-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/align-center.svg create mode 100644 TeXmacs/misc/images/text-toolbar/align-justify-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/align-justify.svg create mode 100644 TeXmacs/misc/images/text-toolbar/align-left-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/align-left.svg create mode 100644 TeXmacs/misc/images/text-toolbar/align-right-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/align-right.svg create mode 100644 TeXmacs/misc/images/text-toolbar/bold-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/bold.svg create mode 100644 TeXmacs/misc/images/text-toolbar/color-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/color.svg create mode 100644 TeXmacs/misc/images/text-toolbar/highlight-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/highlight.svg create mode 100644 TeXmacs/misc/images/text-toolbar/italic-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/italic.svg create mode 100644 TeXmacs/misc/images/text-toolbar/underline-white.svg create mode 100644 TeXmacs/misc/images/text-toolbar/underline.svg create mode 100644 src/Plugins/Qt/QTMTextToolbar.cpp create mode 100644 src/Plugins/Qt/QTMTextToolbar.hpp diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index eab0c22212..2c9d4e5d07 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -11,5 +11,27 @@ ocr-button/middle-align-white.svg ocr-button/right-align-white.svg ocr-button/ocr-white.svg + + + text-toolbar/bold.svg + text-toolbar/italic.svg + text-toolbar/underline.svg + text-toolbar/highlight.svg + text-toolbar/color.svg + text-toolbar/align-left.svg + text-toolbar/align-center.svg + text-toolbar/align-right.svg + text-toolbar/align-justify.svg + + + text-toolbar/bold-white.svg + text-toolbar/italic-white.svg + text-toolbar/underline-white.svg + text-toolbar/highlight-white.svg + text-toolbar/color-white.svg + text-toolbar/align-left-white.svg + text-toolbar/align-center-white.svg + text-toolbar/align-right-white.svg + text-toolbar/align-justify-white.svg \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-center-white.svg b/TeXmacs/misc/images/text-toolbar/align-center-white.svg new file mode 100644 index 0000000000..7c55d0603b --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-center-white.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-center.svg b/TeXmacs/misc/images/text-toolbar/align-center.svg new file mode 100644 index 0000000000..1ffc2c05b6 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-center.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-justify-white.svg b/TeXmacs/misc/images/text-toolbar/align-justify-white.svg new file mode 100644 index 0000000000..923a9ab5c0 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-justify-white.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-justify.svg b/TeXmacs/misc/images/text-toolbar/align-justify.svg new file mode 100644 index 0000000000..220a697ffe --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-justify.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-left-white.svg b/TeXmacs/misc/images/text-toolbar/align-left-white.svg new file mode 100644 index 0000000000..002d21b022 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-left-white.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-left.svg b/TeXmacs/misc/images/text-toolbar/align-left.svg new file mode 100644 index 0000000000..e63297a38a --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-left.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-right-white.svg b/TeXmacs/misc/images/text-toolbar/align-right-white.svg new file mode 100644 index 0000000000..a06c661af7 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-right-white.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-right.svg b/TeXmacs/misc/images/text-toolbar/align-right.svg new file mode 100644 index 0000000000..4cf62a85d8 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/align-right.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/bold-white.svg b/TeXmacs/misc/images/text-toolbar/bold-white.svg new file mode 100644 index 0000000000..e360c7a44c --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/bold-white.svg @@ -0,0 +1,4 @@ + + + B + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/bold.svg b/TeXmacs/misc/images/text-toolbar/bold.svg new file mode 100644 index 0000000000..8b01b4dc33 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/bold.svg @@ -0,0 +1,4 @@ + + + B + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/color-white.svg b/TeXmacs/misc/images/text-toolbar/color-white.svg new file mode 100644 index 0000000000..73c1f5621d --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/color-white.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/color.svg b/TeXmacs/misc/images/text-toolbar/color.svg new file mode 100644 index 0000000000..c20d08816d --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/color.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/highlight-white.svg b/TeXmacs/misc/images/text-toolbar/highlight-white.svg new file mode 100644 index 0000000000..6d257a72ba --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/highlight-white.svg @@ -0,0 +1,5 @@ + + + + A + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/highlight.svg b/TeXmacs/misc/images/text-toolbar/highlight.svg new file mode 100644 index 0000000000..309d263c0d --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/highlight.svg @@ -0,0 +1,5 @@ + + + + A + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/italic-white.svg b/TeXmacs/misc/images/text-toolbar/italic-white.svg new file mode 100644 index 0000000000..73f816eb30 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/italic-white.svg @@ -0,0 +1,4 @@ + + + I + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/italic.svg b/TeXmacs/misc/images/text-toolbar/italic.svg new file mode 100644 index 0000000000..e2835547c6 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/italic.svg @@ -0,0 +1,4 @@ + + + I + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/underline-white.svg b/TeXmacs/misc/images/text-toolbar/underline-white.svg new file mode 100644 index 0000000000..6e987ff225 --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/underline-white.svg @@ -0,0 +1,4 @@ + + + U + \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/underline.svg b/TeXmacs/misc/images/text-toolbar/underline.svg new file mode 100644 index 0000000000..4dab8fa2eb --- /dev/null +++ b/TeXmacs/misc/images/text-toolbar/underline.svg @@ -0,0 +1,4 @@ + + + U + \ No newline at end of file diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index 5f41f33eec..47c9cc988e 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -873,3 +873,65 @@ QWidget#centralWidget QWidget { background: #202020; color: #ffffff; } + +/*文本工具栏窗口样式*/ +QWidget#text_toolbar { + background: #333333; + border: none; + border-radius: 8px; +} + +/*文本工具栏按钮图标*/ +QToolButton#text-toolbar-button[icon-name="bold"] { + qproperty-icon: url(":/text-toolbar/bold-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="italic"] { + qproperty-icon: url(":/text-toolbar/italic-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="underline"] { + qproperty-icon: url(":/text-toolbar/underline-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="highlight"] { + qproperty-icon: url(":/text-toolbar/highlight-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="color"] { + qproperty-icon: url(":/text-toolbar/color-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-left"] { + qproperty-icon: url(":/text-toolbar/align-left-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-center"] { + qproperty-icon: url(":/text-toolbar/align-center-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-right"] { + qproperty-icon: url(":/text-toolbar/align-right-white.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-justify"] { + qproperty-icon: url(":/text-toolbar/align-justify-white.svg"); +} + +/*文本工具栏按钮样式*/ +QToolButton#text-toolbar-button { + background-color: transparent; + border: none; +} + +/*文本工具栏按钮悬停样式*/ +QToolButton#text-toolbar-button:hover { + background-color: rgba(255, 255, 255, 0.1); + border: none; +} + +/*文本工具栏按钮按下样式*/ +QToolButton#text-toolbar-button:pressed { + background-color: rgba(255, 255, 255, 0.2); + border: none; +} diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 823770835e..a39010f472 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -850,3 +850,67 @@ QWidget#auxiliary_container { #guestNotificationCloseButton:pressed { background-color: rgba(0, 0, 0, 0.2); } + +/*文本工具栏窗口样式*/ + +/*文本工具栏窗口样式*/ +QWidget#text_toolbar { + background: #ffffff; + border: none; + border-radius: 8px; +} + +/*文本工具栏按钮图标*/ +QToolButton#text-toolbar-button[icon-name="bold"] { + qproperty-icon: url(":/text-toolbar/bold.svg"); +} + +QToolButton#text-toolbar-button[icon-name="italic"] { + qproperty-icon: url(":/text-toolbar/italic.svg"); +} + +QToolButton#text-toolbar-button[icon-name="underline"] { + qproperty-icon: url(":/text-toolbar/underline.svg"); +} + +QToolButton#text-toolbar-button[icon-name="highlight"] { + qproperty-icon: url(":/text-toolbar/highlight.svg"); +} + +QToolButton#text-toolbar-button[icon-name="color"] { + qproperty-icon: url(":/text-toolbar/color.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-left"] { + qproperty-icon: url(":/text-toolbar/align-left.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-center"] { + qproperty-icon: url(":/text-toolbar/align-center.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-right"] { + qproperty-icon: url(":/text-toolbar/align-right.svg"); +} + +QToolButton#text-toolbar-button[icon-name="align-justify"] { + qproperty-icon: url(":/text-toolbar/align-justify.svg"); +} + +/*文本工具栏按钮样式*/ +QToolButton#text-toolbar-button { + background-color: transparent; + border: none; +} + +/*文本工具栏按钮悬停样式*/ +QToolButton#text-toolbar-button:hover { + background-color: rgba(128, 128, 128, 0.3); + border: none; +} + +/*文本工具栏按钮按下样式*/ +QToolButton#text-toolbar-button:pressed { + background-color: rgba(128, 128, 128, 0.5); + border: none; +} diff --git a/src/Edit/Interface/edit_interface.hpp b/src/Edit/Interface/edit_interface.hpp index 2f99a1ee0d..6491f89a01 100644 --- a/src/Edit/Interface/edit_interface.hpp +++ b/src/Edit/Interface/edit_interface.hpp @@ -237,6 +237,12 @@ class edit_interface_rep : virtual public editor_rep { void update_mouse_loci (); void update_focus_loci (); bool should_show_image_popup (tree t); + bool should_show_text_toolbar (); + rectangle get_text_selection_rect (); + void show_text_toolbar (rectangle selr, double magf, + int scroll_x, int scroll_y, int canvas_x, + int canvas_y); + void hide_text_toolbar (); /* the footer */ tree compute_text_footer (tree st); diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index 7f9b9feefa..293e43b6b5 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -25,6 +25,7 @@ #include "sys_utils.hpp" #include "tm_buffer.hpp" #include "tm_timer.hpp" +#include "qt_simple_widget.hpp" #include #include @@ -780,10 +781,23 @@ edit_interface_rep::mouse_any (string type, SI x, SI y, int mods, time_t t, show_image_popup (tree_of_image_parent, selr, magf, get_scroll_x (), get_scroll_y (), get_canvas_x (), get_canvas_y ()); } + hide_text_toolbar (); } else { set_cursor_style ("normal"); hide_image_popup (); + + // 检查是否应该显示文本工具栏 + if (should_show_text_toolbar ()) { + rectangle text_selr= get_text_selection_rect (); + // 检查矩形是否有效(非零面积) + if (text_selr->x1 < text_selr->x2 && text_selr->y1 < text_selr->y2) { + show_text_toolbar (text_selr, magf, get_scroll_x (), + get_scroll_y (), get_canvas_x (), get_canvas_y ()); + } + } else { + hide_text_toolbar (); + } } if (type == "move") mouse_message ("move", x, y); @@ -1014,3 +1028,49 @@ edit_interface_rep::handle_mouse (string kind, SI x, SI y, int m, time_t t, } handle_exceptions (); } + +/****************************************************************************** + * Text toolbar support + ******************************************************************************/ + +bool +edit_interface_rep::should_show_text_toolbar () { + // 检查是否有活动的文本选区 + if (!selection_active_any ()) return false; + + // 检查选区是否非空 + tree sel_tree= selection_get (); + if (is_atomic (sel_tree) && as_string (sel_tree) == "") return false; + + return true; +} + +rectangle +edit_interface_rep::get_text_selection_rect () { + rectangle sel_rect; + + if (selection_active_any () && !is_nil (selection_rects)) { + // 使用现有的选区矩形 + sel_rect= least_upper_bound (selection_rects); + } + + return sel_rect; +} + +void +edit_interface_rep::show_text_toolbar (rectangle selr, double magf, + int scroll_x, int scroll_y, int canvas_x, + int canvas_y) { + // 通过qt_simple_widget显示文本工具栏 + // this指针实际上是edit_interface_rep,它继承自editor_rep,而editor_rep继承自simple_widget_rep + // 在Qt环境下,simple_widget_rep实际上是qt_simple_widget_rep + qt_simple_widget_rep* qsw= static_cast (this); + qsw->show_text_toolbar (selr, magf, scroll_x, scroll_y, canvas_x, canvas_y); +} + +void +edit_interface_rep::hide_text_toolbar () { + // 通过qt_simple_widget隐藏文本工具栏 + qt_simple_widget_rep* qsw= static_cast (this); + qsw->hide_text_toolbar (); +} diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp new file mode 100644 index 0000000000..2c1e90565f --- /dev/null +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -0,0 +1,282 @@ +/****************************************************************************** + * MODULE : QTMTextToolbar.cpp + * DESCRIPTION: Text selection toolbar popup widget implementation + * COPYRIGHT : (C) 2025 + ******************************************************************************* + * This software falls under the GNU general public license version 3 or later. + * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE + * in the root directory or . + ******************************************************************************/ + +#include "QTMTextToolbar.hpp" +#include "bitmap_font.hpp" +#include "qbuttongroup.h" +#include "qt_renderer.hpp" +#include "qt_utilities.hpp" +#include "scheme.hpp" +#include "server.hpp" +#include "tm_ostream.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +// 悬浮工具栏创建函数 +QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) + : QWidget (parent), owner (owner), layout (nullptr), cached_selection_mid_x (0), + cached_selection_mid_y (0), cached_scroll_x (0), cached_scroll_y (0), + cached_canvas_x (0), cached_canvas_y (0), cached_magf (0.0), + painted (false), painted_count (0) { + Q_INIT_RESOURCE (images); + setObjectName ("text_toolbar"); + setWindowFlags (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + setAttribute (Qt::WA_ShowWithoutActivating); + setMouseTracking (true); + setFocusPolicy (Qt::NoFocus); + layout= new QHBoxLayout (this); + layout->setContentsMargins (0, 0, 0, 0); + layout->setSizeConstraint (QLayout::SetMinimumSize); + layout->setSpacing (1); + setLayout (layout); + + // 添加阴影效果 + QGraphicsDropShadowEffect* effect= new QGraphicsDropShadowEffect (this); + effect->setBlurRadius (40); + effect->setOffset (0, 4); + effect->setColor (QColor (0, 0, 0, 120)); + this->setGraphicsEffect (effect); + + // 创建按钮 + boldBtn= new QToolButton (); + boldBtn->setObjectName ("text-toolbar-button"); + boldBtn->setProperty ("icon-name", "bold"); + boldBtn->setCheckable (true); + boldBtn->setToolTip (qt_translate ("Bold")); + + italicBtn= new QToolButton (); + italicBtn->setObjectName ("text-toolbar-button"); + italicBtn->setProperty ("icon-name", "italic"); + italicBtn->setCheckable (true); + italicBtn->setToolTip (qt_translate ("Italic")); + + underlineBtn= new QToolButton (); + underlineBtn->setObjectName ("text-toolbar-button"); + underlineBtn->setProperty ("icon-name", "underline"); + underlineBtn->setCheckable (true); + underlineBtn->setToolTip (qt_translate ("Underline")); + + highlightBtn= new QToolButton (); + highlightBtn->setObjectName ("text-toolbar-button"); + highlightBtn->setProperty ("icon-name", "highlight"); + highlightBtn->setCheckable (true); + highlightBtn->setToolTip (qt_translate ("Highlight")); + + colorBtn= new QToolButton (); + colorBtn->setObjectName ("text-toolbar-button"); + colorBtn->setProperty ("icon-name", "color"); + colorBtn->setCheckable (false); + colorBtn->setToolTip (qt_translate ("Text color")); + + alignLeftBtn= new QToolButton (); + alignLeftBtn->setObjectName ("text-toolbar-button"); + alignLeftBtn->setProperty ("icon-name", "align-left"); + alignLeftBtn->setCheckable (true); + alignLeftBtn->setToolTip (qt_translate ("Align left")); + + alignCenterBtn= new QToolButton (); + alignCenterBtn->setObjectName ("text-toolbar-button"); + alignCenterBtn->setProperty ("icon-name", "align-center"); + alignCenterBtn->setCheckable (true); + alignCenterBtn->setToolTip (qt_translate ("Align center")); + + alignRightBtn= new QToolButton (); + alignRightBtn->setObjectName ("text-toolbar-button"); + alignRightBtn->setProperty ("icon-name", "align-right"); + alignRightBtn->setCheckable (true); + alignRightBtn->setToolTip (qt_translate ("Align right")); + + alignJustifyBtn= new QToolButton (); + alignJustifyBtn->setObjectName ("text-toolbar-button"); + alignJustifyBtn->setProperty ("icon-name", "align-justify"); + alignJustifyBtn->setCheckable (true); + alignJustifyBtn->setToolTip (qt_translate ("Justify")); + + // 添加按钮到布局 + layout->addWidget (boldBtn); + layout->addWidget (italicBtn); + layout->addWidget (underlineBtn); + layout->addWidget (highlightBtn); + layout->addWidget (colorBtn); + layout->addWidget (alignLeftBtn); + layout->addWidget (alignCenterBtn); + layout->addWidget (alignRightBtn); + layout->addWidget (alignJustifyBtn); + + // 连接按钮点击事件(暂时只显示,不实现功能) + connect (boldBtn, &QToolButton::clicked, this, []() { + // TODO: 实现加粗功能 + }); + connect (italicBtn, &QToolButton::clicked, this, []() { + // TODO: 实现斜体功能 + }); + connect (underlineBtn, &QToolButton::clicked, this, []() { + // TODO: 实现下划线功能 + }); + connect (highlightBtn, &QToolButton::clicked, this, []() { + // TODO: 实现高亮功能 + }); + connect (colorBtn, &QToolButton::clicked, this, []() { + // TODO: 实现文字颜色功能 + }); + + // 对齐按钮分组 + QButtonGroup* alignGroup= new QButtonGroup (this); + alignGroup->addButton (alignLeftBtn); + alignGroup->addButton (alignCenterBtn); + alignGroup->addButton (alignRightBtn); + alignGroup->addButton (alignJustifyBtn); + alignGroup->setExclusive (true); + + connect (alignGroup, + QOverload::of (&QButtonGroup::buttonClicked), this, + [=] (QAbstractButton* button) { + // TODO: 实现对齐功能 + }); + + autoSize (); +} + +QTMTextToolbar::~QTMTextToolbar () {} + +void +QTMTextToolbar::showTextToolbar (qt_renderer_rep* ren, rectangle selr, double magf, + int scroll_x, int scroll_y, int canvas_x, int canvas_y) { + cachePosition (selr, magf, scroll_x, scroll_y, canvas_x, canvas_y); + updatePosition (ren); + show (); + raise (); +} + +void +QTMTextToolbar::updatePosition (qt_renderer_rep* ren) { + int x, y; + getCachedPosition (ren, x, y); + move (x, y); +} + +void +QTMTextToolbar::scrollBy (int x, int y) { + cached_scroll_x+= x; + cached_scroll_y+= y; +} + +void +QTMTextToolbar::cachePosition (rectangle selr, double magf, int scroll_x, int scroll_y, + int canvas_x, int canvas_y) { + cached_rect = selr; + cached_magf = magf; + cached_scroll_x = scroll_x; + cached_scroll_y = scroll_y; + cached_canvas_x = canvas_x; + cached_canvas_y = canvas_y; + + // 计算选区中心位置 + cached_selection_mid_x= (selr->x1 + selr->x2) * 0.5; + cached_selection_mid_y= selr->y2; // 使用选区底部位置,使工具栏显示在选中文字正上方 +} + +void +QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { + rectangle selr = cached_rect; + double inv_unit = 1.0 / 256.0; + double cx_logic = (selr->x1 + selr->x2) * 0.5; + double top_logic= selr->y2; // 使用选区底部位置,使工具栏显示在选中文字正上方 + + // 使用公式计算QT坐标 + double cx_px= + ((cx_logic - cached_scroll_x) * cached_magf + cached_canvas_x) * inv_unit; + double top_px= -(top_logic - cached_scroll_y) * cached_magf * inv_unit; + + // 修正:视口 > 表面:存在空白顶部 + double blank_top= 0.0; + if (owner && owner->scrollarea () && owner->scrollarea ()->viewport () && + owner->scrollarea ()->surface ()) { + int vp_h = owner->scrollarea ()->viewport ()->height (); + int surf_h= owner->scrollarea ()->surface ()->height (); + if (vp_h > surf_h) blank_top= (vp_h - surf_h) * 0.5; + } + top_px+= blank_top; + + x= int (std::round (cx_px - cached_width * 0.5)); + y= int (std::round (top_px - cached_height)); // 在选区底部上方显示,与图片悬浮窗口一致 + + // 确保工具栏在视口内 + if (x < 0) x= 0; + if (y < 0) y= int (std::round (top_px + 10)); // 如果上面空间不够,显示在选区下方 + if (owner && owner->scrollarea () && owner->scrollarea ()->viewport ()) { + int vp_w= owner->scrollarea ()->viewport ()->width (); + int vp_h= owner->scrollarea ()->viewport ()->height (); + if (x + cached_width > vp_w) x= vp_w - cached_width; + if (y + cached_height > vp_h) y= vp_h - cached_height; + } +} + +void +QTMTextToolbar::autoSize () { + // 根据DPI和缩放因子自动调整大小 + QScreen* Screen = QGuiApplication::primaryScreen (); + const double Dpi = Screen ? Screen->logicalDotsPerInch () : 96.0; + const double Scale = Dpi / 96.0; + const double totalScale= Scale * cached_magf * 3.0; + int btn_size; + +#if defined(Q_OS_MAC) + btn_size= int (50 * totalScale); +#else + btn_size= int (40 * totalScale); +#endif + + if (cached_magf <= 0.16) { + btn_size= 25; + } + + // 设置按钮大小 + QSize icon_size (btn_size, btn_size); + boldBtn->setIconSize (icon_size); + italicBtn->setIconSize (icon_size); + underlineBtn->setIconSize (icon_size); + highlightBtn->setIconSize (icon_size); + colorBtn->setIconSize (icon_size); + alignLeftBtn->setIconSize (icon_size); + alignCenterBtn->setIconSize (icon_size); + alignRightBtn->setIconSize (icon_size); + alignJustifyBtn->setIconSize (icon_size); + + // 设置按钮固定大小 + QSize fixed_size (btn_size + 8, btn_size + 8); + boldBtn->setFixedSize (fixed_size); + italicBtn->setFixedSize (fixed_size); + underlineBtn->setFixedSize (fixed_size); + highlightBtn->setFixedSize (fixed_size); + colorBtn->setFixedSize (fixed_size); + alignLeftBtn->setFixedSize (fixed_size); + alignCenterBtn->setFixedSize (fixed_size); + alignRightBtn->setFixedSize (fixed_size); + alignJustifyBtn->setFixedSize (fixed_size); + + // 调整窗口大小 + adjustSize (); + cached_width = width (); + cached_height= height (); +} + +bool +QTMTextToolbar::eventFilter (QObject* obj, QEvent* event) { + // 处理事件过滤 + return QWidget::eventFilter (obj, event); +} \ No newline at end of file diff --git a/src/Plugins/Qt/QTMTextToolbar.hpp b/src/Plugins/Qt/QTMTextToolbar.hpp new file mode 100644 index 0000000000..16795cb797 --- /dev/null +++ b/src/Plugins/Qt/QTMTextToolbar.hpp @@ -0,0 +1,71 @@ +/****************************************************************************** + * MODULE : QTMTextToolbar.hpp + * DESCRIPTION: Text selection toolbar popup widget + * COPYRIGHT : (C) 2025 + ******************************************************************************* + * This software falls under the GNU general public license version 3 or later. + * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE + * in the root directory or . + ******************************************************************************/ + +#ifndef QT_TEXT_TOOLBAR_HPP +#define QT_TEXT_TOOLBAR_HPP + +#include "qt_simple_widget.hpp" +#include "rectangles.hpp" + +#include +#include +#include +#include +#include +#include + +class QTMTextToolbar : public QWidget { +protected: + qt_simple_widget_rep* owner; + QHBoxLayout* layout; + QGraphicsDropShadowEffect* effect; + int cached_selection_mid_x; + int cached_selection_mid_y; + rectangle cached_rect; + int cached_scroll_x; // 页面滚动位置x + int cached_scroll_y; // 页面滚动位置y + int cached_canvas_x; + int cached_canvas_y; + int cached_width; + int cached_height; + double cached_magf; // 缩放因子 + bool painted; + int painted_count; + + // 工具栏按钮 + QToolButton* boldBtn; + QToolButton* italicBtn; + QToolButton* underlineBtn; + QToolButton* highlightBtn; + QToolButton* colorBtn; + QToolButton* alignLeftBtn; + QToolButton* alignCenterBtn; + QToolButton* alignRightBtn; + QToolButton* alignJustifyBtn; + QString btn_style; + +public: + QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner); + ~QTMTextToolbar (); + + void showTextToolbar (qt_renderer_rep* ren, rectangle selr, double magf, + int scroll_x, int scroll_y, int canvas_x, int canvas_y); + void updatePosition (qt_renderer_rep* ren); + void scrollBy (int x, int y); + void autoSize (); + +protected: + void cachePosition (rectangle selr, double magf, int scroll_x, int scroll_y, + int canvas_x, int canvas_y); + void getCachedPosition (qt_renderer_rep* ren, int& x, int& y); + bool eventFilter (QObject* obj, QEvent* event) override; +}; + +#endif // QT_TEXT_TOOLBAR_HPP \ No newline at end of file diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index 3774278a9e..5ef19df5cd 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -19,6 +19,7 @@ #include "QTMCompletionPopup.hpp" #include "QTMImagePopup.hpp" #include "QTMMathCompletionPopup.hpp" +#include "QTMTextToolbar.hpp" #include "QTMMenuHelper.hpp" #include "QTMStyle.hpp" #include "QTMWidget.hpp" @@ -789,4 +790,49 @@ qt_simple_widget_rep::scroll_image_popup_by (SI x, SI y) { qt_renderer_rep* ren= the_qt_renderer (); imagePopUp->updatePosition (ren); } +} + +/****************************************************************************** + * Text toolbar support + ******************************************************************************/ + +void +qt_simple_widget_rep::ensure_text_toolbar () { + if (!textToolbar && canvas ()) { + textToolbar= new QTMTextToolbar (canvas (), this); + if (is_empty (tm_style_sheet)) { + textToolbar->setStyle (qtmstyle ()); + } + } +} + +void +qt_simple_widget_rep::show_text_toolbar (rectangle selr, double magf, + int scroll_x, int scroll_y, int canvas_x, + int canvas_y) { + ensure_text_toolbar (); + qt_renderer_rep* ren= the_qt_renderer (); + textToolbar->showTextToolbar (ren, selr, magf, scroll_x, scroll_y, canvas_x, + canvas_y); +} + +void +qt_simple_widget_rep::hide_text_toolbar () { + if (textToolbar) { + textToolbar->hide (); + textToolbar->setParent (nullptr); + textToolbar->deleteLater (); + textToolbar= nullptr; + } +} + +void +qt_simple_widget_rep::scroll_text_toolbar_by (SI x, SI y) { + if (textToolbar) { + QPoint qp (x, y); + coord2 p= from_qpoint (qp); + textToolbar->scrollBy (p.x1, p.x2); + qt_renderer_rep* ren= the_qt_renderer (); + textToolbar->updatePosition (ren); + } } \ No newline at end of file diff --git a/src/Plugins/Qt/qt_simple_widget.hpp b/src/Plugins/Qt/qt_simple_widget.hpp index 99fb02d199..0b2ce236e3 100644 --- a/src/Plugins/Qt/qt_simple_widget.hpp +++ b/src/Plugins/Qt/qt_simple_widget.hpp @@ -24,6 +24,7 @@ class QTMCompletionPopup; class QTMMathCompletionPopup; class QTMImagePopup; +class QTMTextToolbar; /*! A widget containing a TeXmacs canvas. @@ -121,6 +122,14 @@ class qt_simple_widget_rep : public qt_widget_rep { void hide_image_popup (); void scroll_image_popup_by (SI x, SI y); + ////////////////////// Text toolbar support + void ensure_text_toolbar (); + void show_text_toolbar (rectangle selr, double magf, + int scroll_x, int scroll_y, int canvas_x, + int canvas_y); + void hide_text_toolbar (); + void scroll_text_toolbar_by (SI x, SI y); + ////////////////////// backing store management static void repaint_all (); // called by qt_gui_rep::update() @@ -131,6 +140,7 @@ class qt_simple_widget_rep : public qt_widget_rep { QPointer completionPopUp; QPointer mathCompletionPopUp; QPointer imagePopUp; + QPointer textToolbar; #ifdef USE_MUPDF_RENDERER double bs_zoomf; picture backing_store; From be002cab734f77ff1e6951d2d328d79868ef4f51 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Thu, 22 Jan 2026 22:15:04 +0800 Subject: [PATCH 02/27] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0,?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=E9=9C=80=E8=A6=81=E6=9B=B4=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/images/images.qrc | 16 +++---- TeXmacs/misc/themes/liii-night.css | 12 ++--- TeXmacs/misc/themes/liii.css | 12 ++--- src/Edit/Interface/edit_interface.cpp | 7 +++ src/Edit/Interface/edit_interface.hpp | 2 + src/Edit/Interface/edit_keyboard.cpp | 2 + src/Edit/Interface/edit_mouse.cpp | 63 ++++++++++++++++++++----- src/Plugins/Qt/QTMTextToolbar.cpp | 67 ++++++++++++++++----------- src/Plugins/Qt/QTMTextToolbar.hpp | 1 - src/Plugins/Qt/qt_simple_widget.cpp | 16 +++++++ src/Plugins/Qt/qt_simple_widget.hpp | 1 + 11 files changed, 139 insertions(+), 60 deletions(-) diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index 2c9d4e5d07..6e5691b8b1 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -18,10 +18,10 @@ text-toolbar/underline.svg text-toolbar/highlight.svg text-toolbar/color.svg - text-toolbar/align-left.svg - text-toolbar/align-center.svg - text-toolbar/align-right.svg - text-toolbar/align-justify.svg + ocr-button/left-align.svg + ocr-button/middle-align.svg + ocr-button/right-align.svg + text-toolbar/bold-white.svg @@ -29,9 +29,9 @@ text-toolbar/underline-white.svg text-toolbar/highlight-white.svg text-toolbar/color-white.svg - text-toolbar/align-left-white.svg - text-toolbar/align-center-white.svg - text-toolbar/align-right-white.svg - text-toolbar/align-justify-white.svg + ocr-button/left-align-white.svg + ocr-button/middle-align-white.svg + ocr-button/right-align-white.svg + \ No newline at end of file diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index 47c9cc988e..e7b63d2c17 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -902,16 +902,16 @@ QToolButton#text-toolbar-button[icon-name="color"] { qproperty-icon: url(":/text-toolbar/color-white.svg"); } -QToolButton#text-toolbar-button[icon-name="align-left"] { - qproperty-icon: url(":/text-toolbar/align-left-white.svg"); +QToolButton#text-toolbar-button[icon-name="left-align"] { + qproperty-icon: url(":/ocr-button/left-align-white.svg"); } -QToolButton#text-toolbar-button[icon-name="align-center"] { - qproperty-icon: url(":/text-toolbar/align-center-white.svg"); +QToolButton#text-toolbar-button[icon-name="middle-align"] { + qproperty-icon: url(":/ocr-button/middle-align-white.svg"); } -QToolButton#text-toolbar-button[icon-name="align-right"] { - qproperty-icon: url(":/text-toolbar/align-right-white.svg"); +QToolButton#text-toolbar-button[icon-name="right-align"] { + qproperty-icon: url(":/ocr-button/right-align-white.svg"); } QToolButton#text-toolbar-button[icon-name="align-justify"] { diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index a39010f472..53cb4a2250 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -881,16 +881,16 @@ QToolButton#text-toolbar-button[icon-name="color"] { qproperty-icon: url(":/text-toolbar/color.svg"); } -QToolButton#text-toolbar-button[icon-name="align-left"] { - qproperty-icon: url(":/text-toolbar/align-left.svg"); +QToolButton#text-toolbar-button[icon-name="left-align"] { + qproperty-icon: url(":/ocr-button/left-align.svg"); } -QToolButton#text-toolbar-button[icon-name="align-center"] { - qproperty-icon: url(":/text-toolbar/align-center.svg"); +QToolButton#text-toolbar-button[icon-name="middle-align"] { + qproperty-icon: url(":/ocr-button/middle-align.svg"); } -QToolButton#text-toolbar-button[icon-name="align-right"] { - qproperty-icon: url(":/text-toolbar/align-right.svg"); +QToolButton#text-toolbar-button[icon-name="right-align"] { + qproperty-icon: url(":/ocr-button/right-align.svg"); } QToolButton#text-toolbar-button[icon-name="align-justify"] { diff --git a/src/Edit/Interface/edit_interface.cpp b/src/Edit/Interface/edit_interface.cpp index 019c84c6e2..bd47322357 100644 --- a/src/Edit/Interface/edit_interface.cpp +++ b/src/Edit/Interface/edit_interface.cpp @@ -648,6 +648,11 @@ edit_interface_rep::notify_change (int change) { needs_update (); if ((change & (THE_TREE | THE_SELECTION | THE_CURSOR)) != 0) manual_focus_set (path (), (change & THE_TREE) != 0); + + // 当选区改变时,更新文本工具栏 + if ((change & THE_SELECTION) != 0) { + update_text_toolbar (); + } } bool @@ -990,6 +995,8 @@ edit_interface_rep::apply_changes () { selection_rects= rs; invalidate (selection_rects); } + // 选区改变后更新文本工具栏 + update_text_toolbar (); } // cout << "Handling alternative selection\n"; diff --git a/src/Edit/Interface/edit_interface.hpp b/src/Edit/Interface/edit_interface.hpp index 6491f89a01..5f6cc73dcb 100644 --- a/src/Edit/Interface/edit_interface.hpp +++ b/src/Edit/Interface/edit_interface.hpp @@ -243,6 +243,8 @@ class edit_interface_rep : virtual public editor_rep { int scroll_x, int scroll_y, int canvas_x, int canvas_y); void hide_text_toolbar (); + bool is_point_in_text_toolbar (SI x, SI y); + void update_text_toolbar (); /* the footer */ tree compute_text_footer (tree st); diff --git a/src/Edit/Interface/edit_keyboard.cpp b/src/Edit/Interface/edit_keyboard.cpp index 7997903d43..7bad5e2b22 100644 --- a/src/Edit/Interface/edit_keyboard.cpp +++ b/src/Edit/Interface/edit_keyboard.cpp @@ -487,6 +487,8 @@ edit_interface_rep::handle_keypress (string key_u8, time_t t) { if (!is_nil (focus_ids) && got_focus) call ("link-follow-ids", object (focus_ids), object ("focus")); notify_change (THE_DECORATIONS); + // 键盘事件后更新文本工具栏显示状态 + update_text_toolbar (); end_editing (); // time_t t2= texmacs_time (); // if (t2 - t1 >= 10) cout << "handle_keypress took " << t2-t1 << "ms\n"; diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index 293e43b6b5..6548b95a6b 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -788,16 +788,7 @@ edit_interface_rep::mouse_any (string type, SI x, SI y, int mods, time_t t, hide_image_popup (); // 检查是否应该显示文本工具栏 - if (should_show_text_toolbar ()) { - rectangle text_selr= get_text_selection_rect (); - // 检查矩形是否有效(非零面积) - if (text_selr->x1 < text_selr->x2 && text_selr->y1 < text_selr->y2) { - show_text_toolbar (text_selr, magf, get_scroll_x (), - get_scroll_y (), get_canvas_x (), get_canvas_y ()); - } - } else { - hide_text_toolbar (); - } + update_text_toolbar (); } if (type == "move") mouse_message ("move", x, y); @@ -895,8 +886,13 @@ edit_interface_rep::mouse_any (string type, SI x, SI y, int mods, time_t t, if ((type == "press-left") || (type == "release-left") || (type == "end-drag-left") || (type == "press-middle") || - (type == "press-right")) + (type == "press-right")) { + // 当用户点击其他地方(不在文本工具栏内)时,隐藏文本工具栏 + if (!is_point_in_text_toolbar (x, y)) { + hide_text_toolbar (); + } notify_change (THE_DECORATIONS); + } if (type == "wheel" && N (data) == 2) eval ("(wheel-event " * as_string (data[0]) * " " * as_string (data[1]) * @@ -1053,6 +1049,23 @@ edit_interface_rep::get_text_selection_rect () { // 使用现有的选区矩形 sel_rect= least_upper_bound (selection_rects); } + else if (selection_active_any ()) { + // 如果没有选区矩形,但选区存在,计算一个默认矩形 + path p1, p2; + selection_get (p1, p2); + if (p1 != p2) { + selection sel= search_selection (p1, p2); + if (!is_nil (sel->rs)) { + sel_rect= least_upper_bound (sel->rs); + } + else { + // 如果选区矩形为空,使用光标位置创建一个最小矩形 + cursor cu= get_cursor (); + sel_rect= rectangle (cu->ox - 10 * pixel, cu->oy - 5 * pixel, + cu->ox + 10 * pixel, cu->oy + 5 * pixel); + } + } + } return sel_rect; } @@ -1074,3 +1087,31 @@ edit_interface_rep::hide_text_toolbar () { qt_simple_widget_rep* qsw= static_cast (this); qsw->hide_text_toolbar (); } + +bool +edit_interface_rep::is_point_in_text_toolbar (SI x, SI y) { + // 通过qt_simple_widget检查点是否在文本工具栏内 + qt_simple_widget_rep* qsw= static_cast (this); + return qsw->is_point_in_text_toolbar (x, y); +} + +void +edit_interface_rep::update_text_toolbar () { + // 检查是否应该显示文本工具栏 + if (should_show_text_toolbar ()) { + rectangle text_selr= get_text_selection_rect (); + // 检查矩形是否有效(非零面积) + // 注意:rectangle 不是 list 类型,不能使用 is_nil + // 我们检查矩形坐标是否有效 + if (text_selr->x1 < text_selr->x2 && text_selr->y1 < text_selr->y2) { + show_text_toolbar (text_selr, magf, get_scroll_x (), + get_scroll_y (), get_canvas_x (), get_canvas_y ()); + } + else { + // 即使矩形无效,也尝试显示工具栏(例如单个字符选区) + hide_text_toolbar (); + } + } else { + hide_text_toolbar (); + } +} diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index 2c1e90565f..1aae630bf3 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -16,6 +16,7 @@ #include "scheme.hpp" #include "server.hpp" #include "tm_ostream.hpp" +#include "moebius/data/scheme.hpp" #include #include @@ -84,28 +85,22 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) alignLeftBtn= new QToolButton (); alignLeftBtn->setObjectName ("text-toolbar-button"); - alignLeftBtn->setProperty ("icon-name", "align-left"); + alignLeftBtn->setProperty ("icon-name", "left-align"); alignLeftBtn->setCheckable (true); alignLeftBtn->setToolTip (qt_translate ("Align left")); alignCenterBtn= new QToolButton (); alignCenterBtn->setObjectName ("text-toolbar-button"); - alignCenterBtn->setProperty ("icon-name", "align-center"); + alignCenterBtn->setProperty ("icon-name", "middle-align"); alignCenterBtn->setCheckable (true); alignCenterBtn->setToolTip (qt_translate ("Align center")); alignRightBtn= new QToolButton (); alignRightBtn->setObjectName ("text-toolbar-button"); - alignRightBtn->setProperty ("icon-name", "align-right"); + alignRightBtn->setProperty ("icon-name", "right-align"); alignRightBtn->setCheckable (true); alignRightBtn->setToolTip (qt_translate ("Align right")); - alignJustifyBtn= new QToolButton (); - alignJustifyBtn->setObjectName ("text-toolbar-button"); - alignJustifyBtn->setProperty ("icon-name", "align-justify"); - alignJustifyBtn->setCheckable (true); - alignJustifyBtn->setToolTip (qt_translate ("Justify")); - // 添加按钮到布局 layout->addWidget (boldBtn); layout->addWidget (italicBtn); @@ -115,23 +110,34 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) layout->addWidget (alignLeftBtn); layout->addWidget (alignCenterBtn); layout->addWidget (alignRightBtn); - layout->addWidget (alignJustifyBtn); - // 连接按钮点击事件(暂时只显示,不实现功能) - connect (boldBtn, &QToolButton::clicked, this, []() { - // TODO: 实现加粗功能 + // 连接按钮点击事件 + connect (boldBtn, &QToolButton::clicked, this, [this]() { + if (this->owner) { + call ("toggle-bold"); + } }); - connect (italicBtn, &QToolButton::clicked, this, []() { - // TODO: 实现斜体功能 + connect (italicBtn, &QToolButton::clicked, this, [this]() { + if (this->owner) { + call ("toggle-italic"); + } }); - connect (underlineBtn, &QToolButton::clicked, this, []() { - // TODO: 实现下划线功能 + connect (underlineBtn, &QToolButton::clicked, this, [this]() { + if (this->owner) { + call ("toggle-underlined"); + } }); - connect (highlightBtn, &QToolButton::clicked, this, []() { - // TODO: 实现高亮功能 + connect (highlightBtn, &QToolButton::clicked, this, [this]() { + if (this->owner) { + // 高亮功能 + call ("mark-text"); + } }); - connect (colorBtn, &QToolButton::clicked, this, []() { - // TODO: 实现文字颜色功能 + connect (colorBtn, &QToolButton::clicked, this, [this]() { + if (this->owner) { + // 文字颜色功能 - 打开颜色选择器 + call ("interactive", object ("open-color-selector")); + } }); // 对齐按钮分组 @@ -139,13 +145,20 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) alignGroup->addButton (alignLeftBtn); alignGroup->addButton (alignCenterBtn); alignGroup->addButton (alignRightBtn); - alignGroup->addButton (alignJustifyBtn); alignGroup->setExclusive (true); connect (alignGroup, QOverload::of (&QButtonGroup::buttonClicked), this, [=] (QAbstractButton* button) { - // TODO: 实现对齐功能 + if (this->owner) { + if (button == alignLeftBtn) { + call ("make-line-with", object ("par-mode"), object ("left")); + } else if (button == alignCenterBtn) { + call ("make-line-with", object ("par-mode"), object ("center")); + } else if (button == alignRightBtn) { + call ("make-line-with", object ("par-mode"), object ("right")); + } + } }); autoSize (); @@ -232,7 +245,7 @@ QTMTextToolbar::autoSize () { QScreen* Screen = QGuiApplication::primaryScreen (); const double Dpi = Screen ? Screen->logicalDotsPerInch () : 96.0; const double Scale = Dpi / 96.0; - const double totalScale= Scale * cached_magf * 3.0; + const double totalScale= Scale * cached_magf * 12.0; // 原始3.0倍,扩大4倍后为12.0倍 int btn_size; #if defined(Q_OS_MAC) @@ -255,10 +268,9 @@ QTMTextToolbar::autoSize () { alignLeftBtn->setIconSize (icon_size); alignCenterBtn->setIconSize (icon_size); alignRightBtn->setIconSize (icon_size); - alignJustifyBtn->setIconSize (icon_size); // 设置按钮固定大小 - QSize fixed_size (btn_size + 8, btn_size + 8); + QSize fixed_size (btn_size + 32, btn_size + 32); // 内边距也扩大4倍 (8 * 4.0 = 32) boldBtn->setFixedSize (fixed_size); italicBtn->setFixedSize (fixed_size); underlineBtn->setFixedSize (fixed_size); @@ -267,7 +279,6 @@ QTMTextToolbar::autoSize () { alignLeftBtn->setFixedSize (fixed_size); alignCenterBtn->setFixedSize (fixed_size); alignRightBtn->setFixedSize (fixed_size); - alignJustifyBtn->setFixedSize (fixed_size); // 调整窗口大小 adjustSize (); @@ -279,4 +290,4 @@ bool QTMTextToolbar::eventFilter (QObject* obj, QEvent* event) { // 处理事件过滤 return QWidget::eventFilter (obj, event); -} \ No newline at end of file +} diff --git a/src/Plugins/Qt/QTMTextToolbar.hpp b/src/Plugins/Qt/QTMTextToolbar.hpp index 16795cb797..6b1c12bb13 100644 --- a/src/Plugins/Qt/QTMTextToolbar.hpp +++ b/src/Plugins/Qt/QTMTextToolbar.hpp @@ -48,7 +48,6 @@ class QTMTextToolbar : public QWidget { QToolButton* alignLeftBtn; QToolButton* alignCenterBtn; QToolButton* alignRightBtn; - QToolButton* alignJustifyBtn; QString btn_style; public: diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index 5ef19df5cd..14e02108da 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -835,4 +835,20 @@ qt_simple_widget_rep::scroll_text_toolbar_by (SI x, SI y) { qt_renderer_rep* ren= the_qt_renderer (); textToolbar->updatePosition (ren); } +} + +bool +qt_simple_widget_rep::is_point_in_text_toolbar (SI x, SI y) { + if (!textToolbar) return false; + + // 将逻辑坐标转换为像素坐标 + double inv_unit = 1.0 / 256.0; + int px = int (std::round (x * inv_unit)); + int py = int (std::round (y * inv_unit)); + + // 获取工具栏的几何位置 + QRect toolbarRect = textToolbar->geometry(); + + // 检查点是否在工具栏内 + return toolbarRect.contains (px, py); } \ No newline at end of file diff --git a/src/Plugins/Qt/qt_simple_widget.hpp b/src/Plugins/Qt/qt_simple_widget.hpp index 0b2ce236e3..5bc1278792 100644 --- a/src/Plugins/Qt/qt_simple_widget.hpp +++ b/src/Plugins/Qt/qt_simple_widget.hpp @@ -129,6 +129,7 @@ class qt_simple_widget_rep : public qt_widget_rep { int canvas_y); void hide_text_toolbar (); void scroll_text_toolbar_by (SI x, SI y); + bool is_point_in_text_toolbar (SI x, SI y); ////////////////////// backing store management From d98f4109c4af224ae114ea12d7e0e0de890269e7 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 23 Jan 2026 17:11:05 +0800 Subject: [PATCH 03/27] =?UTF-8?q?=E5=9B=BE=E6=A0=87=E6=9B=B4=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/images/images.qrc | 16 ++++++++++++++++ TeXmacs/misc/themes/liii-night.css | 8 ++++---- TeXmacs/misc/themes/liii.css | 8 ++++---- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index 6e5691b8b1..1d657bd94f 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -22,6 +22,14 @@ ocr-button/middle-align.svg ocr-button/right-align.svg + + ../pixmaps/liii/20x20/mode/tm_bold.svg + ../pixmaps/liii/20x20/mode/tm_italic.svg + ../pixmaps/liii/20x20/mode/tm_underline.svg + ../pixmaps/liii/20x20/mode/tm_marked.svg + + + text-toolbar/bold-white.svg @@ -32,6 +40,14 @@ ocr-button/left-align-white.svg ocr-button/middle-align-white.svg ocr-button/right-align-white.svg + + + ../pixmaps/liii-night/20x20/mode/tm_bold.svg + ../pixmaps/liii-night/20x20/mode/tm_italic.svg + ../pixmaps/liii-night/20x20/mode/tm_underline.svg + ../pixmaps/liii-night/20x20/mode/tm_marked.svg + + \ No newline at end of file diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index e7b63d2c17..a71fc78574 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -883,19 +883,19 @@ QWidget#text_toolbar { /*文本工具栏按钮图标*/ QToolButton#text-toolbar-button[icon-name="bold"] { - qproperty-icon: url(":/text-toolbar/bold-white.svg"); + qproperty-icon: url(":/mode-toolbar/bold-white.svg"); } QToolButton#text-toolbar-button[icon-name="italic"] { - qproperty-icon: url(":/text-toolbar/italic-white.svg"); + qproperty-icon: url(":/mode-toolbar/italic-white.svg"); } QToolButton#text-toolbar-button[icon-name="underline"] { - qproperty-icon: url(":/text-toolbar/underline-white.svg"); + qproperty-icon: url(":/mode-toolbar/underline-white.svg"); } QToolButton#text-toolbar-button[icon-name="highlight"] { - qproperty-icon: url(":/text-toolbar/highlight-white.svg"); + qproperty-icon: url(":/mode-toolbar/highlight-white.svg"); } QToolButton#text-toolbar-button[icon-name="color"] { diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 53cb4a2250..24c1d2ac9c 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -862,19 +862,19 @@ QWidget#text_toolbar { /*文本工具栏按钮图标*/ QToolButton#text-toolbar-button[icon-name="bold"] { - qproperty-icon: url(":/text-toolbar/bold.svg"); + qproperty-icon: url(":/mode-toolbar/bold.svg"); } QToolButton#text-toolbar-button[icon-name="italic"] { - qproperty-icon: url(":/text-toolbar/italic.svg"); + qproperty-icon: url(":/mode-toolbar/italic.svg"); } QToolButton#text-toolbar-button[icon-name="underline"] { - qproperty-icon: url(":/text-toolbar/underline.svg"); + qproperty-icon: url(":/mode-toolbar/underline.svg"); } QToolButton#text-toolbar-button[icon-name="highlight"] { - qproperty-icon: url(":/text-toolbar/highlight.svg"); + qproperty-icon: url(":/mode-toolbar/highlight.svg"); } QToolButton#text-toolbar-button[icon-name="color"] { From 027b9f39e7122a52c3fcfeecbc40553f21475144 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 23 Jan 2026 17:29:08 +0800 Subject: [PATCH 04/27] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/images/images.qrc | 32 +++++++------------ .../text-toolbar/align-center-white.svg | 8 ----- .../misc/images/text-toolbar/align-center.svg | 8 ----- .../text-toolbar/align-justify-white.svg | 8 ----- .../images/text-toolbar/align-justify.svg | 8 ----- .../images/text-toolbar/align-left-white.svg | 8 ----- .../misc/images/text-toolbar/align-left.svg | 8 ----- .../images/text-toolbar/align-right-white.svg | 8 ----- .../misc/images/text-toolbar/align-right.svg | 8 ----- .../misc/images/text-toolbar/bold-white.svg | 4 --- TeXmacs/misc/images/text-toolbar/bold.svg | 4 --- .../misc/images/text-toolbar/color-white.svg | 5 --- TeXmacs/misc/images/text-toolbar/color.svg | 5 --- .../images/text-toolbar/highlight-white.svg | 5 --- .../misc/images/text-toolbar/highlight.svg | 5 --- .../misc/images/text-toolbar/italic-white.svg | 4 --- TeXmacs/misc/images/text-toolbar/italic.svg | 4 --- .../images/text-toolbar/underline-white.svg | 4 --- .../misc/images/text-toolbar/underline.svg | 4 --- TeXmacs/misc/themes/liii-night.css | 10 +++--- TeXmacs/misc/themes/liii.css | 10 +++--- 21 files changed, 22 insertions(+), 138 deletions(-) delete mode 100644 TeXmacs/misc/images/text-toolbar/align-center-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/align-center.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/align-justify-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/align-justify.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/align-left-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/align-left.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/align-right-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/align-right.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/bold-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/bold.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/color-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/color.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/highlight-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/highlight.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/italic-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/italic.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/underline-white.svg delete mode 100644 TeXmacs/misc/images/text-toolbar/underline.svg diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index 1d657bd94f..25b92dc7a4 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -13,39 +13,31 @@ ocr-button/ocr-white.svg - text-toolbar/bold.svg - text-toolbar/italic.svg - text-toolbar/underline.svg - text-toolbar/highlight.svg - text-toolbar/color.svg + ../pixmaps/liii/20x20/mode/tm_bold.svg + ../pixmaps/liii/20x20/mode/tm_italic.svg + ../pixmaps/liii/20x20/mode/tm_underline.svg + ../pixmaps/liii/20x20/mode/tm_marked.svg + ../pixmaps/liii/20x20/mode/tm_color.svg ocr-button/left-align.svg ocr-button/middle-align.svg ocr-button/right-align.svg - - ../pixmaps/liii/20x20/mode/tm_bold.svg - ../pixmaps/liii/20x20/mode/tm_italic.svg - ../pixmaps/liii/20x20/mode/tm_underline.svg - ../pixmaps/liii/20x20/mode/tm_marked.svg + - text-toolbar/bold-white.svg - text-toolbar/italic-white.svg - text-toolbar/underline-white.svg - text-toolbar/highlight-white.svg - text-toolbar/color-white.svg + ../pixmaps/liii-night/20x20/mode/tm_bold.svg + ../pixmaps/liii-night/20x20/mode/tm_italic.svg + ../pixmaps/liii-night/20x20/mode/tm_underline.svg + ../pixmaps/liii-night/20x20/mode/tm_marked.svg + ../pixmaps/liii-night/20x20/mode/tm_color.svg ocr-button/left-align-white.svg ocr-button/middle-align-white.svg ocr-button/right-align-white.svg - - ../pixmaps/liii-night/20x20/mode/tm_bold.svg - ../pixmaps/liii-night/20x20/mode/tm_italic.svg - ../pixmaps/liii-night/20x20/mode/tm_underline.svg - ../pixmaps/liii-night/20x20/mode/tm_marked.svg + diff --git a/TeXmacs/misc/images/text-toolbar/align-center-white.svg b/TeXmacs/misc/images/text-toolbar/align-center-white.svg deleted file mode 100644 index 7c55d0603b..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-center-white.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-center.svg b/TeXmacs/misc/images/text-toolbar/align-center.svg deleted file mode 100644 index 1ffc2c05b6..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-center.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-justify-white.svg b/TeXmacs/misc/images/text-toolbar/align-justify-white.svg deleted file mode 100644 index 923a9ab5c0..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-justify-white.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-justify.svg b/TeXmacs/misc/images/text-toolbar/align-justify.svg deleted file mode 100644 index 220a697ffe..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-justify.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-left-white.svg b/TeXmacs/misc/images/text-toolbar/align-left-white.svg deleted file mode 100644 index 002d21b022..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-left-white.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-left.svg b/TeXmacs/misc/images/text-toolbar/align-left.svg deleted file mode 100644 index e63297a38a..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-left.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-right-white.svg b/TeXmacs/misc/images/text-toolbar/align-right-white.svg deleted file mode 100644 index a06c661af7..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-right-white.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/align-right.svg b/TeXmacs/misc/images/text-toolbar/align-right.svg deleted file mode 100644 index 4cf62a85d8..0000000000 --- a/TeXmacs/misc/images/text-toolbar/align-right.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/bold-white.svg b/TeXmacs/misc/images/text-toolbar/bold-white.svg deleted file mode 100644 index e360c7a44c..0000000000 --- a/TeXmacs/misc/images/text-toolbar/bold-white.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - B - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/bold.svg b/TeXmacs/misc/images/text-toolbar/bold.svg deleted file mode 100644 index 8b01b4dc33..0000000000 --- a/TeXmacs/misc/images/text-toolbar/bold.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - B - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/color-white.svg b/TeXmacs/misc/images/text-toolbar/color-white.svg deleted file mode 100644 index 73c1f5621d..0000000000 --- a/TeXmacs/misc/images/text-toolbar/color-white.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/color.svg b/TeXmacs/misc/images/text-toolbar/color.svg deleted file mode 100644 index c20d08816d..0000000000 --- a/TeXmacs/misc/images/text-toolbar/color.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/highlight-white.svg b/TeXmacs/misc/images/text-toolbar/highlight-white.svg deleted file mode 100644 index 6d257a72ba..0000000000 --- a/TeXmacs/misc/images/text-toolbar/highlight-white.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - A - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/highlight.svg b/TeXmacs/misc/images/text-toolbar/highlight.svg deleted file mode 100644 index 309d263c0d..0000000000 --- a/TeXmacs/misc/images/text-toolbar/highlight.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - A - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/italic-white.svg b/TeXmacs/misc/images/text-toolbar/italic-white.svg deleted file mode 100644 index 73f816eb30..0000000000 --- a/TeXmacs/misc/images/text-toolbar/italic-white.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - I - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/italic.svg b/TeXmacs/misc/images/text-toolbar/italic.svg deleted file mode 100644 index e2835547c6..0000000000 --- a/TeXmacs/misc/images/text-toolbar/italic.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - I - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/underline-white.svg b/TeXmacs/misc/images/text-toolbar/underline-white.svg deleted file mode 100644 index 6e987ff225..0000000000 --- a/TeXmacs/misc/images/text-toolbar/underline-white.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - U - \ No newline at end of file diff --git a/TeXmacs/misc/images/text-toolbar/underline.svg b/TeXmacs/misc/images/text-toolbar/underline.svg deleted file mode 100644 index 4dab8fa2eb..0000000000 --- a/TeXmacs/misc/images/text-toolbar/underline.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - U - \ No newline at end of file diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index a71fc78574..21c50cd88d 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -883,23 +883,23 @@ QWidget#text_toolbar { /*文本工具栏按钮图标*/ QToolButton#text-toolbar-button[icon-name="bold"] { - qproperty-icon: url(":/mode-toolbar/bold-white.svg"); + qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_bold.svg"); } QToolButton#text-toolbar-button[icon-name="italic"] { - qproperty-icon: url(":/mode-toolbar/italic-white.svg"); + qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_italic.svg"); } QToolButton#text-toolbar-button[icon-name="underline"] { - qproperty-icon: url(":/mode-toolbar/underline-white.svg"); + qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_underline.svg"); } QToolButton#text-toolbar-button[icon-name="highlight"] { - qproperty-icon: url(":/mode-toolbar/highlight-white.svg"); + qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_marked.svg"); } QToolButton#text-toolbar-button[icon-name="color"] { - qproperty-icon: url(":/text-toolbar/color-white.svg"); + qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_color.svg"); } QToolButton#text-toolbar-button[icon-name="left-align"] { diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 24c1d2ac9c..967fa36e57 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -862,23 +862,23 @@ QWidget#text_toolbar { /*文本工具栏按钮图标*/ QToolButton#text-toolbar-button[icon-name="bold"] { - qproperty-icon: url(":/mode-toolbar/bold.svg"); + qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_bold.svg"); } QToolButton#text-toolbar-button[icon-name="italic"] { - qproperty-icon: url(":/mode-toolbar/italic.svg"); + qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_italic.svg"); } QToolButton#text-toolbar-button[icon-name="underline"] { - qproperty-icon: url(":/mode-toolbar/underline.svg"); + qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_underline.svg"); } QToolButton#text-toolbar-button[icon-name="highlight"] { - qproperty-icon: url(":/mode-toolbar/highlight.svg"); + qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_marked.svg"); } QToolButton#text-toolbar-button[icon-name="color"] { - qproperty-icon: url(":/text-toolbar/color.svg"); + qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_color.svg"); } QToolButton#text-toolbar-button[icon-name="left-align"] { From a07c9583bffd968a9ac60917f54a4473c70c9661 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 23 Jan 2026 17:33:33 +0800 Subject: [PATCH 05/27] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Edit/Interface/edit_interface.hpp | 5 +- src/Edit/Interface/edit_mouse.cpp | 17 +++--- src/Plugins/Qt/QTMTextToolbar.cpp | 82 +++++++++++++++------------ src/Plugins/Qt/QTMTextToolbar.hpp | 20 +++---- src/Plugins/Qt/qt_simple_widget.cpp | 16 +++--- src/Plugins/Qt/qt_simple_widget.hpp | 5 +- 6 files changed, 77 insertions(+), 68 deletions(-) diff --git a/src/Edit/Interface/edit_interface.hpp b/src/Edit/Interface/edit_interface.hpp index 5f6cc73dcb..f9e6524f19 100644 --- a/src/Edit/Interface/edit_interface.hpp +++ b/src/Edit/Interface/edit_interface.hpp @@ -239,9 +239,8 @@ class edit_interface_rep : virtual public editor_rep { bool should_show_image_popup (tree t); bool should_show_text_toolbar (); rectangle get_text_selection_rect (); - void show_text_toolbar (rectangle selr, double magf, - int scroll_x, int scroll_y, int canvas_x, - int canvas_y); + void show_text_toolbar (rectangle selr, double magf, int scroll_x, + int scroll_y, int canvas_x, int canvas_y); void hide_text_toolbar (); bool is_point_in_text_toolbar (SI x, SI y); void update_text_toolbar (); diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index 6548b95a6b..d40e93e500 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -21,11 +21,11 @@ #include "path.hpp" #include "qapplication.h" #include "qnamespace.h" +#include "qt_simple_widget.hpp" #include "scheme.hpp" #include "sys_utils.hpp" #include "tm_buffer.hpp" #include "tm_timer.hpp" -#include "qt_simple_widget.hpp" #include #include @@ -1061,8 +1061,8 @@ edit_interface_rep::get_text_selection_rect () { else { // 如果选区矩形为空,使用光标位置创建一个最小矩形 cursor cu= get_cursor (); - sel_rect= rectangle (cu->ox - 10 * pixel, cu->oy - 5 * pixel, - cu->ox + 10 * pixel, cu->oy + 5 * pixel); + sel_rect = rectangle (cu->ox - 10 * pixel, cu->oy - 5 * pixel, + cu->ox + 10 * pixel, cu->oy + 5 * pixel); } } } @@ -1072,8 +1072,8 @@ edit_interface_rep::get_text_selection_rect () { void edit_interface_rep::show_text_toolbar (rectangle selr, double magf, - int scroll_x, int scroll_y, int canvas_x, - int canvas_y) { + int scroll_x, int scroll_y, int canvas_x, + int canvas_y) { // 通过qt_simple_widget显示文本工具栏 // this指针实际上是edit_interface_rep,它继承自editor_rep,而editor_rep继承自simple_widget_rep // 在Qt环境下,simple_widget_rep实际上是qt_simple_widget_rep @@ -1104,14 +1104,15 @@ edit_interface_rep::update_text_toolbar () { // 注意:rectangle 不是 list 类型,不能使用 is_nil // 我们检查矩形坐标是否有效 if (text_selr->x1 < text_selr->x2 && text_selr->y1 < text_selr->y2) { - show_text_toolbar (text_selr, magf, get_scroll_x (), - get_scroll_y (), get_canvas_x (), get_canvas_y ()); + show_text_toolbar (text_selr, magf, get_scroll_x (), get_scroll_y (), + get_canvas_x (), get_canvas_y ()); } else { // 即使矩形无效,也尝试显示工具栏(例如单个字符选区) hide_text_toolbar (); } - } else { + } + else { hide_text_toolbar (); } } diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index 1aae630bf3..d20d3b81dd 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -10,13 +10,13 @@ #include "QTMTextToolbar.hpp" #include "bitmap_font.hpp" +#include "moebius/data/scheme.hpp" #include "qbuttongroup.h" #include "qt_renderer.hpp" #include "qt_utilities.hpp" #include "scheme.hpp" #include "server.hpp" #include "tm_ostream.hpp" -#include "moebius/data/scheme.hpp" #include #include @@ -29,10 +29,11 @@ // 悬浮工具栏创建函数 QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) - : QWidget (parent), owner (owner), layout (nullptr), cached_selection_mid_x (0), - cached_selection_mid_y (0), cached_scroll_x (0), cached_scroll_y (0), - cached_canvas_x (0), cached_canvas_y (0), cached_magf (0.0), - painted (false), painted_count (0) { + : QWidget (parent), owner (owner), layout (nullptr), + cached_selection_mid_x (0), cached_selection_mid_y (0), + cached_scroll_x (0), cached_scroll_y (0), cached_canvas_x (0), + cached_canvas_y (0), cached_magf (0.0), painted (false), + painted_count (0) { Q_INIT_RESOURCE (images); setObjectName ("text_toolbar"); setWindowFlags (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); @@ -112,28 +113,28 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) layout->addWidget (alignRightBtn); // 连接按钮点击事件 - connect (boldBtn, &QToolButton::clicked, this, [this]() { + connect (boldBtn, &QToolButton::clicked, this, [this] () { if (this->owner) { call ("toggle-bold"); } }); - connect (italicBtn, &QToolButton::clicked, this, [this]() { + connect (italicBtn, &QToolButton::clicked, this, [this] () { if (this->owner) { call ("toggle-italic"); } }); - connect (underlineBtn, &QToolButton::clicked, this, [this]() { + connect (underlineBtn, &QToolButton::clicked, this, [this] () { if (this->owner) { call ("toggle-underlined"); } }); - connect (highlightBtn, &QToolButton::clicked, this, [this]() { + connect (highlightBtn, &QToolButton::clicked, this, [this] () { if (this->owner) { // 高亮功能 call ("mark-text"); } }); - connect (colorBtn, &QToolButton::clicked, this, [this]() { + connect (colorBtn, &QToolButton::clicked, this, [this] () { if (this->owner) { // 文字颜色功能 - 打开颜色选择器 call ("interactive", object ("open-color-selector")); @@ -153,9 +154,12 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) if (this->owner) { if (button == alignLeftBtn) { call ("make-line-with", object ("par-mode"), object ("left")); - } else if (button == alignCenterBtn) { - call ("make-line-with", object ("par-mode"), object ("center")); - } else if (button == alignRightBtn) { + } + else if (button == alignCenterBtn) { + call ("make-line-with", object ("par-mode"), + object ("center")); + } + else if (button == alignRightBtn) { call ("make-line-with", object ("par-mode"), object ("right")); } } @@ -167,8 +171,9 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) QTMTextToolbar::~QTMTextToolbar () {} void -QTMTextToolbar::showTextToolbar (qt_renderer_rep* ren, rectangle selr, double magf, - int scroll_x, int scroll_y, int canvas_x, int canvas_y) { +QTMTextToolbar::showTextToolbar (qt_renderer_rep* ren, rectangle selr, + double magf, int scroll_x, int scroll_y, + int canvas_x, int canvas_y) { cachePosition (selr, magf, scroll_x, scroll_y, canvas_x, canvas_y); updatePosition (ren); show (); @@ -189,26 +194,27 @@ QTMTextToolbar::scrollBy (int x, int y) { } void -QTMTextToolbar::cachePosition (rectangle selr, double magf, int scroll_x, int scroll_y, - int canvas_x, int canvas_y) { - cached_rect = selr; - cached_magf = magf; - cached_scroll_x = scroll_x; - cached_scroll_y = scroll_y; - cached_canvas_x = canvas_x; - cached_canvas_y = canvas_y; +QTMTextToolbar::cachePosition (rectangle selr, double magf, int scroll_x, + int scroll_y, int canvas_x, int canvas_y) { + cached_rect = selr; + cached_magf = magf; + cached_scroll_x= scroll_x; + cached_scroll_y= scroll_y; + cached_canvas_x= canvas_x; + cached_canvas_y= canvas_y; // 计算选区中心位置 cached_selection_mid_x= (selr->x1 + selr->x2) * 0.5; - cached_selection_mid_y= selr->y2; // 使用选区底部位置,使工具栏显示在选中文字正上方 + cached_selection_mid_y= + selr->y2; // 使用选区底部位置,使工具栏显示在选中文字正上方 } void QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { - rectangle selr = cached_rect; - double inv_unit = 1.0 / 256.0; - double cx_logic = (selr->x1 + selr->x2) * 0.5; - double top_logic= selr->y2; // 使用选区底部位置,使工具栏显示在选中文字正上方 + rectangle selr = cached_rect; + double inv_unit= 1.0 / 256.0; + double cx_logic= (selr->x1 + selr->x2) * 0.5; + double top_logic= selr->y2; // 使用选区底部位置,使工具栏显示在选中文字正上方 // 使用公式计算QT坐标 double cx_px= @@ -226,11 +232,13 @@ QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { top_px+= blank_top; x= int (std::round (cx_px - cached_width * 0.5)); - y= int (std::round (top_px - cached_height)); // 在选区底部上方显示,与图片悬浮窗口一致 + y= int (std::round (top_px - + cached_height)); // 在选区底部上方显示,与图片悬浮窗口一致 // 确保工具栏在视口内 if (x < 0) x= 0; - if (y < 0) y= int (std::round (top_px + 10)); // 如果上面空间不够,显示在选区下方 + if (y < 0) + y= int (std::round (top_px + 10)); // 如果上面空间不够,显示在选区下方 if (owner && owner->scrollarea () && owner->scrollarea ()->viewport ()) { int vp_w= owner->scrollarea ()->viewport ()->width (); int vp_h= owner->scrollarea ()->viewport ()->height (); @@ -242,11 +250,12 @@ QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { void QTMTextToolbar::autoSize () { // 根据DPI和缩放因子自动调整大小 - QScreen* Screen = QGuiApplication::primaryScreen (); - const double Dpi = Screen ? Screen->logicalDotsPerInch () : 96.0; - const double Scale = Dpi / 96.0; - const double totalScale= Scale * cached_magf * 12.0; // 原始3.0倍,扩大4倍后为12.0倍 - int btn_size; + QScreen* Screen= QGuiApplication::primaryScreen (); + const double Dpi = Screen ? Screen->logicalDotsPerInch () : 96.0; + const double Scale = Dpi / 96.0; + const double totalScale= + Scale * cached_magf * 12.0; // 原始3.0倍,扩大4倍后为12.0倍 + int btn_size; #if defined(Q_OS_MAC) btn_size= int (50 * totalScale); @@ -270,7 +279,8 @@ QTMTextToolbar::autoSize () { alignRightBtn->setIconSize (icon_size); // 设置按钮固定大小 - QSize fixed_size (btn_size + 32, btn_size + 32); // 内边距也扩大4倍 (8 * 4.0 = 32) + QSize fixed_size (btn_size + 32, + btn_size + 32); // 内边距也扩大4倍 (8 * 4.0 = 32) boldBtn->setFixedSize (fixed_size); italicBtn->setFixedSize (fixed_size); underlineBtn->setFixedSize (fixed_size); diff --git a/src/Plugins/Qt/QTMTextToolbar.hpp b/src/Plugins/Qt/QTMTextToolbar.hpp index 6b1c12bb13..8b53c44792 100644 --- a/src/Plugins/Qt/QTMTextToolbar.hpp +++ b/src/Plugins/Qt/QTMTextToolbar.hpp @@ -40,22 +40,22 @@ class QTMTextToolbar : public QWidget { int painted_count; // 工具栏按钮 - QToolButton* boldBtn; - QToolButton* italicBtn; - QToolButton* underlineBtn; - QToolButton* highlightBtn; - QToolButton* colorBtn; - QToolButton* alignLeftBtn; - QToolButton* alignCenterBtn; - QToolButton* alignRightBtn; - QString btn_style; + QToolButton* boldBtn; + QToolButton* italicBtn; + QToolButton* underlineBtn; + QToolButton* highlightBtn; + QToolButton* colorBtn; + QToolButton* alignLeftBtn; + QToolButton* alignCenterBtn; + QToolButton* alignRightBtn; + QString btn_style; public: QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner); ~QTMTextToolbar (); void showTextToolbar (qt_renderer_rep* ren, rectangle selr, double magf, - int scroll_x, int scroll_y, int canvas_x, int canvas_y); + int scroll_x, int scroll_y, int canvas_x, int canvas_y); void updatePosition (qt_renderer_rep* ren); void scrollBy (int x, int y); void autoSize (); diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index 14e02108da..49a91eb023 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -19,9 +19,9 @@ #include "QTMCompletionPopup.hpp" #include "QTMImagePopup.hpp" #include "QTMMathCompletionPopup.hpp" -#include "QTMTextToolbar.hpp" #include "QTMMenuHelper.hpp" #include "QTMStyle.hpp" +#include "QTMTextToolbar.hpp" #include "QTMWidget.hpp" #include #include @@ -808,12 +808,12 @@ qt_simple_widget_rep::ensure_text_toolbar () { void qt_simple_widget_rep::show_text_toolbar (rectangle selr, double magf, - int scroll_x, int scroll_y, int canvas_x, - int canvas_y) { + int scroll_x, int scroll_y, + int canvas_x, int canvas_y) { ensure_text_toolbar (); qt_renderer_rep* ren= the_qt_renderer (); textToolbar->showTextToolbar (ren, selr, magf, scroll_x, scroll_y, canvas_x, - canvas_y); + canvas_y); } void @@ -842,12 +842,12 @@ qt_simple_widget_rep::is_point_in_text_toolbar (SI x, SI y) { if (!textToolbar) return false; // 将逻辑坐标转换为像素坐标 - double inv_unit = 1.0 / 256.0; - int px = int (std::round (x * inv_unit)); - int py = int (std::round (y * inv_unit)); + double inv_unit= 1.0 / 256.0; + int px = int (std::round (x * inv_unit)); + int py = int (std::round (y * inv_unit)); // 获取工具栏的几何位置 - QRect toolbarRect = textToolbar->geometry(); + QRect toolbarRect= textToolbar->geometry (); // 检查点是否在工具栏内 return toolbarRect.contains (px, py); diff --git a/src/Plugins/Qt/qt_simple_widget.hpp b/src/Plugins/Qt/qt_simple_widget.hpp index 5bc1278792..55c217229f 100644 --- a/src/Plugins/Qt/qt_simple_widget.hpp +++ b/src/Plugins/Qt/qt_simple_widget.hpp @@ -124,9 +124,8 @@ class qt_simple_widget_rep : public qt_widget_rep { ////////////////////// Text toolbar support void ensure_text_toolbar (); - void show_text_toolbar (rectangle selr, double magf, - int scroll_x, int scroll_y, int canvas_x, - int canvas_y); + void show_text_toolbar (rectangle selr, double magf, int scroll_x, + int scroll_y, int canvas_x, int canvas_y); void hide_text_toolbar (); void scroll_text_toolbar_by (SI x, SI y); bool is_point_in_text_toolbar (SI x, SI y); From be4ebe159f33ea1b34b7912d9ef5cf9cc90565df Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 23 Jan 2026 17:38:32 +0800 Subject: [PATCH 06/27] =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devel/201_63.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 devel/201_63.md diff --git a/devel/201_63.md b/devel/201_63.md new file mode 100644 index 0000000000..4270ba0783 --- /dev/null +++ b/devel/201_63.md @@ -0,0 +1,5 @@ +# [201_63] 文字选中悬浮窗口初步实现 + +## 如何测试 +1. 输入一段文字通过键盘或鼠标选中,会出现悬浮窗口 +2. 点击悬浮窗口按钮,实现的功能和模式工具栏一致,第五个按钮暂未实现 From e9964b73a9102eedd7f0520de2629c395240bd15 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 23 Jan 2026 17:40:36 +0800 Subject: [PATCH 07/27] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/images/images.qrc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index 25b92dc7a4..c2f7023c74 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -22,11 +22,6 @@ ocr-button/middle-align.svg ocr-button/right-align.svg - - - - - ../pixmaps/liii-night/20x20/mode/tm_bold.svg ../pixmaps/liii-night/20x20/mode/tm_italic.svg @@ -36,10 +31,6 @@ ocr-button/left-align-white.svg ocr-button/middle-align-white.svg ocr-button/right-align-white.svg - - - - \ No newline at end of file From 3206c1b7b3081afa86363763565c3e56b426215f Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 23 Jan 2026 19:51:27 +0800 Subject: [PATCH 08/27] =?UTF-8?q?=E6=9B=B4=E9=9A=8F=E7=A7=BB=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Plugins/Qt/QTMTextToolbar.cpp | 4 ++-- src/Plugins/Qt/QTMWidget.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index d20d3b81dd..849040eab3 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -189,8 +189,8 @@ QTMTextToolbar::updatePosition (qt_renderer_rep* ren) { void QTMTextToolbar::scrollBy (int x, int y) { - cached_scroll_x+= x; - cached_scroll_y+= y; + cached_scroll_x-= (int) (x / cached_magf); + cached_scroll_y-= (int) (y / cached_magf); } void diff --git a/src/Plugins/Qt/QTMWidget.cpp b/src/Plugins/Qt/QTMWidget.cpp index 78580a9568..1640c3ec2a 100644 --- a/src/Plugins/Qt/QTMWidget.cpp +++ b/src/Plugins/Qt/QTMWidget.cpp @@ -156,6 +156,7 @@ QTMWidget::scrollContentsBy (int dx, int dy) { tm_widget ()->scroll_completion_popup_by (dx, dy); tm_widget ()->scroll_math_completion_popup_by (dx, dy); tm_widget ()->scroll_image_popup_by (dx, dy); + tm_widget ()->scroll_text_toolbar_by (dx, dy); } void From a0461ab0c4f05b1e7ca451ddd4e2fcfdfbd31d25 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 30 Jan 2026 09:07:32 +0800 Subject: [PATCH 09/27] link color menu --- src/Plugins/Qt/QTMTextToolbar.cpp | 30 +++++- src/Plugins/Qt/color.md | 156 ++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 src/Plugins/Qt/color.md diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index 849040eab3..94a7901e4c 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -136,8 +136,34 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) }); connect (colorBtn, &QToolButton::clicked, this, [this] () { if (this->owner) { - // 文字颜色功能 - 打开颜色选择器 - call ("interactive", object ("open-color-selector")); + debug_std << "点击颜色按钮\n"; + + // 方案1:call("interactive", object("color-menu")) + // 编译通过,但可能不工作,因为 interactive 期望命令而不是菜单 + //debug_std << "尝试方案1: call(\"interactive\", object(\"color-menu\"))\n"; + //call ("interactive", object ("color-menu")); + + // 方案2:eval("(interactive color-menu)") + // 编译通过,但可能同样的问题 + // debug_std << "尝试方案2: eval(\"(interactive color-menu)\")\n"; + // eval ("(interactive color-menu)"); + + // 方案3:eval("(menu-popup (lambda () (link color-menu)) (gui-position))") + // 编译通过,尝试使用 menu-popup 函数 + // debug_std << "尝试方案3: menu-popup\n"; + //eval ("(menu-popup (lambda () (link color-menu)) (gui-position))"); + + // 方案4:eval("(show-context-menu (lambda () (link color-menu)) (gui-position))") + // 编译通过,尝试使用 show-context-menu 函数 + // debug_std << "尝试方案4: show-context-menu\n"; + // eval ("(show-context-menu (lambda () (link color-menu)) (gui-position))"); + + // 方案5:call("interactive-color", ...) + // 编译通过,提供基本的颜色选择功能 + // debug_std << "尝试方案5: interactive-color\n"; + // call ("interactive-color", + // object ("(lambda (col) (make-with \"color\" col))"), + // object ("()")); } }); diff --git a/src/Plugins/Qt/color.md b/src/Plugins/Qt/color.md new file mode 100644 index 0000000000..a8806d3df3 --- /dev/null +++ b/src/Plugins/Qt/color.md @@ -0,0 +1,156 @@ +文本模式工具栏中的选择前景色功能分析 + + 基于您提供的 color-menu 代码片段和我的分析,以下是文本模式工具栏中选择前景色功能的完整实现机制: + + 1. 调用链分析 + + 从工具栏按钮到颜色选择器的完整调用路径: + + 文本模式工具栏颜色按钮点击 + ↓ + text-format-icons 中的颜色按钮定义 (TeXmacs/progs/text/text-menu.scm:633-634) + ↓ + (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) + ↓ + color-menu 定义 (TeXmacs/progs/generic/format-menu.scm:73-82) + ↓ + (with setter (lambda (col) (make-with "color" col)) …) + ↓ + ("Palette" (interactive-color setter '())) + ↓ + interactive-color 函数 (TeXmacs/progs/kernel/gui/menu-widget.scm:1243-1250) + ↓ + widget-color-picker Scheme 函数 + ↓ + color_picker_widget C++ 函数 (src/Plugins/Qt/qt_widget.cpp:594-597) + ↓ + qt_color_picker_widget_rep C++ 类 (src/Plugins/Qt/qt_color_picker_widget.cpp) + ↓ + QColorDialog::getColor() Qt 原生颜色选择器 + + 2. color-menu 功能详解 + + 您提供的 color-menu 代码片段包含以下选项: + + (menu-bind color-menu + (with setter (lambda (col) (make-with "color" col)) + (if (allow-pattern-colors?) + (pick-background "" (setter answer))) + (if (not (allow-pattern-colors?)) + (pick-color (setter answer))) + ("Palette" (interactive-color setter '())) + (if (allow-pattern-colors?) + ("Pattern" (open-pattern-selector setter "1cm"))) + ("Other" (make-interactive-with "color")))) + + 各选项功能: + + 1. pick-background / pick-color - 快速颜色选择(预定义颜色网格) + 2. "Palette" - 打开完整的颜色选择器对话框 + 3. "Pattern" - 打开图案选择器(如果允许图案颜色) + 4. "Other" - 交互式颜色输入对话框 + + 3. 核心函数分析 + + make-with 函数 (src/Edit/Modify/edit_dynamic.cpp:414-421) + + void edit_dynamic_rep::make_with (string var, string val) { + if (selection_active_normal ()) { + tree t = remove_changes_in (selection_get (), var); + selection_cut (); + insert_tree (tree (WITH, var, val, t), path (2, end (t))); + } + else insert_tree (tree (WITH, var, val, ""), path (2, 0)); + } + 功能:创建 with 环境来设置文本属性 + - var = "color"(颜色属性) + - val = 颜色值(如 "#ff0000"、"red" 等) + - 如果有选区,将选区内容包装在 with 环境中 + - 如果没有选区,在当前光标位置插入 with 环境 + + interactive-color 函数 (TeXmacs/progs/kernel/gui/menu-widget.scm:1243-1250) + + (tm-define (interactive-color cmd proposals) + (:interactive #t) + (set! proposals (map tm->tree proposals)) + (if (not (qt-gui?)) + (interactive-rgb-picker cmd proposals) + (with p (lambda (com) (widget-color-picker com #f proposals)) + (with cmd* (lambda (t) (when t (cmd (tm->stree t)))) + (interactive-window p cmd* "Choose color"))))) + 功能:创建交互式颜色选择器 + - 如果是 Qt GUI,使用 widget-color-picker + - 否则使用 interactive-rgb-picker + - cmd 参数是回调函数(即 setter = (lambda (col) (make-with "color" col))) + + color_picker_widget 函数 (src/Plugins/Qt/qt_widget.cpp:594-597) + + widget color_picker_widget (command call_back, bool bg, array proposals) { + if (headless_mode) return headless_widget (); + return tm_new (call_back, bg, proposals); + } + + Qt 颜色选择器实现 (src/Plugins/Qt/qt_color_picker_widget.cpp:66-80) + + void qt_color_picker_widget_rep::showDialog () { + // … + QColor _sel = QColorDialog::getColor(Qt::white); + if (_sel.isValid ()) { + _commandAfterExecution (list_object (object (tree (from_qcolor (_sel))))); + } + } + 功能:调用 Qt 原生颜色选择对话框,将选择的颜色传递给回调函数 + + 4. 数据结构转换 + + 颜色数据的转换流程: + QColor (Qt 颜色对象) + ↓ from_qcolor() + string (颜色字符串,如 "#ff0000") + ↓ tree() + tree (TeXmacs 树结构) + ↓ object() + object (Scheme 对象) + ↓ list_object() + list_object (Scheme 列表对象) + ↓ _commandAfterExecution() + 执行回调函数 setter + ↓ (lambda (col) (make-with "color" col)) + make-with "color" col + ↓ 创建 with 环境设置文本颜色 + + 5. 在文本模式工具栏中的位置 + + 调用层级: + texmacs-mode-icons (主模式图标) + ↓ (if (in-text?) (link text-icons)) + text-icons (文本模式图标) + ↓ (link text-inline-icons) + text-inline-icons + ↓ (link text-format-icons) + text-format-icons (文本格式图标) + ↓ (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) + color-menu (颜色菜单) + + 6. 关键文件位置 + + 1. 颜色菜单定义:TeXmacs/progs/generic/format-menu.scm:73-82 + 2. 文本模式颜色按钮:TeXmacs/progs/text/text-menu.scm:633-634 + 3. 交互式颜色选择器:TeXmacs/progs/kernel/gui/menu-widget.scm:1243-1250 + 4. C++ make_with 实现:src/Edit/Modify/edit_dynamic.cpp:414-421 + 5. Qt 颜色选择器:src/Plugins/Qt/qt_color_picker_widget.cpp:66-80 + 6. 颜色选择器工厂函数:src/Plugins/Qt/qt_widget.cpp:594-597 + + 7. 工作流程总结 + + 1. 用户点击:在文本模式下点击工具栏中的颜色按钮(tm_color.xpm 图标) + 2. 菜单展开:显示 color-menu 子菜单 + 3. 选择"Palette":用户点击"Palette"选项 + 4. 打开颜色选择器:调用 interactive-color → widget-color-picker → color_picker_widget + 5. Qt 对话框:显示 Qt 原生颜色选择对话框 QColorDialog::getColor() + 6. 颜色选择:用户选择颜色并确认 + 7. 回调执行:颜色值通过回调链传递回 setter 函数 + 8. 应用颜色:make-with "color" col 创建 with 环境设置文本颜色 + 9. 文档更新:选中的文本或当前光标位置应用新的前景色 + + 这个机制展示了 TeXmacs 如何将 Scheme 配置、C++ 核心功能和 Qt GUI 组件紧密结合,提供了完整的颜色选择功能。 \ No newline at end of file From 4691fb554ad6d8790cbe7d5e7c07b210596cf977 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 11:17:52 +0800 Subject: [PATCH 10/27] =?UTF-8?q?scheme=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/progs/generic/text-toolbar.scm | 34 ++++ src/Plugins/Qt/QTMTextToolbar.cpp | 231 +++++++++---------------- src/Plugins/Qt/QTMTextToolbar.hpp | 17 +- 3 files changed, 116 insertions(+), 166 deletions(-) create mode 100644 TeXmacs/progs/generic/text-toolbar.scm diff --git a/TeXmacs/progs/generic/text-toolbar.scm b/TeXmacs/progs/generic/text-toolbar.scm new file mode 100644 index 0000000000..1da5a1545a --- /dev/null +++ b/TeXmacs/progs/generic/text-toolbar.scm @@ -0,0 +1,34 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MODULE : text-toolbar.scm +;; DESCRIPTION : text selection toolbar icons +;; COPYRIGHT : (C) 2026 +;; +;; This software falls under the GNU general public license version 3 or later. +;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE +;; in the root directory or . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(texmacs-module (generic text-toolbar) + (:use (generic format-edit) + (generic format-menu) + (generic generic-edit))) + +(menu-bind text-toolbar-icons + ((balloon (icon "tm_bold.xpm") "Write bold text") + (toggle-bold)) + ((balloon (icon "tm_italic.xpm") "Write italic text") + (toggle-italic)) + ((balloon (icon "tm_underline.xpm") "Write underline") + (toggle-underlined)) + ((balloon (icon "tm_marked.svg") "Marked text") + (mark-text)) + (=> (balloon (icon "tm_color.xpm") "Select a foreground color") + (link color-menu)) + ((balloon (icon "tm_align_left.xpm") "Align text to the left") + (make-line-with "par-mode" "left")) + ((balloon (icon "tm_align_center.xpm") "Center text") + (make-line-with "par-mode" "center")) + ((balloon (icon "tm_align_right.xpm") "Align text to the right") + (make-line-with "par-mode" "right"))) diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index 94a7901e4c..0364a79d6e 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -9,9 +9,10 @@ ******************************************************************************/ #include "QTMTextToolbar.hpp" +#include "QTMStyle.hpp" #include "bitmap_font.hpp" #include "moebius/data/scheme.hpp" -#include "qbuttongroup.h" +#include "object_l5.hpp" #include "qt_renderer.hpp" #include "qt_utilities.hpp" #include "scheme.hpp" @@ -19,12 +20,17 @@ #include "tm_ostream.hpp" #include +#include #include #include +#include #include #include #include +#include +#include #include +#include #include // 悬浮工具栏创建函数 @@ -53,149 +59,77 @@ QTMTextToolbar::QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner) effect->setColor (QColor (0, 0, 0, 120)); this->setGraphicsEffect (effect); - // 创建按钮 - boldBtn= new QToolButton (); - boldBtn->setObjectName ("text-toolbar-button"); - boldBtn->setProperty ("icon-name", "bold"); - boldBtn->setCheckable (true); - boldBtn->setToolTip (qt_translate ("Bold")); - - italicBtn= new QToolButton (); - italicBtn->setObjectName ("text-toolbar-button"); - italicBtn->setProperty ("icon-name", "italic"); - italicBtn->setCheckable (true); - italicBtn->setToolTip (qt_translate ("Italic")); - - underlineBtn= new QToolButton (); - underlineBtn->setObjectName ("text-toolbar-button"); - underlineBtn->setProperty ("icon-name", "underline"); - underlineBtn->setCheckable (true); - underlineBtn->setToolTip (qt_translate ("Underline")); - - highlightBtn= new QToolButton (); - highlightBtn->setObjectName ("text-toolbar-button"); - highlightBtn->setProperty ("icon-name", "highlight"); - highlightBtn->setCheckable (true); - highlightBtn->setToolTip (qt_translate ("Highlight")); - - colorBtn= new QToolButton (); - colorBtn->setObjectName ("text-toolbar-button"); - colorBtn->setProperty ("icon-name", "color"); - colorBtn->setCheckable (false); - colorBtn->setToolTip (qt_translate ("Text color")); - - alignLeftBtn= new QToolButton (); - alignLeftBtn->setObjectName ("text-toolbar-button"); - alignLeftBtn->setProperty ("icon-name", "left-align"); - alignLeftBtn->setCheckable (true); - alignLeftBtn->setToolTip (qt_translate ("Align left")); - - alignCenterBtn= new QToolButton (); - alignCenterBtn->setObjectName ("text-toolbar-button"); - alignCenterBtn->setProperty ("icon-name", "middle-align"); - alignCenterBtn->setCheckable (true); - alignCenterBtn->setToolTip (qt_translate ("Align center")); - - alignRightBtn= new QToolButton (); - alignRightBtn->setObjectName ("text-toolbar-button"); - alignRightBtn->setProperty ("icon-name", "right-align"); - alignRightBtn->setCheckable (true); - alignRightBtn->setToolTip (qt_translate ("Align right")); - - // 添加按钮到布局 - layout->addWidget (boldBtn); - layout->addWidget (italicBtn); - layout->addWidget (underlineBtn); - layout->addWidget (highlightBtn); - layout->addWidget (colorBtn); - layout->addWidget (alignLeftBtn); - layout->addWidget (alignCenterBtn); - layout->addWidget (alignRightBtn); - - // 连接按钮点击事件 - connect (boldBtn, &QToolButton::clicked, this, [this] () { - if (this->owner) { - call ("toggle-bold"); + rebuildButtonsFromScheme (); +} + +QTMTextToolbar::~QTMTextToolbar () {} + +void +QTMTextToolbar::clearButtons () { + if (!layout) return; + QLayoutItem* item= nullptr; + while ((item= layout->takeAt (0)) != nullptr) { + if (QWidget* w= item->widget ()) { + w->setParent (nullptr); + delete w; } - }); - connect (italicBtn, &QToolButton::clicked, this, [this] () { - if (this->owner) { - call ("toggle-italic"); + else if (QLayout* l= item->layout ()) { + delete l; } - }); - connect (underlineBtn, &QToolButton::clicked, this, [this] () { - if (this->owner) { - call ("toggle-underlined"); + delete item; + } +} + +void +QTMTextToolbar::rebuildButtonsFromScheme () { + eval ("(use-modules (generic text-toolbar))"); + object menu= eval ("'(horizontal (link text-toolbar-icons))"); + object obj = call ("make-menu-widget", menu, 0); + if (!is_widget (obj)) return; + + text_toolbar_widget= concrete (as_widget (obj)); + QList* list= text_toolbar_widget->get_qactionlist (); + if (!list) return; + + clearButtons (); + + for (int i= 0; i < list->count (); ++i) { + QAction* action= list->at (i); + if (!action) continue; + + if (action->isSeparator ()) { + QFrame* sep= new QFrame (this); + sep->setFrameShape (QFrame::VLine); + sep->setFrameShadow (QFrame::Plain); + sep->setFixedWidth (1); + sep->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Expanding); + layout->addWidget (sep); + continue; } - }); - connect (highlightBtn, &QToolButton::clicked, this, [this] () { - if (this->owner) { - // 高亮功能 - call ("mark-text"); + + if (action->text ().isNull () && action->icon ().isNull ()) { + layout->addSpacing (8); + continue; } - }); - connect (colorBtn, &QToolButton::clicked, this, [this] () { - if (this->owner) { - debug_std << "点击颜色按钮\n"; - - // 方案1:call("interactive", object("color-menu")) - // 编译通过,但可能不工作,因为 interactive 期望命令而不是菜单 - //debug_std << "尝试方案1: call(\"interactive\", object(\"color-menu\"))\n"; - //call ("interactive", object ("color-menu")); - - // 方案2:eval("(interactive color-menu)") - // 编译通过,但可能同样的问题 - // debug_std << "尝试方案2: eval(\"(interactive color-menu)\")\n"; - // eval ("(interactive color-menu)"); - - // 方案3:eval("(menu-popup (lambda () (link color-menu)) (gui-position))") - // 编译通过,尝试使用 menu-popup 函数 - // debug_std << "尝试方案3: menu-popup\n"; - //eval ("(menu-popup (lambda () (link color-menu)) (gui-position))"); - - // 方案4:eval("(show-context-menu (lambda () (link color-menu)) (gui-position))") - // 编译通过,尝试使用 show-context-menu 函数 - // debug_std << "尝试方案4: show-context-menu\n"; - // eval ("(show-context-menu (lambda () (link color-menu)) (gui-position))"); - - // 方案5:call("interactive-color", ...) - // 编译通过,提供基本的颜色选择功能 - // debug_std << "尝试方案5: interactive-color\n"; - // call ("interactive-color", - // object ("(lambda (col) (make-with \"color\" col))"), - // object ("()")); + + if (QWidgetAction* wa= qobject_cast (action)) { + QWidget* w= wa->requestWidget (this); + if (w) layout->addWidget (w); + continue; } - }); - - // 对齐按钮分组 - QButtonGroup* alignGroup= new QButtonGroup (this); - alignGroup->addButton (alignLeftBtn); - alignGroup->addButton (alignCenterBtn); - alignGroup->addButton (alignRightBtn); - alignGroup->setExclusive (true); - - connect (alignGroup, - QOverload::of (&QButtonGroup::buttonClicked), this, - [=] (QAbstractButton* button) { - if (this->owner) { - if (button == alignLeftBtn) { - call ("make-line-with", object ("par-mode"), object ("left")); - } - else if (button == alignCenterBtn) { - call ("make-line-with", object ("par-mode"), - object ("center")); - } - else if (button == alignRightBtn) { - call ("make-line-with", object ("par-mode"), object ("right")); - } - } - }); + + QToolButton* button= new QToolButton (this); + button->setObjectName ("text-toolbar-button"); + button->setAutoRaise (true); + button->setDefaultAction (action); + button->setPopupMode (QToolButton::InstantPopup); + if (tm_style_sheet == "") button->setStyle (qtmstyle ()); + layout->addWidget (button); + } autoSize (); } -QTMTextToolbar::~QTMTextToolbar () {} - void QTMTextToolbar::showTextToolbar (qt_renderer_rep* ren, rectangle selr, double magf, int scroll_x, int scroll_y, @@ -295,26 +229,17 @@ QTMTextToolbar::autoSize () { // 设置按钮大小 QSize icon_size (btn_size, btn_size); - boldBtn->setIconSize (icon_size); - italicBtn->setIconSize (icon_size); - underlineBtn->setIconSize (icon_size); - highlightBtn->setIconSize (icon_size); - colorBtn->setIconSize (icon_size); - alignLeftBtn->setIconSize (icon_size); - alignCenterBtn->setIconSize (icon_size); - alignRightBtn->setIconSize (icon_size); - - // 设置按钮固定大小 QSize fixed_size (btn_size + 32, btn_size + 32); // 内边距也扩大4倍 (8 * 4.0 = 32) - boldBtn->setFixedSize (fixed_size); - italicBtn->setFixedSize (fixed_size); - underlineBtn->setFixedSize (fixed_size); - highlightBtn->setFixedSize (fixed_size); - colorBtn->setFixedSize (fixed_size); - alignLeftBtn->setFixedSize (fixed_size); - alignCenterBtn->setFixedSize (fixed_size); - alignRightBtn->setFixedSize (fixed_size); + const QList buttons= + findChildren (QString (), Qt::FindChildrenRecursively); + for (QToolButton* button : buttons) { + if (!button) continue; + if (button->objectName ().isEmpty ()) + button->setObjectName ("text-toolbar-button"); + button->setIconSize (icon_size); + button->setFixedSize (fixed_size); + } // 调整窗口大小 adjustSize (); diff --git a/src/Plugins/Qt/QTMTextToolbar.hpp b/src/Plugins/Qt/QTMTextToolbar.hpp index 8b53c44792..622664abd4 100644 --- a/src/Plugins/Qt/QTMTextToolbar.hpp +++ b/src/Plugins/Qt/QTMTextToolbar.hpp @@ -18,7 +18,6 @@ #include #include #include -#include #include class QTMTextToolbar : public QWidget { @@ -38,17 +37,7 @@ class QTMTextToolbar : public QWidget { double cached_magf; // 缩放因子 bool painted; int painted_count; - - // 工具栏按钮 - QToolButton* boldBtn; - QToolButton* italicBtn; - QToolButton* underlineBtn; - QToolButton* highlightBtn; - QToolButton* colorBtn; - QToolButton* alignLeftBtn; - QToolButton* alignCenterBtn; - QToolButton* alignRightBtn; - QString btn_style; + qt_widget text_toolbar_widget; public: QTMTextToolbar (QWidget* parent, qt_simple_widget_rep* owner); @@ -64,7 +53,9 @@ class QTMTextToolbar : public QWidget { void cachePosition (rectangle selr, double magf, int scroll_x, int scroll_y, int canvas_x, int canvas_y); void getCachedPosition (qt_renderer_rep* ren, int& x, int& y); + void rebuildButtonsFromScheme (); + void clearButtons (); bool eventFilter (QObject* obj, QEvent* event) override; }; -#endif // QT_TEXT_TOOLBAR_HPP \ No newline at end of file +#endif // QT_TEXT_TOOLBAR_HPP From 25fc892df9673824ed49af4682727361b1cc8ec4 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 11:56:25 +0800 Subject: [PATCH 11/27] =?UTF-8?q?=E5=9B=BE=E6=A0=87=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liii-night/20x20/mode/left-align.svg | 8 ++++ .../liii-night/20x20/mode/middle-align.svg | 8 ++++ .../liii-night/20x20/mode/right-align.svg | 8 ++++ .../pixmaps/liii/20x20/mode/left-align.svg | 8 ++++ .../pixmaps/liii/20x20/mode/middle-align.svg | 8 ++++ .../pixmaps/liii/20x20/mode/right-align.svg | 8 ++++ TeXmacs/misc/themes/liii-night.css | 37 ------------------ TeXmacs/misc/themes/liii.css | 38 ------------------- TeXmacs/progs/generic/text-toolbar.scm | 6 +-- 9 files changed, 51 insertions(+), 78 deletions(-) create mode 100644 TeXmacs/misc/pixmaps/liii-night/20x20/mode/left-align.svg create mode 100644 TeXmacs/misc/pixmaps/liii-night/20x20/mode/middle-align.svg create mode 100644 TeXmacs/misc/pixmaps/liii-night/20x20/mode/right-align.svg create mode 100644 TeXmacs/misc/pixmaps/liii/20x20/mode/left-align.svg create mode 100644 TeXmacs/misc/pixmaps/liii/20x20/mode/middle-align.svg create mode 100644 TeXmacs/misc/pixmaps/liii/20x20/mode/right-align.svg diff --git a/TeXmacs/misc/pixmaps/liii-night/20x20/mode/left-align.svg b/TeXmacs/misc/pixmaps/liii-night/20x20/mode/left-align.svg new file mode 100644 index 0000000000..002d21b022 --- /dev/null +++ b/TeXmacs/misc/pixmaps/liii-night/20x20/mode/left-align.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/pixmaps/liii-night/20x20/mode/middle-align.svg b/TeXmacs/misc/pixmaps/liii-night/20x20/mode/middle-align.svg new file mode 100644 index 0000000000..7c55d0603b --- /dev/null +++ b/TeXmacs/misc/pixmaps/liii-night/20x20/mode/middle-align.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/pixmaps/liii-night/20x20/mode/right-align.svg b/TeXmacs/misc/pixmaps/liii-night/20x20/mode/right-align.svg new file mode 100644 index 0000000000..a06c661af7 --- /dev/null +++ b/TeXmacs/misc/pixmaps/liii-night/20x20/mode/right-align.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/pixmaps/liii/20x20/mode/left-align.svg b/TeXmacs/misc/pixmaps/liii/20x20/mode/left-align.svg new file mode 100644 index 0000000000..e63297a38a --- /dev/null +++ b/TeXmacs/misc/pixmaps/liii/20x20/mode/left-align.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/pixmaps/liii/20x20/mode/middle-align.svg b/TeXmacs/misc/pixmaps/liii/20x20/mode/middle-align.svg new file mode 100644 index 0000000000..1ffc2c05b6 --- /dev/null +++ b/TeXmacs/misc/pixmaps/liii/20x20/mode/middle-align.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/pixmaps/liii/20x20/mode/right-align.svg b/TeXmacs/misc/pixmaps/liii/20x20/mode/right-align.svg new file mode 100644 index 0000000000..4cf62a85d8 --- /dev/null +++ b/TeXmacs/misc/pixmaps/liii/20x20/mode/right-align.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/TeXmacs/misc/themes/liii-night.css b/TeXmacs/misc/themes/liii-night.css index 21c50cd88d..abb2220ff7 100644 --- a/TeXmacs/misc/themes/liii-night.css +++ b/TeXmacs/misc/themes/liii-night.css @@ -881,43 +881,6 @@ QWidget#text_toolbar { border-radius: 8px; } -/*文本工具栏按钮图标*/ -QToolButton#text-toolbar-button[icon-name="bold"] { - qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_bold.svg"); -} - -QToolButton#text-toolbar-button[icon-name="italic"] { - qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_italic.svg"); -} - -QToolButton#text-toolbar-button[icon-name="underline"] { - qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_underline.svg"); -} - -QToolButton#text-toolbar-button[icon-name="highlight"] { - qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_marked.svg"); -} - -QToolButton#text-toolbar-button[icon-name="color"] { - qproperty-icon: url(":/pixmaps/liii-night/20x20/mode/tm_color.svg"); -} - -QToolButton#text-toolbar-button[icon-name="left-align"] { - qproperty-icon: url(":/ocr-button/left-align-white.svg"); -} - -QToolButton#text-toolbar-button[icon-name="middle-align"] { - qproperty-icon: url(":/ocr-button/middle-align-white.svg"); -} - -QToolButton#text-toolbar-button[icon-name="right-align"] { - qproperty-icon: url(":/ocr-button/right-align-white.svg"); -} - -QToolButton#text-toolbar-button[icon-name="align-justify"] { - qproperty-icon: url(":/text-toolbar/align-justify-white.svg"); -} - /*文本工具栏按钮样式*/ QToolButton#text-toolbar-button { background-color: transparent; diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 967fa36e57..9df2c74d0d 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -852,7 +852,6 @@ QWidget#auxiliary_container { } /*文本工具栏窗口样式*/ - /*文本工具栏窗口样式*/ QWidget#text_toolbar { background: #ffffff; @@ -860,43 +859,6 @@ QWidget#text_toolbar { border-radius: 8px; } -/*文本工具栏按钮图标*/ -QToolButton#text-toolbar-button[icon-name="bold"] { - qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_bold.svg"); -} - -QToolButton#text-toolbar-button[icon-name="italic"] { - qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_italic.svg"); -} - -QToolButton#text-toolbar-button[icon-name="underline"] { - qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_underline.svg"); -} - -QToolButton#text-toolbar-button[icon-name="highlight"] { - qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_marked.svg"); -} - -QToolButton#text-toolbar-button[icon-name="color"] { - qproperty-icon: url(":/pixmaps/liii/20x20/mode/tm_color.svg"); -} - -QToolButton#text-toolbar-button[icon-name="left-align"] { - qproperty-icon: url(":/ocr-button/left-align.svg"); -} - -QToolButton#text-toolbar-button[icon-name="middle-align"] { - qproperty-icon: url(":/ocr-button/middle-align.svg"); -} - -QToolButton#text-toolbar-button[icon-name="right-align"] { - qproperty-icon: url(":/ocr-button/right-align.svg"); -} - -QToolButton#text-toolbar-button[icon-name="align-justify"] { - qproperty-icon: url(":/text-toolbar/align-justify.svg"); -} - /*文本工具栏按钮样式*/ QToolButton#text-toolbar-button { background-color: transparent; diff --git a/TeXmacs/progs/generic/text-toolbar.scm b/TeXmacs/progs/generic/text-toolbar.scm index 1da5a1545a..99770ba5cf 100644 --- a/TeXmacs/progs/generic/text-toolbar.scm +++ b/TeXmacs/progs/generic/text-toolbar.scm @@ -26,9 +26,9 @@ (mark-text)) (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) - ((balloon (icon "tm_align_left.xpm") "Align text to the left") + ((balloon (icon "left-align.xpm") "left") (make-line-with "par-mode" "left")) - ((balloon (icon "tm_align_center.xpm") "Center text") + ((balloon (icon "middle-align.xpm") "center") (make-line-with "par-mode" "center")) - ((balloon (icon "tm_align_right.xpm") "Align text to the right") + ((balloon (icon "right-align.xpm") "right") (make-line-with "par-mode" "right"))) From 440c206bb2e7a5de83af4938e6a3a4b9a153f04d Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 13:22:02 +0800 Subject: [PATCH 12/27] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/images/images.qrc | 20 ---- TeXmacs/misc/themes/liii.css | 1 - devel/201_63.md | 2 +- src/Plugins/Qt/QTMTextToolbar.cpp | 10 +- src/Plugins/Qt/color.md | 156 ------------------------------ 5 files changed, 6 insertions(+), 183 deletions(-) delete mode 100644 src/Plugins/Qt/color.md diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index c2f7023c74..3609a6851d 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -11,26 +11,6 @@ ocr-button/middle-align-white.svg ocr-button/right-align-white.svg ocr-button/ocr-white.svg - - - ../pixmaps/liii/20x20/mode/tm_bold.svg - ../pixmaps/liii/20x20/mode/tm_italic.svg - ../pixmaps/liii/20x20/mode/tm_underline.svg - ../pixmaps/liii/20x20/mode/tm_marked.svg - ../pixmaps/liii/20x20/mode/tm_color.svg - ocr-button/left-align.svg - ocr-button/middle-align.svg - ocr-button/right-align.svg - - - ../pixmaps/liii-night/20x20/mode/tm_bold.svg - ../pixmaps/liii-night/20x20/mode/tm_italic.svg - ../pixmaps/liii-night/20x20/mode/tm_underline.svg - ../pixmaps/liii-night/20x20/mode/tm_marked.svg - ../pixmaps/liii-night/20x20/mode/tm_color.svg - ocr-button/left-align-white.svg - ocr-button/middle-align-white.svg - ocr-button/right-align-white.svg \ No newline at end of file diff --git a/TeXmacs/misc/themes/liii.css b/TeXmacs/misc/themes/liii.css index 9df2c74d0d..109400fb2d 100644 --- a/TeXmacs/misc/themes/liii.css +++ b/TeXmacs/misc/themes/liii.css @@ -851,7 +851,6 @@ QWidget#auxiliary_container { background-color: rgba(0, 0, 0, 0.2); } -/*文本工具栏窗口样式*/ /*文本工具栏窗口样式*/ QWidget#text_toolbar { background: #ffffff; diff --git a/devel/201_63.md b/devel/201_63.md index 4270ba0783..a4e697cec3 100644 --- a/devel/201_63.md +++ b/devel/201_63.md @@ -2,4 +2,4 @@ ## 如何测试 1. 输入一段文字通过键盘或鼠标选中,会出现悬浮窗口 -2. 点击悬浮窗口按钮,实现的功能和模式工具栏一致,第五个按钮暂未实现 +2. 依次点击悬浮窗口按钮,实现的功能和模式工具栏一致 diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index 0364a79d6e..dc67eeeecf 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -19,8 +19,8 @@ #include "server.hpp" #include "tm_ostream.hpp" -#include #include +#include #include #include #include @@ -87,7 +87,7 @@ QTMTextToolbar::rebuildButtonsFromScheme () { object obj = call ("make-menu-widget", menu, 0); if (!is_widget (obj)) return; - text_toolbar_widget= concrete (as_widget (obj)); + text_toolbar_widget = concrete (as_widget (obj)); QList* list= text_toolbar_widget->get_qactionlist (); if (!list) return; @@ -228,9 +228,9 @@ QTMTextToolbar::autoSize () { } // 设置按钮大小 - QSize icon_size (btn_size, btn_size); - QSize fixed_size (btn_size + 32, - btn_size + 32); // 内边距也扩大4倍 (8 * 4.0 = 32) + QSize icon_size (btn_size, btn_size); + QSize fixed_size (btn_size + 32, + btn_size + 32); // 内边距也扩大4倍 (8 * 4.0 = 32) const QList buttons= findChildren (QString (), Qt::FindChildrenRecursively); for (QToolButton* button : buttons) { diff --git a/src/Plugins/Qt/color.md b/src/Plugins/Qt/color.md deleted file mode 100644 index a8806d3df3..0000000000 --- a/src/Plugins/Qt/color.md +++ /dev/null @@ -1,156 +0,0 @@ -文本模式工具栏中的选择前景色功能分析 - - 基于您提供的 color-menu 代码片段和我的分析,以下是文本模式工具栏中选择前景色功能的完整实现机制: - - 1. 调用链分析 - - 从工具栏按钮到颜色选择器的完整调用路径: - - 文本模式工具栏颜色按钮点击 - ↓ - text-format-icons 中的颜色按钮定义 (TeXmacs/progs/text/text-menu.scm:633-634) - ↓ - (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) - ↓ - color-menu 定义 (TeXmacs/progs/generic/format-menu.scm:73-82) - ↓ - (with setter (lambda (col) (make-with "color" col)) …) - ↓ - ("Palette" (interactive-color setter '())) - ↓ - interactive-color 函数 (TeXmacs/progs/kernel/gui/menu-widget.scm:1243-1250) - ↓ - widget-color-picker Scheme 函数 - ↓ - color_picker_widget C++ 函数 (src/Plugins/Qt/qt_widget.cpp:594-597) - ↓ - qt_color_picker_widget_rep C++ 类 (src/Plugins/Qt/qt_color_picker_widget.cpp) - ↓ - QColorDialog::getColor() Qt 原生颜色选择器 - - 2. color-menu 功能详解 - - 您提供的 color-menu 代码片段包含以下选项: - - (menu-bind color-menu - (with setter (lambda (col) (make-with "color" col)) - (if (allow-pattern-colors?) - (pick-background "" (setter answer))) - (if (not (allow-pattern-colors?)) - (pick-color (setter answer))) - ("Palette" (interactive-color setter '())) - (if (allow-pattern-colors?) - ("Pattern" (open-pattern-selector setter "1cm"))) - ("Other" (make-interactive-with "color")))) - - 各选项功能: - - 1. pick-background / pick-color - 快速颜色选择(预定义颜色网格) - 2. "Palette" - 打开完整的颜色选择器对话框 - 3. "Pattern" - 打开图案选择器(如果允许图案颜色) - 4. "Other" - 交互式颜色输入对话框 - - 3. 核心函数分析 - - make-with 函数 (src/Edit/Modify/edit_dynamic.cpp:414-421) - - void edit_dynamic_rep::make_with (string var, string val) { - if (selection_active_normal ()) { - tree t = remove_changes_in (selection_get (), var); - selection_cut (); - insert_tree (tree (WITH, var, val, t), path (2, end (t))); - } - else insert_tree (tree (WITH, var, val, ""), path (2, 0)); - } - 功能:创建 with 环境来设置文本属性 - - var = "color"(颜色属性) - - val = 颜色值(如 "#ff0000"、"red" 等) - - 如果有选区,将选区内容包装在 with 环境中 - - 如果没有选区,在当前光标位置插入 with 环境 - - interactive-color 函数 (TeXmacs/progs/kernel/gui/menu-widget.scm:1243-1250) - - (tm-define (interactive-color cmd proposals) - (:interactive #t) - (set! proposals (map tm->tree proposals)) - (if (not (qt-gui?)) - (interactive-rgb-picker cmd proposals) - (with p (lambda (com) (widget-color-picker com #f proposals)) - (with cmd* (lambda (t) (when t (cmd (tm->stree t)))) - (interactive-window p cmd* "Choose color"))))) - 功能:创建交互式颜色选择器 - - 如果是 Qt GUI,使用 widget-color-picker - - 否则使用 interactive-rgb-picker - - cmd 参数是回调函数(即 setter = (lambda (col) (make-with "color" col))) - - color_picker_widget 函数 (src/Plugins/Qt/qt_widget.cpp:594-597) - - widget color_picker_widget (command call_back, bool bg, array proposals) { - if (headless_mode) return headless_widget (); - return tm_new (call_back, bg, proposals); - } - - Qt 颜色选择器实现 (src/Plugins/Qt/qt_color_picker_widget.cpp:66-80) - - void qt_color_picker_widget_rep::showDialog () { - // … - QColor _sel = QColorDialog::getColor(Qt::white); - if (_sel.isValid ()) { - _commandAfterExecution (list_object (object (tree (from_qcolor (_sel))))); - } - } - 功能:调用 Qt 原生颜色选择对话框,将选择的颜色传递给回调函数 - - 4. 数据结构转换 - - 颜色数据的转换流程: - QColor (Qt 颜色对象) - ↓ from_qcolor() - string (颜色字符串,如 "#ff0000") - ↓ tree() - tree (TeXmacs 树结构) - ↓ object() - object (Scheme 对象) - ↓ list_object() - list_object (Scheme 列表对象) - ↓ _commandAfterExecution() - 执行回调函数 setter - ↓ (lambda (col) (make-with "color" col)) - make-with "color" col - ↓ 创建 with 环境设置文本颜色 - - 5. 在文本模式工具栏中的位置 - - 调用层级: - texmacs-mode-icons (主模式图标) - ↓ (if (in-text?) (link text-icons)) - text-icons (文本模式图标) - ↓ (link text-inline-icons) - text-inline-icons - ↓ (link text-format-icons) - text-format-icons (文本格式图标) - ↓ (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) - color-menu (颜色菜单) - - 6. 关键文件位置 - - 1. 颜色菜单定义:TeXmacs/progs/generic/format-menu.scm:73-82 - 2. 文本模式颜色按钮:TeXmacs/progs/text/text-menu.scm:633-634 - 3. 交互式颜色选择器:TeXmacs/progs/kernel/gui/menu-widget.scm:1243-1250 - 4. C++ make_with 实现:src/Edit/Modify/edit_dynamic.cpp:414-421 - 5. Qt 颜色选择器:src/Plugins/Qt/qt_color_picker_widget.cpp:66-80 - 6. 颜色选择器工厂函数:src/Plugins/Qt/qt_widget.cpp:594-597 - - 7. 工作流程总结 - - 1. 用户点击:在文本模式下点击工具栏中的颜色按钮(tm_color.xpm 图标) - 2. 菜单展开:显示 color-menu 子菜单 - 3. 选择"Palette":用户点击"Palette"选项 - 4. 打开颜色选择器:调用 interactive-color → widget-color-picker → color_picker_widget - 5. Qt 对话框:显示 Qt 原生颜色选择对话框 QColorDialog::getColor() - 6. 颜色选择:用户选择颜色并确认 - 7. 回调执行:颜色值通过回调链传递回 setter 函数 - 8. 应用颜色:make-with "color" col 创建 with 环境设置文本颜色 - 9. 文档更新:选中的文本或当前光标位置应用新的前景色 - - 这个机制展示了 TeXmacs 如何将 Scheme 配置、C++ 核心功能和 Qt GUI 组件紧密结合,提供了完整的颜色选择功能。 \ No newline at end of file From b6ba8f9cecb8de79888e03c3f732258c9eae74f5 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 13:23:13 +0800 Subject: [PATCH 13/27] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/misc/images/images.qrc | 1 - 1 file changed, 1 deletion(-) diff --git a/TeXmacs/misc/images/images.qrc b/TeXmacs/misc/images/images.qrc index 3609a6851d..eab0c22212 100644 --- a/TeXmacs/misc/images/images.qrc +++ b/TeXmacs/misc/images/images.qrc @@ -11,6 +11,5 @@ ocr-button/middle-align-white.svg ocr-button/right-align-white.svg ocr-button/ocr-white.svg - \ No newline at end of file From 42de5b09573cf4b055a9e2acf4e0a3b3239eb6f9 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 14:24:28 +0800 Subject: [PATCH 14/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/progs/generic/text-toolbar.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TeXmacs/progs/generic/text-toolbar.scm b/TeXmacs/progs/generic/text-toolbar.scm index 99770ba5cf..6df32c1c4f 100644 --- a/TeXmacs/progs/generic/text-toolbar.scm +++ b/TeXmacs/progs/generic/text-toolbar.scm @@ -26,9 +26,9 @@ (mark-text)) (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) - ((balloon (icon "left-align.xpm") "left") + ((balloon (icon "left-align.xpm") "left aligned") (make-line-with "par-mode" "left")) ((balloon (icon "middle-align.xpm") "center") (make-line-with "par-mode" "center")) - ((balloon (icon "right-align.xpm") "right") + ((balloon (icon "right-align.xpm") "right aligned") (make-line-with "par-mode" "right"))) From 9c63a7b29b1ea02154a19ba04416dadfa485ba24 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 17:14:34 +0800 Subject: [PATCH 15/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Edit/Interface/edit_interface.cpp | 5 ----- src/Edit/Interface/edit_mouse.cpp | 7 +++++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Edit/Interface/edit_interface.cpp b/src/Edit/Interface/edit_interface.cpp index bd47322357..afb6eb3d45 100644 --- a/src/Edit/Interface/edit_interface.cpp +++ b/src/Edit/Interface/edit_interface.cpp @@ -648,11 +648,6 @@ edit_interface_rep::notify_change (int change) { needs_update (); if ((change & (THE_TREE | THE_SELECTION | THE_CURSOR)) != 0) manual_focus_set (path (), (change & THE_TREE) != 0); - - // 当选区改变时,更新文本工具栏 - if ((change & THE_SELECTION) != 0) { - update_text_toolbar (); - } } bool diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index d40e93e500..bd856f43fe 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -884,8 +884,7 @@ edit_interface_rep::mouse_any (string type, SI x, SI y, int mods, time_t t, if (type == "press-up") mouse_scroll (x, y, true); if (type == "press-down") mouse_scroll (x, y, false); - if ((type == "press-left") || (type == "release-left") || - (type == "end-drag-left") || (type == "press-middle") || + if ((type == "press-left") || (type == "press-middle") || (type == "press-right")) { // 当用户点击其他地方(不在文本工具栏内)时,隐藏文本工具栏 if (!is_point_in_text_toolbar (x, y)) { @@ -1097,6 +1096,10 @@ edit_interface_rep::is_point_in_text_toolbar (SI x, SI y) { void edit_interface_rep::update_text_toolbar () { + if (left_dragging) { + hide_text_toolbar (); + return; + } // 检查是否应该显示文本工具栏 if (should_show_text_toolbar ()) { rectangle text_selr= get_text_selection_rect (); From 082549a860c5b7bc258353036c7cb4ea2d8b0b3c Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 17:25:28 +0800 Subject: [PATCH 16/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Plugins/Qt/qt_simple_widget.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index 49a91eb023..f9d322030d 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -47,6 +47,7 @@ qt_simple_widget_rep::~qt_simple_widget_rep () { if (backingPixmap != NULL) delete backingPixmap; #endif if (completionPopUp != nullptr) delete completionPopUp; + if (textToolbar != nullptr) delete textToolbar; } QWidget* @@ -820,9 +821,6 @@ void qt_simple_widget_rep::hide_text_toolbar () { if (textToolbar) { textToolbar->hide (); - textToolbar->setParent (nullptr); - textToolbar->deleteLater (); - textToolbar= nullptr; } } @@ -851,4 +849,4 @@ qt_simple_widget_rep::is_point_in_text_toolbar (SI x, SI y) { // 检查点是否在工具栏内 return toolbarRect.contains (px, py); -} \ No newline at end of file +} From dd0fae72fad90ff6d6edea77de2a5fa2a4f9e81b Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 17:51:14 +0800 Subject: [PATCH 17/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9hide=5Ftext=5Ftoolbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Plugins/Qt/qt_simple_widget.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index f9d322030d..585f491777 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -799,11 +799,16 @@ qt_simple_widget_rep::scroll_image_popup_by (SI x, SI y) { void qt_simple_widget_rep::ensure_text_toolbar () { - if (!textToolbar && canvas ()) { - textToolbar= new QTMTextToolbar (canvas (), this); - if (is_empty (tm_style_sheet)) { - textToolbar->setStyle (qtmstyle ()); + if (!canvas ()) return; + if (textToolbar) { + if (textToolbar->parent () != canvas ()) { + textToolbar->setParent (canvas ()); } + return; + } + textToolbar= new QTMTextToolbar (canvas (), this); + if (is_empty (tm_style_sheet)) { + textToolbar->setStyle (qtmstyle ()); } } @@ -821,6 +826,9 @@ void qt_simple_widget_rep::hide_text_toolbar () { if (textToolbar) { textToolbar->hide (); + //textToolbar->setParent (nullptr); + textToolbar->deleteLater (); + textToolbar= nullptr; } } From 5a0eedf1ee68ab4e966c4ff6d5d7aeba549eafc1 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 18:05:48 +0800 Subject: [PATCH 18/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9hide=5Ftext=5Ftoolbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Plugins/Qt/qt_simple_widget.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index 585f491777..61df5eb859 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -799,16 +799,11 @@ qt_simple_widget_rep::scroll_image_popup_by (SI x, SI y) { void qt_simple_widget_rep::ensure_text_toolbar () { - if (!canvas ()) return; - if (textToolbar) { - if (textToolbar->parent () != canvas ()) { - textToolbar->setParent (canvas ()); + if (!textToolbar && canvas ()) { + textToolbar= new QTMTextToolbar (canvas (), this); + if (is_empty (tm_style_sheet)) { + textToolbar->setStyle (qtmstyle ()); } - return; - } - textToolbar= new QTMTextToolbar (canvas (), this); - if (is_empty (tm_style_sheet)) { - textToolbar->setStyle (qtmstyle ()); } } From 0f7afe9380a8b223733701f120152923489586b6 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 18:16:15 +0800 Subject: [PATCH 19/27] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Plugins/Qt/qt_simple_widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index 61df5eb859..af0604deed 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -821,7 +821,7 @@ void qt_simple_widget_rep::hide_text_toolbar () { if (textToolbar) { textToolbar->hide (); - //textToolbar->setParent (nullptr); + // textToolbar->setParent (nullptr); textToolbar->deleteLater (); textToolbar= nullptr; } From b2266def675e79242c88a14214cfa98b8dead985 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 18:36:38 +0800 Subject: [PATCH 20/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9ensure=5Ftext=5Ftoolbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Plugins/Qt/qt_simple_widget.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Plugins/Qt/qt_simple_widget.cpp b/src/Plugins/Qt/qt_simple_widget.cpp index af0604deed..1c90e6cb48 100644 --- a/src/Plugins/Qt/qt_simple_widget.cpp +++ b/src/Plugins/Qt/qt_simple_widget.cpp @@ -799,11 +799,16 @@ qt_simple_widget_rep::scroll_image_popup_by (SI x, SI y) { void qt_simple_widget_rep::ensure_text_toolbar () { - if (!textToolbar && canvas ()) { - textToolbar= new QTMTextToolbar (canvas (), this); - if (is_empty (tm_style_sheet)) { - textToolbar->setStyle (qtmstyle ()); + if (!canvas ()) return; + if (textToolbar) { + if (textToolbar->parent () != canvas ()) { + textToolbar->setParent (canvas ()); } + return; + } + textToolbar= new QTMTextToolbar (canvas (), this); + if (is_empty (tm_style_sheet)) { + textToolbar->setStyle (qtmstyle ()); } } @@ -821,9 +826,6 @@ void qt_simple_widget_rep::hide_text_toolbar () { if (textToolbar) { textToolbar->hide (); - // textToolbar->setParent (nullptr); - textToolbar->deleteLater (); - textToolbar= nullptr; } } From 3c23f04d953cb8f623439f24f19bfb6e2479be4a Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 20:19:54 +0800 Subject: [PATCH 21/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Edit/Interface/edit_mouse.cpp | 11 +++++ src/Plugins/Qt/QTMTextToolbar.cpp | 81 ++++++++++++++++++++++++++++--- src/Plugins/Qt/QTMTextToolbar.hpp | 1 + src/Plugins/Qt/QTMWidget.cpp | 5 ++ 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index bd856f43fe..d647a8ae72 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -1107,6 +1107,17 @@ edit_interface_rep::update_text_toolbar () { // 注意:rectangle 不是 list 类型,不能使用 is_nil // 我们检查矩形坐标是否有效 if (text_selr->x1 < text_selr->x2 && text_selr->y1 < text_selr->y2) { + update_visible (); + SI sel_x1= min (text_selr->x1, text_selr->x2); + SI sel_x2= max (text_selr->x1, text_selr->x2); + SI sel_y1= min (text_selr->y1, text_selr->y2); + SI sel_y2= max (text_selr->y1, text_selr->y2); + bool sel_in_view= + !(sel_x2 < vx1 || sel_x1 > vx2 || sel_y2 < vy1 || sel_y1 > vy2); + if (!sel_in_view) { + hide_text_toolbar (); + return; + } show_text_toolbar (text_selr, magf, get_scroll_x (), get_scroll_y (), get_canvas_x (), get_canvas_y ()); } diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index dc67eeeecf..5f4c994cf4 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include // 悬浮工具栏创建函数 @@ -135,6 +136,10 @@ QTMTextToolbar::showTextToolbar (qt_renderer_rep* ren, rectangle selr, double magf, int scroll_x, int scroll_y, int canvas_x, int canvas_y) { cachePosition (selr, magf, scroll_x, scroll_y, canvas_x, canvas_y); + if (!selectionInView ()) { + hide (); + return; + } updatePosition (ren); show (); raise (); @@ -142,6 +147,10 @@ QTMTextToolbar::showTextToolbar (qt_renderer_rep* ren, rectangle selr, void QTMTextToolbar::updatePosition (qt_renderer_rep* ren) { + if (!selectionInView ()) { + hide (); + return; + } int x, y; getCachedPosition (ren, x, y); move (x, y); @@ -173,13 +182,17 @@ void QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { rectangle selr = cached_rect; double inv_unit= 1.0 / 256.0; - double cx_logic= (selr->x1 + selr->x2) * 0.5; - double top_logic= selr->y2; // 使用选区底部位置,使工具栏显示在选中文字正上方 + double cx_logic = (selr->x1 + selr->x2) * 0.5; + double sel_top_logic = (selr->y1 > selr->y2) ? selr->y1 : selr->y2; + double sel_bottom_logic= (selr->y1 > selr->y2) ? selr->y2 : selr->y1; // 使用公式计算QT坐标 double cx_px= ((cx_logic - cached_scroll_x) * cached_magf + cached_canvas_x) * inv_unit; - double top_px= -(top_logic - cached_scroll_y) * cached_magf * inv_unit; + double top_px= + -(sel_top_logic - cached_scroll_y) * cached_magf * inv_unit; + double bottom_px= + -(sel_bottom_logic - cached_scroll_y) * cached_magf * inv_unit; // 修正:视口 > 表面:存在空白顶部 double blank_top= 0.0; @@ -190,21 +203,73 @@ QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { if (vp_h > surf_h) blank_top= (vp_h - surf_h) * 0.5; } top_px+= blank_top; + bottom_px+= blank_top; + + const int above_y= + int (std::round (top_px - + cached_height-10)); // 在选区顶部上方显示 + const int below_y= + int (std::round (bottom_px + 10)); // 如果上面空间不够,显示在选区下方 x= int (std::round (cx_px - cached_width * 0.5)); - y= int (std::round (top_px - - cached_height)); // 在选区底部上方显示,与图片悬浮窗口一致 + y= above_y; // 确保工具栏在视口内 - if (x < 0) x= 0; - if (y < 0) - y= int (std::round (top_px + 10)); // 如果上面空间不够,显示在选区下方 if (owner && owner->scrollarea () && owner->scrollarea ()->viewport ()) { int vp_w= owner->scrollarea ()->viewport ()->width (); int vp_h= owner->scrollarea ()->viewport ()->height (); + + const bool above_fits= + (above_y >= 0) && (above_y + cached_height <= vp_h); + if (!above_fits) y= below_y; + + if (x < 0) x= 0; if (x + cached_width > vp_w) x= vp_w - cached_width; + if (y < 0) y= 0; if (y + cached_height > vp_h) y= vp_h - cached_height; } + else { + if (y < 0) y= below_y; + } +} + +bool +QTMTextToolbar::selectionInView () const { + if (!owner || !owner->scrollarea () || !owner->scrollarea ()->viewport ()) + return true; + + rectangle selr = cached_rect; + double inv_unit= 1.0 / 256.0; + + double x1_px= + ((selr->x1 - cached_scroll_x) * cached_magf + cached_canvas_x) * inv_unit; + double x2_px= + ((selr->x2 - cached_scroll_x) * cached_magf + cached_canvas_x) * inv_unit; + double y1_px= + -(selr->y1 - cached_scroll_y) * cached_magf * inv_unit; + double y2_px= + -(selr->y2 - cached_scroll_y) * cached_magf * inv_unit; + + double blank_top= 0.0; + if (owner->scrollarea ()->surface ()) { + int vp_h = owner->scrollarea ()->viewport ()->height (); + int surf_h= owner->scrollarea ()->surface ()->height (); + if (vp_h > surf_h) blank_top= (vp_h - surf_h) * 0.5; + } + y1_px+= blank_top; + y2_px+= blank_top; + + double left = std::min (x1_px, x2_px); + double right = std::max (x1_px, x2_px); + double top = std::min (y1_px, y2_px); + double bottom= std::max (y1_px, y2_px); + + int vp_w= owner->scrollarea ()->viewport ()->width (); + int vp_h= owner->scrollarea ()->viewport ()->height (); + + if (right < 0.0 || left > vp_w) return false; + if (bottom < 0.0 || top > vp_h) return false; + return true; } void diff --git a/src/Plugins/Qt/QTMTextToolbar.hpp b/src/Plugins/Qt/QTMTextToolbar.hpp index 622664abd4..d60e76c1ba 100644 --- a/src/Plugins/Qt/QTMTextToolbar.hpp +++ b/src/Plugins/Qt/QTMTextToolbar.hpp @@ -53,6 +53,7 @@ class QTMTextToolbar : public QWidget { void cachePosition (rectangle selr, double magf, int scroll_x, int scroll_y, int canvas_x, int canvas_y); void getCachedPosition (qt_renderer_rep* ren, int& x, int& y); + bool selectionInView () const; void rebuildButtonsFromScheme (); void clearButtons (); bool eventFilter (QObject* obj, QEvent* event) override; diff --git a/src/Plugins/Qt/QTMWidget.cpp b/src/Plugins/Qt/QTMWidget.cpp index 1640c3ec2a..7b8e0cb861 100644 --- a/src/Plugins/Qt/QTMWidget.cpp +++ b/src/Plugins/Qt/QTMWidget.cpp @@ -19,6 +19,7 @@ #include "qt_gui.hpp" #include "qt_simple_widget.hpp" #include "qt_utilities.hpp" +#include "edit_interface.hpp" #include "scheme.hpp" #include "sys_utils.hpp" #ifdef USE_MUPDF_RENDERER @@ -157,6 +158,10 @@ QTMWidget::scrollContentsBy (int dx, int dy) { tm_widget ()->scroll_math_completion_popup_by (dx, dy); tm_widget ()->scroll_image_popup_by (dx, dy); tm_widget ()->scroll_text_toolbar_by (dx, dy); + if (edit_interface_rep* ed= + dynamic_cast (tm_widget ())) { + ed->update_text_toolbar (); + } } void From bcd15911ce5fd9ec93b6a3446132af5dd51124af Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 20:39:25 +0800 Subject: [PATCH 22/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Edit/Interface/edit_mouse.cpp | 8 ++++---- src/Plugins/Qt/QTMTextToolbar.cpp | 34 ++++++++++++++++--------------- src/Plugins/Qt/QTMWidget.cpp | 2 +- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index d647a8ae72..03277fda74 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -1108,10 +1108,10 @@ edit_interface_rep::update_text_toolbar () { // 我们检查矩形坐标是否有效 if (text_selr->x1 < text_selr->x2 && text_selr->y1 < text_selr->y2) { update_visible (); - SI sel_x1= min (text_selr->x1, text_selr->x2); - SI sel_x2= max (text_selr->x1, text_selr->x2); - SI sel_y1= min (text_selr->y1, text_selr->y2); - SI sel_y2= max (text_selr->y1, text_selr->y2); + SI sel_x1= min (text_selr->x1, text_selr->x2); + SI sel_x2= max (text_selr->x1, text_selr->x2); + SI sel_y1= min (text_selr->y1, text_selr->y2); + SI sel_y2= max (text_selr->y1, text_selr->y2); bool sel_in_view= !(sel_x2 < vx1 || sel_x1 > vx2 || sel_y2 < vy1 || sel_y1 > vy2); if (!sel_in_view) { diff --git a/src/Plugins/Qt/QTMTextToolbar.cpp b/src/Plugins/Qt/QTMTextToolbar.cpp index 5f4c994cf4..18f2242c4b 100644 --- a/src/Plugins/Qt/QTMTextToolbar.cpp +++ b/src/Plugins/Qt/QTMTextToolbar.cpp @@ -180,17 +180,16 @@ QTMTextToolbar::cachePosition (rectangle selr, double magf, int scroll_x, void QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { - rectangle selr = cached_rect; - double inv_unit= 1.0 / 256.0; - double cx_logic = (selr->x1 + selr->x2) * 0.5; - double sel_top_logic = (selr->y1 > selr->y2) ? selr->y1 : selr->y2; - double sel_bottom_logic= (selr->y1 > selr->y2) ? selr->y2 : selr->y1; + rectangle selr = cached_rect; + double inv_unit = 1.0 / 256.0; + double cx_logic = (selr->x1 + selr->x2) * 0.5; + double sel_top_logic = (selr->y1 > selr->y2) ? selr->y1 : selr->y2; + double sel_bottom_logic= (selr->y1 > selr->y2) ? selr->y2 : selr->y1; // 使用公式计算QT坐标 double cx_px= ((cx_logic - cached_scroll_x) * cached_magf + cached_canvas_x) * inv_unit; - double top_px= - -(sel_top_logic - cached_scroll_y) * cached_magf * inv_unit; + double top_px= -(sel_top_logic - cached_scroll_y) * cached_magf * inv_unit; double bottom_px= -(sel_bottom_logic - cached_scroll_y) * cached_magf * inv_unit; @@ -206,8 +205,7 @@ QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { bottom_px+= blank_top; const int above_y= - int (std::round (top_px - - cached_height-10)); // 在选区顶部上方显示 + int (std::round (top_px - cached_height - 10)); // 在选区顶部上方显示 const int below_y= int (std::round (bottom_px + 10)); // 如果上面空间不够,显示在选区下方 @@ -219,9 +217,15 @@ QTMTextToolbar::getCachedPosition (qt_renderer_rep* ren, int& x, int& y) { int vp_w= owner->scrollarea ()->viewport ()->width (); int vp_h= owner->scrollarea ()->viewport ()->height (); - const bool above_fits= - (above_y >= 0) && (above_y + cached_height <= vp_h); - if (!above_fits) y= below_y; + const bool above_fits= (above_y >= 0) && (above_y + cached_height <= vp_h); + const bool below_fits= (below_y >= 0) && (below_y + cached_height <= vp_h); + + if (above_fits) y= above_y; + else if (below_fits) y= below_y; + else { + x= std::max (0, (vp_w - cached_width) / 2); + y= std::max (0, (vp_h - cached_height) / 2); + } if (x < 0) x= 0; if (x + cached_width > vp_w) x= vp_w - cached_width; @@ -245,10 +249,8 @@ QTMTextToolbar::selectionInView () const { ((selr->x1 - cached_scroll_x) * cached_magf + cached_canvas_x) * inv_unit; double x2_px= ((selr->x2 - cached_scroll_x) * cached_magf + cached_canvas_x) * inv_unit; - double y1_px= - -(selr->y1 - cached_scroll_y) * cached_magf * inv_unit; - double y2_px= - -(selr->y2 - cached_scroll_y) * cached_magf * inv_unit; + double y1_px= -(selr->y1 - cached_scroll_y) * cached_magf * inv_unit; + double y2_px= -(selr->y2 - cached_scroll_y) * cached_magf * inv_unit; double blank_top= 0.0; if (owner->scrollarea ()->surface ()) { diff --git a/src/Plugins/Qt/QTMWidget.cpp b/src/Plugins/Qt/QTMWidget.cpp index 7b8e0cb861..65bf212611 100644 --- a/src/Plugins/Qt/QTMWidget.cpp +++ b/src/Plugins/Qt/QTMWidget.cpp @@ -14,12 +14,12 @@ #include "array.hpp" #include "boot.hpp" #include "converter.hpp" +#include "edit_interface.hpp" #include "object_l5.hpp" #include "preferences.hpp" #include "qt_gui.hpp" #include "qt_simple_widget.hpp" #include "qt_utilities.hpp" -#include "edit_interface.hpp" #include "scheme.hpp" #include "sys_utils.hpp" #ifdef USE_MUPDF_RENDERER From fada47d9630cceeef52daabad9d0fc85cf1f162e Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 21:05:20 +0800 Subject: [PATCH 23/27] =?UTF-8?q?=E5=8D=95=E7=8B=AC=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E5=85=AC=E5=BC=8F=E4=B8=8D=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Edit/Interface/edit_mouse.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index 03277fda74..446a298b1a 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -1030,6 +1030,7 @@ edit_interface_rep::handle_mouse (string kind, SI x, SI y, int m, time_t t, bool edit_interface_rep::should_show_text_toolbar () { + if (as_bool (call ("in-math?"))) return false; // 检查是否有活动的文本选区 if (!selection_active_any ()) return false; From 26e2dd59da54e54bedf20aa6c72416ef523fd1a5 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Wed, 4 Feb 2026 21:13:00 +0800 Subject: [PATCH 24/27] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devel/201_63.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/devel/201_63.md b/devel/201_63.md index a4e697cec3..f4147d353a 100644 --- a/devel/201_63.md +++ b/devel/201_63.md @@ -3,3 +3,6 @@ ## 如何测试 1. 输入一段文字通过键盘或鼠标选中,会出现悬浮窗口 2. 依次点击悬浮窗口按钮,实现的功能和模式工具栏一致 +3. 窗口位置的优先级应该是选区顶部>选区底部>窗口中央 +4. 切换标签页不会导致原标签页的文本选中窗口失效 +5. 单独选中任意数学公式环境该悬浮窗口都不出现,选中公式文本混合内容悬浮窗口出现 From fa33eedd8386cd9d7441060e76a6620d51b0f1af Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 6 Feb 2026 10:42:23 +0800 Subject: [PATCH 25/27] =?UTF-8?q?=E9=80=89=E4=B8=AD=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E6=89=8D=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Edit/Interface/edit_mouse.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Edit/Interface/edit_mouse.cpp b/src/Edit/Interface/edit_mouse.cpp index 446a298b1a..25008be80e 100644 --- a/src/Edit/Interface/edit_mouse.cpp +++ b/src/Edit/Interface/edit_mouse.cpp @@ -1030,7 +1030,9 @@ edit_interface_rep::handle_mouse (string kind, SI x, SI y, int m, time_t t, bool edit_interface_rep::should_show_text_toolbar () { - if (as_bool (call ("in-math?"))) return false; + if (as_bool (call ("in-math?")) || as_bool (call ("in-prog?")) || + as_bool (call ("in-code?")) || as_bool (call ("in-verbatim?"))) + return false; // 检查是否有活动的文本选区 if (!selection_active_any ()) return false; From fa989138e9d423935702abdfdb44103c2a041ee2 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 6 Feb 2026 12:31:19 +0800 Subject: [PATCH 26/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AB=A0=E8=8A=82?= =?UTF-8?q?=E5=92=8C=E8=AF=AD=E4=B9=89=E5=9D=97=E7=9A=84=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/progs/generic/text-toolbar.scm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TeXmacs/progs/generic/text-toolbar.scm b/TeXmacs/progs/generic/text-toolbar.scm index 6df32c1c4f..fedb99b259 100644 --- a/TeXmacs/progs/generic/text-toolbar.scm +++ b/TeXmacs/progs/generic/text-toolbar.scm @@ -26,6 +26,10 @@ (mark-text)) (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) + (=> (balloon (icon "tm_chapter.xpm") "chapter::menu") + (link chapter-menu)) + (=> (balloon (icon "tm_theorem.xpm") "enunciation") + (link enunciation-menu)) ((balloon (icon "left-align.xpm") "left aligned") (make-line-with "par-mode" "left")) ((balloon (icon "middle-align.xpm") "center") From 25d175b8cc2df6a7a97ca7049001841bc5f43e81 Mon Sep 17 00:00:00 2001 From: JackChen <17683835261@163.com> Date: Fri, 6 Feb 2026 12:46:20 +0800 Subject: [PATCH 27/27] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TeXmacs/progs/generic/text-toolbar.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TeXmacs/progs/generic/text-toolbar.scm b/TeXmacs/progs/generic/text-toolbar.scm index fedb99b259..38bc329bb0 100644 --- a/TeXmacs/progs/generic/text-toolbar.scm +++ b/TeXmacs/progs/generic/text-toolbar.scm @@ -26,7 +26,7 @@ (mark-text)) (=> (balloon (icon "tm_color.xpm") "Select a foreground color") (link color-menu)) - (=> (balloon (icon "tm_chapter.xpm") "chapter::menu") + (=> (balloon (icon "tm_section.xpm") "chapter::menu") (link chapter-menu)) (=> (balloon (icon "tm_theorem.xpm") "enunciation") (link enunciation-menu))