touch: add Direct (0-hop) filter to contact list and map
Contact list gains a "Direct (0-hop)" option in the Filter sheet (value 5) that shows only nodes heard without any repeater hops (out_path_len == 0). Header chip shows "Dir" when active. Selecting a filter now auto-dismisses the sheet (matching sort behaviour). Map options panel gets a "Direct (0-hop) only" toggle that hides both contact markers and link lines for any multi-hop or path-unknown node.
This commit is contained in:
1 file changed
+29
-17
+29
-17
@@ -14861,12 +14861,12 @@ static lv_obj_t* s_ct_normal_bar = nullptr; // header toolbar shown in normal m
|
||||
static lv_obj_t* s_ct_select_bar = nullptr; // header toolbar shown in select mode
|
||||
static lv_obj_t* s_ct_del_btn = nullptr; // "Delete (N)" button in the select bar
|
||||
static lv_obj_t* s_ct_sort_btns[3] = { nullptr, nullptr, nullptr };
|
||||
static lv_obj_t* s_ct_filter_btns[5] = { nullptr, nullptr, nullptr, nullptr, nullptr };
|
||||
static lv_obj_t* s_ct_filter_btns[6] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
|
||||
static lv_obj_t* s_ct_filter_btn_lbl = nullptr; // header Filter button label (shows the active filter)
|
||||
static lv_obj_t* s_ct_disc_badge = nullptr; // count badge on the header Discovered button
|
||||
static const char* contactsFilterShortLabel() {
|
||||
switch (g_lv.contacts_filter) {
|
||||
case 1u: return "RPT"; case 2u: return "Peer"; case 3u: return "Fav"; case 4u: return "Loc";
|
||||
case 1u: return "RPT"; case 2u: return "Peer"; case 3u: return "Fav"; case 4u: return "Loc"; case 5u: return "Dir";
|
||||
default: return "All";
|
||||
}
|
||||
}
|
||||
@@ -14899,6 +14899,7 @@ static bool ctPassesFilter(const ContactInfo& c, bool is_fav, int fav_count, con
|
||||
case 2u: if(is_rep) return false; break; // peers
|
||||
case 3u: if(fav_count>0 && !is_fav) return false; break; // favorites
|
||||
case 4u: if(!(c.gps_lat!=0 || c.gps_lon!=0)) return false; break; // has location
|
||||
case 5u: if(c.out_path_len != 0) return false; break; // 0-hop / direct neighbors only
|
||||
default: break; // 0 = all
|
||||
}
|
||||
if(needle && needle[0]){
|
||||
@@ -15100,7 +15101,7 @@ static void ctPaintOpt(lv_obj_t* b, bool active){
|
||||
}
|
||||
static void ctSheetRepaint(){
|
||||
for(int i=0;i<3;++i) ctPaintOpt(s_ct_sort_btns[i], g_contacts_sort==(uint8_t)i);
|
||||
for(int i=0;i<5;++i) ctPaintOpt(s_ct_filter_btns[i], g_lv.contacts_filter==(uint8_t)i);
|
||||
for(int i=0;i<6;++i) ctPaintOpt(s_ct_filter_btns[i], g_lv.contacts_filter==(uint8_t)i);
|
||||
}
|
||||
static void ctSortOptCb(lv_event_t* e){
|
||||
if(lv_event_get_code(e)!=LV_EVENT_CLICKED) return;
|
||||
@@ -15113,7 +15114,8 @@ static void ctFilterOptCb(lv_event_t* e){
|
||||
g_lv.contacts_filter = (uint8_t)(uintptr_t)lv_event_get_user_data(e);
|
||||
updateContactsFilterSegments();
|
||||
if(s_ct_filter_btn_lbl) lv_label_set_text_fmt(s_ct_filter_btn_lbl, "%s %s", LV_SYMBOL_DOWN, contactsFilterShortLabel());
|
||||
ctSheetRepaint(); s_ct_list_force = true; refreshContactsList();
|
||||
s_ct_list_force = true; refreshContactsList();
|
||||
ctSortSheetClose(); // apply and dismiss, like sort does
|
||||
}
|
||||
static void ctSelectFromSheetCb(lv_event_t* e){
|
||||
if(lv_event_get_code(e)!=LV_EVENT_CLICKED) return;
|
||||
@@ -15175,7 +15177,7 @@ static lv_obj_t* ctOpenOptionSheet(const char* title){
|
||||
return card;
|
||||
}
|
||||
static void openContactsSortSheet(){
|
||||
for(int i=0;i<5;++i) s_ct_filter_btns[i]=nullptr; // the filter sheet's buttons are gone now
|
||||
for(int i=0;i<6;++i) s_ct_filter_btns[i]=nullptr; // the filter sheet's buttons are gone now
|
||||
lv_obj_t* card = ctOpenOptionSheet("Sort by");
|
||||
s_ct_sort_btns[0] = ctSheetOption(card, "Name (A-Z)", ctSortOptCb, CONTACTS_SORT_AZ, g_contacts_sort==CONTACTS_SORT_AZ);
|
||||
s_ct_sort_btns[1] = ctSheetOption(card, "Recently heard", ctSortOptCb, CONTACTS_SORT_LAST_HEARD, g_contacts_sort==CONTACTS_SORT_LAST_HEARD);
|
||||
@@ -15187,11 +15189,12 @@ static void openContactsSortSheetCb(lv_event_t* e){ if(lv_event_get_code(e)==LV_
|
||||
static void openContactsFilterSheet(){
|
||||
for(int i=0;i<3;++i) s_ct_sort_btns[i]=nullptr; // the sort sheet's buttons are gone now
|
||||
lv_obj_t* card = ctOpenOptionSheet("Filter");
|
||||
s_ct_filter_btns[0] = ctSheetOption(card, "All", ctFilterOptCb, 0, g_lv.contacts_filter==0);
|
||||
s_ct_filter_btns[1] = ctSheetOption(card, "Repeaters", ctFilterOptCb, 1, g_lv.contacts_filter==1);
|
||||
s_ct_filter_btns[2] = ctSheetOption(card, "Peers", ctFilterOptCb, 2, g_lv.contacts_filter==2);
|
||||
s_ct_filter_btns[3] = ctSheetOption(card, "Favorites", ctFilterOptCb, 3, g_lv.contacts_filter==3);
|
||||
s_ct_filter_btns[4] = ctSheetOption(card, "Has location", ctFilterOptCb, 4, g_lv.contacts_filter==4);
|
||||
s_ct_filter_btns[0] = ctSheetOption(card, "All", ctFilterOptCb, 0, g_lv.contacts_filter==0);
|
||||
s_ct_filter_btns[1] = ctSheetOption(card, "Repeaters", ctFilterOptCb, 1, g_lv.contacts_filter==1);
|
||||
s_ct_filter_btns[2] = ctSheetOption(card, "Peers", ctFilterOptCb, 2, g_lv.contacts_filter==2);
|
||||
s_ct_filter_btns[3] = ctSheetOption(card, "Favorites", ctFilterOptCb, 3, g_lv.contacts_filter==3);
|
||||
s_ct_filter_btns[4] = ctSheetOption(card, "Has location", ctFilterOptCb, 4, g_lv.contacts_filter==4);
|
||||
s_ct_filter_btns[5] = ctSheetOption(card, "Direct (0-hop)", ctFilterOptCb, 5, g_lv.contacts_filter==5);
|
||||
}
|
||||
static void openContactsFilterSheetCb(lv_event_t* e){ if(lv_event_get_code(e)==LV_EVENT_CLICKED) openContactsFilterSheet(); }
|
||||
|
||||
@@ -16854,9 +16857,10 @@ static lv_point_t s_map_link_pts[k_map_markers_max][2];
|
||||
// Per-element visibility of the map's on-screen text/markers (persisted; all
|
||||
// default shown). Coords = bottom-left read-out, TileXYZ = the zoom + tile path
|
||||
// line, Contacts = the contact markers.
|
||||
static bool s_map_show_coords = true;
|
||||
static bool s_map_show_tilexyz = true;
|
||||
static bool s_map_show_contacts = true;
|
||||
static bool s_map_show_coords = true;
|
||||
static bool s_map_show_tilexyz = true;
|
||||
static bool s_map_show_contacts = true;
|
||||
static bool s_map_direct_only = false; // when true, only 0-hop (directly-heard) contacts appear
|
||||
|
||||
// Apply the coords/tile-line visibility flags to the two corner labels. Safe to
|
||||
// call before the labels exist (null-guarded); invoked at map build + on toggle.
|
||||
@@ -16962,6 +16966,7 @@ static void renderMapMarkers() {
|
||||
ContactInfo c;
|
||||
if (!the_mesh.getContactByIdx(i, c)) continue;
|
||||
if (c.gps_lat == 0 && c.gps_lon == 0) continue;
|
||||
if (s_map_direct_only && c.out_path_len != 0) continue;
|
||||
double mwx, mwy;
|
||||
latLonToWorldPx((double)c.gps_lat / 1.0e6, (double)c.gps_lon / 1.0e6,
|
||||
s_map_zoom, &mwx, &mwy);
|
||||
@@ -17009,6 +17014,7 @@ static void renderMapMarkers() {
|
||||
ContactInfo c;
|
||||
if (!the_mesh.getContactByIdx(i, c)) continue;
|
||||
if (c.gps_lat == 0 && c.gps_lon == 0) continue;
|
||||
if (s_map_direct_only && c.out_path_len != 0) continue;
|
||||
|
||||
const double lat = (double)c.gps_lat / 1.0e6;
|
||||
const double lon = (double)c.gps_lon / 1.0e6;
|
||||
@@ -17437,6 +17443,11 @@ static void mapOptContactsCb(lv_event_t* e) {
|
||||
#endif
|
||||
renderMapMarkers(); // add/remove the contact markers (+ their links)
|
||||
}
|
||||
static void mapOptDirectOnlyCb(lv_event_t* e) {
|
||||
if (lv_event_get_code(e) != LV_EVENT_VALUE_CHANGED) return;
|
||||
s_map_direct_only = lv_obj_has_state(lv_event_get_target(e), LV_STATE_CHECKED);
|
||||
renderMapMarkers();
|
||||
}
|
||||
|
||||
static void mapZoomControlsApply(); // fwd (defined near the map build) — reposition zoom controls
|
||||
// Map zoom-control style toggle (map options popup): ON = +/- buttons, OFF = slider.
|
||||
@@ -17692,10 +17703,11 @@ static void openMapOptions() {
|
||||
// Rows: per-element on-map visibility (link lines / coords / tile z-x-y / contacts).
|
||||
{
|
||||
struct { const char* label; bool state; lv_event_cb_t cb; } rows[] = {
|
||||
{ "Show link lines", s_map_show_links, mapOptLinesCb },
|
||||
{ "Show coordinates", s_map_show_coords, mapOptCoordsCb },
|
||||
{ "Show tile z/x/y", s_map_show_tilexyz, mapOptTileXYZCb },
|
||||
{ "Show contacts", s_map_show_contacts, mapOptContactsCb },
|
||||
{ "Show link lines", s_map_show_links, mapOptLinesCb },
|
||||
{ "Show coordinates", s_map_show_coords, mapOptCoordsCb },
|
||||
{ "Show tile z/x/y", s_map_show_tilexyz, mapOptTileXYZCb },
|
||||
{ "Show contacts", s_map_show_contacts, mapOptContactsCb },
|
||||
{ "Direct (0-hop) only", s_map_direct_only, mapOptDirectOnlyCb },
|
||||
};
|
||||
for (auto& r : rows) {
|
||||
lv_obj_t* l = lv_label_create(card);
|
||||
|
||||
Reference in new issue
Block a user