This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch main
in repository eradio.

View the commit online.

commit 67007fa1d502f7f234e8fe8b4a96704ed26a50a3
Author: politebot <[email protected]>
AuthorDate: Fri Oct 10 18:35:17 2025 -0500

    Add a toolbar, favorites view
---
 src/appdata.h      |  8 +++++-
 src/http.c         |  3 ++-
 src/station_list.c | 74 ++++++++++++++++++++++++++++++++++++++++++------------
 src/ui.c           | 67 ++++++++++++++++++++++++++++++++++++------------
 4 files changed, 118 insertions(+), 34 deletions(-)

diff --git a/src/appdata.h b/src/appdata.h
index 8531af1..29ad24e 100644
--- a/src/appdata.h
+++ b/src/appdata.h
@@ -13,6 +13,11 @@ typedef struct _Station
    Eina_Bool favorite;
 } Station;
 
+typedef enum {
+   VIEW_SEARCH,
+   VIEW_FAVORITES
+} ViewMode;
+
 typedef struct _AppData
 {
    Evas_Object *win;
@@ -23,9 +28,10 @@ typedef struct _AppData
    Evas_Object *play_pause_btn;
    Evas_Object *stop_btn;
    Evas_Object *search_btn;
+   Evas_Object *search_bar;
    Eina_List *stations;
    Eina_Bool playing;
    Eina_Hash *favorites;
    Eina_List *favorites_stations;
-   Evas_Object *favorites_btn;
+   ViewMode view_mode;
 } AppData;
diff --git a/src/http.c b/src/http.c
index e59bed8..33d3bc2 100644
--- a/src/http.c
+++ b/src/http.c
@@ -236,7 +236,8 @@ _handle_station_list_complete(Ecore_Con_Event_Url_Complete *ev)
     }
 
     favorites_apply_to_stations(ad);
-    station_list_populate(ad, ad->stations);
+    if (ad->view_mode == VIEW_SEARCH)
+      station_list_populate(ad, ad->stations);
 
     xmlXPathFreeObject(xpathObj);
     xmlXPathFreeContext(xpathCtx);
diff --git a/src/station_list.c b/src/station_list.c
index 7ccab08..0de62dc 100644
--- a/src/station_list.c
+++ b/src/station_list.c
@@ -4,6 +4,7 @@
 #include "favorites.h"
 
 static void _favorite_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _favorite_remove_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 
 static void
 _station_click_counter_request(Station *st)
@@ -52,26 +53,43 @@ station_list_populate(AppData *ad, Eina_List *stations)
     {
         Evas_Object *icon = elm_icon_add(ad->win);
         elm_icon_standard_set(icon, "radio");
-        Evas_Object *fav_btn = elm_button_add(ad->win);
-        evas_object_size_hint_min_set(fav_btn, 40, 40);
-        evas_object_propagate_events_set(fav_btn, EINA_FALSE);
-        if (st->favorite)
-          elm_object_text_set(fav_btn, "★");
-        else
-          elm_object_text_set(fav_btn, "☆");
+        Evas_Object *fav_btn = NULL;
+        if (ad->view_mode == VIEW_SEARCH)
+          {
+             fav_btn = elm_button_add(ad->win);
+             evas_object_size_hint_min_set(fav_btn, 40, 40);
+             evas_object_propagate_events_set(fav_btn, EINA_FALSE);
+             if (st->favorite)
+               elm_object_text_set(fav_btn, "★");
+             else
+               elm_object_text_set(fav_btn, "☆");
+          }
+        else if (ad->view_mode == VIEW_FAVORITES)
+          {
+             fav_btn = elm_button_add(ad->win);
+             evas_object_size_hint_min_set(fav_btn, 60, 30);
+             evas_object_propagate_events_set(fav_btn, EINA_FALSE);
+             elm_object_text_set(fav_btn, "Remove");
+          }
 
         Elm_Object_Item *li = elm_list_item_append(ad->list, st->name, icon, fav_btn, _list_item_selected_cb, ad);
         elm_object_item_data_set(li, st);
 
-        // Attach callback with context so we can save favorites on toggle
-        typedef struct {
-            AppData *ad;
-            Elm_Object_Item *li;
-        } FavCtx;
-        FavCtx *ctx = calloc(1, sizeof(FavCtx));
-        ctx->ad = ad;
-        ctx->li = li;
-        evas_object_smart_callback_add(fav_btn, "clicked", _favorite_btn_clicked_cb, ctx);
+        // Attach callback only when a button exists
+        if (fav_btn)
+          {
+             typedef struct {
+                 AppData *ad;
+                 Elm_Object_Item *li;
+             } FavCtx;
+             FavCtx *ctx = calloc(1, sizeof(FavCtx));
+             ctx->ad = ad;
+             ctx->li = li;
+             if (ad->view_mode == VIEW_SEARCH)
+               evas_object_smart_callback_add(fav_btn, "clicked", _favorite_btn_clicked_cb, ctx);
+             else
+               evas_object_smart_callback_add(fav_btn, "clicked", _favorite_remove_btn_clicked_cb, ctx);
+          }
 
         if (st->favicon && st->favicon[0])
           {
@@ -110,3 +128,27 @@ _favorite_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
 
     free(ctx);
 }
+
+static void
+_favorite_remove_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+    typedef struct {
+        AppData *ad;
+        Elm_Object_Item *li;
+    } FavCtx;
+
+    FavCtx *ctx = data;
+    if (!ctx) return;
+    Station *st = elm_object_item_data_get(ctx->li);
+    if (!st) { free(ctx); return; }
+
+    st->favorite = EINA_FALSE;
+    favorites_set(ctx->ad, st, EINA_FALSE);
+    favorites_save(ctx->ad);
+
+    // Rebuild favorites list to reflect removal
+    favorites_rebuild_station_list(ctx->ad);
+    station_list_populate(ctx->ad, ctx->ad->favorites_stations);
+
+    free(ctx);
+}
diff --git a/src/ui.c b/src/ui.c
index 80bef67..346a1bc 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -6,6 +6,8 @@
 static void _win_del_cb(void *data, Evas_Object *obj, void *event_info);
 static void _app_exit_cb(void *data, Evas_Object *obj, void *event_info);
 static void _hoversel_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
+static void _tb_favorites_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _tb_search_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 
 // Forward declarations for callbacks
 void _play_pause_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
@@ -61,13 +63,27 @@ ui_create(AppData *ad)
    elm_win_resize_object_add(ad->win, box);
    evas_object_show(box);
 
-   Evas_Object *search_hbox = elm_box_add(ad->win);
-   elm_box_horizontal_set(search_hbox, EINA_TRUE);
-   elm_box_padding_set(search_hbox, 10, 0);
-   evas_object_size_hint_weight_set(search_hbox, EVAS_HINT_EXPAND, 0);
-   evas_object_size_hint_align_set(search_hbox, EVAS_HINT_FILL, 0);
-   elm_box_pack_end(box, search_hbox);
-   evas_object_show(search_hbox);
+   /* Toolbar at the top */
+   Evas_Object *toolbar = elm_toolbar_add(ad->win);
+   elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_MENU);
+   elm_toolbar_homogeneous_set(toolbar, EINA_TRUE);
+   elm_object_style_set(toolbar, "transparent");
+   evas_object_size_hint_weight_set(toolbar, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(toolbar, EVAS_HINT_FILL, 0);
+   elm_box_pack_end(box, toolbar);
+   evas_object_show(toolbar);
+
+   /* Toolbar items */
+   elm_toolbar_item_append(toolbar, "system-search", "Search", _tb_search_clicked_cb, ad);
+   elm_toolbar_item_append(toolbar, "emblem-favorite", "Favorites", _tb_favorites_clicked_cb, ad);
+
+   ad->search_bar = elm_box_add(ad->win);
+   elm_box_horizontal_set(ad->search_bar, EINA_TRUE);
+   elm_box_padding_set(ad->search_bar, 10, 0);
+   evas_object_size_hint_weight_set(ad->search_bar, EVAS_HINT_EXPAND, 0);
+   evas_object_size_hint_align_set(ad->search_bar, EVAS_HINT_FILL, 0);
+   elm_box_pack_end(box, ad->search_bar);
+   evas_object_show(ad->search_bar);
 
    ad->search_entry = elm_entry_add(ad->win);
    elm_entry_single_line_set(ad->search_entry, EINA_TRUE);
@@ -75,7 +91,7 @@ ui_create(AppData *ad)
    evas_object_size_hint_weight_set(ad->search_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(ad->search_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
    elm_object_part_text_set(ad->search_entry, "guide", "Search for stations...");
-   elm_box_pack_end(search_hbox, ad->search_entry);
+   elm_box_pack_end(ad->search_bar, ad->search_entry);
    evas_object_show(ad->search_entry);
    elm_object_focus_set(ad->search_entry, EINA_TRUE);
 
@@ -86,18 +102,15 @@ ui_create(AppData *ad)
    elm_hoversel_item_add(ad->search_hoversel, "country", NULL, ELM_ICON_NONE, _hoversel_item_selected_cb, NULL);
    elm_hoversel_item_add(ad->search_hoversel, "language", NULL, ELM_ICON_NONE, _hoversel_item_selected_cb, NULL);
    elm_hoversel_item_add(ad->search_hoversel, "tag", NULL, ELM_ICON_NONE, _hoversel_item_selected_cb, NULL);
-   elm_box_pack_end(search_hbox, ad->search_hoversel);
+   elm_box_pack_end(ad->search_bar, ad->search_hoversel);
    evas_object_show(ad->search_hoversel);
 
    ad->search_btn = elm_button_add(ad->win);
    elm_object_text_set(ad->search_btn, "Search");
-   elm_box_pack_end(search_hbox, ad->search_btn);
+   elm_box_pack_end(ad->search_bar, ad->search_btn);
    evas_object_show(ad->search_btn);
 
-   ad->favorites_btn = elm_button_add(ad->win);
-   elm_object_text_set(ad->favorites_btn, "Favorites");
-   elm_box_pack_end(search_hbox, ad->favorites_btn);
-   evas_object_show(ad->favorites_btn);
+   /* Removed redundant Favorites button from search bar; toolbar handles view switching */
 
    ad->list = elm_list_add(ad->win);
    evas_object_size_hint_weight_set(ad->list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -137,16 +150,38 @@ ui_create(AppData *ad)
    evas_object_smart_callback_add(ad->search_btn, "clicked", _search_btn_clicked_cb, ad);
    evas_object_smart_callback_add(ad->search_entry, "activated", _search_entry_activated_cb, ad);
    evas_object_smart_callback_add(ad->list, "selected", _list_item_selected_cb, ad);
-   evas_object_smart_callback_add(ad->favorites_btn, "clicked", _favorites_btn_clicked_cb, ad);
+   /* Favorites view button removed; toolbar callbacks handle switching */
+
+   /* Default to Search view on startup */
+   ad->view_mode = VIEW_SEARCH;
+   evas_object_show(ad->search_bar);
+   if (ad->stations)
+     station_list_populate(ad, ad->stations);
+   else
+     station_list_clear(ad);
 
    evas_object_resize(ad->win, 400, 600);
    evas_object_show(ad->win);
 }
 
 static void
-_favorites_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+_tb_favorites_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
 {
    AppData *ad = data;
+   ad->view_mode = VIEW_FAVORITES;
+   evas_object_hide(ad->search_bar);
    favorites_rebuild_station_list(ad);
    station_list_populate(ad, ad->favorites_stations);
 }
+
+static void
+_tb_search_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   AppData *ad = data;
+   ad->view_mode = VIEW_SEARCH;
+   evas_object_show(ad->search_bar);
+   if (ad->stations)
+     station_list_populate(ad, ad->stations);
+   else
+     station_list_clear(ad);
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to