diff --git a/core/src/display_object/edit_text.rs b/core/src/display_object/edit_text.rs index ba3db2fdc27f..ff7f2d1121b5 100644 --- a/core/src/display_object/edit_text.rs +++ b/core/src/display_object/edit_text.rs @@ -2314,7 +2314,9 @@ impl<'gc> TInteractiveObject<'gc> for EditText<'gc> { event: ClipEvent, ) -> ClipEventResult { match event { - ClipEvent::Press | ClipEvent::MouseWheel { .. } => ClipEventResult::Handled, + ClipEvent::Press | ClipEvent::MouseWheel { .. } | ClipEvent::MouseMove => { + ClipEventResult::Handled + } _ => ClipEventResult::NotHandled, } } @@ -2339,44 +2341,60 @@ impl<'gc> TInteractiveObject<'gc> for EditText<'gc> { return ClipEventResult::Handled; } - if self.is_editable() || self.is_selectable() { - let tracker = context.focus_tracker; - tracker.set(Some(self.into()), context); - } + if let ClipEvent::Press = event { + if self.is_editable() || self.is_selectable() { + let tracker = context.focus_tracker; + tracker.set(Some(self.into()), context); + } - // We can't hold self as any link may end up modifying this object, so pull the info out - let mut link_to_open = None; + // We can't hold self as any link may end up modifying this object, so pull the info out + let mut link_to_open = None; - if let Some(position) = self.screen_position_to_index(*context.mouse_position) { - self.set_selection(Some(TextSelection::for_position(position)), context.gc()); + if let Some(position) = self.screen_position_to_index(*context.mouse_position) { + self.set_selection(Some(TextSelection::for_position(position)), context.gc()); - if let Some((span_index, _)) = - self.0.read().text_spans.resolve_position_as_span(position) - { - link_to_open = self - .0 - .read() - .text_spans - .span(span_index) - .map(|s| (s.url.clone(), s.target.clone())); + if let Some((span_index, _)) = + self.0.read().text_spans.resolve_position_as_span(position) + { + link_to_open = self + .0 + .read() + .text_spans + .span(span_index) + .map(|s| (s.url.clone(), s.target.clone())); + } + } else { + self.set_selection( + Some(TextSelection::for_position(self.text_length())), + context.gc(), + ); } - } else { - self.set_selection( - Some(TextSelection::for_position(self.text_length())), - context.gc(), - ); + + if let Some((url, target)) = link_to_open { + if !url.is_empty() { + // TODO: This fires on mouse DOWN but it should be mouse UP... + // but only if it went down in the same span. + // Needs more advanced focus handling than we have at time of writing this comment. + self.open_url(context, &url, &target); + } + } + + return ClipEventResult::Handled; } - if let Some((url, target)) = link_to_open { - if !url.is_empty() { - // TODO: This fires on mouse DOWN but it should be mouse UP... - // but only if it went down in the same span. - // Needs more advanced focus handling than we have at time of writing this comment. - self.open_url(context, &url, &target); + if let ClipEvent::MouseMove = event { + // If a mouse has moved and this EditTest is pressed, we need to update the selection. + if InteractiveObject::option_ptr_eq(context.mouse_data.pressed, self.as_interactive()) { + if let Some(mut selection) = self.selection() { + if let Some(position) = self.screen_position_to_index(*context.mouse_position) { + selection.to = position; + self.set_selection(Some(selection), context.gc()); + } + } } } - ClipEventResult::Handled + ClipEventResult::NotHandled } fn mouse_pick_avm1( diff --git a/tests/tests/swfs/avm1/edittext_drag_select/input.json b/tests/tests/swfs/avm1/edittext_drag_select/input.json new file mode 100644 index 000000000000..974c2df90934 --- /dev/null +++ b/tests/tests/swfs/avm1/edittext_drag_select/input.json @@ -0,0 +1,19 @@ +[ + { "type": "MouseMove", "pos": [234,166] }, + { "type": "MouseDown", "pos": [234,166], "btn": "Left" }, + { "type": "MouseMove", "pos": [511,189] }, + { "type": "MouseMove", "pos": [511,189] }, + { "type": "MouseUp", "pos": [511,189], "btn": "Left" }, + + { "type": "MouseMove", "pos": [343,166] }, + { "type": "MouseDown", "pos": [343,166], "btn": "Left" }, + { "type": "MouseMove", "pos": [764,523] }, + { "type": "MouseMove", "pos": [764,523] }, + { "type": "MouseUp", "pos": [764,523], "btn": "Left" }, + + { "type": "MouseMove", "pos": [207,163] }, + { "type": "MouseDown", "pos": [207,163], "btn": "Left" }, + { "type": "MouseMove", "pos": [7,13] }, + { "type": "MouseMove", "pos": [7,13] }, + { "type": "MouseUp", "pos": [7,13], "btn": "Left" } +] diff --git a/tests/tests/swfs/avm1/edittext_drag_select/output.txt b/tests/tests/swfs/avm1/edittext_drag_select/output.txt new file mode 100644 index 000000000000..0dd1d108178e --- /dev/null +++ b/tests/tests/swfs/avm1/edittext_drag_select/output.txt @@ -0,0 +1,9 @@ +Mouse down: 234,166 +Mouse up: 511,189 +Text: Loreetus. +Mouse down: 343,166 +Mouse up: 764,523 +Text: Loreetu +Mouse down: 207,163 +Mouse up: 7,13 +Text: oreetu diff --git a/tests/tests/swfs/avm1/edittext_drag_select/test.as b/tests/tests/swfs/avm1/edittext_drag_select/test.as new file mode 100644 index 000000000000..29c722d04216 --- /dev/null +++ b/tests/tests/swfs/avm1/edittext_drag_select/test.as @@ -0,0 +1,11 @@ +var listener = new Object(); +listener.onMouseDown = function() { + trace("Mouse down: " + _root._xmouse + "," + _root._ymouse) +}; +listener.onMouseUp = function() { + trace("Mouse up: " + _root._xmouse + "," + _root._ymouse) + text.replaceSel(""); + trace("Text: " + text.text.split("\r").join("\\n").split("\n").join("\\n")); +}; +Key.addListener(listener); +Mouse.addListener(listener); diff --git a/tests/tests/swfs/avm1/edittext_drag_select/test.swf b/tests/tests/swfs/avm1/edittext_drag_select/test.swf new file mode 100644 index 000000000000..3446c1e4744a Binary files /dev/null and b/tests/tests/swfs/avm1/edittext_drag_select/test.swf differ diff --git a/tests/tests/swfs/avm1/edittext_drag_select/test.toml b/tests/tests/swfs/avm1/edittext_drag_select/test.toml new file mode 100644 index 000000000000..cf6123969a1d --- /dev/null +++ b/tests/tests/swfs/avm1/edittext_drag_select/test.toml @@ -0,0 +1 @@ +num_ticks = 1