Path tool: sliding point insertion (#1581)

* #1578 sliding point works(1st approx)

TODO:
* don't move too close to the side points
* double click works incorrect?
* do we need to jump from segment to segment?

* #1578 disallow move slide point too close to side points

* fix double click + ctrl insertion

* #1578 select insertion point (except `ctrl` case)

* #1578 far depends on line width & more accurate seg finding

* #1578 insert point on most top suitable selected layer

* #1581 draw insertion point by overlay  + `Esc` abort

* #1581 sharp stay unchanged on double click

* #1581 fix incorrect handle of scaling

* #1581 `square` selection point & too close in px(instead of magic)

* #1581 bug fix: insertion point on unselection

* #1581 use `color: Option` instead of `SelectionType`

* Some code review, still need to review shape_editor.rs

* #1581 insert sharp point on a straight segment

Also correct insertion on quadratic segments

`ManipulatorGroup::have_handle` have such form because `handle = Some(self.anchor)` often used instead of `handle = None`

* Final code review pass

* Code review pass

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Nikita-str
2024-02-05 08:45:25 +00:00
committed by GitHub
co-authored by Keavon Chambers
parent a412a77062
commit f25038067e
11 changed files with 446 additions and 108 deletions
@@ -48,7 +48,7 @@ pub fn path_overlays(document: &DocumentMessageHandler, shape_editor: &mut Shape
overlay_context.handle(handle_position, is_selected(selected, ManipulatorPointId::new(manipulator_group.id, SelectedType::OutHandle)));
}
overlay_context.square(anchor_position, is_selected(selected, ManipulatorPointId::new(manipulator_group.id, SelectedType::Anchor)));
overlay_context.square(anchor_position, is_selected(selected, ManipulatorPointId::new(manipulator_group.id, SelectedType::Anchor)), None);
}
}
}
@@ -66,14 +66,14 @@ pub fn path_endpoint_overlays(document: &DocumentMessageHandler, shape_editor: &
let anchor = first_manipulator.anchor;
let anchor_position = transform.transform_point2(anchor);
overlay_context.square(anchor_position, is_selected(selected, ManipulatorPointId::new(first_manipulator.id, SelectedType::Anchor)));
overlay_context.square(anchor_position, is_selected(selected, ManipulatorPointId::new(first_manipulator.id, SelectedType::Anchor)), None);
};
if let Some(last_manipulator) = manipulator_groups.last() {
let anchor = last_manipulator.anchor;
let anchor_position = transform.transform_point2(anchor);
overlay_context.square(anchor_position, is_selected(selected, ManipulatorPointId::new(last_manipulator.id, SelectedType::Anchor)));
overlay_context.square(anchor_position, is_selected(selected, ManipulatorPointId::new(last_manipulator.id, SelectedType::Anchor)), None);
};
}
}
@@ -54,21 +54,23 @@ impl OverlayContext {
.expect("draw circle");
let fill = if selected { COLOR_OVERLAY_BLUE } else { COLOR_OVERLAY_WHITE };
self.render_context.set_fill_style(&wasm_bindgen::JsValue::from_str(&fill));
self.render_context.set_fill_style(&wasm_bindgen::JsValue::from_str(fill));
self.render_context.fill();
self.render_context.set_stroke_style(&wasm_bindgen::JsValue::from_str(COLOR_OVERLAY_BLUE));
self.render_context.stroke();
}
pub fn square(&mut self, position: DVec2, selected: bool) {
pub fn square(&mut self, position: DVec2, selected: bool, color_selected: Option<&str>) {
let color_selected = color_selected.unwrap_or(COLOR_OVERLAY_BLUE);
self.render_context.begin_path();
let corner = position - DVec2::splat(MANIPULATOR_GROUP_MARKER_SIZE) / 2.;
self.render_context
.rect(corner.x.round(), corner.y.round(), MANIPULATOR_GROUP_MARKER_SIZE, MANIPULATOR_GROUP_MARKER_SIZE);
let fill = if selected { COLOR_OVERLAY_BLUE } else { COLOR_OVERLAY_WHITE };
self.render_context.set_fill_style(&wasm_bindgen::JsValue::from_str(&fill));
let fill = if selected { color_selected } else { COLOR_OVERLAY_WHITE };
self.render_context.set_fill_style(&wasm_bindgen::JsValue::from_str(fill));
self.render_context.fill();
self.render_context.set_stroke_style(&wasm_bindgen::JsValue::from_str(COLOR_OVERLAY_BLUE));
self.render_context.set_stroke_style(&wasm_bindgen::JsValue::from_str(color_selected));
self.render_context.stroke();
}