Move things from crosslang to here
This commit is contained in:
384
src/SDL2/Views/EditTextView.cpp
Normal file
384
src/SDL2/Views/EditTextView.cpp
Normal file
@ -0,0 +1,384 @@
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_SDL2)
|
||||
#include "TessesFramework/SDL2/Views/EditTextView.hpp"
|
||||
|
||||
namespace Tesses::Framework::SDL2::Views
|
||||
{
|
||||
EditTextView::EditTextView() : EditTextView(std::string())
|
||||
{
|
||||
|
||||
}
|
||||
EditTextView::EditTextView(std::string hint) : View()
|
||||
{
|
||||
this->hint = hint;
|
||||
this->cursorPos=0;
|
||||
this->cursorEnd=std::string::npos;
|
||||
}
|
||||
void EditTextView::TypeText(std::string text)
|
||||
{
|
||||
size_t cursorBegin = this->cursorPos;
|
||||
size_t cursorEnd = this->cursorEnd;
|
||||
if(cursorBegin > cursorEnd)
|
||||
{
|
||||
cursorBegin ^= cursorEnd;
|
||||
cursorEnd ^= cursorBegin;
|
||||
cursorBegin ^= cursorEnd;
|
||||
}
|
||||
|
||||
if(cursorEnd != std::string::npos && cursorEnd <= this->text.size())
|
||||
{
|
||||
this->text.erase(cursorBegin,cursorEnd-cursorBegin);
|
||||
this->text.insert(cursorBegin,text);
|
||||
}
|
||||
else if(cursorBegin <= this->text.size()) {
|
||||
this->text.insert(cursorBegin,text);
|
||||
|
||||
}
|
||||
|
||||
this->cursorPos = cursorBegin+text.size();
|
||||
this->cursorEnd = std::string::npos;
|
||||
|
||||
}
|
||||
void EditTextView::SetText(std::string text)
|
||||
{
|
||||
View::SetText(text);
|
||||
this->cursorPos=0;
|
||||
this->cursorEnd = std::string::npos;
|
||||
|
||||
}
|
||||
void EditTextView::SetHint(std::string hint)
|
||||
{
|
||||
this->hint = hint;
|
||||
}
|
||||
std::string EditTextView::GetHint()
|
||||
{
|
||||
return this->hint;
|
||||
}
|
||||
std::pair<int,int> EditTextView::PreferedMinSize()
|
||||
{
|
||||
int x=-2;
|
||||
int y=-2;
|
||||
auto win = this->GetWindow();
|
||||
if(win != nullptr)
|
||||
{
|
||||
x=-1;
|
||||
y=win->monospaced_font->MaxHeight()+16;
|
||||
|
||||
}
|
||||
|
||||
return std::pair<int,int>(x,y);
|
||||
}
|
||||
|
||||
bool EditTextView::OnEvent(SDL_Event& event, SDL_Rect& myBounds, SDL_Rect& myVisibleBounds)
|
||||
{
|
||||
if(this->GetViewFlag(VIEWFLAG_ISACTIVE))
|
||||
{
|
||||
if(event.type == SDL_TEXTINPUT)
|
||||
{
|
||||
if(this->GetViewFlag(VIEWFLAG_TOUCHED))
|
||||
{
|
||||
this->SetViewFlag(VIEWFLAG_TOUCHED,false);
|
||||
|
||||
if(!this->text.empty())
|
||||
{
|
||||
this->cursorPos=0;
|
||||
this->cursorEnd=this->text.size();
|
||||
}
|
||||
}
|
||||
TypeText(event.text.text);
|
||||
}
|
||||
else if(event.type == SDL_KEYDOWN)
|
||||
{
|
||||
switch(event.key.keysym.sym)
|
||||
{
|
||||
case SDL_KeyCode::SDLK_c:
|
||||
{
|
||||
if((event.key.keysym.mod & KMOD_CTRL) != 0)
|
||||
{
|
||||
size_t cursorBegin = cursorPos;
|
||||
size_t cursorEnd = this->cursorEnd;
|
||||
if(cursorBegin > cursorEnd)
|
||||
{
|
||||
cursorBegin ^= cursorEnd;
|
||||
cursorEnd ^= cursorBegin;
|
||||
cursorBegin ^= cursorEnd;
|
||||
}
|
||||
|
||||
if(cursorEnd != std::string::npos && cursorEnd <= this->text.size() && this->text.size() > 0)
|
||||
{
|
||||
std::string res = this->text.substr(cursorBegin,cursorEnd-cursorBegin);
|
||||
//SDL_GetClipboardText()
|
||||
SDL_SetClipboardText(res.c_str());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KeyCode::SDLK_v:
|
||||
{
|
||||
if((event.key.keysym.mod & KMOD_CTRL) != 0)
|
||||
{
|
||||
if(SDL_HasClipboardText())
|
||||
{
|
||||
char* text = SDL_GetClipboardText();
|
||||
if(text != NULL)
|
||||
{
|
||||
TypeText(text);
|
||||
}
|
||||
SDL_free(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KeyCode::SDLK_x:
|
||||
{
|
||||
if((event.key.keysym.mod & KMOD_CTRL) != 0)
|
||||
{
|
||||
size_t cursorBegin = cursorPos;
|
||||
size_t cursorEnd = this->cursorEnd;
|
||||
if(cursorBegin > cursorEnd)
|
||||
{
|
||||
cursorBegin ^= cursorEnd;
|
||||
cursorEnd ^= cursorBegin;
|
||||
cursorBegin ^= cursorEnd;
|
||||
}
|
||||
|
||||
if(cursorEnd != std::string::npos && cursorEnd <= this->text.size() && this->text.size() > 0)
|
||||
{
|
||||
std::string res = this->text.substr(cursorBegin,cursorEnd-cursorBegin);
|
||||
//SDL_GetClipboardText()
|
||||
SDL_SetClipboardText(res.c_str());
|
||||
|
||||
TypeText("");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KeyCode::SDLK_a:
|
||||
{
|
||||
if((event.key.keysym.mod & KMOD_CTRL) != 0)
|
||||
{
|
||||
this->cursorPos=0;
|
||||
this->cursorEnd=this->text.size();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KeyCode::SDLK_BACKSPACE:
|
||||
{
|
||||
if(this->cursorEnd == std::string::npos)
|
||||
{
|
||||
if(this->cursorPos > 0)
|
||||
{
|
||||
this->cursorPos--;
|
||||
this->text.erase(this->cursorPos,1);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
TypeText("");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KeyCode::SDLK_DELETE:
|
||||
{
|
||||
if(this->cursorEnd == std::string::npos)
|
||||
{
|
||||
if(this->cursorPos + 1 <= this->text.size())
|
||||
{
|
||||
this->text.erase(this->cursorPos,1);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
TypeText("");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KeyCode::SDLK_LEFT:
|
||||
{
|
||||
if((event.key.keysym.mod & KMOD_SHIFT) != 0)
|
||||
{
|
||||
if(this->cursorEnd > this->text.size())
|
||||
this->cursorEnd = this->cursorPos;
|
||||
|
||||
this->cursorEnd--;
|
||||
|
||||
|
||||
if(this->cursorEnd > this->text.size()) this->cursorEnd=0;
|
||||
if(this->cursorEnd == this->cursorPos) this->cursorEnd = std::string::npos;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cursorPos > cursorEnd)
|
||||
{
|
||||
cursorPos ^= cursorEnd;
|
||||
cursorEnd ^= cursorPos;
|
||||
cursorPos ^= cursorEnd;
|
||||
}
|
||||
this->cursorPos--;
|
||||
this->cursorEnd=std::string::npos;
|
||||
if(this->cursorPos > this->text.size()) this->cursorPos=0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_KeyCode::SDLK_RIGHT:
|
||||
if((event.key.keysym.mod & KMOD_SHIFT) != 0)
|
||||
{
|
||||
if(this->cursorEnd == std::string::npos)
|
||||
this->cursorEnd = this->cursorPos;
|
||||
|
||||
this->cursorEnd++;
|
||||
|
||||
|
||||
if(this->cursorEnd > this->text.size()) this->cursorEnd=this->text.size();
|
||||
if(this->cursorEnd == this->cursorPos) this->cursorEnd = std::string::npos;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cursorPos > cursorEnd)
|
||||
{
|
||||
cursorPos ^= cursorEnd;
|
||||
cursorEnd ^= cursorPos;
|
||||
cursorPos ^= cursorEnd;
|
||||
}
|
||||
if(cursorEnd != std::string::npos)
|
||||
{
|
||||
this->cursorPos=cursorEnd+1;
|
||||
|
||||
}else {
|
||||
this->cursorPos++;
|
||||
}
|
||||
this->cursorEnd=std::string::npos;
|
||||
if(this->cursorPos > this->text.size()) this->cursorPos=this->text.size();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event.type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
if(event.button.x >= myVisibleBounds.x && event.button.x < myVisibleBounds.x+myVisibleBounds.w && event.button.y >= myVisibleBounds.y && event.button.y < myVisibleBounds.y+myVisibleBounds.h)
|
||||
{
|
||||
this->GetWindow()->MakeActive(this);
|
||||
this->SetViewFlag(VIEWFLAG_TOUCHED,false);
|
||||
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
}
|
||||
if(event.type == SDL_FINGERDOWN)
|
||||
{
|
||||
auto pos = this->GetCordFromEvent(event);
|
||||
if(pos.first >= myVisibleBounds.x && pos.first < myVisibleBounds.x+myVisibleBounds.w && pos.second >= myVisibleBounds.y && pos.second < myVisibleBounds.y+myVisibleBounds.h)
|
||||
{
|
||||
this->GetWindow()->MakeActive(this);
|
||||
|
||||
this->SetViewFlag(VIEWFLAG_TOUCHED,true);
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
}
|
||||
return View::OnEvent(event,myBounds,myVisibleBounds);
|
||||
}
|
||||
void EditTextView::OnDraw(SDL_Renderer* renderer, SDL_Rect& r)
|
||||
{
|
||||
size_t cursorBegin = this->cursorPos;
|
||||
size_t cursorEnd = this->cursorEnd;
|
||||
if(cursorBegin > cursorEnd)
|
||||
{
|
||||
cursorBegin ^= cursorEnd;
|
||||
cursorEnd ^= cursorBegin;
|
||||
cursorBegin ^= cursorEnd;
|
||||
}
|
||||
auto win = this->GetWindow();
|
||||
//SDL_SetRenderDrawColor(renderer,win->palette.accent.r,win->palette.accent.g,win->palette.accent.b,win->palette.accent.a);
|
||||
//SDL_RenderFillRect(renderer,&r);
|
||||
|
||||
int textW=win->monospaced_font->MaxWidth()+2;
|
||||
int textH=win->monospaced_font->MaxHeight();
|
||||
|
||||
int noChars = (r.w-16) / textW;
|
||||
|
||||
|
||||
int x=0;
|
||||
int y=(r.h/2)-((textH+16)/2);
|
||||
x+=r.x+8;
|
||||
y+=r.y+8;
|
||||
|
||||
auto isHovering = this->GetViewFlag(VIEWFLAG_HOVER_STATE);
|
||||
auto isActive = this->GetViewFlag(VIEWFLAG_ISACTIVE);
|
||||
auto isMouseDown = this->GetViewFlag(VIEWFLAG_MOUSEDOWN_STATE);
|
||||
|
||||
SDL_Color& color = win->palette.GetBorderColor(isHovering,isActive,isMouseDown);
|
||||
|
||||
size_t tracking = this->cursorPos;
|
||||
if(cursorEnd != std::string::npos)
|
||||
tracking = this->cursorEnd;
|
||||
|
||||
|
||||
size_t off = noChars == 0 ? (size_t)0 : ((tracking / (size_t)noChars) * (size_t)noChars);
|
||||
|
||||
|
||||
std::string& datext = this->text.empty() ? this->hint : this->text;
|
||||
|
||||
//printf("%i %i %i\n",(int) tracking,(int)off,(int)noChars);
|
||||
|
||||
for(size_t i = 0; i < (size_t)noChars; i++)
|
||||
{
|
||||
if(cursorEnd == std::string::npos && (i+off) == cursorBegin)
|
||||
{
|
||||
SDL_SetRenderDrawColor(renderer,color.r,color.g,color.b,color.a);
|
||||
int x1=((int)i*textW)+x;
|
||||
int y1 = y;
|
||||
int y2 = y+textH;
|
||||
SDL_RenderDrawLine(renderer,x1,y1,x1,y2);
|
||||
}
|
||||
if(i + off < datext.size())
|
||||
{
|
||||
if(cursorEnd != std::string::npos && (i+off) >= cursorBegin && (i+off) < cursorEnd)
|
||||
{
|
||||
SDL_Rect r0={.x=((int)i*textW)+x,.y=y,.w=textW,.h=textH+8};
|
||||
SDL_SetRenderDrawColor(renderer,win->palette.accent.r,win->palette.accent.g,win->palette.accent.b,win->palette.accent.a);
|
||||
SDL_RenderFillRect(renderer,&r0);
|
||||
|
||||
auto ch=win->monospaced_font->GetCharOfColor(datext[i+off],color);
|
||||
|
||||
SDL_Rect src={.x=0,.y=0,.w=0,.h=0};
|
||||
SDL_QueryTexture(ch,NULL,NULL,&src.w,&src.h);
|
||||
SDL_Rect dest = {.x=((int)i*textW)+x+1,.y=y,.w=src.w,.h=src.h};
|
||||
SDL_RenderCopy(renderer,ch,&src,&dest);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
|
||||
|
||||
auto ch=win->monospaced_font->GetCharOfColor(datext[i+off],this->text.empty() ? color : win->palette.accent);
|
||||
|
||||
SDL_Rect src={.x=0,.y=0,.w=0,.h=0};
|
||||
SDL_QueryTexture(ch,NULL,NULL,&src.w,&src.h);
|
||||
SDL_Rect dest = {.x=((int)i*textW)+x+1,.y=y,.w=src.w,.h=src.h};
|
||||
SDL_RenderCopy(renderer,ch,&src,&dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SDL_SetRenderDrawColor(renderer,color.r,color.g,color.b,color.a);
|
||||
|
||||
SDL_Rect r2={.x=r.x,.y=y-4,.w=r.w,.h=textH+16};
|
||||
for(size_t i=0;i < 4; i++)
|
||||
{
|
||||
SDL_RenderDrawRect(renderer,&r2);
|
||||
r2.x++;
|
||||
r2.y++;
|
||||
r2.w-=2;
|
||||
r2.h-=2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user