Sync before tar home

This commit is contained in:
2025-07-12 03:28:15 -05:00
parent dda439929d
commit a1eff24436
9 changed files with 244 additions and 13 deletions

View File

@@ -64,6 +64,7 @@ src/SDL2/Views/TextListView.cpp
src/SDL2/Views/ScrollableTextListView.cpp src/SDL2/Views/ScrollableTextListView.cpp
src/SDL2/Views/ProgressView.cpp src/SDL2/Views/ProgressView.cpp
src/SDL2/Views/CheckView.cpp src/SDL2/Views/CheckView.cpp
src/SDL2/Views/MultilineEditTextView.cpp
src/SDL2/Views/EditTextView.cpp src/SDL2/Views/EditTextView.cpp
src/SDL2/Views/PictureView.cpp src/SDL2/Views/PictureView.cpp
src/SDL2/Views/VScrollView.cpp src/SDL2/Views/VScrollView.cpp

View File

@@ -71,11 +71,19 @@ namespace Tesses::Framework::Http
} StatusCode; } StatusCode;
struct CaseInsensitiveLess { struct CaseInsensitiveLess {
CaseInsensitiveLess(const CaseInsensitiveLess& str);
CaseInsensitiveLess();
CaseInsensitiveLess* offset;
bool caseSensitive;
bool operator() (const std::string& s1, const std::string& s2) const; bool operator() (const std::string& s1, const std::string& s2) const;
}; };
class HttpDictionary { class HttpDictionary {
public: public:
HttpDictionary();
HttpDictionary(bool caseSensitive);
std::map<std::string,std::vector<std::string>,CaseInsensitiveLess> kvp; std::map<std::string,std::vector<std::string>,CaseInsensitiveLess> kvp;
void SetCaseSensitive(bool isCaseSensitive);
void Clear(); void Clear();
void Clear(std::string key, bool kvpExistsAfter); void Clear(std::string key, bool kvpExistsAfter);
void SetValue(std::string key, std::string value); void SetValue(std::string key, std::string value);
@@ -116,6 +124,7 @@ struct CaseInsensitiveLess {
class Uri { class Uri {
public: public:
Uri();
std::string GetQuery(); std::string GetQuery();
std::string GetPathAndQuery(); std::string GetPathAndQuery();
uint16_t GetPort(); uint16_t GetPort();

View File

@@ -24,7 +24,7 @@ class FontCache
int MaxHeight(); int MaxHeight();
int PointSize(); int PointSize();
void CalculateSize(std::string text, int& x,int& y); void CalculateSize(std::string text, int& x,int& y);
void Render(SDL_Renderer* renderer,int x,int y, std::string text, const SDL_Color& color); void Render(SDL_Renderer* renderer,int x,int y, std::string text, const SDL_Color& color,size_t begin=0,size_t end=std::string::npos);
~FontCache(); ~FontCache();
}; };
} }

View File

@@ -678,6 +678,7 @@ namespace Tesses::Framework::Http
this->statusCode = OK; this->statusCode = OK;
this->strm = strm; this->strm = strm;
this->sent = false; this->sent = false;
this->queryParams.SetCaseSensitive(true);
this->responseHeaders.AddValue("Server","TessesFrameworkWebServer"); this->responseHeaders.AddValue("Server","TessesFrameworkWebServer");
} }
Stream& ServerContext::GetStream() Stream& ServerContext::GetStream()

View File

@@ -137,6 +137,10 @@ namespace Tesses::Framework::Http {
return true; return true;
} }
Uri::Uri()
{
this->query.SetCaseSensitive(true);
}
std::string Uri::GetPathAndQuery() std::string Uri::GetPathAndQuery()
{ {
return this->path + this->GetQuery(); return this->path + this->GetQuery();
@@ -740,6 +744,28 @@ namespace Tesses::Framework::Http {
return ""; return "";
} }
} }
CaseInsensitiveLess::CaseInsensitiveLess(const CaseInsensitiveLess& str)
{
this->caseSensitive = str.caseSensitive;
this->offset = this;
}
CaseInsensitiveLess::CaseInsensitiveLess()
{
this->caseSensitive=false;
this->offset = this;
}
void HttpDictionary::SetCaseSensitive(bool isCaseSensitive)
{
this->kvp.key_comp().offset->caseSensitive=isCaseSensitive;
}
HttpDictionary::HttpDictionary(bool isCaseSensitive)
{
this->SetCaseSensitive(isCaseSensitive);
}
HttpDictionary::HttpDictionary() : HttpDictionary(false)
{
}
bool HttpDictionary::AnyEquals(std::string key, std::string value) bool HttpDictionary::AnyEquals(std::string key, std::string value)
{ {
@@ -858,6 +884,7 @@ namespace Tesses::Framework::Http {
return true; return true;
} }
bool CaseInsensitiveLess::operator() (const std::string& s1, const std::string& s2) const { bool CaseInsensitiveLess::operator() (const std::string& s1, const std::string& s2) const {
if(this->caseSensitive) return s1 == s2;
return HttpUtils::ToLower(s1) < HttpUtils::ToLower(s2); return HttpUtils::ToLower(s1) < HttpUtils::ToLower(s2);
} }

View File

@@ -87,13 +87,16 @@ void FontCache::CalculateSize(std::string text, int& x,int& y)
} }
if(myX > x) x = myX; if(myX > x) x = myX;
} }
void FontCache::Render(SDL_Renderer* renderer,int x,int y, std::string text,const SDL_Color& color) void FontCache::Render(SDL_Renderer* renderer,int x,int y, std::string text,const SDL_Color& color, size_t begin, size_t end)
{ {
int myX = x; int myX = x;
int maxH = MaxHeight(); int maxH = MaxHeight();
for(auto c : text) if(begin >= text.size()) return;
if(end > text.size()) end = text.size();
for(size_t i = begin; i < end; i++)
{ {
switch(c) switch(text[i])
{ {
case '\n': case '\n':
{ {
@@ -112,7 +115,7 @@ void FontCache::Render(SDL_Renderer* renderer,int x,int y, std::string text,cons
break; break;
default: default:
{ {
auto tex = GetCharOfColor(c,color); auto tex = GetCharOfColor(text[i],color);
int wi; int wi;
int he; int he;
SDL_QueryTexture(tex,NULL,NULL,&wi,&he); SDL_QueryTexture(tex,NULL,NULL,&wi,&he);

View File

@@ -8,6 +8,7 @@
#include "TessesFramework/SDL2/Views/TextListView.hpp" #include "TessesFramework/SDL2/Views/TextListView.hpp"
#include "TessesFramework/SDL2/Views/AbsoluteView.hpp" #include "TessesFramework/SDL2/Views/AbsoluteView.hpp"
#include "TessesFramework/SDL2/Views/EditTextView.hpp" #include "TessesFramework/SDL2/Views/EditTextView.hpp"
#include "TessesFramework/SDL2/Views/MultilineEditTextView.hpp"
#include "TessesFramework/SDL2/Views/PictureView.hpp" #include "TessesFramework/SDL2/Views/PictureView.hpp"
#include "TessesFramework/SDL2/Views/ScrollableTextListView.hpp" #include "TessesFramework/SDL2/Views/ScrollableTextListView.hpp"
#include "TessesFramework/SDL2/Views/HScrollView.hpp" #include "TessesFramework/SDL2/Views/HScrollView.hpp"
@@ -580,6 +581,17 @@ namespace Tesses::Framework::SDL2
etv->SetHint(hint); etv->SetHint(hint);
return etv; return etv;
} }
else if(type == "MultilineEditTextView")
{
auto etv = new Views::MultilineEditTextView();
etv->SetId(id);
etv->SetText(text);
std::string hint;
json.TryGetValueAsType("Hint",hint);
etv->SetHint(hint);
return etv;
}
else if(type == "PictureView") else if(type == "PictureView")
{ {
auto pv = new Views::PictureView(); auto pv = new Views::PictureView();

View File

@@ -4,6 +4,18 @@
namespace Tesses::Framework::SDL2::Views namespace Tesses::Framework::SDL2::Views
{ {
static int numberWidth(size_t n)
{
if(n == 0) return 1;
size_t digits = 0;
while(n != 0)
{
n /= 10;
digits++;
}
return digits;
}
void MultilineEditTextView::OnDraw(SDL_Renderer* renderer, SDL_Rect& r) void MultilineEditTextView::OnDraw(SDL_Renderer* renderer, SDL_Rect& r)
{ {
//1 | //1 |
@@ -11,13 +23,38 @@ namespace Tesses::Framework::SDL2::Views
// 9 | // 9 |
//10 | //10 |
auto win = this->GetWindow();
auto w = win->monospaced_font->MaxWidth();
auto h = win->monospaced_font->MaxHeight();
auto digitsTotal = numberWidth(this->lines.size());
auto numLines = (r.h - (win->palette.borderSize*4)) / h;
if(numLines+this->topLeft.y > this->lines.size()) numLines = this->lines.size() - this->topLeft.y;
for(size_t i = 0; i < numLines; i++)
{
win->monospaced_font->Render(renderer, r.x+(win->palette.borderSize*2),r.y+(h*i), Http::HttpUtils::LeftPad(std::to_string(i+this->topLeft.y+1),digitsTotal,' '),win->palette.accent);
win->monospaced_font->Render(renderer,r.x+(win->palette.borderSize*2)+(w*(digitsTotal+5)),r.y+(h*i),this->lines[i+this->topLeft.y],win->palette.accent,this->topLeft.x);
}
} }
bool MultilineEditTextView::OnEvent(SDL_Event& event, SDL_Rect& myBounds, SDL_Rect& visibleBounds) bool MultilineEditTextView::OnEvent(SDL_Event& event, SDL_Rect& myBounds, SDL_Rect& visibleBounds)
{ {
if(event.type == SDL_TEXTINPUT)
{
TypeText(event.text.text);
}
else if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
TypeText("\n");
break;
}
}
return false;
} }
MultilineEditTextView::MultilineEditTextView() :MultilineEditTextView(std::string()) MultilineEditTextView::MultilineEditTextView() :MultilineEditTextView(std::string())
{ {
@@ -72,7 +109,7 @@ namespace Tesses::Framework::SDL2::Views
SDL_Point cursorBegin = this->cursorPos; SDL_Point cursorBegin = this->cursorPos;
SDL_Point cursorEnd = this->cursorEnd; SDL_Point cursorEnd = this->cursorEnd;
if(cursorBegin.y > cursorEnd.y || ((cursorBegin.y == cursorEnd.y) && (cursorBegin.x > cursorEnd.x))) if((cursorBegin.y > cursorEnd.y || ((cursorBegin.y == cursorEnd.y) && (cursorBegin.x > cursorEnd.x))) && this->cursorEnd.x != -1 && this->cursorEnd.y != -1)
{ {
cursorBegin.y ^= cursorEnd.y; cursorBegin.y ^= cursorEnd.y;
cursorEnd.y ^= cursorBegin.y; cursorEnd.y ^= cursorBegin.y;
@@ -97,7 +134,7 @@ namespace Tesses::Framework::SDL2::Views
this->cursorPos = cursorBegin+text.size(); this->cursorPos = cursorBegin+text.size();
this->cursorEnd = std::string::npos;*/ this->cursorEnd = std::string::npos;*/
if(cursorEnd.y != -1 && cursorEnd.x != -1) if(this->cursorEnd.y != -1 && this->cursorEnd.x != -1)
{ {
int line = cursorBegin.y; int line = cursorBegin.y;
for(int y = cursorBegin.y; y <= cursorEnd.y && y < lines.size(); y++) for(int y = cursorBegin.y; y <= cursorEnd.y && y < lines.size(); y++)
@@ -137,32 +174,49 @@ namespace Tesses::Framework::SDL2::Views
auto mylines = Http::HttpUtils::SplitString(text,"\n"); auto mylines = text == "\n" ? std::vector<std::string>({"",""}) : Http::HttpUtils::SplitString(text,"\n");
if(!mylines.empty()) if(!mylines.empty())
{ {
int setXTo = 0;
if(mylines.size()==1)
{
setXTo=mylines[0].size()+cursorBegin.x;
}
else {
setXTo=mylines.back().size();
}
if(cursorBegin.y < this->lines.size()) if(cursorBegin.y < this->lines.size())
{ {
if(cursorBegin.x > 0) if(cursorBegin.x > 0)
{ {
mylines[0] = this->lines[cursorBegin.y].substr(0,cursorBegin.x) + mylines[0]; mylines[0] = this->lines[cursorBegin.y].substr(0,cursorBegin.x) + mylines[0];
} }
if(cursorBegin.x < this->lines[cursorBegin.y].size()) if(cursorBegin.x < this->lines[cursorBegin.y].size())
{ {
mylines.back() += this->lines[cursorBegin.y].substr(cursorBegin.x); mylines.back() += this->lines[cursorBegin.y].substr(cursorBegin.x);
} }
this->lines.erase(this->lines.begin()+cursorBegin.y); this->lines.erase(this->lines.begin()+cursorBegin.y);
} }
bool first=true;
for(auto& item : mylines) for(auto& item : mylines)
{ {
this->lines.insert(this->lines.begin()+cursorBegin.y,{item}); if(!first)
{
cursorBegin.y++;
} }
this->lines.insert(this->lines.begin()+cursorBegin.y,{item});
first=false;
}
cursorBegin.x = setXTo;
} }

View File

@@ -12,6 +12,74 @@ namespace Tesses::Framework::SDL2::Views
int h = int h =
win->monospaced_font->MaxHeight() + (win->palette.borderSize*3); win->monospaced_font->MaxHeight() + (win->palette.borderSize*3);
int w = win->monospaced_font->MaxWidth() + (win->palette.borderSize*3);
size_t noItems = this->items.size();
size_t offset = 0;
size_t width = noItems == 0 ? 0 : (r.w / noItems);
if(noItems > 0 && (r.w / noItems) < w*5)
{
offset=this->firstTab;
noItems = (r.w - (w*2)) / (w * 5);
width = noItems == 0 ? 0 : ((r.w - (w*2)) / noItems);
if(offset > items.size())
offset = items.size()-3;
if((offset+noItems)>items.size()) noItems = items.size()-offset;
}
for(size_t i = 0; i < noItems; i++)
{
Clipper clipper(renderer,r);
int yBottom = (h - 1)+r.y;
//auto bc = win->palette.GetBorderColor(false,(i+offset)==this->selectedTab,false);
std::string text = this->items[i+offset].first;
int textW;
int textH;
win->monospaced_font->CalculateSize(text,textW,textH);
/*if(i>0)
{
//auto bc2 = win->palette.GetBorderColor(false,(i+offset)==this->selectedTab || ((i+offset)-1)==this->selectedTab,false);
//SDL_SetRenderDrawColor(renderer,bc2.r,bc2.g,bc2.b,bc2.a);
// SDL_RenderDrawLine(renderer,(width*i)+r.x,r.y,(width*i)+r.x,yBottom);
}*/
//SDL_SetRenderDrawColor(renderer,bc.r,bc.g,bc.b,bc.a);
if((i+offset)==this->selectedTab)
{
SDL_SetRenderDrawColor(renderer,win->palette.accent.r,win->palette.accent.g,win->palette.accent.b,win->palette.accent.a);
SDL_Rect r0={.x=(int)(width*i+1)+r.x,.y=r.y,.w=(int)width-2,.h=yBottom-r.y};
SDL_RenderFillRect(renderer,&r0);
}
//SDL_RenderDrawLine(renderer,(width*i+1)+r.x,yBottom,(width*(i+1)-2),yBottom);
clipper.Clip({.x=(int)(width*i+1)+r.x,.y=r.y,.w=(int)width-2,.h=yBottom-r.y});
int textX = ((width-2)/2) - (textW/2);
int textY = ((yBottom-r.y)/2) - (textH/2);
win->monospaced_font->Render(renderer,textX+r.x+(width*i+2),textY+r.y,text,((i+offset)==this->selectedTab) ? win->palette.background : win->palette.accent);
}
if(noItems != items.size())
{
auto greaterThanX=(r.w-w)+r.x;
auto lessThanX = greaterThanX-w;
int lgtX;
int lgtY;
win->monospaced_font->CalculateSize("<",lgtX,lgtY);
lgtX = (w/2)-(lgtX/2);
lgtY = (h/2)-(lgtY/2);
win->monospaced_font->Render(renderer,lessThanX+lgtX,r.y+lgtY,"<",win->palette.accent);
win->monospaced_font->CalculateSize(">",lgtX,lgtY);
lgtX = (w/2)-(lgtX/2);
lgtY = (h/2)-(lgtY/2);
win->monospaced_font->Render(renderer,greaterThanX+lgtX,r.y+lgtY,">",win->palette.accent);
}
SDL_Rect viewBounds = { SDL_Rect viewBounds = {
.x=r.x, .x=r.x,
@@ -34,6 +102,62 @@ namespace Tesses::Framework::SDL2::Views
{ {
int h = int h =
win->monospaced_font->MaxHeight() + (win->palette.borderSize*3); win->monospaced_font->MaxHeight() + (win->palette.borderSize*3);
int w = win->monospaced_font->MaxWidth() + (win->palette.borderSize*3);
int yBottom = (h - 1)+myBounds.y;
size_t noItems = this->items.size();
size_t offset = 0;
size_t width = noItems == 0 ? 0 : (myBounds.w / noItems);
if(noItems > 0 && (myBounds.w / noItems) < w*5)
{
offset=this->firstTab;
noItems = (myBounds.w - (w*2)) / (w * 5);
width = noItems == 0 ? 0 : ((myBounds.w - (w*2)) / noItems);
if(offset > items.size())
offset = items.size()-3;
if((offset+noItems)>items.size()) noItems = items.size()-offset;
}
int width_total = width*noItems;
if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT)
{
if(event.button.x >= visibleBounds.x && event.button.x < visibleBounds.x+visibleBounds.w && event.button.y >= visibleBounds.y && event.button.y < visibleBounds.y+visibleBounds.h)
{
if(event.button.y < myBounds.y+h && event.button.x < myBounds.x+width_total)
{
this->selectedTab = offset + ((event.button.x-myBounds.x) / width);
return true;
}
if(event.button.y < myBounds.y+h && event.button.x < myBounds.x+myBounds.w)
{
if(noItems != items.size())
{
auto greaterThanX=myBounds.w-w+myBounds.x;
auto lessThanX = greaterThanX-w;
if(event.button.x >= lessThanX && event.button.x < greaterThanX)
{
firstTab--;
if(firstTab >= items.size())
firstTab=0;
}
else if(event.button.x >= greaterThanX)
{
firstTab++;
if(firstTab >= items.size())
firstTab = items.size()-1;
}
}
}
}
}
SDL_Rect viewBounds = { SDL_Rect viewBounds = {
.x=0, .x=0,
.y=h, .y=h,