diff --git a/Aircraft/ufo/Dialogs/callsign.xml b/Aircraft/ufo/Dialogs/callsign.xml
new file mode 100644
index 000000000..3d3a37b5c
--- /dev/null
+++ b/Aircraft/ufo/Dialogs/callsign.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+
+<PropertyList>
+	<name>callsign</name>
+	<layout>vbox</layout>
+	<x>30</x>
+	<y>60</y>
+	<pref-width>160</pref-width>
+
+	<nasal>
+		<open>
+			var loopid = 0;
+			var list = cmdarg().getNode("list");
+
+			var search = func(list, item) {
+				var left = 0;
+				var right = size(list);
+				while (left &lt; right) {
+					var middle = int((left + right) / 2);
+					var c = cmp(list[middle].getNode("callsign").getValue(), item);
+					if (!c)
+						return middle;
+					if (c > 0)
+						right = middle;
+					else
+						left = middle + 1;
+				}
+				return -1;
+			}
+
+			var select = func(which) {
+				var index = search(cam.aircraft_list, which);
+				if (index >= 0)
+					cam.select_aircraft(index);
+			}
+
+			var loop = func(id) {
+				id == loopid or return;
+				cam.update_aircraft_list();
+				list.removeChildren("value");
+
+				forindex (var i; cam.aircraft_list) {
+					var name = cam.aircraft_list[i].getNode("callsign").getValue();
+					list.getChild("value", i, 1).setValue(name);
+				}
+				gui.dialog_update("callsign", "list");
+				settimer(func { loop(id) }, 5);
+			}
+
+			loop(loopid);
+		</open>
+
+		<close>
+			loopid += 1;
+		</close>
+	</nasal>
+
+	<group>
+		<layout>hbox</layout>
+		<empty><stretch>1</stretch></empty>
+
+		<text>
+			<label>Select Aircraft</label>
+		</text>
+
+		<empty><stretch>1</stretch></empty>
+
+		<button>
+			<pref-width>16</pref-width>
+			<pref-height>16</pref-height>
+			<legend></legend>
+			<default>1</default>
+			<keynum>27</keynum>
+			<border>2</border>
+
+			<binding>
+				<command>nasal</command>
+				<script>cam.callsign_dialog.close()</script>
+			</binding>
+		</button>
+	</group>
+
+	<hrule/>
+
+	<list>
+		<name>list</name>
+		<halign>fill</halign>
+		<pref-height>300</pref-height>
+		<property>/sim/gui/dialogs/cam/select</property>
+		<binding>
+			<command>dialog-apply</command>
+		</binding>
+		<binding>
+			<command>nasal</command>
+			<script>select(getprop("/sim/gui/dialogs/cam/select"))</script>
+		</binding>
+	</list>
+</PropertyList>
diff --git a/Aircraft/ufo/Dialogs/campanel.xml b/Aircraft/ufo/Dialogs/cam.xml
similarity index 82%
rename from Aircraft/ufo/Dialogs/campanel.xml
rename to Aircraft/ufo/Dialogs/cam.xml
index 1ee833f5f..f77640c53 100644
--- a/Aircraft/ufo/Dialogs/campanel.xml
+++ b/Aircraft/ufo/Dialogs/cam.xml
@@ -1,13 +1,14 @@
 <?xml version="1.0"?>
 
 <PropertyList>
-	<name>cam-keys</name>
+	<name>cam</name>
 	<layout>vbox</layout>
 	<x>0</x>
 	<y>24</y>
 	<pref-width>1024</pref-width>
 	<pref-height>24</pref-height>
 	<modal>false</modal>
+
 	<color>
 		<red>0.5</red>
 		<green>0.5</green>
@@ -36,6 +37,21 @@
 			</binding>
 		</checkbox>
 
+		<button>
+			<color>
+				<red>0.5</red>
+				<green>0.5</green>
+				<blue>0.5</blue>
+			</color>
+			<pref-width>20</pref-width>
+			<pref-height>20</pref-height>
+			<legend>^</legend>
+			<binding>
+				<command>nasal</command>
+				<script>cam.callsign_dialog.toggle()</script>
+			</binding>
+		</button>
+
 		<text>
 			<label>000000</label>
 			<format>No# %d</format>
@@ -60,9 +76,11 @@
 			<pref-height>20</pref-height>
 			<legend>&lt;&lt;</legend>
 			<binding>
-				<command>property-adjust</command>
-				<property>/sim/cam/target-number</property>
-				<step>-1</step>
+				<command>nasal</command>
+				<script>
+					cam.update_aircraft_list();
+					cam.select_aircraft(getprop("/sim/cam/target-number") - 1);
+				</script>
 			</binding>
 		</button>
 
@@ -77,9 +95,11 @@
 			<pref-height>20</pref-height>
 			<legend>&gt;&gt;</legend>
 			<binding>
-				<command>property-adjust</command>
-				<property>/sim/cam/target-number</property>
-				<step>1</step>
+				<command>nasal</command>
+				<script>
+					cam.update_aircraft_list();
+					cam.select_aircraft(getprop("/sim/cam/target-number") + 1);
+				</script>
 			</binding>
 		</button>
 
diff --git a/Aircraft/ufo/cam.nas b/Aircraft/ufo/cam.nas
index 876733a4a..fea89b296 100644
--- a/Aircraft/ufo/cam.nas
+++ b/Aircraft/ufo/cam.nas
@@ -9,18 +9,23 @@ var sin = func(v) math.sin(v * D2R);
 var cos = func(v) math.cos(v * D2R);
 var atan2 = func(v, w) math.atan2(v, w) * R2D;
 
-var ViewNum = 0;
-var Grd_Offset = 5.0;
-var panel = gui.Dialog.new("/sim/gui/dialogs/cam/dialog", "Aircraft/ufo/Dialogs/campanel.xml");
+var panel_dialog = gui.Dialog.new("/sim/gui/dialogs/cam/panel/dialog",
+        "Aircraft/ufo/Dialogs/cam.xml");
+var callsign_dialog = gui.Dialog.new("/sim/gui/dialogs/cam/select/dialog",
+        "Aircraft/ufo/Dialogs/callsign.xml");
+
 var maxspeedN = props.globals.getNode("engines/engine/speed-max-mps");
 var speed = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000];
 var current = 7;
 var maxspeed = speed[current];
 var cam_view = nil;
+var view_number = 0;
+var ground_offset = 5.0;
 
 var targetN = nil;
 var target = geo.Coord.new();
 var self = nil;
+var aircraft_list = [];
 
 
 controls.flapsDown = func(x) {
@@ -35,61 +40,31 @@ controls.flapsDown = func(x) {
 }
 
 
-var throttle = 0;
-controls.throttleAxis = func {
-	val = cmdarg().getNode("setting").getValue();
-	if (size(arg) > 0)
-		val = -val;
-	throttle = (1 - val) * 0.5;
+#var throttle = 0;
+#controls.throttleAxis = func {
+#	val = cmdarg().getNode("setting").getValue();
+#	if (size(arg) > 0)
+#		val = -val;
+#	throttle = (1 - val) * 0.5;
+#	props.setAll("/controls/engines/engine", "throttle", throttleL.filter(throttle));
+#}
+
+
+var by_callsign = func(a, b) {
+	cmp(a.getNode("callsign").getValue(), b.getNode("callsign").getValue());
 }
 
 
-# directly called from the dialog
-var goto_target = func {
-	targetN != nil or return;
-	var lat = targetN.getNode("position/latitude-deg").getValue();
-	var lon = targetN.getNode("position/longitude-deg").getValue();
-	var alt = targetN.getNode("position/altitude-ft").getValue() * geo.FT2M;
-	var speed = targetN.getNode("velocities/true-airspeed-kt").getValue() * MPS * 2;
-	var course = targetN.getNode("orientation/true-heading-deg").getValue();
-	self.set_latlon(lat, lon, alt).apply_course_distance(course + 180, 100);
-	setprop("/position/latitude-deg", self.lat());
-	setprop("/position/longitude-deg", self.lon());
-	altL.set(self.alt());
-	speedL.set(speed);
-	mode.chase.setValue(1);
-	mode.focus.setValue(1);
-	mode.alt.setValue(1);
-	mode.speed.setValue(1);
-	maxspeed = speed * 2;
-	throttleL.set(0.5);
-}
+var update_aircraft_list = func {
+	var ac = [];
+	var n = props.globals.getNode("/ai/models");
 
-
-var set_aircraft = func {
-	var list = [];
 	if (getprop("/sim/cam/target-ai"))
-		list ~= props.globals.getNode("/ai/models").getChildren("aircraft");
+		ac ~= n.getChildren("aircraft");
 	if (getprop("/sim/cam/target-mp"))
-		list ~= props.globals.getNode("/ai/models").getChildren("multiplayer");
+		ac ~= n.getChildren("multiplayer");
 
-	var name = "";
-	var index = getprop("/sim/cam/target-number");
-	targetN = nil;
-
-	if (size(list)) {
-		if (index < 0)
-			index = size(list) - 1;
-		elsif (index >= size(list))
-			index = 0;
-
-		targetN = list[index];
-		name = targetN.getNode("callsign").getValue();
-		printlog("info", "cam: new aircraft: ", targetN.getPath(), "\t", name);
-	}
-
-	setprop("/sim/cam/target-number", index);
-	setprop("/sim/cam/target-name", name);
+	aircraft_list = sort(ac, by_callsign);
 }
 
 
@@ -175,30 +150,77 @@ if (0) {
 	maxspeedN.setDoubleValue(speedL.filter(maxspeed));
 
 	var AGL = getprop("/position/altitude-agl-ft");
-	if (AGL < Grd_Offset)
-		setprop("/position/altitude-ft", getprop("/position/altitude-ft") + Grd_Offset - AGL);
-
-	props.setAll("/controls/engines/engine", "throttle", throttleL.filter(throttle));
+	if (AGL < ground_offset)
+		setprop("/position/altitude-ft", getprop("/position/altitude-ft") + ground_offset - AGL);
 }
 
 
 var loop = func {
-	if (ViewNum == cam_view and targetN != nil)
+	if (view_number == cam_view and targetN != nil)
 		update();
 
 	settimer(loop, 0);
 }
 
 
-setlistener("/sim/cam/target-number", set_aircraft);
-setlistener("/sim/cam/target-ai", set_aircraft);
-setlistener("/sim/cam/target-mp", set_aircraft);
+var select_aircraft = func(index) {
+	update_aircraft_list();
+
+	var number = size(aircraft_list);
+	var name = "";
+	targetN = nil;
+
+	if (number) {
+		if (index < 0)
+			index = number - 1;
+		elsif (index >= number)
+			index = 0;
+
+		targetN = aircraft_list[index];
+		name = targetN.getNode("callsign").getValue();
+	}
+	setprop("/sim/cam/target-number", index);
+	setprop("/sim/cam/target-name", name);
+}
+
+
+# called from the dialog
+var goto_target = func {
+	targetN != nil or return;
+	var lat = targetN.getNode("position/latitude-deg").getValue();
+	var lon = targetN.getNode("position/longitude-deg").getValue();
+	var alt = targetN.getNode("position/altitude-ft").getValue() * geo.FT2M;
+	var speed = targetN.getNode("velocities/true-airspeed-kt").getValue() * MPS * 2;
+	var course = targetN.getNode("orientation/true-heading-deg").getValue();
+	self.set_latlon(lat, lon, alt).apply_course_distance(course + 180, 100);
+	setprop("/position/latitude-deg", self.lat());
+	setprop("/position/longitude-deg", self.lon());
+	altL.set(self.alt());
+	speedL.set(speed);
+	mode.chase.setValue(1);
+	mode.focus.setValue(1);
+	mode.alt.setValue(1);
+	mode.speed.setValue(1);
+	maxspeed = speed * 2;
+#	props.setAll("/controls/engines/engine", "throttle", throttleL.set(0.5));
+}
+
+
+var update_aircraft = func {
+	select_aircraft(getprop("/sim/cam/target-number"));
+}
+
+
+setlistener("/sim/cam/target-number", update_aircraft);
+setlistener("/sim/cam/target-ai", update_aircraft);
+setlistener("/sim/cam/target-mp", update_aircraft);
+
 setlistener("/sim/current-view/view-number", func {
-	ViewNum = cmdarg().getValue();
-	if (ViewNum == 7)
-		panel.open();
+	view_number = cmdarg().getValue();
+	if (view_number == cam_view)
+		panel_dialog.open();
 	else
-		panel.dialog.close();
+		panel_dialog.close();
 });
 
 
@@ -222,7 +244,7 @@ setlistener("/sim/signals/fdm-initialized", func {
 
 	setprop("/sim/current-view/view-number", cam_view);
 	setprop("/engines/engine/speed-max-mps", 500);
-	settimer(set_aircraft, 1);
+	update_aircraft();
 	loop();
 });
 
diff --git a/Aircraft/ufo/mibs-set.xml b/Aircraft/ufo/mibs-set.xml
index b68b935d0..2900f70da 100644
--- a/Aircraft/ufo/mibs-set.xml
+++ b/Aircraft/ufo/mibs-set.xml
@@ -84,7 +84,7 @@
                 <desc>Show dialog</desc>
                 <binding>
                     <command>nasal</command>
-                    <script>cam.panel_dialog.toggle()</script>
+                    <script>cam.panel.toggle()</script>
                 </binding>
             </key>
         </keyboard>