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/ProgressView.cpp
src/SDL2/Views/CheckView.cpp
src/SDL2/Views/MultilineEditTextView.cpp
src/SDL2/Views/EditTextView.cpp
src/SDL2/Views/PictureView.cpp
src/SDL2/Views/VScrollView.cpp

View File

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

View File

@@ -24,7 +24,7 @@ class FontCache
int MaxHeight();
int PointSize();
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();
};
}

View File

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

View File

@@ -137,6 +137,10 @@ namespace Tesses::Framework::Http {
return true;
}
Uri::Uri()
{
this->query.SetCaseSensitive(true);
}
std::string Uri::GetPathAndQuery()
{
return this->path + this->GetQuery();
@@ -740,6 +744,28 @@ namespace Tesses::Framework::Http {
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)
{
@@ -858,6 +884,7 @@ namespace Tesses::Framework::Http {
return true;
}
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);
}

View File

@@ -87,13 +87,16 @@ void FontCache::CalculateSize(std::string text, int& x,int& y)
}
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 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':
{
@@ -112,7 +115,7 @@ void FontCache::Render(SDL_Renderer* renderer,int x,int y, std::string text,cons
break;
default:
{
auto tex = GetCharOfColor(c,color);
auto tex = GetCharOfColor(text[i],color);
int wi;
int he;
SDL_QueryTexture(tex,NULL,NULL,&wi,&he);

View File

@@ -8,6 +8,7 @@
#include "TessesFramework/SDL2/Views/TextListView.hpp"
#include "TessesFramework/SDL2/Views/AbsoluteView.hpp"
#include "TessesFramework/SDL2/Views/EditTextView.hpp"
#include "TessesFramework/SDL2/Views/MultilineEditTextView.hpp"
#include "TessesFramework/SDL2/Views/PictureView.hpp"
#include "TessesFramework/SDL2/Views/ScrollableTextListView.hpp"
#include "TessesFramework/SDL2/Views/HScrollView.hpp"
@@ -580,6 +581,17 @@ namespace Tesses::Framework::SDL2
etv->SetHint(hint);
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")
{
auto pv = new Views::PictureView();

View File

@@ -4,6 +4,18 @@
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)
{
//1 |
@@ -11,13 +23,38 @@ namespace Tesses::Framework::SDL2::Views
// 9 |
//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)
{
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())
{
@@ -72,7 +109,7 @@ namespace Tesses::Framework::SDL2::Views
SDL_Point cursorBegin = this->cursorPos;
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;
cursorEnd.y ^= cursorBegin.y;
@@ -97,7 +134,7 @@ namespace Tesses::Framework::SDL2::Views
this->cursorPos = cursorBegin+text.size();
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;
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())
{
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.x > 0)
{
mylines[0] = this->lines[cursorBegin.y].substr(0,cursorBegin.x) + mylines[0];
}
if(cursorBegin.x < this->lines[cursorBegin.y].size())
{
mylines.back() += this->lines[cursorBegin.y].substr(cursorBegin.x);
}
this->lines.erase(this->lines.begin()+cursorBegin.y);
}
bool first=true;
for(auto& item : mylines)
{
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 =
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 = {
.x=r.x,
@@ -34,6 +102,62 @@ namespace Tesses::Framework::SDL2::Views
{
int h =
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 = {
.x=0,
.y=h,