Add Chat / Pastes / Formatting (#682)
* Initial fixes for ContainerSetSlotPacket and CraftItemPacket * Chat: paste, history, § formatting, 1-9 block when open (Windows64) Made-with: Cursor * static_cast refactor
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Screen.h"
|
||||
#include "Button.h"
|
||||
#include "ChatScreen.h"
|
||||
#include "GuiParticles.h"
|
||||
#include "Tesselator.h"
|
||||
#include "Textures.h"
|
||||
@@ -42,13 +43,32 @@ void Screen::keyPressed(wchar_t eventCharacter, int eventKey)
|
||||
|
||||
wstring Screen::getClipboard()
|
||||
{
|
||||
// 4J - removed
|
||||
return NULL;
|
||||
#ifdef _WINDOWS64
|
||||
if (!OpenClipboard(NULL)) return wstring();
|
||||
HANDLE h = GetClipboardData(CF_UNICODETEXT);
|
||||
wstring out;
|
||||
if (h)
|
||||
{
|
||||
const wchar_t *p = reinterpret_cast<const wchar_t*>(GlobalLock(h));
|
||||
if (p) { out = p; GlobalUnlock(h); }
|
||||
}
|
||||
CloseClipboard();
|
||||
return out;
|
||||
#else
|
||||
return wstring();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::setClipboard(const wstring& str)
|
||||
{
|
||||
// 4J - removed
|
||||
#ifdef _WINDOWS64
|
||||
if (!OpenClipboard(NULL)) return;
|
||||
EmptyClipboard();
|
||||
size_t len = (str.length() + 1) * sizeof(wchar_t);
|
||||
HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, len);
|
||||
if (h) { memcpy(GlobalLock(h), str.c_str(), len); GlobalUnlock(h); SetClipboardData(CF_UNICODETEXT, h); }
|
||||
CloseClipboard();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Screen::mouseClicked(int x, int y, int buttonNum)
|
||||
@@ -121,34 +141,88 @@ void Screen::updateEvents()
|
||||
}
|
||||
}
|
||||
|
||||
// Poll keyboard events
|
||||
// Only drain WM_CHAR when this screen wants text input (e.g. ChatScreen); otherwise we'd steal keys from the game
|
||||
if (dynamic_cast<ChatScreen*>(this) != nullptr)
|
||||
{
|
||||
wchar_t ch;
|
||||
while (g_KBMInput.ConsumeChar(ch))
|
||||
{
|
||||
if (ch >= 0x20)
|
||||
keyPressed(ch, -1);
|
||||
else if (ch == 0x08)
|
||||
keyPressed(0, Keyboard::KEY_BACK);
|
||||
else if (ch == 0x0D)
|
||||
keyPressed(0, Keyboard::KEY_RETURN);
|
||||
}
|
||||
}
|
||||
|
||||
// Arrow key repeat: deliver on first press (when key down and last==0) and while held (throttled)
|
||||
static DWORD s_arrowLastTime[2] = { 0, 0 };
|
||||
static bool s_arrowFirstRepeat[2] = { false, false };
|
||||
const DWORD ARROW_REPEAT_DELAY_MS = 250;
|
||||
const DWORD ARROW_REPEAT_INTERVAL_MS = 50;
|
||||
DWORD now = GetTickCount();
|
||||
|
||||
// Poll keyboard events (special keys that may not come through WM_CHAR, e.g. Escape, arrows)
|
||||
for (int vk = 0; vk < 256; vk++)
|
||||
{
|
||||
if (g_KBMInput.IsKeyPressed(vk))
|
||||
bool deliver = g_KBMInput.IsKeyPressed(vk);
|
||||
if (vk == VK_LEFT || vk == VK_RIGHT)
|
||||
{
|
||||
// Map Windows virtual key to the Keyboard constants used by Screen::keyPressed
|
||||
int mappedKey = -1;
|
||||
wchar_t ch = 0;
|
||||
if (vk == VK_ESCAPE) mappedKey = Keyboard::KEY_ESCAPE;
|
||||
else if (vk == VK_RETURN) mappedKey = Keyboard::KEY_RETURN;
|
||||
else if (vk == VK_BACK) mappedKey = Keyboard::KEY_BACK;
|
||||
else if (vk == VK_UP) mappedKey = Keyboard::KEY_UP;
|
||||
else if (vk == VK_DOWN) mappedKey = Keyboard::KEY_DOWN;
|
||||
else if (vk == VK_LEFT) mappedKey = Keyboard::KEY_LEFT;
|
||||
else if (vk == VK_RIGHT) mappedKey = Keyboard::KEY_RIGHT;
|
||||
else if (vk == VK_LSHIFT || vk == VK_RSHIFT) mappedKey = Keyboard::KEY_LSHIFT;
|
||||
else if (vk == VK_TAB) mappedKey = Keyboard::KEY_TAB;
|
||||
else if (vk >= 'A' && vk <= 'Z')
|
||||
int idx = (vk == VK_LEFT) ? 0 : 1;
|
||||
if (!g_KBMInput.IsKeyDown(vk))
|
||||
{
|
||||
ch = (wchar_t)(vk - 'A' + L'a');
|
||||
if (g_KBMInput.IsKeyDown(VK_LSHIFT) || g_KBMInput.IsKeyDown(VK_RSHIFT)) ch = (wchar_t)vk;
|
||||
s_arrowLastTime[idx] = 0;
|
||||
s_arrowFirstRepeat[idx] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD last = s_arrowLastTime[idx];
|
||||
if (last == 0)
|
||||
deliver = true;
|
||||
else if (!deliver)
|
||||
{
|
||||
DWORD interval = s_arrowFirstRepeat[idx] ? ARROW_REPEAT_INTERVAL_MS : ARROW_REPEAT_DELAY_MS;
|
||||
if ((now - last) >= interval)
|
||||
{
|
||||
deliver = true;
|
||||
s_arrowFirstRepeat[idx] = true;
|
||||
}
|
||||
}
|
||||
if (deliver)
|
||||
s_arrowLastTime[idx] = now;
|
||||
}
|
||||
else if (vk >= '0' && vk <= '9') ch = (wchar_t)vk;
|
||||
else if (vk == VK_SPACE) ch = L' ';
|
||||
|
||||
if (mappedKey != -1) keyPressed(ch, mappedKey);
|
||||
else if (ch != 0) keyPressed(ch, -1);
|
||||
}
|
||||
// Escape: deliver when key is down so we don't miss it (IsKeyPressed can be one frame late)
|
||||
if (vk == VK_ESCAPE && g_KBMInput.IsKeyDown(VK_ESCAPE))
|
||||
deliver = true;
|
||||
if (!deliver) continue;
|
||||
|
||||
if (dynamic_cast<ChatScreen*>(this) != nullptr &&
|
||||
(vk >= 'A' && vk <= 'Z' || vk >= '0' && vk <= '9' || vk == VK_SPACE || vk == VK_RETURN || vk == VK_BACK))
|
||||
continue;
|
||||
// Map to Screen::keyPressed
|
||||
int mappedKey = -1;
|
||||
wchar_t ch = 0;
|
||||
if (vk == VK_ESCAPE) mappedKey = Keyboard::KEY_ESCAPE;
|
||||
else if (vk == VK_RETURN) mappedKey = Keyboard::KEY_RETURN;
|
||||
else if (vk == VK_BACK) mappedKey = Keyboard::KEY_BACK;
|
||||
else if (vk == VK_UP) mappedKey = Keyboard::KEY_UP;
|
||||
else if (vk == VK_DOWN) mappedKey = Keyboard::KEY_DOWN;
|
||||
else if (vk == VK_LEFT) mappedKey = Keyboard::KEY_LEFT;
|
||||
else if (vk == VK_RIGHT) mappedKey = Keyboard::KEY_RIGHT;
|
||||
else if (vk == VK_LSHIFT || vk == VK_RSHIFT) mappedKey = Keyboard::KEY_LSHIFT;
|
||||
else if (vk == VK_TAB) mappedKey = Keyboard::KEY_TAB;
|
||||
else if (vk >= 'A' && vk <= 'Z')
|
||||
{
|
||||
ch = static_cast<wchar_t>(vk - 'A' + L'a');
|
||||
if (g_KBMInput.IsKeyDown(VK_LSHIFT) || g_KBMInput.IsKeyDown(VK_RSHIFT)) ch = static_cast<wchar_t>(vk);
|
||||
}
|
||||
else if (vk >= '0' && vk <= '9') ch = static_cast<wchar_t>(vk);
|
||||
else if (vk == VK_SPACE) ch = L' ';
|
||||
|
||||
if (mappedKey != -1) keyPressed(ch, mappedKey);
|
||||
else if (ch != 0) keyPressed(ch, -1);
|
||||
}
|
||||
#else
|
||||
/* 4J - TODO
|
||||
@@ -232,10 +306,10 @@ void Screen::renderDirtBackground(int vo)
|
||||
float s = 32;
|
||||
t->begin();
|
||||
t->color(0x404040);
|
||||
t->vertexUV((float)(0), (float)( height), (float)( 0), (float)( 0), (float)( height / s + vo));
|
||||
t->vertexUV((float)(width), (float)( height), (float)( 0), (float)( width / s), (float)( height / s + vo));
|
||||
t->vertexUV((float)(width), (float)( 0), (float)( 0), (float)( width / s), (float)( 0 + vo));
|
||||
t->vertexUV((float)(0), (float)( 0), (float)( 0), (float)( 0), (float)( 0 + vo));
|
||||
t->vertexUV(static_cast<float>(0), static_cast<float>(height), static_cast<float>(0), static_cast<float>(0), static_cast<float>(height / s + vo));
|
||||
t->vertexUV(static_cast<float>(width), static_cast<float>(height), static_cast<float>(0), static_cast<float>(width / s), static_cast<float>(height / s + vo));
|
||||
t->vertexUV(static_cast<float>(width), static_cast<float>(0), static_cast<float>(0), static_cast<float>(width / s), static_cast<float>(0 + vo));
|
||||
t->vertexUV(static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(0), static_cast<float>(0 + vo));
|
||||
t->end();
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user