Text input :)
parent
a08af1b260
commit
1955331519
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "util/Types.h"
|
||||
|
||||
|
||||
class CallbackRef {
|
||||
public:
|
||||
CallbackRef() = default;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
})
|
|
@ -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
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue