swwmgz_m/zscript/kbase/swwm_kbase_textbox.zsc

125 lines
3.8 KiB
Text

// Class for text box element
Class DemolitionistMenuTextBox ui
{
DemolitionistMenu master;
String txt;
BrokenLines l;
TextureID img;
int ofs;
int x, w;
bool scrollbar;
double smofs;
int maxofs;
// textbox initialization
DemolitionistMenuTextBox Init( DemolitionistMenu master, String txt, int x = 0, int w = 0 )
{
self.master = master;
self.x = x;
if ( w == 0 ) self.w = 640-x;
else self.w = w;
if ( txt.Left(1) == "$" ) self.txt = StringTable.Localize(txt);
else self.txt = txt;
ofs = 0;
// break lines
l = master.mSmallFont.BreakLines(self.txt,self.w-12);
int h = l.Count()*13;
if ( h > (master.ws.y-34) )
{
l.Destroy();
l = master.mSmallFont.BreakLines(self.txt,self.w-20);
scrollbar = true;
maxofs = int((l.Count()*13)-(master.ws.y-34));
}
return self;
}
// allow changing contents without re-creating the class
void Reinit( String txt, int x = 0, int w = 0 )
{
String oldtxt = self.txt;
self.txt = txt;
self.x = x;
int oldw = self.w;
if ( w == 0 ) self.w = 640-x;
else self.w = w;
// break lines again (if changed)
if ( (self.w == oldw) && (self.txt == oldtxt) ) return;
if ( l ) l.Destroy();
l = master.mSmallFont.BreakLines(self.txt,self.w-12);
int h = l.Count()*13;
scrollbar = false;
maxofs = 0;
if ( h > (master.ws.y-34) )
{
l.Destroy();
l = master.mSmallFont.BreakLines(self.txt,self.w-20);
scrollbar = true;
maxofs = int((l.Count()*13)-(master.ws.y-34));
}
// restrict scroll (if changed)
if ( ofs > maxofs ) smofs = ofs = maxofs;
// reset scroll if text is different
if ( self.txt != oldtxt ) smofs = ofs = 0;
}
override void OnDestroy()
{
if ( l ) l.Destroy();
}
// called when sending a scroll input
// returns true if the position actually changed
// speed: how many pixels to move (either back or forward)
bool Scroll( int speed )
{
int oldofs = ofs;
ofs = clamp(ofs+speed,0,maxofs);
return (ofs != oldofs);
}
// called when clicking on our scrollbar
// returns true if the position actually changed
// y: relative click position
bool SetOffset( double y )
{
int oldofs = ofs;
ofs = clamp(int(round((y-20.5)/((master.ws.y-41.)/maxofs))),0,maxofs);
return (ofs != oldofs);
}
void Ticker()
{
// update smooth scroll
smofs = (smofs*.6)+(ofs*.4);
if ( abs(smofs-ofs) < (1./master.hs) ) smofs = ofs;
}
void Drawer( double fractic, bool dark = false )
{
double ssmofs = (smofs~==ofs)?smofs:(smofs*(1.-fractic)+((smofs*.6)+(ofs*.4))*fractic);
double xx = x+6;
double yy = 17-ssmofs;
Screen.SetClipRect(int((master.origin.x+xx)*master.hs),int((master.origin.y+17)*master.hs),int(w*master.hs),int((master.ws.y-34)*master.hs));
// draw image if defined and visible
if ( img.IsValid() )
{
Vector2 imgsz = TexMan.GetScaledSize(img);
Vector2 imgofs = TexMan.GetScaledOffset(img);
if ( (yy+imgsz.y-imgofs.y >= 17) && (yy-imgofs.y < master.ws.y) )
Screen.DrawTexture(img,false,master.origin.x+xx,master.origin.y+yy,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true);
}
for ( int i=0; i<l.Count(); i++, yy+=13 )
{
// to save time, we skip lines that aren't visible
if ( yy < 4 ) continue;
if ( yy >= master.ws.y-19 ) continue;
Screen.DrawText(master.mSmallFont,Font.CR_WHITE,master.origin.x+xx,master.origin.y+yy,l.StringAt(i),DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,dark?Color(96,0,0,0):Color(0,0,0,0));
}
Screen.ClearClipRect();
if ( !scrollbar ) return;
xx = x+(w-8);
master.DrawVSeparator(xx,14,master.ws.y-28);
xx += 2;
yy = floor(ssmofs*((master.ws.y-39)/maxofs))+14;
Screen.DrawText(master.mSmallFont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,"▮",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true);
}
}