Files
Edit2D/handle_input.odin
T

222 lines
4.1 KiB
Odin

package edit2d
import b2 "vendor:box2d"
import im "shared:odin-imgui"
import "vendor:glfw"
import "base:runtime"
/*
Handling input
Key Bindings
Meta keys
E -> Cycle thru interface edit mode
CTRL + S -> Save level
CTRL + C -> Copy entity
CTRL + V -> Paste entity
ALT + D -> Delete entity
CTRL + Mouse left -> Move according to edit mode
Mouse wheel -> Scale according to edit mode
Mouse Left -> select entity
Mouse Right -> create new entity
TODO:
Command mode?
Different handling of keys for different modes
*/
/*
Handle all keys when the editor is in entity mode
Select
Add
Move
Delete
Copy paste
Resize
*/
handle_entity_mode :: proc(
$E : typeid,
state : ^engine_state,
game_data : ^$G,
) -> bool
{
ret := false
click_query_filter :: proc "c" (
shape_id : b2.ShapeId,
ctx : rawptr
) -> bool
{
context = runtime.default_context()
game := cast(^engine_game)ctx
index := i32(uintptr(b2.Shape_GetUserData(shape_id)))
game.interface.selected_entity = index
return true
}
game: ^engine_game = game_data
interface := &game.interface
level := &game_data.levels[game.curr_level]
input := &state.input
mpos := camera_convert_screen_to_world(&state.draw.cam, input.mouse)
//Setlect entity
if is_key_pressed(state, glfw.MOUSE_BUTTON_LEFT)
{
aabb : b2.AABB = {mpos, mpos + 1}
r := b2.World_OverlapAABB(
level.engine.world_id,
aabb,
b2.DefaultQueryFilter(),
click_query_filter,
game,
)
}
else if is_key_pressed(state, glfw.MOUSE_BUTTON_RIGHT)
{
new_def := E {
engine = default_engine_entity_def(),
type = .NPC
}
interface.selected_entity = i32(len(level.entity_defs))
append(&level.entity_defs, new_def)
ret = true
}
else{
//Can only do these actions if a entity is selected
if interface.selected_entity != -1 && len(level.entity_defs) > 0
{
def := &level.entity_defs[interface.selected_entity]
//Copy paste
if is_key_down( state, glfw.KEY_LEFT_CONTROL)\\
&& is_key_pressed( state, glfw.KEY_C)
{
game_data.copied_def = def^
}
else if is_key_down( state, glfw.KEY_LEFT_CONTROL) \\
&& is_key_pressed( state, glfw.KEY_V)
{
//Paste the copied def on the mouse position
interface.selected_entity = i32(len(level.entity_defs))
game_data.copied_def.body_def.position = mpos
append(&level.entity_defs, game_data.copied_def)
ret = true
}
else if is_key_down( state, glfw.KEY_LEFT_CONTROL) \\
&& is_key_pressed( state, glfw.KEY_D)
{
//Remove the def
unordered_remove(&level.entity_defs, interface.selected_entity)
interface.selected_entity = -1
ret = true
}
else if is_key_down( state, glfw.KEY_LEFT_CONTROL) \\
&& is_key_down( state, glfw.MOUSE_BUTTON_LEFT)
{
//move def
def.body_def.position = mpos
ret = true
}
else if state.input.mouse_wheel.y != 0
{
def.scale += f32(state.input.mouse_prev.y / 5)
ret = true
}
}
}
return ret
}
handle_input :: proc(
$E : typeid,
state : ^engine_state,
game_data : ^$G,
) -> bool
{
game : ^engine_game = &game_data.engine
/*
Applies for all mode
*/
level := &game_data.levels[game.curr_level]
if is_key_pressed(state, glfw.KEY_E)
{
interface := &game.interface
if interface.edit_mode == max(EditMode)
{
interface.edit_mode = min(EditMode)
}else
{
new_val := int(interface.edit_mode) + 1
interface.edit_mode = EditMode(new_val)
}
}
if is_key_pressed(state, glfw.KEY_S) && \\
is_key_down(state, glfw.KEY_LEFT_CONTROL)
{
level_save_to_file(level, state)
}
if im.GetIO().WantCaptureMouse do return false
if im.GetIO().WantCaptureKeyboard do return false
#partial switch game.interface.edit_mode
{
case .ENTITY : handle_entity_mode(E, state, game_data)
// case .VERTICES : interface_handle_vertices_mode(state, game_data)
// case .OVERVIEW : interface_handle_overview_mode(state, game_data)
// case .CHAIN : interface_handle_chain_mode(state, game_data)
// case .JOINT : interface_handle_joint_mode(state, game_data)
}
return false
}