Some checks failed
odin-ci / build-test (push) Has been cancelled
add to gitignore
207 lines
7.6 KiB
Odin
207 lines
7.6 KiB
Odin
package gui
|
|
|
|
import rl "vendor:raylib"
|
|
|
|
editor_update :: proc(app: ^GUI_App_State) {
|
|
ed := &app.editor
|
|
if !ed.active { return }
|
|
|
|
pen := &app.pen
|
|
|
|
mouse := rl.GetMousePosition()
|
|
cr := ed.canvas_rect
|
|
mx := vec2_x(mouse)
|
|
my := vec2_y(mouse)
|
|
in_canvas := mx >= cr.x && mx <= cr.x + cr.width && my >= cr.y && my <= cr.y + cr.height
|
|
space_down := rl.IsKeyDown(.SPACE)
|
|
pan_pressed := (rl.IsMouseButtonPressed(.RIGHT) || (space_down && rl.IsMouseButtonPressed(.LEFT))) && in_canvas
|
|
pan_down := rl.IsMouseButtonDown(.RIGHT) || (space_down && rl.IsMouseButtonDown(.LEFT))
|
|
|
|
if pan_pressed {
|
|
ed.is_panning = true
|
|
ed.pan_start = mouse
|
|
ed.pan_offset_start = ed.pan_offset
|
|
}
|
|
if ed.is_panning {
|
|
if pan_down {
|
|
_, fit_scale := editor_image_dest_rect(ed)
|
|
if fit_scale <= 0 { fit_scale = 1.0 }
|
|
dx := vec2_x(mouse) - vec2_x(ed.pan_start)
|
|
dy := vec2_y(mouse) - vec2_y(ed.pan_start)
|
|
ed.pan_offset = rl.Vector2{vec2_x(ed.pan_offset_start) + dx / fit_scale, vec2_y(ed.pan_offset_start) + dy / fit_scale}
|
|
ed.needs_redraw = true
|
|
} else {
|
|
ed.is_panning = false
|
|
}
|
|
}
|
|
|
|
wheel := rl.GetMouseWheelMove()
|
|
shift_down := rl.IsKeyDown(.LEFT_SHIFT) || rl.IsKeyDown(.RIGHT_SHIFT)
|
|
if wheel != 0 && in_canvas {
|
|
if shift_down {
|
|
ed.brush_size += wheel * 2.0
|
|
if ed.brush_size < 1.0 { ed.brush_size = 1.0 }
|
|
if ed.brush_size > 80.0 { ed.brush_size = 80.0 }
|
|
} else {
|
|
editor_zoom_at_mouse(ed, mouse, wheel * 0.1)
|
|
}
|
|
}
|
|
|
|
image_rect, _ := editor_image_dest_rect(ed)
|
|
in_image := mx >= image_rect.x && mx <= image_rect.x + image_rect.width && my >= image_rect.y && my <= image_rect.y + image_rect.height
|
|
|
|
if ed.current_tool == .Move && !ed.is_panning && !space_down {
|
|
canvas_pos := editor_clamp_canvas_pos(ed, editor_screen_to_canvas(ed, mouse))
|
|
if rl.IsMouseButtonPressed(.LEFT) && in_image {
|
|
handle := editor_selection_handle_at_screen_pos(ed, mouse)
|
|
if ed.selection_active && handle != .None {
|
|
ed.is_resizing_selection = true
|
|
ed.active_selection_handle = handle
|
|
ed.selection_drag_origin = ed.selection_rect
|
|
ed.selection_resize_anchor = editor_selection_opposite_corner(ed.selection_rect, handle)
|
|
} else if ed.selection_active && editor_rect_contains_point(ed.selection_rect, canvas_pos) {
|
|
ed.is_moving_selection = true
|
|
ed.selection_drag_start = canvas_pos
|
|
ed.selection_drag_origin = ed.selection_rect
|
|
} else {
|
|
ed.selection_active = false
|
|
ed.is_moving_selection = false
|
|
ed.is_resizing_selection = false
|
|
ed.active_selection_handle = .None
|
|
ed.is_drawing = true
|
|
ed.draw_start = canvas_pos
|
|
clear(&ed.current_stroke.points)
|
|
append(&ed.current_stroke.points, canvas_pos)
|
|
ed.current_stroke.tool = .Move
|
|
}
|
|
}
|
|
if ed.is_resizing_selection && rl.IsMouseButtonDown(.LEFT) {
|
|
end_pos := editor_constrain_shape_point(.Crop, ed.selection_resize_anchor, canvas_pos, shift_down)
|
|
ed.selection_rect = editor_clamp_rect_to_image(ed, editor_make_rect_from_points(ed.selection_resize_anchor, end_pos))
|
|
}
|
|
if ed.is_moving_selection && rl.IsMouseButtonDown(.LEFT) {
|
|
dx := vec2_x(canvas_pos) - vec2_x(ed.selection_drag_start)
|
|
dy := vec2_y(canvas_pos) - vec2_y(ed.selection_drag_start)
|
|
ed.selection_rect = editor_move_rect_within_image(ed, rl.Rectangle{ed.selection_drag_origin.x + dx, ed.selection_drag_origin.y + dy, ed.selection_drag_origin.width, ed.selection_drag_origin.height})
|
|
}
|
|
if ed.is_drawing && rl.IsMouseButtonDown(.LEFT) {
|
|
end_pos := editor_constrain_shape_point(.Crop, ed.draw_start, canvas_pos, shift_down)
|
|
if len(ed.current_stroke.points) > 1 {
|
|
ed.current_stroke.points[len(ed.current_stroke.points)-1] = end_pos
|
|
} else {
|
|
append(&ed.current_stroke.points, end_pos)
|
|
}
|
|
}
|
|
if ed.is_resizing_selection && rl.IsMouseButtonReleased(.LEFT) {
|
|
ed.is_resizing_selection = false
|
|
ed.active_selection_handle = .None
|
|
return
|
|
}
|
|
if ed.is_moving_selection && rl.IsMouseButtonReleased(.LEFT) {
|
|
ed.is_moving_selection = false
|
|
if ed.selection_rect.x != ed.selection_drag_origin.x || ed.selection_rect.y != ed.selection_drag_origin.y {
|
|
push_status(&app.status_msg, &app.action_log, editor_apply_move_selection(ed, ed.selection_drag_origin, ed.selection_rect))
|
|
}
|
|
}
|
|
if ed.is_drawing && rl.IsMouseButtonReleased(.LEFT) {
|
|
ed.is_drawing = false
|
|
if len(ed.current_stroke.points) >= 2 {
|
|
ed.selection_rect = editor_clamp_rect_to_image(ed, editor_make_rect_from_points(ed.current_stroke.points[0], ed.current_stroke.points[len(ed.current_stroke.points)-1]))
|
|
ed.selection_active = ed.selection_rect.width >= 2 && ed.selection_rect.height >= 2
|
|
}
|
|
clear(&ed.current_stroke.points)
|
|
return
|
|
}
|
|
}
|
|
if ed.current_tool == .Move {
|
|
return
|
|
}
|
|
|
|
if !ed.is_panning && !space_down && (in_image || ed.is_drawing) {
|
|
if rl.IsMouseButtonPressed(.LEFT) {
|
|
canvas_pos := editor_clamp_canvas_pos(ed, editor_screen_to_canvas(ed, mouse))
|
|
|
|
if ed.current_tool == .Color_Pick {
|
|
picked, ok := editor_sample_composited_color(ed, canvas_pos)
|
|
if ok {
|
|
ed.brush_color = picked
|
|
editor_push_recent_color(ed, picked)
|
|
}
|
|
} else if ed.current_tool == .Fill {
|
|
push_status(&app.status_msg, &app.action_log, editor_apply_fill(ed, canvas_pos))
|
|
return
|
|
} else {
|
|
ed.is_drawing = true
|
|
ed.draw_start = canvas_pos
|
|
clear(&ed.current_stroke.points)
|
|
append(&ed.current_stroke.points, canvas_pos)
|
|
ed.current_stroke.color = ed.brush_color
|
|
effective_size := ed.brush_size * pen_tablet_pressure_for_stroke(pen)
|
|
ed.current_stroke.thickness = effective_size
|
|
ed.current_stroke.tool = ed.current_tool
|
|
ed.current_stroke.filled = !ed.shape_outline_only
|
|
if ed.current_tool == .Eraser || pen.eraser {
|
|
ed.current_stroke.color = rl.Color{0, 0, 0, 0}
|
|
ed.current_stroke.thickness = effective_size * 2
|
|
}
|
|
}
|
|
}
|
|
|
|
if ed.is_drawing && rl.IsMouseButtonDown(.LEFT) {
|
|
canvas_pos := editor_clamp_canvas_pos(ed, editor_screen_to_canvas(ed, mouse))
|
|
canvas_pos = editor_constrain_shape_point(ed.current_tool, ed.draw_start, canvas_pos, shift_down)
|
|
if ed.current_tool == .Pen || ed.current_tool == .Eraser {
|
|
append(&ed.current_stroke.points, canvas_pos)
|
|
} else {
|
|
if len(ed.current_stroke.points) > 1 {
|
|
ed.current_stroke.points[len(ed.current_stroke.points)-1] = canvas_pos
|
|
} else {
|
|
append(&ed.current_stroke.points, canvas_pos)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ed.is_drawing && rl.IsMouseButtonReleased(.LEFT) {
|
|
ed.is_drawing = false
|
|
|
|
if ed.current_tool == .Crop {
|
|
if len(ed.current_stroke.points) >= 2 {
|
|
p0 := ed.current_stroke.points[0]
|
|
p1 := ed.current_stroke.points[len(ed.current_stroke.points)-1]
|
|
crop_rect := rl.Rectangle{min(vec2_x(p0), vec2_x(p1)), min(vec2_y(p0), vec2_y(p1)), abs(vec2_x(p1) - vec2_x(p0)), abs(vec2_y(p1) - vec2_y(p0))}
|
|
push_status(&app.status_msg, &app.action_log, editor_apply_crop(ed, crop_rect))
|
|
}
|
|
ed.current_stroke = Brush_Stroke{}
|
|
ed.current_stroke.points = make([dynamic]rl.Vector2)
|
|
ed.current_stroke.color = ed.brush_color
|
|
ed.current_stroke.thickness = ed.brush_size
|
|
ed.current_stroke.tool = ed.current_tool
|
|
ed.current_stroke.filled = !ed.shape_outline_only
|
|
return
|
|
}
|
|
|
|
editor_push_undo(ed)
|
|
|
|
rl.BeginTextureMode(ed.drawing_rt)
|
|
if ed.current_tool == .Eraser {
|
|
rl.BeginBlendMode(.ALPHA)
|
|
}
|
|
editor_render_stroke(ed.current_stroke)
|
|
if ed.current_tool == .Eraser {
|
|
rl.EndBlendMode()
|
|
}
|
|
rl.EndTextureMode()
|
|
|
|
append(&ed.committed_strokes, ed.current_stroke)
|
|
ed.current_stroke = Brush_Stroke{}
|
|
ed.current_stroke.points = make([dynamic]rl.Vector2)
|
|
ed.current_stroke.color = ed.brush_color
|
|
ed.current_stroke.thickness = ed.brush_size
|
|
ed.current_stroke.tool = ed.current_tool
|
|
ed.current_stroke.filled = !ed.shape_outline_only
|
|
|
|
ed.needs_redraw = true
|
|
}
|
|
}
|