- exported the clipping rectangle to scripting and added a statusbar scaling wrapper for it.

- fixed: BaseStatusBar.Fill did not pass its flags parameter to the native function.
This commit is contained in:
Christoph Oelckers 2017-03-30 12:13:28 +02:00
parent a3ef711d1d
commit 3a1228bf95
5 changed files with 126 additions and 4 deletions

View file

@ -397,6 +397,7 @@ public:
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY); void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY); void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY);
void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0); void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
void SetClipRect(double x, double y, double w, double h, int flags = 0);
void BeginStatusBar(int resW, int resH, int relTop, bool forceScaled); void BeginStatusBar(int resW, int resH, int relTop, bool forceScaled);
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false); void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);

View file

@ -1910,7 +1910,82 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, Fill)
PARAM_FLOAT(h); PARAM_FLOAT(h);
PARAM_INT_DEF(flags); PARAM_INT_DEF(flags);
if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->Fill(color, x, y, w, h); self->Fill(color, x, y, w, h, flags);
return 0;
}
//============================================================================
//
// draw stuff
//
//============================================================================
void DBaseStatusBar::SetClipRect(double x, double y, double w, double h, int flags)
{
// resolve auto-alignment before making any adjustments to the position values.
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
{
if (x < 0) flags |= DI_SCREEN_RIGHT;
else flags |= DI_SCREEN_LEFT;
if (y < 0) flags |= DI_SCREEN_BOTTOM;
else flags |= DI_SCREEN_TOP;
}
x += drawOffset.X;
y += drawOffset.Y;
if (!fullscreenOffsets)
{
StatusbarToRealCoords(x, y, w, h);
}
else
{
double orgx, orgy;
switch (flags & DI_SCREEN_HMASK)
{
default: orgx = 0; break;
case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break;
}
switch (flags & DI_SCREEN_VMASK)
{
default: orgy = 0; break;
case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
}
// move stuff in the top right corner a bit down if the fps counter is on.
if ((flags & (DI_SCREEN_HMASK | DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
DVector2 Scale = GetHUDScale();
x *= Scale.X;
y *= Scale.Y;
w *= Scale.X;
h *= Scale.Y;
x += orgx;
y += orgy;
}
int x1 = int(x);
int y1 = int(y);
int ww = int(x + w - x1); // account for scaling to non-integers. Truncating the values separately would fail for cases like
int hh = int(y + h - y1); // y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
screen->SetClipRect(x1, y1, ww, hh);
}
DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetClipRect)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_FLOAT(w);
PARAM_FLOAT(h);
PARAM_INT_DEF(flags);
self->SetClipRect(x, y, w, h, flags);
return 0; return 0;
} }

View file

@ -190,6 +190,24 @@ void DCanvas::SetClipRect(int x, int y, int w, int h)
clipwidth = clamp(w, 0, GetHeight() - y); clipwidth = clamp(w, 0, GetHeight() - y);
} }
DEFINE_ACTION_FUNCTION(_Screen, SetClipRect)
{
PARAM_PROLOGUE;
PARAM_INT(x);
PARAM_INT(y);
PARAM_INT(w);
PARAM_INT(h);
screen->SetClipRect(x, y, w, h);
return 0;
}
DEFINE_ACTION_FUNCTION(_Screen, ClearClipRect)
{
PARAM_PROLOGUE;
screen->ClearClipRect();
return 0;
}
void DCanvas::GetClipRect(int *x, int *y, int *w, int *h) void DCanvas::GetClipRect(int *x, int *y, int *w, int *h)
{ {
if (x) *x = clipleft; if (x) *x = clipleft;
@ -198,6 +216,19 @@ void DCanvas::GetClipRect(int *x, int *y, int *w, int *h)
if (h) *h = clipheight; if (h) *h = clipheight;
} }
DEFINE_ACTION_FUNCTION(_Screen, GetClipRect)
{
PARAM_PROLOGUE;
int x, y, w, h;
screen->GetClipRect(&x, &y, &w, &h);
if (numret > 0) ret[0].SetInt(x);
if (numret > 1) ret[1].SetInt(x);
if (numret > 2) ret[2].SetInt(x);
if (numret > 3) ret[3].SetInt(x);
return MIN(numret, 4);
}
bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const
{ {
if (img != NULL) if (img != NULL)

View file

@ -166,6 +166,10 @@ struct Screen native
native static void DrawFrame(int x, int y, int w, int h); native static void DrawFrame(int x, int y, int w, int h);
native static Vector2, Vector2 VirtualToRealCoords(Vector2 pos, Vector2 size, Vector2 vsize, bool vbottom=false, bool handleaspect=true); native static Vector2, Vector2 VirtualToRealCoords(Vector2 pos, Vector2 size, Vector2 vsize, bool vbottom=false, bool handleaspect=true);
native static double GetAspectRatio(); native static double GetAspectRatio();
native static void SetClipRect(int x, int y, int w, int h);
native static void ClearClipRect();
native static int, int, int, int GetClipRect();
// This is a leftover of the abandoned Inventory.DrawPowerup method. // This is a leftover of the abandoned Inventory.DrawPowerup method.
deprecated("2.5") static ui void DrawHUDTexture(TextureID tex, double x, double y) deprecated("2.5") static ui void DrawHUDTexture(TextureID tex, double x, double y)

View file

@ -327,6 +327,12 @@ class BaseStatusBar native ui
native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = ""); native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = "");
native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0); native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0);
native int GetTopOfStatusBar(); native int GetTopOfStatusBar();
native void SetClipRect(double x, double y, double w, double h, int flags = 0);
void ClearClipRect()
{
screen.ClearClipRect();
}
//============================================================================ //============================================================================
// //
@ -984,13 +990,17 @@ class BaseStatusBar native ui
double sizeOfImage = (horizontal ? texsize.X - border*2 : texsize.Y - border*2); double sizeOfImage = (horizontal ? texsize.X - border*2 : texsize.Y - border*2);
Clip[(!horizontal) | ((!reverse)<<1)] = sizeOfImage - sizeOfImage *value; Clip[(!horizontal) | ((!reverse)<<1)] = sizeOfImage - sizeOfImage *value;
// preserve the active clipping rectangle
int cx, cy, cw, ch;
[cx, cy, cw, ch] = screen.GetClipRect();
if(border != 0) if(border != 0)
{ {
for(int i = 0; i < 4; i++) Clip[i] += border; for(int i = 0; i < 4; i++) Clip[i] += border;
//Draw the whole foreground //Draw the whole foreground
DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP); DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP);
// SetClip SetClipRect(position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3], flags);
} }
if (offtex.IsValid() && TexMan.GetScaledSize(offtex) == texsize) DrawTexture(offtex, position, flags | DI_ITEM_LEFT_TOP); if (offtex.IsValid() && TexMan.GetScaledSize(offtex) == texsize) DrawTexture(offtex, position, flags | DI_ITEM_LEFT_TOP);
@ -998,10 +1008,11 @@ class BaseStatusBar native ui
if (border == 0) if (border == 0)
{ {
// SetClip SetClipRect(position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3], flags);
DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP); DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP);
} }
// UnsetClip // restore the previous clipping rectangle
screen.SetClipRect(cx, cy, cw, ch);
} }
//============================================================================ //============================================================================