// 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( bool dark = false ) { double xx = x+6; double yy = 17-smofs; 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= 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(smofs*((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); } }