mirror of
https://github.com/penpot/penpot.git
synced 2026-08-05 12:29:00 +00:00
🔧 Support text style shortcuts (#11002)
This commit is contained in:
parent
ca29f734c7
commit
14a6ea5c52
@ -11,6 +11,7 @@
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.data.shortcuts :as ds]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.workspace.texts-v3 :as dwt-v3]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.features :as features]
|
||||
[app.main.fonts :as fonts]
|
||||
@ -170,6 +171,8 @@
|
||||
:else props)]
|
||||
|
||||
(when (and shape props)
|
||||
(when (features/active-feature? @st/state "text-editor-wasm/v1")
|
||||
(st/emit! (dwt-v3/v3-update-text-editor-styles (:id shape) props)))
|
||||
(st/emit! (dwt/update-attrs (:id shape) props)))))
|
||||
|
||||
(defn blend-props
|
||||
|
||||
@ -99,6 +99,18 @@
|
||||
(or (.-isComposing native)
|
||||
(= 229 (.-keyCode event)))))
|
||||
|
||||
(defn- input-surface-class
|
||||
"Class list for the contenteditable capture surface.
|
||||
|
||||
Mousetrap's `stopCallback` drops every keystroke whose target is
|
||||
contentEditable, so without the `mousetrap` class (as in V1/V2) the text
|
||||
shortcuts (Ctrl+B, Ctrl+I, …) never reach the dispatcher."
|
||||
[rotation]
|
||||
(dm/str "mousetrap "
|
||||
(cur/get-dynamic "text" rotation)
|
||||
" "
|
||||
(stl/css :text-editor-container)))
|
||||
|
||||
(mf/defc text-editor*
|
||||
"Contenteditable element positioned over the text shape to capture input events."
|
||||
[{:keys [shape]}]
|
||||
@ -359,7 +371,9 @@
|
||||
(let [native-event (dom/event->native-event event)
|
||||
off-pt (dom/get-offset-position native-event)]
|
||||
(mf/set-ref-val! dragging-ref true)
|
||||
(wasm.api/text-editor-pointer-down off-pt)
|
||||
(if (.-shiftKey event)
|
||||
(wasm.api/text-editor-pointer-down-extend off-pt)
|
||||
(wasm.api/text-editor-pointer-down off-pt))
|
||||
;; Repaint the caret over the cached tiles instead of a full render,
|
||||
;; which flashes at high zoom (see `render-text-editor-overlay!`).
|
||||
(wasm.api/render-text-editor-overlay!))))
|
||||
@ -505,7 +519,5 @@
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:id "text-editor-wasm-input"
|
||||
:class (dm/str (cur/get-dynamic "text" (:rotation shape))
|
||||
" "
|
||||
(stl/css :text-editor-container))
|
||||
:class (input-surface-class (:rotation shape))
|
||||
:data-testid "text-editor-container"}]]]]))
|
||||
|
||||
@ -281,6 +281,7 @@
|
||||
(def text-editor-set-cursor-from-point text-editor/text-editor-set-cursor-from-point)
|
||||
(def text-editor-toggle-overtype-mode text-editor/text-editor-toggle-overtype-mode)
|
||||
(def text-editor-pointer-down text-editor/text-editor-pointer-down)
|
||||
(def text-editor-pointer-down-extend text-editor/text-editor-pointer-down-extend)
|
||||
(def text-editor-pointer-move text-editor/text-editor-pointer-move)
|
||||
(def text-editor-pointer-up text-editor/text-editor-pointer-up)
|
||||
(def text-editor-get-current-styles text-editor/text-editor-get-current-styles)
|
||||
|
||||
@ -222,6 +222,12 @@
|
||||
(when (wasm/ready?)
|
||||
(h/call wasm/internal-module "_text_editor_pointer_down" x y)))
|
||||
|
||||
(defn text-editor-pointer-down-extend
|
||||
"Extends the selection up to the pointer instead of collapsing the caret."
|
||||
[{:keys [x y]}]
|
||||
(when (wasm/ready?)
|
||||
(h/call wasm/internal-module "_text_editor_pointer_down_extend" x y)))
|
||||
|
||||
(defn text-editor-pointer-move
|
||||
[{:keys [x y]}]
|
||||
(when (wasm/ready?)
|
||||
|
||||
@ -192,6 +192,35 @@ pub extern "C" fn text_editor_pointer_down(x: f32, y: f32) {
|
||||
});
|
||||
}
|
||||
|
||||
/// Like `text_editor_pointer_down`, but keeps the current anchor and moves the
|
||||
/// focus to the pointer instead of collapsing the caret there (Shift+click).
|
||||
#[no_mangle]
|
||||
pub extern "C" fn text_editor_pointer_down_extend(x: f32, y: f32) {
|
||||
with_state!(state, {
|
||||
if !get_text_editor_state().has_focus {
|
||||
return;
|
||||
}
|
||||
let Some(shape_id) = get_text_editor_state().active_shape_id else {
|
||||
return;
|
||||
};
|
||||
let Some(shape) = state.shapes.get(&shape_id) else {
|
||||
return;
|
||||
};
|
||||
let Type::Text(text_content) = &shape.shape_type else {
|
||||
return;
|
||||
};
|
||||
let point = Point::new(x, y);
|
||||
get_text_editor_state().start_pointer_selection();
|
||||
if let Some(position) = text_content.get_caret_position_from_shape_coords(&point) {
|
||||
get_text_editor_state().extend_selection_from_position(&position);
|
||||
// The click after pointerup would collapse the caret and drop the
|
||||
// selection we just extended.
|
||||
get_text_editor_state().is_click_event_skipped = true;
|
||||
get_text_editor_state().update_styles(text_content);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn text_editor_pointer_move(x: f32, y: f32) {
|
||||
with_state!(state, {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user