indexing description: "[ The representation of a scene ]" date: "$Date$" revision: "$Revision$" class SCENE create make feature -- Initialization make is -- creation procedure. do create circles.make create rectangles.make create polygons.make create image_panes.make (image_capacity) create history.make create collision_detector.make create splitting_line.make (Void, Void) center_x := 512 center_y := 368 scale := 1 is_saved := False end feature -- Access circles: DS_LINKED_LIST [CIRCLE] -- List of all circles rectangles: DS_LINKED_LIST [RECTANGLE] -- List of all rectangles polygons: DS_LINKED_LIST [POLYGON] -- List of all polygons image_panes: HEAP_PRIORITY_QUEUE_WALKABLE [IMAGE_PANE] -- List of all image panes splitting_line: EM_PAIR [EM_VECTOR_2D, EM_VECTOR_2D] -- splitting line to be drawn if not void name: STRING is -- name of the window do if file = Void or else file.is_equal ("") then Result := "New Scene" else Result := file end end path: STRING -- string of the path (directory) file: STRING -- string of the file name is_saved: BOOLEAN -- is this scene currently saved? save_error: INTEGER -- save error number -- 0: no errors -- 1: error saving - invalid path -- 2: scene not saved, have to prompt for overwrite open_error: INTEGER -- open error number -- 0: no errors -- 1: invalid file format -- 2: file not readable -- 3: file not found history: HISTORY -- undo/redo history image_capacity: INTEGER is 100 -- maximum amount of image panes focus_on_scene: BOOLEAN -- is the mouse over the scene? center_x, center_y: INTEGER -- screen center for viewing scale: DOUBLE -- view scale grid: BOOLEAN -- show grid? vertex_mode: BOOLEAN -- is the display mode set to vertex mode? screen_width: INTEGER is 1024 -- screen width screen_height: INTEGER is 736 -- screen height half_screen_width: INTEGER is 512 -- half of the screens width half_screen_height: INTEGER is 368 -- half of the screens height collision_detector: COLLISION_DETECTOR -- collision detector, that has the capability to return intersecting objects feature -- Saving save is -- saves the scene to `path'/`file' require path_set: path /= Void and then not path.is_equal ("") file_set: file /= Void and then not file.is_equal ("") do save_overwrite end save_as (a_path, a_file: STRING) is -- saves the scene to a certain file. require a_path_not_void: a_path /= Void a_file_not_void: a_file /= Void local saver: SCENE_SAVER is_valid: INTEGER do is_saved := False create saver.make (current, a_path, a_file) is_valid := saver.is_file_valid if is_valid = 1 then -- file can be created saver.save is_saved := True path := a_path file := a_file save_error := 0 elseif is_valid = 2 then -- has to be overwritten, otherwise ok save_error := 2 else -- the file is not valid save_error := 1 end end save_overwrite is -- after saving and overwrite was granted. require path_set: path /= Void and then not path.is_equal ("") file_set: file /= Void and then not file.is_equal ("") local saver: SCENE_SAVER is_valid: INTEGER do is_saved := False create saver.make (current, path, file) is_valid := saver.is_file_valid if is_valid = 1 or is_valid = 2 then -- save file saver.save is_saved := True else -- the file is not valid save_error := 1 end end open (a_file: STRING) is -- open a file and import its elements to the current scene. require a_file_not_void: a_file /= Void a_file_not_empty: not a_file.is_empty local opener: SCENE_SAVER is_valid: INTEGER do create opener.make_from_absolute (current, a_file) is_valid := opener.is_file_valid if is_valid = 2 then -- file is valid and readable open_error := 0 opener.open -- if opener.image_panes = Void then -- open_error := 1 -- else -- image_panes := opener.image_panes -- circles := opener.circles -- end elseif is_valid = 3 then -- file is not readable, but exists open_error := 2 elseif is_valid = 4 then -- invalid file format open_error := 1 else -- file does not exist open_error := 3 end end feature -- Element Change set_file (a_path, a_file: STRING) is -- saves the scene to a certain file. -- a_path and a_file HAVE to be valid. require a_path_not_void: a_path /= Void a_file_not_void: a_file /= Void do path := a_path file := a_file ensure path_set: path = a_path file_set: file = a_file end set_focus_on_scene (b: BOOLEAN) is -- sets `focus_on_scene' do focus_on_scene := b ensure focus_on_scene_set: focus_on_scene = b end set_changed is -- sets `is_saved' to false. do is_saved := False end set_center (an_x, a_y: INTEGER) is -- sets `center_x' and `center_y' do center_x := an_x center_y := a_y set_update_vertices ensure center_set: center_x = an_x and center_y = a_y end set_scale (a_scale: DOUBLE) is -- sets `scale' require scale_valid: a_scale > 0 do scale := a_scale set_update_vertices ensure scale_set: scale = a_scale end set_grid (b: BOOLEAN) is -- sets `grid' do grid := b ensure grid_set: grid = b end set_vertex_mode (b: BOOLEAN) is -- sets `vertex_mode' do vertex_mode := b ensure vertex_mode_set: vertex_mode = b end set_update_vertices is -- loop through all objects and reset vertices local c: DS_LINKED_LIST_CURSOR [CIRCLE] r: DS_LINKED_LIST_CURSOR [RECTANGLE] p: DS_LINKED_LIST_CURSOR [POLYGON] do create c.make (circles) from c.start until c.off loop c.item.set_changed c.forth end create r.make (rectangles) from r.start until r.off loop r.item.set_changed r.forth end create p.make (polygons) from p.start until p.off loop p.item.set_changed p.forth end end feature {SELECTION_TOOL, EDITING_PANEL, VERTEX_SELECTION_TOOL} -- Selection Tool features set_selection_box (v1, v2: EM_VECTOR_2D) is -- set `start_drag' do selection_box_top_left := v1 selection_box_bottom_right := v2 end selection_box_top_left, selection_box_bottom_right: EM_VECTOR_2D -- dragging box (is void, if not to be displayed) feature -- Computation screen_position_from_coordinates (an_x, a_y: DOUBLE): EM_VECTOR_2D is -- converts real positions to on-screen positions using `scale', `center_x' and `center_y' local top_left_x, top_left_y: DOUBLE do -- top_left is equivalent to the top left corner of the screen (result = (0,0)) top_left_x := center_x - half_screen_width / scale top_left_y := center_y - half_screen_height / scale create Result.make ((an_x - top_left_x) * scale, (a_y - top_left_y) * scale) end coordinates_from_screen_position (an_x, a_y: DOUBLE): EM_VECTOR_2D is -- converts a screen position into coordinates local top_left_x, top_left_y: DOUBLE do top_left_x := center_x - half_screen_width / scale top_left_y := center_y - half_screen_height / scale create Result.make (an_x / scale + top_left_x, a_y / scale + top_left_y) end invariant circles_not_void: circles /= Void rectangles_not_void: rectangles /= Void polygons_not_void: polygons /= Void image_panes_not_void: image_panes /= Void history_not_void: history /= Void scale_valid: scale > 0 splitting_line_not_void: splitting_line /= Void end