Canvas: Basic GUI API and API cleanup
This commit is contained in:
parent
eda3232dc4
commit
20c6d48ee7
3 changed files with 163 additions and 78 deletions
64
Nasal/canvas/PropertyElement.nas
Normal file
64
Nasal/canvas/PropertyElement.nas
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# PropertyElement
|
||||||
|
# ==============================================================================
|
||||||
|
# Baseclass for all property controlled elements/objects
|
||||||
|
#
|
||||||
|
var PropertyElement = {
|
||||||
|
# Constructor
|
||||||
|
#
|
||||||
|
# @param node Node to be used for element or vector [parent, type] for
|
||||||
|
# creation of a new node with name type and given parent
|
||||||
|
# @param id ID/Name (Should be unique)
|
||||||
|
new: func(node, id)
|
||||||
|
{
|
||||||
|
if( typeof(node) == 'vector' )
|
||||||
|
var node = _createNodeWithIndex(node[0], node[1]);
|
||||||
|
else
|
||||||
|
var node = aircraft.makeNode(node);
|
||||||
|
|
||||||
|
if( !isa(node, props.Node) )
|
||||||
|
return debug.warn("Not a props.Node!");
|
||||||
|
|
||||||
|
var m = {
|
||||||
|
parents: [PropertyElement],
|
||||||
|
_node: node
|
||||||
|
};
|
||||||
|
|
||||||
|
if( id != nil )
|
||||||
|
m.set("id", id);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
},
|
||||||
|
# Destructor (has to be called manually!)
|
||||||
|
del: func()
|
||||||
|
{
|
||||||
|
me._node.remove();
|
||||||
|
},
|
||||||
|
set: func(key, value)
|
||||||
|
{
|
||||||
|
me._node.getNode(key, 1).setValue(value);
|
||||||
|
return me;
|
||||||
|
},
|
||||||
|
setBool: func(key, value)
|
||||||
|
{
|
||||||
|
me._node.getNode(key, 1).setBoolValue(value);
|
||||||
|
return me;
|
||||||
|
},
|
||||||
|
setDouble: func(key, value)
|
||||||
|
{
|
||||||
|
me._node.getNode(key, 1).setDoubleValue(value);
|
||||||
|
return me;
|
||||||
|
},
|
||||||
|
setInt: func(key, value)
|
||||||
|
{
|
||||||
|
me._node.getNode(key, 1).setIntValue(value);
|
||||||
|
return me;
|
||||||
|
},
|
||||||
|
get: func(key, default = nil)
|
||||||
|
{
|
||||||
|
var node = me._node.getNode(key);
|
||||||
|
if( node != nil )
|
||||||
|
return node.getValue();
|
||||||
|
else
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
};
|
|
@ -3,6 +3,8 @@
|
||||||
#
|
#
|
||||||
var _createNodeWithIndex = func(node, path, min_index = 0)
|
var _createNodeWithIndex = func(node, path, min_index = 0)
|
||||||
{
|
{
|
||||||
|
var node = aircraft.makeNode(node);
|
||||||
|
|
||||||
# TODO do we need an upper limit? (50000 seems already seems unreachable)
|
# TODO do we need an upper limit? (50000 seems already seems unreachable)
|
||||||
for(var i = min_index; i < 50000; i += 1)
|
for(var i = min_index; i < 50000; i += 1)
|
||||||
{
|
{
|
||||||
|
@ -161,61 +163,20 @@ var Transform = {
|
||||||
var Element = {
|
var Element = {
|
||||||
# Constructor
|
# Constructor
|
||||||
#
|
#
|
||||||
# @param parent Parent node (In the property tree)
|
# @param node Node to be used for element or vector [parent, type] for
|
||||||
# @param type Type string (Used as node name)
|
# creation of a new node with name type and given parent
|
||||||
# @param id ID/Name (Should be unique)
|
# @param id ID/Name (Should be unique)
|
||||||
new: func(parent, type, id)
|
new: func(node, id)
|
||||||
{
|
{
|
||||||
# arg can contain the node to be used instead of creating a new one
|
var m = { parents: [PropertyElement.new(node, id), Element] };
|
||||||
var args = _arg2valarray(arg);
|
|
||||||
if( size(args) == 1 )
|
|
||||||
{
|
|
||||||
var node = args[0];
|
|
||||||
if( !isa(node, props.Node) )
|
|
||||||
return debug.warn("Not a props.Node!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
var node = _createNodeWithIndex(parent, type);
|
|
||||||
|
|
||||||
var m = {
|
m._center = [
|
||||||
parents: [Element],
|
m._node.getNode("center[0]"),
|
||||||
_node: node,
|
m._node.getNode("center[1]")
|
||||||
_center: [
|
];
|
||||||
node.getNode("center[0]"),
|
|
||||||
node.getNode("center[1]")
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
if( id != nil )
|
|
||||||
m._node.getNode("id", 1).setValue(id);
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
},
|
},
|
||||||
# Destructor (has to be called manually!)
|
|
||||||
del: func()
|
|
||||||
{
|
|
||||||
me._node.remove();
|
|
||||||
},
|
|
||||||
set: func(key, value)
|
|
||||||
{
|
|
||||||
me._node.getNode(key, 1).setValue(value);
|
|
||||||
return me;
|
|
||||||
},
|
|
||||||
setBool: func(key, value)
|
|
||||||
{
|
|
||||||
me._node.getNode(key, 1).setBoolValue(value);
|
|
||||||
return me;
|
|
||||||
},
|
|
||||||
setDouble: func(key, value)
|
|
||||||
{
|
|
||||||
me._node.getNode(key, 1).setDoubleValue(value);
|
|
||||||
return me;
|
|
||||||
},
|
|
||||||
setInt: func(key, value)
|
|
||||||
{
|
|
||||||
me._node.getNode(key, 1).setIntValue(value);
|
|
||||||
return me;
|
|
||||||
},
|
|
||||||
# Trigger an update of the element
|
# Trigger an update of the element
|
||||||
#
|
#
|
||||||
# Elements are automatically updated once a frame, with a delay of one frame.
|
# Elements are automatically updated once a frame, with a delay of one frame.
|
||||||
|
@ -342,17 +303,9 @@ var Element = {
|
||||||
# Class for a group element on a canvas
|
# Class for a group element on a canvas
|
||||||
#
|
#
|
||||||
var Group = {
|
var Group = {
|
||||||
new: func(parent, id, type = "group")
|
new: func(node, id)
|
||||||
{
|
{
|
||||||
# special case: if called from #getElementById the third argument is the
|
return { parents: [Group, Element.new(node, id)] };
|
||||||
# existing node so we need to rearange the variables a bit.
|
|
||||||
if( typeof(type) != "scalar" )
|
|
||||||
{
|
|
||||||
var arg = [type];
|
|
||||||
var type = "group";
|
|
||||||
}
|
|
||||||
|
|
||||||
return { parents: [Group, Element.new(parent, type, id, arg)] };
|
|
||||||
},
|
},
|
||||||
# Create a child of given type with specified id.
|
# Create a child of given type with specified id.
|
||||||
# type can be group, text
|
# type can be group, text
|
||||||
|
@ -366,7 +319,7 @@ var Group = {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return factory(me._node, id);
|
return factory([me._node, type], id);
|
||||||
},
|
},
|
||||||
# Get first child with given id (breadth-first search)
|
# Get first child with given id (breadth-first search)
|
||||||
#
|
#
|
||||||
|
@ -387,13 +340,8 @@ var Group = {
|
||||||
{
|
{
|
||||||
var node_id = node.getNode("id");
|
var node_id = node.getNode("id");
|
||||||
if( node_id != nil and node_id.getValue() == id )
|
if( node_id != nil and node_id.getValue() == id )
|
||||||
return me._element_factories[ node.getName() ]
|
# Create element from existing node
|
||||||
(
|
return me._element_factories[ node.getName() ](node, nil);
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
# use the existing node
|
|
||||||
node
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(var c; node.getChildren())
|
foreach(var c; node.getChildren())
|
||||||
|
@ -419,9 +367,9 @@ var Group = {
|
||||||
# which automatically get projected according to the specified projection.
|
# which automatically get projected according to the specified projection.
|
||||||
#
|
#
|
||||||
var Map = {
|
var Map = {
|
||||||
new: func(parent, id)
|
new: func(node, id)
|
||||||
{
|
{
|
||||||
return { parents: [Map, Group.new(parent, id, "map", arg)] };
|
return { parents: [Map, Group.new(node, id)] };
|
||||||
}
|
}
|
||||||
# TODO
|
# TODO
|
||||||
};
|
};
|
||||||
|
@ -431,11 +379,9 @@ var Map = {
|
||||||
# Class for a text element on a canvas
|
# Class for a text element on a canvas
|
||||||
#
|
#
|
||||||
var Text = {
|
var Text = {
|
||||||
new: func(parent, id)
|
new: func(node, id)
|
||||||
{
|
{
|
||||||
var m = {
|
var m = { parents: [Text, Element.new(node, id)] };
|
||||||
parents: [Text, Element.new(parent, "text", id, arg)]
|
|
||||||
};
|
|
||||||
m.color = _createColorNodes(m._node, "color");
|
m.color = _createColorNodes(m._node, "color");
|
||||||
m.color_fill = _createColorNodes(m._node, "color-fill");
|
m.color_fill = _createColorNodes(m._node, "color-fill");
|
||||||
return m;
|
return m;
|
||||||
|
@ -566,10 +512,10 @@ var Path = {
|
||||||
],
|
],
|
||||||
|
|
||||||
#
|
#
|
||||||
new: func(parent, id)
|
new: func(node, id)
|
||||||
{
|
{
|
||||||
var m = {
|
var m = {
|
||||||
parents: [Path, Element.new(parent, "path", id, arg)],
|
parents: [Path, Element.new(node, id)],
|
||||||
_num_cmds: 0,
|
_num_cmds: 0,
|
||||||
_num_coords: 0
|
_num_coords: 0
|
||||||
};
|
};
|
||||||
|
@ -706,10 +652,10 @@ var Path = {
|
||||||
# Class for an image element on a canvas
|
# Class for an image element on a canvas
|
||||||
#
|
#
|
||||||
var Image = {
|
var Image = {
|
||||||
new: func(parent, id)
|
new: func(node, id)
|
||||||
{
|
{
|
||||||
var m = {
|
var m = {
|
||||||
parents: [Image, Element.new(parent, "image", id, arg)]
|
parents: [Image, Element.new(node, id)]
|
||||||
};
|
};
|
||||||
m.color_fill = _createColorNodes(m._node, "color-fill");
|
m.color_fill = _createColorNodes(m._node, "color-fill");
|
||||||
return m;
|
return m;
|
||||||
|
@ -786,7 +732,7 @@ var Canvas = {
|
||||||
# @param id Optional id/name for the group
|
# @param id Optional id/name for the group
|
||||||
createGroup: func(id = nil)
|
createGroup: func(id = nil)
|
||||||
{
|
{
|
||||||
return Group.new(me.texture, id);
|
return Group.new([me.texture, "group"], id);
|
||||||
},
|
},
|
||||||
# Set the background color
|
# Set the background color
|
||||||
#
|
#
|
||||||
|
|
75
Nasal/canvas/gui.nas
Normal file
75
Nasal/canvas/gui.nas
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
var Dialog = {
|
||||||
|
# Constructor
|
||||||
|
#
|
||||||
|
# @param size_dlg Dialog size ([width, height])
|
||||||
|
new: func(size_dlg, id = nil)
|
||||||
|
{
|
||||||
|
var m = {
|
||||||
|
parents: [Dialog, PropertyElement.new(["/sim/gui/canvas", "window"], id)]
|
||||||
|
};
|
||||||
|
m.setInt("size[0]", size_dlg[0]);
|
||||||
|
m.setInt("size[1]", size_dlg[1]);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
},
|
||||||
|
# Create the canvas to be used for this dialog
|
||||||
|
#
|
||||||
|
# @return The new canvas
|
||||||
|
createCanvas: func()
|
||||||
|
{
|
||||||
|
var size_dlg = [
|
||||||
|
me.get("size[0]"),
|
||||||
|
me.get("size[1]")
|
||||||
|
];
|
||||||
|
|
||||||
|
me._canvas = new({
|
||||||
|
size: [2 * size_dlg[0], 2 * size_dlg[1]],
|
||||||
|
view: size_dlg,
|
||||||
|
placement: {
|
||||||
|
type: "window",
|
||||||
|
index: me._node.getIndex()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
# Set an existing canvas to be used for this dialog
|
||||||
|
setCanvas: func(canvas_)
|
||||||
|
{
|
||||||
|
if( !isa(canvas_, canvas.Canvas) )
|
||||||
|
return debug.warn("Not a canvas.Canvas");
|
||||||
|
|
||||||
|
canvas_.addPlacement({type: "window", index: me._node.getIndex()});
|
||||||
|
me['_canvas'] = canvas_;
|
||||||
|
},
|
||||||
|
# Get the displayed canvas
|
||||||
|
getCanvas: func()
|
||||||
|
{
|
||||||
|
return me['_canvas'];
|
||||||
|
},
|
||||||
|
setPosition: func(x, y)
|
||||||
|
{
|
||||||
|
me.setInt("x", x);
|
||||||
|
me.setInt("y", y);
|
||||||
|
},
|
||||||
|
move: func(x, y)
|
||||||
|
{
|
||||||
|
me.setInt("x", me.get("x", 0) + x);
|
||||||
|
me.setInt("y", me.get("y", 0) + y);
|
||||||
|
},
|
||||||
|
# Raise to top of window stack
|
||||||
|
raise: func()
|
||||||
|
{
|
||||||
|
me.setBool("raise-top", 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var Event = {
|
||||||
|
PUSH: 1,
|
||||||
|
RELEASE: 2,
|
||||||
|
DRAG: 8,
|
||||||
|
MOVE: 16,
|
||||||
|
SCROLL: 512,
|
||||||
|
|
||||||
|
LEFT_MOUSE_BUTTON: 1,
|
||||||
|
MIDDLE_MOUSE_BUTTON: 2,
|
||||||
|
RIGHT_MOUSE_BUTTON: 4
|
||||||
|
};
|
Loading…
Reference in a new issue