Text input :)

master
Auri 2021-09-04 00:25:34 -07:00
parent a08af1b260
commit 1955331519
9 changed files with 90 additions and 56 deletions

View File

@ -6,7 +6,6 @@
#include "util/Types.h"
class CallbackRef {
public:
CallbackRef() = default;

View File

@ -9,6 +9,7 @@
void Input::init(GLFWwindow* window) {
this->window = window;
glfwSetKeyCallback(window, keyCallback);
glfwSetCharCallback(window, charCallback);
glfwSetScrollCallback(window, scrollCallback);
glfwSetMouseButtonCallback(window, mouseCallback);
}
@ -61,10 +62,14 @@ ivec2 Input::getMouseDelta() {
}
void Input::updateKey(u32 key, i32 state) {
if (state == GLFW_REPEAT) return;
keyState[key] = state != GLFW_RELEASE && state != 3;
events.call(CBType::KEY, key, state);
events.call(state != GLFW_RELEASE ? CBType::KEY_PRESS : CBType::KEY_RELEASE, key, state);
events.call(state == GLFW_PRESS ? CBType::KEY_PRESS :
state == GLFW_RELEASE ? CBType::KEY_RELEASE : CBType::KEY_REPEAT, key, state);
}
void Input::updateChar(u32 codepoint) {
events.call(CBType::CHAR, codepoint, 0);
}
void Input::updateMouse(u32 button, i32 state) {
@ -80,10 +85,15 @@ void Input::scrollCallback(GLFWwindow* window, f64 x, f64 y) {
void Input::keyCallback(GLFWwindow* window, i32 key, i32, i32 action, i32) {
let& self = static_cast<Window*>(glfwGetWindowUserPointer(window))->input;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE);
if (key == GLFW_KEY_LEFT_ALT) glfwSetWindowShouldClose(window, GL_TRUE);
else if (key >= 32 && key < 1024) self.updateKey(key, action);
}
void Input::charCallback(GLFWwindow* window, u32 codepoint) {
let& self = static_cast<Window*>(glfwGetWindowUserPointer(window))->input;
self.updateChar(codepoint);
}
void Input::mouseCallback(GLFWwindow* window, i32 button, i32 action, i32) {
let& self = static_cast<Window*>(glfwGetWindowUserPointer(window))->input;
self.updateMouse(button, action);

View File

@ -48,7 +48,9 @@ public:
enum class CBType {
KEY,
KEY_PRESS,
KEY_REPEAT,
KEY_RELEASE,
CHAR,
MOUSE,
MOUSE_PRESS,
MOUSE_RELEASE,
@ -62,6 +64,9 @@ private:
/** Calls the key callbacks and sets the key state of the key provided. */
void updateKey(u32 key, i32 state);
/** Calls the char callbacks with the codepoint provided. */
void updateChar(u32 codepoint);
/** Calls the button callbacks and sets the button state of the mouse button provided. */
void updateMouse(u32 button, i32 state);
@ -75,6 +80,9 @@ private:
/** Calls the updateKey function with the proper key and state. */
static void keyCallback(GLFWwindow* window, i32 key, i32 code, i32 action, i32 mode);
/** Calls the updateChar function with the proper codepoint. */
static void charCallback(GLFWwindow* window, u32 codepoint);
/** Calls the updateMouse function with the proper button and state. */
static void mouseCallback(GLFWwindow* window, i32 key, i32 action, i32 mods);

View File

@ -5,14 +5,36 @@
#include "client/Input.h"
#include "lua/LocalLuaParser.h"
// http://www.zedwood.com/article/cpp-utf8-char-to-codepoint
string utf8chr(i32 cp) {
char c[5]={ 0x00,0x00,0x00,0x00,0x00 };
if (cp<=0x7F) { c[0] = cp; }
else if(cp<=0x7FF) { c[0] = (cp>>6)+192; c[1] = (cp&63)+128; }
else if(0xd800<=cp && cp<=0xdfff) {} //invalid block of utf8
else if(cp<=0xFFFF) { c[0] = (cp>>12)+224; c[1]= ((cp>>6)&63)+128; c[2]=(cp&63)+128; }
else if(cp<=0x10FFFF) { c[0] = (cp>>18)+240; c[1] = ((cp>>12)&63)+128; c[2] = ((cp>>6)&63)+128; c[3]=(cp&63)+128; }
return string(c);
}
usize Api::Usertype::KeyObserver::ID_NEXT = 0;
void Api::Usertype::KeyObserver::start() {
if (nativeCBs.size()) return;
parser.addKBObserver(id);
nativeCBs.emplace_back(input.events.bind(Input::CBType::KEY, [&](i32 key, u32 state) {
if (state == GLFW_PRESS && on_press) on_press(key);
else if (state == GLFW_RELEASE && on_release) on_release(key);
if (key == GLFW_KEY_BACKSPACE && state != GLFW_RELEASE && buffer.size()) {
buffer.pop_back();
if (on_change) on_change(buffer);
}
}));
nativeCBs.emplace_back(input.events.bind(Input::CBType::CHAR, [&](i32 codepoint, u32) {
buffer += utf8chr(codepoint);
if (on_change) on_change(buffer);
}));
}
@ -21,6 +43,16 @@ void Api::Usertype::KeyObserver::stop() {
nativeCBs.clear();
}
const string& Api::Usertype::KeyObserver::getBuffer() {
std::cout << "getting buffre :)" << std::endl;
return buffer;
}
void Api::Usertype::KeyObserver::setBuffer(const string& buffer) {
this->buffer = buffer;
if (on_change) on_change(this->buffer);
}
Api::Usertype::KeyObserver::~KeyObserver() {
stop();
}
@ -34,8 +66,10 @@ void Api::Usertype::KeyObserver::bind(sol::state& lua, sol::table& core, Input&
"start", &KeyObserver::start,
"stop", &KeyObserver::stop,
"buffer", sol::property(&KeyObserver::getBuffer, &KeyObserver::setBuffer),
"on_press", &KeyObserver::on_press,
"on_release", &KeyObserver::on_release,
"on_change", &KeyObserver::on_change
);
}
}

View File

@ -18,20 +18,24 @@ namespace Api::Usertype {
void stop();
const string& getBuffer();
void setBuffer(const string& buffer);
static void bind(sol::state& lua, sol::table& core, Input& input, LocalLuaParser& parser);
private:
usize id = 0;
bool active = false;
string buffer {};
sol::protected_function on_press = sol::nil;
sol::protected_function on_release = sol::nil;
sol::protected_function on_change = sol::nil;
vec<CallbackRef> nativeCBs {};
usize id = 0;
bool active = false;
Input& input;
LocalLuaParser& parser;
vec<CallbackRef> nativeCBs {};
static usize ID_NEXT;
};

View File

@ -51,6 +51,7 @@ void Server::update() {
break;
case ENET_EVENT_TYPE_DISCONNECT:
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
clients.handleDisconnect(event);
break;
@ -66,6 +67,7 @@ void Server::update() {
break;
}
}
}

View File

@ -40,24 +40,20 @@ local chat_menu_tabs = chat_menu:get('chat_tabs')
local chat_menu_input = chat_menu:get('chat_input')
local chat_menu_input_text = chat_menu:get('chat_input_text')
local chat_buffer = ''
local pipe = '`r` `c1|'
local has_pipe = false
local observer = KeyObserver.new()
observer.on_press = function(keycode)
local key = zepha.keycodes[keycode]
if key == 'enter' then return
elseif key == 'space' then chat_buffer = chat_buffer .. ' '
elseif key == 'backspace' then chat_buffer = chat_buffer:sub(1, chat_buffer:len() - 1)
else chat_buffer = chat_buffer .. key end
chat_menu_input_text.content = chat_buffer .. (has_pipe and pipe or '')
local function update_content()
chat_menu_input_text.content = observer.buffer .. (has_pipe and pipe or '')
end
observer.on_change = update_content
zepha.after(function()
if not chat.open then return true end
has_pipe = not has_pipe
chat_menu_input_text.content = chat_buffer .. (has_pipe and pipe or '')
update_content()
return true
end, 0.5)
@ -70,11 +66,13 @@ chat._refresh = function()
if chat.open then
chat_menu_tabs:clear()
update_content()
local i = 0
for _, identifier in ipairs(chat.channel_order) do
local channel = chat.channels[identifier]
chat_menu_tabs:append(zepha.Gui.Box {
cursor = 'pointer',
size = { '48dp', '10dp' },
pos = { i * 49 .. 'dp', '0dp' },
background = (chat.current_channel == identifier) and '#0005' or '#0002',
@ -132,20 +130,15 @@ chat.set_open = function(open)
if open == nil then chat.open = not chat.open
else chat.open = open end
if chat.open then
observer:start()
else
observer:stop()
chat_buffer = ''
end
if chat.open then zepha.after(function() observer:start() end, 0.05)
else observer:stop() end
observer.buffer = ''
zepha.player.menu = chat.open and chat_menu or nil
chat._refresh()
end
-- Keyboard shortcut to toggle the chat.
zepha.register_keybind(":open_chat", {
description = "Open Chat",
default = zepha.keys.p,
@ -155,13 +148,22 @@ zepha.register_keybind(":open_chat", {
end
})
zepha.register_keybind(":close_chat", {
description = "Close Chat",
default = zepha.keys.escape,
on_press = function()
if not chat.open then return end
chat.set_open()
end
})
-- Keyboard shortcut to send the message
zepha.register_keybind(":send_message", {
description = "Send Message",
default = zepha.keys.enter,
on_press = function()
if not chat.open then return end
chat.send(chat_buffer)
if observer.buffer:len() > 0 then chat.send(observer.buffer) end
chat.set_open()
end
})

View File

@ -1,29 +1,4 @@
if zepha.server then
chat.create_channel('commands', { name = 'Commands', icon = '@auri:chat:commands_icon' })
chat.create_channel('debug', { name = 'Debug', icon = '@auri:chat:debug_icon' })
-- local random_messages = {
-- { '`b`cbA`cdu`cfr`cdi`cb!', 'the quick brown fox jumps over the lazy dog' },
-- { '`b`cbA`cdu`cfr`cdi`cb!', 'lorum ipsum dolor sit amet consequitor lorem ipsum dolor sit amet' },
-- { '`b`cbZ`cay`cet`cch`cdi`c5a', '`iomg shut the fuck up`r' },
-- { '`b`cbA`cdu`cfr`cdi`cb!', 'lol epic' },
-- { '`b`cbA`cdu`cfr`cdi`cb!', 'chat mod' },
-- { '`b`cbZ`cay`cet`cch`cdi`c5a', 'testing testing 123' },
-- { '`bJAYCEE', 'PENIS!' },
-- { '`b`cbA`cdu`cfr`cdi`cb!', '#epic' },
-- { 'alphabet', '`bABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789' }
-- }
--
-- local function random_message()
-- local message = random_messages[math.floor(math.random() * #random_messages) + 1]
-- chat.send(message[1], message[2])
-- zepha.after(random_message, math.random() > 0.5 and math.random() * 1 or math.random() * 2)
-- end
-- random_message()
elseif zepha.client then
zepha.register_keybind(":send_test_message", {
description = "Send test message",
default = zepha.keys.j,
on_press = function() chat.send('hihihih') end
})
end

View File

@ -145,13 +145,13 @@ local noise = {
-- heightmap = {
-- module = "add",
-- sources = {
-- runfile(_PATH .. 'world_noise'),
-- require(_PATH .. 'world_noise'),
-- {
-- module = "max",
-- scalar = 0,
-- source = {
-- module = "add",
-- scalar = -150,
-- scalar = -50,
-- source = {
-- module = "multiply",
-- scalar = 400,
@ -172,7 +172,7 @@ local noise = {
y_scale = 2,
source = {
module = "add",
scalar = -2200,
scalar = -1800,
source = {
module = "multiply",
scalar = 3000,