void GridMapEditor::_menu_option(int p_option) { switch(p_option) { case MENU_OPTION_CONFIGURE: { } break; case MENU_OPTION_LOCK_VIEW: { int index=options->get_popup()->get_item_index(MENU_OPTION_LOCK_VIEW); lock_view=!options->get_popup()->is_item_checked(index); options->get_popup()->set_item_checked(index,lock_view); } break; case MENU_OPTION_CLIP_DISABLED: case MENU_OPTION_CLIP_ABOVE: case MENU_OPTION_CLIP_BELOW: { clip_mode=ClipMode(p_option-MENU_OPTION_CLIP_DISABLED); for(int i=0;i<3;i++) { int index=options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED+i); options->get_popup()->set_item_checked(index,i==clip_mode); } _update_clip(); } break; case MENU_OPTION_X_AXIS: case MENU_OPTION_Y_AXIS: case MENU_OPTION_Z_AXIS: { int new_axis = p_option-MENU_OPTION_X_AXIS; for(int i=0;i<3;i++) { int idx=options->get_popup()->get_item_index(MENU_OPTION_X_AXIS+i); options->get_popup()->set_item_checked(idx,i==new_axis); } edit_axis=Vector3::Axis(new_axis); update_grid(); _update_clip(); } break; case MENU_OPTION_CURSOR_ROTATE_Y: { Basis r; if (input_action==INPUT_DUPLICATE) { r.set_orthogonal_index(selection.duplicate_rot); r.rotate(Vector3(0,1,0),-Math_PI/2.0); selection.duplicate_rot=r.get_orthogonal_index(); _update_duplicate_indicator(); break; } r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(0,1,0),-Math_PI/2.0); cursor_rot=r.get_orthogonal_index(); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_ROTATE_X: { Basis r; if (input_action==INPUT_DUPLICATE) { r.set_orthogonal_index(selection.duplicate_rot); r.rotate(Vector3(1,0,0),-Math_PI/2.0); selection.duplicate_rot=r.get_orthogonal_index(); _update_duplicate_indicator(); break; } r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(1,0,0),-Math_PI/2.0); cursor_rot=r.get_orthogonal_index(); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_ROTATE_Z: { Basis r; if (input_action==INPUT_DUPLICATE) { r.set_orthogonal_index(selection.duplicate_rot); r.rotate(Vector3(0,0,1),-Math_PI/2.0); selection.duplicate_rot=r.get_orthogonal_index(); _update_duplicate_indicator(); break; } r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(0,0,1),-Math_PI/2.0); cursor_rot=r.get_orthogonal_index(); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_Y: { Basis r; r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(0,1,0),Math_PI/2.0); cursor_rot=r.get_orthogonal_index(); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_X: { Basis r; r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(1,0,0),Math_PI/2.0); cursor_rot=r.get_orthogonal_index(); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_BACK_ROTATE_Z: { Basis r; r.set_orthogonal_index(cursor_rot); r.rotate(Vector3(0,0,1),Math_PI/2.0); cursor_rot=r.get_orthogonal_index(); _update_cursor_transform(); } break; case MENU_OPTION_CURSOR_CLEAR_ROTATION: { if (input_action==INPUT_DUPLICATE) { selection.duplicate_rot=0; _update_duplicate_indicator(); break; } cursor_rot=0; _update_cursor_transform(); } break; case MENU_OPTION_DUPLICATE_SELECTS: { int idx = options->get_popup()->get_item_index(MENU_OPTION_DUPLICATE_SELECTS); options->get_popup()->set_item_checked( idx, !options->get_popup()->is_item_checked( idx ) ); } break; case MENU_OPTION_SELECTION_MAKE_AREA: case MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR: { if (!selection.active) break; int area = node->get_unused_area_id(); Error err = node->create_area(area,Rect3(selection.begin,selection.end-selection.begin+Vector3(1,1,1))); if (err!=OK) { } if (p_option==MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR) { node->area_set_exterior_portal(area,true); } _update_areas_display(); update_areas(); } break; case MENU_OPTION_REMOVE_AREA: { if (selected_area<1) return; node->erase_area(selected_area); _update_areas_display(); update_areas(); } break; case MENU_OPTION_SELECTION_DUPLICATE: if (!(selection.active && input_action==INPUT_NONE)) return; if (last_mouseover==Vector3(-1,-1,-1)) //nono mouseovering anythin break; input_action=INPUT_DUPLICATE; selection.click=last_mouseover; selection.current=last_mouseover; selection.duplicate_rot=0; _update_duplicate_indicator(); break; case MENU_OPTION_SELECTION_CLEAR: { if (!selection.active) return; _delete_selection(); } break; case MENU_OPTION_GRIDMAP_SETTINGS: { settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50)); } break; } }
static int message_handle_key_editmode(struct key_event * k) { int line_len, num_lines = -1; int new_cursor_line = cursor_line; int new_cursor_char = cursor_char; char *ptr; int doing_drag = 0; int clipl, clipr, cp; if (k->mouse == MOUSE_SCROLL_UP) { if (k->state == KEY_RELEASE) return 0; new_cursor_line -= MOUSE_SCROLL_LINES; } else if (k->mouse == MOUSE_SCROLL_DOWN) { if (k->state == KEY_RELEASE) return 0; new_cursor_line += MOUSE_SCROLL_LINES; } else if (k->mouse == MOUSE_CLICK && k->mouse_button == 2) { if (k->state == KEY_RELEASE) status.flags |= CLIPPY_PASTE_SELECTION; return 1; } else if (k->mouse == MOUSE_CLICK) { if (k->x >= 2 && k->x <= 77 && k->y >= 13 && k->y <= 47) { new_cursor_line = (k->y - 13) + top_line; new_cursor_char = (k->x - 2); if (k->sx != k->x || k->sy != k->y) { /* yay drag operation */ cp = get_absolute_position(current_song->message, (k->sy-13)+top_line, (k->sx-2)); widgets_message[0].clip_start = cp; doing_drag = 1; } } } line_len = get_nth_line(current_song->message, cursor_line, &ptr); switch (k->sym) { case SDLK_UP: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line--; break; case SDLK_DOWN: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line++; break; case SDLK_LEFT: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_char--; break; case SDLK_RIGHT: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_char++; break; case SDLK_PAGEUP: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line -= 35; break; case SDLK_PAGEDOWN: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line += 35; break; case SDLK_HOME: if (k->state == KEY_RELEASE) return 1; if (k->mod & KMOD_CTRL) new_cursor_line = 0; else new_cursor_char = 0; break; case SDLK_END: if (k->state == KEY_RELEASE) return 1; if (k->mod & KMOD_CTRL) { num_lines = get_num_lines(current_song->message); new_cursor_line = num_lines; } else { new_cursor_char = line_len; } break; case SDLK_ESCAPE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; message_set_viewmode(); memused_songchanged(); return 1; case SDLK_BACKSPACE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { _delete_selection(); } else { message_delete_char(); } return 1; case SDLK_DELETE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { _delete_selection(); } else { message_delete_next_char(); } return 1; default: if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; if (k->sym == SDLK_t) { message_extfont = !message_extfont; break; } else if (k->sym == SDLK_y) { clippy_select(NULL, NULL, 0); message_delete_line(); break; } } else if (k->mod & KMOD_ALT) { if (k->state == KEY_RELEASE) return 1; if (k->sym == SDLK_c) { prompt_message_clear(); return 1; } } else if (k->mouse == MOUSE_NONE) { if (k->unicode == '\r' || k->unicode == '\t' || k->unicode >= 32) { if (k->state == KEY_RELEASE) return 1; if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { _delete_selection(); } if (k->mod & (KMOD_SHIFT|KMOD_CAPS)) { message_insert_char(toupper((unsigned int)k->unicode)); } else { message_insert_char(k->unicode); } return 1; } return 0; } if (k->mouse != MOUSE_CLICK) return 0; if (k->state == KEY_RELEASE) return 1; if (!doing_drag) { clippy_select(NULL, NULL, 0); } } if (new_cursor_line != cursor_line) { if (num_lines == -1) num_lines = get_num_lines(current_song->message); if (new_cursor_line < 0) new_cursor_line = 0; else if (new_cursor_line > num_lines) new_cursor_line = num_lines; /* make sure the cursor doesn't go past the new eol */ line_len = get_nth_line(current_song->message, new_cursor_line, &ptr); if (new_cursor_char > line_len) new_cursor_char = line_len; cursor_char = new_cursor_char; cursor_line = new_cursor_line; } else if (new_cursor_char != cursor_char) { /* we say "else" here ESPECIALLY because the mouse can only come in the top section - not because it's some clever optimization */ if (new_cursor_char < 0) { if (cursor_line == 0) { new_cursor_char = cursor_char; } else { cursor_line--; new_cursor_char = get_nth_line(current_song->message, cursor_line, &ptr); } } else if (new_cursor_char > get_nth_line(current_song->message, cursor_line, &ptr)) { if (cursor_line == get_num_lines(current_song->message)) { new_cursor_char = cursor_char; } else { cursor_line++; new_cursor_char = 0; } } cursor_char = new_cursor_char; } message_reposition(); cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); if (doing_drag) { widgets_message[0].clip_end = cursor_pos; clipl = widgets_message[0].clip_start; clipr = widgets_message[0].clip_end; if (clipl > clipr) { cp = clipl; clipl = clipr; clipr = cp; } clippy_select(widgets_message, (current_song->message+clipl), clipr-clipl); } status.flags |= NEED_UPDATE; return 1; }
bool GridMapEditor::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) { if (edit_mode->get_selected()==0) { // regular click switch (p_event.type) { case InputEvent::KEY: { if (p_event.key.pressed && p_event.key.scancode==KEY_D && p_event.key.mod.shift && selection.active && input_action==INPUT_NONE) { if (last_mouseover==Vector3(-1,-1,-1)) //nono mouseovering anythin return false; input_action=INPUT_DUPLICATE; selection.click=last_mouseover; selection.current=last_mouseover; selection.duplicate_rot=0; _update_duplicate_indicator(); } if (p_event.key.pressed && p_event.key.scancode==KEY_DELETE && selection.active) { _delete_selection(); return true; } } break; case InputEvent::MOUSE_BUTTON: { if (p_event.mouse_button.button_index==BUTTON_WHEEL_UP && (p_event.mouse_button.mod.command || p_event.mouse_button.mod.shift)) { if (p_event.mouse_button.pressed) floor->set_val( floor->get_val() +1); return true; //eaten } else if (p_event.mouse_button.button_index==BUTTON_WHEEL_DOWN && (p_event.mouse_button.mod.command || p_event.mouse_button.mod.shift)) { if (p_event.mouse_button.pressed) floor->set_val( floor->get_val() -1); return true; } if (p_event.mouse_button.pressed) { if (p_event.mouse_button.button_index==BUTTON_LEFT) { if (input_action==INPUT_DUPLICATE) { //paste _duplicate_paste(); input_action=INPUT_NONE; _update_duplicate_indicator(); } else if (p_event.mouse_button.mod.shift) { input_action=INPUT_SELECT; } else if (p_event.mouse_button.mod.command) input_action=INPUT_COPY; else { input_action=INPUT_PAINT; set_items.clear(); } } else if (p_event.mouse_button.button_index==BUTTON_RIGHT) if (input_action==INPUT_DUPLICATE) { input_action=INPUT_NONE; _update_duplicate_indicator(); } else { input_action=INPUT_ERASE; set_items.clear(); } else return false; return do_input_action(p_camera,Point2(p_event.mouse_button.x,p_event.mouse_button.y),true); } else { if ( (p_event.mouse_button.button_index==BUTTON_RIGHT && input_action==INPUT_ERASE) || (p_event.mouse_button.button_index==BUTTON_LEFT && input_action==INPUT_PAINT) ) { if (set_items.size()) { undo_redo->create_action("GridMap Paint"); for(List<SetItem>::Element *E=set_items.front();E;E=E->next()) { const SetItem &si=E->get(); undo_redo->add_do_method(node,"set_cell_item",si.pos.x,si.pos.y,si.pos.z,si.new_value,si.new_orientation); } for(List<SetItem>::Element *E=set_items.back();E;E=E->prev()) { const SetItem &si=E->get(); undo_redo->add_undo_method(node,"set_cell_item",si.pos.x,si.pos.y,si.pos.z,si.old_value,si.old_orientation); } undo_redo->commit_action(); } set_items.clear(); input_action=INPUT_NONE; return true; } if (p_event.mouse_button.button_index==BUTTON_LEFT && input_action!=INPUT_NONE) { set_items.clear(); input_action=INPUT_NONE; return true; } if (p_event.mouse_button.button_index==BUTTON_RIGHT && (input_action==INPUT_ERASE || input_action==INPUT_DUPLICATE)) { input_action=INPUT_NONE; return true; } } } break; case InputEvent::MOUSE_MOTION: { return do_input_action(p_camera,Point2(p_event.mouse_motion.x,p_event.mouse_motion.y),false); } break; } } else if (edit_mode->get_selected()==1) { //area mode, select an area switch (p_event.type) { case InputEvent::MOUSE_BUTTON: { if (p_event.mouse_button.button_index==BUTTON_LEFT && p_event.mouse_button.pressed) { Point2 point = Point2(p_event.mouse_motion.x,p_event.mouse_motion.y); Camera *camera = p_camera; Vector3 from = camera->project_ray_origin(point); Vector3 normal = camera->project_ray_normal(point); Transform local_xform = node->get_global_transform().affine_inverse(); from=local_xform.xform(from); normal=local_xform.basis.xform(normal).normalized(); List<int> areas; node->get_area_list(&areas); float min_d=1e10; int min_area=-1; for(List<int>::Element *E=areas.front();E;E=E->next()) { int area = E->get(); AABB aabb = node->area_get_bounds(area); aabb.pos*=node->get_cell_size(); aabb.size*=node->get_cell_size(); Vector3 rclip,rnormal; if (!aabb.intersects_segment(from,from+normal*10000,&rclip,&rnormal)) continue; float d = normal.dot(rclip); if (d<min_d) { min_d=d; min_area=area; } } selected_area=min_area; update_areas(); } } break; } } return false; }