mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 10:56:20 +00:00
Merge pull request #7771 from penpot/elenatorro-12541-improve-text-selection-and-cursor
✨ Improve text shape selection
This commit is contained in:
commit
e1f2fca4af
@ -309,7 +309,7 @@
|
|||||||
|
|
||||||
[{:keys [x y width height]} transform]
|
[{:keys [x y width height]} transform]
|
||||||
(if render-wasm?
|
(if render-wasm?
|
||||||
(let [{:keys [width height]} (wasm.api/get-text-dimensions shape-id)
|
(let [{:keys [height]} (wasm.api/get-text-dimensions shape-id)
|
||||||
selrect-transform (mf/deref refs/workspace-selrect)
|
selrect-transform (mf/deref refs/workspace-selrect)
|
||||||
[selrect transform] (dsh/get-selrect selrect-transform shape)
|
[selrect transform] (dsh/get-selrect selrect-transform shape)
|
||||||
|
|
||||||
@ -320,7 +320,7 @@
|
|||||||
"bottom" (- y (- height (:height selrect)))
|
"bottom" (- y (- height (:height selrect)))
|
||||||
"center" (- y (/ (- height (:height selrect)) 2))
|
"center" (- y (/ (- height (:height selrect)) 2))
|
||||||
y)]
|
y)]
|
||||||
[(assoc selrect :y y :width width :height height) transform])
|
[(assoc selrect :y y :width (:width selrect) :height (:height selrect)) transform])
|
||||||
|
|
||||||
(let [bounds (gst/shape->rect shape)
|
(let [bounds (gst/shape->rect shape)
|
||||||
x (mth/min (dm/get-prop bounds :x)
|
x (mth/min (dm/get-prop bounds :x)
|
||||||
@ -342,8 +342,8 @@
|
|||||||
|
|
||||||
(not render-wasm?)
|
(not render-wasm?)
|
||||||
(obj/merge!
|
(obj/merge!
|
||||||
#js {"--editor-container-width" (dm/str (:width shape) "px")
|
#js {"--editor-container-width" (dm/str width "px")
|
||||||
"--editor-container-height" (dm/str (:height shape) "px")})
|
"--editor-container-height" (dm/str height "px")})
|
||||||
|
|
||||||
;; Transform is necessary when there is a text overflow and the vertical
|
;; Transform is necessary when there is a text overflow and the vertical
|
||||||
;; aligment is center or bottom.
|
;; aligment is center or bottom.
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
.text-editor-container {
|
.text-editor-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-editor-selection-imposter {
|
.text-editor-selection-imposter {
|
||||||
|
|||||||
@ -316,7 +316,7 @@
|
|||||||
(not (contains? child-parent? %)))
|
(not (contains? child-parent? %)))
|
||||||
(and (features/active-feature? @st/state "render-wasm/v1")
|
(and (features/active-feature? @st/state "render-wasm/v1")
|
||||||
(cfh/text-shape? objects %)
|
(cfh/text-shape? objects %)
|
||||||
(not (wasm.api/intersect-position % @last-point-ref)))))))
|
(not (wasm.api/intersect-position-in-shape % @last-point-ref)))))))
|
||||||
|
|
||||||
remove-measure-xf
|
remove-measure-xf
|
||||||
(cond
|
(cond
|
||||||
|
|||||||
@ -139,6 +139,7 @@
|
|||||||
:shape-id id
|
:shape-id id
|
||||||
:dimensions (get-text-dimensions id)}))
|
:dimensions (get-text-dimensions id)}))
|
||||||
|
|
||||||
|
|
||||||
(defn- ensure-text-content
|
(defn- ensure-text-content
|
||||||
"Guarantee that the shape always sends a valid text tree to WASM. When the
|
"Guarantee that the shape always sends a valid text tree to WASM. When the
|
||||||
content is nil (freshly created text) we fall back to
|
content is nil (freshly created text) we fall back to
|
||||||
@ -852,11 +853,11 @@
|
|||||||
(mem/free)
|
(mem/free)
|
||||||
{:x x :y y :width width :height height :max-width max-width})))
|
{:x x :y y :width width :height height :max-width max-width})))
|
||||||
|
|
||||||
(defn intersect-position
|
(defn intersect-position-in-shape
|
||||||
[id position]
|
[id position]
|
||||||
(let [buffer (uuid/get-u32 id)
|
(let [buffer (uuid/get-u32 id)
|
||||||
result
|
result
|
||||||
(h/call wasm/internal-module "_intersect_position"
|
(h/call wasm/internal-module "_intersect_position_in_shape"
|
||||||
(aget buffer 0)
|
(aget buffer 0)
|
||||||
(aget buffer 1)
|
(aget buffer 1)
|
||||||
(aget buffer 2)
|
(aget buffer 2)
|
||||||
|
|||||||
@ -189,6 +189,7 @@ impl TextContentLayout {
|
|||||||
* Check if the current x,y (in paragraph relative coordinates) is inside
|
* Check if the current x,y (in paragraph relative coordinates) is inside
|
||||||
* the paragraph
|
* the paragraph
|
||||||
*/
|
*/
|
||||||
|
#[allow(dead_code)]
|
||||||
fn intersects(paragraph: &skia_safe::textlayout::Paragraph, x: f32, y: f32) -> bool {
|
fn intersects(paragraph: &skia_safe::textlayout::Paragraph, x: f32, y: f32) -> bool {
|
||||||
if y < 0.0 || y > paragraph.height() {
|
if y < 0.0 || y > paragraph.height() {
|
||||||
return false;
|
return false;
|
||||||
@ -693,7 +694,28 @@ impl TextContent {
|
|||||||
(fallback_width, fallback_height)
|
(fallback_width, fallback_height)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersect_position(&self, shape: &Shape, x_pos: f32, y_pos: f32) -> bool {
|
pub fn intersect_position_in_shape(&self, shape: &Shape, x_pos: f32, y_pos: f32) -> bool {
|
||||||
|
let rect = shape.selrect;
|
||||||
|
let mut matrix = Matrix::new_identity();
|
||||||
|
let center = shape.center();
|
||||||
|
let Some(inv_transform) = &shape.transform.invert() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
matrix.pre_translate(center);
|
||||||
|
matrix.pre_concat(inv_transform);
|
||||||
|
matrix.pre_translate(-center);
|
||||||
|
|
||||||
|
let result = matrix.map_point((x_pos, y_pos));
|
||||||
|
|
||||||
|
let x_pos = result.x;
|
||||||
|
let y_pos = result.y;
|
||||||
|
|
||||||
|
x_pos >= rect.x() && x_pos <= rect.right() && y_pos >= rect.y() && y_pos <= rect.bottom()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leave this function for future use in the upcoming render editor
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn intersect_position_in_text(&self, shape: &Shape, x_pos: f32, y_pos: f32) -> bool {
|
||||||
let rect = self.content_rect(&shape.selrect, shape.vertical_align);
|
let rect = self.content_rect(&shape.selrect, shape.vertical_align);
|
||||||
let mut matrix = Matrix::new_identity();
|
let mut matrix = Matrix::new_identity();
|
||||||
let center = shape.center();
|
let center = shape.center();
|
||||||
|
|||||||
@ -341,7 +341,7 @@ pub extern "C" fn get_text_dimensions() -> *mut u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn intersect_position(
|
pub extern "C" fn intersect_position_in_shape(
|
||||||
a: u32,
|
a: u32,
|
||||||
b: u32,
|
b: u32,
|
||||||
c: u32,
|
c: u32,
|
||||||
@ -355,7 +355,7 @@ pub extern "C" fn intersect_position(
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if let Type::Text(content) = &shape.shape_type {
|
if let Type::Text(content) = &shape.shape_type {
|
||||||
return content.intersect_position(shape, x_pos, y_pos);
|
return content.intersect_position_in_shape(shape, x_pos, y_pos);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user