9 #INCLUDE ONCE "cairo/cairo.bi"
10 #INCLUDE ONCE "Gir/OsmGpsMap-1.0.bi"
11 #INCLUDE ONCE "Gir/_GLibMacros-2.0.bi"
12 #INCLUDE ONCE "Gir/_GObjectMacros-2.0.bi"
17 #INCLUDE ONCE "string.bi"
26 TYPE(@!
"\&b00100111" "rgba(0xA4,0x00,0x00,1)", @!
"\1" "#EF2929") _
27 ,
TYPE(@!
"\&b01000111" "rgba(0xCE,0x5C,0x00,1)", @!
"\1" "#FCAF3E") _
28 ,
TYPE(@!
"\&b10010111" "rgba(0xC4,0xA0,0x00,1)", @!
"\1" "#FCE94F") _
29 ,
TYPE(@!
"\&h34" "rgba(0x4E,0x9A,0x06,1)", @!
"\4" "#8AE234") _
30 ,
TYPE(@!
"\&h35" "rgba(0x20,0x4A,0x87,1)", @!
"\5" "#729FCF") _
31 ,
TYPE(@!
"\&h35" "rgba(0x5C,0x35,0x66,1)", @!
"\4" "#AD7FA8") _
32 ,
TYPE(@!
"\&h35" "rgba(0x8F,0x59,0x02,1)", @!
"\5" "#E9B96E") _
33 ,
TYPE(@!
"\&h34" "rgba(0x2E,0x34,0x36,1)", @!
"\4" "#888A85") _
34 ,
TYPE(@!
"\&h34" "rgba(0xBA,0xBD,0xB6,1)", @!
"\4" "#EEEEEC") _
67 AS cairo_surface_t
PTR _
92 G_DEFINE_TYPE_WITH_CODE(TrackLayer, track_layer, G_TYPE_OBJECT _
96 DECLARE SUB render_info CDECL(
BYVAL Lay
AS TrackLayer
PTR,
BYVAL Map AS OsmGpsMap
PTR)
97 DECLARE SUB track_layer_render CDECL(
BYVAL AS OsmGpsMapLayer
PTR,
BYVAL AS OsmGpsMap
PTR)
98 DECLARE SUB track_layer_draw CDECL(
BYVAL AS OsmGpsMapLayer
PTR,
BYVAL AS OsmGpsMap
PTR,
BYVAL AS cairo_t
PTR)
99 DECLARE FUNCTION track_layer_busy CDECL(
BYVAL AS OsmGpsMapLayer
PTR)
AS gboolean
100 DECLARE FUNCTION track_layer_button_press CDECL(
BYVAL AS OsmGpsMapLayer
PTR,
BYVAL AS OsmGpsMap
PTR,
BYVAL AS GdkEventButton
PTR)
AS gboolean
131 BYVAL Obj
AS Gobject
PTR _
132 ,
BYVAL Property_id
AS guint _
133 ,
BYVAL Value
AS GValue
PTR _
134 ,
BYVAL Pspec
AS GParamSpec
PTR)
136 SELECT CASE AS CONST Property_id
145 G_OBJECT_WARN_INVALID_PROPERTY_ID(Obj, Property_id, Pspec)
163 BYVAL Obj
AS Gobject
PTR _
164 ,
BYVAL Property_id
AS guint _
165 ,
BYVAL Value
AS CONST GValue
PTR _
166 ,
BYVAL Pspec
AS GParamSpec
PTR)
168 SELECT CASE AS CONST Property_id
178 IF 0 = .
FTyp ORELSE 0 = .
FTyp[0]
THEN .
FTyp = g_strdup(@
"Sans")
180 G_OBJECT_WARN_INVALID_PROPERTY_ID(Obj, Property_id, Pspec)
200 ,
BYVAL N_prop
AS guint _
201 ,
BYVAL Prop
AS GObjectConstructParam
PTR)
AS Gobject
PTR
203 VAR obj = G_OBJECT_CLASS(track_layer_parent_class)->
constructor(Typ, N_prop, Prop)
214 .
TIw = PAR->InfoFontSize * 10
215 .
TIh = PAR->InfoFontSize * 7
236 G_OBJECT_CLASS(track_layer_parent_class)->finalize(Obj)
249 g_type_class_add_private(klass,
SIZEOF(TrackLayerPrivate))
250 VAR object_class = G_OBJECT_CLASS(klass)
258 g_object_class_install_property( _
261 , g_param_spec_int(
"width" _
267 , G_PARAM_READWRITE
OR G_PARAM_CONSTRUCT_ONLY))
270 g_object_class_install_property( _
273 , g_param_spec_int(
"height" _
279 , G_PARAM_READWRITE
OR G_PARAM_CONSTRUCT_ONLY))
282 g_object_class_install_property( _
285 , g_param_spec_pointer(
"map" _
287 ,
"the corresponding map widget" _
288 , G_PARAM_READWRITE
OR G_PARAM_CONSTRUCT))
291 g_object_class_install_property( _
294 , g_param_spec_pointer(
"defaults" _
296 ,
"array of default parameters" _
297 , G_PARAM_READWRITE
OR G_PARAM_CONSTRUCT))
300 g_object_class_install_property( _
303 , g_param_spec_pointer(
"loader" _
305 ,
"the active track loader" _
306 , G_PARAM_READWRITE
OR G_PARAM_CONSTRUCT))
309 g_object_class_install_property( _
312 , g_param_spec_int(
"font-size" _
314 ,
"font size for info pad" _
318 , G_PARAM_READWRITE
OR G_PARAM_CONSTRUCT))
321 g_object_class_install_property( _
324 , g_param_spec_string(
"font-type" _
325 ,
"InfoPadFontType" _
326 ,
"font family for info pad" _
328 , G_PARAM_READWRITE
OR G_PARAM_CONSTRUCT))
342 G_TYPE_INSTANCE_GET_PRIVATE(Self, TRACK_TYPE_LAYER, TrackLayerPrivate)
358 BYVAL Lay
AS OsmGpsMapLayer
PTR _
359 ,
BYVAL Map AS OsmGpsMap
PTR _
360 ,
BYVAL Cr AS cairo_t
PTR)
362 g_return_if_fail(TRACK_IS_LAYER(Lay))
366 cairo_set_source_surface(
Cr, .
Surface, 0, 0)
388 FUNCTION track_layer_busy CDECL(
BYVAL Lay
AS OsmGpsMapLayer
PTR)
AS gboolean
414 BYVAL Lay
AS OsmGpsMapLayer
PTR _
415 ,
BYVAL Map AS OsmGpsMap
PTR _
416 ,
BYVAL Event
AS GdkEventButton
PTR)
AS gboolean
417 g_return_val_if_fail(TRACK_IS_LAYER(Lay), FALSE)
419 VAR state = Event->state
XOR GDK_MOD2_MASK
420 IF NOT((GDK_CONTROL_MASK + GDK_SHIFT_MASK + GDK_LOCK_MASK)
AND state)
THEN RETURN FALSE
422 DIM AS float lat, lon
423 VAR osm = OSM_GPS_MAP(GUI->MAP) _
424 , pt = osm_gps_map_get_event_location(osm, Event)
425 osm_gps_map_point_get_radians(pt, @lat, @lon)
426 osm_gps_map_point_free(pt)
427 VAR sc = osm_gps_map_get_scale(osm) _
428 , d = osm_gps_map_get_scale(osm) * PAR->NearDist / ERA
430 IF GDK_CONTROL_MASK
AND Event->state
THEN
431 WITH TYPE<TS_nearest>(lat, lon)
432 VAR ii = -1L, ni = 0L
433 FOR i
AS LONG = 0
TO UBOUND(.Res)
434 IF NULL = .Res(i).Loa
THEN EXIT FOR
435 IF .Res(i).Dist < d
THEN ni += 1 : ii = i : d = .Res(i).Dist
437 IF 0 = ni
THEN RETURN TRUE
448 IF 0 = .
Loader THEN RETURN FALSE
449 IF d < .
Loader->Nearest(lon, lat)
THEN RETURN FALSE
456 osm_gps_map_set_center(OSM_GPS_MAP(GUI->MAP), Rad2Deg*lat, Rad2Deg*lon)
475 BYVAL Wid
AS GtkWidget
PTR _
476 ,
BYVAL Event
AS GdkEventConfigure
PTR _
477 ,
BYVAL UDat
AS GPOINTER)
AS gboolean
478 WITH Peek(TrackLayerPrivate, UDat)
481 END WITH :
RETURN FALSE
498 g_return_val_if_fail(OSM_IS_GPS_MAP(
Map), NULL)
499 VAR osm = GTK_WIDGET(
Map) _
500 , w = gtk_widget_get_allocated_width(osm) _
501 , h = gtk_widget_get_allocated_height(osm)
502 VAR r = g_object_new(TRACK_TYPE_LAYER _
507 osm_gps_map_layer_add(OSM_GPS_MAP(
Map), OSM_GPS_MAP_LAYER(r))
508 g_signal_connect(
Map,
"configure_event" _
527 SUB render_rtext(
BYVAL Cr AS cairo_t
PTR,
BYREF Y
AS LONG,
BYREF W
AS LONG,
BYREF S
AS STRING)
528 IF 0 =
LEN(S)
THEN EXIT SUB
530 DIM AS cairo_text_extents_t extents
531 cairo_text_extents(
Cr, S, @extents)
532 g_assert(extents.
width <> 0.0)
534 VAR xt = W - extents.
width - 2 _
535 , yt = Y - extents.y_bearing
536 cairo_set_source_rgb(
Cr, 1.0, 1.0, 1.0)
537 cairo_set_line_width(
Cr, PAR->InfoFontSize/6)
538 cairo_move_to(
Cr, xt, yt)
539 cairo_text_path(
Cr, S)
542 cairo_set_source_rgb(
Cr, 0.0, 0.0, 0.0)
543 cairo_move_to(
Cr, xt, yt)
544 cairo_show_text(
Cr, S)
546 y -= PAR->InfoFontSize*6\5
564 RETURN g &
FORMAT(m,
"\°00.0000\'") & *
IIF(V >= 0, @
"N", @
"S")
582 RETURN g &
FORMAT(m,
"\°00.0000\'") & *
IIF(V >= 0, @
"E", @
"W")
600 BYVAL Lay
AS TrackLayer
PTR _
601 ,
BYVAL Map AS OsmGpsMap
PTR)
607 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE)
609 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0)
611 cairo_set_operator(cr, CAIRO_OPERATOR_OVER)
613 cairo_select_font_face(cr _
615 , CAIRO_FONT_SLANT_NORMAL _
616 , CAIRO_FONT_WEIGHT_BOLD)
617 cairo_set_font_size(cr, .
FSiz)
619 DIM AS LONG y = .
TIh - PAR->InfoFontSize, w = .
TIw
625 render_rtext(cr, y, w,
FORMAT(.Ele,
"##### \m") &
FORMAT(.Ang,
" ###\°"))
630 DIM AS gfloat lat, lon
631 g_object_get(
Map,
"latitude", @lat,
"longitude", @lon, NULL)
656 BYVAL Model
AS GtkTreeModel
PTR _
657 ,
BYVAL Path
AS GtkTreePath
PTR _
658 ,
BYVAL Iter
AS GtkTreeIter
PTR _
659 ,
BYVAL TLPriv
AS gpointer)
AS gboolean
661 gtk_tree_model_get(Model, Iter _
664 IF FALSE = en
THEN RETURN FALSE
667 DIM AS gchar
PTR lcs, pcs
668 DIM AS TrackLoader
PTR loa
669 gtk_tree_model_get(Model, Iter _
672 , COL_P_COLOR, @pcs _
673 , COL_L_COLOR, @lcs _
674 , COL__LOADER, @loa _
676 DIM AS GdkRGBA lc, pc
677 gdk_rgba_parse(@pc, pcs) : g_free(pcs)
678 gdk_rgba_parse(@lc, lcs) : g_free(lcs)
679 IF NULL = loa
THEN RETURN false
681 WITH PEEK(TrackLayerPrivate, TLPriv)
682 IF loa->Pixel(.
TLx, .
TLy, .
TLz)
THEN RETURN false
685 cairo_set_line_width(.
Cr, lw)
686 cairo_set_source_rgba(.
Cr, lc.red, lc.green, lc.blue, lc.
alpha)
687 cairo_set_line_cap(.
Cr, CAIRO_LINE_CAP_ROUND)
688 cairo_set_line_join(.
Cr, CAIRO_LINE_JOIN_ROUND)
689 cairo_move_to(.
Cr, loa->V[0].Xpix, loa->V[0].Ypix)
690 FOR i
AS INTEGER = 1
TO loa->Az
691 cairo_line_to(.
Cr, loa->V[i].Xpix, loa->V[i].Ypix)
696 IF pw
AND &b1111
THEN
697 cairo_set_source_rgba(.
Cr, pc.red, pc.green, pc.blue, pc.
alpha)
698 SELECT CASE AS CONST pw
699 CASE &b0001
TO &b1111
700 FOR i
AS INTEGER = 0
TO loa->Az
701 cairo_new_sub_path(.
Cr)
702 cairo_arc(.
Cr, loa->V[i].Xpix, loa->V[i].Ypix, pw, 0.0, PIx2)
703 NEXT : cairo_fill(.
Cr)
705 DIM AS INTEGER p4, p6
706 DIM AS float up_4, up_6, low4, low6
707 IF pw
AND &b00110000
THEN
708 SELECT CASE AS CONST (pw
SHR 4)
AND &b11
709 CASE 1 : p4 =
OFFSETOF(TrP, Ele) : low4 = loa->Mn.Ele : up_4 = loa->Mx.Ele
710 CASE 2 : p4 =
OFFSETOF(TrP, Spd) : low4 = loa->Mn.Spd : up_4 = loa->Mx.Spd
711 CASE 3 : p4 =
OFFSETOF(TrP, Ang) : low4 = loa->Mn.Ang : up_4 = loa->Mx.Ang
714 IF pw
AND &b11000000
THEN
715 SELECT CASE AS CONST (pw
SHR 6)
AND &b11
716 CASE 1 : p6 =
OFFSETOF(TrP, Ele) : low6 = loa->Mn.Ele : up_6 = loa->Mx.Ele
717 CASE 2 : p6 =
OFFSETOF(TrP, Spd) : low6 = loa->Mn.Spd : up_6 = loa->Mx.Spd
718 CASE 3 : p6 =
OFFSETOF(TrP, Ang) : low6 = loa->Mn.Ang : up_6 = loa->Mx.Ang
722 IF p4
ANDALSO p6
THEN
723 VAR fac4 =
IIF(up_4 <> low4, ((pw
AND &b1111) - 1) / (up_4 - low4), 1.) _
724 , fac6 =
IIF(up_6 <> low6, .9 / (up_6 - low6), 1.)
725 FOR i
AS INTEGER = 0
TO loa->Az
726 VAR a = .1 + (
PEEK(
float,
CAST(
ANY PTR, @loa->V[i]) + p6) - low6) * fac6 _
727 , r = 1. + (
PEEK(
float,
CAST(
ANY PTR, @loa->V[i]) + p4) - low4) * fac4
728 cairo_set_source_rgba(.
Cr, pc.red, pc.green, pc.blue, a)
729 cairo_arc(.
Cr, loa->V[i].Xpix, loa->V[i].Ypix, r, 0.0, PIx2)
733 VAR fac =
IIF(up_4 <> low4, ((pw
AND &b1111) - 1) / (up_4 - low4), 1.)
734 FOR i
AS INTEGER = 0
TO loa->Az
735 VAR r = 1. + (
PEEK(
float,
CAST(
ANY PTR, @loa->V[i]) + p4) - low4) * fac
736 cairo_new_sub_path(.
Cr)
737 cairo_arc(.
Cr, loa->V[i].Xpix, loa->V[i].Ypix, r, 0.0, PIx2)
738 NEXT : cairo_fill(.
Cr)
740 VAR r = pw
AND &b1111 _
741 , fac =
IIF(up_6 <> low6, .9 / (up_6 - low6), 1.)
742 FOR i
AS INTEGER = 0
TO loa->Az
743 VAR a = .1 + (
PEEK(
float,
CAST(
ANY PTR, @loa->V[i]) + p6) - low6) * fac
744 cairo_set_source_rgba(.
Cr, pc.red, pc.green, pc.blue, a)
745 cairo_arc(.
Cr, loa->V[i].Xpix, loa->V[i].Ypix, r, 0.0, PIx2)
767 BYVAL Lay
AS OsmGpsMapLayer
PTR _
768 ,
BYVAL Map AS OsmGpsMap
PTR)
770 g_return_if_fail(TRACK_IS_LAYER(Lay))
778 .
Surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, .
TLw, .
TLh)
783 g_object_get(GUI->MAP _
790 cairo_set_operator(.
Cr, CAIRO_OPERATOR_SOURCE)
791 cairo_set_source_rgba(.
Cr, 1.0, 0.0, 0.0, 0.0)
793 cairo_set_operator(.
Cr, CAIRO_OPERATOR_OVER)
795 gtk_tree_model_foreach(GTK_TREE_MODEL(GUI->STO) _
818 g_return_val_if_fail(TRACK_IS_LAYER(Lay), NULL)
837 BYVAL Lay
AS TrackLayer
PTR)
AS TrackLoader
PTR
839 g_return_val_if_fail(TRACK_IS_LAYER(Lay), NULL)
854 BYVAL Lay
AS TrackLayer
PTR)
856 g_return_if_fail(TRACK_IS_LAYER(Lay))
858 IF 0 = Lay->Priv->
Loader THEN EXIT SUB
860 .MapCenter(Lay->Priv->
TLw, Lay->Priv->
TLh)
861 osm_gps_map_set_center_and_zoom(OSM_GPS_MAP(GUI->MAP), .UsLa, .UsLo, .UsZo)
876 BYVAL Lay
AS TrackLayer
PTR _
877 ,
BYVAL Loa
AS TrackLoader
PTR)
879 g_return_if_fail(TRACK_IS_LAYER(Lay))
881 Lay->Priv->
Loader = Loa :
IF 0 = Loa
THEN EXIT SUB
883 IF .UsZo < 0
THEN .MapCenter(Lay->Priv->
TLw, Lay->Priv->
TLh)
884 osm_gps_map_set_center_and_zoom(OSM_GPS_MAP(GUI->MAP), .UsLa, .UsLo, .UsZo)
899 g_return_if_fail(TRACK_IS_LAYER(Lay))
917 g_return_val_if_fail(TRACK_IS_LAYER(Lay), -1)
918 IF NULL = Lay->Priv->
Loader THEN RETURN -1
919 RETURN Lay->Priv->
Loader->Cur
937 g_return_if_fail(TRACK_IS_LAYER(Lay))
938 IF NULL = Lay->Priv->
Loader THEN EXIT SUB
941 .Cur =
IIF(N > .Az, .Az,
IIF(N < 0, 0, N))
942 .UsLa = Rad2Deg * .V[.Cur].Lat
943 .UsLo = Rad2Deg * .V[.Cur].Lon
945 osm_gps_map_set_center_and_zoom(OSM_GPS_MAP(GUI->MAP), .UsLa, .UsLo, .UsZo)
968 g_return_if_fail(TRACK_IS_LAYER(Lay))
971 osm_gps_map_set_center_and_zoom(OSM_GPS_MAP(GUI->MAP) _
972 , Rad2Deg * (La0 + La1) * .5 _
973 , Rad2Deg * (Lo0 + Lo1) * .5 _
990 g_return_if_fail(TRACK_IS_LAYER(Lay))
991 IF NULL = Lay->Priv->
Loader THEN EXIT SUB
994 SELECT CASE AS CONST S[0]
995 CASE ASC(
"+") : .Cur += 1 :
IF .Cur > .Az
THEN .Cur = .Az
996 CASE ASC(
"-") : .Cur -= 1 :
IF .Cur < 0
THEN .Cur = 0
997 CASE ASC(
"f") : .Cur += .Az
SHR 5 :
IF .Cur > .Az
THEN .Cur = .Az
998 CASE ASC(
"b") : .Cur -= .Az
SHR 5 :
IF .Cur < 0
THEN .Cur = 0
999 CASE ASC(
"F") : .Cur += .Az
SHR 3 :
IF .Cur > .Az
THEN .Cur = .Az
1000 CASE ASC(
"B") : .Cur -= .Az
SHR 3 :
IF .Cur < 0
THEN .Cur = 0
1001 CASE ASC(
"H") : .Cur = 0
1002 CASE ASC(
"E") : .Cur = .Az
1003 CASE ASC(
"M") : .Cur = .Az
SHR 1
1004 CASE ASC(
"1") : .Cur =
CINT(.1 * .Az)
1005 CASE ASC(
"2") : .Cur =
CINT(.2 * .Az)
1006 CASE ASC(
"3") : .Cur =
CINT(.3 * .Az)
1007 CASE ASC(
"4") : .Cur =
CINT(.4 * .Az)
1008 CASE ASC(
"5") : .Cur =
CINT(.5 * .Az)
1009 CASE ASC(
"6") : .Cur =
CINT(.6 * .Az)
1010 CASE ASC(
"7") : .Cur =
CINT(.7 * .Az)
1011 CASE ASC(
"8") : .Cur =
CINT(.8 * .Az)
1012 CASE ASC(
"9") : .Cur =
CINT(.9 * .Az)
1013 CASE ASC(
"}") : .Cur = .SkipOut( 2, PAR->SkipFact * osm_gps_map_get_scale(Lay->Priv->
Map))
1014 CASE ASC(
">") : .Cur = .SkipOut( 1, PAR->SkipFact * osm_gps_map_get_scale(Lay->Priv->
Map))
1015 CASE ASC(
"<") : .Cur = .SkipOut(-1, PAR->SkipFact * osm_gps_map_get_scale(Lay->Priv->
Map))
1016 CASE ASC(
"{") : .Cur = .SkipOut(-2, PAR->SkipFact * osm_gps_map_get_scale(Lay->Priv->
Map))
1017 CASE ELSE :
EXIT SUB
1019 .UsLa = Rad2Deg * .V[.Cur].Lat
1020 .UsLo = Rad2Deg * .V[.Cur].Lon
1022 osm_gps_map_set_center_and_zoom(OSM_GPS_MAP(GUI->MAP), .UsLa, .UsLo, .UsZo)