~rycwo/forge

ref: HEAD forge/src/gui_input.c -rw-r--r-- 2.3 KiB
d7ee94d6Ryan Chan Fix missing cd in .build.yml 14 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// This file is part of Forge, the foundation library for Forge tools.
//
// Copyright (C) 2021 Ryan Chan <rycwo@posteo.net>
// SPDX-License-Identifier: GPL-3.0-only
//
// This Source Code Form is subject to the terms of the GNU General Public
// License v3.0 only. You should have received a copy of the license along with
// this program. If not, see <https://www.gnu.org/licenses/>.

#include "forge/gui_input.h"

#include <assert.h>

#include "forge/gui_util.h"
#include "forge/vector.h"

static inline bool
check_bounds(fg_vec2 const pos, fg_vec4 const rect) {
	return pos[0] > rect[0] && pos[0] < (rect[0] + rect[2])
		&& pos[1] > rect[1] && pos[1] < (rect[1] + rect[3]);
}

void
fg_set_gui_cursor_position(struct fg_gui_input* input, fg_vec2 const pos) {
	fg_vec2_sub(input->cursor_pos_delta, pos, input->cursor_pos);
	fg_vec2_copy(input->cursor_pos, pos);
}

void
fg_set_gui_mouse_buttons(struct fg_gui_input* input, int mouse_buttons) {
	input->mouse_press = ~(input->mouse) & mouse_buttons;
	input->mouse_release = input->mouse & ~mouse_buttons;
	input->mouse = mouse_buttons;
}

void
fg_gui_viewport_size(struct fg_gui_context const* context, fg_vec2 size) {
	assert(context->layout.size > 0);
	size[0] = context->layout.buf[0][2];
	size[1] = context->layout.buf[0][3];
}

void
fg_set_gui_viewport_size(
		struct fg_gui_context* context,
		fg_vec2 const size) {
	assert(context->layout.capacity > 0);
	context->layout.buf[0][2] = size[0];
	context->layout.buf[0][3] = size[1];
}

bool
fg_gui_item_hovered(
		struct fg_gui_context* context,
		uint64_t id,
		fg_vec4 const rect) {
	fg_vec4 transformed_rect;
	fg_gui_transform_rect(context, transformed_rect, rect);
	if (context->layer >= context->next_hover_layer
			&& check_bounds(context->input.cursor_pos, transformed_rect)) {
		context->next_hover = id;
		context->next_hover_layer = context->layer;
	}
	return context->hover == id;
}

bool
fg_gui_item_pressed(
		struct fg_gui_context* context,
		uint64_t id,
		fg_vec4 const rect,
		int mouse_buttons,
		bool* hovered) {
	*hovered = fg_gui_item_hovered(context, id, rect);
	if (*hovered
			&& !context->active
			&& context->input.mouse_press & mouse_buttons)
		context->active = id;
	else if (context->active == id
			&& !(context->input.mouse & mouse_buttons))
		context->active = 0;
	return context->active == id;
}