indexing description: "[ A polygon editing tool left click on edge: insert vertex left click on vertex: start polygon splitting tool (drag to an other vertex) right click on vertex: delete vertex (if possible) left or right click on splitting line to delete it ]" date: "$Date$" revision: "$Revision$" class POLYGON_EDIT_TOOL inherit TOOL redefine set_toolchanged end create make feature -- Access cursor: MOUSE_CURSOR is -- appropriate cursor local p: POLYGON do if scene.focus_on_scene then if dragging_vertex /= Void then if is_over_vertex /= Void and then is_over_vertex /= dragging_vertex then Result := polygon_close_cursor else Result := arrow_cursor end elseif is_over_vertex /= Void then p ?= is_over_vertex.object if p /= Void and then p.count > 3 then Result := polygon_cross_cursor else Result := arrow_cursor end elseif is_over_line /= Void then Result := polygon_close_cursor elseif is_over_splitting_line /= Void then Result := polygon_cross_cursor else Result := arrow_cursor end else Result := arrow_cursor end end feature -- Event Handling handle_mouse_button_down_event (event: EM_MOUSEBUTTON_EVENT) is -- Handle mouse button down event. do if scene.focus_on_scene then if event.is_left_button then is_pressed := True select_drag_start_coords := scene.coordinates_from_screen_position (x, y) select_drag_start_screen_position := create {EM_VECTOR_2D}.make (x, y) if is_over_vertex /= Void then dragging_vertex := is_over_vertex else dragging_vertex := Void end elseif event.is_right_button then is_right_button_pressed := True end end end handle_mouse_button_up_event (event: EM_MOUSEBUTTON_EVENT) is -- Handle mouse button up event. local p: POLYGON i_ref: INTEGER_REF v: EM_VECTOR_2D do if scene.focus_on_scene then if event.is_left_button then is_pressed := False -- left mouse button has been released if dragging_vertex /= Void then if is_over_vertex /= Void and is_over_vertex /= dragging_vertex then -- create splitting line from `dragging_vertex' to `is_over_vertex' p ?= is_over_vertex.object p.add_splitting_line (create {EM_PAIR [INTEGER, INTEGER]}.make (p.index_of_vertex (dragging_vertex), p.index_of_vertex (is_over_vertex))) scene.history.execute (create {CHANGE_POLYGON}.make, [p]) end dragging_vertex.set_selected (False) dragging_vertex := Void elseif is_over_vertex = Void and is_over_line /= Void then -- left mouse button was released over a line p ?= is_over_line.item (1) i_ref ?= is_over_line.item (2) v ?= is_over_line.item (3) if p /= Void and i_ref /= Void and v /= Void then -- add vertex p.add_vertex (create {POLYGON_VERTEX}.make (scene.screen_position_from_coordinates (v.x, v.y), p), i_ref.item + 1) p.set_vertexes_updated scene.history.execute (create {CHANGE_POLYGON}.make, [p]) end elseif is_over_splitting_line /= Void then -- remove splitting line is_over_splitting_line.first.remove_splitting_line (is_over_splitting_line.second) scene.history.execute (create {CHANGE_POLYGON}.make, [is_over_splitting_line.first]) end select_drag_start_coords := Void select_drag_start_screen_position := Void elseif event.is_right_button then is_right_button_pressed := False if is_over_vertex /= Void and dragging_vertex = Void then -- remove `is_over_vertex' from the polygon p ?= is_over_vertex.object if p /= Void and then p.count > 3 then is_over_vertex.delete p.set_vertexes_updated scene.history.execute (create {CHANGE_POLYGON}.make, [p]) end elseif is_over_splitting_line /= Void then -- remove splitting line is_over_splitting_line.first.remove_splitting_line (is_over_splitting_line.second) scene.history.execute (create {CHANGE_POLYGON}.make, [is_over_splitting_line.first]) end end end end handle_mouse_motion_event (event: EM_MOUSEMOTION_EVENT) is -- Handle mouse motion event. local polygons: DS_LINKED_LIST_CURSOR [POLYGON] vertexes: DS_LINKED_LIST_CURSOR [POLYGON_VERTEX] over_the_line: EM_PAIR [INTEGER, EM_VECTOR_2D] do x := event.screen_x y := event.screen_y - 32 coords := scene.coordinates_from_screen_position (x, y) -- update `is_over_vertex' and `is_over_object' if scene.focus_on_scene then if is_over_vertex /= Void then is_over_vertex.set_selected (False) is_over_vertex := Void end is_over_line := Void is_over_splitting_line := Void -- update `is_over_vertex', `is_over_line' and `is_over_splitting_line' create polygons.make (scene.polygons) from polygons.start until polygons.off or is_over_vertex /= Void loop create vertexes.make (polygons.item.vertex_list) -- loop through vertexes from vertexes.start until vertexes.off or is_over_vertex /= Void loop if vertexes.item.is_point_over_vertex (x, y) then is_over_vertex := vertexes.item is_over_vertex.set_selected (True) end vertexes.forth end if is_over_vertex = Void and is_over_line = Void then -- set `is_over_line' over_the_line := polygons.item.is_on_border_line_width (coords, 3.0) if over_the_line /= Void then is_over_line := [polygons.item, over_the_line.first, over_the_line.second] end end if is_over_vertex = Void and is_over_line = Void and is_over_splitting_line = Void then -- set `is_over_splitting_line' create is_over_splitting_line.make (polygons.item, polygons.item.is_on_splitting_line (coords, 3.0)) if is_over_splitting_line.second = Void then is_over_splitting_line := Void end end polygons.forth end -- change splitting line of scene if currently dragging if dragging_vertex /= Void then scene.splitting_line.put (create {EM_VECTOR_2D}.make (x, y), select_drag_start_screen_position) else scene.splitting_line.put (Void, Void) end end last_x := x last_y := y end handle_key_down_event (event: EM_KEYBOARD_EVENT) is -- Handle key down event. do end handle_key_up_event (event: EM_KEYBOARD_EVENT) is -- Handle key up event. do end feature -- Element Change set_toolchanged is -- tool was changed, unselect all items do unselect_all_selected end feature {NONE} -- Implementation unselect_all_selected is -- unselects all selected elements do if is_over_vertex /= Void then is_over_vertex.set_selected (False) end is_over_vertex := Void end select_drag_start_coords, select_drag_start_screen_position: EM_VECTOR_2D -- where the mouse started dragging is_over_vertex: POLYGON_VERTEX -- is the mouse currently over a vertex? is_over_line: TUPLE [POLYGON, INTEGER, EM_VECTOR_2D] -- is the mouse currenty over a line? -- (only if not already over a vertex!) -- if not over a line this will be Void -- item (1) :: Polygon -- item (2) :: index of the starting vector -- item (3) :: exact position on line is_over_splitting_line: EM_PAIR [POLYGON, EM_PAIR [INTEGER, INTEGER]] -- is the mouse currently over a splitting line? dragging_vertex: VERTEX -- is the tool dragging a vertex? is_right_button_pressed: BOOLEAN -- is the right button pressed? coords: EM_VECTOR_2D -- coordinates of the mouse end