da3a564c43
* BUG: Rect class can be used as a fonction correctly now. git-svn-id: svn://localhost/gambas/trunk@4497 867c0c6c-44f3-4631-809d-bfa615b0a4ec
350 lines
6.7 KiB
C
350 lines
6.7 KiB
C
/***************************************************************************
|
|
|
|
crect.c
|
|
|
|
(c) 2000-2012 Benoît Minisini <gambas@users.sourceforge.net>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA.
|
|
|
|
***************************************************************************/
|
|
|
|
#define __CRECT_C
|
|
|
|
#include "gb_common.h"
|
|
#include "crect.h"
|
|
|
|
static void normalize(CRECT *_object)
|
|
{
|
|
if (THIS->w < 0)
|
|
{
|
|
THIS->w = (- THIS->w);
|
|
THIS->x -= THIS->w;
|
|
}
|
|
|
|
if (THIS->h < 0)
|
|
{
|
|
THIS->h = (- THIS->h);
|
|
THIS->y -= THIS->h;
|
|
}
|
|
}
|
|
|
|
CRECT *CRECT_create(void)
|
|
{
|
|
return GB.New(GB.FindClass("Rect"), NULL, NULL);
|
|
}
|
|
|
|
BEGIN_METHOD(Rect_new, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
|
|
|
|
if (!MISSING(x) && !MISSING(y) && !MISSING(w) && !MISSING(h))
|
|
{
|
|
THIS->x = VARG(x);
|
|
THIS->y = VARG(y);
|
|
THIS->w = VARG(w);
|
|
THIS->h = VARG(h);
|
|
normalize(THIS);
|
|
}
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_call, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
|
|
|
|
CRECT *rect = CRECT_create();
|
|
|
|
if (!MISSING(x) && !MISSING(y) && !MISSING(w) && !MISSING(h))
|
|
{
|
|
rect->x = VARG(x);
|
|
rect->y = VARG(y);
|
|
rect->w = VARG(w);
|
|
rect->h = VARG(h);
|
|
normalize(rect);
|
|
}
|
|
|
|
GB.ReturnObject(rect);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_PROPERTY(Rect_X)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->x);
|
|
else
|
|
THIS->x = VPROP(GB_INTEGER);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(Rect_Y)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->y);
|
|
else
|
|
THIS->y = VPROP(GB_INTEGER);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(Rect_Width)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->w);
|
|
else
|
|
{
|
|
THIS->w = VPROP(GB_INTEGER);
|
|
normalize(THIS);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(Rect_Height)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->h);
|
|
else
|
|
{
|
|
THIS->h = VPROP(GB_INTEGER);
|
|
normalize(THIS);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(Rect_Left)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->x);
|
|
else
|
|
{
|
|
int dx = VPROP(GB_INTEGER) - THIS->x;
|
|
if (dx > THIS->w)
|
|
dx = THIS->w;
|
|
|
|
THIS->x += dx;
|
|
THIS->w -= dx;
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(Rect_Top)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->y);
|
|
else
|
|
{
|
|
int dy = VPROP(GB_INTEGER) - THIS->y;
|
|
if (dy > THIS->h)
|
|
dy = THIS->h;
|
|
|
|
THIS->y += dy;
|
|
THIS->h -= dy;
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(Rect_Right)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->x + THIS->w);
|
|
else
|
|
{
|
|
int x2 = VPROP(GB_INTEGER);
|
|
if (x2 < THIS->x)
|
|
x2 = THIS->x;
|
|
|
|
THIS->w = x2 - THIS->x;
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(Rect_Bottom)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnInteger(THIS->y + THIS->h);
|
|
else
|
|
{
|
|
int y2 = VPROP(GB_INTEGER);
|
|
if (y2 < THIS->y)
|
|
y2 = THIS->y;
|
|
|
|
THIS->h = y2 - THIS->y;
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_METHOD_VOID(Rect_Clear)
|
|
|
|
THIS->x = THIS->y = THIS->w = THIS->h = 0;
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD_VOID(Rect_IsVoid)
|
|
|
|
GB.ReturnBoolean(THIS->w <= 0 || THIS->h <= 0);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD_VOID(Rect_Copy)
|
|
|
|
CRECT *copy = CRECT_create();
|
|
|
|
copy->x = THIS->x;
|
|
copy->y = THIS->y;
|
|
copy->w = THIS->w;
|
|
copy->h = THIS->h;
|
|
|
|
GB.ReturnObject(copy);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_Move, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
|
|
|
|
THIS->x = VARG(x);
|
|
THIS->y = VARG(y);
|
|
if (!MISSING(w) && !MISSING(h))
|
|
{
|
|
THIS->w = VARG(w);
|
|
THIS->h = VARG(h);
|
|
normalize(THIS);
|
|
}
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_Resize, GB_INTEGER w; GB_INTEGER h)
|
|
|
|
THIS->w = VARG(w);
|
|
THIS->h = VARG(h);
|
|
normalize(THIS);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_Translate, GB_INTEGER dx; GB_INTEGER dy)
|
|
|
|
THIS->x += VARG(dx);
|
|
THIS->y += VARG(dy);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_Union, GB_OBJECT rect)
|
|
|
|
CRECT *dest;
|
|
int x, y, w, h;
|
|
CRECT *rect = (CRECT *)VARG(rect);
|
|
|
|
if (GB.CheckObject(rect))
|
|
return;
|
|
|
|
dest = CRECT_create();
|
|
|
|
x = Min(THIS->x, rect->x);
|
|
y = Min(THIS->y, rect->y);
|
|
w = Max(THIS->x + THIS->w, rect->x + rect->w) - x;
|
|
h = Max(THIS->y + THIS->h, rect->y + rect->h) - y;
|
|
|
|
dest->x = x;
|
|
dest->y = y;
|
|
dest->w = w;
|
|
dest->h = h;
|
|
|
|
GB.ReturnObject(dest);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_Intersection, GB_OBJECT rect)
|
|
|
|
CRECT *dest;
|
|
int x, y, x2, y2;
|
|
CRECT *rect = (CRECT *)VARG(rect);
|
|
|
|
if (GB.CheckObject(rect))
|
|
return;
|
|
|
|
x = Max(THIS->x, rect->x);
|
|
y = Max(THIS->y, rect->y);
|
|
x2 = Min(THIS->x + THIS->w, rect->x + rect->w);
|
|
y2 = Min(THIS->y + THIS->h, rect->y + rect->h);
|
|
|
|
if (x2 > x && y2 > y)
|
|
{
|
|
dest = CRECT_create();
|
|
|
|
dest->x = x;
|
|
dest->y = y;
|
|
dest->w = x2 - x;
|
|
dest->h = y2 - y;
|
|
|
|
GB.ReturnObject(dest);
|
|
}
|
|
else
|
|
{
|
|
GB.ReturnNull();
|
|
}
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_Contains, GB_INTEGER x; GB_INTEGER y)
|
|
|
|
int x = VARG(x);
|
|
int y = VARG(y);
|
|
|
|
GB.ReturnBoolean((x >= THIS->x) && (x < (THIS->x + THIS->w)) && (y >= THIS->y) && (y < (THIS->y + THIS->h)));
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(Rect_Adjust, GB_INTEGER left; GB_INTEGER top; GB_INTEGER right; GB_INTEGER bottom)
|
|
|
|
int left = VARG(left);
|
|
int top = VARGOPT(top, left);
|
|
int right = VARGOPT(right, left);
|
|
int bottom = VARGOPT(bottom, top);
|
|
|
|
THIS->x += left;
|
|
THIS->w -= (left + right);
|
|
THIS->y += top;
|
|
THIS->h -= (top + bottom);
|
|
|
|
if (THIS->w < 1 || THIS->h < 1)
|
|
THIS->w = THIS->h = 0;
|
|
|
|
END_METHOD
|
|
|
|
GB_DESC RectDesc[] =
|
|
{
|
|
GB_DECLARE("Rect", sizeof(CRECT)),
|
|
|
|
GB_METHOD("_new", NULL, Rect_new, "[(X)i(Y)i(Width)i(Height)i]"),
|
|
GB_METHOD("_call", "Rect", Rect_call, "[(X)i(Y)i(Width)i(Height)i]"),
|
|
|
|
GB_PROPERTY("X", "i", Rect_X),
|
|
GB_PROPERTY("Y", "i", Rect_Y),
|
|
GB_PROPERTY("W", "i", Rect_Width),
|
|
GB_PROPERTY("H", "i", Rect_Height),
|
|
GB_PROPERTY("Width", "i", Rect_Width),
|
|
GB_PROPERTY("Height", "i", Rect_Height),
|
|
GB_PROPERTY("Left", "i", Rect_Left),
|
|
GB_PROPERTY("Top", "i", Rect_Top),
|
|
GB_PROPERTY("Right", "i", Rect_Right),
|
|
GB_PROPERTY("Bottom", "i", Rect_Bottom),
|
|
|
|
GB_METHOD("Clear", NULL, Rect_Clear, NULL),
|
|
GB_METHOD("IsVoid", "b", Rect_IsVoid, NULL),
|
|
GB_METHOD("Copy", "Rect", Rect_Copy, NULL),
|
|
GB_METHOD("Move", NULL, Rect_Move, "(X)i(Y)i[(Width)i(Height)i]"),
|
|
GB_METHOD("Resize", NULL, Rect_Resize, "(Width)i(Height)i"),
|
|
GB_METHOD("Translate", NULL, Rect_Translate, "(DX)i(DY)i"),
|
|
GB_METHOD("Union", "Rect", Rect_Union, "(Rect)Rect;"),
|
|
GB_METHOD("Intersection", "Rect", Rect_Intersection, "(Rect)Rect;"),
|
|
GB_METHOD("Contains", "b", Rect_Contains, "(X)i(Y)i"),
|
|
GB_METHOD("Adjust", NULL, Rect_Adjust, "(Left)i[(Top)i(Right)i(Bottom)i]"),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|