Canvas API: draw (rounded) rect and rename Dialog to Window.
- std.string: * Add method compare * Add method starts_with - canvas.Group: * Add method rect for drawing (rounded) rectangles - Rename canvas.Dialog to canvas.Window to free the name Dialog for real dialogs.
This commit is contained in:
parent
49d7af00b4
commit
91ae186330
3 changed files with 141 additions and 14 deletions
|
@ -317,6 +317,89 @@ var Group = {
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
},
|
},
|
||||||
|
# Create a path child drawing a (rounded) rectangle
|
||||||
|
#
|
||||||
|
# @param x Position of left border
|
||||||
|
# @param y Position of top border
|
||||||
|
# @param w Width
|
||||||
|
# @param h Height
|
||||||
|
# @param cfg Optional settings (eg. {"border-top-radius": 5})
|
||||||
|
rect: func(x, y, w, h, cfg = nil)
|
||||||
|
{
|
||||||
|
var opts = (cfg != nil) ? cfg : {};
|
||||||
|
|
||||||
|
# resolve border-[top-,bottom-][left-,right-]radius
|
||||||
|
var br = opts["border-radius"];
|
||||||
|
if( typeof(br) == 'scalar' )
|
||||||
|
br = [br, br];
|
||||||
|
|
||||||
|
var _parseRadius = func(id)
|
||||||
|
{
|
||||||
|
var r = opts["border-" ~ id ~ "-radius"];
|
||||||
|
var id = std.string.new(id);
|
||||||
|
|
||||||
|
if( r == nil )
|
||||||
|
{
|
||||||
|
# parse top, bottom, left, right separate if no value specified for
|
||||||
|
# single corner
|
||||||
|
foreach(var s; ["top", "bottom", "left", "right"])
|
||||||
|
{
|
||||||
|
if( id.starts_with(s ~ "-") )
|
||||||
|
{
|
||||||
|
r = opts["border-" ~ s ~ "-radius"];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( r == nil )
|
||||||
|
return br;
|
||||||
|
else if( typeof(r) == 'scalar' )
|
||||||
|
return [r, r];
|
||||||
|
else
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
|
var path = me.createChild("path");
|
||||||
|
|
||||||
|
# top-left
|
||||||
|
if( (var r = _parseRadius("top-left")) != nil )
|
||||||
|
{
|
||||||
|
path.moveTo(x, y + r[1])
|
||||||
|
.arcSmallCWTo(r[0], r[1], 0, x + r[0], y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
path.moveTo(x, y);
|
||||||
|
|
||||||
|
# top-right
|
||||||
|
if( (r = _parseRadius("top-right")) != nil )
|
||||||
|
{
|
||||||
|
path.horizTo(x + w - r[0])
|
||||||
|
.arcSmallCWTo(r[0], r[1], 0, x + w, y + r[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
path.horizTo(x + w);
|
||||||
|
|
||||||
|
# bottom-right
|
||||||
|
if( (r = _parseRadius("bottom-right")) != nil )
|
||||||
|
{
|
||||||
|
path.vertTo(y + h - r[1])
|
||||||
|
.arcSmallCWTo(r[0], r[1], 0, x + w - r[0], y + h);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
path.vertTo(y + h);
|
||||||
|
|
||||||
|
# bottom-left
|
||||||
|
if( (r = _parseRadius("bottom-left")) != nil )
|
||||||
|
{
|
||||||
|
path.horizTo(x + r[0])
|
||||||
|
.arcSmallCWTo(r[0], r[1], 0, x, y + h - r[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
path.horizTo(x);
|
||||||
|
|
||||||
|
return path.close();
|
||||||
|
},
|
||||||
# Get a vector of all child elements
|
# Get a vector of all child elements
|
||||||
getChildren: func()
|
getChildren: func()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
var Dialog = {
|
var Window = {
|
||||||
# Constructor
|
# Constructor
|
||||||
#
|
#
|
||||||
# @param size_dlg Dialog size ([width, height])
|
# @param size ([width, height])
|
||||||
new: func(size_dlg, id = nil)
|
new: func(size, id = nil)
|
||||||
{
|
{
|
||||||
var m = {
|
var m = {
|
||||||
parents: [Dialog, PropertyElement.new(["/sim/gui/canvas", "window"], id)]
|
parents: [Window, PropertyElement.new(["/sim/gui/canvas", "window"], id)]
|
||||||
};
|
};
|
||||||
m.setInt("size[0]", size_dlg[0]);
|
m.setInt("size[0]", size[0]);
|
||||||
m.setInt("size[1]", size_dlg[1]);
|
m.setInt("size[1]", size[1]);
|
||||||
|
|
||||||
# arg = [child, listener_node, mode, is_child_event]
|
# arg = [child, listener_node, mode, is_child_event]
|
||||||
setlistener(m._node, func m._propCallback(arg[0], arg[2]), 0, 2);
|
setlistener(m._node, func m._propCallback(arg[0], arg[2]), 0, 2);
|
||||||
|
@ -22,26 +22,29 @@ var Dialog = {
|
||||||
if( me["_canvas"] != nil )
|
if( me["_canvas"] != nil )
|
||||||
me._canvas.del();
|
me._canvas.del();
|
||||||
},
|
},
|
||||||
# Create the canvas to be used for this dialog
|
# Create the canvas to be used for this Window
|
||||||
#
|
#
|
||||||
# @return The new canvas
|
# @return The new canvas
|
||||||
createCanvas: func()
|
createCanvas: func()
|
||||||
{
|
{
|
||||||
var size_dlg = [
|
var size = [
|
||||||
me.get("size[0]"),
|
me.get("size[0]"),
|
||||||
me.get("size[1]")
|
me.get("size[1]")
|
||||||
];
|
];
|
||||||
|
|
||||||
me._canvas = new({
|
me._canvas = new({
|
||||||
size: [2 * size_dlg[0], 2 * size_dlg[1]],
|
size: [2 * size[0], 2 * size[1]],
|
||||||
view: size_dlg,
|
view: size,
|
||||||
placement: {
|
placement: {
|
||||||
type: "window",
|
type: "window",
|
||||||
index: me._node.getIndex()
|
index: me._node.getIndex()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
me._canvas.addEventListener("mousedown", func me.raise());
|
||||||
|
return me._canvas;
|
||||||
},
|
},
|
||||||
# Set an existing canvas to be used for this dialog
|
# Set an existing canvas to be used for this Window
|
||||||
setCanvas: func(canvas_)
|
setCanvas: func(canvas_)
|
||||||
{
|
{
|
||||||
if( !isa(canvas_, canvas.Canvas) )
|
if( !isa(canvas_, canvas.Canvas) )
|
||||||
|
|
|
@ -11,6 +11,43 @@ var string = {
|
||||||
{
|
{
|
||||||
return { parents: [string], _str: str };
|
return { parents: [string], _str: str };
|
||||||
},
|
},
|
||||||
|
# compare(s)
|
||||||
|
# compare(pos, n, s)
|
||||||
|
#
|
||||||
|
# @param s String to compare to
|
||||||
|
# @param pos Position of first character used to compare
|
||||||
|
# @param n Number of characters to compare
|
||||||
|
compare: func
|
||||||
|
{
|
||||||
|
var s = "";
|
||||||
|
var pos = 0;
|
||||||
|
var n = -1;
|
||||||
|
|
||||||
|
var num = size(arg);
|
||||||
|
if( num == 1 )
|
||||||
|
s = arg[0];
|
||||||
|
else if( num == 3 )
|
||||||
|
{
|
||||||
|
pos = arg[0];
|
||||||
|
n = arg[1];
|
||||||
|
s = arg[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
die("std::string::compare: Invalid args");
|
||||||
|
|
||||||
|
if( n < 0 )
|
||||||
|
n = me.size();
|
||||||
|
else if( n > me.size() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( n != size(s) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(var i = pos; i < n; i += 1)
|
||||||
|
if( me._str[i] != s[i] )
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
},
|
||||||
find_first_of: func(s, pos = 0)
|
find_first_of: func(s, pos = 0)
|
||||||
{
|
{
|
||||||
return me._find(pos, size(me._str), s, 1);
|
return me._find(pos, size(me._str), s, 1);
|
||||||
|
@ -27,6 +64,10 @@ var string = {
|
||||||
{
|
{
|
||||||
return substr(me._str, pos, len);
|
return substr(me._str, pos, len);
|
||||||
},
|
},
|
||||||
|
starts_with: func(s)
|
||||||
|
{
|
||||||
|
return me.compare(0, size(s), s);
|
||||||
|
},
|
||||||
size: func()
|
size: func()
|
||||||
{
|
{
|
||||||
return size(me._str);
|
return size(me._str);
|
||||||
|
@ -63,12 +104,12 @@ var stoul = func(str, base = 10)
|
||||||
var digval = _string.toupper(c) - `A` + 10;
|
var digval = _string.toupper(c) - `A` + 10;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( digval >= base )
|
if( digval >= base )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
val = val * base + digval;
|
val = val * base + digval;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue