layout uses x,y
This commit is contained in:
@@ -36,7 +36,7 @@ var clay_base = {
|
||||
spacing:0,
|
||||
padding:0,
|
||||
margin:0,
|
||||
offset:[0,0],
|
||||
offset:{x:0, y:0},
|
||||
size:null,
|
||||
background_color: null
|
||||
};
|
||||
@@ -54,6 +54,10 @@ clay.draw = function draw(size, fn, config = {})
|
||||
lay_ctx.reset();
|
||||
boxes = [];
|
||||
var root = lay_ctx.item();
|
||||
// Accept both array and object formats
|
||||
if (Array.isArray(size)) {
|
||||
size = {width: size[0], height: size[1]};
|
||||
}
|
||||
lay_ctx.set_size(root,size);
|
||||
lay_ctx.set_contain(root,layout.contain.row);
|
||||
root_item = root;
|
||||
@@ -86,9 +90,9 @@ clay.draw = function draw(size, fn, config = {})
|
||||
box.marginbox.width += margin.l+margin.r;
|
||||
box.marginbox.height += margin.t+margin.b;
|
||||
box.content.y *= -1;
|
||||
box.content.y += size.y;
|
||||
box.content.y += size.height;
|
||||
box.boundingbox.y *= -1;
|
||||
box.boundingbox.y += size.y;
|
||||
box.boundingbox.y += size.height;
|
||||
box.content.anchor_y = 1;
|
||||
box.boundingbox.anchor_y = 1;
|
||||
}
|
||||
@@ -128,7 +132,7 @@ clay.spacer = create_view_fn({
|
||||
|
||||
function image_size(img)
|
||||
{
|
||||
return [img.rect[2]*img.texture.width, img.rect[3]*img.texture.height];
|
||||
return [img.width * (img.rect?.width || 1), img.height * (img.rect?.height || 1)];
|
||||
}
|
||||
|
||||
function add_item(config)
|
||||
@@ -163,6 +167,11 @@ function add_item(config)
|
||||
|
||||
var item = lay_ctx.item();
|
||||
lay_ctx.set_margins(item, use_config.margin);
|
||||
use_config.size ??= {width:0, height:0}
|
||||
// Convert array to object if needed
|
||||
if (Array.isArray(use_config.size)) {
|
||||
use_config.size = {width: use_config.size[0], height: use_config.size[1]};
|
||||
}
|
||||
lay_ctx.set_size(item,use_config.size);
|
||||
lay_ctx.set_contain(item,use_config.contain);
|
||||
lay_ctx.set_behave(item,use_config.behave);
|
||||
@@ -195,18 +204,18 @@ clay.image = function image(path, ...configs)
|
||||
{
|
||||
var config = rectify_configs(configs);
|
||||
var image = graphics.texture(path);
|
||||
config.image = image;
|
||||
config.size ??= [image.texture.width, image.texture.height];
|
||||
config.image = path; // Store the path string, not the texture object
|
||||
config.size ??= {width: image.width, height: image.height};
|
||||
add_item(config);
|
||||
}
|
||||
|
||||
clay.text = function text(str, ...configs)
|
||||
{
|
||||
var config = rectify_configs(configs);
|
||||
config.size ??= [0,0];
|
||||
config.size ??= {width:0, height:0};
|
||||
// config.font = graphics.get_font(config.font)
|
||||
var tsize = 12; //config.font.text_size(str, 0, 0, config.size.x);
|
||||
config.size = config.size.map((x,i) => Math.max(x, tsize[i]));
|
||||
var tsize = {width: 12, height: 12}; //config.font.text_size(str, 0, 0, config.size.width);
|
||||
config.size = {width: Math.max(config.size.width, tsize.width), height: Math.max(config.size.height, tsize.height)};
|
||||
config.text = str;
|
||||
add_item(config);
|
||||
}
|
||||
@@ -236,13 +245,17 @@ clay.button = function button(str, action, config = {})
|
||||
var hovered = null;
|
||||
clay.newframe = function() { hovered = null; }
|
||||
|
||||
function point_add(a,b) {
|
||||
return {x: a.x+b.x, y: a.y+b.y}
|
||||
}
|
||||
|
||||
// mousepos given in hud coordinates
|
||||
clay.draw_commands = function draw_commands(cmds, pos = [0,0], mousepos = prosperon.camera.screen2hud(input.mouse.screenpos()))
|
||||
clay.draw_commands = function draw_commands(cmds, pos = {x:0, y:0}, mousepos = {x:0,y:0})
|
||||
{
|
||||
for (var cmd of cmds) {
|
||||
var config = cmd.config;
|
||||
var boundingbox = geometry.rect_move(cmd.boundingbox,pos.add(config.offset));
|
||||
var content = geometry.rect_move(cmd.content,pos.add(config.offset));
|
||||
var boundingbox = geometry.rect_move(cmd.boundingbox,point_add(pos,config.offset));
|
||||
var content = geometry.rect_move(cmd.content,point_add(pos, config.offset));
|
||||
|
||||
if (config.hovered && geometry.rect_point_inside(boundingbox, mousepos)) {
|
||||
config.hovered.__proto__ = config;
|
||||
@@ -259,7 +272,7 @@ clay.draw_commands = function draw_commands(cmds, pos = [0,0], mousepos = prospe
|
||||
draw.rectangle(boundingbox, config.background_color);
|
||||
|
||||
if (config.text)
|
||||
draw.text(config.text, content, config.font, config.font_size, config.color, config.size.x);
|
||||
draw.text(config.text, content, config.font, config.font_size, config.color, config.size.width);
|
||||
if (config.image)
|
||||
draw.image(config.image, content, 0, config.color);
|
||||
}
|
||||
@@ -270,7 +283,7 @@ clay.debug_colors = dbg_colors;
|
||||
dbg_colors.content = [1,0,0,0.1];
|
||||
dbg_colors.boundingbox = [0,1,0,0,0.1];
|
||||
dbg_colors.margin = [0,0,1,0.1];
|
||||
clay.draw_debug = function draw_debug(cmds, pos = [0,0])
|
||||
clay.draw_debug = function draw_debug(cmds, pos = {x:0, y:0})
|
||||
{
|
||||
for (var i = 0; i < cmds.length; i++) {
|
||||
var cmd = cmds[i];
|
||||
|
||||
@@ -6,7 +6,7 @@ Includes both JavaScript and C-implemented routines for creating geometry buffer
|
||||
rectangle packing, etc.
|
||||
`
|
||||
|
||||
var renderer_actor = arg[0]
|
||||
var renderer_actor = arg?.[0] || null
|
||||
|
||||
var io = use('io')
|
||||
var time = use('time')
|
||||
@@ -34,7 +34,7 @@ graphics.Image = function(surfaceData) {
|
||||
Object.defineProperties(graphics.Image.prototype, {
|
||||
gpu: {
|
||||
get: function() {
|
||||
if (!this[GPU] && !this[LOADING]) {
|
||||
if (!this[GPU] && !this[LOADING] && renderer_actor) {
|
||||
this[LOADING] = true;
|
||||
var self = this;
|
||||
|
||||
@@ -76,13 +76,13 @@ Object.defineProperties(graphics.Image.prototype, {
|
||||
|
||||
width: {
|
||||
get: function() {
|
||||
return this[CPU].width
|
||||
return this[CPU]?.width || 0
|
||||
}
|
||||
},
|
||||
|
||||
height: {
|
||||
get: function() {
|
||||
return this[CPU].height
|
||||
return this[CPU]?.height || 0
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -97,29 +97,44 @@ graphics.Image.prototype.unload_cpu = function() {
|
||||
}
|
||||
|
||||
function calc_image_size(img) {
|
||||
if (!img.texture || !img.rect) return
|
||||
if (!img.rect) return
|
||||
if (img.texture) {
|
||||
return [img.texture.width * img.rect.width, img.texture.height * img.rect.height]
|
||||
} else if (img[CPU]) {
|
||||
return [img[CPU].width * img.rect.width, img[CPU].height * img.rect.height]
|
||||
}
|
||||
return [0, 0]
|
||||
}
|
||||
|
||||
function decorate_rect_px(img) {
|
||||
// needs a GPU texture to measure
|
||||
if (!img || !img.texture) return
|
||||
|
||||
// default UV rect is the whole image if none supplied
|
||||
img.rect ??= {x:0, y:0, width:1, height:1} // [u0,v0,uw,vh] in 0-1
|
||||
|
||||
var width = 0, height = 0;
|
||||
if (img.texture) {
|
||||
width = img.texture.width;
|
||||
height = img.texture.height;
|
||||
} else if (img[CPU]) {
|
||||
width = img[CPU].width;
|
||||
height = img[CPU].height;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// store pixel-space version: [x, y, w, h] in texels
|
||||
img.rect_px = {
|
||||
x:Math.round(img.rect.x * img.texture.width),
|
||||
y:Math.round(img.rect.y * img.texture.height),
|
||||
width:Math.round(img.rect.width * img.texture.width),
|
||||
height:Math.round(img.rect.height * img.texture.height)
|
||||
x:Math.round(img.rect.x * width),
|
||||
y:Math.round(img.rect.y * height),
|
||||
width:Math.round(img.rect.width * width),
|
||||
height:Math.round(img.rect.height * height)
|
||||
}
|
||||
}
|
||||
|
||||
function make_handle(obj)
|
||||
{
|
||||
return new graphics.Image(obj);
|
||||
var img = new graphics.Image(obj);
|
||||
decorate_rect_px(img);
|
||||
return img;
|
||||
}
|
||||
|
||||
function wrapSurface(surf, maybeRect){
|
||||
@@ -189,7 +204,15 @@ function create_image(path){
|
||||
|
||||
var image = {}
|
||||
image.dimensions = function() {
|
||||
return [this.texture.width, this.texture.height].scale([this.rect[2], this.rect[3]])
|
||||
var width = 0, height = 0;
|
||||
if (this.texture) {
|
||||
width = this.texture.width;
|
||||
height = this.texture.height;
|
||||
} else if (this[CPU]) {
|
||||
width = this[CPU].width;
|
||||
height = this[CPU].height;
|
||||
}
|
||||
return [width, height].scale([this.rect[2], this.rect[3]])
|
||||
}
|
||||
image.dimensions[cell.DOC] = `
|
||||
:return: A 2D array [width, height] that is the scaled size of this image (texture size * rect size).
|
||||
@@ -224,7 +247,7 @@ graphics.texture_from_data = function(data)
|
||||
var image = graphics.make_texture(data);
|
||||
var img = make_handle(image)
|
||||
|
||||
img.gpu;
|
||||
if (renderer_actor) img.gpu;
|
||||
|
||||
return img;
|
||||
}
|
||||
@@ -341,6 +364,7 @@ graphics.get_font = function get_font(path, size) {
|
||||
var font = graphics.make_font(data,size)
|
||||
|
||||
// Load font texture via renderer actor (async)
|
||||
if (renderer_actor) {
|
||||
send(renderer_actor, {
|
||||
kind: "renderer",
|
||||
op: "loadTexture",
|
||||
@@ -352,6 +376,7 @@ graphics.get_font = function get_font(path, size) {
|
||||
font.texture = response;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fontcache[fontstr] = font
|
||||
|
||||
|
||||
@@ -218,8 +218,6 @@ JSValue __##PROP##__v = JS_GetPropertyStr(JS,VALUE,#ATOM); \
|
||||
TARGET = js2##TYPE(JS, __##PROP##__v); \
|
||||
JS_FreeValue(JS,__##PROP##__v); }\
|
||||
|
||||
#define JS_SETATOM(JS, TARGET, ATOM, VALUE, TYPE) JS_SetProperty(JS, TARGET, #ATOM, TYPE##2js(JS, VALUE));
|
||||
|
||||
int JS_GETBOOL(JSContext *js, JSValue v, const char *prop)
|
||||
{
|
||||
JSValue __v = JS_GetPropertyStr(js,v,prop);
|
||||
@@ -429,8 +427,23 @@ JSValue color2js(JSContext *js, colorf color)
|
||||
HMM_Vec2 js2vec2(JSContext *js,JSValue v)
|
||||
{
|
||||
HMM_Vec2 v2;
|
||||
|
||||
// Check if it's an array
|
||||
if (JS_IsArray(js, v)) {
|
||||
v2.X = js_getnum_uint32(js,v,0);
|
||||
v2.Y = js_getnum_uint32(js,v,1);
|
||||
} else {
|
||||
// Try to get x,y properties from object
|
||||
JSValue x_val = JS_GetPropertyStr(js, v, "x");
|
||||
JSValue y_val = JS_GetPropertyStr(js, v, "y");
|
||||
|
||||
v2.X = js2number(js, x_val);
|
||||
v2.Y = js2number(js, y_val);
|
||||
|
||||
JS_FreeValue(js, x_val);
|
||||
JS_FreeValue(js, y_val);
|
||||
}
|
||||
|
||||
return v2;
|
||||
}
|
||||
|
||||
@@ -609,10 +622,10 @@ HMM_Vec2 transform_point(SDL_Renderer *ren, HMM_Vec2 in, HMM_Mat3 *t)
|
||||
|
||||
JSValue rect2js(JSContext *js,rect rect) {
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SETATOM(js, obj, x, rect.x, number);
|
||||
JS_SETATOM(js, obj, y, rect.y, number);
|
||||
JS_SETATOM(js, obj, width, rect.w, number);
|
||||
JS_SETATOM(js, obj, height, rect.h, number);
|
||||
JS_SetPropertyStr(js, obj, "x", number2js(js, rect.x));
|
||||
JS_SetPropertyStr(js, obj, "y", number2js(js, rect.y));
|
||||
JS_SetPropertyStr(js, obj, "width", number2js(js, rect.w));
|
||||
JS_SetPropertyStr(js, obj, "height", number2js(js, rect.h));
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,16 +36,35 @@ static JSValue js_layout_set_size(JSContext *js, JSValueConst self, int argc, JS
|
||||
|
||||
GETLAY
|
||||
GETITEM(id, argv[0])
|
||||
double size[2];
|
||||
double width = 0, height = 0;
|
||||
|
||||
// Check if it's an array (for backwards compatibility)
|
||||
if (JS_IsArray(js, argv[1])) {
|
||||
JSValue width_val = JS_GetPropertyUint32(js, argv[1], 0);
|
||||
JSValue height_val = JS_GetPropertyUint32(js, argv[1], 1);
|
||||
JS_ToFloat64(js, &size[0], width_val);
|
||||
JS_ToFloat64(js, &size[1], height_val);
|
||||
JS_ToFloat64(js, &width, width_val);
|
||||
JS_ToFloat64(js, &height, height_val);
|
||||
JS_FreeValue(js, width_val);
|
||||
JS_FreeValue(js, height_val);
|
||||
if (isnan(size[0])) size[0] = 0;
|
||||
if (isnan(size[1])) size[1] = 0;
|
||||
lay_set_size_xy(lay, id, size[0], size[1]);
|
||||
} else {
|
||||
// Handle object with x,y or width,height properties
|
||||
JSValue width_val = JS_GetPropertyStr(js, argv[1], "width");
|
||||
if (JS_IsNull(width_val)) {
|
||||
width_val = JS_GetPropertyStr(js, argv[1], "x");
|
||||
}
|
||||
JSValue height_val = JS_GetPropertyStr(js, argv[1], "height");
|
||||
if (JS_IsNull(height_val)) {
|
||||
height_val = JS_GetPropertyStr(js, argv[1], "y");
|
||||
}
|
||||
JS_ToFloat64(js, &width, width_val);
|
||||
JS_ToFloat64(js, &height, height_val);
|
||||
JS_FreeValue(js, width_val);
|
||||
JS_FreeValue(js, height_val);
|
||||
}
|
||||
|
||||
if (isnan(width)) width = 0;
|
||||
if (isnan(height)) height = 0;
|
||||
lay_set_size_xy(lay, id, width, height);
|
||||
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
@@ -7129,11 +7129,14 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj,
|
||||
} else {
|
||||
slow_path:
|
||||
/* ToObject() must be done before ToPropertyKey() */
|
||||
atom = JS_ValueToAtom(ctx, prop);
|
||||
if (JS_IsNull(this_obj)) {
|
||||
JS_FreeValue(ctx, prop);
|
||||
return JS_ThrowTypeError(ctx, "cannot read property of null");
|
||||
JSValue ret = JS_ThrowTypeErrorAtom(ctx, "cannot read property '%s' of null", atom);
|
||||
JS_FreeAtom(ctx, atom);
|
||||
return ret;
|
||||
}
|
||||
atom = JS_ValueToAtom(ctx, prop);
|
||||
|
||||
JS_FreeValue(ctx, prop);
|
||||
if (unlikely(atom == JS_ATOM_NULL))
|
||||
return JS_EXCEPTION;
|
||||
|
||||
Reference in New Issue
Block a user