222 lines
4.1 KiB
Odin
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
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|