Obecnie staram się zrobić input w bibliotece SDL2. Brakuje już tylko jednej rzeczy, kiedy jest za dużo tekstu i użytkownik ma kursor na lewej krawędzi, oraz klika strzałkę w lewo, tekst powinien przesuwać się w prawo. Ma ktoś pomysł, jak to zrobić? Obecny kod:
struct Input {
SDL_Rect r{};
Text text;
SDL_Rect cursorR{};
int currentLetter = 0; // NOTE: 0 == cursor is before first letter or on r.x on empty string
void handleEvent(SDL_Event event, SDL_Renderer* renderer, TTF_Font* font)
{
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.scancode == SDL_SCANCODE_BACKSPACE) {
if (currentLetter) {
utf8Erase(text.text, currentLetter - 1);
text.setText(renderer, font, text.text, {});
--currentLetter;
cursorR.x = calcCursorX(currentLetter, text, renderer, font, r);
}
}
else if (event.key.keysym.scancode == SDL_SCANCODE_LEFT) {
if (currentLetter) {
--currentLetter;
cursorR.x = calcCursorX(currentLetter, text, renderer, font, r);
}
}
else if (event.key.keysym.scancode == SDL_SCANCODE_RIGHT) {
if (currentLetter != utf8ToUcs4(text.text).size()) {
++currentLetter;
cursorR.x = calcCursorX(currentLetter, text, renderer, font, r);
}
}
}
else if (event.type == SDL_TEXTINPUT) {
utf8Insert(text.text, currentLetter, event.text.text);
text.setText(renderer, font, text.text, {});
++currentLetter;
cursorR.x = calcCursorX(currentLetter, text, renderer, font, r);
}
}
void draw(SDL_Renderer* renderer, TTF_Font* font)
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0);
SDL_RenderFillRect(renderer, &r);
static Text t;
t = text;
int count = 0;
while (t.dstR.x + t.dstR.w > r.x + r.w) {
utf8Erase(t.text, 0);
t.setText(renderer, font, t.text, {});
--currentLetter;
cursorR.x = calcCursorX(currentLetter, text, renderer, font, r);
++count;
}
t.draw(renderer);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 0);
SDL_RenderFillRect(renderer, &cursorR);
for (int i = 0; i < count; ++i) {
++currentLetter;
cursorR.x = calcCursorX(currentLetter, text, renderer, font, r);
}
}
};
Tutaj kod struktury Text oraz funkcja renderText:
SDL_Texture* renderText(SDL_Texture* previousTexture, TTF_Font* font, SDL_Renderer* renderer, const std::string& text, SDL_Color color)
{
if (previousTexture) {
SDL_DestroyTexture(previousTexture);
}
SDL_Surface* surface;
if (text.empty()) {
surface = TTF_RenderUTF8_Blended(font, " ", color);
}
else {
surface = TTF_RenderUTF8_Blended(font, text.c_str(), color);
}
if (surface) {
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
return texture;
}
else {
return 0;
}
}
struct Text {
std::string text;
SDL_Surface* surface = 0;
SDL_Texture* t = 0;
SDL_FRect dstR{};
bool autoAdjustW = false;
bool autoAdjustH = false;
float wMultiplier = 1;
float hMultiplier = 1;
~Text()
{
if (surface) {
SDL_FreeSurface(surface);
}
if (t) {
SDL_DestroyTexture(t);
}
}
Text()
{
}
Text(const Text& rightText)
{
text = rightText.text;
if (surface) {
SDL_FreeSurface(surface);
}
if (t) {
SDL_DestroyTexture(t);
}
if (rightText.surface) {
surface = SDL_ConvertSurface(rightText.surface, rightText.surface->format, SDL_SWSURFACE);
}
if (rightText.t) {
t = SDL_CreateTextureFromSurface(renderer, surface);
}
dstR = rightText.dstR;
autoAdjustW = rightText.autoAdjustW;
autoAdjustH = rightText.autoAdjustH;
wMultiplier = rightText.wMultiplier;
hMultiplier = rightText.hMultiplier;
}
Text& operator=(const Text& rightText)
{
text = rightText.text;
if (surface) {
SDL_FreeSurface(surface);
}
if (t) {
SDL_DestroyTexture(t);
}
if (rightText.surface) {
surface = SDL_ConvertSurface(rightText.surface, rightText.surface->format, SDL_SWSURFACE);
}
if (rightText.t) {
t = SDL_CreateTextureFromSurface(renderer, surface);
}
dstR = rightText.dstR;
autoAdjustW = rightText.autoAdjustW;
autoAdjustH = rightText.autoAdjustH;
wMultiplier = rightText.wMultiplier;
hMultiplier = rightText.hMultiplier;
return *this;
}
void setText(SDL_Renderer* renderer, TTF_Font* font, std::string text, SDL_Color c = { 255,255,255 })
{
this->text = text;
#if 1 // NOTE: renderText
if (surface) {
SDL_FreeSurface(surface);
}
if (t) {
SDL_DestroyTexture(t);
}
if (text.empty()) {
surface = TTF_RenderUTF8_Blended(font, " ", c);
}
else {
surface = TTF_RenderUTF8_Blended(font, text.c_str(), c);
}
if (surface) {
t = SDL_CreateTextureFromSurface(renderer, surface);
}
#endif
if (autoAdjustW) {
SDL_QueryTextureF(t, 0, 0, &dstR.w, 0);
}
if (autoAdjustH) {
SDL_QueryTextureF(t, 0, 0, 0, &dstR.h);
}
dstR.w *= wMultiplier;
dstR.h *= hMultiplier;
}
void setText(SDL_Renderer* renderer, TTF_Font* font, int value, SDL_Color c = { 255,255,255 })
{
setText(renderer, font, std::to_string(value), c);
}
void draw(SDL_Renderer* renderer)
{
if (t) {
SDL_RenderCopyF(renderer, t, 0, &dstR);
}
}
};