mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-04 22:17:01 +08:00
active aircraft highlighted. Buttons of others hidden
This commit is contained in:
@@ -508,7 +508,6 @@ let _main =
|
||||
|
||||
(** Aircraft notebook *)
|
||||
let ac_notebook = GPack.notebook ~tab_border:0 () in
|
||||
ac_notebook#connect#switch_page ~callback:(fun i -> Printf.printf "tab=%d -> %d\n%!" ac_notebook#current_page i);
|
||||
|
||||
(** Alerts text frame *)
|
||||
let alert_page = GBin.frame () in
|
||||
@@ -573,25 +572,8 @@ let _main =
|
||||
ignore (frame#event#connect#button_press ~callback)
|
||||
end;
|
||||
|
||||
|
||||
(** Periodically probe new A/Cs *)
|
||||
ignore (Glib.Timeout.add 2000 (fun () -> Live.message_request "map2d" "AIRCRAFTS" [] (fun _sender vs -> Live.aircrafts_msg my_alert geomap ac_notebook vs); false));
|
||||
|
||||
(** New aircraft message *)
|
||||
Live.safe_bind "NEW_AIRCRAFT" (fun _sender vs -> Live.one_new_ac my_alert geomap ac_notebook (Pprz.string_assoc "ac_id" vs));
|
||||
|
||||
(** Listen for all messages on ivy *)
|
||||
Live.listen_flight_params geomap !auto_center_new_ac my_alert;
|
||||
Live.listen_wind_msg geomap;
|
||||
Live.listen_fbw_msg ();
|
||||
Live.listen_engine_status_msg ();
|
||||
Live.listen_if_calib_msg ();
|
||||
Live.listen_waypoint_moved ();
|
||||
Live.listen_infrared ();
|
||||
Live.listen_svsinfo ();
|
||||
Live.listen_telemetry_status ();
|
||||
Live.listen_alert my_alert;
|
||||
Live.listen_error my_alert;
|
||||
(** Wait for A/Cs and subsequent messages *)
|
||||
Live.listen_acs_and_msgs geomap ac_notebook my_alert !auto_center_new_ac;
|
||||
|
||||
(** Display the window *)
|
||||
let accel_group = menu_fact#accel_group in
|
||||
|
||||
@@ -69,6 +69,8 @@ type aircraft = {
|
||||
misc_page : Pages.misc;
|
||||
dl_settings_page : Pages.settings option;
|
||||
rc_settings_page : Pages.rc_settings option;
|
||||
pages : GObj.widget;
|
||||
notebook_label : GMisc.label;
|
||||
strip : Strip.t;
|
||||
mutable first_pos : bool;
|
||||
mutable last_block_name : string;
|
||||
@@ -83,10 +85,26 @@ type aircraft = {
|
||||
}
|
||||
|
||||
let live_aircrafts = Hashtbl.create 3
|
||||
let active_ac = ref ""
|
||||
let get_ac = fun vs ->
|
||||
let ac_id = Pprz.string_assoc "ac_id" vs in
|
||||
Hashtbl.find live_aircrafts ac_id
|
||||
|
||||
let select_ac = fun ?(switch_notebook = true) acs_notebook ac_id ->
|
||||
if !active_ac <> ac_id then
|
||||
let ac = Hashtbl.find live_aircrafts ac_id in
|
||||
ac.notebook_label#set_width_chars 20;
|
||||
ac.strip#show_buttons ();
|
||||
if !active_ac <> "" then begin
|
||||
let ac' = Hashtbl.find live_aircrafts !active_ac in
|
||||
ac'.strip#hide_buttons ();
|
||||
ac'.notebook_label#set_width_chars (String.length ac'.notebook_label#text)
|
||||
end;
|
||||
active_ac := ac_id;
|
||||
if switch_notebook then
|
||||
let n = acs_notebook#page_num ac.pages in
|
||||
acs_notebook#goto_page n
|
||||
|
||||
|
||||
module M = Map.Make (struct type t = string let compare = compare end)
|
||||
let log =
|
||||
@@ -298,7 +316,6 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id
|
||||
let eb = GBin.event_box () in
|
||||
let _label = GMisc.label ~text:name ~packing:eb#add () in
|
||||
eb#coerce#misc#modify_bg [`NORMAL, `NAME color;`ACTIVE, `NAME color];
|
||||
_label#set_width_chars 20;
|
||||
|
||||
(** Put a notebook for this A/C *)
|
||||
let ac_frame = GBin.frame ~packing:(acs_notebook#append_page ~tab_label:eb#coerce) () in
|
||||
@@ -306,16 +323,9 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id
|
||||
let visible = fun w ->
|
||||
ac_notebook#page_num w#coerce = ac_notebook#current_page in
|
||||
|
||||
(** Add a strip and connect it to the A/C notebook *)
|
||||
let select_this_tab =
|
||||
let n = acs_notebook#page_num ac_frame#coerce in
|
||||
fun () -> acs_notebook#goto_page n in
|
||||
(** Add a strip *)
|
||||
let strip = Strip.add config color center_ac (mark geomap ac_id track !Plugin.frame) in
|
||||
let deselect_others = fun () ->
|
||||
Hashtbl.iter (fun ac_id' ac -> if ac_id' <> ac_id then ac.strip#hide_buttons ()) live_aircrafts in
|
||||
strip#connect (fun () -> select_this_tab (); deselect_others ());
|
||||
deselect_others ();
|
||||
|
||||
strip#connect (fun () -> select_ac acs_notebook ac_id);
|
||||
|
||||
(** Build the XML flight plan, connect then "jump_to_block" *)
|
||||
let fp_xml = ExtXml.child fp_xml_dump "flight_plan" in
|
||||
@@ -426,8 +436,12 @@ let create_ac = fun alert (geomap:G.widget) (acs_notebook:GPack.notebook) (ac_id
|
||||
last_block_name = ""; alt = 0.; target_alt = 0.;
|
||||
in_kill_mode = false; speed = 0.;
|
||||
wind_dir = 42.; ground_prox = true;
|
||||
wind_speed = 0.; } in
|
||||
wind_speed = 0.;
|
||||
pages = ac_frame#coerce;
|
||||
notebook_label = _label
|
||||
} in
|
||||
Hashtbl.add live_aircrafts ac_id ac;
|
||||
select_ac acs_notebook ac_id;
|
||||
|
||||
(** Periodically send the wind estimation through
|
||||
a WIND_INFO message packed into a RAW_DATALINK *)
|
||||
@@ -816,3 +830,34 @@ let listen_error = fun a ->
|
||||
let msg = Pprz.string_assoc "message" vs in
|
||||
log_and_say a "gcs" msg in
|
||||
safe_bind "TELEMETRY_ERROR" get_error
|
||||
|
||||
|
||||
let listen_acs_and_msgs = fun geomap ac_notebook my_alert auto_center_new_ac ->
|
||||
(** Periodically probe new A/Cs *)
|
||||
ignore (Glib.Timeout.add 2000 (fun () -> message_request "map2d" "AIRCRAFTS" [] (fun _sender vs -> aircrafts_msg my_alert geomap ac_notebook vs); false));
|
||||
|
||||
(** New aircraft message *)
|
||||
safe_bind "NEW_AIRCRAFT" (fun _sender vs -> one_new_ac my_alert geomap ac_notebook (Pprz.string_assoc "ac_id" vs));
|
||||
|
||||
(** Listen for all messages on ivy *)
|
||||
listen_flight_params geomap auto_center_new_ac my_alert;
|
||||
listen_wind_msg geomap;
|
||||
listen_fbw_msg ();
|
||||
listen_engine_status_msg ();
|
||||
listen_if_calib_msg ();
|
||||
listen_waypoint_moved ();
|
||||
listen_infrared ();
|
||||
listen_svsinfo ();
|
||||
listen_telemetry_status ();
|
||||
listen_alert my_alert;
|
||||
listen_error my_alert;
|
||||
|
||||
(** Select the active aircraft on notebook page selection *)
|
||||
let callback = fun i ->
|
||||
let ac_page = ac_notebook#get_nth_page i in
|
||||
Hashtbl.iter
|
||||
(fun ac_id ac ->
|
||||
if ac.pages#get_oid = ac_page#get_oid
|
||||
then select_ac ~switch_notebook:false ac_notebook ac_id)
|
||||
live_aircrafts in
|
||||
ignore (ac_notebook#connect#switch_page ~callback)
|
||||
|
||||
@@ -1,17 +1 @@
|
||||
val message_request : string -> string -> Pprz.values -> (string -> Pprz.values -> unit) -> unit
|
||||
|
||||
val aircrafts_msg : Pages.alert -> MapCanvas.widget -> GPack.notebook -> Pprz.values -> unit
|
||||
val safe_bind : string -> (string -> Pprz.values -> unit) -> unit
|
||||
val one_new_ac : Pages.alert -> MapCanvas.widget -> GPack.notebook -> string -> unit
|
||||
val listen_flight_params :
|
||||
< center : MapCanvas.LL.geographic -> unit; .. > -> bool -> Pages.alert -> unit
|
||||
val listen_wind_msg : MapCanvas.widget -> unit
|
||||
val listen_fbw_msg : unit -> unit
|
||||
val listen_engine_status_msg : unit -> unit
|
||||
val listen_if_calib_msg : unit -> unit
|
||||
val listen_waypoint_moved : unit -> unit
|
||||
val listen_infrared : unit -> unit
|
||||
val listen_svsinfo : unit -> unit
|
||||
val listen_alert : Pages.alert -> unit
|
||||
val listen_error : Pages.alert -> unit
|
||||
val listen_telemetry_status : unit -> unit
|
||||
val listen_acs_and_msgs : MapCanvas.widget -> GPack.notebook -> Pages.alert -> bool -> unit
|
||||
|
||||
@@ -31,7 +31,9 @@ type t =
|
||||
set_bat : float -> unit;
|
||||
set_color : string -> string -> unit;
|
||||
set_label : string -> string -> unit;
|
||||
connect : (unit -> unit) -> unit; hide_buttons : unit -> unit >
|
||||
connect : (unit -> unit) -> unit;
|
||||
hide_buttons : unit -> unit;
|
||||
show_buttons : unit -> unit >
|
||||
|
||||
let bat_max = 12.5
|
||||
let bat_min = 9.
|
||||
@@ -66,44 +68,45 @@ class gauge = fun ?(color="green") ?(history_len=50) gauge v_min v_max ->
|
||||
val mutable history_index = -1
|
||||
method set = fun value string ->
|
||||
let {Gtk.width=width; height=height} = gauge#misc#allocation in
|
||||
let dr = GDraw.pixmap ~width ~height ~window:gauge () in
|
||||
dr#set_foreground (`NAME "orange");
|
||||
dr#rectangle ~x:0 ~y:0 ~width ~height ~filled:true ();
|
||||
|
||||
let f = (value -. v_min) /. (v_max -. v_min) in
|
||||
let f = max 0. (min 1. f) in
|
||||
let h = truncate (float height *. f) in
|
||||
|
||||
(* First call: fill the array with the given value *)
|
||||
if history_index < 0 then begin
|
||||
if height > 1 then (* Else the drawing area is not allocated already *)
|
||||
let dr = GDraw.pixmap ~width ~height ~window:gauge () in
|
||||
dr#set_foreground (`NAME "orange");
|
||||
dr#rectangle ~x:0 ~y:0 ~width ~height ~filled:true ();
|
||||
|
||||
let f = (value -. v_min) /. (v_max -. v_min) in
|
||||
let f = max 0. (min 1. f) in
|
||||
let h = truncate (float height *. f) in
|
||||
|
||||
(* First call: fill the array with the given value *)
|
||||
if history_index < 0 then begin
|
||||
for i = 0 to history_len - 1 do
|
||||
history.(i) <- h
|
||||
done;
|
||||
history_index <- 0;
|
||||
end;
|
||||
|
||||
(* Store the value in the history array and update index *)
|
||||
history.(history_index) <- h;
|
||||
history_index <- (history_index+1) mod history_len;
|
||||
|
||||
dr#set_foreground (`NAME color);
|
||||
|
||||
(* From left to right, older to new values *)
|
||||
let polygon = ref [0,height; width,height] in
|
||||
for i = 0 to history_len - 1 do
|
||||
history.(i) <- h
|
||||
let idx = (history_index+i) mod history_len in
|
||||
polygon := ((i*width)/history_len, (height-history.(idx))):: !polygon;
|
||||
done;
|
||||
history_index <- 0;
|
||||
end;
|
||||
|
||||
(* Store the value in the history array and update index *)
|
||||
history.(history_index) <- h;
|
||||
history_index <- (history_index+1) mod history_len;
|
||||
|
||||
dr#set_foreground (`NAME color);
|
||||
|
||||
(* From left to right, older to new values *)
|
||||
let polygon = ref [0,height; width,height] in
|
||||
for i = 0 to history_len - 1 do
|
||||
let idx = (history_index+i) mod history_len in
|
||||
polygon := ((i*width)/history_len, (height-history.(idx))):: !polygon;
|
||||
done;
|
||||
polygon := (width,height-h):: !polygon;
|
||||
dr#polygon ~filled:true !polygon;
|
||||
|
||||
let context = gauge#misc#create_pango_context in
|
||||
let layout = context#create_layout in
|
||||
Pango.Layout.set_text layout string;
|
||||
let (w,h) = Pango.Layout.get_pixel_size layout in
|
||||
dr#put_layout ~x:((width-w)/2) ~y:((height-h)/2) ~fore:`BLACK layout;
|
||||
|
||||
(new GDraw.drawable gauge#misc#window)#put_pixmap ~x:0 ~y:0 dr#pixmap
|
||||
polygon := (width,height-h):: !polygon;
|
||||
dr#polygon ~filled:true !polygon;
|
||||
|
||||
let context = gauge#misc#create_pango_context in
|
||||
let layout = context#create_layout in
|
||||
Pango.Layout.set_text layout string;
|
||||
let (w,h) = Pango.Layout.get_pixel_size layout in
|
||||
dr#put_layout ~x:((width-w)/2) ~y:((height-h)/2) ~fore:`BLACK layout;
|
||||
|
||||
(new GDraw.drawable gauge#misc#window)#put_pixmap ~x:0 ~y:0 dr#pixmap
|
||||
end
|
||||
|
||||
|
||||
@@ -160,8 +163,10 @@ let add config color center_ac mark =
|
||||
|
||||
(** Table (everything except the user buttons) *)
|
||||
let strip = GPack.table ~rows ~columns ~col_spacings:3 ~packing:framevb#add () in
|
||||
strip#set_row_spacing 0 3;
|
||||
strip#set_row_spacing (rows-2) 3;
|
||||
strip#set_row_spacing 0 2;
|
||||
strip#set_row_spacing 1 2;
|
||||
strip#set_row_spacing (rows-1) 2;
|
||||
strip#set_row_spacing (rows-2) 2;
|
||||
|
||||
(* Name in top left *)
|
||||
let name = (GMisc.label ~text: (ac_name) ~packing: (strip#attach ~top: 0 ~left: 0) ()) in
|
||||
@@ -187,13 +192,13 @@ let add config color center_ac mark =
|
||||
tooltips#set_tip plane_color#coerce ~text:"Flight time - Block time - Stage time - Block name";
|
||||
|
||||
(* battery gauge *)
|
||||
let bat_da = GMisc.drawing_area ~height:60 ~show:true ~packing:(strip#attach ~top:1 ~bottom:(rows-1) ~left:0) () in
|
||||
let bat_da = GMisc.drawing_area ~show:true ~packing:(strip#attach ~top:1 ~bottom:(rows-1) ~left:0) () in
|
||||
bat_da#misc#realize ();
|
||||
let bat = new gauge bat_da bat_min bat_max in
|
||||
|
||||
(* AGL gauge *)
|
||||
let agl_box = GBin.event_box ~packing:(strip#attach ~top:1 ~bottom:3 ~left:(columns-1)) () in
|
||||
let agl_da = GMisc.drawing_area ~width:40 ~height:60 ~show:true ~packing:agl_box#add () in
|
||||
let agl_da = GMisc.drawing_area ~width:30 ~show:true ~packing:agl_box#add () in
|
||||
agl_da#misc#realize ();
|
||||
tooltips#set_tip agl_box#coerce ~text:"AGL (m)";
|
||||
let agl = new gauge agl_da 0. agl_max in
|
||||
@@ -225,7 +230,7 @@ let add config color center_ac mark =
|
||||
) labels_name;
|
||||
|
||||
(* Buttons *)
|
||||
let hbox = GPack.hbox ~packing:framevb#add () in
|
||||
let hbox = GPack.hbox ~spacing:2 ~packing:framevb#add () in
|
||||
let b = GButton.button ~label:"Center A/C" ~packing:hbox#add () in
|
||||
ignore(b#connect#clicked ~callback:center_ac);
|
||||
let b = GButton.button ~label:"Mark" ~packing:hbox#add () in
|
||||
@@ -237,9 +242,9 @@ let add config color center_ac mark =
|
||||
ignore (b#connect#clicked ~callback:mark);
|
||||
|
||||
(* User buttons *)
|
||||
let user_hbox = GPack.hbox ~packing:framevb#add () in
|
||||
let user_hbox = GPack.hbox ~spacing:2 ~packing:framevb#add () in
|
||||
|
||||
(object
|
||||
object
|
||||
method set_agl value = set_agl agl value
|
||||
method set_bat value = set_bat bat value
|
||||
method set_label name value = set_label !strip_labels name value
|
||||
@@ -250,10 +255,8 @@ let add config color center_ac mark =
|
||||
ignore (plus30#connect#clicked (fun () -> callback 30.));
|
||||
ignore (minus5#connect#clicked (fun () -> callback (-5.)))
|
||||
method hide_buttons () = hbox#misc#hide (); user_hbox#misc#hide ()
|
||||
method show_buttons () = hbox#misc#show (); user_hbox#misc#show ()
|
||||
method connect = fun (select: unit -> unit) ->
|
||||
let callback = fun _ ->
|
||||
select ();
|
||||
hbox#misc#show (); user_hbox#misc#show ();
|
||||
true in
|
||||
let callback = fun _ -> select (); true in
|
||||
ignore (strip_ebox#event#connect#button_press ~callback)
|
||||
end:t)
|
||||
end
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
type t =
|
||||
< add_widget : GObj.widget -> unit;
|
||||
connect_shift_alt : (float -> unit) -> unit;
|
||||
set_agl : float -> unit;
|
||||
set_bat : float -> unit;
|
||||
set_color : string -> string -> unit;
|
||||
set_label : string -> string -> unit;
|
||||
hide_buttons : unit -> unit;
|
||||
connect : (unit -> unit) -> unit>
|
||||
type t = <
|
||||
add_widget : GObj.widget -> unit;
|
||||
connect_shift_alt : (float -> unit) -> unit;
|
||||
set_agl : float -> unit;
|
||||
set_bat : float -> unit;
|
||||
set_color : string -> string -> unit;
|
||||
set_label : string -> string -> unit;
|
||||
hide_buttons : unit -> unit;
|
||||
show_buttons : unit -> unit;
|
||||
connect : (unit -> unit) -> unit
|
||||
>
|
||||
|
||||
|
||||
val scrolled : GBin.scrolled_window
|
||||
|
||||
Reference in New Issue
Block a user