diff --git a/Nasal/canvas/gui/widgets/CdlgWidgets.nas b/Nasal/canvas/gui/widgets/CdlgWidgets.nas
new file mode 100644
index 000000000..a9fd4d76a
--- /dev/null
+++ b/Nasal/canvas/gui/widgets/CdlgWidgets.nas
@@ -0,0 +1,452 @@
+# generic widgets for aircraft-side canvas dialogs
+# Thorsten Renk 2018
+
+# box gauge ##############################################################
+
+var cdlg_widget_box = {
+	new: func (root, width, height, color, fill_color ) {
+ 	var wb = { parents: [cdlg_widget_box] };
+		
+	wb.width = width;
+	wb.height = height;
+	wb.color = color;
+	wb.fill_color = fill_color;
+
+	wb.graph = root.createChild("group", "box_widget");
+
+	#var data = [[0.0, 0.0], [0.0, height], [width, height], [width, 0.0], [0.0, 0.0]];
+	
+	var data = [[0.0, 0.0], [-0.5 * width, 0.0], [-0.5*width, -height], [0.5*width, -height], [0.5*width, 0.0], [0.0, 0.0]];
+
+	wb.frame = wb.graph.createChild("path", "")
+        .setStrokeLineWidth(2)
+        .setColor(color)
+	.moveTo(data[0][0], data[0][1]);
+	for (var i = 0; (i< size(data)-1); i=i+1) 
+		{wb.frame.lineTo(data[i+1][0], data[i+1][1]);}
+
+	wb.fill = wb.graph.createChild("path", "")
+        .setStrokeLineWidth(2)
+        .setColor(color)
+	.setColorFill(fill_color)
+	.moveTo(data[0][0], data[0][1]);
+	for (var i = 0; (i< size(data)-1); i=i+1) 
+		{wb.fill.lineTo(data[i+1][0], data[i+1][1]);}
+
+	return wb;
+	},
+
+
+	setTranslation: func (x,y) {
+		me.graph.setTranslation(x,y);
+
+	},
+
+	setPercentageHt: func (x) {
+
+		if (x > 1.0)
+			{x = 1.0;}
+		else if (x < 0.0) {x = 0.0;}
+
+		var red_ht = me.height * x;
+
+		var cmd = [canvas.Path.VG_MOVE_TO, canvas.Path.VG_LINE_TO,
+	  		canvas.Path.VG_LINE_TO,canvas.Path.VG_LINE_TO,canvas.Path.VG_LINE_TO];
+
+		var draw = [0.0, 0.0, -0.5 * me.width, 0.0, -0.5*me.width, -red_ht, 0.5*me.width, -red_ht, 0.5*me.width, 0.0, 0.0, 0.0];
+
+
+		me.fill.setData(cmd, draw);
+
+	},
+
+	setContextHelp: func (f) {
+
+			me.frame.addEventListener("mouseover", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'left-right'}));
+			f("mouseover");
+		  	});
+
+			me.frame.addEventListener("mouseout", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'inherit'}));
+			f("mouseout");
+		  	});
+
+			me.fill.addEventListener("mouseover", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'left-right'}));
+			f("mouseover");
+		  	});
+
+			me.fill.addEventListener("mouseout", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'inherit'}));
+			f("mouseout");
+		  	});
+
+
+
+	},
+
+
+};
+
+
+
+# tank gauge ##############################################################
+
+var cdlg_widget_tank = {
+	new: func (root, radius, color, fill_color ) {
+	 	var wtk = { parents: [cdlg_widget_tank] };
+		
+		wtk.radius = radius;
+		wtk.color = color;
+		wtk.fill_color = fill_color;
+
+		wtk.graph = root.createChild("group", "tank_widget");
+
+		var data = [];
+
+
+		for (var i = 0; i< 33; i=i+1)
+			{
+			var phi = i * 2.0 * math.pi/32.0;
+
+			var x = radius * math.cos(phi);
+			var y = radius * math.sin(phi);
+
+			append(data, [x,y]);
+			}
+
+
+		wtk.frame = wtk.graph.createChild("path", "")
+		.setStrokeLineWidth(2)
+		.setColor(color)
+		.moveTo(data[0][0], data[0][1]);
+		for (var i = 0; (i< size(data)-1); i=i+1) 
+			{wtk.frame.lineTo(data[i+1][0], data[i+1][1]);}
+
+		wtk.fill = wtk.graph.createChild("path", "")
+		.setStrokeLineWidth(2)
+		.setColor(color)
+		.setColorFill(fill_color)
+		.moveTo(data[0][0], data[0][1]);
+		for (var i = 0; (i< size(data)-1); i=i+1) 
+			{wtk.fill.lineTo(data[i+1][0], data[i+1][1]);}
+
+
+
+		return wtk;
+	},
+
+	setTranslation: func (x,y) {
+		me.graph.setTranslation(x,y);
+
+	},
+
+	setPercentage: func (x) {
+
+		if (x > 1.0)
+			{x = 1.0;}
+		else if (x < 0.0) {x = 0.0;}
+
+		var red_ht = me.radius -2.0 * me.radius * x;
+		var arg = me.radius * me.radius - red_ht * red_ht;
+		if (arg < 0.0) {arg = 0.0;}
+
+		var xlimit = math.sqrt(arg);
+		
+		var draw = [];
+		var cmd = [];
+
+		for (var i = 0; i< 33; i=i+1)
+			{
+			var phi = i * 2.0 * math.pi/32.0;
+
+			var x = me.radius * math.cos(phi);
+			var y = me.radius * math.sin(phi);
+
+			
+			if (y < red_ht) { y = red_ht; if (x>0.0) {x = xlimit;} else {x=-xlimit;} }
+
+			append(draw,x);
+			append(draw,y);
+			append(cmd, canvas.Path.VG_LINE_TO);
+			}
+
+		cmd[0] = canvas.Path.VG_MOVE_TO; 
+
+		me.fill.setData(cmd, draw);		
+
+	},
+
+
+	setContextHelp: func (f) {
+
+			me.frame.addEventListener("mouseover", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'left-right'}));
+			f("mouseover");
+		  	});
+
+			me.frame.addEventListener("mouseout", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'inherit'}));
+			f("mouseout");
+		  	});
+
+			me.fill.addEventListener("mouseover", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'left-right'}));
+			f("mouseover");
+		  	});
+
+			me.fill.addEventListener("mouseout", func(e) {
+			fgcommand("set-cursor", props.Node.new({'cursor':'inherit'}));
+			f("mouseout");
+		  	});
+
+
+
+	},
+
+
+};
+
+
+# property display labels ##############################################################
+
+var cdlg_widget_property_label = {
+	new: func (root, text, text_color = nil, color = nil, fill_color = nil ) {
+ 	var pl = { parents: [cdlg_widget_property_label] };
+		
+	pl.text_string = text;
+	pl.size = utf8.size(text);
+	pl.limits = 0;
+
+	if (text_color == nil) {text_color = [0.0, 0.0, 0.0];}
+	pl.text_color = text_color;
+
+	pl.font_scale_factor = 1.0;
+
+	if (color == nil) 
+		{pl.box_mode = 0;}
+	else
+		{
+		pl.color = color;
+		pl.box_mode = 1;
+		}
+
+	if (fill_color == nil)
+		{
+		pl.box_fill = 0;
+		}
+	else
+		{
+		pl.box_fill = 1;
+		pl.fill_color = fill_color;
+		}
+
+
+
+	pl.graph = root.createChild("group", "property_label");
+
+
+
+	if (pl.box_mode == 1)
+		{
+		var height = 25.0;
+		var width = 10.0 * pl.size;
+		var data = [[0.0, -0.8 * height], [-0.5 * width, -0.8 * height], [-0.5 * width, 0.2 * height], [0.5 * width, 0.2 * height], [0.5 * width, -0.8 * height],[0.0, -0.8 * height]];
+		pl.box = pl.graph.createChild("path", "")
+		.setStrokeLineWidth(2)
+		.setColor(color)
+		.moveTo(data[0][0], data[0][1]);
+		for (var i = 0; (i< size(data)-1); i=i+1) 
+			{pl.box.lineTo(data[i+1][0], data[i+1][1]);}
+
+		if (pl.box_fill == 1)
+			{
+			pl.box.setColorFill(fill_color);
+			}
+		}
+
+	
+	pl.text = pl.graph.createChild("text")
+      		.setText(text)
+		.setColor(text_color)
+		.setFontSize(15)
+		#.setFont("LiberationFonts/LiberationMono-Bold.ttf")
+		.setFont("LiberationFonts/LiberationSans-Bold.ttf")
+		.setAlignment("center-bottom")
+		.setRotation(0.0);
+
+	pl.text.enableUpdate();
+
+	pl.text.setTranslation(0.0, pl.getOffset(text));
+	if (pl.box_mode == 1)
+		{
+		pl.box.setTranslation(0.0, -pl.getOffset(text));
+		}
+	
+	return pl;
+	},
+
+	setTranslation: func (x,y) {
+		me.graph.setTranslation(x,y);
+
+	},
+
+	updateText: func (text) {
+
+		me.text.updateText(text);
+	},
+
+	setText: func (text) {
+
+		me.text.setText(text);
+	},
+
+	setFont: func (font) {
+
+		me.text.setFont(font);
+	},
+
+	setFontSize: func (size) {
+
+		me.font_scale_factor = size/15.0;
+		me.text.setFontSize(size);
+	},
+
+	setScale: func (x,y = nil) {
+
+		me.graph.setScale(x,y);
+	},
+
+	setBoxScale: func (x,y = nil) {
+
+		if (me.box_mode == 0) {return;}
+		me.box.setScale(x,y);
+	},
+
+	setLimits: func (lower, upper = 1e6) {
+	
+		me.limits = 1;
+		me.limit_lower = lower;
+		me.limit_upper = upper; 
+
+	},	 
+
+	getOffset: func (string) {
+		return 0.0;
+		var flag = 0;
+		for (var i = 0; i < utf8.size(string); i=i+1)
+			{
+			var char = utf8.strc(string, i);
+
+			if ((char == "y") or (char == "g") or (char == "j") or (char == "p") or (char == "q"))
+				{
+				flag == 1; break;
+				}
+			}
+		if (flag == 0) {return -2.0;}
+		else {return 0.0;}
+	},
+
+};
+
+
+
+# analog gauge ##############################################################
+
+var cdlg_widget_analog_gauge = {
+	new: func (root, gauge_bg, gauge_needle ) {
+ 	var ag = { parents: [cdlg_widget_analog_gauge] };
+
+	ag.graph = root.createChild("group", "analog gauge");
+
+	ag.gauge_background = ag.graph.createChild("image")
+			.setFile(gauge_bg);
+
+	ag.gauge_needle = ag.graph.createChild("image")
+			.setFile(gauge_needle);
+
+	ag.gauge_needle.setCenter(127,127);
+
+	return ag;
+	},
+
+	setTranslation: func (x,y) {
+
+		me.graph.setTranslation(x,y);
+
+	},
+
+
+	setAngle: func (angle) {
+
+		me.gauge_needle.setRotation(angle);
+
+	},
+
+};
+
+
+# clickspots ##############################################################
+
+var cdlg_clickspot = {
+
+	new: func (x,y,rw,rh,tab,type) {
+	 	var cs = { parents: [cdlg_clickspot] };
+		
+		cs.x = x;
+		cs.y = y;
+		cs.rw = rw;
+		cs.rh = rh;
+		cs.fraction_up = 0.0;
+		cs.fraction_right = 0.0;
+		cs.tab = tab;
+		cs.type = type;
+
+		return cs;
+	},
+
+	check_event : func (click_x, click_y) {
+
+		if (me.type = "rect") 
+			{
+			if ((math.abs(click_x - me.x) < me.rw) and (math.abs(click_y - me.y) < me.rh)) 					{
+				me.update_fractions (click_x, click_y);
+				return 1;
+				}
+			}
+		else if (me.type = "circle") 
+			{
+			var click_r = math.sqrt((click_x - me.x) * (click_x - me.x) + (click_y - me.y) * (click_y - me.y));
+
+			if (click_r < me.rw)
+				{
+				me.update_fractions (click_x, click_y);
+				return 1;
+				}
+			}
+		return 0;
+	},
+
+	update_fractions: func (click_x, click_y) {
+
+		var y_rel = (click_y - me.y);
+		var x_rel = (click_x - me.x);
+		me.fraction_up = (-y_rel + me.rw)/(2.0 * me.rw);
+		me.fraction_right = (x_rel + me.rw)/(2.0 * me.rw);
+
+	},
+
+	get_fraction_up: func {
+
+		return me.fraction_up;
+
+	},
+
+	get_fraction_right: func {
+
+		return me.fraction_right;
+
+	},
+
+};